視錘台カリング

[戻る]
佐藤 卓 2007/01/17(水) 00:17:36
お世話になります。

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

佐藤 卓 2007/01/17(水) 21:12:29
[[解決]]
こんな質問じゃ回答来ないなと思いつつ、、、解決しました。

視錘台と法線を可視化したらあっていたようでした。
結局 d の要素いれたらちゃんとカリングされるようになりました。


nt.x * pos.x + nt.y * pos.y + nt.z * pos.z + d > (*it).radius
                                          ^^^^^


以上。

古いスレッドには追加発言できません。