void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar) { if (!avatar->_motionState) { avatar->_motionState = new AvatarMotionState(avatar, nullptr); } AvatarMotionState* motionState = avatar->_motionState; ShapeInfo shapeInfo; avatar->computeShapeInfo(shapeInfo); const btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); assert(shape); motionState->setShape(shape); motionState->setMass(avatar->computeMass()); if (motionState->getRigidBody()) { transaction.objectsToReinsert.push_back(motionState); } else { transaction.objectsToAdd.push_back(motionState); } motionState->clearIncomingDirtyFlags(); // Rather than reconcile numbers of joints after change to model or LOD // we blow away old detailedMotionStates and create anew all around. // delete old detailedMotionStates auto& detailedMotionStates = avatar->getDetailedMotionStates(); if (detailedMotionStates.size() != 0) { for (auto& detailedMotionState : detailedMotionStates) { transaction.objectsToRemove.push_back(detailedMotionState); } avatar->resetDetailedMotionStates(); } // build new detailedMotionStates OtherAvatar::BodyLOD lod = avatar->getBodyLOD(); if (lod == OtherAvatar::BodyLOD::Sphere) { auto dMotionState = createDetailedMotionState(avatar, -1); if (dMotionState) { detailedMotionStates.push_back(dMotionState); transaction.objectsToAdd.push_back(dMotionState); } } else { int32_t numJoints = avatar->getJointCount(); for (int32_t i = 0; i < numJoints; i++) { auto dMotionState = createDetailedMotionState(avatar, i); if (dMotionState) { detailedMotionStates.push_back(dMotionState); transaction.objectsToAdd.push_back(dMotionState); } } } avatar->_needsReinsertion = false; }
void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { SetOfOtherAvatars failedShapeBuilds; for (auto avatar : _avatarsToChangeInPhysics) { bool isInPhysics = avatar->isInPhysicsSimulation(); if (isInPhysics != avatar->shouldBeInPhysicsSimulation()) { if (isInPhysics) { transaction.objectsToRemove.push_back(avatar->_motionState); avatar->_motionState = nullptr; auto& detailedMotionStates = avatar->getDetailedMotionStates(); for (auto& mState : detailedMotionStates) { transaction.objectsToRemove.push_back(mState); } avatar->resetDetailedMotionStates(); } else { if (avatar->getDetailedMotionStates().size() == 0) { avatar->createDetailedMotionStates(avatar); for (auto dMotionState : avatar->getDetailedMotionStates()) { transaction.objectsToAdd.push_back(dMotionState); } } if (avatar->getDetailedMotionStates().size() > 0) { ShapeInfo shapeInfo; avatar->computeShapeInfo(shapeInfo); btCollisionShape* shape = const_cast<btCollisionShape*>(ObjectMotionState::getShapeManager()->getShape(shapeInfo)); if (shape) { AvatarMotionState* motionState = new AvatarMotionState(avatar, shape); motionState->setMass(avatar->computeMass()); avatar->_motionState = motionState; transaction.objectsToAdd.push_back(motionState); } else { failedShapeBuilds.insert(avatar); } } else { failedShapeBuilds.insert(avatar); } } } else if (isInPhysics) { transaction.objectsToChange.push_back(avatar->_motionState); auto& detailedMotionStates = avatar->getDetailedMotionStates(); for (auto& mState : detailedMotionStates) { if (mState) { transaction.objectsToChange.push_back(mState); } } } } _avatarsToChangeInPhysics.swap(failedShapeBuilds); }