// Z3DBoundingVolumeObject.cpp: implementation of the CZ3DBoundingVolumeObject class. // ////////////////////////////////////////////////////////////////////// #include "Z3DBoundingVolumeObject.h" #include "GMMemory.h" bool CZ3DOBB::ms_bRender = false; D3DSLVERTEX CZ3DOBB::ms_pOutlineVertex[8] = { D3DSLVERTEX( 0, 0, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 0, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 0, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 0, 0, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 0, 1, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 1, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 1, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 0, 1, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ) }; WORD CZ3DOBB::ms_pOutlineIndex[24] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 }; ////////////////////////////////////////////////////////////////////////// bool CZ3DBoundingVolumeObject::ms_bRender = false; D3DSLVERTEX CZ3DBoundingVolumeObject::ms_pOutlineVertex[8] = { D3DSLVERTEX( 0, 0, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 0, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 0, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 0, 0, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 0, 1, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 1, 0, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 1, 1, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ), D3DSLVERTEX( 0, 1, 1, D3DCOLOR_ARGB(0xff,0xff,0xff,0xff) ) }; WORD CZ3DBoundingVolumeObject::ms_pOutlineIndex[24] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 }; void CZ3DOBB::SetStaticParameter( vector3& vExtent ) { m_vExtent = vExtent; } void CZ3DOBB::SetDynamicParameter( vector3& vCenter, matrix& rDir ) { m_aAxis[0].x = rDir._11; m_aAxis[0].y = rDir._12; m_aAxis[0].z = rDir._13; m_aAxis[1].x = rDir._21; m_aAxis[1].y = rDir._22; m_aAxis[1].z = rDir._23; m_aAxis[2].x = rDir._31; m_aAxis[2].y = rDir._32; m_aAxis[2].z = rDir._33; m_Center = vCenter; } bool CZ3DOBB::CheckCollision( const CZ3DOBB& rOBB ) const { // cutoff val. to check if two axes are parallel const float fCutoff = (float)0.999999f; bool bExistsParallelPair = false; int i; vector3 kD = rOBB.m_Center - m_Center; float aafC[3][3]; float aafAbsC[3][3]; float afAD[3]; float fR0, fR1, fR, fR01; // axis Box1 x for( i = 0; i < 3; ++i ) { aafC[0][i] = m_aAxis[0] * rOBB.m_aAxis[i]; aafAbsC[0][i] = fabs( aafC[0][i] ); if( aafAbsC[0][i] > fCutoff ) { bExistsParallelPair = true; } } afAD[0] = m_aAxis[0] * kD; fR = fabs( afAD[0] ); fR1 = rOBB.m_vExtent.x*aafAbsC[0][0] + rOBB.m_vExtent.y*aafAbsC[0][1] + rOBB.m_vExtent.z*aafAbsC[0][2]; fR01 = m_vExtent.x + fR1; if( fR > fR01 ) { return false; } // axis Box1 y for( i = 0; i < 3; ++i ) { aafC[1][i] = m_aAxis[1] * rOBB.m_aAxis[i]; aafAbsC[1][i] = fabs( aafC[1][i] ); if( aafAbsC[1][i] > fCutoff ) { bExistsParallelPair = true; } } afAD[1] = m_aAxis[1] * kD; fR = fabs( afAD[1] ); fR1 = rOBB.m_vExtent.x*aafAbsC[1][0] + rOBB.m_vExtent.y*aafAbsC[1][1] + rOBB.m_vExtent.z*aafAbsC[1][2]; fR01 = m_vExtent.y + fR1; if( fR > fR01 ) { return false; } // axis Box1 z for( i = 0; i < 3; ++i ) { aafC[2][i] = m_aAxis[2] * rOBB.m_aAxis[i]; aafAbsC[2][i] = fabs( aafC[2][i] ); if( aafAbsC[2][i] > fCutoff ) { bExistsParallelPair = true; } } afAD[2] = m_aAxis[2] * kD; fR = fabs( afAD[2] ); fR1 = rOBB.m_vExtent.x*aafAbsC[2][0] + rOBB.m_vExtent.y*aafAbsC[2][1] + rOBB.m_vExtent.z*aafAbsC[2][2]; fR01 = m_vExtent.z + fR1; if( fR > fR01 ) { return false; } // axis Box2 x fR = fabs( rOBB.m_aAxis[0] * kD ); fR0 = m_vExtent.x*aafAbsC[0][0] + m_vExtent.y*aafAbsC[1][0] + m_vExtent.z*aafAbsC[2][0]; fR01 = fR0 + rOBB.m_vExtent.x; if( fR > fR01 ) { return false; } // axis Box2 y fR = fabs( rOBB.m_aAxis[1] * kD ); fR0 = m_vExtent.x*aafAbsC[0][1] + m_vExtent.y*aafAbsC[1][1] + m_vExtent.z*aafAbsC[2][1]; fR01 = fR0 + rOBB.m_vExtent.y; if( fR > fR01 ) { return false; } // axis Box2 z fR = fabs( rOBB.m_aAxis[2] * kD ); fR0 = m_vExtent.x*aafAbsC[0][2] + m_vExtent.y*aafAbsC[1][2] + m_vExtent.z*aafAbsC[2][2]; fR01 = fR0 + rOBB.m_vExtent.z; if( fR > fR01 ) { return false; } // if( bExistsParallelPair ) { return true; } // axis Box1 x ^ Box2 x fR = fabs( afAD[2]*aafC[1][0] - afAD[1]*aafC[2][0] ); fR0 = m_vExtent.y*aafAbsC[2][0] + m_vExtent.z*aafAbsC[1][0]; fR1 = rOBB.m_vExtent.y*aafAbsC[0][2] + rOBB.m_vExtent.z*aafAbsC[1][0]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 x ^ Box2 y fR = fabs( afAD[2]*aafC[1][1] - afAD[1]*aafC[2][1] ); fR0 = m_vExtent.y*aafAbsC[2][1] + m_vExtent.z*aafAbsC[1][1]; fR1 = rOBB.m_vExtent.x*aafAbsC[0][2] + rOBB.m_vExtent.z*aafAbsC[0][0]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 x ^ Box2 z fR = fabs( afAD[2]*aafC[1][2] - afAD[1]*aafC[2][2] ); fR0 = m_vExtent.y*aafAbsC[2][2] + m_vExtent.z*aafAbsC[1][2]; fR1 = rOBB.m_vExtent.x*aafAbsC[0][1] + rOBB.m_vExtent.y*aafAbsC[0][0]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 y ^ Box2 x fR = fabs( afAD[0]*aafC[2][0] - afAD[2]*aafC[0][0] ); fR0 = m_vExtent.x*aafAbsC[2][0] + m_vExtent.z*aafAbsC[0][0]; fR1 = rOBB.m_vExtent.y*aafAbsC[1][2] + rOBB.m_vExtent.z*aafAbsC[1][1]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 y ^ Box2 y fR = fabs( afAD[0]*aafC[2][1] - afAD[2]*aafC[0][1] ); fR0 = m_vExtent.x*aafAbsC[2][1] + m_vExtent.z*aafAbsC[0][1]; fR1 = rOBB.m_vExtent.x*aafAbsC[1][2] + rOBB.m_vExtent.z*aafAbsC[1][0]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 y ^ Box2 z fR = fabs( afAD[0]*aafC[2][2] - afAD[2]*aafC[0][2] ); fR0 = m_vExtent.x*aafAbsC[2][2] + m_vExtent.z*aafAbsC[0][2]; fR1 = rOBB.m_vExtent.x*aafAbsC[1][1] + rOBB.m_vExtent.y*aafAbsC[1][0]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 z ^ Box2 x fR = fabs( afAD[1]*aafC[0][0] - afAD[0]*aafC[1][0] ); fR0 = m_vExtent.x*aafAbsC[1][0] + m_vExtent.y*aafAbsC[0][0]; fR1 = rOBB.m_vExtent.y*aafAbsC[2][2] + rOBB.m_vExtent.z*aafAbsC[2][1]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 z ^ Box2 y fR = fabs( afAD[1]*aafC[0][1] - afAD[0]*aafC[1][1] ); fR0 = m_vExtent.x*aafAbsC[1][1] + m_vExtent.y*aafAbsC[0][1]; fR1 = rOBB.m_vExtent.x*aafAbsC[2][2] + rOBB.m_vExtent.z*aafAbsC[2][0]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } // axis Box1 z ^ Box2 z fR = fabs( afAD[1]*aafC[0][2] - afAD[0]*aafC[1][2] ); fR0 = m_vExtent.x*aafAbsC[1][2] + m_vExtent.y*aafAbsC[0][2]; fR1 = rOBB.m_vExtent.x*aafAbsC[2][1] + rOBB.m_vExtent.y*aafAbsC[2][0]; fR01 = fR0 + fR1; if( fR > fR01 ) { return false; } return true; } void CZ3DOBB::Render() { if( !ms_bRender ) { return; } vector3 vTmp, vResult; vResult = -m_vExtent.x*m_aAxis[0] - m_vExtent.y*m_aAxis[1] - m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[0].x = vResult.x; ms_pOutlineVertex[0].y = vResult.y; ms_pOutlineVertex[0].z = vResult.z; vResult = m_vExtent.x*m_aAxis[0] - m_vExtent.y*m_aAxis[1] - m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[1].x = vResult.x; ms_pOutlineVertex[1].y = vResult.y; ms_pOutlineVertex[1].z = vResult.z; vResult = m_vExtent.x*m_aAxis[0] - m_vExtent.y*m_aAxis[1] + m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[2].x = vResult.x; ms_pOutlineVertex[2].y = vResult.y; ms_pOutlineVertex[2].z = vResult.z; vResult = -m_vExtent.x*m_aAxis[0] - m_vExtent.y*m_aAxis[1] + m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[3].x = vResult.x; ms_pOutlineVertex[3].y = vResult.y; ms_pOutlineVertex[3].z = vResult.z; vResult = -m_vExtent.x*m_aAxis[0] + m_vExtent.y*m_aAxis[1] - m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[4].x = vResult.x; ms_pOutlineVertex[4].y = vResult.y; ms_pOutlineVertex[4].z = vResult.z; vResult = m_vExtent.x*m_aAxis[0] + m_vExtent.y*m_aAxis[1] - m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[5].x = vResult.x; ms_pOutlineVertex[5].y = vResult.y; ms_pOutlineVertex[5].z = vResult.z; vResult = m_vExtent.x*m_aAxis[0] + m_vExtent.y*m_aAxis[1] + m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[6].x = vResult.x; ms_pOutlineVertex[6].y = vResult.y; ms_pOutlineVertex[6].z = vResult.z; vResult = -m_vExtent.x*m_aAxis[0] + m_vExtent.y*m_aAxis[1] + m_vExtent.z*m_aAxis[2] + m_Center; ms_pOutlineVertex[7].x = vResult.x; ms_pOutlineVertex[7].y = vResult.y; ms_pOutlineVertex[7].z = vResult.z; D3DMATRIX* pMat = GetIdentityD3DMatrix(); GetDevice()->SetTransform( D3DTS_WORLD, pMat ); GetDevice()->SetVertexShader( D3DFVF_SLVERTEX ); GetDevice()->DrawIndexedPrimitiveUP( D3DPT_LINELIST, 0, 8, 12, ms_pOutlineIndex, D3DFMT_INDEX16, ms_pOutlineVertex, sizeof(D3DSLVERTEX) ); } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CZ3DBoundingVolumeObject::CZ3DBoundingVolumeObject() : CZ3DObject(), CZ3DRenderable(false) { m_rpChrModel = NULL; m_vExtent.Identity(); m_fScaleFactor = 1.0f; } CZ3DBoundingVolumeObject::~CZ3DBoundingVolumeObject() { } void CZ3DBoundingVolumeObject::UpdateFrame() { CZ3DObject::UpdateFrame(); if( m_rpChrModel ) { m_Pos = m_fScaleFactor*m_Pos + m_rpChrModel->GetPosition(); } vector3 v = m_fScaleFactor * m_vExtent; m_OBB.SetStaticParameter( v ); m_OBB.SetDynamicParameter( m_Pos, m_TM ); } void CZ3DBoundingVolumeObject::Render() { if( !ms_bRender ) { return; } vector3 vTmp, vResult; vTmp = vector3( -m_OBB.m_vExtent.x, -m_OBB.m_vExtent.y, -m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[0].x = vResult.x; ms_pOutlineVertex[0].y = vResult.y; ms_pOutlineVertex[0].z = vResult.z; vTmp = vector3( m_OBB.m_vExtent.x, -m_OBB.m_vExtent.y, -m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[1].x = vResult.x; ms_pOutlineVertex[1].y = vResult.y; ms_pOutlineVertex[1].z = vResult.z; vTmp = vector3( m_OBB.m_vExtent.x, -m_OBB.m_vExtent.y, m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[2].x = vResult.x; ms_pOutlineVertex[2].y = vResult.y; ms_pOutlineVertex[2].z = vResult.z; vTmp = vector3( -m_OBB.m_vExtent.x, -m_OBB.m_vExtent.y, m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[3].x = vResult.x; ms_pOutlineVertex[3].y = vResult.y; ms_pOutlineVertex[3].z = vResult.z; vTmp = vector3( -m_OBB.m_vExtent.x, m_OBB.m_vExtent.y, -m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[4].x = vResult.x; ms_pOutlineVertex[4].y = vResult.y; ms_pOutlineVertex[4].z = vResult.z; vTmp = vector3( m_OBB.m_vExtent.x, m_OBB.m_vExtent.y, -m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[5].x = vResult.x; ms_pOutlineVertex[5].y = vResult.y; ms_pOutlineVertex[5].z = vResult.z; vTmp = vector3( m_OBB.m_vExtent.x, m_OBB.m_vExtent.y, m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[6].x = vResult.x; ms_pOutlineVertex[6].y = vResult.y; ms_pOutlineVertex[6].z = vResult.z; vTmp = vector3( -m_OBB.m_vExtent.x, m_OBB.m_vExtent.y, m_OBB.m_vExtent.z ); z3d::VectorRotate( vResult, vTmp, m_Dir ); vResult += m_OBB.m_Center; ms_pOutlineVertex[7].x = vResult.x; ms_pOutlineVertex[7].y = vResult.y; ms_pOutlineVertex[7].z = vResult.z; D3DMATRIX* pMat = GetIdentityD3DMatrix(); GetDevice()->SetTransform( D3DTS_WORLD, pMat ); GetDevice()->SetVertexShader( D3DFVF_SLVERTEX ); GetDevice()->DrawIndexedPrimitiveUP( D3DPT_LINELIST, 0, 8, 12, ms_pOutlineIndex, D3DFMT_INDEX16, ms_pOutlineVertex, sizeof(D3DSLVERTEX) ); }