動いているAABBとBSP-Treeに入れてある複数のAABBの接触判定
CAABBは軸平行境界ボックス(Axis-Aligned Bounding Box)構造体をメンバ変数に持つクラス。
- 作者: Christer Ericson,中村達也
- 出版社/メーカー: ボーンデジタル
- 発売日: 2005/10
- メディア: 単行本
- 購入: 7人 クリック: 150回
- この商品を含むブログ (41件) を見る
CBSPNodeはBSP-Treeです。
//----------------------------------------------- // 動いているAABBとBSP-Treeの同じ領域のAABBとの交差を検出 //----------------------------------------------- void IntersectMovingAABBvsBSPcontent( CAABB *a, CBSPNode *node ) { // 分割平面に対して正か負の領域にいるかを判定 if( ( Dot( a->m_AABB.c, node->m_splitPlane.n ) - node->m_splitPlane.d ) < 0 ) { // 負の領域 if( node->m_pNegativeNode ) IntersectMovingAABBvsBSPcontent( a, node->m_pNegativeNode ); } else { // 正の領域(ゼロを含む) if( node->m_pPositiveNode ) IntersectMovingAABBvsBSPcontent( a, node->m_pPositiveNode ); } float tfirst = 0.0f; float tlast = 1.0f; if( node->IsLeaf() ) for( int i = 0; i < (int)node->m_AABBList.size(); ++i ) { if( IntersectMovingAABBAABB( a->m_AABB, node->m_AABBList.at(i)->m_AABB, a->m_velocity, node->m_AABBList.at(i)->m_velocity, tfirst, tlast ) ) { // 衝突した a->m_color = 2; node->m_AABBList.at(i)->m_color = 2; a->m_AABB.c += tfirst * a->m_velocity + (1-tfirst)*(-a->m_velocity); // 跳ね返り a->m_velocity = -a->m_velocity; } else { // 衝突してない a->m_color = 0; node->m_AABBList.at(i)->m_color = 1; a->m_AABB.c += a->m_velocity; } } }
こんな感じでサンプルを作った。
後は、下の関数をコピペして部分だけ変えて作ったのだけれども、再帰的に呼び出している部分を書き換え忘れてた。
それだから、上手く動かなくて焦ったりした。
void IntersectAABBvsBSPcontent( CAABB *a, CBSPNode *node );
上の関数をコピへして使ったが故に下記のような間違いをした。
//----------------------------------------------- // 動いているAABBとBSP-Treeの同じ領域のAABBとの交差を検出 //----------------------------------------------- void IntersectMovingAABBvsBSPcontent( CAABB *a, CBSPNode *node ) { // 分割平面に対して正か負の領域にいるかを判定 if( ( Dot( a->m_AABB.c, node->m_splitPlane.n ) - node->m_splitPlane.d ) < 0 ) { // 負の領域 if( node->m_pNegativeNode ) IntersectAABBvsBSPcontent( a, node->m_pNegativeNode ); // ←ここで別関数に飛んでるので再帰にならない } else { // 正の領域(ゼロを含む) if( node->m_pPositiveNode ) IntersectAABBvsBSPcontent( a, node->m_pPositiveNode ); // ←ここも再帰されていない } // ここから先には来ない float tfirst = 0.0f; float tlast = 1.0f; if( node->IsLeaf() ) for( int i = 0; i < (int)node->m_AABBList.size(); ++i ) { if( IntersectMovingAABBAABB( a->m_AABB, node->m_AABBList.at(i)->m_AABB, a->m_velocity, node->m_AABBList.at(i)->m_velocity, tfirst, tlast ) ) { // 衝突した a->m_color = 2; node->m_AABBList.at(i)->m_color = 2; a->m_AABB.c += tfirst * a->m_velocity + (1-tfirst)*(-a->m_velocity); // 跳ね返り a->m_velocity = -a->m_velocity; } else { // 衝突してない a->m_color = 0; node->m_AABBList.at(i)->m_color = 1; a->m_AABB.c += a->m_velocity; } } }
こんな感じでウダウダしていた。