mirror of
https://github.com/0TheSpy/Seaside.git
synced 2025-01-07 10:03:29 +08:00
380 lines
9.8 KiB
C++
380 lines
9.8 KiB
C++
#ifndef COLLISIONPROPERTY_H
|
|
#define COLLISIONPROPERTY_H
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "networkvar.h"
|
|
#include "ICollideable.h"
|
|
#include "vector.h"
|
|
#include "ispatialpartition.h"
|
|
|
|
|
|
class CBaseEntity;
|
|
class IHandleEntity;
|
|
class QAngle;
|
|
class Vector;
|
|
struct Ray_t;
|
|
class IPhysicsObject;
|
|
|
|
|
|
void UpdateDirtySpatialPartitionEntities();
|
|
|
|
|
|
enum SurroundingBoundsType_t
|
|
{
|
|
USE_OBB_COLLISION_BOUNDS = 0,
|
|
USE_BEST_COLLISION_BOUNDS,
|
|
USE_HITBOXES,
|
|
USE_SPECIFIED_BOUNDS,
|
|
USE_GAME_CODE,
|
|
USE_ROTATION_EXPANDED_BOUNDS,
|
|
USE_COLLISION_BOUNDS_NEVER_VPHYSICS,
|
|
|
|
SURROUNDING_TYPE_BIT_COUNT = 3
|
|
};
|
|
|
|
|
|
class CCollisionProperty : public ICollideable
|
|
{
|
|
DECLARE_CLASS_NOBASE(CCollisionProperty);
|
|
DECLARE_EMBEDDED_NETWORKVAR();
|
|
DECLARE_PREDICTABLE();
|
|
|
|
#ifdef GAME_DLL
|
|
DECLARE_DATADESC();
|
|
#endif
|
|
|
|
public:
|
|
CCollisionProperty();
|
|
~CCollisionProperty();
|
|
|
|
void Init(CBaseEntity* pEntity);
|
|
|
|
virtual IHandleEntity* GetEntityHandle();
|
|
virtual const Vector& OBBMinsPreScaled() const { return m_vecMinsPreScaled.Get(); }
|
|
virtual const Vector& OBBMaxsPreScaled() const { return m_vecMaxsPreScaled.Get(); }
|
|
virtual const Vector& OBBMins() const { return m_vecMins.Get(); }
|
|
virtual const Vector& OBBMaxs() const { return m_vecMaxs.Get(); }
|
|
virtual void WorldSpaceTriggerBounds(Vector* pVecWorldMins, Vector* pVecWorldMaxs) const;
|
|
virtual bool TestCollision(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr);
|
|
virtual bool TestHitboxes(const Ray_t& ray, unsigned int fContentsMask, trace_t& tr);
|
|
virtual int GetCollisionModelIndex();
|
|
virtual const model_t* GetCollisionModel();
|
|
virtual const Vector& GetCollisionOrigin() const;
|
|
virtual const QAngle& GetCollisionAngles() const;
|
|
virtual const matrix3x4_t& CollisionToWorldTransform() const;
|
|
virtual SolidType_t GetSolid() const;
|
|
virtual int GetSolidFlags() const;
|
|
virtual IClientUnknown* GetIClientUnknown();
|
|
virtual int GetCollisionGroup() const;
|
|
virtual void WorldSpaceSurroundingBounds(Vector* pVecMins, Vector* pVecMaxs);
|
|
virtual bool ShouldTouchTrigger(int triggerSolidFlags) const;
|
|
virtual const matrix3x4_t* GetRootParentToWorldTransform() const;
|
|
|
|
public:
|
|
void CreatePartitionHandle();
|
|
void DestroyPartitionHandle();
|
|
unsigned short GetPartitionHandle() const;
|
|
|
|
void MarkPartitionHandleDirty();
|
|
|
|
void SetCollisionBounds(const Vector& mins, const Vector& maxs);
|
|
|
|
void RefreshScaledCollisionBounds(void);
|
|
|
|
void UseTriggerBounds(bool bEnable, float flBloat = 0.0f);
|
|
|
|
void SetSurroundingBoundsType(SurroundingBoundsType_t type, const Vector* pMins = NULL, const Vector* pMaxs = NULL);
|
|
|
|
void SetSolid(SolidType_t val);
|
|
|
|
const Vector& OBBSize() const;
|
|
|
|
float BoundingRadius() const;
|
|
float BoundingRadius2D() const;
|
|
|
|
const Vector& OBBCenter() const;
|
|
|
|
const Vector& WorldSpaceCenter() const;
|
|
|
|
void ClearSolidFlags(void);
|
|
void RemoveSolidFlags(int flags);
|
|
void AddSolidFlags(int flags);
|
|
bool IsSolidFlagSet(int flagMask) const;
|
|
void SetSolidFlags(int flags);
|
|
bool IsSolid() const;
|
|
|
|
void UpdatePartition();
|
|
|
|
bool IsBoundsDefinedInEntitySpace() const;
|
|
|
|
const Vector& CollisionToWorldSpace(const Vector& in, Vector* pResult) const;
|
|
|
|
const Vector& WorldToCollisionSpace(const Vector& in, Vector* pResult) const;
|
|
|
|
const Vector& WorldDirectionToCollisionSpace(const Vector& in, Vector* pResult) const;
|
|
|
|
void RandomPointInBounds(const Vector& vecNormalizedMins, const Vector& vecNormalizedMaxs, Vector* pPoint) const;
|
|
|
|
bool IsPointInBounds(const Vector& vecWorldPt) const;
|
|
|
|
void WorldSpaceAABB(Vector* pWorldMins, Vector* pWorldMaxs) const;
|
|
|
|
const Vector& CollisionSpaceMins(void) const;
|
|
|
|
const Vector& CollisionSpaceMaxs(void) const;
|
|
|
|
const Vector& NormalizedToCollisionSpace(const Vector& in, Vector* pResult) const;
|
|
|
|
const Vector& NormalizedToWorldSpace(const Vector& in, Vector* pResult) const;
|
|
|
|
const Vector& WorldToNormalizedSpace(const Vector& in, Vector* pResult) const;
|
|
|
|
const Vector& CollisionToNormalizedSpace(const Vector& in, Vector* pResult) const;
|
|
|
|
void CalcNearestPoint(const Vector& vecWorldPt, Vector* pVecNearestWorldPt) const;
|
|
|
|
float CalcDistanceFromPoint(const Vector& vecWorldPt) const;
|
|
|
|
bool DoesRotationInvalidateSurroundingBox() const;
|
|
|
|
bool DoesVPhysicsInvalidateSurroundingBox() const;
|
|
|
|
void MarkSurroundingBoundsDirty();
|
|
|
|
float ComputeSupportMap(const Vector& vecDirection) const;
|
|
|
|
private:
|
|
void CollisionAABBToWorldAABB(const Vector& entityMins, const Vector& entityMaxs, Vector* pWorldMins, Vector* pWorldMaxs) const;
|
|
|
|
void ComputeVPhysicsSurroundingBox(Vector* pVecWorldMins, Vector* pVecWorldMaxs);
|
|
|
|
bool ComputeHitboxSurroundingBox(Vector* pVecWorldMins, Vector* pVecWorldMaxs);
|
|
bool ComputeEntitySpaceHitboxSurroundingBox(Vector* pVecWorldMins, Vector* pVecWorldMaxs);
|
|
|
|
void ComputeCollisionSurroundingBox(bool bUseVPhysics, Vector* pVecWorldMins, Vector* pVecWorldMaxs);
|
|
|
|
void ComputeRotationExpandedBounds(Vector* pVecWorldMins, Vector* pVecWorldMaxs);
|
|
|
|
void ComputeSurroundingBox(Vector* pVecWorldMins, Vector* pVecWorldMaxs);
|
|
|
|
void CheckForUntouch();
|
|
|
|
void UpdateServerPartitionMask();
|
|
|
|
CBaseEntity* GetOuter();
|
|
const CBaseEntity* GetOuter() const;
|
|
|
|
private:
|
|
CBaseEntity* m_pOuter;
|
|
|
|
CNetworkVector(m_vecMinsPreScaled);
|
|
CNetworkVector(m_vecMaxsPreScaled);
|
|
CNetworkVector(m_vecMins);
|
|
CNetworkVector(m_vecMaxs);
|
|
float m_flRadius;
|
|
|
|
CNetworkVar(unsigned short, m_usSolidFlags);
|
|
|
|
SpatialPartitionHandle_t m_Partition;
|
|
CNetworkVar(unsigned char, m_nSurroundType);
|
|
|
|
CNetworkVar(unsigned char, m_nSolidType);
|
|
CNetworkVar(unsigned char, m_triggerBloat);
|
|
|
|
CNetworkVector(m_vecSpecifiedSurroundingMinsPreScaled);
|
|
CNetworkVector(m_vecSpecifiedSurroundingMaxsPreScaled);
|
|
CNetworkVector(m_vecSpecifiedSurroundingMins);
|
|
CNetworkVector(m_vecSpecifiedSurroundingMaxs);
|
|
|
|
#if 0
|
|
short m_surroundingMins[3];
|
|
short m_surroundingMaxs[3];
|
|
#else
|
|
Vector m_vecSurroundingMins;
|
|
Vector m_vecSurroundingMaxs;
|
|
#endif
|
|
|
|
friend class CBaseEntity;
|
|
};
|
|
|
|
|
|
#ifdef CLIENT_DLL
|
|
EXTERN_RECV_TABLE(DT_CollisionProperty);
|
|
#else
|
|
EXTERN_SEND_TABLE(DT_CollisionProperty);
|
|
#endif
|
|
|
|
|
|
inline CBaseEntity* CCollisionProperty::GetOuter()
|
|
{
|
|
return m_pOuter;
|
|
}
|
|
|
|
inline const CBaseEntity* CCollisionProperty::GetOuter() const
|
|
{
|
|
return m_pOuter;
|
|
}
|
|
|
|
|
|
inline unsigned short CCollisionProperty::GetPartitionHandle() const
|
|
{
|
|
return m_Partition;
|
|
}
|
|
|
|
|
|
inline const Vector& CCollisionProperty::OBBSize() const
|
|
{
|
|
Vector& temp = AllocTempVector();
|
|
VectorSubtract(m_vecMaxs, m_vecMins, temp);
|
|
return temp;
|
|
}
|
|
|
|
|
|
inline float CCollisionProperty::BoundingRadius() const
|
|
{
|
|
return m_flRadius;
|
|
}
|
|
|
|
|
|
inline bool CCollisionProperty::IsBoundsDefinedInEntitySpace() const
|
|
{
|
|
return ((m_usSolidFlags & FSOLID_FORCE_WORLD_ALIGNED) == 0) &&
|
|
(m_nSolidType != SOLID_BBOX) && (m_nSolidType != SOLID_NONE);
|
|
}
|
|
|
|
inline void CCollisionProperty::ClearSolidFlags(void)
|
|
{
|
|
SetSolidFlags(0);
|
|
}
|
|
|
|
inline void CCollisionProperty::RemoveSolidFlags(int flags)
|
|
{
|
|
SetSolidFlags(m_usSolidFlags & ~flags);
|
|
}
|
|
|
|
inline void CCollisionProperty::AddSolidFlags(int flags)
|
|
{
|
|
SetSolidFlags(m_usSolidFlags | flags);
|
|
}
|
|
|
|
inline int CCollisionProperty::GetSolidFlags(void) const
|
|
{
|
|
return m_usSolidFlags;
|
|
}
|
|
|
|
inline bool CCollisionProperty::IsSolidFlagSet(int flagMask) const
|
|
{
|
|
return (m_usSolidFlags & flagMask) != 0;
|
|
}
|
|
|
|
inline bool CCollisionProperty::IsSolid() const
|
|
{
|
|
return ::IsSolid((SolidType_t)(unsigned char)m_nSolidType, m_usSolidFlags);
|
|
}
|
|
|
|
|
|
inline const Vector& CCollisionProperty::OBBCenter() const
|
|
{
|
|
Vector& vecResult = AllocTempVector();
|
|
VectorLerp(m_vecMins, m_vecMaxs, 0.5f, vecResult);
|
|
return vecResult;
|
|
}
|
|
|
|
|
|
inline const Vector& CCollisionProperty::WorldSpaceCenter() const
|
|
{
|
|
Vector& vecResult = AllocTempVector();
|
|
CollisionToWorldSpace(OBBCenter(), &vecResult);
|
|
return vecResult;
|
|
}
|
|
|
|
|
|
inline const Vector& CCollisionProperty::CollisionToWorldSpace(const Vector& in, Vector* pResult) const
|
|
{
|
|
if (!IsBoundsDefinedInEntitySpace() || (GetCollisionAngles() == vec3_angle))
|
|
{
|
|
VectorAdd(in, GetCollisionOrigin(), *pResult);
|
|
}
|
|
else
|
|
{
|
|
VectorTransform(in, CollisionToWorldTransform(), *pResult);
|
|
}
|
|
return *pResult;
|
|
}
|
|
|
|
|
|
inline const Vector& CCollisionProperty::WorldToCollisionSpace(const Vector& in, Vector* pResult) const
|
|
{
|
|
if (!IsBoundsDefinedInEntitySpace() || (GetCollisionAngles() == vec3_angle))
|
|
{
|
|
VectorSubtract(in, GetCollisionOrigin(), *pResult);
|
|
}
|
|
else
|
|
{
|
|
VectorITransform(in, CollisionToWorldTransform(), *pResult);
|
|
}
|
|
return *pResult;
|
|
}
|
|
|
|
|
|
inline const Vector& CCollisionProperty::WorldDirectionToCollisionSpace(const Vector& in, Vector* pResult) const
|
|
{
|
|
if (!IsBoundsDefinedInEntitySpace() || (GetCollisionAngles() == vec3_angle))
|
|
{
|
|
*pResult = in;
|
|
}
|
|
else
|
|
{
|
|
VectorIRotate(in, CollisionToWorldTransform(), *pResult);
|
|
}
|
|
return *pResult;
|
|
}
|
|
|
|
|
|
inline void CCollisionProperty::WorldSpaceAABB(Vector* pWorldMins, Vector* pWorldMaxs) const
|
|
{
|
|
CollisionAABBToWorldAABB(m_vecMins, m_vecMaxs, pWorldMins, pWorldMaxs);
|
|
}
|
|
|
|
|
|
inline const Vector& CCollisionProperty::CollisionSpaceMins(void) const
|
|
{
|
|
return m_vecMins;
|
|
}
|
|
|
|
inline const Vector& CCollisionProperty::CollisionSpaceMaxs(void) const
|
|
{
|
|
return m_vecMaxs;
|
|
}
|
|
|
|
|
|
inline bool CCollisionProperty::DoesRotationInvalidateSurroundingBox() const
|
|
{
|
|
if (IsSolidFlagSet(FSOLID_ROOT_PARENT_ALIGNED))
|
|
return true;
|
|
|
|
switch (m_nSurroundType)
|
|
{
|
|
case USE_COLLISION_BOUNDS_NEVER_VPHYSICS:
|
|
case USE_OBB_COLLISION_BOUNDS:
|
|
case USE_BEST_COLLISION_BOUNDS:
|
|
return IsBoundsDefinedInEntitySpace();
|
|
|
|
case USE_HITBOXES:
|
|
case USE_GAME_CODE:
|
|
return true;
|
|
|
|
case USE_ROTATION_EXPANDED_BOUNDS:
|
|
case USE_SPECIFIED_BOUNDS:
|
|
return false;
|
|
|
|
default:
|
|
Assert(0);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
#endif |