diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9de0154f1c..03621fc24a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2413,10 +2413,18 @@ void Application::paintGL() { auto lodManager = DependencyManager::get(); RenderArgs renderArgs; + + float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); { PROFILE_RANGE(render, "/buildFrustrumAndArgs"); { QMutexLocker viewLocker(&_viewMutex); + // adjust near clip plane to account for sensor scaling. + auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + _viewFrustum.getAspectRatio(), + DEFAULT_NEAR_CLIP * sensorToWorldScale, + _viewFrustum.getFarClip()); + _viewFrustum.setProjection(adjustedProjection); _viewFrustum.calculate(); } renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), @@ -2570,7 +2578,6 @@ void Application::paintGL() { float ipdScale = hmdInterface->getIPDScale(); // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); ipdScale *= sensorToWorldScale; mat4 eyeProjections[2]; @@ -2582,6 +2589,7 @@ void Application::paintGL() { // in the overlay render? // Viewport is assigned to the size of the framebuffer renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + auto baseProjection = renderArgs.getViewFrustum().getProjection(); if (displayPlugin->isStereo()) { // Stereo modes will typically have a larger projection matrix overall, // so we ask for the 'mono' projection matrix, which for stereo and HMD @@ -2592,17 +2600,11 @@ void Application::paintGL() { // just relying on the left FOV in each case and hoping that the // overall culling margin of error doesn't cause popping in the // right eye. There are FIXMEs in the relevant plugins - _myCamera.setProjection(displayPlugin->getCullingProjection(_myCamera.getProjection())); + _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); renderArgs._context->enableStereo(true); mat4 eyeOffsets[2]; mat4 eyeProjections[2]; - // adjust near clip plane by sensorToWorldScale - auto baseProjection = glm::perspective(renderArgs.getViewFrustum().getFieldOfView(), - renderArgs.getViewFrustum().getAspectRatio(), - renderArgs.getViewFrustum().getNearClip() * sensorToWorldScale, - renderArgs.getViewFrustum().getFarClip()); - // FIXME we probably don't need to set the projection matrix every frame, // only when the display plugin changes (or in non-HMD modes when the user // changes the FOV manually, which right now I don't think they can. diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 7f72c80d55..55b55ed16f 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -16,9 +16,6 @@ #include "Overlay.h" -// AJT: keep or remove this. -// #define USE_SN_SCALE - class Base3DOverlay : public Overlay, public SpatiallyNestable { Q_OBJECT diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index e2877e1e07..e865714e58 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -69,8 +69,9 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve Transform Planar3DOverlay::evalRenderTransform() const { auto transform = getTransform(); + transform.setScale(1.0f); // ignore inherited scale factor from parents if (glm::length2(getDimensions()) != 1.0f) { transform.postScale(vec3(getDimensions(), 1.0f)); } return transform; -} \ No newline at end of file +} diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index b8249d6c75..0807d1c117 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -187,15 +187,6 @@ void Web3DOverlay::update(float deltatime) { Parent::update(deltatime); } -Transform Web3DOverlay::evalRenderTransform() const { - Transform transform = getTransform(); - transform.setScale(1.0f); // ignore inherited scale factor from parents - if (glm::length2(getDimensions()) != 1.0f) { - transform.postScale(vec3(getDimensions(), 1.0f)); - } - return transform; -} - QString Web3DOverlay::pickURL() { QUrl sourceUrl(_url); if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" || diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 7031a3f2c9..6bd540d120 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -38,7 +38,6 @@ public: virtual const render::ShapeKey getShapeKey() override; virtual void update(float deltatime) override; - virtual Transform Web3DOverlay::evalRenderTransform() const override; QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index bcf2b16ac6..db4e0ff7a1 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -28,7 +28,7 @@ public: float getIPD() const override final { return _ipd; } glm::mat4 getEyeToHeadTransform(Eye eye) const override final { return _eyeOffsets[eye]; } glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override { return _eyeProjections[eye]; } - glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override final { return _cullingProjection; } + glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override { return _cullingProjection; } glm::uvec2 getRecommendedUiSize() const override final; glm::uvec2 getRecommendedRenderSize() const override final { return _renderTargetSize; } bool isDisplayVisible() const override { return isHmdMounted(); } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index aa39353b94..ea0af0d5f5 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -76,6 +76,20 @@ glm::mat4 OculusBaseDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& ba } } +glm::mat4 OculusBaseDisplayPlugin::getCullingProjection(const glm::mat4& baseProjection) const { + if (_session) { + ViewFrustum baseFrustum; + baseFrustum.setProjection(baseProjection); + float baseNearClip = baseFrustum.getNearClip(); + float baseFarClip = baseFrustum.getFarClip(); + auto combinedFov = _eyeFovs[0]; + combinedFov.LeftTan = combinedFov.RightTan = std::max(combinedFov.LeftTan, combinedFov.RightTan); + return toGlm(ovrMatrix4f_Projection(combinedFov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_ClipRangeOpenGL)); + } else { + return baseProjection; + } +} + // DLL based display plugins MUST initialize GLEW inside the DLL code. void OculusBaseDisplayPlugin::customizeContext() { glewExperimental = true; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 4d14223618..b3b99c0ad1 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -20,6 +20,7 @@ public: bool isSupported() const override; glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override; + glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override; bool hasAsyncReprojection() const override { return true; } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 25c85737fe..96ad19f46b 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -370,6 +370,19 @@ glm::mat4 OpenVrDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& basePr } } +glm::mat4 OpenVrDisplayPlugin::getCullingProjection(const glm::mat4& baseProjection) const { + if (_system) { + ViewFrustum baseFrustum; + baseFrustum.setProjection(baseProjection); + float baseNearClip = baseFrustum.getNearClip(); + float baseFarClip = baseFrustum.getFarClip(); + // FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes + return toGlm(_system->GetProjectionMatrix((vr::EVREye)0, baseNearClip, baseFarClip)); + } else { + return baseProjection; + } +} + float OpenVrDisplayPlugin::getTargetFrameRate() const { if (forceInterleavedReprojection && !_asyncReprojectionActive) { return TARGET_RATE_OpenVr / 2.0f; diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 062345943a..6aea6ef575 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -39,6 +39,7 @@ public: const QString getName() const override { return NAME; } glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override; + glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override; void init() override;