resurrection of threadsafe ViewFrustum
Showing the changes to interface/src/Application.cpp (1 of 51 files). Show all
Unified · Split
| @@ -1481,10 +1481,17 @@ void Application::paintGL() { · 1480 unmodified lines | ||
| 1481 | 1481 | |
| 1482 | 1482 | auto lodManager = DependencyManager::get<LODManager>(); |
| 1483 | 1483 | |
| 1484 | − | |
| 1485 | − RenderArgs renderArgs(_gpuContext, getEntities(), getViewFrustum(), lodManager->getOctreeSizeScale(), | |
| 1484 | + { | |
| 1485 | + QMutexLocker viewLocker(&_viewMutex); | |
| 1486 | + _viewFrustum.calculate(); | |
| 1487 | + } | |
| 1488 | + RenderArgs renderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(), | |
| 1486 | 1489 | lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, |
| 1487 | 1490 | RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); |
| 1491 | + { | |
| 1492 | + QMutexLocker viewLocker(&_viewMutex); | |
| 1493 | + renderArgs.setViewFrustum(_viewFrustum); | |
| 1494 | + } | |
| 1488 | 1495 | |
| 1489 | 1496 | PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); |
| 1490 | 1497 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); |
| @@ -1651,7 +1658,7 @@ void Application::paintGL() { · 160 unmodified lines | ||
| 1651 | 1658 | renderArgs._context->enableStereo(true); |
| 1652 | 1659 | mat4 eyeOffsets[2]; |
| 1653 | 1660 | mat4 eyeProjections[2]; |
| 1654 | − auto baseProjection = renderArgs._viewFrustum->getProjection(); | |
| 1661 | + auto baseProjection = renderArgs.getViewFrustum().getProjection(); | |
| 1655 | 1662 | auto hmdInterface = DependencyManager::get<HMDScriptingInterface>(); |
| 1656 | 1663 | float IPDScale = hmdInterface->getIPDScale(); |
| 1657 | 1664 | mat4 headPose = displayPlugin->getHeadPose(); |
| @@ -1781,7 +1788,10 @@ void Application::resizeGL() { · 123 unmodified lines | ||
| 1781 | 1788 | _myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio, |
| 1782 | 1789 | DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); |
| 1783 | 1790 | // Possible change in aspect ratio |
| 1784 | − loadViewFrustum(_myCamera, _viewFrustum); | |
| 1791 | + { | |
| 1792 | + QMutexLocker viewLocker(&_viewMutex); | |
| 1793 | + loadViewFrustum(_myCamera, _viewFrustum); | |
| 1794 | + } | |
| 1785 | 1795 | |
| 1786 | 1796 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 1787 | 1797 | auto uiSize = displayPlugin->getRecommendedUiSize(); |
| @@ -2108,6 +2118,7 @@ void Application::keyPressEvent(QKeyEvent* event) { · 320 unmodified lines | ||
| 2108 | 2118 | |
| 2109 | 2119 | case Qt::Key_J: |
| 2110 | 2120 | if (isShifted) { |
| 2121 | + QMutexLocker viewLocker(&_viewMutex); | |
| 2111 | 2122 | _viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f); |
| 2112 | 2123 | } else { |
| 2113 | 2124 | _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0)); |
| @@ -2117,6 +2128,7 @@ void Application::keyPressEvent(QKeyEvent* event) { · 3 unmodified lines | ||
| 2117 | 2128 | |
| 2118 | 2129 | case Qt::Key_M: |
| 2119 | 2130 | if (isShifted) { |
| 2131 | + QMutexLocker viewLocker(&_viewMutex); | |
| 2120 | 2132 | _viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f); |
| 2121 | 2133 | } else { |
| 2122 | 2134 | _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0)); |
| @@ -2965,7 +2977,10 @@ void Application::init() { · 842 unmodified lines | ||
| 2965 | 2977 | DependencyManager::get<NodeList>()->sendDomainServerCheckIn(); |
| 2966 | 2978 | |
| 2967 | 2979 | getEntities()->init(); |
| 2968 | − getEntities()->setViewFrustum(getViewFrustum()); | |
| 2980 | + { | |
| 2981 | + QMutexLocker viewLocker(&_viewMutex); | |
| 2982 | + getEntities()->setViewFrustum(_viewFrustum); | |
| 2983 | + } | |
| 2969 | 2984 | |
| 2970 | 2985 | ObjectMotionState::setShapeManager(&_shapeManager); |
| 2971 | 2986 | _physicsEngine->init(); |
| @@ -2985,7 +3000,10 @@ void Application::init() { · 13 unmodified lines | ||
| 2985 | 3000 | getEntities()->connectSignalsToSlots(entityScriptingInterface.data()); |
| 2986 | 3001 | |
| 2987 | 3002 | _entityClipboardRenderer.init(); |
| 2988 | − _entityClipboardRenderer.setViewFrustum(getViewFrustum()); | |
| 3003 | + { | |
| 3004 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3005 | + _entityClipboardRenderer.setViewFrustum(_viewFrustum); | |
| 3006 | + } | |
| 2989 | 3007 | _entityClipboardRenderer.setTree(_entityClipboard); |
| 2990 | 3008 | |
| 2991 | 3009 | // Make sure any new sounds are loaded as soon as know about them. |
| @@ -3199,9 +3217,12 @@ void Application::resetPhysicsReadyInformation() { · 207 unmodified lines | ||
| 3199 | 3217 | |
| 3200 | 3218 | void Application::reloadResourceCaches() { |
| 3201 | 3219 | resetPhysicsReadyInformation(); |
| 3220 | + { | |
| 3221 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3222 | + _viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE)); | |
| 3223 | + _viewFrustum.setOrientation(glm::quat()); | |
| 3224 | + } | |
| 3202 | 3225 | // Clear entities out of view frustum |
| 3203 | − _viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE)); | |
| 3204 | − _viewFrustum.setOrientation(glm::quat()); | |
| 3205 | 3226 | queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions); |
| 3206 | 3227 | |
| 3207 | 3228 | DependencyManager::get<AssetClient>()->clearCache(); |
| @@ -3490,7 +3511,7 @@ void Application::update(float deltaTime) { · 282 unmodified lines | ||
| 3490 | 3511 | // actually need to calculate the view frustum planes to send these details |
| 3491 | 3512 | // to the server. |
| 3492 | 3513 | { |
| 3493 | − PerformanceTimer perfTimer("loadViewFrustum"); | |
| 3514 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3494 | 3515 | loadViewFrustum(_myCamera, _viewFrustum); |
| 3495 | 3516 | } |
| 3496 | 3517 | |
| @@ -3499,6 +3520,7 @@ void Application::update(float deltaTime) { · 2 unmodified lines | ||
| 3499 | 3520 | // Update my voxel servers with my current voxel query... |
| 3500 | 3521 | { |
| 3501 | 3522 | PROFILE_RANGE_EX("QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount()); |
| 3523 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3502 | 3524 | PerformanceTimer perfTimer("queryOctree"); |
| 3503 | 3525 | quint64 sinceLastQuery = now - _lastQueriedTime; |
| 3504 | 3526 | const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND; |
| @@ -3610,14 +3632,16 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 105 unmodified lines | ||
| 3610 | 3632 | //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); |
| 3611 | 3633 | bool wantExtraDebugging = getLogger()->extraDebugging(); |
| 3612 | 3634 | |
| 3613 | − _octreeQuery.setCameraPosition(_viewFrustum.getPosition()); | |
| 3614 | − _octreeQuery.setCameraOrientation(_viewFrustum.getOrientation()); | |
| 3615 | − _octreeQuery.setCameraFov(_viewFrustum.getFieldOfView()); | |
| 3616 | − _octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio()); | |
| 3617 | − _octreeQuery.setCameraNearClip(_viewFrustum.getNearClip()); | |
| 3618 | − _octreeQuery.setCameraFarClip(_viewFrustum.getFarClip()); | |
| 3635 | + ViewFrustum viewFrustum; | |
| 3636 | + copyViewFrustum(viewFrustum); | |
| 3637 | + _octreeQuery.setCameraPosition(viewFrustum.getPosition()); | |
| 3638 | + _octreeQuery.setCameraOrientation(viewFrustum.getOrientation()); | |
| 3639 | + _octreeQuery.setCameraFov(viewFrustum.getFieldOfView()); | |
| 3640 | + _octreeQuery.setCameraAspectRatio(viewFrustum.getAspectRatio()); | |
| 3641 | + _octreeQuery.setCameraNearClip(viewFrustum.getNearClip()); | |
| 3642 | + _octreeQuery.setCameraFarClip(viewFrustum.getFarClip()); | |
| 3619 | 3643 | _octreeQuery.setCameraEyeOffsetPosition(glm::vec3()); |
| 3620 | − _octreeQuery.setCameraCenterRadius(_viewFrustum.getCenterRadius()); | |
| 3644 | + _octreeQuery.setCameraCenterRadius(viewFrustum.getCenterRadius()); | |
| 3621 | 3645 | auto lodManager = DependencyManager::get<LODManager>(); |
| 3622 | 3646 | _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); |
| 3623 | 3647 | _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); |
| @@ -3653,7 +3677,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 29 unmodified lines | ||
| 3653 | 3677 | rootDetails.y * TREE_SCALE, |
| 3654 | 3678 | rootDetails.z * TREE_SCALE) - glm::vec3(HALF_TREE_SCALE), |
| 3655 | 3679 | rootDetails.s * TREE_SCALE); |
| 3656 | − if (_viewFrustum.cubeIntersectsKeyhole(serverBounds)) { | |
| 3680 | + if (viewFrustum.cubeIntersectsKeyhole(serverBounds)) { | |
| 3657 | 3681 | inViewServers++; |
| 3658 | 3682 | } |
| 3659 | 3683 | } |
| @@ -3719,11 +3743,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 59 unmodified lines | ||
| 3719 | 3743 | rootDetails.s * TREE_SCALE); |
| 3720 | 3744 | |
| 3721 | 3745 | |
| 3722 | − inView = _viewFrustum.cubeIntersectsKeyhole(serverBounds); | |
| 3723 | − } else { | |
| 3724 | − if (wantExtraDebugging) { | |
| 3725 | − qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!"; | |
| 3726 | − } | |
| 3746 | + inView = viewFrustum.cubeIntersectsKeyhole(serverBounds); | |
| 3747 | + } else if (wantExtraDebugging) { | |
| 3748 | + qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!"; | |
| 3727 | 3749 | } |
| 3728 | 3750 | } |
| 3729 | 3751 | |
| @@ -3814,6 +3836,7 @@ QRect Application::getDesirableApplicationGeometry() const { · 84 unmodified lines | ||
| 3814 | 3836 | // or the "myCamera". |
| 3815 | 3837 | // |
| 3816 | 3838 | void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { |
| 3839 | + PerformanceTimer perfTimer("loadViewFrustum"); | |
| 3817 | 3840 | PROFILE_RANGE(__FUNCTION__); |
| 3818 | 3841 | // We will use these below, from either the camera or head vectors calculated above |
| 3819 | 3842 | viewFrustum.setProjection(camera.getProjection()); |
| @@ -3842,7 +3865,8 @@ PickRay Application::computePickRay(float x, float y) const { · 22 unmodified lines | ||
| 3842 | 3865 | getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction); |
| 3843 | 3866 | } else { |
| 3844 | 3867 | pickPoint /= getCanvasSize(); |
| 3845 | − getViewFrustum()->computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction); | |
| 3868 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3869 | + _viewFrustum.computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction); | |
| 3846 | 3870 | } |
| 3847 | 3871 | return result; |
| 3848 | 3872 | } |
| @@ -3855,44 +3879,19 @@ glm::vec3 Application::getAvatarPosition() const { · 6 unmodified lines | ||
| 3855 | 3879 | return getMyAvatar()->getPosition(); |
| 3856 | 3880 | } |
| 3857 | 3881 | |
| 3858 | −ViewFrustum* Application::getViewFrustum() { | |
| 3859 | −#ifdef DEBUG | |
| 3860 | − if (QThread::currentThread() == activeRenderingThread) { | |
| 3861 | − // FIXME, figure out a better way to do this | |
| 3862 | − //qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?"; | |
| 3863 | − } | |
| 3864 | −#endif | |
| 3865 | − return &_viewFrustum; | |
| 3866 | −} | |
| 3867 | − | |
| 3868 | −const ViewFrustum* Application::getViewFrustum() const { | |
| 3869 | −#ifdef DEBUG | |
| 3870 | − if (QThread::currentThread() == activeRenderingThread) { | |
| 3871 | − // FIXME, figure out a better way to do this | |
| 3872 | − //qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?"; | |
| 3873 | − } | |
| 3874 | −#endif | |
| 3875 | − return &_viewFrustum; | |
| 3882 | +void Application::copyViewFrustum(ViewFrustum& viewOut) const { | |
| 3883 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3884 | + viewOut = _viewFrustum; | |
| 3876 | 3885 | } |
| 3877 | 3886 | |
| 3878 | −ViewFrustum* Application::getDisplayViewFrustum() { | |
| 3879 | −#ifdef DEBUG | |
| 3880 | − if (QThread::currentThread() != activeRenderingThread) { | |
| 3881 | − // FIXME, figure out a better way to do this | |
| 3882 | − // qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?"; | |
| 3883 | − } | |
| 3884 | −#endif | |
| 3885 | − return &_displayViewFrustum; | |
| 3887 | +void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { | |
| 3888 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3889 | + viewOut = _displayViewFrustum; | |
| 3886 | 3890 | } |
| 3887 | 3891 | |
| 3888 | −const ViewFrustum* Application::getDisplayViewFrustum() const { | |
| 3889 | −#ifdef DEBUG | |
| 3890 | − if (QThread::currentThread() != activeRenderingThread) { | |
| 3891 | − // FIXME, figure out a better way to do this | |
| 3892 | − // qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?"; | |
| 3893 | − } | |
| 3894 | −#endif | |
| 3895 | − return &_displayViewFrustum; | |
| 3892 | +void Application::copyShadowViewFrustum(ViewFrustum& viewOut) const { | |
| 3893 | + QMutexLocker viewLocker(&_viewMutex); | |
| 3894 | + viewOut = _shadowViewFrustum; | |
| 3896 | 3895 | } |
| 3897 | 3896 | |
| 3898 | 3897 | // WorldBox Render Data & rendering functions |
| @@ -3957,7 +3956,7 @@ namespace render { · 58 unmodified lines | ||
| 3957 | 3956 | auto skybox = skyStage->getSkybox(); |
| 3958 | 3957 | if (skybox) { |
| 3959 | 3958 | PerformanceTimer perfTimer("skybox"); |
| 3960 | − skybox->render(batch, *(args->_viewFrustum)); | |
| 3959 | + skybox->render(batch, args->getViewFrustum()); | |
| 3961 | 3960 | break; |
| 3962 | 3961 | } |
| 3963 | 3962 | } |
| @@ -4001,7 +4000,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 37 unmodified lines | ||
| 4001 | 4000 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); |
| 4002 | 4001 | |
| 4003 | 4002 | // load the view frustum |
| 4004 | − loadViewFrustum(theCamera, _displayViewFrustum); | |
| 4003 | + { | |
| 4004 | + QMutexLocker viewLocker(&_viewMutex); | |
| 4005 | + loadViewFrustum(theCamera, _displayViewFrustum); | |
| 4006 | + } | |
| 4005 | 4007 | |
| 4006 | 4008 | // TODO fix shadows and make them use the GPU library |
| 4007 | 4009 | |
| @@ -4069,7 +4071,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 61 unmodified lines | ||
| 4069 | 4071 | { |
| 4070 | 4072 | PerformanceTimer perfTimer("EngineRun"); |
| 4071 | 4073 | |
| 4072 | − renderArgs->_viewFrustum = getDisplayViewFrustum(); | |
| 4074 | + { | |
| 4075 | + QMutexLocker viewLocker(&_viewMutex); | |
| 4076 | + renderArgs->setViewFrustum(_displayViewFrustum); | |
| 4077 | + } | |
| 4073 | 4078 | _renderEngine->getRenderContext()->args = renderArgs; |
| 4074 | 4079 | |
| 4075 | 4080 | // Before the deferred pass, let's try to use the render engine |
| @@ -5199,10 +5204,10 @@ void Application::updateInputModes() { · 1123 unmodified lines | ||
| 5199 | 5204 | } |
| 5200 | 5205 | |
| 5201 | 5206 | mat4 Application::getEyeProjection(int eye) const { |
| 5207 | + QMutexLocker viewLocker(&_viewMutex); | |
| 5202 | 5208 | if (isHMDMode()) { |
| 5203 | 5209 | return getActiveDisplayPlugin()->getEyeProjection((Eye)eye, _viewFrustum.getProjection()); |
| 5204 | 5210 | } |
| 5205 | − | |
| 5206 | 5211 | return _viewFrustum.getProjection(); |
| 5207 | 5212 | } |
| 5208 | 5213 | |