#include "munga.h" #pragma hdrstop #include "boxsolid.h" #include "plane.h" #include "line.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampContainsLine( Line *line, const Plane& plane, Scalar enters, Scalar leaves ) { // //------------------------------------------------------------------------ // Find the perpendicular distance from the origin of the ray to the ramp, // and find the direction of the ray relative to the ramp //------------------------------------------------------------------------ // Scalar distance = plane.DistanceTo(line->origin); Scalar drift = line->direction*plane.normal; // //-------------------------------------------------------------------------- // If the ray is going out of the ramp and the origin of the // ray is in the half-space that the plane's normal points to //-------------------------------------------------------------------------- // if (drift > 0 && distance > 0) { return False; } // //-------------------------------------------------------------------------- // If the ray is parallel to the ramp, the ray will hit if the origin of the // ray is not in the half-space that the plane's normal points to //-------------------------------------------------------------------------- // if (!drift) { if (distance <= 0.0f) { line->length = Max(enters, 0.0f); return True; } return False; } // //-------------------------------------------------------------------- // Otherwise, if the plane faces the ray, check to see how far the ray // travels before hitting it //-------------------------------------------------------------------- // if (drift < 0.0f) { distance /= -drift; // //----------------------------------------------------------------------- // If the ray strikes the plane after all other facing surfaces, then the // ray enters the solid through this plane. So check to make sure that // the ray does not miss the plane as clipped by the other surfaces, and // if it hits, return this distance as the projection length. If the ray // enters the ramp through an edge face of the bounding box, set the line // length to the entering value calculated for the box //----------------------------------------------------------------------- // if (distance > enters) { if (distance > leaves || distance > line->length) { return False; } enters = distance; } line->length = Max(enters, 0.0f); return True; } // //------------------------------------------------------------------------ // If the plane faces away from the ray, check to see how far the ray // travels before exiting it, and ensure this is not before the ray enters // the object //------------------------------------------------------------------------ // distance /= -drift; if (distance >= enters) { line->length = Max(enters, 0.0f); return True; } return False; } //############################################################################# //######################### BoxedRampFacingNegativeZ #################### //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingNegativeZ::BoxedRampFacingNegativeZ( const ExtentBox &extents, BoxedSolid::Material material, Simulation *owner, BoxedSolid *next_solid ): BoxedSolid(extents, RampFacingNegativeZType, material, owner, next_solid) { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingNegativeZ::~BoxedRampFacingNegativeZ() { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeZ::IntersectsBounded(const ExtentBox &extents) { Check(this); Check(&extents); Verify(minX <= extents.minX); Verify(maxX >= extents.maxX); Verify(minY <= extents.minY); Verify(maxY >= extents.maxY); Verify(minZ <= extents.minZ); Verify(maxZ >= extents.maxZ); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar rise = maxY - minY; Scalar run = minZ - maxZ; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar y = extents.minY - minY; Scalar z = extents.minZ - maxZ; // //------------------------------------------------------------------------ // If the slope rise/run is more negative than y/z slope, then the extent // box of the disk has clipped the ramp. Note that rise/run <= y/z yields // rise*z <= y*run, which avoids any divide-by-0 errors. //------------------------------------------------------------------------ // return z*rise <= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeZ::ContainsBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(maxY >= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar rise = maxY - minY; Scalar run = minZ - maxZ; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar y = point.y - minY; Scalar z = point.z - maxZ; // //------------------------------------------------------------------------ // If the slope rise/run is more negative than y/z slope, then the extent // box of the disk has clipped the ramp. Note that rise/run <= y/z yields // rise*z <= y*run, which avoids any divide-by-0 errors //------------------------------------------------------------------------ // return z*rise <= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Scalar BoxedRampFacingNegativeZ::FindDistanceBelowBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin. If the run is zero, make sure no divide by zero // happens //---------------------------------------------------------------------- // Scalar rise = maxY - minY; Scalar run = minZ - maxZ; Verify(!Small_Enough(run)); // //---------------------------------------------------------- // Get the point coordinates local the the start of the ramp //---------------------------------------------------------- // Scalar y = point.y - minY; Scalar z = point.z - maxZ; // //------------------------------------------------------------------- // Return the distance from the point to where it intersects the ramp //------------------------------------------------------------------- // y -= (rise/run)*z; return Max(y,0.0f); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeZ::HitByBounded( Line *line, Scalar enters, Scalar leaves ) { Plane ramp; Scalar temp; // //------------------------------------------------------------------- // Make a vector pointing normal to the face of the north facing ramp //------------------------------------------------------------------- // ramp.normal.x = 0.0f; ramp.normal.y = maxZ - minZ; ramp.normal.z = maxY - minY; // //------------------------------------------------------------- // Scale the vector to a normal and figure out the plane offset //------------------------------------------------------------- // temp = ramp.normal.y*ramp.normal.y + ramp.normal.z*ramp.normal.z; Verify(!Small_Enough(temp)) temp = Sqrt(temp); ramp.normal.y /= temp; ramp.normal.z /= temp; ramp.offset = maxY*ramp.normal.y + minZ*ramp.normal.z; // //--------------------------------------------------------------------- // Now that we have added a new plane into the definition of the convex // polyhedron, call a common ramp line collider //--------------------------------------------------------------------- // return BoxedRampContainsLine(line, ramp, enters, leaves); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeZ::TestInstance() const { return solidType == RampFacingNegativeZType; } //############################################################################# //######################### BoxedRampFacingPositiveZ #################### //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingPositiveZ::BoxedRampFacingPositiveZ( const ExtentBox &extents, BoxedSolid::Material material, Simulation *owner, BoxedSolid *next_solid ): BoxedSolid(extents, RampFacingPositiveZType, material, owner, next_solid) { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingPositiveZ::~BoxedRampFacingPositiveZ() { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveZ::IntersectsBounded(const ExtentBox &extents) { Check(this); Check(&extents); Verify(minX <= extents.minX); Verify(maxX >= extents.maxX); Verify(minY <= extents.minY); Verify(maxY >= extents.maxY); Verify(minZ <= extents.minZ); Verify(maxZ >= extents.maxZ); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar rise = maxY - minY; Scalar run = maxZ - minZ; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar y = extents.minY - minY; Scalar z = extents.maxZ - minZ; // //------------------------------------------------------------------------ // If the slope rise/run is more positive than y/z slope, then the extent // box of the disk has clipped the ramp. Note that rise/run >= y/z yields // rise*z >= y*run, which avoids any divide-by-0 errors //------------------------------------------------------------------------ // return z*rise >= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveZ::ContainsBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(maxY >= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar rise = maxY - minY; Scalar run = maxZ - minZ; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar y = point.y - minY; Scalar z = point.z - minZ; // //------------------------------------------------------------------------ // If the slope rise/run is more negative than y/z slope, then the extent // box of the disk has clipped the ramp. Note that rise/run >= y/z yields // rise*z >= y*run, which avoids any divide-by-0 errors //------------------------------------------------------------------------ // return z*rise >= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Scalar BoxedRampFacingPositiveZ::FindDistanceBelowBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin. If the run is zero, make sure no divide by zero // happens //---------------------------------------------------------------------- // Scalar rise = maxY - minY; Scalar run = maxZ - minZ; Verify(!Small_Enough(run)); // //---------------------------------------------------------- // Get the point coordinates local the the start of the ramp //---------------------------------------------------------- // Scalar y = point.y - minY; Scalar z = point.z - minZ; // //------------------------------------------------------------------- // Return the distance from the point to where it intersects the ramp //------------------------------------------------------------------- // y -= (rise/run)*z; return Max(y,0.0f); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveZ::HitByBounded( Line *line, Scalar enters, Scalar leaves ) { Plane ramp; Scalar temp; // //------------------------------------------------------------------- // Make a vector pointing normal to the face of the north facing ramp //------------------------------------------------------------------- // ramp.normal.x = 0.0f; ramp.normal.y = maxZ - minZ; ramp.normal.z = minY - maxY; // //------------------------------------------------------------- // Scale the vector to a normal and figure out the plane offset //------------------------------------------------------------- // temp = ramp.normal.y*ramp.normal.y + ramp.normal.z*ramp.normal.z; Verify(!Small_Enough(temp)) temp = Sqrt(temp); ramp.normal.y /= temp; ramp.normal.z /= temp; ramp.offset = minY*ramp.normal.y + minZ*ramp.normal.z; // //--------------------------------------------------------------------- // Now that we have added a new plane into the definition of the convex // polyhedron, call a common ramp line collider //--------------------------------------------------------------------- // return BoxedRampContainsLine(line, ramp, enters, leaves); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveZ::TestInstance() const { return solidType == RampFacingPositiveZType; } //############################################################################# //######################### BoxedRampFacingNegativeX #################### //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingNegativeX::BoxedRampFacingNegativeX( const ExtentBox &extents, BoxedSolid::Material material, Simulation *owner, BoxedSolid *next_solid ): BoxedSolid(extents, RampFacingNegativeXType, material, owner, next_solid) { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingNegativeX::~BoxedRampFacingNegativeX() { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeX::IntersectsBounded(const ExtentBox &extents) { Check(this); Check(&extents); Verify(minX <= extents.minX); Verify(maxX >= extents.maxX); Verify(minY <= extents.minY); Verify(maxY >= extents.maxY); Verify(minZ <= extents.minZ); Verify(maxZ >= extents.maxZ); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar run = minX - maxX; Scalar rise = maxY - minY; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar x = extents.minX - maxX; Scalar y = extents.minY - minY; // //------------------------------------------------------------------------ // If the slope rise/run is more negative than y/x slope, then the extent // box of the disk has clipped the ramp. Note that rise/run <= y/x yields // rise*x <= y*run, which avoids any divide-by-0 errors //------------------------------------------------------------------------ // return x*rise <= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeX::ContainsBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(maxY >= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar run = minX - maxX; Scalar rise = maxY - minY; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar x = point.x - maxX; Scalar y = point.y - minY; // //------------------------------------------------------------------------ // If the slope rise/run is more negative than y/x slope, then the extent // box of the disk has clipped the ramp. Note that rise/run <= y/x yields // rise*x <= y*run, which avoids any divide-by-0 errors //------------------------------------------------------------------------ // return x*rise <= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Scalar BoxedRampFacingNegativeX::FindDistanceBelowBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin. If the run is zero, make sure no divide by zero // happens //---------------------------------------------------------------------- // Scalar run = minX - maxX; Scalar rise = maxY - minY; Verify(!Small_Enough(run)); // //---------------------------------------------------------- // Get the point coordinates local the the start of the ramp //---------------------------------------------------------- // Scalar x = point.x - maxX; Scalar y = point.y - minY; // //------------------------------------------------------------------- // Return the distance from the point to where it intersects the ramp //------------------------------------------------------------------- // y -= (rise/run)*x; return Max(y,0.0f); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeX::HitByBounded( Line *line, Scalar enters, Scalar leaves ) { Plane ramp; Scalar temp; // //------------------------------------------------------------------- // Make a vector pointing normal to the face of the north facing ramp //------------------------------------------------------------------- // ramp.normal.y = maxX - minX; ramp.normal.x = maxY - minY; ramp.normal.z = 0.0f; // //------------------------------------------------------------- // Scale the vector to a normal and figure out the plane offset //------------------------------------------------------------- // temp = ramp.normal.y*ramp.normal.y + ramp.normal.x*ramp.normal.x; Verify(!Small_Enough(temp)) temp = Sqrt(temp); ramp.normal.y /= temp; ramp.normal.x /= temp; ramp.offset = maxY*ramp.normal.y + minX*ramp.normal.x; // //--------------------------------------------------------------------- // Now that we have added a new plane into the definition of the convex // polyhedron, call a common ramp line collider //--------------------------------------------------------------------- // return BoxedRampContainsLine(line, ramp, enters, leaves); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingNegativeX::TestInstance() const { return solidType == RampFacingNegativeXType; } //############################################################################# //######################### BoxedRampFacingPositiveX #################### //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingPositiveX::BoxedRampFacingPositiveX( const ExtentBox &extents, BoxedSolid::Material material, Simulation *owner, BoxedSolid *next_solid ): BoxedSolid(extents, RampFacingPositiveXType, material, owner, next_solid) { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // BoxedRampFacingPositiveX::~BoxedRampFacingPositiveX() { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveX::IntersectsBounded(const ExtentBox &extents) { Check(this); Check(&extents); Verify(minX <= extents.minX); Verify(maxX >= extents.maxX); Verify(minY <= extents.minY); Verify(maxY >= extents.maxY); Verify(minZ <= extents.minZ); Verify(maxZ >= extents.maxZ); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar run = maxX - minX; Scalar rise = maxY - minY; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar x = extents.maxX - minX; Scalar y = extents.minY - minY; // //------------------------------------------------------------------------ // If the slope rise/run is more positive than y/x slope, then the extent // box of the disk has clipped the ramp. Note that rise/run >= y/x yields // rise*x >= x*run, which avoids any divide-by-0 errors //------------------------------------------------------------------------ // return x*rise >= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveX::ContainsBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(maxY >= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin //---------------------------------------------------------------------- // Scalar run = maxX - minX; Scalar rise = maxY - minY; Verify(!Small_Enough(run)); // //------------------------------------------------------------------- // Calculate the "slope" of the line from the base of the ramp to the // lower-north edge of the block //------------------------------------------------------------------- // Scalar x = point.x - minX; Scalar y = point.y - minY; // //------------------------------------------------------------------------ // If the slope rise/run is more negative than y/x slope, then the extent // box of the disk has clipped the ramp. Note that rise/run >= y/x yields // rise*x >= y*run, which avoids any divide-by-0 errors //------------------------------------------------------------------------ // return x*rise >= y*run; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Scalar BoxedRampFacingPositiveX::FindDistanceBelowBounded(const Point3D &point) { Check(this); Check(&point); Verify(minX <= point.x); Verify(maxX >= point.x); Verify(minY <= point.y); Verify(minZ <= point.z); Verify(maxZ >= point.z); // //---------------------------------------------------------------------- // Calculate the "slope" of the ramp when the base of the ramp is placed // at the origin. If the run is zero, make sure no divide by zero // happens //---------------------------------------------------------------------- // Scalar run = maxX - minX; Scalar rise = maxY - minY; Verify(!Small_Enough(run)); // //---------------------------------------------------------- // Get the point coordinates local the the start of the ramp //---------------------------------------------------------- // Scalar x = point.x - minX; Scalar y = point.y - minY; // //------------------------------------------------------------------- // Return the distance from the point to where it intersects the ramp //------------------------------------------------------------------- // y -= (rise/run)*x; return Max(y,0.0f); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveX::HitByBounded( Line *line, Scalar enters, Scalar leaves ) { Plane ramp; Scalar temp; // //------------------------------------------------------------------- // Make a vector pointing normal to the face of the north facing ramp //------------------------------------------------------------------- // ramp.normal.y = maxX - minX; ramp.normal.x = minY - maxY; ramp.normal.z = 0.0f; // //------------------------------------------------------------- // Scale the vector to a normal and figure out the plane offset //------------------------------------------------------------- // temp = ramp.normal.y*ramp.normal.y + ramp.normal.x*ramp.normal.x; Verify(!Small_Enough(temp)) temp = Sqrt(temp); ramp.normal.y /= temp; ramp.normal.x /= temp; ramp.offset = minY*ramp.normal.y + minX*ramp.normal.x; // //--------------------------------------------------------------------- // Now that we have added a new plane into the definition of the convex // polyhedron, call a common ramp line collider //--------------------------------------------------------------------- // return BoxedRampContainsLine(line, ramp, enters, leaves); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical BoxedRampFacingPositiveX::TestInstance() const { return solidType == RampFacingPositiveXType; }