From 4c212fb1e56450c57f4f70792fd3c3041fd77da4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 10 Apr 2017 17:28:21 -0700 Subject: [PATCH 01/16] pull qApp spaghetti out of Avatar class some ends of spaghetti get pushed into AvatarManger class split Camera class into Camera base and FancyCamera derivation Application::getCamera() returns Camera by refence instead of pointer --- interface/src/FancyCamera.h | 3 --- interface/src/avatar/Avatar.cpp | 1 - 2 files changed, 4 deletions(-) diff --git a/interface/src/FancyCamera.h b/interface/src/FancyCamera.h index cd231cd929..9ffa6cafd8 100644 --- a/interface/src/FancyCamera.h +++ b/interface/src/FancyCamera.h @@ -13,9 +13,6 @@ #include "Camera.h" -#include - -// TODO: come up with a better name than "FancyCamera" class FancyCamera : public Camera { Q_OBJECT diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ce8ec44f6c..9360421417 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -59,7 +59,6 @@ namespace render { auto avatarPtr = static_pointer_cast(avatar); if (avatarPtr->isInitialized() && args) { PROFILE_RANGE_BATCH(*args->_batch, "renderAvatarPayload"); - // TODO AVATARS_RENDERER: remove need for qApp avatarPtr->render(args); } } From 65682a914da69a55ed7c75e1fd3a1165e345f291 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 14 Apr 2017 10:22:32 -0700 Subject: [PATCH 02/16] remove cufty AvatarManager LocalLights feature --- interface/src/Application.cpp | 6 ----- interface/src/avatar/Avatar.cpp | 31 +++++------------------ interface/src/avatar/AvatarManager.cpp | 35 -------------------------- interface/src/avatar/AvatarManager.h | 15 ----------- 4 files changed, 6 insertions(+), 81 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 39a4b8ee7c..8801989e44 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5451,12 +5451,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri entityScriptingInterface->setPacketSender(&_entityEditSender); entityScriptingInterface->setEntityTree(getEntities()->getTree()); - // AvatarManager has some custom types - AvatarManager::registerMetaTypes(scriptEngine); - - // give the script engine to the RecordingScriptingInterface for its callbacks - DependencyManager::get()->setScriptEngine(scriptEngine); - if (property(hifi::properties::TEST).isValid()) { scriptEngine->registerGlobalObject("Test", TestScriptingInterface::getInstance()); } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9360421417..a639b6880b 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -638,36 +638,17 @@ void Avatar::render(RenderArgs* renderArgs) { glm::vec3 toTarget = frustum.getPosition() - getPosition(); float distanceToTarget = glm::length(toTarget); - { - fixupModelsInScene(renderArgs->_scene); + fixupModelsInScene(renderArgs->_scene); - if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) { - // add local lights - const float BASE_LIGHT_DISTANCE = 2.0f; - const float LIGHT_FALLOFF_RADIUS = 0.01f; - const float LIGHT_EXPONENT = 1.0f; - const float LIGHT_CUTOFF = glm::radians(80.0f); - float distance = BASE_LIGHT_DISTANCE * getUniformScale(); - glm::vec3 position = _skeletonModel->getTranslation(); - glm::quat orientation = getOrientation(); - foreach (const AvatarManager::LocalLight& light, DependencyManager::get()->getLocalLights()) { - glm::vec3 direction = orientation * light.direction; - DependencyManager::get()->addSpotLight(position - direction * distance, - distance * 2.0f, light.color, 0.5f, LIGHT_FALLOFF_RADIUS, orientation, LIGHT_EXPONENT, LIGHT_CUTOFF); - } - } - - bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes); - if (renderBounding && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { - PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes"); - const float BOUNDING_SHAPE_ALPHA = 0.7f; - _skeletonModel->renderBoundingCollisionShapes(*renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA); - } + bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes); + if (renderBounding && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { + PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes"); + const float BOUNDING_SHAPE_ALPHA = 0.7f; + _skeletonModel->renderBoundingCollisionShapes(*renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA); } const float DISPLAYNAME_DISTANCE = 20.0f; setShowDisplayName(distanceToTarget < DISPLAYNAME_DISTANCE); - if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { auto& frustum = renderArgs->getViewFrustum(); auto textPosition = getDisplayNamePosition(); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c4bcb67a16..ef57211d5c 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -50,23 +50,6 @@ static const quint64 MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS = USECS_PER_SECOND / // We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key. const QUuid MY_AVATAR_KEY; // NULL key -static QScriptValue localLightToScriptValue(QScriptEngine* engine, const AvatarManager::LocalLight& light) { - QScriptValue object = engine->newObject(); - object.setProperty("direction", vec3toScriptValue(engine, light.direction)); - object.setProperty("color", vec3toScriptValue(engine, light.color)); - return object; -} - -static void localLightFromScriptValue(const QScriptValue& value, AvatarManager::LocalLight& light) { - vec3FromScriptValue(value.property("direction"), light.direction); - vec3FromScriptValue(value.property("color"), light.color); -} - -void AvatarManager::registerMetaTypes(QScriptEngine* engine) { - qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue); - qScriptRegisterSequenceMetaType >(engine); -} - AvatarManager::AvatarManager(QObject* parent) : _avatarsToFade(), _myAvatar(std::make_shared(qApp->thread(), std::make_shared())) @@ -387,24 +370,6 @@ void AvatarManager::deleteAllAvatars() { } } -void AvatarManager::setLocalLights(const QVector& localLights) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "setLocalLights", Q_ARG(const QVector&, localLights)); - return; - } - _localLights = localLights; -} - -QVector AvatarManager::getLocalLights() const { - if (QThread::currentThread() != thread()) { - QVector result; - QMetaObject::invokeMethod(const_cast(this), "getLocalLights", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(QVector, result)); - return result; - } - return _localLights; -} - void AvatarManager::getObjectsToRemoveFromPhysics(VectorOfMotionStates& result) { result.clear(); result.swap(_motionStatesToRemoveFromPhysics); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 45f1a597eb..074e0f4fba 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -64,16 +64,6 @@ public: bool shouldShowReceiveStats() const { return _shouldShowReceiveStats; } - class LocalLight { - public: - glm::vec3 color; - glm::vec3 direction; - }; - - Q_INVOKABLE void setLocalLights(const QVector& localLights); - Q_INVOKABLE QVector getLocalLights() const; - - void getObjectsToRemoveFromPhysics(VectorOfMotionStates& motionStates); void getObjectsToAddToPhysics(VectorOfMotionStates& motionStates); void getObjectsToChange(VectorOfMotionStates& motionStates); @@ -116,8 +106,6 @@ private: std::shared_ptr _myAvatar; quint64 _lastSendAvatarDataTime = 0; // Controls MyAvatar send data rate. - QVector _localLights; - bool _shouldShowReceiveStats = false; std::list> _collisionInjectors; @@ -129,7 +117,4 @@ private: bool _shouldRender { true }; }; -Q_DECLARE_METATYPE(AvatarManager::LocalLight) -Q_DECLARE_METATYPE(QVector) - #endif // hifi_AvatarManager_h From 63939728740a7fea32d30f21695b87a3b8b1190b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 14 Apr 2017 13:36:20 -0700 Subject: [PATCH 03/16] remove AvatarManager dependency from Avatar --- interface/src/avatar/Avatar.cpp | 16 ++++++++++------ interface/src/avatar/Avatar.h | 3 ++- interface/src/avatar/AvatarManager.h | 6 +----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index a639b6880b..84638f8008 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -28,7 +28,6 @@ #include #include -#include "AvatarManager.h" #include "AvatarMotionState.h" #include "Camera.h" #include "Menu.h" @@ -73,6 +72,12 @@ namespace render { } } +// static +bool showReceiveStats = false; +void Avatar::setShowReceiveStats(bool receiveStats) { + showReceiveStats = receiveStats; +} + Avatar::Avatar(QThread* thread, RigPointer rig) : AvatarData(), _skeletonOffset(0.0f), @@ -582,7 +587,6 @@ void Avatar::render(RenderArgs* renderArgs) { bool havePosition, haveRotation; if (_handState & LEFT_HAND_POINTING_FLAG) { - if (_handState & IS_FINGER_POINTING_FLAG) { int leftIndexTip = getJointIndex("LeftHandIndex4"); int leftIndexTipJoint = getJointIndex("LeftHandIndex3"); @@ -809,7 +813,7 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& view, const g void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const { PROFILE_RANGE_BATCH(batch, __FUNCTION__); - bool shouldShowReceiveStats = DependencyManager::get()->shouldShowReceiveStats() && !isMyAvatar(); + bool shouldShowReceiveStats = showReceiveStats && !isMyAvatar(); // If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return static const float CLIP_DISTANCE = 0.2f; @@ -1473,16 +1477,16 @@ QList Avatar::getSkeleton() { void Avatar::addToScene(AvatarSharedPointer myHandle, const render::ScenePointer& scene) { if (scene) { - render::Transaction transaction; auto nodelist = DependencyManager::get(); if (DependencyManager::get()->shouldRenderAvatars() && !nodelist->isIgnoringNode(getSessionUUID()) && !nodelist->isRadiusIgnoringNode(getSessionUUID())) { + render::Transaction transaction; addToScene(myHandle, scene, transaction); + scene->enqueueTransaction(transaction); } - scene->enqueueTransaction(transaction); } else { - qCWarning(interfaceapp) << "AvatarManager::addAvatar() : Unexpected null scene, possibly during application shutdown"; + qCWarning(interfaceapp) << "Avatar::addAvatar() : Unexpected null scene, possibly during application shutdown"; } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 14d1da530a..9bb8010b0d 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -66,6 +66,8 @@ class Avatar : public AvatarData { Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset) public: + static void setShowReceiveStats(bool receiveStats); + explicit Avatar(QThread* thread, RigPointer rig = nullptr); ~Avatar(); @@ -251,7 +253,6 @@ public slots: void setModelURLFinished(bool success); protected: - friend class AvatarManager; const float SMOOTH_TIME_POSITION = 0.125f; const float SMOOTH_TIME_ORIENTATION = 0.075f; diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 074e0f4fba..1832bc7126 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -62,8 +62,6 @@ public: void clearOtherAvatars(); void deleteAllAvatars(); - bool shouldShowReceiveStats() const { return _shouldShowReceiveStats; } - void getObjectsToRemoveFromPhysics(VectorOfMotionStates& motionStates); void getObjectsToAddToPhysics(VectorOfMotionStates& motionStates); void getObjectsToChange(VectorOfMotionStates& motionStates); @@ -85,7 +83,7 @@ public: float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); } public slots: - void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; } + void setShouldShowReceiveStats(bool shouldShowReceiveStats) const { Avatar::setShowReceiveStats(shouldShowReceiveStats); } void updateAvatarRenderStatus(bool shouldRenderAvatars); private: @@ -106,8 +104,6 @@ private: std::shared_ptr _myAvatar; quint64 _lastSendAvatarDataTime = 0; // Controls MyAvatar send data rate. - bool _shouldShowReceiveStats = false; - std::list> _collisionInjectors; RateCounter<> _myAvatarSendRate; From 010d1dfa222286744959e47a6d4a8fb370d3198c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 14 Apr 2017 14:39:33 -0700 Subject: [PATCH 04/16] remove Menu dependency from Avatar class --- interface/src/avatar/Avatar.cpp | 34 ++++++++++++++++++++------ interface/src/avatar/Avatar.h | 21 ++++++++++------ interface/src/avatar/AvatarManager.cpp | 6 +++++ 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 84638f8008..2234630504 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -30,7 +30,6 @@ #include "AvatarMotionState.h" #include "Camera.h" -#include "Menu.h" #include "InterfaceLogging.h" #include "SceneScriptingInterface.h" #include "SoftAttachmentModel.h" @@ -78,6 +77,26 @@ void Avatar::setShowReceiveStats(bool receiveStats) { showReceiveStats = receiveStats; } +// static +bool renderMyLookAtVectors = false; +bool renderOtherLookAtVectors = false; +void Avatar::setShowLookAtVectors(bool showMine, bool showOthers) { + renderMyLookAtVectors = showMine; + renderOtherLookAtVectors = showOthers; +} + +// static +bool renderCollisionShapes = false; +void Avatar::setRenderCollisionShapes(bool render) { + renderCollisionShapes = render; +} + +// static +bool showNamesAboveHeads = false; +void Avatar::setShowNamesAboveHeads(bool show) { + showNamesAboveHeads = show; +} + Avatar::Avatar(QThread* thread, RigPointer rig) : AvatarData(), _skeletonOffset(0.0f), @@ -354,7 +373,7 @@ void Avatar::simulate(float deltaTime, bool inView) { _smoothPositionTimer += deltaTime; if (_smoothPositionTimer < _smoothPositionTime) { AvatarData::setPosition( - lerp(_smoothPositionInitial, + lerp(_smoothPositionInitial, _smoothPositionTarget, easeInOutQuad(glm::clamp(_smoothPositionTimer / _smoothPositionTime, 0.0f, 1.0f))) ); @@ -367,7 +386,7 @@ void Avatar::simulate(float deltaTime, bool inView) { _smoothOrientationTimer += deltaTime; if (_smoothOrientationTimer < _smoothOrientationTime) { AvatarData::setOrientation( - slerp(_smoothOrientationInitial, + slerp(_smoothOrientationInitial, _smoothOrientationTarget, easeInOutQuad(glm::clamp(_smoothOrientationTimer / _smoothOrientationTime, 0.0f, 1.0f))) ); @@ -541,9 +560,9 @@ void Avatar::postUpdate(float deltaTime) { bool renderLookAtVectors; if (isMyAvatar()) { - renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderMyLookAtVectors); + renderLookAtVectors = renderMyLookAtVectors; } else { - renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderOtherLookAtVectors); + renderLookAtVectors = renderOtherLookAtVectors; } if (renderLookAtVectors) { @@ -644,8 +663,7 @@ void Avatar::render(RenderArgs* renderArgs) { fixupModelsInScene(renderArgs->_scene); - bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes); - if (renderBounding && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { + if (renderCollisionShapes && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes"); const float BOUNDING_SHAPE_ALPHA = 0.7f; _skeletonModel->renderBoundingCollisionShapes(*renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA); @@ -1269,7 +1287,7 @@ float Avatar::getPelvisFloatingHeight() const { } void Avatar::setShowDisplayName(bool showDisplayName) { - if (!Menu::getInstance()->isOptionChecked(MenuOption::NamesAboveHeads)) { + if (!showNamesAboveHeads) { _displayNameAlpha = 0.0f; return; } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 9bb8010b0d..116e5aad11 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -67,6 +67,9 @@ class Avatar : public AvatarData { public: static void setShowReceiveStats(bool receiveStats); + static void setShowLookAtVectors(bool showMine, bool showOthers); + static void setRenderCollisionShapes(bool render); + static void setShowNamesAboveHeads(bool show); explicit Avatar(QThread* thread, RigPointer rig = nullptr); ~Avatar(); @@ -240,6 +243,13 @@ public: return (lerpValue*(4.0f - 2.0f * lerpValue) - 1.0f); } + float getBoundingRadius() const; + + void addToScene(AvatarSharedPointer self, const render::ScenePointer& scene); + void ensureInScene(AvatarSharedPointer self, const render::ScenePointer& scene); + bool isInScene() const { return render::Item::isValidID(_renderItemID); } + + void setMotionState(AvatarMotionState* motionState); public slots: @@ -261,8 +271,6 @@ protected: QString _empty{}; virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) override { _sessionDisplayName = sessionDisplayName; } // don't use no-op setter! - void setMotionState(AvatarMotionState* motionState); - SkeletonModelPointer _skeletonModel; glm::vec3 _skeletonOffset; std::vector> _attachmentModels; @@ -316,16 +324,13 @@ protected: ThreadSafeValueCache _rightPalmPositionCache { glm::vec3() }; ThreadSafeValueCache _rightPalmRotationCache { glm::quat() }; - void addToScene(AvatarSharedPointer self, const render::ScenePointer& scene); - void ensureInScene(AvatarSharedPointer self, const render::ScenePointer& scene); - bool isInScene() const { return render::Item::isValidID(_renderItemID); } - // Some rate tracking support RateCounter<> _simulationRate; RateCounter<> _simulationInViewRate; RateCounter<> _skeletonModelSimulationRate; RateCounter<> _jointDataSimulationRate; +<<<<<<< 4318cce04a59543d80a9364c86aab79408dcb50e // Smoothing data for blending from one position/orientation to another on remote agents. float _smoothPositionTime; float _smoothPositionTimer; @@ -336,6 +341,8 @@ protected: glm::quat _smoothOrientationInitial; glm::quat _smoothOrientationTarget; +======= +>>>>>>> remove Menu dependency from Avatar class private: class AvatarEntityDataHash { public: @@ -355,8 +362,6 @@ private: bool _isLookAtTarget { false }; bool _isAnimatingScale { false }; - float getBoundingRadius() const; - static int _jointConesID; int _voiceSphereID; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index ef57211d5c..35a5681213 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -147,6 +147,12 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { ViewFrustum cameraView; qApp->copyDisplayViewFrustum(cameraView); + // HACK: update Avatar namespace settings + Avatar::setShowLookAtVectors( + Menu::getInstance()->isOptionChecked(MenuOption::RenderMyLookAtVectors), + Menu::getInstance()->isOptionChecked(MenuOption::RenderOtherLookAtVectors)); + Avatar::setRenderCollisionShapes(Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes)); + std::priority_queue sortedAvatars; AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars, From aceac12398674418786cc99165bc01556d5b0b27 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Apr 2017 13:36:33 -0700 Subject: [PATCH 05/16] use 'using' instead of 'typedef' --- libraries/physics/src/PhysicsEngine.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 9f2f1aff5c..07de0e7b5c 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -41,8 +41,8 @@ public: void* _b; // ObjectMotionState pointer }; -typedef std::map ContactMap; -typedef std::vector CollisionEvents; +using ContactMap = std::map; +using CollisionEvents = std::vector; class PhysicsEngine { public: From 2441536de387637b48531fcbec6121d68206d968 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Apr 2017 13:37:36 -0700 Subject: [PATCH 06/16] remove Avatar dependency on AvatarMotionState --- interface/src/avatar/Avatar.cpp | 25 ++++--- interface/src/avatar/Avatar.h | 14 ++-- interface/src/avatar/AvatarManager.cpp | 76 ++++++++++++++-------- interface/src/avatar/AvatarManager.h | 4 +- interface/src/avatar/AvatarMotionState.cpp | 6 +- interface/src/avatar/AvatarMotionState.h | 8 +-- libraries/physics/src/PhysicsEngine.cpp | 1 + 7 files changed, 79 insertions(+), 55 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 2234630504..91d8dfb447 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -149,11 +149,6 @@ Avatar::~Avatar() { }); } - if (_motionState) { - delete _motionState; - _motionState = nullptr; - } - auto geometryCache = DependencyManager::get(); if (geometryCache) { geometryCache->releaseID(_nameRectGeometryID); @@ -1202,8 +1197,8 @@ int Avatar::parseDataFromBuffer(const QByteArray& buffer) { const float MOVE_DISTANCE_THRESHOLD = 0.001f; _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; - if (_moving && _motionState) { - _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); + if (_moving) { + addPhysicsFlags(Simulation::DIRTY_POSITION); } if (_moving || _hasNewJointData) { locationChanged(); @@ -1325,14 +1320,18 @@ void Avatar::getCapsule(glm::vec3& start, glm::vec3& end, float& radius) { radius = halfExtents.x; } -void Avatar::setMotionState(AvatarMotionState* motionState) { - _motionState = motionState; -} - // virtual void Avatar::rebuildCollisionShape() { - if (_motionState) { - _motionState->addDirtyFlags(Simulation::DIRTY_SHAPE); + addPhysicsFlags(Simulation::DIRTY_SHAPE); +} + +void Avatar::setPhysicsCallback(AvatarPhysicsCallback cb) { + _physicsCallback = cb; +} + +void Avatar::addPhysicsFlags(uint32_t flags) { + if (_physicsCallback) { + _physicsCallback(flags); } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 116e5aad11..17b5ea926e 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -11,6 +11,7 @@ #ifndef hifi_Avatar_h #define hifi_Avatar_h +#include #include #include @@ -48,9 +49,10 @@ enum ScreenTintLayer { NUM_SCREEN_TINT_LAYERS }; -class AvatarMotionState; class Texture; +using AvatarPhysicsCallback = std::function; + class Avatar : public AvatarData { Q_OBJECT @@ -190,7 +192,7 @@ public: virtual void computeShapeInfo(ShapeInfo& shapeInfo); void getCapsule(glm::vec3& start, glm::vec3& end, float& radius); - AvatarMotionState* getMotionState() { return _motionState; } + //AvatarMotionState* getMotionState() { return _motionState; } using SpatiallyNestable::setPosition; virtual void setPosition(const glm::vec3& position) override; @@ -248,8 +250,12 @@ public: void addToScene(AvatarSharedPointer self, const render::ScenePointer& scene); void ensureInScene(AvatarSharedPointer self, const render::ScenePointer& scene); bool isInScene() const { return render::Item::isValidID(_renderItemID); } + bool isMoving() const { return _moving; } - void setMotionState(AvatarMotionState* motionState); + //void setMotionState(AvatarMotionState* motionState); + void setPhysicsCallback(AvatarPhysicsCallback cb); + void addPhysicsFlags(uint32_t flags); + bool isInPhysicsSimulation() const { return _physicsCallback != nullptr; } public slots: @@ -366,7 +372,7 @@ private: int _voiceSphereID; - AvatarMotionState* _motionState = nullptr; + AvatarPhysicsCallback _physicsCallback { nullptr }; }; #endif // hifi_Avatar_h diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 35a5681213..41cf797eba 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -74,6 +74,7 @@ AvatarManager::AvatarManager(QObject* parent) : } AvatarManager::~AvatarManager() { + assert(_motionStates.empty()); } void AvatarManager::init() { @@ -128,10 +129,9 @@ float AvatarManager::getAvatarUpdateRate(const QUuid& sessionID, const QString& float AvatarManager::getAvatarSimulationRate(const QUuid& sessionID, const QString& rateName) const { auto avatar = std::static_pointer_cast(getAvatarBySessionID(sessionID)); - return avatar ? avatar->getSimulationRate(rateName) : 0.0f; + return avatar ? avatar->getSimulationRate(rateName) : 0.0f; } - void AvatarManager::updateOtherAvatars(float deltaTime) { // lock the hash for read to check the size QReadLocker lock(&_hashLock); @@ -189,16 +189,15 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { if (_shouldRender) { avatar->ensureInScene(avatar, qApp->getMain3DScene()); } - if (!avatar->getMotionState()) { + if (!avatar->isInPhysicsSimulation()) { ShapeInfo shapeInfo; avatar->computeShapeInfo(shapeInfo); btCollisionShape* shape = const_cast(ObjectMotionState::getShapeManager()->getShape(shapeInfo)); if (shape) { - // don't add to the simulation now, instead put it on a list to be added later - AvatarMotionState* motionState = new AvatarMotionState(avatar.get(), shape); - avatar->setMotionState(motionState); + AvatarMotionState* motionState = new AvatarMotionState(avatar, shape); + avatar->setPhysicsCallback([=] (uint32_t flags) { motionState->addDirtyFlags(flags); }); + _motionStates.insert(avatar.get(), motionState); _motionStatesToAddToPhysics.insert(motionState); - _motionStatesThatMightUpdate.insert(motionState); } } avatar->animateScaleChanges(deltaTime); @@ -283,30 +282,34 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { const float MIN_FADE_SCALE = MIN_AVATAR_SCALE; QReadLocker locker(&_hashLock); - QVector::iterator itr = _avatarsToFade.begin(); - while (itr != _avatarsToFade.end()) { - auto avatar = std::static_pointer_cast(*itr); + QVector::iterator avatarItr = _avatarsToFade.begin(); + while (avatarItr != _avatarsToFade.end()) { + auto avatar = std::static_pointer_cast(*avatarItr); avatar->setTargetScale(avatar->getUniformScale() * SHRINK_RATE); avatar->animateScaleChanges(deltaTime); if (avatar->getTargetScale() <= MIN_FADE_SCALE) { - // fading to zero is such a rare event we push unique transaction for each one + // fading to zero is such a rare event we push a unique transaction for each if (avatar->isInScene()) { const render::ScenePointer& scene = qApp->getMain3DScene(); render::Transaction transaction; - avatar->removeFromScene(*itr, scene, transaction); + avatar->removeFromScene(*avatarItr, scene, transaction); scene->enqueueTransaction(transaction); } - // only remove from _avatarsToFade if we're sure its motionState has been removed from PhysicsEngine - if (_motionStatesToRemoveFromPhysics.empty()) { - itr = _avatarsToFade.erase(itr); - } else { - ++itr; + // delete the motionState + // TODO: use SharedPointer technology to make this happen automagically + assert(!avatar->isInPhysicsSimulation()); + AvatarMotionStateMap::iterator motionStateItr = _motionStates.find(avatar.get()); + if (motionStateItr != _motionStates.end()) { + delete *motionStateItr; + _motionStates.erase(motionStateItr); } + + avatarItr = _avatarsToFade.erase(avatarItr); } else { const bool inView = true; // HACK avatar->simulate(deltaTime, inView); - ++itr; + ++avatarItr; } } } @@ -315,19 +318,24 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() { return std::make_shared(qApp->thread(), std::make_shared()); } +void AvatarManager::removeAvatarFromPhysicsSimulation(Avatar* avatar) { + assert(avatar); + avatar->setPhysicsCallback(nullptr); + AvatarMotionStateMap::iterator itr = _motionStates.find(avatar); + if (itr != _motionStates.end()) { + AvatarMotionState* motionState = *itr; + _motionStatesToAddToPhysics.remove(motionState); + _motionStatesToRemoveFromPhysics.push_back(motionState); + } +} + void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) { AvatarHashMap::handleRemovedAvatar(removedAvatar, removalReason); // removedAvatar is a shared pointer to an AvatarData but we need to get to the derived Avatar // class in this context so we can call methods that don't exist at the base class. auto avatar = std::static_pointer_cast(removedAvatar); - - AvatarMotionState* motionState = avatar->getMotionState(); - if (motionState) { - _motionStatesThatMightUpdate.remove(motionState); - _motionStatesToAddToPhysics.remove(motionState); - _motionStatesToRemoveFromPhysics.push_back(motionState); - } + removeAvatarFromPhysicsSimulation(avatar.get()); if (removalReason == KillAvatarReason::TheirAvatarEnteredYourBubble) { emit DependencyManager::get()->enteredIgnoreRadius(); @@ -362,11 +370,21 @@ void AvatarManager::clearOtherAvatars() { ++avatarIterator; } } + assert(scene); scene->enqueueTransaction(transaction); _myAvatar->clearLookAtTargetAvatar(); } void AvatarManager::deleteAllAvatars() { + // delete motionStates + // TODO: use shared_ptr technology to make this work automagically + AvatarMotionStateMap::iterator motionStateItr = _motionStates.begin(); + while (motionStateItr != _motionStates.end()) { + delete *motionStateItr; + ++motionStateItr; + } + _motionStates.clear(); + QReadLocker locker(&_hashLock); AvatarHash::iterator avatarIterator = _avatarHash.begin(); while (avatarIterator != _avatarHash.end()) { @@ -391,10 +409,12 @@ void AvatarManager::getObjectsToAddToPhysics(VectorOfMotionStates& result) { void AvatarManager::getObjectsToChange(VectorOfMotionStates& result) { result.clear(); - for (auto state : _motionStatesThatMightUpdate) { - if (state->_dirtyFlags > 0) { - result.push_back(state); + AvatarMotionStateMap::iterator motionStateItr = _motionStates.begin(); + while (motionStateItr != _motionStates.end()) { + if ((*motionStateItr)->getIncomingDirtyFlags() != 0) { + result.push_back(*motionStateItr); } + ++motionStateItr; } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 1832bc7126..5c8935417b 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -93,11 +93,13 @@ private: void simulateAvatarFades(float deltaTime); AvatarSharedPointer newSharedAvatar() override; + void removeAvatarFromPhysicsSimulation(Avatar* avatar); void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason) override; QVector _avatarsToFade; - QSet _motionStatesThatMightUpdate; + using AvatarMotionStateMap = QMap; + AvatarMotionStateMap _motionStates; VectorOfMotionStates _motionStatesToRemoveFromPhysics; SetOfMotionStates _motionStatesToAddToPhysics; diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index 335245670b..ffa99e3990 100644 --- a/interface/src/avatar/AvatarMotionState.cpp +++ b/interface/src/avatar/AvatarMotionState.cpp @@ -17,7 +17,7 @@ #include "AvatarMotionState.h" #include "BulletUtil.h" -AvatarMotionState::AvatarMotionState(Avatar* avatar, const btCollisionShape* shape) : ObjectMotionState(shape), _avatar(avatar) { +AvatarMotionState::AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape) : ObjectMotionState(shape), _avatar(avatar) { assert(_avatar); _type = MOTIONSTATE_TYPE_AVATAR; if (_shape) { @@ -49,7 +49,7 @@ PhysicsMotionType AvatarMotionState::computePhysicsMotionType() const { // virtual and protected const btCollisionShape* AvatarMotionState::computeNewShape() { ShapeInfo shapeInfo; - _avatar->computeShapeInfo(shapeInfo); + std::static_pointer_cast(_avatar)->computeShapeInfo(shapeInfo); return getShapeManager()->getShape(shapeInfo); } @@ -130,7 +130,7 @@ glm::vec3 AvatarMotionState::getObjectAngularVelocity() const { // virtual glm::vec3 AvatarMotionState::getObjectGravity() const { - return _avatar->getAcceleration(); + return std::static_pointer_cast(_avatar)->getAcceleration(); } // virtual diff --git a/interface/src/avatar/AvatarMotionState.h b/interface/src/avatar/AvatarMotionState.h index 98b2b69373..a8dd7327ca 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -20,7 +20,7 @@ class Avatar; class AvatarMotionState : public ObjectMotionState { public: - AvatarMotionState(Avatar* avatar, const btCollisionShape* shape); + AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape); virtual PhysicsMotionType getMotionType() const override { return _motionType; } @@ -74,11 +74,7 @@ protected: virtual bool isReadyToComputeShape() const override { return true; } virtual const btCollisionShape* computeNewShape() override; - // The AvatarMotionState keeps a RAW backpointer to its Avatar because all AvatarMotionState - // instances are "owned" by their corresponding Avatar instance and are deleted in the Avatar dtor. - // In other words, it is impossible for the Avatar to be deleted out from under its MotionState. - // In conclusion: weak pointer shennanigans would be pure overhead. - Avatar* _avatar; // do NOT use smartpointer here, no need for weakpointer + AvatarSharedPointer _avatar; uint32_t _dirtyFlags; }; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index ca6889485a..87a15eb264 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -220,6 +220,7 @@ void PhysicsEngine::removeObjects(const SetOfMotionStates& objects) { body->setMotionState(nullptr); delete body; } + object->clearIncomingDirtyFlags(); } } From caf6a77baf15c8f6cacd420ef5c273f651b8b093 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Apr 2017 16:35:32 -0700 Subject: [PATCH 07/16] repair bad merge during rebase --- interface/src/FancyCamera.h | 2 ++ interface/src/avatar/Avatar.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/FancyCamera.h b/interface/src/FancyCamera.h index 9ffa6cafd8..66f7a07dbd 100644 --- a/interface/src/FancyCamera.h +++ b/interface/src/FancyCamera.h @@ -13,6 +13,8 @@ #include "Camera.h" +#include + class FancyCamera : public Camera { Q_OBJECT diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 17b5ea926e..e777460ecb 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -336,7 +336,6 @@ protected: RateCounter<> _skeletonModelSimulationRate; RateCounter<> _jointDataSimulationRate; -<<<<<<< 4318cce04a59543d80a9364c86aab79408dcb50e // Smoothing data for blending from one position/orientation to another on remote agents. float _smoothPositionTime; float _smoothPositionTimer; @@ -347,8 +346,6 @@ protected: glm::quat _smoothOrientationInitial; glm::quat _smoothOrientationTarget; -======= ->>>>>>> remove Menu dependency from Avatar class private: class AvatarEntityDataHash { public: From 72f5860538de8f3467b432d2141b53e8e09f2a5d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 19 Apr 2017 10:37:49 -0700 Subject: [PATCH 08/16] restore RecordingScriptingInterface to Application --- interface/src/Application.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8801989e44..5fd0b30d01 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5451,6 +5451,9 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri entityScriptingInterface->setPacketSender(&_entityEditSender); entityScriptingInterface->setEntityTree(getEntities()->getTree()); + // give the script engine to the RecordingScriptingInterface for its callbacks + DependencyManager::get()->setScriptEngine(scriptEngine); + if (property(hifi::properties::TEST).isValid()) { scriptEngine->registerGlobalObject("Test", TestScriptingInterface::getInstance()); } From 823f3a73c6b96d1afee64304e7afd8a66fe355ae Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 19 Apr 2017 11:00:29 -0700 Subject: [PATCH 09/16] remove commented out cruft --- interface/src/avatar/Avatar.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index e777460ecb..b323954049 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -192,8 +192,6 @@ public: virtual void computeShapeInfo(ShapeInfo& shapeInfo); void getCapsule(glm::vec3& start, glm::vec3& end, float& radius); - //AvatarMotionState* getMotionState() { return _motionState; } - using SpatiallyNestable::setPosition; virtual void setPosition(const glm::vec3& position) override; using SpatiallyNestable::setOrientation; From 00b05ed137bf064aaa21e23ed9c9deca2f80180c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 21 Apr 2017 09:31:33 -0700 Subject: [PATCH 10/16] connect menu options to avatar render features --- interface/src/Menu.cpp | 11 +++--- interface/src/Menu.h | 8 ++--- interface/src/avatar/Avatar.cpp | 46 +++++++++++--------------- interface/src/avatar/Avatar.h | 10 +++--- interface/src/avatar/AvatarManager.cpp | 6 ---- interface/src/avatar/AvatarManager.h | 1 - 6 files changed, 36 insertions(+), 46 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 8754951317..97e566309f 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -504,11 +504,14 @@ Menu::Menu() { #endif addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AvatarReceiveStats, 0, false, - avatarManager.data(), SLOT(setShouldShowReceiveStats(bool))); + avatar.get(), SLOT(setShowReceiveStats(bool))); + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowBoundingCollisionShapes, 0, false, + avatar.get(), SLOT(setShowCollisionShapes(bool))); + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowMyLookAtVectors, 0, false, + avatar.get(), SLOT(setShowMyLookAtVectors(bool))); + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowOtherLookAtVectors, 0, false, + avatar.get(), SLOT(setShowOtherLookAtVectors(bool))); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderBoundingCollisionShapes); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderMyLookAtVectors, 0, false); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderOtherLookAtVectors, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::FixGaze, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AnimDebugDrawDefaultPose, 0, false, avatar.get(), SLOT(setEnableDebugDrawDefaultPose(bool))); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index eeffcac7ca..d46c2736a4 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -146,9 +146,6 @@ namespace MenuOption { const QString Quit = "Quit"; const QString ReloadAllScripts = "Reload All Scripts"; const QString ReloadContent = "Reload Content (Clears all caches)"; - const QString RenderBoundingCollisionShapes = "Show Bounding Collision Shapes"; - const QString RenderMyLookAtVectors = "Show My Eye Vectors"; - const QString RenderOtherLookAtVectors = "Show Other Eye Vectors"; const QString RenderMaxTextureMemory = "Maximum Texture Memory"; const QString RenderMaxTextureAutomatic = "Automatic Texture Memory"; const QString RenderMaxTexture4MB = "4 MB"; @@ -174,8 +171,11 @@ namespace MenuOption { const QString SendWrongDSConnectVersion = "Send wrong DS connect version"; const QString SendWrongProtocolVersion = "Send wrong protocol version"; const QString SetHomeLocation = "Set Home Location"; - const QString ShowDSConnectTable = "Show Domain Connection Timing"; const QString ShowBordersEntityNodes = "Show Entity Nodes"; + const QString ShowBoundingCollisionShapes = "Show Bounding Collision Shapes"; + const QString ShowDSConnectTable = "Show Domain Connection Timing"; + const QString ShowMyLookAtVectors = "Show My Eye Vectors"; + const QString ShowOtherLookAtVectors = "Show Other Eye Vectors"; const QString ShowRealtimeEntityStats = "Show Realtime Entity Stats"; const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; const QString SimulateEyeTracking = "Simulate"; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 91d8dfb447..1e759ed396 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -71,28 +71,27 @@ namespace render { } } -// static -bool showReceiveStats = false; +static bool showReceiveStats = false; void Avatar::setShowReceiveStats(bool receiveStats) { showReceiveStats = receiveStats; } -// static -bool renderMyLookAtVectors = false; -bool renderOtherLookAtVectors = false; -void Avatar::setShowLookAtVectors(bool showMine, bool showOthers) { - renderMyLookAtVectors = showMine; - renderOtherLookAtVectors = showOthers; +static bool showMyLookAtVectors = false; +void Avatar::setShowMyLookAtVectors(bool showMine) { + showMyLookAtVectors = showMine; } -// static -bool renderCollisionShapes = false; -void Avatar::setRenderCollisionShapes(bool render) { - renderCollisionShapes = render; +static bool showOtherLookAtVectors = false; +void Avatar::setShowOtherLookAtVectors(bool showOthers) { + showOtherLookAtVectors = showOthers; } -// static -bool showNamesAboveHeads = false; +static bool showCollisionShapes = false; +void Avatar::setShowCollisionShapes(bool render) { + showCollisionShapes = render; +} + +static bool showNamesAboveHeads = false; void Avatar::setShowNamesAboveHeads(bool show) { showNamesAboveHeads = show; } @@ -553,14 +552,7 @@ void Avatar::updateRenderItem(render::Transaction& transaction) { void Avatar::postUpdate(float deltaTime) { - bool renderLookAtVectors; - if (isMyAvatar()) { - renderLookAtVectors = renderMyLookAtVectors; - } else { - renderLookAtVectors = renderOtherLookAtVectors; - } - - if (renderLookAtVectors) { + if (isMyAvatar() ? showMyLookAtVectors : showOtherLookAtVectors) { const float EYE_RAY_LENGTH = 10.0; const glm::vec4 BLUE(0.0f, 0.0f, 1.0f, 1.0f); const glm::vec4 RED(1.0f, 0.0f, 0.0f, 1.0f); @@ -653,17 +645,18 @@ void Avatar::render(RenderArgs* renderArgs) { return; } - glm::vec3 toTarget = frustum.getPosition() - getPosition(); - float distanceToTarget = glm::length(toTarget); - fixupModelsInScene(renderArgs->_scene); - if (renderCollisionShapes && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { + if (showCollisionShapes && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes"); const float BOUNDING_SHAPE_ALPHA = 0.7f; _skeletonModel->renderBoundingCollisionShapes(*renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA); } +#if 0 /// -------------- REMOVED FOR NOW -------------- + // removed CPU calculations as per removal of menu option + glm::vec3 toTarget = frustum.getPosition() - getPosition(); + float distanceToTarget = glm::length(toTarget); const float DISPLAYNAME_DISTANCE = 20.0f; setShowDisplayName(distanceToTarget < DISPLAYNAME_DISTANCE); if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { @@ -673,6 +666,7 @@ void Avatar::render(RenderArgs* renderArgs) { renderDisplayName(batch, frustum, textPosition); } } +#endif } glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b323954049..b2b0120b9a 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -68,11 +68,6 @@ class Avatar : public AvatarData { Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset) public: - static void setShowReceiveStats(bool receiveStats); - static void setShowLookAtVectors(bool showMine, bool showOthers); - static void setRenderCollisionShapes(bool render); - static void setShowNamesAboveHeads(bool show); - explicit Avatar(QThread* thread, RigPointer rig = nullptr); ~Avatar(); @@ -256,6 +251,11 @@ public: bool isInPhysicsSimulation() const { return _physicsCallback != nullptr; } public slots: + void setShowReceiveStats(bool receiveStats); + void setShowMyLookAtVectors(bool showMine); + void setShowOtherLookAtVectors(bool showOthers); + void setShowCollisionShapes(bool render); + void setShowNamesAboveHeads(bool show); // FIXME - these should be migrated to use Pose data instead // thread safe, will return last valid palm from cache diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 41cf797eba..ec22c3403a 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -147,12 +147,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { ViewFrustum cameraView; qApp->copyDisplayViewFrustum(cameraView); - // HACK: update Avatar namespace settings - Avatar::setShowLookAtVectors( - Menu::getInstance()->isOptionChecked(MenuOption::RenderMyLookAtVectors), - Menu::getInstance()->isOptionChecked(MenuOption::RenderOtherLookAtVectors)); - Avatar::setRenderCollisionShapes(Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes)); - std::priority_queue sortedAvatars; AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars, diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 5c8935417b..e5b2117beb 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -83,7 +83,6 @@ public: float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); } public slots: - void setShouldShowReceiveStats(bool shouldShowReceiveStats) const { Avatar::setShowReceiveStats(shouldShowReceiveStats); } void updateAvatarRenderStatus(bool shouldRenderAvatars); private: From 442080dec7134ba01c38703f7cae2b9c7bc74d54 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 21 Apr 2017 09:32:07 -0700 Subject: [PATCH 11/16] remove unused RenderArgs::_cameraMode hack --- interface/src/Application.cpp | 1 - libraries/shared/src/RenderArgs.h | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5fd0b30d01..dff50fd616 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5119,7 +5119,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se QMutexLocker viewLocker(&_viewMutex); renderArgs->setViewFrustum(_displayViewFrustum); } - renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK renderArgs->_scene = getMain3DScene(); _renderEngine->getRenderContext()->args = renderArgs; diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 10a9a20287..9d81913078 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -130,8 +130,7 @@ public: bool _enableTexturing { true }; RenderDetails _details; - render::ScenePointer _scene; // HACK - int8_t _cameraMode { -1 }; // HACK + render::ScenePointer _scene; }; #endif // hifi_RenderArgs_h From 75b563d5982b5fa0651c40ad2ae4dcc4acf831ec Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 21 Apr 2017 11:07:12 -0700 Subject: [PATCH 12/16] restore rendering of avatar receive stats --- interface/src/Application.cpp | 1 + interface/src/avatar/Avatar.cpp | 27 +++++++++++++-------------- interface/src/avatar/Avatar.h | 6 +++++- libraries/avatars/src/AvatarData.cpp | 2 -- libraries/avatars/src/AvatarData.h | 3 --- libraries/shared/src/RenderArgs.h | 1 + 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dff50fd616..5fd0b30d01 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5119,6 +5119,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se QMutexLocker viewLocker(&_viewMutex); renderArgs->setViewFrustum(_displayViewFrustum); } + renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK renderArgs->_scene = getMain3DScene(); _renderEngine->getRenderContext()->args = renderArgs; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 1e759ed396..3bd4c663d2 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -653,20 +653,19 @@ void Avatar::render(RenderArgs* renderArgs) { _skeletonModel->renderBoundingCollisionShapes(*renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA); } -#if 0 /// -------------- REMOVED FOR NOW -------------- - // removed CPU calculations as per removal of menu option - glm::vec3 toTarget = frustum.getPosition() - getPosition(); - float distanceToTarget = glm::length(toTarget); - const float DISPLAYNAME_DISTANCE = 20.0f; - setShowDisplayName(distanceToTarget < DISPLAYNAME_DISTANCE); - if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { - auto& frustum = renderArgs->getViewFrustum(); - auto textPosition = getDisplayNamePosition(); - if (frustum.pointIntersectsFrustum(textPosition)) { - renderDisplayName(batch, frustum, textPosition); + if (showReceiveStats || showNamesAboveHeads) { + glm::vec3 toTarget = frustum.getPosition() - getPosition(); + float distanceToTarget = glm::length(toTarget); + const float DISPLAYNAME_DISTANCE = 20.0f; + updateDisplayNameAlpha(distanceToTarget < DISPLAYNAME_DISTANCE); + if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { + auto& frustum = renderArgs->getViewFrustum(); + auto textPosition = getDisplayNamePosition(); + if (frustum.pointIntersectsFrustum(textPosition)) { + renderDisplayName(batch, frustum, textPosition); + } } } -#endif } glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { @@ -1275,8 +1274,8 @@ float Avatar::getPelvisFloatingHeight() const { return -_skeletonModel->getBindExtents().minimum.y; } -void Avatar::setShowDisplayName(bool showDisplayName) { - if (!showNamesAboveHeads) { +void Avatar::updateDisplayNameAlpha(bool showDisplayName) { + if (!(showNamesAboveHeads || showReceiveStats)) { _displayNameAlpha = 0.0f; return; } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b2b0120b9a..192de146b9 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -150,7 +150,7 @@ public: virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setAttachmentData(const QVector& attachmentData) override; - void setShowDisplayName(bool showDisplayName); + void updateDisplayNameAlpha(bool showDisplayName); virtual void setSessionDisplayName(const QString& sessionDisplayName) override { }; // no-op virtual int parseDataFromBuffer(const QByteArray& buffer) override; @@ -368,6 +368,10 @@ private: int _voiceSphereID; AvatarPhysicsCallback _physicsCallback { nullptr }; + + float _displayNameTargetAlpha { 1.0f }; + float _displayNameAlpha { 1.0f }; + }; #endif // hifi_Avatar_h diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 1427ce6359..55c8cc3b65 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -63,8 +63,6 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _forceFaceTrackerConnected(false), _headData(NULL), - _displayNameTargetAlpha(1.0f), - _displayNameAlpha(1.0f), _errorLogExpiry(0), _owningAvatarMixer(), _targetVelocity(0.0f) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 545a5f1f8c..f325b6bce7 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -692,9 +692,6 @@ protected: QString _sessionDisplayName { }; QUrl cannonicalSkeletonModelURL(const QUrl& empty) const; - float _displayNameTargetAlpha; - float _displayNameAlpha; - QHash _jointIndices; ///< 1-based, since zero is returned for missing keys QStringList _jointNames; ///< in order of depth-first traversal diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 9d81913078..f44d736e1a 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -131,6 +131,7 @@ public: RenderDetails _details; render::ScenePointer _scene; + int8_t _cameraMode { -1 }; }; #endif // hifi_RenderArgs_h From aa90a6bd028e729060fd1ead9bb99c51a67ebfe8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 21 Apr 2017 11:41:00 -0700 Subject: [PATCH 13/16] use static methods for setting avatar debug options --- interface/src/Menu.cpp | 16 ++++++++-------- interface/src/avatar/Avatar.h | 11 ++++++----- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 97e566309f..1fbf3f9cf2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -503,14 +503,14 @@ Menu::Menu() { qApp, SLOT(setActiveEyeTracker())); #endif - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AvatarReceiveStats, 0, false, - avatar.get(), SLOT(setShowReceiveStats(bool))); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowBoundingCollisionShapes, 0, false, - avatar.get(), SLOT(setShowCollisionShapes(bool))); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowMyLookAtVectors, 0, false, - avatar.get(), SLOT(setShowMyLookAtVectors(bool))); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowOtherLookAtVectors, 0, false, - avatar.get(), SLOT(setShowOtherLookAtVectors(bool))); + action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AvatarReceiveStats, 0, false); + connect(action, &QAction::triggered, []{ Avatar::setShowReceiveStats(Menu::getInstance()->isOptionChecked(MenuOption::AvatarReceiveStats)); }); + action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowBoundingCollisionShapes, 0, false); + connect(action, &QAction::triggered, []{ Avatar::setShowCollisionShapes(Menu::getInstance()->isOptionChecked(MenuOption::ShowBoundingCollisionShapes)); }); + action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowMyLookAtVectors, 0, false); + connect(action, &QAction::triggered, []{ Avatar::setShowMyLookAtVectors(Menu::getInstance()->isOptionChecked(MenuOption::ShowMyLookAtVectors)); }); + action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowOtherLookAtVectors, 0, false); + connect(action, &QAction::triggered, []{ Avatar::setShowOtherLookAtVectors(Menu::getInstance()->isOptionChecked(MenuOption::ShowOtherLookAtVectors)); }); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::FixGaze, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AnimDebugDrawDefaultPose, 0, false, diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 192de146b9..f86bf35bd9 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -68,6 +68,12 @@ class Avatar : public AvatarData { Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset) public: + static void setShowReceiveStats(bool receiveStats); + static void setShowMyLookAtVectors(bool showMine); + static void setShowOtherLookAtVectors(bool showOthers); + static void setShowCollisionShapes(bool render); + static void setShowNamesAboveHeads(bool show); + explicit Avatar(QThread* thread, RigPointer rig = nullptr); ~Avatar(); @@ -251,11 +257,6 @@ public: bool isInPhysicsSimulation() const { return _physicsCallback != nullptr; } public slots: - void setShowReceiveStats(bool receiveStats); - void setShowMyLookAtVectors(bool showMine); - void setShowOtherLookAtVectors(bool showOthers); - void setShowCollisionShapes(bool render); - void setShowNamesAboveHeads(bool show); // FIXME - these should be migrated to use Pose data instead // thread safe, will return last valid palm from cache From 5cf233db3a7e0c16bc97d158f03dc74f053bdb97 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 21 Apr 2017 16:17:53 -0700 Subject: [PATCH 14/16] less labyrinth --- interface/src/Menu.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1fbf3f9cf2..4ce9085053 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -504,13 +504,13 @@ Menu::Menu() { #endif action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AvatarReceiveStats, 0, false); - connect(action, &QAction::triggered, []{ Avatar::setShowReceiveStats(Menu::getInstance()->isOptionChecked(MenuOption::AvatarReceiveStats)); }); + connect(action, &QAction::triggered, [this]{ Avatar::setShowReceiveStats(isOptionChecked(MenuOption::AvatarReceiveStats)); }); action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowBoundingCollisionShapes, 0, false); - connect(action, &QAction::triggered, []{ Avatar::setShowCollisionShapes(Menu::getInstance()->isOptionChecked(MenuOption::ShowBoundingCollisionShapes)); }); + connect(action, &QAction::triggered, [this]{ Avatar::setShowCollisionShapes(isOptionChecked(MenuOption::ShowBoundingCollisionShapes)); }); action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowMyLookAtVectors, 0, false); - connect(action, &QAction::triggered, []{ Avatar::setShowMyLookAtVectors(Menu::getInstance()->isOptionChecked(MenuOption::ShowMyLookAtVectors)); }); + connect(action, &QAction::triggered, [this]{ Avatar::setShowMyLookAtVectors(isOptionChecked(MenuOption::ShowMyLookAtVectors)); }); action = addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowOtherLookAtVectors, 0, false); - connect(action, &QAction::triggered, []{ Avatar::setShowOtherLookAtVectors(Menu::getInstance()->isOptionChecked(MenuOption::ShowOtherLookAtVectors)); }); + connect(action, &QAction::triggered, [this]{ Avatar::setShowOtherLookAtVectors(isOptionChecked(MenuOption::ShowOtherLookAtVectors)); }); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::FixGaze, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AnimDebugDrawDefaultPose, 0, false, From 32c367b644181ecc3db953f5a8df5914df66fd0c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 28 Apr 2017 10:18:15 -0700 Subject: [PATCH 15/16] use 'using' rather than 'typedef' --- libraries/physics/src/ObjectMotionState.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 1d258560c3..4230f636b3 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -170,7 +170,7 @@ protected: bool _hasInternalKinematicChanges { false }; }; -typedef QSet SetOfMotionStates; -typedef QVector VectorOfMotionStates; +using SetOfMotionStates = QSet; +using VectorOfMotionStates = QVector; #endif // hifi_ObjectMotionState_h From 994eed7b83a58b60a6a40f3e550b4366e9cd10aa Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 28 Apr 2017 10:18:19 -0700 Subject: [PATCH 16/16] safer delete of AvatarMotionStates --- interface/src/avatar/AvatarManager.cpp | 52 ++++++++++---------------- interface/src/avatar/AvatarManager.h | 3 +- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index ec22c3403a..04ab1531ba 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -289,16 +289,6 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { avatar->removeFromScene(*avatarItr, scene, transaction); scene->enqueueTransaction(transaction); } - - // delete the motionState - // TODO: use SharedPointer technology to make this happen automagically - assert(!avatar->isInPhysicsSimulation()); - AvatarMotionStateMap::iterator motionStateItr = _motionStates.find(avatar.get()); - if (motionStateItr != _motionStates.end()) { - delete *motionStateItr; - _motionStates.erase(motionStateItr); - } - avatarItr = _avatarsToFade.erase(avatarItr); } else { const bool inView = true; // HACK @@ -312,24 +302,19 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() { return std::make_shared(qApp->thread(), std::make_shared()); } -void AvatarManager::removeAvatarFromPhysicsSimulation(Avatar* avatar) { - assert(avatar); +void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) { + AvatarHashMap::handleRemovedAvatar(removedAvatar, removalReason); + + // remove from physics + auto avatar = std::static_pointer_cast(removedAvatar); avatar->setPhysicsCallback(nullptr); - AvatarMotionStateMap::iterator itr = _motionStates.find(avatar); + AvatarMotionStateMap::iterator itr = _motionStates.find(avatar.get()); if (itr != _motionStates.end()) { AvatarMotionState* motionState = *itr; _motionStatesToAddToPhysics.remove(motionState); _motionStatesToRemoveFromPhysics.push_back(motionState); + _motionStates.erase(itr); } -} - -void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) { - AvatarHashMap::handleRemovedAvatar(removedAvatar, removalReason); - - // removedAvatar is a shared pointer to an AvatarData but we need to get to the derived Avatar - // class in this context so we can call methods that don't exist at the base class. - auto avatar = std::static_pointer_cast(removedAvatar); - removeAvatarFromPhysicsSimulation(avatar.get()); if (removalReason == KillAvatarReason::TheirAvatarEnteredYourBubble) { emit DependencyManager::get()->enteredIgnoreRadius(); @@ -370,14 +355,8 @@ void AvatarManager::clearOtherAvatars() { } void AvatarManager::deleteAllAvatars() { - // delete motionStates - // TODO: use shared_ptr technology to make this work automagically - AvatarMotionStateMap::iterator motionStateItr = _motionStates.begin(); - while (motionStateItr != _motionStates.end()) { - delete *motionStateItr; - ++motionStateItr; - } - _motionStates.clear(); + assert(_motionStates.empty()); // should have called clearOtherAvatars() before getting here + deleteMotionStates(); QReadLocker locker(&_hashLock); AvatarHash::iterator avatarIterator = _avatarHash.begin(); @@ -388,9 +367,18 @@ void AvatarManager::deleteAllAvatars() { } } +void AvatarManager::deleteMotionStates() { + // delete motionstates that were removed from physics last frame + for (auto state : _motionStatesToDelete) { + delete state; + } + _motionStatesToDelete.clear(); +} + void AvatarManager::getObjectsToRemoveFromPhysics(VectorOfMotionStates& result) { - result.clear(); - result.swap(_motionStatesToRemoveFromPhysics); + deleteMotionStates(); + result = _motionStatesToRemoveFromPhysics; + _motionStatesToDelete.swap(_motionStatesToRemoveFromPhysics); } void AvatarManager::getObjectsToAddToPhysics(VectorOfMotionStates& result) { diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index e5b2117beb..c67088a4be 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -92,7 +92,7 @@ private: void simulateAvatarFades(float deltaTime); AvatarSharedPointer newSharedAvatar() override; - void removeAvatarFromPhysicsSimulation(Avatar* avatar); + void deleteMotionStates(); void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason) override; QVector _avatarsToFade; @@ -100,6 +100,7 @@ private: using AvatarMotionStateMap = QMap; AvatarMotionStateMap _motionStates; VectorOfMotionStates _motionStatesToRemoveFromPhysics; + VectorOfMotionStates _motionStatesToDelete; SetOfMotionStates _motionStatesToAddToPhysics; std::shared_ptr _myAvatar;