226 lines
6.1 KiB
C++
226 lines
6.1 KiB
C++
#pragma once
|
|
|
|
enum CollisionType
|
|
{
|
|
CT_BOX = 0,
|
|
CT_SPHERE = 1,
|
|
CT_CAPSULE = 2,
|
|
CT_TRIANGLE = 3,
|
|
CT_TRIANGLE_LIST = 4,
|
|
CT_TYPE_COUNT = 5,
|
|
};
|
|
|
|
struct SCollisionPrimitive
|
|
{
|
|
virtual ~SCollisionPrimitive() {}
|
|
virtual void GetBoundingBox( SAABox &Box ) {}
|
|
virtual void Load( CStream *pStream ) {}
|
|
virtual void Save( CStream *pStream ) {}
|
|
|
|
CollisionType Type;
|
|
};
|
|
|
|
#include "MemPool.h"
|
|
struct SCollisionTriangle : SCollisionPrimitive, public TBoostMemoryPool< SCollisionTriangle >
|
|
{
|
|
SCollisionTriangle() { Type = CT_TRIANGLE; }
|
|
virtual void GetBoundingBox( SAABox &Box )
|
|
{
|
|
Box.Reset();
|
|
Box.AddPoint( vOrigin );
|
|
Box.AddPoint( vOrigin + vEdge1 );
|
|
Box.AddPoint( vOrigin + vEdge2 );
|
|
}
|
|
virtual void Load( CStream *pStream )
|
|
{
|
|
pStream->Read( vOrigin, sizeof( EtVector3 ) );
|
|
pStream->Read( vEdge1, sizeof( EtVector3 ) );
|
|
pStream->Read( vEdge2, sizeof( EtVector3 ) );
|
|
}
|
|
virtual void Save( CStream *pStream )
|
|
{
|
|
pStream->Write( vOrigin, sizeof( EtVector3 ) );
|
|
pStream->Write( vEdge1, sizeof( EtVector3 ) );
|
|
pStream->Write( vEdge2, sizeof( EtVector3 ) );
|
|
}
|
|
void GetNormal( EtVector3 &vNormal )
|
|
{
|
|
EtVec3Cross( &vNormal, &vEdge1, &vEdge2 );
|
|
EtVec3Normalize( &vNormal, &vNormal );
|
|
}
|
|
|
|
EtVector3 vOrigin;
|
|
EtVector3 vEdge1;
|
|
EtVector3 vEdge2;
|
|
};
|
|
|
|
struct SCollisionTriangleList : SCollisionPrimitive, public TBoostMemoryPool< SCollisionTriangleList >
|
|
{
|
|
SCollisionTriangleList() { Type = CT_TRIANGLE_LIST; }
|
|
std::vector< SCollisionTriangle > vecTriangle;
|
|
};
|
|
|
|
struct SCollisionSphere : SCollisionPrimitive, public TBoostMemoryPool< SCollisionSphere >
|
|
{
|
|
SCollisionSphere() : fRadius( 0.0f ) { Type = CT_SPHERE; }
|
|
virtual void GetBoundingBox( SAABox &Box )
|
|
{
|
|
Box.Max = vCenter + EtVector3( fRadius, fRadius, fRadius );
|
|
Box.Min = vCenter - EtVector3( fRadius, fRadius, fRadius );
|
|
}
|
|
virtual void Load( CStream *pStream )
|
|
{
|
|
pStream->Read( vCenter, sizeof( EtVector3 ) );
|
|
pStream->Read( &fRadius, sizeof( float ) );
|
|
}
|
|
virtual void Save( CStream *pStream )
|
|
{
|
|
pStream->Write( vCenter, sizeof( EtVector3 ) );
|
|
pStream->Write( &fRadius, sizeof( float ) );
|
|
}
|
|
|
|
EtVector3 vCenter;
|
|
float fRadius;
|
|
};
|
|
|
|
#include "MemPool.h"
|
|
struct SCollisionBox : SCollisionPrimitive, public TBoostMemoryPool< SCollisionBox >
|
|
{
|
|
SCollisionBox() { Type = CT_BOX; memset( fExtent, 0, sizeof( fExtent ) ); }
|
|
virtual void GetBoundingBox( SAABox &Box )
|
|
{
|
|
EtVector3 TempAxis[ 3 ] = { fExtent[ 0 ] * vAxis[0], fExtent[ 1 ] * vAxis[ 1 ], fExtent[ 2 ] * vAxis[ 2 ] };
|
|
Box.Reset();
|
|
|
|
Box.AddPoint( vCenter - TempAxis[ 0 ] - TempAxis[ 1 ] - TempAxis[ 2 ] );
|
|
Box.AddPoint( vCenter + TempAxis[ 0 ] - TempAxis[ 1 ] - TempAxis[ 2 ] );
|
|
Box.AddPoint( vCenter - TempAxis[ 0 ] + TempAxis[ 1 ] - TempAxis[ 2 ] );
|
|
Box.AddPoint( vCenter + TempAxis[ 0 ] + TempAxis[ 1 ] - TempAxis[ 2 ] );
|
|
Box.AddPoint( vCenter - TempAxis[ 0 ] - TempAxis[ 1 ] + TempAxis[ 2 ] );
|
|
Box.AddPoint( vCenter + TempAxis[ 0 ] - TempAxis[ 1 ] + TempAxis[ 2 ] );
|
|
Box.AddPoint( vCenter - TempAxis[ 0 ] + TempAxis[ 1 ] + TempAxis[ 2 ] );
|
|
Box.AddPoint( vCenter + TempAxis[ 0 ] + TempAxis[ 1 ] + TempAxis[ 2 ] );
|
|
}
|
|
virtual void Load( CStream *pStream )
|
|
{
|
|
pStream->Read( vCenter, sizeof( EtVector3 ) );
|
|
pStream->Read( vAxis, sizeof( EtVector3 ) * 3 );
|
|
pStream->Read( &fExtent, sizeof( float ) * 3 );
|
|
}
|
|
virtual void Save( CStream *pStream )
|
|
{
|
|
pStream->Write( vCenter, sizeof( EtVector3 ));
|
|
pStream->Write( vAxis, sizeof( EtVector3 ) * 3 );
|
|
pStream->Write( &fExtent, sizeof( float ) * 3 );
|
|
}
|
|
|
|
EtVector3 vCenter;
|
|
EtVector3 vAxis[ 3 ];
|
|
float fExtent[ 3 ];
|
|
};
|
|
|
|
struct SCollisionCapsule : SCollisionPrimitive, public TBoostMemoryPool< SCollisionCapsule >
|
|
{
|
|
SCollisionCapsule() : fRadius( 0.0f ) { Type = CT_CAPSULE; }
|
|
virtual void GetBoundingBox( SAABox &Box )
|
|
{
|
|
Box.Reset();
|
|
Box.AddPoint( Segment.vOrigin + EtVector3( fRadius, fRadius, fRadius ) );
|
|
Box.AddPoint( Segment.vOrigin - EtVector3( fRadius, fRadius, fRadius ) );
|
|
Box.AddPoint( Segment.vOrigin + Segment.vDirection + EtVector3( fRadius, fRadius, fRadius ) );
|
|
Box.AddPoint( Segment.vOrigin + Segment.vDirection - EtVector3( fRadius, fRadius, fRadius ) );
|
|
}
|
|
virtual void Load( CStream *pStream )
|
|
{
|
|
pStream->Read( &Segment.vOrigin, sizeof( EtVector3 ) );
|
|
pStream->Read( &Segment.vDirection, sizeof( EtVector3 ) );
|
|
pStream->Read( &fRadius, sizeof( float ) );
|
|
}
|
|
virtual void Save( CStream *pStream )
|
|
{
|
|
pStream->Write( &Segment.vOrigin, sizeof( EtVector3 ) );
|
|
pStream->Write( &Segment.vDirection, sizeof( EtVector3 ) );
|
|
pStream->Write( &fRadius, sizeof( float ) );
|
|
}
|
|
|
|
SSegment Segment;
|
|
float fRadius;
|
|
};
|
|
|
|
struct SKdTreeCollisionPrimitive
|
|
{
|
|
SKdTreeCollisionPrimitive()
|
|
{
|
|
pPrimitive = NULL;
|
|
m_bSeleDelete = false;
|
|
}
|
|
~SKdTreeCollisionPrimitive()
|
|
{
|
|
if( m_bSeleDelete )
|
|
{
|
|
SAFE_DELETE( pPrimitive );
|
|
}
|
|
}
|
|
void GetBoundingBox( SAABox &Box )
|
|
{
|
|
pPrimitive->GetBoundingBox( Box );
|
|
}
|
|
void Load( CStream *pStream )
|
|
{
|
|
CollisionType Type;
|
|
pStream->Read( &Type, sizeof( CollisionType ) );
|
|
switch( Type )
|
|
{
|
|
case CT_BOX:
|
|
pPrimitive = new SCollisionBox();
|
|
break;
|
|
case CT_SPHERE:
|
|
pPrimitive = new SCollisionSphere();
|
|
break;
|
|
case CT_CAPSULE:
|
|
pPrimitive = new SCollisionCapsule();
|
|
break;
|
|
case CT_TRIANGLE:
|
|
pPrimitive = new SCollisionTriangle();
|
|
break;
|
|
}
|
|
if( pPrimitive )
|
|
{
|
|
pPrimitive->Load( pStream );
|
|
pPrimitive->Type = Type;
|
|
}
|
|
m_bSeleDelete = true;
|
|
}
|
|
void Save( CStream *pStream )
|
|
{
|
|
if( pPrimitive )
|
|
{
|
|
pStream->Write( &pPrimitive->Type, sizeof( CollisionType ) );
|
|
pPrimitive->Save( pStream );
|
|
}
|
|
}
|
|
|
|
SCollisionPrimitive *pPrimitive;
|
|
bool m_bSeleDelete;
|
|
};
|
|
|
|
struct SCollisionResponse
|
|
{
|
|
SCollisionResponse()
|
|
{
|
|
fContactTime = 1.0f;
|
|
pCollisionPrimitive = NULL;
|
|
vNormal.x = FLT_MAX;
|
|
vExtraNormal.x = FLT_MAX;
|
|
}
|
|
|
|
EtVector3 vNormal;
|
|
EtVector3 vExtraNormal;
|
|
EtVector3 vMove;
|
|
float fContactTime;
|
|
SCollisionPrimitive *pCollisionPrimitive;
|
|
};
|
|
|
|
void UpdateCollisionPrimitive( SCollisionPrimitive &DestPrimitive, SCollisionPrimitive &SourPrimitive, const EtMatrix &WorldMat, const EtVector3 &vScale );
|
|
bool IsInside( SCollisionPrimitive &Primitive, EtVector3 &vPoint );
|
|
void GetCenterPos( SCollisionPrimitive &Primitive, EtVector3 &vPoint );
|