From 71b2d647e85defbfd3430a1f79700c4591dbcc98 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 7 Mar 2016 10:04:54 -0800 Subject: [PATCH] add locks and explicitly copy ViewFrustums --- .../src/octree/OctreeQueryNode.cpp | 48 +++++--- .../src/octree/OctreeQueryNode.h | 8 +- .../src/octree/OctreeSendThread.cpp | 4 +- interface/src/Application.cpp | 109 ++++++++++++------ interface/src/Application.h | 9 +- interface/src/avatar/Avatar.cpp | 22 ++-- interface/src/avatar/Head.h | 2 - interface/src/avatar/MyAvatar.cpp | 14 ++- .../src/AbstractViewStateInterface.h | 8 +- .../render-utils/src/RenderDeferredTask.cpp | 6 +- libraries/render/src/render/SortTask.cpp | 4 +- 11 files changed, 148 insertions(+), 86 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 55eddf9e13..364cbf33c1 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -141,6 +141,16 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by } } +void OctreeQueryNode::copyCurrentViewFrustum(ViewFrustum& viewOut) const { + QMutexLocker viewLocker(&_viewMutex); + viewOut = _currentViewFrustum; +} + +void OctreeQueryNode::copyLastKnownViewFrustum(ViewFrustum& viewOut) const { + QMutexLocker viewLocker(&_viewMutex); + viewOut = _lastKnownViewFrustum; +} + bool OctreeQueryNode::updateCurrentViewFrustum() { // if shutting down, return immediately if (_isShuttingDown) { @@ -171,11 +181,13 @@ bool OctreeQueryNode::updateCurrentViewFrustum() { } - // if there has been a change, then recalculate - if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) { - _currentViewFrustum = newestViewFrustum; - _currentViewFrustum.calculate(); - currentViewFrustumChanged = true; + { // if there has been a change, then recalculate + QMutexLocker viewLocker(&_viewMutex); + if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) { + _currentViewFrustum = newestViewFrustum; + _currentViewFrustum.calculate(); + currentViewFrustumChanged = true; + } } // Also check for LOD changes from the client @@ -219,11 +231,14 @@ void OctreeQueryNode::updateLastKnownViewFrustum() { return; } - bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum); + { + QMutexLocker viewLocker(&_viewMutex); + bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum); - if (frustumChanges) { - // save our currentViewFrustum into our lastKnownViewFrustum - _lastKnownViewFrustum = _currentViewFrustum; + if (frustumChanges) { + // save our currentViewFrustum into our lastKnownViewFrustum + _lastKnownViewFrustum = _currentViewFrustum; + } } // save that we know the view has been sent. @@ -237,15 +252,13 @@ bool OctreeQueryNode::moveShouldDump() const { return false; } + QMutexLocker viewLocker(&_viewMutex); glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition(); glm::vec3 newPosition = _currentViewFrustum.getPosition(); // theoretically we could make this slightly larger but relative to avatar scale. const float MAXIMUM_MOVE_WITHOUT_DUMP = 0.0f; - if (glm::distance(newPosition, oldPosition) > MAXIMUM_MOVE_WITHOUT_DUMP) { - return true; - } - return false; + return glm::distance(newPosition, oldPosition) > MAXIMUM_MOVE_WITHOUT_DUMP; } void OctreeQueryNode::dumpOutOfView() { @@ -257,8 +270,13 @@ void OctreeQueryNode::dumpOutOfView() { int stillInView = 0; int outOfView = 0; OctreeElementBag tempBag; + ViewFrustum viewCopy; + { + QMutexLocker viewLocker(&_viewMutex); + viewCopy = _currentViewFrustum; + } while (OctreeElementPointer elementToCheck = elementBag.extract()) { - if (elementToCheck->isInView(_currentViewFrustum)) { + if (elementToCheck->isInView(viewCopy)) { tempBag.insert(elementToCheck); stillInView++; } else { @@ -267,7 +285,7 @@ void OctreeQueryNode::dumpOutOfView() { } if (stillInView > 0) { while (OctreeElementPointer elementToKeepInBag = tempBag.extract()) { - if (elementToKeepInBag->isInView(_currentViewFrustum)) { + if (elementToKeepInBag->isInView(viewCopy)) { elementBag.insert(elementToKeepInBag); } } diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 22d04d81f6..96f46cb2fa 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -56,8 +56,8 @@ public: OctreeElementBag elementBag; OctreeElementExtraEncodeData extraEncodeData; - const ViewFrustum& getCurrentViewFrustum() const { return _currentViewFrustum; } - const ViewFrustum& getLastKnownViewFrustum() const { return _lastKnownViewFrustum; } + void copyCurrentViewFrustum(ViewFrustum& viewOut) const; + void copyLastKnownViewFrustum(ViewFrustum& viewOut) const; // These are not classic setters because they are calculating and maintaining state // which is set asynchronously through the network receive @@ -114,6 +114,8 @@ private: int _maxSearchLevel { 1 }; int _maxLevelReachedInLastSearch { 1 }; + + mutable QMutex _viewMutex { QMutex::Recursive }; ViewFrustum _currentViewFrustum; ViewFrustum _lastKnownViewFrustum; quint64 _lastTimeBagEmpty { 0 }; @@ -139,7 +141,7 @@ private: QQueue _nackedSequenceNumbers; quint64 _sceneSendStartTime = 0; - + std::array _lastOctreePayload; }; diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 7701cedd94..709cdd5d07 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -427,9 +427,9 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* nodeData->getLastTimeBagEmpty(), isFullScene, &nodeData->stats, _myServer->getJurisdiction(), &nodeData->extraEncodeData); - params.viewFrustum = nodeData->getCurrentViewFrustum(); + nodeData->copyCurrentViewFrustum(params.viewFrustum); if (viewFrustumChanged) { - params.lastViewFrustum = nodeData->getLastKnownViewFrustum(); + nodeData->copyLastKnownViewFrustum(params.lastViewFrustum); } // Our trackSend() function is implemented by the server subclass, and will be called back diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 994bb89556..19b0e432e1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1511,12 +1511,17 @@ void Application::paintGL() { auto lodManager = DependencyManager::get(); - - _viewFrustum.calculate(); + { + QMutexLocker viewLocker(&_viewMutex); + _viewFrustum.calculate(); + } RenderArgs renderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(), lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - renderArgs.setViewFrustum(getViewFrustum()); + { + QMutexLocker viewLocker(&_viewMutex); + renderArgs.setViewFrustum(_viewFrustum); + } PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); @@ -1813,7 +1818,10 @@ void Application::resizeGL() { _myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); // Possible change in aspect ratio - loadViewFrustum(_myCamera, _viewFrustum); + { + QMutexLocker viewLocker(&_viewMutex); + loadViewFrustum(_myCamera, _viewFrustum); + } auto offscreenUi = DependencyManager::get(); auto uiSize = displayPlugin->getRecommendedUiSize(); @@ -2140,6 +2148,7 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_J: if (isShifted) { + QMutexLocker viewLocker(&_viewMutex); _viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f); } else { _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0)); @@ -2149,6 +2158,7 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_M: if (isShifted) { + QMutexLocker viewLocker(&_viewMutex); _viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f); } else { _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0)); @@ -2997,7 +3007,10 @@ void Application::init() { DependencyManager::get()->sendDomainServerCheckIn(); getEntities()->init(); - getEntities()->setViewFrustum(getViewFrustum()); + { + QMutexLocker viewLocker(&_viewMutex); + getEntities()->setViewFrustum(_viewFrustum); + } ObjectMotionState::setShapeManager(&_shapeManager); _physicsEngine->init(); @@ -3017,7 +3030,10 @@ void Application::init() { getEntities()->connectSignalsToSlots(entityScriptingInterface.data()); _entityClipboardRenderer.init(); - _entityClipboardRenderer.setViewFrustum(getViewFrustum()); + { + QMutexLocker viewLocker(&_viewMutex); + _entityClipboardRenderer.setViewFrustum(_viewFrustum); + } _entityClipboardRenderer.setTree(_entityClipboard); // Make sure any new sounds are loaded as soon as know about them. @@ -3220,9 +3236,12 @@ void Application::resetPhysicsReadyInformation() { void Application::reloadResourceCaches() { resetPhysicsReadyInformation(); + { + QMutexLocker viewLocker(&_viewMutex); + _viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE)); + _viewFrustum.setOrientation(glm::quat()); + } // Clear entities out of view frustum - _viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE)); - _viewFrustum.setOrientation(glm::quat()); queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions); DependencyManager::get()->clearCache(); @@ -3511,7 +3530,7 @@ void Application::update(float deltaTime) { // actually need to calculate the view frustum planes to send these details // to the server. { - PerformanceTimer perfTimer("loadViewFrustum"); + QMutexLocker viewLocker(&_viewMutex); loadViewFrustum(_myCamera, _viewFrustum); } @@ -3520,6 +3539,7 @@ void Application::update(float deltaTime) { // Update my voxel servers with my current voxel query... { PROFILE_RANGE_EX("QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount()); + QMutexLocker viewLocker(&_viewMutex); PerformanceTimer perfTimer("queryOctree"); quint64 sinceLastQuery = now - _lastQueriedTime; const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND; @@ -3631,14 +3651,19 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); bool wantExtraDebugging = getLogger()->extraDebugging(); - _octreeQuery.setCameraPosition(_viewFrustum.getPosition()); - _octreeQuery.setCameraOrientation(_viewFrustum.getOrientation()); - _octreeQuery.setCameraFov(_viewFrustum.getFieldOfView()); - _octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio()); - _octreeQuery.setCameraNearClip(_viewFrustum.getNearClip()); - _octreeQuery.setCameraFarClip(_viewFrustum.getFarClip()); + ViewFrustum viewFrustumCopy; + { + QMutexLocker viewLocker(&_viewMutex); + viewFrustumCopy = _viewFrustum; + } + _octreeQuery.setCameraPosition(viewFrustumCopy.getPosition()); + _octreeQuery.setCameraOrientation(viewFrustumCopy.getOrientation()); + _octreeQuery.setCameraFov(viewFrustumCopy.getFieldOfView()); + _octreeQuery.setCameraAspectRatio(viewFrustumCopy.getAspectRatio()); + _octreeQuery.setCameraNearClip(viewFrustumCopy.getNearClip()); + _octreeQuery.setCameraFarClip(viewFrustumCopy.getFarClip()); _octreeQuery.setCameraEyeOffsetPosition(glm::vec3()); - _octreeQuery.setCameraCenterRadius(_viewFrustum.getCenterRadius()); + _octreeQuery.setCameraCenterRadius(viewFrustumCopy.getCenterRadius()); auto lodManager = DependencyManager::get(); _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); @@ -3674,7 +3699,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node rootDetails.y * TREE_SCALE, rootDetails.z * TREE_SCALE) - glm::vec3(HALF_TREE_SCALE), rootDetails.s * TREE_SCALE); - if (_viewFrustum.cubeIntersectsKeyhole(serverBounds)) { + if (viewFrustumCopy.cubeIntersectsKeyhole(serverBounds)) { inViewServers++; } } @@ -3740,7 +3765,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node rootDetails.s * TREE_SCALE); - inView = _viewFrustum.cubeIntersectsKeyhole(serverBounds); + inView = viewFrustumCopy.cubeIntersectsKeyhole(serverBounds); } else { if (wantExtraDebugging) { qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!"; @@ -3835,6 +3860,7 @@ QRect Application::getDesirableApplicationGeometry() const { // or the "myCamera". // void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { + PerformanceTimer perfTimer("loadViewFrustum"); PROFILE_RANGE(__FUNCTION__); // We will use these below, from either the camera or head vectors calculated above viewFrustum.setProjection(camera.getProjection()); @@ -3863,7 +3889,8 @@ PickRay Application::computePickRay(float x, float y) const { getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction); } else { pickPoint /= getCanvasSize(); - getViewFrustum().computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction); + QMutexLocker viewLocker(&_viewMutex); + _viewFrustum.computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction); } return result; } @@ -3876,24 +3903,19 @@ glm::vec3 Application::getAvatarPosition() const { return getMyAvatar()->getPosition(); } -const ViewFrustum& Application::getViewFrustum() const { -#ifdef DEBUG - if (QThread::currentThread() == activeRenderingThread) { - // FIXME, figure out a better way to do this - //qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?"; - } -#endif - return _viewFrustum; +void Application::copyViewFrustum(ViewFrustum& viewOut) const { + QMutexLocker viewLocker(&_viewMutex); + viewOut = _viewFrustum; } -const ViewFrustum& Application::getDisplayViewFrustum() const { -#ifdef DEBUG - if (QThread::currentThread() != activeRenderingThread) { - // FIXME, figure out a better way to do this - // qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?"; - } -#endif - return _displayViewFrustum; +void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { + QMutexLocker viewLocker(&_viewMutex); + viewOut = _displayViewFrustum; +} + +void Application::copyShadowViewFrustum(ViewFrustum& viewOut) const { + QMutexLocker viewLocker(&_viewMutex); + viewOut = _shadowViewFrustum; } // WorldBox Render Data & rendering functions @@ -4002,7 +4024,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // load the view frustum - loadViewFrustum(theCamera, _displayViewFrustum); + { + QMutexLocker viewLocker(&_viewMutex); + loadViewFrustum(theCamera, _displayViewFrustum); + } // TODO fix shadows and make them use the GPU library @@ -4070,7 +4095,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se { PerformanceTimer perfTimer("EngineRun"); - renderArgs->setViewFrustum(getDisplayViewFrustum()); + { + QMutexLocker viewLocker(&_viewMutex); + renderArgs->setViewFrustum(_displayViewFrustum); + } _renderEngine->getRenderContext()->args = renderArgs; // Before the deferred pass, let's try to use the render engine @@ -4496,6 +4524,11 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("Reticle", getApplicationCompositor().getReticleInterface()); } +void Application::copyCurrentViewFrustum(ViewFrustum& viewOut) const { + QMutexLocker viewLocker(&_viewMutex); + viewOut = _displayViewFrustum; +} + bool Application::canAcceptURL(const QString& urlString) const { QUrl url(urlString); if (urlString.startsWith(HIFI_URL_SCHEME)) { @@ -5200,10 +5233,10 @@ void Application::updateInputModes() { } mat4 Application::getEyeProjection(int eye) const { + QMutexLocker viewLocker(&_viewMutex); if (isHMDMode()) { return getActiveDisplayPlugin()->getEyeProjection((Eye)eye, _viewFrustum.getProjection()); } - return _viewFrustum.getProjection(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 3f26f7bc38..018265db4a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -128,12 +128,12 @@ public: Camera* getCamera() { return &_myCamera; } const Camera* getCamera() const { return &_myCamera; } // Represents the current view frustum of the avatar. - const ViewFrustum& getViewFrustum() const; + void copyViewFrustum(ViewFrustum& viewOut) const; // Represents the view frustum of the current rendering pass, // which might be different from the viewFrustum, i.e. shadowmap // passes, mirror window passes, etc - const ViewFrustum& getDisplayViewFrustum() const; - const ViewFrustum& getShadowViewFrustum() override { return _shadowViewFrustum; } + void copyDisplayViewFrustum(ViewFrustum& viewOut) const; + void copyShadowViewFrustum(ViewFrustum& viewOut) const override; const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } EntityTreeRenderer* getEntities() const { return DependencyManager::get().data(); } QUndoStack* getUndoStack() { return &_undoStack; } @@ -167,7 +167,7 @@ public: virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; } virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) override; - virtual const ViewFrustum& getCurrentViewFrustum() override { return getDisplayViewFrustum(); } + virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const override; virtual QThread* getMainThread() override { return thread(); } virtual PickRay computePickRay(float x, float y) const override; virtual glm::vec3 getAvatarPosition() const override; @@ -412,6 +412,7 @@ private: EntityTreeRenderer _entityClipboardRenderer; EntityTreePointer _entityClipboard; + mutable QMutex _viewMutex { QMutex::Recursive }; ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels) ViewFrustum _displayViewFrustum; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index f753309ffc..356b940713 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -172,7 +172,9 @@ void Avatar::simulate(float deltaTime) { // update the shouldAnimate flag to match whether or not we will render the avatar. const float MINIMUM_VISIBILITY_FOR_ON = 0.4f; const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f; - float visibility = calculateRenderAccuracy(qApp->getViewFrustum().getPosition(), + ViewFrustum viewFrustum; + qApp->copyViewFrustum(viewFrustum); + float visibility = calculateRenderAccuracy(viewFrustum.getPosition(), getBounds(), DependencyManager::get()->getOctreeSizeScale()); if (!_shouldAnimate) { if (visibility > MINIMUM_VISIBILITY_FOR_ON) { @@ -186,8 +188,9 @@ void Avatar::simulate(float deltaTime) { // simple frustum check float boundingRadius = getBoundingRadius(); - bool avatarPositionInView = qApp->getDisplayViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius); - bool avatarMeshInView = qApp->getDisplayViewFrustum()->boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound()); + qApp->copyDisplayViewFrustum(viewFrustum); + bool avatarPositionInView = viewFrustum.sphereIntersectsFrustum(getPosition(), boundingRadius); + bool avatarMeshInView = viewFrustum.boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound()); if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) { { @@ -384,9 +387,12 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } { // simple frustum check - const ViewFrustum& frustum = renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE ? - qApp->getShadowViewFrustum() : - qApp->getDisplayViewFrustum(); + ViewFrustum frustum; + if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) { + qApp->copyShadowViewFrustum(frustum); + } else { + qApp->copyDisplayViewFrustum(frustum); + } if (!frustum.sphereIntersectsFrustum(getPosition(), getBoundingRadius())) { return; } @@ -500,7 +506,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto cameraMode = qApp->getCamera()->getMode(); if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) { - auto frustum = renderArgs->getViewFrustum(); + ViewFrustum frustum = renderArgs->getViewFrustum(); auto textPosition = getDisplayNamePosition(); if (frustum.pointIntersectsFrustum(textPosition)) { renderDisplayName(batch, frustum, textPosition); @@ -550,7 +556,7 @@ void Avatar::fixupModelsInScene() { scene->enqueuePendingChanges(pendingChanges); } -void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) { +void Avatar::renderBody(RenderArgs* renderArgs, float glowLevel) { fixupModelsInScene(); getHead()->renderLookAts(renderArgs); } diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 4c0a516ecc..ef9584f1a7 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -29,8 +29,6 @@ class Head : public HeadData { public: explicit Head(Avatar* owningAvatar); - Head(Avatar* owningAvatar); - void init(); void reset(); void simulate(float deltaTime, bool isMine, bool billboard = false); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2208e827a0..d4e024e49e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -546,7 +546,9 @@ void MyAvatar::updateFromTrackers(float deltaTime) { head->setDeltaYaw(estimatedRotation.y); head->setDeltaRoll(estimatedRotation.z); } else { - float magnifyFieldOfView = qApp->getViewFrustum().getFieldOfView() / _realWorldFieldOfView.get(); + ViewFrustum viewFrustum; + qApp->copyViewFrustum(viewFrustum); + float magnifyFieldOfView = viewFrustum.getFieldOfView() / _realWorldFieldOfView.get(); head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView); head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView); head->setDeltaRoll(estimatedRotation.z); @@ -929,15 +931,17 @@ void MyAvatar::updateLookAtTargetAvatar() { // (We will be adding that offset to the camera position, after making some other adjustments.) glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition(); + ViewFrustum viewFrustum; + qApp->copyViewFrustum(viewFrustum); + // scale gazeOffset by IPD, if wearing an HMD. if (qApp->isHMDMode()) { glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left); glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right); glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]); glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]); - auto humanSystem = qApp->getViewFrustum(); - glm::vec3 humanLeftEye = humanSystem.getPosition() + (humanSystem.getOrientation() * leftEyeHeadLocal); - glm::vec3 humanRightEye = humanSystem.getPosition() + (humanSystem.getOrientation() * rightEyeHeadLocal); + glm::vec3 humanLeftEye = viewFrustum.getPosition() + (viewFrustum.getOrientation() * leftEyeHeadLocal); + glm::vec3 humanRightEye = viewFrustum.getPosition() + (viewFrustum.getOrientation() * rightEyeHeadLocal); auto hmdInterface = DependencyManager::get(); float ipdScale = hmdInterface->getIPDScale(); @@ -951,7 +955,7 @@ void MyAvatar::updateLookAtTargetAvatar() { } // And now we can finally add that offset to the camera. - glm::vec3 corrected = qApp->getViewFrustum().getPosition() + gazeOffset; + glm::vec3 corrected = viewFrustum.getPosition() + gazeOffset; avatar->getHead()->setCorrectedLookAtPosition(corrected); diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index c068baf453..81790728f8 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -28,11 +28,11 @@ class PickRay; /// Interface provided by Application to other objects that need access to the current view state details class AbstractViewStateInterface { public: - /// gets the current view frustum for rendering the view state - virtual const ViewFrustum& getCurrentViewFrustum() = 0; + /// copies the current view frustum for rendering the view state + virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const = 0; - /// gets the shadow view frustum for rendering the view state - virtual const ViewFrustum& getShadowViewFrustum() = 0; + /// copies the shadow view frustum for rendering the view state + virtual void copyShadowViewFrustum(ViewFrustum& viewOut) const = 0; virtual QThread* getMainThread() = 0; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 000446d9df..444c52623e 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -202,7 +202,7 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont void DrawStateSortDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems) { assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->args->hasViewFrustum()); auto config = std::static_pointer_cast(renderContext->jobConfig); @@ -215,8 +215,8 @@ void DrawStateSortDeferred::run(const SceneContextPointer& sceneContext, const R glm::mat4 projMat; Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + args->getViewFrustum().evalProjectionMatrix(projMat); + args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); diff --git a/libraries/render/src/render/SortTask.cpp b/libraries/render/src/render/SortTask.cpp index d2fda542b1..9c288f96ff 100644 --- a/libraries/render/src/render/SortTask.cpp +++ b/libraries/render/src/render/SortTask.cpp @@ -42,7 +42,7 @@ struct BackToFrontSort { void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemBounds& inItems, ItemBounds& outItems) { assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->args->hasViewFrustum()); auto& scene = sceneContext->_scene; RenderArgs* args = renderContext->args; @@ -60,7 +60,7 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende for (auto itemDetails : inItems) { auto item = scene->getItem(itemDetails.id); auto bound = itemDetails.bound; // item.getBound(); - float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter()); + float distance = args->getViewFrustum().distanceToCamera(bound.calcCenter()); itemBoundSorts.emplace_back(ItemBoundSort(distance, distance, distance, itemDetails.id, bound)); }