Problem with bounding sphere.

Started by
5 comments, last by QuadMV 17 years, 10 months ago
Hello, My bounding sphere function used to work okay. Unfortunately, my cMesh class has got a bit more sophisticated and caused a knock on effect. I've added code that computes the tangents of a supplied mesh. It clones the previous mesh into a new one with the extended FVF. Unfortunately, now the GetFVF() function I'm using returns this error: D3DX: ID3DXMesh::GetFVF: The declaration cannot be converted to an FVF SDK says:
Quote: This method can return 0 if the vertex format cannot be mapped directly to an FVF code. This will occur for a mesh created from a vertex declaration that doesn't have the same order and elements supported by the FVF codes.
Sounds like my problem... how do convert this declaration into an FVF compatible one? Heres the code which builds the tangents.
	// Expand the mesh to hold tangent data
    D3DVERTEXELEMENT9 decl[] =
    {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, 
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },  
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 }, 
        D3DDECL_END()
    };

    hr = m_pMesh->CloneMesh( dw32BitFlag | D3DXMESH_MANAGED, decl, g_device, 
		&l_pTempMesh );
    if (FAILED(hr))
	{
		StringCchPrintf( temp, 100, "cSimpleMesh::CloneMesh() - FAILED - '%s'\n", m_name );
		OutputDebugString( temp );
		SAFE_RELEASE(l_pTempMesh);	
		return;
	}

    hr = D3DXComputeTangent( l_pTempMesh, // input mesh 
		0, // TexStageIndex 
		0, // TangentIndex 
		0, // BinormIndex 
		0, // Wrap 
		pAdjacency//NULL // Adjacency 
		);

    m_pMesh->Release();
    m_pMesh = l_pTempMesh;

	delete pAdjacency;

	// END OF TANGENT BUILDER ----------------------------------------------------------------------

and heres the call to GetFVF():
D3DXVECTOR3 *vertices;
	if( SUCCEEDED( mesh->LockVertexBuffer( D3DLOCK_READONLY, (void**)&vertices ) ) )
	{
		D3DXComputeBoundingSphere( vertices, mesh->GetNumVertices(), D3DXGetFVFVertexSize( mesh->GetFVF() ), &m_sphere->centre, &m_sphere->radius );
		mesh->UnlockVertexBuffer();
	}


Thanks for yuor advice. Simon
Advertisement
OMG! I solved a problem unassisted:

	D3DXVECTOR3 *vertices;	if( SUCCEEDED( mesh->LockVertexBuffer( D3DLOCK_READONLY, (void**)&vertices ) ) )	{//		D3DXComputeBoundingSphere( vertices, mesh->GetNumVertices(), D3DXGetFVFVertexSize( mesh->GetFVF() ), &m_sphere->centre, &m_sphere->radius );		D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];		mesh->GetDeclaration(decl);		D3DXComputeBoundingSphere( vertices, mesh->GetNumVertices(), D3DXGetDeclVertexSize( decl, 0 ), &m_sphere->centre, &m_sphere->radius );		mesh->UnlockVertexBuffer();	}
Well you dont actually need the FVF, and given that FVF's are a relic from fixed-function and the rest of your code seems to be using declarations you may as well ditch it [smile]

If you want the stride for a vertex you can get that from the declaration:

D3DVERTEXELEMENT9 decl[ MAX_FVF_DECL_SIZE ];if( SUCCEEDED( mesh->GetDeclaration( decl ) ) ){    // Inspect the declaration to determine its size:    UINT stride = D3DXGetDeclVertexSize( decl, 0 );    // Now continue as normal:    D3DXVECTOR3 *vertices;    if( SUCCEEDED( mesh->LockVertexBuffer( D3DLOCK_READONLY, (void**)&vertices ) ) )    {        D3DXComputeBoundingSphere( vertices, mesh->GetNumVertices(), D3DXGetFVFVertexSize( mesh->GetFVF() ) stride, &m_sphere->centre, &m_sphere->radius );        mesh->UnlockVertexBuffer();    }}


Sorted [grin]

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

BLimey, this is one busy server....
Quote:Original post by sipickles
BLimey, this is one busy server....
What, you saying you dont like the 500's? It's this years fashion statement. [lol]

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by jollyjeffers
Quote:Original post by sipickles
BLimey, this is one busy server....
What, you saying you dont like the 500's? It's this years fashion statement. [lol]

Jack

Those 500's causes a vicious spiral. Whenever I get three in a row, I click hard and fast on 'Refresh' 20 times just to punish the server for being so mean.
[s]--------------------------------------------------------[/s]chromecode.com - software with source code
I just thought it might be worth noting a separate issue I had with D3DXComputeBoundingSphere that others may encounter. As you know this returns both the object virtual center and the radius. I know my model was centered at 0,0,0 and was basically square, so I expected the virtual center to be pretty close to 0,0,0, however it was quite a ways off. When I used just the radius to calculate against distance to see if I was within the sphere of this other object, I was entering the sphere way earlier than I should have. Long story short, I took the length of the virtual center from 0,0,0, then subtracted that from the calculated radius, and used this value as the new radius. Now it seems to be the real radius. I went so far as to draw a sphere around the object using this new radius and it covers the object perfectly. I also went back into 3dsmax and calculated the object radius and got the same value as the new radius. So for some of you, you might want that virtual center, but for me it wasn’t what I expected and by subtracting it out it actually gave me what I wanted.

Don’t know if this will help anyone, but I thought it worth mentioning.
3DMUVE is an amateur game development team, and the designer and developer of a new gaming technology “MUVE” for the gaming industry.

This topic is closed to new replies.

Advertisement