Implemented with succes, from the point of view of the result that is :)
LSpiro (and others); any feedback is appreciated.
bool CD3dmeshInst::UpdateBVWorldSpace()
{
// WORLD MATRIX should be already updated
if(!mDynamic) return false;
// FULL mesh
if(mIsMoved || mIsRotated || mIsScaled)
{
// Update bounding sphere
D3DXVec3TransformCoord(&mSphereCenterWorldspace, &mSphereCenterModelspace, &mMatWorld);
mSphereBoundingRadius = mSphereBoundingRadiusBase * mScale;
// Update OBB - stays unchanged if no renderables 'exceed'
for(int i=0;i<8;++i) D3DXVec3TransformCoord(&mBoundingBox.OBBcorners[i], &mBoundingBox.AABBcorners[i], &mMatWorld);
UpdateAABBWorld(&mBoundingBox);
D3DXVec3TransformCoord(&mBoundingBox.OBBcenter, &mBoundingBox.AABBcenter, &mMatWorld);
// Update bounding volumes of all renderables + update Bounding Volume of parent/ instance
for(size_t obj=0;obj<GetNrRenderables();++obj)
{
auto &renderable = mRenderables[obj];
renderable.UpdateBVWorldSpace();
if(renderable.GetDynamic())
{
// UPDATE sphere radius is needed
float dist = CoordToCoordDist(renderable.GetSphereCenterWorld(), mSphereCenterWorldspace);
if(dist + renderable.GetSphereBoundingRadius() > mSphereBoundingRadius)
mSphereBoundingRadius = dist + renderable.GetSphereBoundingRadius();
// Update OBB and AABB if needed
if(UpdateOBB(&mBoundingBox, renderable.GetBoundingBox()))
{
UpdateAABBWorld(&mBoundingBox);
}
}
}
}
return true;
}
// updating an OBB if needed
/**************************************************************************************/
/*** UPDATE OBB ***/
/*** ==> usage: to update the OBB if another/ child impacts the OBB ***/
/*** ==> compares parent and child OBB and updates parent if child exceeds parent ***/
/**************************************************************************************/
bool UpdateOBB(BOUNDINGBOX *pParentBox, const BOUNDINGBOX &pChildBox)
{
if(pParentBox == NULL) return false;
// first find OBB MIN and MAX
D3DXVECTOR3 parentOBBmin = pParentBox->OBBcorners[0];
D3DXVECTOR3 parentOBBmax = pParentBox->OBBcorners[0];
D3DXVECTOR3 childOBBmin = pChildBox.OBBcorners[0];
D3DXVECTOR3 childOBBmax = pChildBox.OBBcorners[0];
for(int vtx=0;vtx<8;++vtx)
{
// parent
if(pParentBox->OBBcorners[vtx].x < parentOBBmin.x) parentOBBmin.x = pParentBox->OBBcorners[vtx].x;
if(pParentBox->OBBcorners[vtx].y < parentOBBmin.y) parentOBBmin.y = pParentBox->OBBcorners[vtx].y;
if(pParentBox->OBBcorners[vtx].z < parentOBBmin.z) parentOBBmin.z = pParentBox->OBBcorners[vtx].z;
if(pParentBox->OBBcorners[vtx].x > parentOBBmax.x) parentOBBmax.x = pParentBox->OBBcorners[vtx].x;
if(pParentBox->OBBcorners[vtx].y > parentOBBmax.y) parentOBBmax.y = pParentBox->OBBcorners[vtx].y;
if(pParentBox->OBBcorners[vtx].z > parentOBBmax.z) parentOBBmax.z = pParentBox->OBBcorners[vtx].z;
// child
if(pChildBox.OBBcorners[vtx].x < childOBBmin.x) childOBBmin.x = pChildBox.OBBcorners[vtx].x;
if(pChildBox.OBBcorners[vtx].y < childOBBmin.y) childOBBmin.y = pChildBox.OBBcorners[vtx].y;
if(pChildBox.OBBcorners[vtx].z < childOBBmin.z) childOBBmin.z = pChildBox.OBBcorners[vtx].z;
if(pChildBox.OBBcorners[vtx].x > childOBBmax.x) childOBBmax.x = pChildBox.OBBcorners[vtx].x;
if(pChildBox.OBBcorners[vtx].y > childOBBmax.y) childOBBmax.y = pChildBox.OBBcorners[vtx].y;
if(pChildBox.OBBcorners[vtx].z > childOBBmax.z) childOBBmax.z = pChildBox.OBBcorners[vtx].z;
}
// check if child 'exceeds' parent
bool changed = false;
D3DXVECTOR3 newOBBmin = parentOBBmin;
D3DXVECTOR3 newOBBmax = parentOBBmax;
if(childOBBmin.x < parentOBBmin.x) { newOBBmin.x = childOBBmin.x; changed = true; };
if(childOBBmin.y < parentOBBmin.y) { newOBBmin.y = childOBBmin.y; changed = true; };
if(childOBBmin.z < parentOBBmin.z) { newOBBmin.z = childOBBmin.z; changed = true; };
if(childOBBmax.x > parentOBBmax.x) { newOBBmax.x = childOBBmax.x; changed = true; };
if(childOBBmax.y > parentOBBmax.y) { newOBBmax.y = childOBBmax.y; changed = true; };
if(childOBBmax.z > parentOBBmax.z) { newOBBmax.z = childOBBmax.z; changed = true; };
if(changed)
{
// update OBB corners
pParentBox->OBBcorners[0].x = newOBBmin.x;
pParentBox->OBBcorners[0].y = newOBBmin.y;
pParentBox->OBBcorners[0].z = newOBBmin.z;
pParentBox->OBBcorners[1].x = newOBBmax.x;
pParentBox->OBBcorners[1].y = newOBBmax.y;
pParentBox->OBBcorners[1].z = newOBBmax.z;
pParentBox->OBBcorners[2].x = newOBBmax.x;
pParentBox->OBBcorners[2].y = newOBBmax.y;
pParentBox->OBBcorners[2].z = newOBBmin.z;
pParentBox->OBBcorners[3].x = newOBBmin.x;
pParentBox->OBBcorners[3].y = newOBBmax.y;
pParentBox->OBBcorners[3].z = newOBBmin.z;
pParentBox->OBBcorners[4].x = newOBBmin.x;
pParentBox->OBBcorners[4].y = newOBBmin.y;
pParentBox->OBBcorners[4].z = newOBBmax.z;
pParentBox->OBBcorners[5].x = newOBBmax.x;
pParentBox->OBBcorners[5].y = newOBBmin.y;
pParentBox->OBBcorners[5].z = newOBBmax.z;
pParentBox->OBBcorners[6].x = newOBBmax.x;
pParentBox->OBBcorners[6].y = newOBBmin.y;
pParentBox->OBBcorners[6].z = newOBBmin.z;
pParentBox->OBBcorners[7].x = newOBBmin.x;
pParentBox->OBBcorners[7].y = newOBBmax.y;
pParentBox->OBBcorners[7].z = newOBBmax.z;
pParentBox->OBBsize.x = newOBBmax.x - newOBBmin.x;
pParentBox->OBBsize.y = newOBBmax.y - newOBBmin.y;
pParentBox->OBBsize.z = newOBBmax.z - newOBBmin.z;
pParentBox->OBBcenter = newOBBmax - (pParentBox->OBBsize / 2.0f);
return true;
}
return false;
}