public override bool RayCast(Ray ray, out RayCastHit hit) { ray.direction.Normalize(); hit = null; float t0, t1; // solutions for t if the ray intersects // geometric solution Vector3 L = object3D.transform.Location - ray.origin; float tca = Vector3.Dot(L, ray.direction); if (tca < 0) { return(false); } float d2 = Vector3.Dot(L, L) - tca * tca; if (d2 > radius) { return(false); } float thc = (float)Math.Sqrt(radius - d2); t0 = tca - thc; t1 = tca + thc; if (t0 > t1) { float temp = t1; t1 = t0; t0 = temp; } if (t0 < 0) { t0 = t1; // if t0 is negative, let's use t1 instead if (t0 < 0) { return(false); // both t0 and t1 are negative } } hit = new RayCastHit { collider = this, distance = t0, hit = ray.origin + t0 * ray.direction, normal = ray.origin + t0 * ray.direction - object3D.transform.Location, }; return(true); }
public virtual bool RayCast(Ray ray, out RayCastHit hit) { Triangle3 hitTriangle = new Triangle3(); Vector3 barycentricCoords; Vector3 pt; ray.direction.Normalize(); for (int face = 0; face < mesh.faces.GetLength(0); face++) { //Ignore faces where ray hits from behind float rayNormalDot = Vector3.Dot(mesh.faceNormals[face], ray.direction); if (rayNormalDot >= 0) { continue; } float planeConst = Vector3.Dot(mesh.faceNormals[face], mesh.vertices[mesh.faces[face, 0]] + object3D.transform.Location); float t = -(Vector3.Dot(mesh.faceNormals[face], ray.origin) + planeConst) / Vector3.Dot(mesh.faceNormals[face], ray.direction); //Triangle is behind ray origin if (t < 0) { continue; } pt = ray.origin + (t * ray.direction); hitTriangle.v0 = mesh.vertices[mesh.faces[face, 0]] + object3D.transform.Location; hitTriangle.v1 = mesh.vertices[mesh.faces[face, 1]] + object3D.transform.Location; hitTriangle.v2 = mesh.vertices[mesh.faces[face, 2]] + object3D.transform.Location; hitTriangle.vn0 = mesh.vertexNormalCoords[mesh.vertexNormals[face, 0]]; hitTriangle.vn1 = mesh.vertexNormalCoords[mesh.vertexNormals[face, 1]]; hitTriangle.vn2 = mesh.vertexNormalCoords[mesh.vertexNormals[face, 2]]; hitTriangle.uv0 = mesh.uvcoords[mesh.uvs[face, 0]]; hitTriangle.uv1 = mesh.uvcoords[mesh.uvs[face, 1]]; hitTriangle.uv2 = mesh.uvcoords[mesh.uvs[face, 2]]; hitTriangle.normal = mesh.faceNormals[face]; barycentricCoords = hitTriangle.GetBarycentricCoordinates(pt, out bool inTri); if (inTri) { hit = new RayCastHit { hit = pt, barycentricCoordinates = barycentricCoords, collider = this, distance = t, normal = (smoothMesh ? hitTriangle.NormalAt(pt) : hitTriangle.normal), triangle = hitTriangle }; return(true); } } hit = null; return(false); }
public static bool RayCast(Ray ray, out RayCastHit hit) { if (RayCastAll(ray, out RayCastHit[] hits))