Ejemplo n.º 1
0
        private CollisionDetails GetFirstCollisionInternal(Shapes.Ray ray, bool isRayInside, bool useBiggerX, bool useBiggerY, bool useBiggerZ)
        {
            var result = new CollisionDetails {
                Distance = double.PositiveInfinity
            };

            if (isRayInside) // recheck because ray was inside parent
            {
                isRayInside = PointCube.Encloses(_center, _halfWidth, ray.Origin);
            }

            // not inside and no hit -> return
            if (!isRayInside && double.IsInfinity(RayIntersectionDistance(ray, useBiggerX, useBiggerY, useBiggerZ)))
            {
                return(result);
            }


            if (_children != null && _children.Length > 0)
            {
                foreach (var child in _children)
                {
                    var collision = child.GetFirstCollisionInternal(ray, isRayInside, useBiggerX, useBiggerY, useBiggerZ);
                    if (!double.IsInfinity(collision.Distance))
                    {
                        result = collision;
                        break;
                    }
                }
            }

            foreach (var o3D in _objects)
            {
                double distance = o3D.GetHitPointDistance(ray);
                if (distance > 0 && distance < result.Distance)
                {
                    result.Obj      = o3D;
                    result.Distance = distance;
                }
            }

            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get the nearest intersection with the cube
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="useBiggerX"></param>
        /// <param name="useBiggerY"></param>
        /// <param name="useBiggerZ"></param>
        /// <returns></returns>
        private double RayIntersectionDistance(Shapes.Ray ray, bool useBiggerX, bool useBiggerY, bool useBiggerZ)
        {
            if (PointCube.Encloses(_center, _halfWidth, ray.Origin))
            {
                return(0);
            }

            var normal = new Vect3 {
                X = useBiggerX ? _halfWidth : -_halfWidth
            };
            var    planeCenter = _center + normal;
            double distance    = SideRayIntersectionDistance(ray, normal, planeCenter);

            // we can return instantly as we only evaluate the hear side -> only one side should be hit at any time
            if (!double.IsInfinity(distance))
            {
                return(distance);
            }

            normal = new Vect3 {
                Y = useBiggerY ? _halfWidth : -_halfWidth
            };
            planeCenter = _center + normal;
            distance    = SideRayIntersectionDistance(ray, normal, planeCenter);
            if (!double.IsInfinity(distance))
            {
                return(distance);
            }

            normal = new Vect3 {
                Z = useBiggerZ ? _halfWidth : -_halfWidth
            };
            planeCenter = _center + normal;
            distance    = SideRayIntersectionDistance(ray, normal, planeCenter);
            if (!double.IsInfinity(distance))
            {
                return(distance);
            }

            return(double.PositiveInfinity);
        }
Ejemplo n.º 3
0
 /**
  * @param v a <code>Vect3</code> representing a point
  * @return true if, and only if, <code>v</code> is enclosed by this subtree.
  */
 public bool Encloses(Vect3 v)
 {
     return(PointCube.Encloses(Center, Width / 2 + Constants.EPS, v));
 }