Hi,
Just can't figure out why I can't get my matrix rotation/ translation correct.
I try to achieve the following:
- for a mesh I have 'x' vertices
- they are in model/ local space
- calculate the bounding box min and max vertices (in model space)
- transform the min and max vertices into worldspace, by using the rotation and translation matrices
I can't get the expected result unless I:
- rotate/scale the vertices in model space
- then calculate the bounding box min and max vertices (model space, but rotated/scaled)
- transform the min and max vertices using only the translation matrix (world position)
Although it works the 1st way above, this makes me have to go through all vertices when an object is rotated/ scaled/ moved, and I need to update the min and max vertices. This I want to prevent.
Pseudo "updatebox" code:
transformcoordinate(min vertex, world matrix);
transformcoordinate(max vertex, world matrix);
Here is the code of both the OK and the not OK situation.
OK:
bool CD3dmeshInst::CalcRadiusAndWorldPos(CD3dmesh *pMesh)
{
TVERTEX *verticesPointer;
TVERTEX *vertices = new TVERTEX[pMesh->mMesh->GetNumVertices()];
pMesh->mVtxBuffer->Lock(0, 0, (void**)&verticesPointer, 0); //D3DLOCK_READONLY);
memcpy(vertices, verticesPointer, pMesh->mMesh->GetNumVertices()*D3DXGetDeclVertexSize(vtxdecl, 0));
pMesh->mVtxBuffer->Unlock();
// SCALE AND ROTATE ALL MESH VERTICES
D3DXMatrixScaling(&mMatScale, mScale, mScale, mScale);
D3DXMatrixRotationX(&mMatRotateX, D3DXToRadian(mRot.x));
D3DXMatrixRotationY(&mMatRotateY, D3DXToRadian(mRot.y));
D3DXMatrixRotationZ(&mMatRotateZ, D3DXToRadian(mRot.z));
mMatWorld = (D3DXMATRIXA16)(mMatScale*mMatRotateX*mMatRotateY*mMatRotateZ);
for(DWORD vc=0;vc<pMesh->mMesh->GetNumVertices();++vc)
D3DXVec3TransformCoord(&vertices[vc].position, &vertices[vc].position, &mMatWorld);
// VERTICES ARE STILL IN LOCAL SPACE (MODEL), BUT SCALED AND ROTATED
// bounding radius and AABB for full mesh
D3DXComputeBoundingSphere(&vertices[0].position, pMesh->mMesh->GetNumVertices(), D3DXGetDeclVertexSize(vtxdecl, 0), &pMesh->mMeshCenter, &mBoundingRadius);
CalcBoundingBox(vertices, 0, pMesh->mMesh->GetNumVertices(), &mBoundingBox);
// NOTE: MWORLDPOS IS NOW NOT RELATED TO mMESHCENTER
delete[] vertices;
// CREATE worldspace matrix and transform bounding volumes to worldspace (AABB, sphere)
CreateWorldMatrix();
D3DXVec3TransformCoord(&mBoundingBox.min, &mBoundingBox.min, &mMatTranslate);
D3DXVec3TransformCoord(&mBoundingBox.max, &mBoundingBox.max, &mMatTranslate);
return true;
}
Not OK (and goal):
bool CD3dmeshInst::CalcRadiusAndWorldPos(CD3dmesh *pMesh)
{
TVERTEX *verticesPointer;
TVERTEX *vertices = new TVERTEX[pMesh->mMesh->GetNumVertices()];
pMesh->mVtxBuffer->Lock(0, 0, (void**)&verticesPointer, 0); //D3DLOCK_READONLY);
memcpy(vertices, verticesPointer, pMesh->mMesh->GetNumVertices()*D3DXGetDeclVertexSize(vtxdecl, 0));
pMesh->mVtxBuffer->Unlock();
// VERTICES ARE IN LOCAL SPACE (MODEL), NOT SCALED AND ROTATED
// bounding radius and AABB for full mesh
D3DXComputeBoundingSphere(&vertices[0].position, pMesh->mMesh->GetNumVertices(), D3DXGetDeclVertexSize(vtxdecl, 0), &pMesh->mMeshCenter, &mBoundingRadius);
CalcBoundingBox(vertices, 0, pMesh->mMesh->GetNumVertices(), &mBoundingBox);
// NOTE: MWORLDPOS IS NOW NOT RELATED TO mMESHCENTER
// CREATE worldspace matrix and transform bounding volumes to worldspace (AABB, sphere)
CreateWorldMatrix();
D3DXVec3TransformCoord(&mBoundingBox.min, &mBoundingBox.min, &mMatWorld);
D3DXVec3TransformCoord(&mBoundingBox.max, &mBoundingBox.max, &mMatWorld);
// create worldmatrix does:
// D3DXMatrixTranslation(&mMatTranslate, mWorldPos.x, mWorldPos.y, mWorldPos.z);
// D3DXMatrixScaling(&mMatScale, mScale, mScale, mScale);
// D3DXMatrixRotationX(&mMatRotateX, D3DXToRadian(mRot.x));
// D3DXMatrixRotationY(&mMatRotateY, D3DXToRadian(mRot.y));
// D3DXMatrixRotationZ(&mMatRotateZ, D3DXToRadian(mRot.z));
// mMatWorld = (D3DXMATRIXA16)(mMatScale*mMatRotateX*mMatRotateY*mMatRotateZ*mMatTranslate);
return true;
}
Really like to hear your thoughts.