お世話になります。
現在 DirectX を使用して境界球を1000個程作り視錘台カリングを勉強しています。
が、期待通りにクリップされません。
詰まってしまいましたので質問させて頂きます。
ご存知の方がいらっしゃいましたらご教示願います。
開発環境:VS.net WindowsXP
//----------------------------------
// 以下ソース
//----------------------------------
void
ClipCheck( D3DVIEWPORT9& iViewPort, D3DXMATRIX iProMat, D3DXMATRIX iViewMat )
{
// 視錐台の平面の法線ベクトル計算
float x1 = (float)iViewPort.X;
float y1 = (float)iViewPort.Y;
float x2 = (float)iViewPort.X + (float)iViewPort.Width;
float y2 = (float)iViewPort.Y + (float)iViewPort.Height;
D3DXVECTOR3 Near[ 4 ];
D3DXVECTOR3 Far[ 4 ];
Near[0] = D3DXVECTOR3( x1, y1, 0 );
Near[1] = D3DXVECTOR3( x2, y1, 0 );
Near[2] = D3DXVECTOR3( x1, y2, 0 );
Near[3] = D3DXVECTOR3( x2, y2, 0 );
Far[0] = D3DXVECTOR3( x1, y1, 1 );
Far[1] = D3DXVECTOR3( x2, y1, 1 );
Far[2] = D3DXVECTOR3( x1, y2, 1 );
Far[3] = D3DXVECTOR3( x2, y2, 1 );
// 視錐台の8点の計算
D3DXMATRIX world;
D3DXMatrixIdentity( &world );
for( int i = 0; i < 4; ++i )
{
D3DXVec3Unproject(&Near[i], &Near[i], &iViewPort, &iProMat, &iViewMat,
&world);
D3DXVec3Unproject(&Far[i], &Far[i], &iViewPort, &iProMat, &iViewMat,
&world);
}
// 平面の3点から法線の計算
D3DXVECTOR3 nt, nb, nl, nr;
D3DXVECTOR3 tmp1, tmp2;
// 左
tmp1 = Near[2] - Near[0];
tmp2 = Far[0] - Near[0];
D3DXVec3Cross( &nl, &tmp1, &tmp2 );
D3DXVec3Normalize( &nl, &nl );
// 右
tmp1 = Near[3] - Near[1];
tmp2 = Far[1] - Near[1];
D3DXVec3Cross( &nr, &tmp1, &tmp2 );
D3DXVec3Normalize( &nr, &nr );
// 上
tmp1 = Near[3] - Near[2];
tmp2 = Far[2] - Near[2];
D3DXVec3Cross( &nt, &tmp1, &tmp2 );
D3DXVec3Normalize( &nt, &nt );
// 下
tmp1 = Far[0] - Near[0];
tmp2 = Near[1] - Near[0];
D3DXVec3Cross( &nb, &tmp1, &tmp2 );
D3DXVec3Normalize( &nb, &nb );
for( SphereIterator it = mSphere.begin(); it != mSphere.end(); ++it )
{
D3DXVECTOR3 pos = (*it).position;
// 上下左右との比較(Near,Farは省略) normal ・ center > radius
if( ( nt.x * pos.x + nt.y * pos.y + nt.z * pos.z > (*it).radius
|| nb.x * pos.x + nb.y * pos.y + nb.z * pos.z > (*it).radius
|| nl.x * pos.x + nl.y * pos.y + nl.z * pos.z > (*it).radius
|| nr.x * pos.x + nr.y * pos.y + nr.z * pos.z > (*it).radius ) )
{
(*it).is_visible = false;
continue;
}
// 合格
(*it).is_visible = true;
}
}
こんな質問じゃ回答来ないなと思いつつ、、、解決しました。
視錘台と法線を可視化したらあっていたようでした。
結局 d の要素いれたらちゃんとカリングされるようになりました。
nt.x * pos.x + nt.y * pos.y + nt.z * pos.z + d > (*it).radius
^^^^^
以上。