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

Revised Raycasting utility

By: a guest on Dec 19th, 2013  |  syntax: Java  |  size: 6.65 KB  |  views: 96  |  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.         public static final float ACCURACY = 0.00001f;
  32.        
  33.        
  34.        
  35.        
  36.         public static Vector3f rayTest(Vector3f rayOrigin, Vector3f rayDirection, Model model){
  37.                 float[] vertexes = new float[model.getVertexBuffer().limit()];
  38.                 float[] normals =  new float[model.getNormalBuffer().limit()];
  39.                 model.getVertexBuffer().rewind();
  40.                 model.getVertexBuffer().get(vertexes);
  41.                 model.getNormalBuffer().rewind();
  42.                 model.getNormalBuffer().get(normals);
  43.                 Vector3f pos = model.getModelMatrix().getPosition();
  44.                 Vector3f result = null;
  45.                 float    resultDist = Float.MAX_VALUE;
  46.                
  47.                 for(int i=0;i<vertexes.length;){
  48.                         // fix we need to adjust the triangle coords by the model position
  49.                         Vector3f normal = new Vector3f(normals[i+0],normals[i+1],normals[i+2]);
  50.                         Vector3f point1 = new Vector3f(vertexes[i]+pos.x,vertexes[i+1]+pos.y,vertexes[i+2]+pos.z);
  51.                         Vector3f point2 = new Vector3f(vertexes[i+3]+pos.x,vertexes[i+4]+pos.y,vertexes[i+5]+pos.z);
  52.                         Vector3f point3 = new Vector3f(vertexes[i+6]+pos.x,vertexes[i+7]+pos.y,vertexes[i+8]+pos.z);
  53.                         Vector3f tempResult =  rayTest(rayOrigin, rayDirection, normal,point1, point2, point3);
  54.                         if(tempResult!=null){
  55.                                 float d = VectorUtil.distance(rayOrigin, tempResult);
  56.                                 if(d < resultDist){
  57.                                         resultDist = d;
  58.                                         result = tempResult;
  59.                                 }
  60.                         }
  61.                         i+=9;
  62.                 }
  63.                 return result;
  64.         }
  65.        
  66.        
  67.        
  68.        
  69.         public static  Vector3f rayTest(Vector3f rayOrigin, Vector3f rayDirection, Vector3f planeNormal, Vector3f trianglePoint1, Vector3f trianglePoint2, Vector3f trianglePoint3){
  70.                 rayStartComp.setText("RayStart = "+rayOrigin);
  71.                 rayDirComp.setText("RayDir = "+rayDirection);
  72.                 intersectionComp.setText("IntPoint");
  73.  
  74.                
  75.                 triag1 = trianglePoint1;
  76.                 triag2 = trianglePoint2;
  77.                 triag3 = trianglePoint3;
  78.                 normal = planeNormal;
  79.                
  80.                
  81.                 // nx, ny, nz : normal vector of the plane
  82.                 // x0, y0, z0 = a point on the plane
  83.                
  84.                 // RAY properties...
  85.                 // x = xs+t*xd
  86.                 // y = ys+t*yd
  87.                 // z = zs+t*zd
  88.                 // xs, ys, zs = starting point of ray
  89.                 // xd, yd, zd = direction of ray
  90.                
  91.                 // the raw equation we use.
  92.                 //t=(x0*nx+y0*ny+z0*nz-nx*nx-ny*ya-nz*zs) / (xd*nx+yd*ny+zd*nz)
  93.                 //                                        / <this part is the dot factor
  94.                
  95.                
  96.                 Vector3f pointOnPLane = trianglePoint1; // any point should work as long as its on the plane.
  97.                  //    a=    xd           *     nx      +         yd   *     ny      +      zd      *    nz;
  98.                 float dot = rayDirection.x*planeNormal.x+rayDirection.y*planeNormal.y+rayDirection.z*planeNormal.z;
  99.                 dotComp.setText("DOT = "+dot);
  100.                 float t=0;
  101.                 // if dot = 0 then the ray is pararel and will never intersect the plane. T should = 0 in this case.
  102.                 // 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.
  103.                 // leave t equal to 0
  104.                 if(dot == 0){
  105.                         return null; // this line is parrel and will never touch
  106.                 }
  107.                 //                   (p1.x       *    nx       +  p1.y        *      ny     +   p1.z       *    nz       -   nx        *  xs        -   ny           *     ys    -    nz       *   zs)
  108.                 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;
  109.                 t = coordRatio / dot;
  110.                 tComp.setText("T = "+t);
  111.                 if(t<0){ // if t<0 then they intersect but the direction of intersection is opposite the cast direction.
  112.                         return null;
  113.                 }
  114.                 // 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.
  115.                 // now lets figure out the intersect point
  116.                
  117.                 float intX = rayOrigin.x+t*rayDirection.x;
  118.                 float intY = rayOrigin.y+t*rayDirection.y ;
  119.                 float intZ = rayOrigin.z+t*rayDirection.z;
  120.                
  121.                 Vector3f intPoint = new Vector3f(intX,intY,intZ);
  122.                 intersectionComp.setText("IntPoint = "+intPoint);
  123.                
  124.                 float fullArea = calculateTriangleArea(trianglePoint1, trianglePoint2, trianglePoint3);
  125.                 fullAreaComp.setText("Full Area = "+fullArea);
  126.                
  127.                 float subTriangle1 = calculateTriangleArea(trianglePoint1, trianglePoint2, intPoint);
  128.                 area1Comp.setText("Area1 = "+subTriangle1);
  129.                
  130.                 float subTriangle2 = calculateTriangleArea(trianglePoint2, trianglePoint3, intPoint);
  131.                 area2Comp.setText("Area2 = "+subTriangle2);
  132.                
  133.                 float subTriangle3 = calculateTriangleArea(trianglePoint1, trianglePoint3, intPoint);
  134.                 area3Comp.setText("Area3 = "+subTriangle3);
  135.                
  136.                 float totalSubAreas = subTriangle1 + subTriangle2 +subTriangle3;
  137.                 areaTotalComp.setText("Area Total = "+ totalSubAreas);
  138.                
  139.                 // have an accuracy approach is import cause rounding errors will happen when doing Math.sqr. !
  140.                 if(Math.abs(fullArea- totalSubAreas)<ACCURACY){
  141.                         hitComp.setText("HIT");
  142.                         return intPoint;
  143.                 }else{
  144.                         hitComp.setText("MISS");
  145.                         return null;
  146.                 }
  147.                
  148.         }
  149.        
  150.        
  151.        
  152.        
  153.         private static float calculateTriangleArea(Vector3f p1, Vector3f p2, Vector3f p3){
  154.                 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));
  155.                 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));
  156.                 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));
  157.                 float s = (a+b+c)/2;
  158.                 float result = (float)Math.sqrt(s*(s-a)*(s-b)*(s-c));
  159.                 return result;
  160.         }
  161.        
  162.        
  163.  
  164.        
  165. }
clone this paste RAW Paste Data