Пример #1
0
 Point3DTestResult Intersects(const Plane& Surface, const Ray& Cast)
 {
     // Code in this function is based on the equivalent in Ogre
     Real Denom = Surface.Normal.DotProduct( Cast.GetNormal() );// + Surface.Distance;
     if( MathTools::Abs(Denom) < std::numeric_limits<Real>::epsilon() ) {
         return Point3DTestResult( false, Vector3() );
     }else{
         Real Nom = Surface.Normal.DotProduct( Cast.GetOrigin() ) + Surface.Distance;
         Real Distance = -( Nom / Denom );
         return Point3DTestResult( true, Cast.GetOrigin() + ( Cast.GetNormal() * Distance) );
     }
     return Point3DTestResult( false, Vector3() );
 }
Пример #2
0
        GeometryRayTestResult Intersects(const Sphere& Ball, const Ray& Cast)
        {
            // Code in this function is based on the equivalent in Ogre
            const Vector3 CastDir = Cast.GetNormal();
            const Vector3 CastOrigin = Cast.GetOrigin() - Ball.Center; // Makes math easier to do this in sphere local coordinates
            const Real Radius = Ball.Radius;

            // Build coefficients for our formula
            // t = (-b +/- sqrt(b*b + 4ac)) / 2a
            Real ACoEff = CastDir.DotProduct(CastDir);
            Real BCoEff = 2 * CastOrigin.DotProduct(CastDir);
            Real CCoEff = CastOrigin.DotProduct(CastOrigin) - ( Radius * Radius );

            // Get the Determinate
            Real Determinate = ( BCoEff * BCoEff ) - ( 4 * ACoEff * CCoEff );
            if( Determinate < 0 ) {
                return GeometryRayTestResult(false,Ray());
            }else{
                Real NearDist = ( -BCoEff - MathTools::Sqrt( Determinate ) ) / ( 2 * ACoEff );
                Real FarDist = ( -BCoEff + MathTools::Sqrt( Determinate ) ) / ( 2 * ACoEff );

                Ray Ret( Cast.GetOrigin() + (CastDir * NearDist), Cast.GetOrigin() + (CastDir * FarDist) );
                return GeometryRayTestResult(true,Ret);
            }
        }
Пример #3
0
        GeometryRayTestResult Intersects(const AxisAlignedBox& Box, const Ray& Cast)
        {
            // Code in this function is based on the equivalent in Ogre
            Vector3 CastDir = Cast.GetNormal();
            Vector3 AbsoluteDir = CastDir;
            AbsoluteDir.X = MathTools::Abs( AbsoluteDir.X );
            AbsoluteDir.Y = MathTools::Abs( AbsoluteDir.Y );
            AbsoluteDir.Z = MathTools::Abs( AbsoluteDir.Z );

            // A small fixed sized constant time sorting algorithm for sorting the length of each axis.
            Whole MaxAxis = 0, MidAxis = 1, MinAxis = 2;
            if( AbsoluteDir[0] < AbsoluteDir[2] ) {
                MaxAxis = 2;
                MinAxis = 1;
            }else if( AbsoluteDir[1] < AbsoluteDir[MinAxis] ) {
                MidAxis = MinAxis;
                MinAxis = 1;
            }else if( AbsoluteDir[1] > AbsoluteDir[MaxAxis] ) {
                MidAxis = MaxAxis;
                MaxAxis = 1;
            }

            if(IsInside(Box,Cast.Origin))
            {
                Vector3 Intersects;
                Intersects[MinAxis] = 0;
                Intersects[MidAxis] = 0;
                Intersects[MaxAxis] = 1;
                /*Plane Side(Intersects,)
                if(CastDir[MaxAxis]>0)
                {

                }else{

                }
                return GeometryRayTestResult(true,Ray(,Vector3));*/
            }

            SegmentPosPair Distances(0,std::numeric_limits<Real>::infinity());

            ::CalculateAxis(MaxAxis,Cast,Box,Distances);
            if( AbsoluteDir[MidAxis] < std::numeric_limits<Real>::epsilon() ) {
                if( Cast.GetOrigin()[MidAxis] < Box.MinExt[MidAxis] || Cast.GetOrigin()[MidAxis] > Box.MaxExt[MidAxis] ||
                    Cast.GetOrigin()[MinAxis] < Box.MinExt[MinAxis] || Cast.GetOrigin()[MinAxis] > Box.MaxExt[MinAxis] )
                {
                    return GeometryRayTestResult(false,Ray());
                }
            }else{
                ::CalculateAxis(MidAxis,Cast,Box,Distances);
                if( AbsoluteDir[MinAxis] < std::numeric_limits<Real>::epsilon() ) {
                    if( Cast.GetOrigin()[MinAxis] < Box.MinExt[MinAxis] || Cast.GetOrigin()[MinAxis] > Box.MaxExt[MinAxis] ) {
                        return GeometryRayTestResult(false,Ray());
                    }
                }else{
                    ::CalculateAxis(MinAxis,Cast,Box,Distances);
                }
            }

            Ray Ret( Cast.GetOrigin() + (CastDir * Distances.first), Cast.GetOrigin() + (CastDir * Distances.second) );
            return GeometryRayTestResult(true,Ret);
        }