Esempio n. 1
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;
        }
Esempio n. 2
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;
        }
Esempio n. 3
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;
        }