www.pudn.com > RCApp-src.zip > Collision.h
/* RedEye Project (http://members.ozemail.com.au/~ndmcevoy/) Copyright (C) 2003 Nick McEvoy This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------- Commented for use with Doxygen (http://www.doxygen.org) ----------------------------------------------------------------- */ /*! \file Collision.h * \brief Collision detection methods. * * This file contains methods for collision detection. * * Thanks to the following for code: * - DigiBen (DigiBen@GameTutorials.com) * - Steve Baker (http://www.sjbaker.org) * - Tomas Akenine-Möller (Fast 3D Triangle-Box Overlap Testing - tribox.cpp) * http://www.acm.org/jgt/papers/AkenineMoller01/tribox.html * http://www.ce.chalmers.se/staff/tomasm/pubs/tribox.pdf */ #ifndef _RE_GAME_COLLISION_H_ #define _RE_GAME_COLLISION_H_ // PLIB includes #include// ODE includes #include "ode/common.h" #define HIGHEST_HEAVEN 1000000.0f #define DEEPEST_HELL -1000000.0f // Code adapted from Steve Baker (TuxKart & TuxAQFH) static void pr_from_normal(sgVec3 hpr, sgVec3 nrm) { float sy = (float)sin(-hpr[0]*SG_DEGREES_TO_RADIANS); float cy = (float)cos(-hpr[0]*SG_DEGREES_TO_RADIANS); hpr[2] = SG_RADIANS_TO_DEGREES*((float)atan2(nrm[0]* cy - nrm[1]*sy, nrm[2])); hpr[1] = -SG_RADIANS_TO_DEGREES*((float)atan2(nrm[1]* cy + nrm[0]*sy, nrm[2])); } // Code adapted from Steve Baker (TuxKart & TuxAQFH) static void hpr_from_normal(sgVec3 hpr, sgVec3 nrm) { pr_from_normal(hpr, nrm); hpr[0] = -SG_RADIANS_TO_DEGREES*((float)atan2(nrm[0], nrm[1])); } void reGetBodyTransform(ssgTransform* dest, dBodyID src); void reGetBodyPosition(sgVec3 dest, dBodyID src); void reGetBodyVelocity(sgVec3 dest, dBodyID src); //! Generates ODE contacts of 'hit' triangles agains a sphere. /*! * This service returns true if any contacts are generated. * The hit list may be obtained from bounding sphere check * using plib's ssgIsect() routine. * * \param iNumHits - number of hits in hit list * \param pHitList - hit list (of triangles) * \param SphereBody - ODE sphere body * \param SphereGeom - ODE sphere geometry * \return true if contacts generated, else false */ bool reTriangleSphereContact(int iNumHits, ssgHit* pHitList, dBodyID SphereBody, dGeomID SphereGeom); //! Generates ODE contacts of 'hit' triangles agains a box. /*! * This service returns true if any contacts are generated. * The hit list may be obtained from bounding sphere check * using plib's ssgIsect() routine. * * \param iNumHits - number of hits in hit list * \param pHitList - hit list (of triangles) * \param BoxBody - ODE box body * \param BoxGeom - ODE box geometry * \return true if contacts generated, else false */ bool reTriangleBoxContact(int iNumHits, ssgHit* pHitList, dBodyID BoxBody, dGeomID BoxGeom); //! Returns HOT (Height Of Terrain). /*! * This service returns the HOT (Height Of Terrain) and the normal * of the nearest polygon *beneath* a given position. * * \param pScene - scene * \param vMyPosition - position in the scene * \return vNormal - normal of nearest polygon *beneath* the position * \return HOT (Height Of Terrain) */ float reGetHeightAndNormal(ssgRoot* pScene, const sgVec3 vMyPosition, sgVec3 vNormal, ssgHit** pHit); //! Returns HOT (Height Of Terrain). /*! * This service returns the HOT (Height Of Terrain) * of the nearest polygon *beneath* a given position. * * \param pScene - scene * \param vMyPosition - position in the scene * \return HOT (Height Of Terrain) */ inline float reGetHeight(ssgRoot* pScene, sgVec3 vMyPosition) { ssgHit* pHit; return reGetHeightAndNormal(pScene, vMyPosition, NULL, &pHit); } //! Returns altitude above terrain. /*! * This service returns the altitude above terrain. * * \param pScene - scene * \param vMyPosition - position in the scene * \return altitude */ inline float reGetAltitude(ssgRoot* pScene, const sgVec3 vMyPosition) { ssgHit* pHit; float fHOT = reGetHeightAndNormal(pScene, vMyPosition, NULL, &pHit); return vMyPosition[SG_Z] - fHOT; } //! Returns triangle normal. /*! * This service returns the normal of a triangle (ie. the direction * that the triangle is facing). * * \param vTriangle - triangle * \return vNormal - triangle normal */ void reNormal(sgVec3 vNormal, const sgVec3 vTriangle[3]); //! Returns distance between plane and origin. /*! * This service returns the distance between a plane and the origin. * * \param vNormal - plane normal * \return vPoint - point on the plane */ float rePlaneDistance(const sgVec3 vNormal, const sgVec3 vPoint); //! Returns plane definition. /*! * This service returns the plane definition. * * Plane equation Ax + By + Cz + D = 0 * Where ABC = plane normal, xyz = point on plane & D = plane distance from origin * * vPlane[0,1,2] = ABC * vPlane[3] = D * * \param vTriangle - 3 points on the plane * \param vNormal - plane normal (can be set NULL) * \return vPlane - plane */ void reDefinePlane(const sgVec3 vTriangle[3], const sgVec3 vNormal, sgVec4 vPlane); //! Returns true if line intersects a plane. /*! * This service returns true if line intersects a plane. * * \param vLine - line * \param vPlane - plane * \return true if line intersects, else false */ bool reLineIntersectsPlane(const sgVec3 vLine[2], const sgVec4 vPlane); //! Returns line-plane intersection point. /*! * This service returns true if line intersects a plane, also returns * the intersection point. * * \param vLine - line * \param vPlane - plane * \return vPoint - intersection point * \return true if intersects, else false */ bool reLinePlaneIntersectionPoint(const sgVec3 vLine[2], const sgVec4 vPlane, sgVec3 vPoint); //! Returns line-triangle intersection point. /*! * This service returns true if line intersects a triangle, also returns * the intersection point. * * \param vLine - line * \param vTriangle - triangle * \param vNormal - triangle normal (can be set NULL) * \return vPoint - intersection point * \return true if intersects, else false */ bool reLineTriangleIntersectionPoint(const sgVec3 vLine[2], const sgVec3 vTriangle[3], const sgVec3 vNormal, sgVec3 vPoint); //! Returns a point on a line closest to a given point. /*! * This service returns a point on the line that is closest to a point. * * \param vLine - line * \param vPoint - point * \return vLinePoint - point on line closest to point */ void reClosestPointOnLine(const sgVec3 vLine[2], const sgVec3 vPoint, sgVec3 vLinePoint); //! Returns true point is inside a polygon. /*! * This service returns true if a point is inside the ranges of a * polygon. * * \param vPoint - point on poly * \param vPoly - polygon points * \param iVertexCount - number of polygon points * \return true if point is inside polygon, else false */ bool reInsidePolygon(const sgVec3 vPoint, const sgVec3 vPoly[], int iVertexCount); //! Returns true if sphere intersects edges of a polygon. /*! * This service returns true if the sphere is intersecting any of the * edges of a polygon. * * \param vCenter - sphere center * \param vPoly - polygon points * \param iVertexCount - number of polygon points * \param fRadius - sphere radius * \return true if sphere intersects edges polygon, else false */ bool reEdgeSphereCollision(const sgVec3 vCenter, const sgVec3 vPoly[], int iVertexCount, float fRadius); //! Returns true if sphere is *between* edge planes of a triangle. /*! * This service returns true if the sphere is *between* the edge * planes of a triangle. * * \param vCenter - sphere center * \param vTriangle - triangle * \param vNormal - triangle normal * \param fRadius - sphere radius * \return true if sphere *between* edge planes of triangle, else false */ bool reEdgePlanesCollision(const sgVec3 vCenter, const sgVec3 vTriangle[], const sgVec3 vNormal, float fRadius); //! Returns if sphere is BEHIND, in FRONT, or INTERSECTS a plane. /*! * This service returns if sphere is BEHIND, in FRONT, or INTERSECTS * a plane, also returns it's distance from the plane. * * \param vCenter - sphere center * \param vNormal - plane normal * \param vPoint - point on plane * \param fRadius - sphere radius * \return fDistance - distance from sphere center to plane point * \return 0 = BEHIND, 1 = in FRONT, 2 = INTERSECTS */ int reClassifySphere(const sgVec3 vCenter, const sgVec3 vNormal, const sgVec3 vPoint, float fRadius, float& fDistance); //! Returns triangle-sphere intersection point. /*! * This service returns true if triangle intersects a sphere, also returns * the intersection point and depth of penetration. * * \param vSphereCenter - sphere center * \param fSphereRadius - sphere radius * \param vTriangle - triangle * \param vNormal - triangle normal (can be set NULL) * \return vPoint - intersection point * \return fDepth - depth of penetration * \return true if intersects, else false */ bool reTriangleSphereIntersectionPoint(const sgVec3 vSphereCenter, float fSphereRadius, const sgVec3 vTriangle[3], const sgVec3 vNormal, sgVec3 vPoint, float& fDepth); #endif // _RE_GAME_COLLISION_H_