public bool Raycast(Ray ray, ref RayTriangleHit closestRayTriangleHitInfo, ref Triangle closestTriangle) { if (!_boundingBox.Raycast(ray, closestRayTriangleHitInfo.Distance)) return false; bool hitFound = false; var hitInfo = new RayTriangleHit(); foreach (Triangle triangle in _directTriangleChildren) { if (triangle.RayCast(ray, ref hitInfo) && (closestRayTriangleHitInfo.Distance > hitInfo.Distance)) { closestRayTriangleHitInfo = hitInfo; closestTriangle = triangle; hitFound = true; } } for (int i = 0; i < 8; i++) { if (_children[i] != null) { bool childHit = _children[i].Raycast(ray, ref closestRayTriangleHitInfo, ref closestTriangle); hitFound |= childHit; } } return hitFound; }
/// <summary> /// Casts a ray against mesh /// </summary> /// <param name="ray">Ray to be cast</param> /// <param name="maxDistance">Maximum distance to trace ray</param> /// <param name="hitInfo">Will contain hit information if true is returned</param> /// <returns>Distance along the ray the hit was found</returns> public bool Raycast(Ray ray, float maxDistance, ref RaycastHit hitInfo) { #if DEBUG Interlocked.Increment(ref Counters.RaysCast); #endif var localRayDirection = ray.Direction.RotatedBy(_invRotation); var localRayOrigin = (ray.Origin - Position).RotatedBy(_invRotation); var localRay = new Ray(localRayOrigin, localRayDirection); var hit = new RayTriangleHit {Distance = maxDistance}; Triangle closestTriangle = null; bool hitFound = _octree.Raycast(localRay, ref hit, ref closestTriangle); if (!hitFound) return false; Vector3 normal = _normalSampler.Sample(closestTriangle, hit.U, hit.V).RotatedBy(_rotation); hitInfo = new RaycastHit(hit, closestTriangle, this, ray, normal); return true; }
public bool RayCast(Ray ray, ref RayTriangleHit hitInfo) { #if DEBUG Interlocked.Increment(ref Counters.RayTriangleTests); #endif if (Vector3.IsDotGreaterThanZero(Normal, ray.Direction)) { #if DEBUG Interlocked.Increment(ref Counters.BackfaceCulls); #endif return false; } Vector3 pVec = Vector3.Cross(ray.Direction, _edge2); float determinant = Vector3.Dot(_edge1, pVec); // ReSharper disable once CompareOfFloatsByEqualityOperator float invDeterminant = 1 / determinant; Vector3 tVec = ray.Origin - V1; float u = Vector3.Dot(tVec, pVec) * invDeterminant; if (u < 0 || u > 1) return false; Vector3 qVec = Vector3.Cross(tVec, _edge1); float v = Vector3.Dot(ray.Direction, qVec) * invDeterminant; if (v < 0 || u + v > 1) return false; float distance = Vector3.Dot(_edge2, qVec) * invDeterminant; if (distance < 0) return false; hitInfo.U = u; hitInfo.V = v; hitInfo.Distance = distance; #if DEBUG Interlocked.Increment(ref Counters.RayHits); #endif return true; }