From ce96ea5bf8039c074b36166868a4ed0f57803228 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Jun 2019 11:20:42 -0700 Subject: [PATCH] more correct rebuild OtherAvatar detailed pickable shapes --- interface/src/avatar/AvatarManager.cpp | 31 +++++++++++-------- interface/src/avatar/AvatarManager.h | 4 ++- .../src/avatar/MyCharacterController.cpp | 8 ++--- interface/src/avatar/MyCharacterController.h | 1 - interface/src/avatar/OtherAvatar.cpp | 8 ++--- interface/src/avatar/OtherAvatar.h | 4 +-- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index efe3d59d90..c88a934acf 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -435,7 +435,7 @@ DetailedMotionState* AvatarManager::createDetailedMotionState(OtherAvatarPointer return nullptr; } -void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar) { +void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) { if (!avatar->_motionState) { avatar->_motionState = new AvatarMotionState(avatar, nullptr); } @@ -452,20 +452,24 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction 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. - +void AvatarManager::removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) { // delete old detailedMotionStates auto& detailedMotionStates = avatar->getDetailedMotionStates(); if (detailedMotionStates.size() != 0) { for (auto& detailedMotionState : detailedMotionStates) { transaction.objectsToRemove.push_back(detailedMotionState); } - avatar->resetDetailedMotionStates(); + avatar->forgetDetailedMotionStates(); } +} - // build new detailedMotionStates +void AvatarManager::rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) { + // Rather than reconcile numbers of joints after change to model or LOD + // we blow away old detailedMotionStates and create anew all around. + removeDetailedAvatarPhysics(transaction, avatar); + auto& detailedMotionStates = avatar->getDetailedMotionStates(); OtherAvatar::BodyLOD lod = avatar->getBodyLOD(); if (lod == OtherAvatar::BodyLOD::Sphere) { auto dMotionState = createDetailedMotionState(avatar, -1); @@ -483,24 +487,21 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction } } } - avatar->_needsReinsertion = false; + avatar->_needsDetailedRebuild = false; } void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { _myAvatar->getCharacterController()->buildPhysicsTransaction(transaction); for (auto avatar : _otherAvatarsToChangeInPhysics) { bool isInPhysics = avatar->isInPhysicsSimulation(); - if (isInPhysics != avatar->shouldBeInPhysicsSimulation() || avatar->_needsReinsertion) { + 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(); + removeDetailedAvatarPhysics(transaction, avatar); } else { rebuildAvatarPhysics(transaction, avatar); + rebuildDetailedAvatarPhysics(transaction, avatar); } } else if (isInPhysics) { AvatarMotionState* motionState = avatar->_motionState; @@ -519,6 +520,10 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact } motionState->clearIncomingDirtyFlags(); } + + if (avatar->_needsDetailedRebuild) { + rebuildDetailedAvatarPhysics(transaction, avatar); + } } } _otherAvatarsToChangeInPhysics.clear(); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index db1bc125a4..ce23a80309 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -274,7 +274,9 @@ public slots: protected: AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) override; DetailedMotionState* createDetailedMotionState(OtherAvatarPointer avatar, int32_t jointIndex); - void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar); + void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar); + void removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar); + void rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar); private: explicit AvatarManager(QObject* parent = 0); diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index aef1bcd668..2f59b70592 100755 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -398,15 +398,13 @@ DetailedMotionState* MyCharacterController::createDetailedMotionStateForJoint(in } void MyCharacterController::clearDetailedMotionStates() { + // we don't actually clear the MotionStates here + // instead we twiddle some flags as a signal of what to do later _pendingFlags |= PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION; // We make sure we don't add them again _pendingFlags &= ~PENDING_FLAG_ADD_DETAILED_TO_SIMULATION; } -void MyCharacterController::resetDetailedMotionStates() { - _detailedMotionStates.clear(); -} - void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { for (size_t i = 0; i < _detailedMotionStates.size(); i++) { _detailedMotionStates[i]->forceActive(); @@ -416,6 +414,8 @@ void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction& for (size_t i = 0; i < _detailedMotionStates.size(); i++) { transaction.objectsToRemove.push_back(_detailedMotionStates[i]); } + // NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove + // See AvatarManager::handleProcessedPhysicsTransaction() _detailedMotionStates.clear(); } if (_pendingFlags & PENDING_FLAG_ADD_DETAILED_TO_SIMULATION) { diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 0b64f66850..7ddcf94f67 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -48,7 +48,6 @@ public: DetailedMotionState* createDetailedMotionStateForJoint(int32_t jointIndex); std::vector& getDetailedMotionStates() { return _detailedMotionStates; } void clearDetailedMotionStates(); - void resetDetailedMotionStates(); void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction); diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index 6f83c61cd6..a6e2d6a998 100755 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -177,7 +177,7 @@ const btCollisionShape* OtherAvatar::createCollisionShape(int32_t jointIndex, bo return ObjectMotionState::getShapeManager()->getShape(shapeInfo); } -void OtherAvatar::resetDetailedMotionStates() { +void OtherAvatar::forgetDetailedMotionStates() { // NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove // See AvatarManager::handleProcessedPhysicsTransaction() _detailedMotionStates.clear(); @@ -209,7 +209,7 @@ void OtherAvatar::computeShapeLOD() { if (newLOD != _bodyLOD) { _bodyLOD = newLOD; if (isInPhysicsSimulation()) { - _needsReinsertion = true; + _needsDetailedRebuild = true; } } } @@ -224,14 +224,14 @@ bool OtherAvatar::shouldBeInPhysicsSimulation() const { bool OtherAvatar::needsPhysicsUpdate() const { constexpr uint32_t FLAGS_OF_INTEREST = Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS | Simulation::DIRTY_POSITION | Simulation::DIRTY_COLLISION_GROUP; - return (_needsReinsertion || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST))); + return (_needsDetailedRebuild || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST))); } void OtherAvatar::rebuildCollisionShape() { if (_motionState) { // do not actually rebuild here, instead flag for later _motionState->addDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); - _needsReinsertion = true; + _needsDetailedRebuild = true; } } diff --git a/interface/src/avatar/OtherAvatar.h b/interface/src/avatar/OtherAvatar.h index 498971d6ee..cfe0c8332d 100644 --- a/interface/src/avatar/OtherAvatar.h +++ b/interface/src/avatar/OtherAvatar.h @@ -54,7 +54,7 @@ public: const btCollisionShape* createCollisionShape(int32_t jointIndex, bool& isBound, std::vector& boundJoints); std::vector& getDetailedMotionStates() { return _detailedMotionStates; } - void resetDetailedMotionStates(); + void forgetDetailedMotionStates(); BodyLOD getBodyLOD() { return _bodyLOD; } void computeShapeLOD(); @@ -90,7 +90,7 @@ protected: int32_t _spaceIndex { -1 }; uint8_t _workloadRegion { workload::Region::INVALID }; BodyLOD _bodyLOD { BodyLOD::Sphere }; - bool _needsReinsertion { false }; + bool _needsDetailedRebuild { false }; }; using OtherAvatarPointer = std::shared_ptr;