Hi,

I have a strange problem with calculating my AABB extents, min and max.

For testing I places 2 small cubes in my scene, which constantly take over the AABB's min and max vertices as a world position.

This perfectly illustrates the sympton.

Only with 90, 180, 270 or 360 degrees rotation the extents match the real min and max points of the rotating object.

Here's the video:

Below are the related code parts.

This is what I do:

- calculate the AABB initally with untransformed, not rotated verticies

- the 8 corners are stored in a 'base' vertex array

- every frame where the object is moved or rotated, I transform the 8 base vertices with the new matrix

- then I find the min/ max extents to use for AABB culling

Can someone help me out?

// initial creation of the AABB void CreateAABB(TVERTEX *pVtxArray, DWORD pStart, DWORD pNr, BOUNDINGBOX *pBox) { // MIN and MAX vertices pBox->min.x = pVtxArray[pStart].position.x; pBox->min.y = pVtxArray[pStart].position.y; pBox->min.z = pVtxArray[pStart].position.z; pBox->max.x = pVtxArray[pStart].position.x; pBox->max.y = pVtxArray[pStart].position.y; pBox->max.z = pVtxArray[pStart].position.z; for(DWORD vc=pStart;vc<pStart+pNr;++vc) { if(pVtxArray[vc].position.x < pBox->min.x) pBox->min.x = pVtxArray[vc].position.x; if(pVtxArray[vc].position.x > pBox->max.x) pBox->max.x = pVtxArray[vc].position.x; if(pVtxArray[vc].position.y < pBox->min.y) pBox->min.y = pVtxArray[vc].position.y; if(pVtxArray[vc].position.y > pBox->max.y) pBox->max.y = pVtxArray[vc].position.y; if(pVtxArray[vc].position.z < pBox->min.z) pBox->min.z = pVtxArray[vc].position.z; if(pVtxArray[vc].position.z > pBox->max.z) pBox->max.z = pVtxArray[vc].position.z; } // FULL 8 vertices of the AABB pBox->boxArrayBase[0].x = pBox->min.x; pBox->boxArrayBase[0].y = pBox->min.y; pBox->boxArrayBase[0].z = pBox->min.z; pBox->boxArrayBase[1].x = pBox->max.x; pBox->boxArrayBase[1].y = pBox->max.y; pBox->boxArrayBase[1].z = pBox->max.z; pBox->boxArrayBase[2].x = pBox->max.x; pBox->boxArrayBase[2].y = pBox->max.y; pBox->boxArrayBase[2].z = pBox->min.z; pBox->boxArrayBase[3].x = pBox->min.x; pBox->boxArrayBase[3].y = pBox->max.y; pBox->boxArrayBase[3].z = pBox->min.z; pBox->boxArrayBase[4].x = pBox->min.x; pBox->boxArrayBase[4].y = pBox->min.y; pBox->boxArrayBase[4].z = pBox->max.z; pBox->boxArrayBase[5].x = pBox->max.x; pBox->boxArrayBase[5].y = pBox->min.y; pBox->boxArrayBase[5].z = pBox->max.z; pBox->boxArrayBase[6].x = pBox->max.x; pBox->boxArrayBase[6].y = pBox->min.y; pBox->boxArrayBase[6].z = pBox->min.z; pBox->boxArrayBase[7].x = pBox->min.x; pBox->boxArrayBase[7].y = pBox->max.y; pBox->boxArrayBase[7].z = pBox->max.z; for(int i=0;i<8;++i) pBox->boxArray[i] = pBox->boxArrayBase[i]; pBox->created = true; } // updating the AABB bool UpdateAABB(BOUNDINGBOX *pBox) { if(!pBox->created) return false; // 8 AABB corners need to be transformed by the latest world matrix // now find the 2 extents pBox->min.x = pBox->boxArray[0].x; pBox->min.y = pBox->boxArray[0].y; pBox->min.z = pBox->boxArray[0].z; pBox->max.x = pBox->boxArray[0].x; pBox->max.y = pBox->boxArray[0].y; pBox->max.z = pBox->boxArray[0].z; for(int vc=0;vc<8;++vc) { if(pBox->boxArray[vc].x < pBox->min.x) pBox->min.x = pBox->boxArray[vc].x; if(pBox->boxArray[vc].x > pBox->max.x) pBox->max.x = pBox->boxArray[vc].x; if(pBox->boxArray[vc].y < pBox->min.y) pBox->min.y = pBox->boxArray[vc].y; if(pBox->boxArray[vc].y > pBox->max.y) pBox->max.y = pBox->boxArray[vc].y; if(pBox->boxArray[vc].z < pBox->min.z) pBox->min.z = pBox->boxArray[vc].z; if(pBox->boxArray[vc].z > pBox->max.z) pBox->max.z = pBox->boxArray[vc].z; } return true; } // update the world matrix bool CD3dmeshInst::UpdateWorldMatrix() { if(!mDynamic) return false; if(!mIsMoved && !mIsRotated && !mIsScaled) return false; if(mIsMoved) { D3DXMatrixIdentity(&mMatTranslate); D3DXMatrixTranslation(&mMatTranslate, mWorldPos.x, mWorldPos.y, mWorldPos.z); } if(mIsRotated) { D3DXMatrixIdentity(&mMatRotateX); D3DXMatrixRotationX(&mMatRotateX, D3DXToRadian(mRot.x)); D3DXMatrixIdentity(&mMatRotateY); D3DXMatrixRotationY(&mMatRotateY, D3DXToRadian(mRot.y)); D3DXMatrixIdentity(&mMatRotateZ); D3DXMatrixRotationZ(&mMatRotateZ, D3DXToRadian(mRot.z)); } if(mScale) { D3DXMatrixIdentity(&mMatScale); D3DXMatrixScaling(&mMatScale, mScale, mScale, mScale); } mMatWorld = (D3DXMATRIXA16)(mMatScale*mMatRotateX*mMatRotateY*mMatRotateZ*mMatTranslate); D3DXMatrixInverse(&mMatWorldInv, NULL, &mMatWorld); D3DXMatrixTranspose(&mMatWorldInvTransp, &mMatWorldInv); return true; } // update the bounding volume based on new world matrix bool CD3dmeshInst::UpdateBVWorldSpace() { // WORLD MATRIX should be already updated if(!mDynamic) return false; // FULL mesh if(mIsMoved || mIsRotated || mIsScaled) // TO BE SPECIFIED LATER { mBoundingRadius = mBoundingRadiusBase * mScale; for(int i=0;i<8;++i) D3DXVec3TransformCoord(&mBoundingBox.boxArray[i], &mBoundingBox.boxArrayBase[i], &mMatWorld); if(!UpdateAABB(&mBoundingBox)) return false; } return true; }

Rotation, translation etc. of the mesh all work fine, I use the same updated mMatWorld matrix for rendering the mesh through my shaders without problems. Maybe something wrong with updating/ transforming the boundingbox corners/ extents? radians and degrees?

Help );