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() ); }
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); } }
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); }