From 60824a1fb013dc3a2eb839aef5272d8456a7b670 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 3 Nov 2015 16:07:28 -0800 Subject: [PATCH] back out some off-brand changes. add parentChanged call --- interface/src/Application.cpp | 142 ++++++++++----------- interface/src/avatar/Avatar.cpp | 32 ++--- interface/src/avatar/AvatarManager.cpp | 26 ++-- interface/src/avatar/AvatarUpdate.cpp | 11 +- libraries/avatars/src/AvatarData.cpp | 55 ++++++-- libraries/avatars/src/AvatarData.h | 18 ++- libraries/entities/src/EntityItem.cpp | 11 -- libraries/shared/src/SpatiallyNestable.cpp | 14 +- libraries/shared/src/SpatiallyNestable.h | 2 + 9 files changed, 178 insertions(+), 133 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e1ba4a8163..e9c2e0ccb1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1128,77 +1128,75 @@ void Application::paintGL() { { PerformanceTimer perfTimer("CameraUpdates"); + auto myAvatar = getMyAvatar(); - myAvatar->withReadLock([&] { - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, - myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); - Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, - !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); - cameraMenuChanged(); - } + + myAvatar->startCapture(); + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); + Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); + cameraMenuChanged(); + } - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setRotation(glm::quat_cast(camMat)); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); - } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setRotation(glm::normalize(glm::quat_cast(hmdWorldMat))); - auto worldBoomOffset = myAvatar->getOrientation() * - (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + worldBoomOffset); - } else { - _myCamera.setRotation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getRotation() * - (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * - (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); - } - } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + (myAvatar->getOrientation() * - glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); - } else { - _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setRotation(glm::quat_cast(camMat)); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _fps); + } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setRotation(glm::normalize(glm::quat_cast(hmdWorldMat))); + auto worldBoomOffset = myAvatar->getOrientation() * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + worldBoomOffset); + } else { + _myCamera.setRotation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getRotation() + * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() + * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } } - }); + } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); + } else { + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _fps); + } + myAvatar->endCapture(); } // Primary rendering pass @@ -3454,9 +3452,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // FIXME: This preRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. auto myAvatar = getMyAvatar(); - myAvatar->withReadLock([&] { - myAvatar->preRender(renderArgs); - }); + myAvatar->startRender(); + myAvatar->preRender(renderArgs); + myAvatar->endRender(); activeRenderingThread = QThread::currentThread(); @@ -3570,9 +3568,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se _renderEngine->setRenderContext(renderContext); // Before the deferred pass, let's try to use the render engine - myAvatar->withReadLock([&] { - _renderEngine->run(); - }); + myAvatar->startRenderRun(); + _renderEngine->run(); + myAvatar->endRenderRun(); auto engineRC = _renderEngine->getRenderContext(); sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4ffa1ffc7c..b6a6ae001d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -377,6 +377,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) { + endRender(); return; } @@ -535,6 +536,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { renderDisplayName(batch, frustum, textPosition); } } + endRender(); } glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { @@ -1011,25 +1013,23 @@ void Avatar::setBillboard(const QByteArray& billboard) { } int Avatar::parseDataFromBuffer(const QByteArray& buffer) { - int bytesRead; + startUpdate(); + if (!_initialized) { + // now that we have data for this Avatar we are go for init + init(); + } - withWriteLock([&] { - if (!_initialized) { - // now that we have data for this Avatar we are go for init - init(); - } + // change in position implies movement + glm::vec3 oldPosition = getPosition(); - // change in position implies movement - glm::vec3 oldPosition = getPosition(); + int bytesRead = AvatarData::parseDataFromBuffer(buffer); - bytesRead = AvatarData::parseDataFromBuffer(buffer); - - const float MOVE_DISTANCE_THRESHOLD = 0.001f; - _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; - if (_moving && _motionState) { - _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); - } - }); + const float MOVE_DISTANCE_THRESHOLD = 0.001f; + _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; + if (_moving && _motionState) { + _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); + } + endUpdate(); return bytesRead; } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index e9f4c63532..551891cbfa 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -133,9 +133,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { QWriteLocker locker(&_hashLock); avatarIterator = _avatarHash.erase(avatarIterator); } else { - avatar->withWriteLock([&] { - avatar->simulate(deltaTime); - }); + avatar->startUpdate(); + avatar->simulate(deltaTime); + avatar->endUpdate(); ++avatarIterator; } } @@ -154,16 +154,16 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { render::PendingChanges pendingChanges; while (fadingIterator != _avatarFades.end()) { auto avatar = std::static_pointer_cast(*fadingIterator); - avatar->withWriteLock([&] { - avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE); - if (avatar->getTargetScale() < MIN_FADE_SCALE) { - avatar->removeFromScene(*fadingIterator, scene, pendingChanges); - fadingIterator = _avatarFades.erase(fadingIterator); - } else { - avatar->simulate(deltaTime); - ++fadingIterator; - } - }); + avatar->startUpdate(); + avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE); + if (avatar->getTargetScale() < MIN_FADE_SCALE) { + avatar->removeFromScene(*fadingIterator, scene, pendingChanges); + fadingIterator = _avatarFades.erase(fadingIterator); + } else { + avatar->simulate(deltaTime); + ++fadingIterator; + } + avatar->endUpdate(); } scene->enqueuePendingChanges(pendingChanges); } diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index a32948f598..cae593ff85 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -56,11 +56,12 @@ bool AvatarUpdate::process() { //gets current lookat data, removes missing avatars, etc. manager->updateOtherAvatars(deltaSeconds); - myAvatar->withWriteLock([&] { - qApp->updateMyAvatarLookAtPosition(); - // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes - manager->updateMyAvatar(deltaSeconds); - }); + myAvatar->startUpdate(); + qApp->updateMyAvatarLookAtPosition(); + // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes + manager->updateMyAvatar(deltaSeconds); + myAvatar->endUpdate(); + if (!isThreaded()) { return true; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a1db573d8d..a06b3448ea 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -111,25 +111,60 @@ void AvatarData::setBodyRoll(float bodyRoll) { } void AvatarData::setPosition(const glm::vec3& position) { - withWriteLock([&] { - SpatiallyNestable::setPosition(position); - }); + SpatiallyNestable::setPosition(position); } void AvatarData::setOrientation(const glm::quat& orientation) { - withWriteLock([&] { - SpatiallyNestable::setOrientation(orientation); - }); + SpatiallyNestable::setOrientation(orientation); } // There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { - withWriteLock([&] { - SpatiallyNestable::setPosition(position); - SpatiallyNestable::setOrientation(orientation); - }); + avatarLock.lock(); + SpatiallyNestable::setPosition(position); + SpatiallyNestable::setOrientation(orientation); + avatarLock.unlock(); updateAttitude(); } +void AvatarData::startCapture() { + avatarLock.lock(); + assert(_nextAllowed); + _nextAllowed = false; + _nextPosition = getPosition(); + _nextOrientation = getOrientation(); +} +void AvatarData::endCapture() { + avatarLock.unlock(); +} +void AvatarData::startUpdate() { + avatarLock.lock(); +} +void AvatarData::endUpdate() { + avatarLock.unlock(); +} +void AvatarData::startRenderRun() { + // I'd like to get rid of this and just (un)lock at (end-)startRender. + // But somehow that causes judder in rotations. + avatarLock.lock(); +} +void AvatarData::endRenderRun() { + avatarLock.unlock(); +} +void AvatarData::startRender() { + glm::vec3 pos = getPosition(); + glm::quat rot = getOrientation(); + setPosition(_nextPosition); + setOrientation(_nextOrientation); + updateAttitude(); + _nextPosition = pos; + _nextOrientation = rot; +} +void AvatarData::endRender() { + setPosition(_nextPosition); + setOrientation(_nextOrientation); + updateAttitude(); + _nextAllowed = true; +} float AvatarData::getTargetScale() const { return _targetScale; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 8a0a9ac38a..2e3257554d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -44,13 +44,13 @@ typedef unsigned long long quint64; #include #include #include +#include #include #include #include #include #include -#include #include "AABox.h" #include "HandData.h" @@ -136,7 +136,7 @@ class QDataStream; class AttachmentData; class JointData; -class AvatarData : public QObject, public ReadWriteLockable, public SpatiallyNestable { +class AvatarData : public QObject, public SpatiallyNestable { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) @@ -200,6 +200,14 @@ public: virtual void setOrientation(const glm::quat& orientation); void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. + void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. + void endCapture(); + void startUpdate(); // start/end of update iteration + void endUpdate(); + void startRender(); // start/end of rendering of this object + void startRenderRun(); // start/end of entire scene. + void endRenderRun(); + void endRender(); virtual void updateAttitude() {} // Tell skeleton mesh about changes glm::quat getHeadOrientation() const { return _headData->getOrientation(); } @@ -355,6 +363,10 @@ public slots: protected: glm::vec3 _handPosition; + glm::vec3 _nextPosition {}; + glm::quat _nextOrientation {}; + bool _nextAllowed {true}; + // Body scale float _targetScale; @@ -404,6 +416,8 @@ protected: SimpleMovingAverage _averageBytesReceived; + QMutex avatarLock; // Name is redundant, but it aids searches. + private: static QUrl _defaultFullAvatarModelUrl; // privatize the copy constructor and assignment operator so they cannot be called diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index a4f4ed6512..0227aa23a1 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1795,9 +1795,6 @@ void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) { } void EntityItem::setActionData(QByteArray actionData) { - if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { - qDebug() << "EntityItem::setActionData to " << actionData.size() << "bytes."; - } withWriteLock([&] { setActionDataInternal(actionData); }); @@ -1805,16 +1802,8 @@ void EntityItem::setActionData(QByteArray actionData) { void EntityItem::setActionDataInternal(QByteArray actionData) { if (_allActionsDataCache != actionData) { - if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { - qDebug() << "EntityItem::setActionDataInternal to " << actionData.size() << "bytes."; - } - _allActionsDataCache = actionData; deserializeActionsInternal(); - } else { - if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { - qDebug() << "EntityItem::setActionDataInternal NOT setting to " << actionData.size() << "bytes."; - } } checkWaitingToRemove(); } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 300d9a5728..f8b1d0dd54 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -61,7 +61,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { _parent.reset(); } - // we have a _parentID but no parent pointer, or our parent pointer is to the wrong thing + // we have a _parentID but no parent pointer, or our parent pointer was to the wrong thing QSharedPointer parentFinder = DependencyManager::get(); _parent = parentFinder->find(_parentID); parent = _parent.lock(); @@ -69,6 +69,11 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { parent->beParentOfChild(thisPointer); _parentKnowsMe = true; } + + if (parent || _parentID.isNull()) { + parentChanged(); + } + return parent; } @@ -80,10 +85,11 @@ void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const { _children.remove(newChild->getID()); } - void SpatiallyNestable::setParentID(const QUuid& parentID) { - _parentID = parentID; - _parentKnowsMe = false; + if (_parentID != parentID) { + _parentID = parentID; + _parentKnowsMe = false; + } } glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position) { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 986a282891..82e6c3d788 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -92,6 +92,8 @@ protected: virtual void forgetChild(SpatiallyNestablePointer newChild) const; mutable QHash _children; + virtual void parentChanged() const {} // called when parent pointer is updated + private: Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform.