Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.windpoweredgames.mocha.util;
- import java.util.Collection;
- import org.lwjgl.opengl.GL11;
- import org.lwjgl.util.vector.Vector3f;
- import com.windpoweredgames.mocha.GameEngine;
- import com.windpoweredgames.mocha.component.TextComponent;
- import com.windpoweredgames.mocha.model.Model;
- import com.windpoweredgames.mocha.model.matrix.ModelMatrix;
- public class RayCastUtil {
- public static TextComponent rayStartComp = new TextComponent("RayStart");
- public static TextComponent rayDirComp = new TextComponent("RayDir");
- public static TextComponent dotComp = new TextComponent("DOT");
- public static TextComponent tComp = new TextComponent("T");
- public static TextComponent intersectionComp = new TextComponent("IntPoint");
- public static TextComponent hitComp = new TextComponent("HitPoint");
- public static TextComponent fullAreaComp = new TextComponent("Full Area");
- public static TextComponent area1Comp = new TextComponent("Area1");
- public static TextComponent area2Comp = new TextComponent("Area2");
- public static TextComponent area3Comp = new TextComponent("Area3");
- public static TextComponent areaTotalComp = new TextComponent("Total Area");
- public static Vector3f triag1 = new Vector3f();
- public static Vector3f triag2 = new Vector3f();
- public static Vector3f triag3 = new Vector3f();
- public static Vector3f normal = new Vector3f();
- public static final float ACCURACY = 0.00001f;
- public static Vector3f rayTest(Vector3f rayOrigin, Vector3f rayDirection, Model model){
- float[] vertexes = new float[model.getVertexBuffer().limit()];
- float[] normals = new float[model.getNormalBuffer().limit()];
- model.getVertexBuffer().rewind();
- model.getVertexBuffer().get(vertexes);
- model.getNormalBuffer().rewind();
- model.getNormalBuffer().get(normals);
- Vector3f pos = model.getModelMatrix().getPosition();
- Vector3f result = null;
- float resultDist = Float.MAX_VALUE;
- for(int i=0;i<vertexes.length;){
- // fix we need to adjust the triangle coords by the model position
- Vector3f normal = new Vector3f(normals[i+0],normals[i+1],normals[i+2]);
- Vector3f point1 = new Vector3f(vertexes[i]+pos.x,vertexes[i+1]+pos.y,vertexes[i+2]+pos.z);
- Vector3f point2 = new Vector3f(vertexes[i+3]+pos.x,vertexes[i+4]+pos.y,vertexes[i+5]+pos.z);
- Vector3f point3 = new Vector3f(vertexes[i+6]+pos.x,vertexes[i+7]+pos.y,vertexes[i+8]+pos.z);
- Vector3f tempResult = rayTest(rayOrigin, rayDirection, normal,point1, point2, point3);
- if(tempResult!=null){
- float d = VectorUtil.distance(rayOrigin, tempResult);
- if(d < resultDist){
- resultDist = d;
- result = tempResult;
- }
- }
- i+=9;
- }
- return result;
- }
- public static Vector3f rayTest(Vector3f rayOrigin, Vector3f rayDirection, Vector3f planeNormal, Vector3f trianglePoint1, Vector3f trianglePoint2, Vector3f trianglePoint3){
- rayStartComp.setText("RayStart = "+rayOrigin);
- rayDirComp.setText("RayDir = "+rayDirection);
- intersectionComp.setText("IntPoint");
- triag1 = trianglePoint1;
- triag2 = trianglePoint2;
- triag3 = trianglePoint3;
- normal = planeNormal;
- // nx, ny, nz : normal vector of the plane
- // x0, y0, z0 = a point on the plane
- // RAY properties...
- // x = xs+t*xd
- // y = ys+t*yd
- // z = zs+t*zd
- // xs, ys, zs = starting point of ray
- // xd, yd, zd = direction of ray
- // the raw equation we use.
- //t=(x0*nx+y0*ny+z0*nz-nx*nx-ny*ya-nz*zs) / (xd*nx+yd*ny+zd*nz)
- // / <this part is the dot factor
- Vector3f pointOnPLane = trianglePoint1; // any point should work as long as its on the plane.
- // a= xd * nx + yd * ny + zd * nz;
- float dot = rayDirection.x*planeNormal.x+rayDirection.y*planeNormal.y+rayDirection.z*planeNormal.z;
- dotComp.setText("DOT = "+dot);
- float t=0;
- // if dot = 0 then the ray is pararel and will never intersect the plane. T should = 0 in this case.
- // 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.
- // leave t equal to 0
- if(dot == 0){
- return null; // this line is parrel and will never touch
- }
- // (p1.x * nx + p1.y * ny + p1.z * nz - nx * xs - ny * ys - nz * zs)
- 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;
- t = coordRatio / dot;
- tComp.setText("T = "+t);
- if(t<0){ // if t<0 then they intersect but the direction of intersection is opposite the cast direction.
- return null;
- }
- // 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.
- // now lets figure out the intersect point
- float intX = rayOrigin.x+t*rayDirection.x;
- float intY = rayOrigin.y+t*rayDirection.y ;
- float intZ = rayOrigin.z+t*rayDirection.z;
- Vector3f intPoint = new Vector3f(intX,intY,intZ);
- intersectionComp.setText("IntPoint = "+intPoint);
- float fullArea = calculateTriangleArea(trianglePoint1, trianglePoint2, trianglePoint3);
- fullAreaComp.setText("Full Area = "+fullArea);
- float subTriangle1 = calculateTriangleArea(trianglePoint1, trianglePoint2, intPoint);
- area1Comp.setText("Area1 = "+subTriangle1);
- float subTriangle2 = calculateTriangleArea(trianglePoint2, trianglePoint3, intPoint);
- area2Comp.setText("Area2 = "+subTriangle2);
- float subTriangle3 = calculateTriangleArea(trianglePoint1, trianglePoint3, intPoint);
- area3Comp.setText("Area3 = "+subTriangle3);
- float totalSubAreas = subTriangle1 + subTriangle2 +subTriangle3;
- areaTotalComp.setText("Area Total = "+ totalSubAreas);
- // have an accuracy approach is import cause rounding errors will happen when doing Math.sqr. !
- if(Math.abs(fullArea- totalSubAreas)<ACCURACY){
- hitComp.setText("HIT");
- return intPoint;
- }else{
- hitComp.setText("MISS");
- return null;
- }
- }
- private static float calculateTriangleArea(Vector3f p1, Vector3f p2, Vector3f p3){
- 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));
- 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));
- 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));
- float s = (a+b+c)/2;
- float result = (float)Math.sqrt(s*(s-a)*(s-b)*(s-c));
- return result;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement