void RagDoll::UpdateSkeleton(Bone* bone) { if (bone == NULL) return; if (bone->m_pObb != NULL) { //Calculate new position for the bone D3DXMATRIX pos; D3DXVECTOR3 pivot = bone->m_pObb->GetPivot(bone->m_pivot); D3DXMatrixTranslation(&pos, pivot.x, pivot.y, pivot.z); //Calculate new orientation for the bone D3DXMATRIX rot; D3DXMatrixRotationQuaternion(&rot, &bone->m_pObb->GetRotation(bone->m_originalRot)); //Combine to create new transformation matrix bone->CombinedTransformationMatrix = rot * pos; //Update children bones with our new transformation matrix if (bone->pFrameFirstChild != NULL) UpdateMatrices((Bone*)bone->pFrameFirstChild, &bone->CombinedTransformationMatrix); } //Traverse the rest of the bone hierarchy UpdateSkeleton((Bone*)bone->pFrameSibling); UpdateSkeleton((Bone*)bone->pFrameFirstChild); }
void JModel::Render( const Mat4& tm, JBoneInstance* pSkelInst, bool bIgnoreShader, bool bUseCachedData ) { if (m_IBufID == -1) { Init(); } // check geometry caching status, update if needed g_pRenderServer->CacheIB( m_IBufID, m_Indices.GetData(), m_Indices.GetSize(), m_IBIteration, m_IBFirstByte ); int nBones = m_SkelInst.size(); // calculate world-space transforms for bones if (!pSkelInst && nBones > 0) pSkelInst = &m_SkelInst[0]; UpdateSkeleton( Mat4::identity, pSkelInst ); // cycle through geometries and render them int nGeom = m_Meshes.size(); int cMtl = -1; for (int i = 0; i < nGeom; i++) { JMesh* pMesh = m_Meshes[i]; if (!pMesh->IsVisible()) { continue; } pMesh->CacheVB(); int mtlID = pMesh->GetMaterialID(); if (mtlID >= 0 && mtlID != cMtl) { JMaterial* pMtl = m_Materials[mtlID]; pMtl->Render( bIgnoreShader ); cMtl = mtlID; } Mat4 worldTM = tm; int hostBoneID = pMesh->GetHostBoneID(); if (hostBoneID >= 0 && pMesh->GetNSkinBones() == 0) { JBoneInstance& hb = pSkelInst[hostBoneID]; if (!hb.m_bVisible) { continue; } Mat4 rootTM = hb.m_ModelTM*tm; worldTM = rootTM; } pMesh->Render( m_IBFirstByte, pSkelInst, worldTM, bUseCachedData ); } if (m_bDrawSkeleton) { DrawSkeleton( tm, pSkelInst ); } } // JModel::Render
void RagDoll::Render() { if (KeyDown(VK_RETURN)) { for (int i=0; i<(int)m_boxes.size(); i++) { m_boxes[i]->Render(); } } //Update Ragdoll from physical representation UpdateSkeleton((Bone*)m_pRootBone); //Render the ragdoll RenderMesh(NULL); }
void JModel::GatherChildren() { m_Materials.clear(); m_Meshes.clear(); GatherBones(); int nCh = GetNChildren(); for (int i = 0; i < nCh; i++) { JMaterial* pMaterial = obj_cast<JMaterial>( GetChild( i ) ); if (pMaterial) { m_Materials.push_back( pMaterial ); pMaterial->Init(); } } // calculate rest pose world transforms for bones UpdateSkeleton( Mat4::identity, NULL ); for (int i = 0; i < nCh; i++) { JMesh* pMesh = obj_cast<JMesh>( GetChild( i ) ); if (!pMesh) continue; // find material index const char* mtlName = pMesh->GetMaterialName(); int idx = -1; for (int j = 0; j < m_Materials.size(); j++) { if (!stricmp( m_Materials[j]->GetName(), mtlName )) { idx = j; break; } } pMesh->SetMaterialID( idx ); pMesh->SetModel( this ); pMesh->Init(); pMesh->LinkBones( &m_SkelInst[0], m_SkelInst.size() ); pMesh->SetModel( this ); m_Meshes.push_back( pMesh ); } } // JModel::GatherChildren