bate's blog

調べたこと実装したことなどを取りとめもなく書きます。

動いているAABBとBSP-Treeに入れてある複数のAABBの接触判定

CAABBは軸平行境界ボックス(Axis-Aligned Bounding Box)構造体をメンバ変数に持つクラス。

ゲームプログラミングのためのリアルタイム衝突判定

ゲームプログラミングのためのリアルタイム衝突判定


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;
			}
		}
}

こんな感じでウダウダしていた。

広告を非表示にする