// protected void AvatarManager::removeAvatarMotionState(AvatarSharedPointer avatar) { auto rawPointer = std::static_pointer_cast<Avatar>(avatar); AvatarMotionState* motionState = rawPointer->getMotionState(); if (motionState) { // clean up physics stuff motionState->clearObjectBackPointer(); rawPointer->setMotionState(nullptr); _avatarMotionStates.remove(motionState); _motionStatesToAdd.remove(motionState); _motionStatesToDelete.push_back(motionState); } }
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); }
void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { _myAvatar->getCharacterController()->buildPhysicsTransaction(transaction); for (auto avatar : _otherAvatarsToChangeInPhysics) { 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& motionState : detailedMotionStates) { transaction.objectsToRemove.push_back(motionState); } avatar->resetDetailedMotionStates(); } else { rebuildAvatarPhysics(transaction, avatar); } } else if (isInPhysics) { AvatarMotionState* motionState = avatar->_motionState; uint32_t flags = motionState->getIncomingDirtyFlags(); if (flags & EASY_DIRTY_PHYSICS_FLAGS) { motionState->handleEasyChanges(flags); } // NOTE: we don't call detailedMotionState->handleEasyChanges() here because they are KINEMATIC // and Bullet will automagically call DetailedMotionState::getWorldTransform() on all that are active. if (motionState->needsNewShape()) { rebuildAvatarPhysics(transaction, avatar); } else { if (flags & (Simulation::DIRTY_MOTION_TYPE | Simulation::DIRTY_COLLISION_GROUP)) { transaction.objectsToReinsert.push_back(motionState); } motionState->clearIncomingDirtyFlags(); } } } }