Archived

This topic is now archived and is closed to further replies.

AngryMan

D3DXComputeBoundingSphere

Recommended Posts

AngryMan    122
The problem is curious one! I''m using D3DXComputeBoundingSphere to compute bounding sphere for each triangle in the mesh, however it doesn''t seem to work well. The size of triangles is almost equal, however the radius given out by this function vary dramatically. e.g. Most of them are about 6 units, as they should be, but few are >200 units. Why is this happening? D3DXComputeBoundingSphere(vert + pIndices[3*i], 3 , D3DXGetFVFVertexSize(meshClone->GetFVF() ), &cModel.center, &cModel[i].radius); vert = pointer to first vertex. Everything else should be obvious. Please try and help me, someone! I''m getting desperate!! Thanks in advance!

Share this post


Link to post
Share on other sites
neneboricua19    634
Could it be that the mesh includes some degenerate triangles? Have you tried to validate/clean the mesh (D3DXValidMesh, and D3DXCleanMesh), or maybe optimize it?

Also, if you just want to compute the bounding sphere of a single triangle, you might as well write your own function to do it because it''s extremely simple.

What the heck, I''ll go ahead and write it for you:

// a couple of helper functions
D3DXVECTOR3 min3Vec( const D3DXVECTOR3 &v0, const D3DXVECTOR3 &v1, const D3DXVECTOR3 &v2 )
{
D3DXVECTOR3 temp = v0;
if( v1.x < temp.x && v1.y < temp.y && v1.z < temp.z ) temp = v1;
if( v2.x < temp.x && v2.y < temp.y && v2.z < temp.z ) temp = v2;
return temp;
}

D3DXVECTOR3 max3Vec( const D3DXVECTOR3 &v0, const D3DXVECTOR3 &v1, const D3DXVECTOR3 &v2 )
{
D3DXVECTOR3 temp = v0;
if( v1.x > temp.x && v1.y > temp.y && v1.z > temp.z ) temp = v1;
if( v2.x > temp.x && v2.y > temp.y && v2.z > temp.z ) temp = v2;
return temp;
}

BOUNDINGSPHERE ComputeBoundingSphere( const D3DXVECTOR3 &v0, const D3DXVECTOR3 &v1, const D3DXVECTOR3 &v2 )
{
BOUNDINGSPHERE boundingSphere;
D3DXVECTOR3 vMin = min3Vec( v0, v1, v2 );
D3DXVECTOR3 vMax = max3Vec( v0, v1, v2 );

boundingSphere.vCenter = (vMax+vMin)/2.0f;
boundingSphere.fRadius = D3DXVec3Length( &(vMax - boundingSphere.vCenter) );

return boundingSphere;
}

To call this function, you would do something like this:

BOUNDINGSPHERE bSphere = ComputeBoundingSphere( vert[pIndices[3*i]].position, vert[pindices[3*i+1]].position, vert[pIndices[3*i+2]].position );

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
ms291052    223
Your code looks all right for the most part... Personally I''d prefer to see vert[pIndices[3*i]] instead of the + sign with pointers. Do you really mean to have it be cModel.center or did you need to have a cModel.center[i+0] in there?

If nothing else, it could be a memory bug, possibly that your vert pointer isn''t laid out in consecutive memory, which would completely knacker the vert + pIndices[3*i], as well as possibly the internal code where (I image) it repetively adds the stride to the vertex you pass it.

Share this post


Link to post
Share on other sites
jacklin    124
You are assuming each face uses vertices that are contiguous in the vertex buffer. For example, a face using vertex 15, 16, and 17.

In reality, that is not true. What you need to do is create an array of three vertices, then copy each vertex of a face to this array. Then you pass this array to D3DXComputeBoundingSphere. The code looks somewhat like this:

YOURVERTEXTYPE TriVert[3];

// In loop

TriVert[0] = vert[ pIndices[3*i] ];
TriVert[1] = vert[ pIndices[3*i+1] ];
TriVert[2] = vert[ pIndices[3*i+2] ];

D3DXComputeBoundingSphere(TriVert, 3 , D3DXGetFVFVertexSize(meshClone->GetFVF() ), &cModel.center, &cModel[i].radius);

Share this post


Link to post
Share on other sites