示例#1
0
 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);
 }
示例#2
0
        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;
        }
示例#3
0
 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();
 }
示例#4
0
 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);
 }
示例#5
0
        /// <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;
        }
示例#6
0
        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;
        }
示例#7
0
        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);
        }
示例#8
0
        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;
        }
示例#9
0
        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
            };
        }
示例#10
0
        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;
        }
示例#11
0
        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;
        }