Advertisement
Guest User

Revised Raycasting utility

a guest
Dec 19th, 2013
311
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.65 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement