// Finds if the two rays intersect public bool intersects(ref Ray ray) { // Variables Vector vec= direction.getCrossProduct(ray.direction); float a= vec.getMagnitude(); if(a== 0f && position.x== ray.position.x && position.y== ray.position.y && position.z== ray.position.z) return true; // Variables float[] n= new float[27]; Vector vox; a*= a; n[0]= ray.position.x-position.x; n[1]= ray.position.y-position.y; n[2]= ray.position.z-position.z; n[3]= vec.x; n[4]= vec.y; n[5]= vec.z; n[6]= (n[0]*ray.direction.y*n[5]+n[1]*ray.direction.z*n[3]+n[2]*ray.direction.x*n[4]-n[0]*ray.direction.z*n[4]-n[1]*ray.direction.x*n[5]-n[2]*ray.direction.y*n[3]); n[7]= (n[0]*direction.y*n[5]+n[1]*direction.z*n[3]+n[2]*direction.x*n[4]-n[0]*direction.z*n[4]-n[1]*direction.x*n[5]-n[2]*direction.y*n[3]); n[8]= n[6]/a; n[9]= n[7]/a; vec= (position.toVector())+n[8]*direction; vox= (ray.position.toVector())+n[8]*ray.direction; if(!vec.Equals(vox)) return false; return true; }
// Gets the picking ray of the mouse and the world public Ray getPickingRay(float[] viewport) { // Variables OpenTK.Matrix4 mdlv, proj; float mx, my; float nx, ny, nz; float fx, fy, fz; Ray ray; GL.GetFloat(GetPName.ProjectionMatrix, out proj); GL.GetFloat(GetPName.ModelviewMatrix, out mdlv); mx= mouse.position.x; my= viewport[3]-mouse.position.y; // Unproject unproject(ref mx, ref my, 0f, ref mdlv, ref proj, ref viewport, out nx, out ny, out nz); unproject(ref mx, ref my, 1f, ref mdlv, ref proj, ref viewport, out fx, out fy, out fz); ray= new Ray(new Point(nx, ny, nz), new Point(fx, fy, fz)); return ray; }
public bool intersects(Ray ray) { return intersects(ref ray); }
// Finds if the given ray intersects the box public bool intersects(Ray ray) { // Variables bool bInside= true; byte[] quad= new byte[3]; int plane; float[] maxT= new float[3]; Point cPlane= Point.ORIGIN; Point min= position; Point max= position+size; if(ray.position.x< min.x) { quad[0]= 0; cPlane.x= min.x; bInside= false; } else if(ray.position.x> max.x) { quad[0]= 1; cPlane.x= max.x; bInside= false; } else quad[0]= 2; if(ray.position.y< min.y) { quad[1]= 0; cPlane.y= min.y; bInside= false; } else if(ray.position.y> max.y) { quad[1]= 1; cPlane.y= max.y; bInside= false; } else quad[1]= 2; if(ray.position.z< min.z) { quad[2]= 0; cPlane.z= min.z; bInside= false; } else if(ray.position.z> max.z) { quad[2]= 1; cPlane.z= max.z; bInside= false; } else quad[2]= 2; if(bInside) return true; if(quad[0]!= 2 && ray.direction.x!= 0) maxT[0]= (cPlane.x-ray.position.x)/ray.direction.x; else maxT[0]= -1; if(quad[1]!= 2 && ray.direction.y!= 0) maxT[1]= (cPlane.y-ray.position.y)/ray.direction.y; else maxT[1]= -1; if(quad[2]!= 2 && ray.direction.z!= 0) maxT[2]= (cPlane.z-ray.position.z)/ray.direction.z; else maxT[2]= -1; plane= 0; for(int i= 0; i< maxT.Length; i++) { if(maxT[plane]< maxT[i]) plane= i; } if(maxT[plane]< 0) return false; if(plane!= 0) { cPlane.x= ray.position.x+maxT[plane]*ray.direction.x; if(cPlane.x< min.x || cPlane.x> max.x) return false; } if(plane!= 1) { cPlane.y= ray.position.y+maxT[plane]*ray.direction.y; if(cPlane.y< min.y || cPlane.y> max.y) return false; } if(plane!= 2) { cPlane.z= ray.position.z+maxT[plane]*ray.direction.z; if(cPlane.z< min.z || cPlane.z> max.z) return false; } return (maxT[plane]< 1f); }