//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef DISPCOLL_H #define DISPCOLL_H #pragma once #include "mathlib/vector.h" class CCoreDispInfo; //============================================================================= // // Displacement Collision Triangle Data // class CDispCollTri { public: void Init(void); inline void SetPoint(int index, Vector const &vert); inline void SetPointNormal(int index, Vector const &normal); void CalcPlane(void); inline void SetIntersect(bool bIntersect); inline bool IsIntersect(void); Vector m_Points[3]; // polygon points Vector m_PointNormals[3]; // polygon point normals Vector m_Normal; // plane normal float m_Distance; // plane distance short m_ProjAxes[2]; // projection axes (2 minor axes) bool m_bIntersect; // intersected triangle??? }; //============================================================================= // // Displacement Collision Node Data // class CDispCollNode { public: CDispCollNode(); inline bool IsLeaf(void); inline void SetBounds(Vector const &bMin, Vector const &bMax); inline void GetBounds(Vector &bMin, Vector &bMax); Vector m_Bounds[2]; // node minimum and maximum bool m_bIsLeaf; // is the node a leaf? ( may have to make this an int for // alignment!) CDispCollTri m_Tris[2]; // two triangles contained in leaf node }; //============================================================================= // // Displacement Collision Data // class CDispCollData { public: Vector m_StartPos; Vector m_EndPos; Vector m_Extents; float m_Fraction; int m_Contents; Vector m_Normal; float m_Distance; bool m_bOcclude; }; // HACKHACK: JAY: Moved this out of CDispCollTree to be thread safe in vrad enum { TRILIST_CACHE_SIZE = 128 }; class CDispCollTreeTempData { public: // // temps // int m_TriListCount; CDispCollTri *m_ppTriList[TRILIST_CACHE_SIZE]; // collision tree node cache float m_AABBDistances[6]; }; //============================================================================= // // Displacement Collision Tree // class CDispCollTree { public: static const float COLLISION_EPSILON; static const float ONE_MINUS_COLLISION_EPSILON; //========================================================================= // // Creation/Destruction // CDispCollTree(); ~CDispCollTree(); virtual bool Create(CCoreDispInfo *pDisp); //========================================================================= // // Collision Functions // bool RayTest(CDispCollData *pData); bool RayTestAllTris(CDispCollData *pData, int power); bool AABBIntersect(CDispCollData *pData); bool AABBSweep(CDispCollData *pData); //========================================================================= // // Attrib Functions // inline void SetPower(int power); inline int GetPower(void); inline void SetCheckCount(int count); inline int GetCheckCount(void); inline void GetBounds(Vector &boundMin, Vector &boundMax); protected: int m_Power; int m_NodeCount; CDispCollNode *m_pNodes; int m_CheckCount; // collision tree node cache Vector m_AABBNormals[6]; //========================================================================= // // Creation/Destruction // void InitAABBData(void); void InitLeaves(CCoreDispInfo *pDisp); void CreateNodes(CCoreDispInfo *pDisp); void CreateNodes_r(CCoreDispInfo *pDisp, int nodeIndex, int termLevel); void CalcBounds(CDispCollNode *pNode, int nodeIndex); //========================================================================= // // Collision Functions // void CreatePlanesFromBounds(CDispCollTreeTempData *pTemp, Vector const &bbMin, Vector const &bbMax); // void RayNodeTest_r( int nodeIndex, Vector &rayStart, Vector &rayEnd ); void RayNodeTest_r(CDispCollTreeTempData *pTemp, int nodeIndex, Vector rayStart, Vector rayEnd); bool RayAABBTest(CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd); bool RayTriListTest(CDispCollTreeTempData *pTemp, CDispCollData *pData); bool RayTriTest(Vector const &rayStart, Vector const &rayDir, float const rayLength, CDispCollTri const *pTri, float *fraction); void BuildTriList_r(CDispCollTreeTempData *pTemp, int nodeIndex, Vector &rayStart, Vector &rayEnd, Vector &extents, bool bIntersect); bool IntersectAABBAABBTest(CDispCollTreeTempData *pTemp, const Vector &pos, const Vector &extents); bool SweptAABBAABBTest(CDispCollTreeTempData *pTemp, const Vector &rayStart, const Vector &rayEnd, const Vector &extents); bool CullTriList(CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd, Vector &extents, bool bIntersect); bool SweptAABBTriTest(Vector &rayStart, Vector &rayEnd, Vector &extents, CDispCollTri const *pTri); bool AABBTriIntersect(CDispCollTreeTempData *pTemp, CDispCollData *pData); bool IntersectAABBTriTest(Vector &rayStart, Vector &extents, CDispCollTri const *pTri); bool SweptAABBTriIntersect(Vector &rayStart, Vector &rayEnd, Vector &extents, CDispCollTri const *pTri, Vector &plNormal, float *plDist, float *fraction); //========================================================================= // // Memory Functions // bool AllocNodes(int nodeCount); void FreeNodes(void); //========================================================================= // // Utility Functions // inline int CalcNodeCount(int power); inline int GetParentNode(int nodeIndex); inline int GetChildNode(int nodeIndex, int direction); inline int GetNodeLevel(int nodeIndex); int GetNodeIndexFromComponents(int x, int y); }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- inline void CDispCollTree::SetPower(int power) { m_Power = power; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- inline int CDispCollTree::GetPower(void) { return m_Power; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- inline void CDispCollTree::SetCheckCount(int count) { m_CheckCount = count; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- inline int CDispCollTree::GetCheckCount(void) { return m_CheckCount; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- inline void CDispCollTree::GetBounds(Vector &boundMin, Vector &boundMax) { boundMin[0] = m_pNodes[0].m_Bounds[0].x; boundMin[1] = m_pNodes[0].m_Bounds[0].y; boundMin[2] = m_pNodes[0].m_Bounds[0].z; boundMax[0] = m_pNodes[0].m_Bounds[1].x; boundMax[1] = m_pNodes[0].m_Bounds[1].y; boundMax[2] = m_pNodes[0].m_Bounds[1].z; } #endif // DISPCOLL_H