DragonNest/Common/EternityEngine/EtCollisionMng.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

186 lines
5.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "EtCollisionMng.h"
#include "EtFindCollision.h"
#if !defined( USE_BOOST_MEMPOOL )
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
#endif
CEtCollisionMng::CEtCollisionMng(void)
{
}
CEtCollisionMng::~CEtCollisionMng(void)
{
Clear();
}
void CEtCollisionMng::Clear()
{
m_CollisionKdTree.Clear();
SAFE_DELETE_AVEC( m_vecAllocPrimitive );
}
void CEtCollisionMng::AddCollisionMeshToKdTree( SCollisionPrimitive &Primitive, EtMatrix &WorldMat, const EtVector3 &vScale )
{
if( m_CollisionKdTree.IsBuild() )
{
m_CollisionKdTree.Clear();
}
SKdTreeCollisionPrimitive KdTreePrimitive;
float fScale = max( max( vScale.x, vScale.y ), vScale.z );
switch( Primitive.Type )
{
case CT_TRIANGLE_LIST:
{
SCollisionTriangleList *pCollisionTriangle;
SCollisionTriangle *pTriangle;
int i, nTriangleCount;
pCollisionTriangle = ( SCollisionTriangleList * )&Primitive;
nTriangleCount = ( int )pCollisionTriangle->vecTriangle.size();
pTriangle = new SCollisionTriangle[ nTriangleCount ];
m_vecAllocPrimitive.push_back( pTriangle );
for( i = 0; i < nTriangleCount; i++ )
{
EtVector3 vPoint[ 3 ];
KdTreePrimitive.pPrimitive = pTriangle + i;
vPoint[ 0 ] = pCollisionTriangle->vecTriangle[ i ].vOrigin;
vPoint[ 1 ] = pCollisionTriangle->vecTriangle[ i ].vOrigin + pCollisionTriangle->vecTriangle[ i ].vEdge1;
vPoint[ 2 ] = pCollisionTriangle->vecTriangle[ i ].vOrigin + pCollisionTriangle->vecTriangle[ i ].vEdge2;
EtVec3TransformCoordArray( vPoint, sizeof( EtVector3 ), vPoint, sizeof( EtVector3 ), &WorldMat, 3 );
pTriangle[ i ].vOrigin = vPoint[ 0 ];
pTriangle[ i ].vEdge1 = vPoint[ 1 ] - vPoint[ 0 ];
pTriangle[ i ].vEdge2 = vPoint[ 2 ] - vPoint[ 0 ];
m_CollisionKdTree.AddPrimitive( KdTreePrimitive );
}
}
break;
case CT_BOX:
{
int i;
SCollisionBox *pBox, *pOriginalBox;
pOriginalBox = ( SCollisionBox * )&Primitive;
pBox = new SCollisionBox();
KdTreePrimitive.pPrimitive = pBox;
m_vecAllocPrimitive.push_back( pBox );
EtVec3TransformCoord( &pBox->vCenter, &pOriginalBox->vCenter, &WorldMat );
EtMatrix WorldNormalMat = WorldMat;
EtVector3 vLength;
vLength.x = EtVec3Length((EtVector3*)&WorldNormalMat._11);
vLength.y = EtVec3Length((EtVector3*)&WorldNormalMat._21);
vLength.z = EtVec3Length((EtVector3*)&WorldNormalMat._31);
*(EtVector3*)(&WorldNormalMat._11) /= vLength.x;
*(EtVector3*)(&WorldNormalMat._21) /= vLength.y;
*(EtVector3*)(&WorldNormalMat._31) /= vLength.z;
// Non-Uniform Scale Matrix <20><> <20><>ǥ<EFBFBD><20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>ڿ<EFBFBD> Normalize<7A><65> <20><><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ϹǷ<CFB9>, <20≯<EFBFBD> Orthogonal Matrix <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
for( i = 0; i < 3; i++ )
{
EtVec3TransformNormal( pBox->vAxis + i, pOriginalBox->vAxis + i, &WorldNormalMat );
pBox->fExtent[ i ] = pOriginalBox->fExtent[ i ] * ((FLOAT*)&vLength.x)[ i ];
}
/*EtMatrix MatIdent;
EtMatrixIdentity(&MatIdent);
*(EtVector3*)&MatIdent._11 = pBox->vAxis[0];
*(EtVector3*)&MatIdent._21 = pBox->vAxis[1];
*(EtVector3*)&MatIdent._31 = pBox->vAxis[2];
float fDet = fabsf(EtMatrixDeterminant(&MatIdent) - 1.0f);
ASSERT( fDet < 0.0001f );*/
m_CollisionKdTree.AddPrimitive( KdTreePrimitive );
}
break;
case CT_SPHERE:
SCollisionSphere *pSphere, *pOriginalSphere;
pOriginalSphere = ( SCollisionSphere * )&Primitive;
pSphere = new SCollisionSphere();
KdTreePrimitive.pPrimitive = pSphere;
m_vecAllocPrimitive.push_back( pSphere );
EtVec3TransformCoord( &pSphere->vCenter, &pOriginalSphere->vCenter, &WorldMat );
pSphere->fRadius = pOriginalSphere->fRadius * fScale;
m_CollisionKdTree.AddPrimitive( KdTreePrimitive );
break;
case CT_CAPSULE:
SCollisionCapsule *pCapsule, *pOriginalCapsule;
pOriginalCapsule = ( SCollisionCapsule * )&Primitive;
pCapsule = new SCollisionCapsule();
KdTreePrimitive.pPrimitive = pCapsule;
m_vecAllocPrimitive.push_back( pCapsule );
EtVec3TransformCoord( &pCapsule->Segment.vOrigin, &pOriginalCapsule->Segment.vOrigin, &WorldMat );
EtVector3 vOriginFar = pOriginalCapsule->Segment.vOrigin + pOriginalCapsule->Segment.vDirection;
EtVec3TransformCoord( &vOriginFar, &vOriginFar, &WorldMat );
pCapsule->Segment.vDirection = vOriginFar - pCapsule->Segment.vOrigin;
pCapsule->fRadius = pOriginalCapsule->fRadius * fScale;
if( fScale != 1.0f )
{
pCapsule->Segment.vOrigin = pCapsule->Segment.vOrigin - ( fScale - 1.0f ) * 0.5f * pCapsule->Segment.vDirection;
pCapsule->Segment.vDirection += pCapsule->Segment.vDirection * ( fScale - 1.0f ) * 0.5f;
}
m_CollisionKdTree.AddPrimitive( KdTreePrimitive );
break;
}
}
void CEtCollisionMng::BuildCollisionTree()
{
m_CollisionKdTree.BuildTree();
}
bool CEtCollisionMng::FindCollision( std::vector< SCollisionPrimitive * > &vecPrimitive, SAABox &BoundingBox, EtVector3 &vMove, DNVector(SCollisionResponse) &vecResponse, bool bCalcContactTime)
{
int i;
bool bCollision;
static std::vector< SKdTreeCollisionPrimitive * > vecResult;
SCollisionResponse Response;
bCollision = false;
vecResult.clear();
m_CollisionKdTree.Pick( BoundingBox, vecResult );
if( !vecResult.empty() )
{
std::vector< SKdTreeCollisionPrimitive * >::iterator it;
Response.vMove = vMove;
for( i = 0; i < ( int )vecPrimitive.size(); i++ )
{
for( it = vecResult.begin() ; it != vecResult.end(); it++ )
{
Response.vExtraNormal.x = FLT_MAX;
if( CEtCollisionFinder::GetInstance().FindCollision( *vecPrimitive[ i ], *( ( *it )->pPrimitive), Response, bCalcContactTime ) )
{
Response.pCollisionPrimitive = ( *it )->pPrimitive;
vecResponse.push_back( Response );
if( Response.vExtraNormal.x != FLT_MAX )
{
Response.vNormal = Response.vExtraNormal;
vecResponse.push_back( Response );
}
bCollision = true;
}
}
}
}
return bCollision;
}