/** * Cast a ray (in model space) against a mesh. */ public static bool MeshRaycast(Ray InRay, Vector3[] vertices, int[] triangles, out ObiRaycastHit hit, float distance = Mathf.Infinity) { Vector3 hitNormal = Vector3.zero; // vars used in loop Vector3 vert0, vert1, vert2; Vector3 origin = InRay.origin, direction = InRay.direction; hit = new ObiRaycastHit(Mathf.Infinity, Vector3.zero, Vector3.zero, -1); /** * Iterate faces, testing for nearest hit to ray origin. */ for (int CurTri = 0; CurTri < triangles.Length; CurTri += 3) { if (CurTri + 2 >= triangles.Length) { continue; } if (triangles[CurTri + 2] >= vertices.Length) { continue; } vert0 = vertices[triangles[CurTri + 0]]; vert1 = vertices[triangles[CurTri + 1]]; vert2 = vertices[triangles[CurTri + 2]]; // Second pass, test intersection with triangle if (RayIntersectsTriangle(origin, direction, vert0, vert1, vert2, ref distance, ref hitNormal)) { if (distance < hit.distance) { hit.distance = distance; hit.triangle = CurTri / 3; hit.position = InRay.GetPoint(hit.distance); hit.normal = hitNormal; } } } return(hit.triangle > -1); }
/** * Find the nearest triangle intersected by InWorldRay on this mesh. InWorldRay is in world space. * @hit contains information about the hit point. @distance limits how far from @InWorldRay.origin the hit * point may be. @cullingMode determines what face orientations are tested (Culling.Front only tests front * faces, Culling.Back only tests back faces, and Culling.FrontBack tests both). * Ray origin and position values are in local space. */ public static bool WorldRaycast(Ray InWorldRay, Matrix4x4 transform, Vector3[] vertices, int[] triangles, out ObiRaycastHit hit, float distance = Mathf.Infinity) { Ray ray = InWorldRay; if (transform != null) { Matrix4x4 inv = transform.inverse; ray.origin = inv.MultiplyPoint3x4(ray.origin); ray.direction = inv.MultiplyVector(ray.direction); } return(MeshRaycast(ray, vertices, triangles, out hit, distance)); }