HRESULT C3DDisplayObject::CheckForGroundCollsion(){ bool bGroundCollide = false; D3DXVECTOR3 v1; D3DXVECTOR3 v2; D3DXVECTOR3 vP; D3DXVECTOR3 vN; D3DXVECTOR3 vPtOnGround; D3DXVECTOR3 vPtOnBoundingPlaneNearestGround; const D3DXVECTOR3 vUp = D3DXVECTOR3(0.0f,1.0f,0.0f); if( m_bRenderBoundingBox ) { g_p3DDrawManager->InvalidatePoints( m_dwID ); g_p3DDrawManager->InvalidateLines( m_dwID ); } int nNumCollides = 0; for(;;) { bGroundCollide = false; for( int i=0; i<8; i++ ) { vPtOnGround = m_vBoundingVertexWorld[i]; vPtOnGround.y = g_pTerrain->GetHeight( vPtOnGround.x, vPtOnGround.z ); HRESULT hr = ResolveCollsionWithGroundPt( m_vBoundingVertexWorld[i], vPtOnGround ); if( hr == APP_S_COLLIDING ) { bGroundCollide = true; break; } } // Stop if there weren't any collisions found if( !bGroundCollide ) break; nNumCollides++; // Keep going if there's a lot of collides (unlikely) if( nNumCollides > 20 ) break; // If there have been too many collides then // cheat a little by raising the object up if( nNumCollides > 10 ) { for( int i=0; i<8; i++ ) { float fDelta = g_pTerrain->GetHeight( m_vBoundingVertexWorld[i].x, m_vBoundingVertexWorld[i].z ) - m_vBoundingVertexWorld[i].y; if( fDelta > 0.0f ) { // Raise all bounding box points and m_vCMPos for( int j=0; j<8; j++ ) m_vBoundingVertexWorld[j].y += fDelta; m_pResult->m_vCMPos.y += fDelta; } } } } if( m_bRenderBoundingBox ) { D3DXVECTOR3 vNormalsVertexWorld[12]; DWORD dwBounding[24] = { 0,1, 2,3, 0,2, 1,3, 4,5, 6,7, 4,6, 5,7, 0,4, 2,6, 1,5, 3,7 }; DWORD dwColor; if( bGroundCollide ) dwColor = 0xFFFF0000; else dwColor = 0xFFFFFFFF; g_p3DDrawManager->InvalidateLines( m_dwID+10000 ); for( int i=0; i<12; i++ ) { g_p3DDrawManager->AddLine( m_vBoundingVertexWorld[ dwBounding[i*2] ], m_vBoundingVertexWorld[ dwBounding[i*2+1] ], dwColor, m_dwID+10000, FALSE ); } static const DWORD dwBoundFaces[6][4] = { {0,1, 2,3}, // front {4,5, 0,1}, // bottom {1,5, 3,7}, // right {4,0, 6,2}, // left {5,4, 7,6}, // back {2,3, 6,7} };// top D3DXVECTOR3 vBoundFaceNormals[6]; for( int iFace=3; iFace<4; iFace++ ) { dwColor = 0xFF0000FF; D3DXVECTOR3 vP; D3DXVECTOR3 vN; D3DXVECTOR3 vP2; v1 = m_pModel->m_vBoundingVertex[dwBoundFaces[iFace][1]] - m_pModel->m_vBoundingVertex[dwBoundFaces[iFace][0]]; v2 = m_pModel->m_vBoundingVertex[dwBoundFaces[iFace][2]] - m_pModel->m_vBoundingVertex[dwBoundFaces[iFace][0]]; vP2 = m_pModel->m_vBoundingVertex[dwBoundFaces[iFace][0]] + v1 / 2.0f + v2 / 2.0f; D3DXVec3TransformNormal( &vP, &vP2, &m_pResult->m_mOrientation ); vP += m_pResult->m_vCMPos; D3DXVec3Cross( &vN, &v2, &v1 ); D3DXVec3Normalize( &vN, &vN ); D3DXVec3TransformNormal( &vBoundFaceNormals[iFace], &vN, &m_pResult->m_mOrientation ); g_p3DDrawManager->AddLine( vP, vP + vBoundFaceNormals[iFace], dwColor, m_dwID+10000, FALSE ); } } return S_OK;}//-----------------------------------------------------------------------------
2005年12月10日 02点12分
22