PolygonSoup碰撞檢測學習筆記

解決PolygonSoup碰撞檢測的成熟方案是使用層次BV樹,根據BV的不同衍生出:AABB,OBB,K-dop三種方案.
在內存使用上: AABB -> OBB -> K-dop遞增.在效率上則尚無定論,根據具體的應用環境不同而不同.

Opcode: 開源,完全免費,採用AABB樹構造,內存耗用很小,支持複雜模型,起初想使用它,但發現其,基本上沒有文檔,Sample,1.3版本接口變動巨大,且無文檔,自2003年來再無更新,最致命的是不支持Instance transform的Scale,AABBCollider沒有Transform支持,而且是在看代碼時發現的,吐血.主要設計目標是少的內存耗用,但速度也很快.爲ODE,Tokamak,Crystal Space所用.

RAPID: 開源,免費,採用OBB構造,內存耗用巨大,學院派設計,最倒黴的庫,因爲其他每個庫都拿它作比較,都說比它快.

SOLID: GPL開源,商業軟件,採用AABB樹構造,2005.4月出3.5版本,效率不錯,內存耗用中等,在後面4.0會支持AABB數據壓縮,有文檔,接口簡單,代碼清晰.支持複雜模型,支持Instance transform的Scale,甚至支持各向不等縮放,支持Penetration Depth計算,cool.作者Gino van den Bergen是3D碰撞研究專家,著有:Collision Detection in Interactive 3D Environments一書,有e版.邏輯順暢地集成入DM,效果不錯,滿足使用要求.不過其IndexBuffer是unsigned int,Matrix是DX風格的,但代碼很清晰,很容易定製.
SOLID有個嚴重的Bug,必須確保DT_GetCommonPoint,DT_GetPenDepth,DT_GetClosestPair在檢測Complex和Convex對象時,第一個參數必須是Complex對象,否則崩潰.因爲SOLID的double dispatch實現有問題,不完整,沒有Convex + Complex順序的對應函數.

QuickCD: 開源,免費,K-dop樹構造.

ColDet,支持複雜模型,也不支持Instance Transform的Scale.

Reference:
http://www.codercorner.com/Opcode.htm
http://www.dtecta.com/
http://www.cs.unc.edu/~geom/OBB/OBBT.html
http://www.ams.sunysb.edu/~jklosow/quickcd/QuickCD.html
http://photoneffect.com/coldet/
http://www.merl.com/projects/vclip/
http://www.q12.org/ode/ode.html

None.gifvoid DmModel::SetBoundPolygonSoup(uint32 nPolygonSoupVertices, vec3_type* pVertices, uint32 nTrianglePrims, uint16* pTrianglePrims)
ExpandedBlockStart.gif
{    
InBlock.gif    ASSERT(m_hSolidShape 
== NULL);
InBlock.gif    
InBlock.gif    
if(nTrianglePrims == 0return;
InBlock.gif    
if(nPolygonSoupVertices == 0return;
InBlock.gif            
InBlock.gif    
// Save polygon soup data for collision test!
InBlock.gif
    m_pPolygonSoupVertices = new vec3_type[nPolygonSoupVertices];
InBlock.gif    memcpy(m_pPolygonSoupVertices, pVertices, 
sizeof(vec3_type) * nPolygonSoupVertices);
InBlock.gif    
InBlock.gif    
// Build 
InBlock.gif
    DT_VertexBaseHandle hVertexBase = DT_NewVertexBase(m_pPolygonSoupVertices, 0);
InBlock.gif    m_hSolidShape 
= DT_NewComplexShape(hVertexBase);
InBlock.gif    m_hSolidVertexBase 
= hVertexBase;
InBlock.gif        
InBlock.gif    
// Define mesh triangles
InBlock.gif
    for(uint32 i = 0; i < nTrianglePrims; i += 3)
ExpandedSubBlockStart.gif    
{    
InBlock.gif        DT_VertexIndices(
3, pTrianglePrims + i);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
// End it
InBlock.gif
    DT_EndComplexShape();
ExpandedBlockEnd.gif}

None.gif
None.gif
void DmModelInstanceNode::BuildPhysics()
ExpandedBlockStart.gif
{    
InBlock.gif    
// Setup Phisic stuffs
InBlock.gif
    DT_ShapeHandle hShape = (DT_ShapeHandle)m_pRefModelInstance->m_pRefModel->m_hSolidShape;
InBlock.gif    
if(hShape)
ExpandedSubBlockStart.gif    
{    
InBlock.gif        DT_ObjectHandle hObject 
= DT_CreateObject(NULL, hShape);
InBlock.gif        DM_SetMatrixf(hObject, m_matTransform);
InBlock.gif        m_hSolidObject 
= hObject;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
void DmGameCreature::BuildPhysics()
ExpandedBlockStart.gif
{    
InBlock.gif    ASSERT(m_hSolidObject 
== NULL);
InBlock.gif    
InBlock.gif    vec3_type vMin, vMax;
InBlock.gif    getBoundBox(vMin, vMax);
InBlock.gif    DT_ShapeHandle hShape 
= DT_NewBox(vMax.x - vMin.x, vMax.y - vMin.y, vMax.z - vMin.z);
InBlock.gif    DT_ObjectHandle hObject 
= DT_CreateObject(NULL, hShape);
InBlock.gif    
InBlock.gif    m_hSolidShape 
= hShape;
InBlock.gif    m_hSolidObject 
= hObject;
ExpandedBlockEnd.gif}

None.gif
None.gif
bool DmModelInstanceNode::TestCollision(HANDLE hSolidObject)
ExpandedBlockStart.gif
{    
InBlock.gif    
if(!m_hSolidObject) return false;
InBlock.gif    
InBlock.gif    DT_ObjectHandle hTestObject 
= (DT_ObjectHandle)hSolidObject;
InBlock.gif    DT_ObjectHandle hThisObject 
= (DT_ObjectHandle)m_hSolidObject;
InBlock.gif        
InBlock.gif    DT_Vector3 v;
InBlock.gif    
return (DT_GetCommonPoint(hThisObject, hTestObject, v) != 0);
ExpandedBlockEnd.gif}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章