void PhysxBone::Initiliaze(MeshFilter* pMeshFilter) { //Map the bone MapToBone(pMeshFilter); //Create actor and set it on the correct position CreatePhysxBone(pMeshFilter); } void PhysxBone::MapToBone(MeshFilter* pMeshFilter) { //Find the bone we want to map to for(auto bone : pMeshFilter->GetSkeleton()) { if(m_boneLayout.name == bone.Name) { m_pBone = &bone; break; } } //Check if we found our bone, else there is a mistake with the input ASSERT(m_pBone!=nullptr, _T("PhysxBone NAME INCORRECT! PhysxBone can not be mapped to a Bone in the Model!")); if(m_pBone) { //Store the index m_iBoneIndex = m_pBone->Index; //Get all it's parent and calculate the total offset, or the position in modelspace int currentParentIndex = m_pBone->Parent; vector vOffsets; //get all offsets first while(currentParentIndex > -1) { vOffsets.push_back(pMeshFilter->GetSkeleton().at(currentParentIndex).Offset); currentParentIndex = pMeshFilter->GetSkeleton().at(currentParentIndex).Parent; } //inverse the vector and calculate the total offset std::reverse(vOffsets.begin(), vOffsets.end()); for(auto offset : vOffsets) { m_matTotalOffset *= offset; } //finally adding it's own offset to the calculation to get the final position on modelspace m_matTotalOffset *= m_pBone->Offset; //when we know the transform in modelspace calculate the transform in worldspace //FIXME: worldtransform of model is hardcoded atm!! D3DXMATRIX world; D3DXMatrixIdentity(&world); m_matWorldSpace = m_matTotalOffset * world; } } void PhysxBone::UpdateLeechMode(D3DXMATRIX matKeyTransform) { //Calculate the final position //Orientation * TotalOffset * LocalTransformAnimation m_matWorldSpace = m_matTotalOffset * matKeyTransform * world; //Convert matrix and position the actor NxMat34 nPos; PhysicsManager::GetInstance()->DMatToNMat(nPos, m_matWorldSpace); m_pActor->setGlobalPose(nPos); } void PhysxBone::CreatePhysxBone(MeshFilter* pMeshFilter) { //Creates the bone using the information we know when we mapped the bone //Also taking into account which shape we want if(m_boneLayout.shapeType == RagdollShapeType::capsule) { //Create the capsule shape desc NxCapsuleShapeDesc capsuleDesc; capsuleDesc.height = m_boneLayout.height; capsuleDesc.radius = m_boneLayout.radius; capsuleDesc.localPose.t = NxVec3(0, capsuleDesc.radius + 0.5f * capsuleDesc.height, 0); //Create body so the actor is dynamic NxBodyDesc bodyDesc; bodyDesc.setToDefault(); bodyDesc.angularDamping = 0.75f; bodyDesc.linearVelocity = NxVec3(0,0,0); //Create the actor NxActorDesc actorDesc; actorDesc.shapes.pushBack(&capsuleDesc); actorDesc.body = &bodyDesc; actorDesc.density = 10.0f; //Important to set a density if we have a body to succesfully create an actor with a body //Position the actor to the correct place NxMat34 nPos; PhysicsManager::GetInstance()->DMatToNMat(nPos, m_matWorldSpace); actorDesc.globalPose = nPos; //Create the actor m_pActor = m_pPhysicsScene->createActor(actorDesc); if(!m_pActor) Logger::Log(_T("Error creating actor"), LogLevel::Error); //Default set our actor to be kinematic m_pActor->raiseBodyFlag(NX_BF_KINEMATIC); m_pActor->raiseActorFlag(NX_AF_DISABLE_COLLISION); } else if(m_boneLayout.shapeType == RagdollShapeType::sphere) { //Create the sphere shape desc NxSphereShapeDesc sphereDesc; sphereDesc.radius = m_boneLayout.radius; sphereDesc.localPose.t = NxVec3(0, m_boneLayout.radius, 0); //Create body so the actor is dynamic NxBodyDesc bodyDesc; bodyDesc.setToDefault(); bodyDesc.angularDamping = 0.75f; bodyDesc.linearVelocity = NxVec3(0,0,0); NxActorDesc actorDesc; actorDesc.shapes.pushBack(&sphereDesc); actorDesc.body = &bodyDesc; actorDesc.density = 10.0f; //Important to set a density if we have a body to succesfully create an actor with a body //Position the actor to the correct place NxMat34 nPos; PhysicsManager::GetInstance()->DMatToNMat(nPos, m_matWorldSpace); actorDesc.globalPose = nPos; //Create the actor m_pActor = m_pPhysicsScene->createActor(actorDesc); if(!m_pActor) Logger::Log(_T("Error creating actor"), LogLevel::Error); //Default set our actor to be kinematic m_pActor->raiseBodyFlag(NX_BF_KINEMATIC); m_pActor->raiseActorFlag(NX_AF_DISABLE_COLLISION); } }