Want more features on Pastebin? Sign Up, it's FREE!
Guest

RayCastUtil

By: a guest on Dec 9th, 2013  |  syntax: Java  |  size: 7.04 KB  |  views: 197  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. package com.windpoweredgames.mocha.util;
  2.  
  3. import java.util.Collection;
  4.  
  5. import org.lwjgl.opengl.GL11;
  6. import org.lwjgl.util.vector.Vector3f;
  7.  
  8. import com.windpoweredgames.mocha.GameEngine;
  9. import com.windpoweredgames.mocha.component.TextComponent;
  10. import com.windpoweredgames.mocha.model.Model;
  11. import com.windpoweredgames.mocha.model.matrix.ModelMatrix;
  12.  
  13. public class RayCastUtil {
  14.  
  15.         public static TextComponent rayStartComp = new TextComponent("RayStart");
  16.         public static TextComponent rayDirComp = new TextComponent("RayDir");
  17.        
  18.         public static TextComponent dotComp = new TextComponent("DOT");
  19.         public static TextComponent tComp = new TextComponent("T");
  20.         public static TextComponent intersectionComp = new TextComponent("IntPoint");
  21.         public static TextComponent hitComp = new TextComponent("HitPoint");
  22.         public static TextComponent fullAreaComp = new TextComponent("Full Area");
  23.         public static TextComponent area1Comp = new TextComponent("Area1");
  24.         public static TextComponent area2Comp = new TextComponent("Area2");
  25.         public static TextComponent area3Comp = new TextComponent("Area3");
  26.         public static TextComponent areaTotalComp = new TextComponent("Total Area");
  27.         public static Vector3f triag1 = new Vector3f();
  28.         public static Vector3f triag2 = new Vector3f();
  29.         public static Vector3f triag3 = new Vector3f();
  30.         public static Vector3f normal = new Vector3f();
  31.        
  32.        
  33.        
  34.        
  35.         public static Vector3f rayTest(Vector3f rayOrigin, Vector3f rayDirection, Collection<Model> models){
  36.                 Vector3f result = null;
  37.                 for(Model model : models){
  38.                         result = rayTest(rayOrigin, rayDirection, model);
  39.                         if(result!=null){
  40.                                 return result;
  41.                         }
  42.                 }
  43.                 return result;
  44.         }
  45.        
  46.        
  47.         public static Vector3f rayTest(Vector3f rayOrigin, Vector3f rayDirection, Model model){
  48.                 float[] vertexes = new float[model.getVertexBuffer().limit()];
  49.                 float[] normals =  new float[model.getNormalBuffer().limit()];
  50.                 model.getVertexBuffer().rewind();
  51.                 model.getVertexBuffer().get(vertexes);
  52.                 model.getNormalBuffer().rewind();
  53.                 model.getNormalBuffer().get(normals);
  54.                 Vector3f pos = model.getModelMatrix().getPosition();
  55.                 Vector3f result = null;
  56.                
  57.                 boolean hit = false;
  58.                 for(int i=0;i<vertexes.length;){
  59.                         Vector3f normal = new Vector3f(normals[i+0]-pos.x,normals[i+1]-pos.y,normals[i+2]-pos.z);
  60.                         Vector3f point1 = new Vector3f(vertexes[i]-pos.x,vertexes[i+1]-pos.y,vertexes[i+2]-pos.z);
  61.                         Vector3f point2 = new Vector3f(vertexes[i+3]-pos.x,vertexes[i+4]-pos.y,vertexes[i+5]-pos.z);
  62.                         Vector3f point3 = new Vector3f(vertexes[i+6]-pos.x,vertexes[i+7]-pos.y,vertexes[i+8]-pos.z);
  63.                        
  64.                        
  65.                        
  66.                        
  67.                         result =  rayTest(rayOrigin, rayDirection, normal,point1, point2, point3);
  68.                         if(result != null){
  69.                                
  70.                                 GL11.glPushMatrix();
  71.                                 GL11.glColor3f(0,1, 1);
  72.                                 GL11.glBegin(GL11.GL_TRIANGLES);
  73.                                         GL11.glVertex3f(point1.x, point1.y, point1.z);
  74.                                         GL11.glVertex3f(point2.x, point2.y, point2.z);
  75.                                         GL11.glVertex3f(point3.x, point3.y, point3.z);
  76.                                 GL11.glEnd();
  77.                                 GL11.glPopMatrix();
  78.                                
  79.                                 return result;
  80.                         }
  81.                         i+=9;
  82.                 }
  83.                 return null;
  84.         }
  85.        
  86.        
  87.        
  88.        
  89.         public static  Vector3f rayTest(Vector3f rayOrigin, Vector3f rayDirection, Vector3f planeNormal, Vector3f trianglePoint1, Vector3f trianglePoint2, Vector3f trianglePoint3){
  90.                 rayStartComp.setText("RayStart = "+rayOrigin);
  91.                 rayDirComp.setText("RayDir = "+rayDirection);
  92.                 intersectionComp.setText("IntPoint");
  93.  
  94.                
  95.                 triag1 = trianglePoint1;
  96.                 triag2 = trianglePoint2;
  97.                 triag3 = trianglePoint3;
  98.                 normal = planeNormal;
  99.                
  100.                
  101.                 // nx, ny, nz : normal vector of the plane
  102.                 // x0, y0, z0 = a point on the plane
  103.                
  104.                 // RAY properties...
  105.                 // x = xs+t*xd
  106.                 // y = ys+t*yd
  107.                 // z = zs+t*zd
  108.                 // xs, ys, zs = starting point of ray
  109.                 // xd, yd, zd = direction of ray
  110.                
  111.                 // the raw equation we use.
  112.                 //t=(x0*nx+y0*ny+z0*nz-nx*nx-ny*ya-nz*zs) / (xd*nx+yd*ny+zd*nz)
  113.                 //                                        / <this part is the dot factor
  114.                
  115.                
  116.                 Vector3f pointOnPLane = trianglePoint1; // any point should work as long as its on the plane.
  117.                  //    a=    xd           *     nx      +         yd   *     ny      +      zd      *    nz;
  118.                 float dot = rayDirection.x*planeNormal.x+rayDirection.y*planeNormal.y+rayDirection.z*planeNormal.z;
  119.                 dotComp.setText("DOT = "+dot);
  120.                 float t=0;
  121.                 // if dot = 0 then the ray is pararel and will never intersect the plane. T should = 0 in this case.
  122.                 // if dot < 0 then the ray intersects but it does so in the opposite direction of the cast. so basically this should be treated as a miss.
  123.                 // leave t equal to 0
  124.                 if(dot == 0){
  125.                         return null; // this line is parrel and will never touch
  126.                 }
  127.                 //                   (p1.x       *    nx       +  p1.y        *      ny     +   p1.z       *    nz       -   nx        *  xs        -   ny           *     ys    -    nz       *   zs)
  128.                 float coordRatio = pointOnPLane.x*planeNormal.x+pointOnPLane.y*planeNormal.y+pointOnPLane.z*planeNormal.z-planeNormal.x*rayOrigin.x -   planeNormal.y*rayOrigin.y-planeNormal.z*rayOrigin.z;
  129.                 t = coordRatio / dot;
  130.                 tComp.setText("T = "+t);
  131.                 if(t<0){ // if t<0 then they intersect but the direction of intersection is opposite the cast direction.
  132.                         return null;
  133.                 }
  134.                 // t can be thought of like a distance factor down the ray. Using it we can resolve the exact points (x,y,z) where the ray hits the plane.
  135.                 // now lets figure out the intersect point
  136.                
  137.                 float intX = rayOrigin.x+t*rayDirection.x;
  138.                 float intY = rayOrigin.y+t*rayDirection.y ;
  139.                 float intZ = rayOrigin.z+t*rayDirection.z;
  140.                
  141.                 Vector3f intPoint = new Vector3f(intX,intY,intZ);
  142.                 intersectionComp.setText("IntPoint = "+intPoint);
  143.                
  144.                 float fullArea = calculateTriangleArea(trianglePoint1, trianglePoint2, trianglePoint3);
  145.                 fullAreaComp.setText("Full Area = "+fullArea);
  146.                
  147.                 float subTriangle1 = calculateTriangleArea(trianglePoint1, trianglePoint2, intPoint);
  148.                 area1Comp.setText("Area1 = "+subTriangle1);
  149.                
  150.                 float subTriangle2 = calculateTriangleArea(trianglePoint2, trianglePoint3, intPoint);
  151.                 area2Comp.setText("Area2 = "+subTriangle2);
  152.                
  153.                 float subTriangle3 = calculateTriangleArea(trianglePoint1, trianglePoint3, intPoint);
  154.                 area3Comp.setText("Area3 = "+subTriangle3);
  155.                
  156.                 float totalSubAreas = subTriangle1 + subTriangle2 +subTriangle3;
  157.                 areaTotalComp.setText("Area Total = "+ totalSubAreas);
  158.                
  159.                 // have an accuracy approach is import cause rounding errors will happen when doing Math.sqr. !
  160.                 float accuraty = 0.00001f;
  161.                 if(Math.abs(fullArea- totalSubAreas)<accuraty){
  162.                         hitComp.setText("HIT");
  163.                         return intPoint;
  164.                 }else{
  165.                         hitComp.setText("MISS");
  166.                         return null;
  167.                 }
  168.                
  169.         }
  170.        
  171.        
  172.        
  173.        
  174.         private static float calculateTriangleArea(Vector3f p1, Vector3f p2, Vector3f p3){
  175.                 float a = (float)Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)+(p2.z-p1.z)*(p2.z-p1.z));
  176.                 float b = (float)Math.sqrt((p3.x-p2.x)*(p3.x-p2.x)+(p3.y-p2.y)*(p3.y-p2.y)+(p3.z-p2.z)*(p3.z-p2.z));
  177.                 float c = (float)Math.sqrt((p3.x-p1.x)*(p3.x-p1.x)+(p3.y-p1.y)*(p3.y-p1.y)+(p3.z-p1.z)*(p3.z-p1.z));
  178.                 float s = (a+b+c)/2;
  179.                 float result = (float)Math.sqrt(s*(s-a)*(s-b)*(s-c));
  180.                 return result;
  181.         }
  182.        
  183.        
  184.  
  185.        
  186. }
clone this paste RAW Paste Data