Here's what I have managed to come up with
Code:
bool CCollisionManager::FindNewVelocity(LPDIRECT3DDEVICE9 pDevice,
CMeshInstance* pMesh,
D3DXVECTOR3* pObjectPosition,
D3DXVECTOR3* pOldVelocity,
D3DXVECTOR3* pNewVelocity) {
BOOL Hit = FALSE;
float u, v, dist;
DWORD FaceIndex;
D3DXVECTOR3 ObjectDirection,
PrevObjectDirection,
Velocity = -(*pOldVelocity);
D3DXVECTOR3 PrevObjectPosition = *pObjectPosition - *pOldVelocity;
D3DXVec3Normalize(&ObjectDirection, &PrevObjectDirection);
// Get the normal of the intersected mesh face
// First, Get the vertex and index buffers for the mesh
LPDIRECT3DVERTEXBUFFER9 pVB;
LPDIRECT3DINDEXBUFFER9 pIB;
pMesh->GetMesh()->GetVertexBuffer(&pVB);
pMesh->GetMesh()->GetIndexBuffer(&pIB);
WORD *pIndices = NULL;
WORD *pIntersectedFaceIndex = NULL;
cstmVertex::PositionNormalTextured *pVertices = NULL;
cstmVertex::PositionNormalTextured *pIntersectedFaceVertex = NULL;
pIB->Lock(0, 0, (void**)&pIndices, 0);
pVB->Lock(0, 0, (void**)&pVertices, 0);
// Now find which mesh face was intersected
pDevice->SetTransform(D3DTS_WORLD, pMesh->GetTransform() );
D3DXIntersect(pMesh->GetMesh(),
&PrevObjectPosition,
&ObjectDirection,
&Hit,
&FaceIndex,
&u, &v, &dist,
NULL, NULL);
pIntersectedFaceIndex = &pIndices[3 * FaceIndex];
pIntersectedFaceVertex = &pVertices[*pIntersectedFaceIndex];
pVB->Unlock();
pIB->Unlock();
// Get the normal for the face
D3DXVECTOR3 PlaneNormal(pIntersectedFaceVertex->Nx,
pIntersectedFaceVertex->Ny,
pIntersectedFaceVertex->Nz);
// compute new velocity vector
if (Hit == TRUE) {
float dot = (D3DXVec3Dot(&Velocity, &PlaneNormal) );
*pNewVelocity = (2 * dot) * PlaneNormal + *pOldVelocity;
} else {
*pNewVelocity = *pOldVelocity;
}
return Hit;
}
Everything seems to work fine except for two issues :
- If there is a collision on any axis other than X I get a seg fault
- no mater which face was intersected, I allways get a face normal of (0.0, -1.0, 0.0)
I adapted this from the DX9 SDK sample 'Pick.cpp'
Anyone have any ideas as to what is going on? I've tried everything I can think of and am still at a loss.
Am I even on the right track here? Or is there a better way of getting the face normal?