This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

230 lines
7.7 KiB
C++

//========= 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