public bool IsVisible(Vector3 from, Vector3 to) { Vector3 direction = to - from; float distance = direction.Length(); var ray = new Ray(from, direction); return IsVisible(ray, distance); }
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; }
public Intersection FirstIntersect(Ray ray) { //return from thing in Objects // select thing.Intersect(ray); return Objects .Select(obj => obj.Intersect(ray)) .Where(inter => inter != null) .OrderBy(inter => inter.Dist) .FirstOrDefault(); }
public Vector3 SampleColor(Ray ray, int maxRecursiveRaycasts) { RaycastHit raycastHit = null; bool hitFound = Raycast(ray, float.MaxValue, ref raycastHit); if (!hitFound) { return _skyColor; } return raycastHit.Mesh.SampleColor(this, raycastHit, maxRecursiveRaycasts); }
/// <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 IsVisible(Ray ray, float distance) { float dist = distance - 0.001f; foreach (Mesh mesh in _meshes) { #if DEBUG Interlocked.Increment(ref Counters.BoundingBoxHits); #endif RaycastHit meshHit = null; bool hitFound = mesh.Raycast(ray, dist, ref meshHit); if (hitFound) { return false; } } return true; }
public static Color TraceRay(Vector3 start, Vector3 dir, Scene scene, int depth_) { if (depth_ >= scene.MaxRayDepth) { return scene.Ambient; } Ray ray = new Ray() { Start = start, Dir = dir }; Intersection isect = scene.FirstIntersect(ray); if (null == isect) { return scene.Background; } //todo light hit Surface surf = isect.Thing.Surface; Vector3 pos = isect.Ray.Start + isect.Dist * isect.Ray.Dir; Vector3 invRayDir = -isect.Ray.Dir; Vector3 normal = isect.Thing.Normal(pos, isect.Inside); Vector3 reflect = Vector3.Reflect(normal, invRayDir); Color ambient = scene.Ambient; Color local = LocalLighting(surf, pos, normal, reflect, scene); float refl = surf.Reflect(pos); float alpha = surf.Alpha(pos); Color reflected = Color.Black(); if (0 < refl && 0 < alpha) { reflected = TraceRay(pos + .001 * reflect, reflect, scene, depth_ + 1) * refl; } Color transmitted = Color.Black(); if (1 > alpha) { double eta = isect.Inside ? 1 / surf.Eta : surf.Eta; Vector3 transmit = Vector3.Refract(normal, invRayDir, eta); transmitted = TraceRay(pos + .001 * transmit, transmit, scene, depth_ + 1); } return ambient + (local + reflected) * alpha + transmitted * (1 - alpha); }
public bool Raycast(Ray ray, float maxDistance, ref RaycastHit hitInfo) { float closestHitDistance = maxDistance; bool hitFound = false; foreach (Mesh mesh in _meshes) { #if DEBUG Interlocked.Increment(ref Counters.BoundingBoxHits); #endif RaycastHit meshHit = null; bool hit = mesh.Raycast(ray, closestHitDistance, ref meshHit); if (hit) { hitInfo = meshHit; closestHitDistance = meshHit.Distance; hitFound = true; } } return hitFound; }
public override Intersection Intersect(Ray ray) { Vector3 l = Center-ray.Start; double s = Vector3.Dot(l, ray.Dir); double l2 = Vector3.Dot(l, l); double r2 = Radius*Radius; bool outside = l2 > r2; if (0 > s && outside) return null; double m2 = l2 - s * s; if (m2 > r2) return null; double q = Math.Sqrt(r2 - m2); double t = outside ? s-q : s+q; return new Intersection() { Thing = this, Ray = ray, Dist = t, Inside = !outside }; }
public bool Raycast(Ray ray, float maxDistance) { #if DEBUG Interlocked.Increment(ref Counters.BoundingBoxChecks); #endif float tMin; float tMax; float rayDirectionXInverse = 1 / ray.Direction.x; if (rayDirectionXInverse >= 0) { tMin = (_minX - ray.Origin.x) * rayDirectionXInverse; tMax = (_maxX - ray.Origin.x) * rayDirectionXInverse; } else { tMax = (_minX - ray.Origin.x) * rayDirectionXInverse; tMin = (_maxX - ray.Origin.x) * rayDirectionXInverse; } float tyMin; float tyMax; float rayDirectionYInverse = 1 / ray.Direction.y; if (rayDirectionYInverse >= 0) { tyMin = (_minY - ray.Origin.y) * rayDirectionYInverse; tyMax = (_maxY - ray.Origin.y) * rayDirectionYInverse; } else { tyMax = (_minY - ray.Origin.y) * rayDirectionYInverse; tyMin = (_maxY - ray.Origin.y) * rayDirectionYInverse; } if ((tMin > tyMax) || (tyMin > tMax)) { return false; } if (tyMin > tMin) { tMin = tyMin; } if (tyMax < tMax) { tMax = tyMax; } float tzMin; float tzMax; float rayDirectionZInverse = 1 / ray.Direction.z; if (rayDirectionZInverse >= 0) { tzMin = (_minZ - ray.Origin.z) * rayDirectionZInverse; tzMax = (_maxZ - ray.Origin.z) * rayDirectionZInverse; } else { tzMax = (_minZ - ray.Origin.z) * rayDirectionZInverse; tzMin = (_maxZ - ray.Origin.z) * rayDirectionZInverse; } if (tMin > tzMax || tzMin > tMax) { return false; } if (tzMin > tMin) { tMin = tzMin; } if (tzMax < tMax) { tMax = tzMax; } if (tMax < tMin || tMax < 0 || tMin > maxDistance) { return false; } 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; }