From 81bed9eaaced1752525b4127962f6760182ddd36 Mon Sep 17 00:00:00 2001 From: Terry Welsh Date: Fri, 22 Jul 2022 08:18:23 -0700 Subject: [PATCH 1/2] PSSM algorithm now updates camera projection matrix even when using a custom matrix. --- gazebo/rendering/Camera.cc | 7 ++--- .../rendering/CustomPSSMShadowCameraSetup.cc | 29 +++++++++++++++++++ .../rendering/CustomPSSMShadowCameraSetup.hh | 7 ++++- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/gazebo/rendering/Camera.cc b/gazebo/rendering/Camera.cc index a97e425234..54a77dc3a3 100644 --- a/gazebo/rendering/Camera.cc +++ b/gazebo/rendering/Camera.cc @@ -813,11 +813,8 @@ void Camera::SetClipDist() if (this->camera) { - if (!this->cameraUsingIntrinsics) - { - this->camera->setNearClipDistance(clipElem->Get("near")); - this->camera->setFarClipDistance(clipElem->Get("far")); - } + this->camera->setNearClipDistance(clipElem->Get("near")); + this->camera->setFarClipDistance(clipElem->Get("far")); this->camera->setRenderingDistance(clipElem->Get("far")); } else diff --git a/gazebo/rendering/CustomPSSMShadowCameraSetup.cc b/gazebo/rendering/CustomPSSMShadowCameraSetup.cc index d196c4e94f..7e39a93a70 100644 --- a/gazebo/rendering/CustomPSSMShadowCameraSetup.cc +++ b/gazebo/rendering/CustomPSSMShadowCameraSetup.cc @@ -464,6 +464,16 @@ void CustomPSSMShadowCameraSetup::calculateShadowMappingMatrix( } } +////////////////////////////////////////////////// +Ogre::Matrix4 CustomPSSMShadowCameraSetup::buildSimplePerspectiveMatrix( + const Ogre::Real _near, const Ogre::Real _far) const +{ + return Ogre::Matrix4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -(_far + _near) / (_far - _near), -2 * _far * _near / (_far - _near), + 0, 0, -1, 0); +} + ////////////////////////////////////////////////// Ogre::Matrix4 CustomPSSMShadowCameraSetup::buildViewMatrix( const Ogre::Vector3 &_pos, const Ogre::Vector3 &_dir, @@ -611,8 +621,23 @@ void CustomPSSMShadowCameraSetup::getShadowCamera(const Ogre::SceneManager *_sm, Ogre::Camera *cam = const_cast(_cam); Ogre::Real oldNear = _cam->getNearClipDistance(); Ogre::Real oldFar = _cam->getFarClipDistance(); + Ogre::Matrix4 oldCustomProjMat = _cam->getProjectionMatrix(); cam->setNearClipDistance(nearDist); cam->setFarClipDistance(farDist); + if (cam->isCustomProjectionMatrixEnabled()) + { + // setNearClipDistance() and setFarClipDistance() will cause a regular + // camera projection matrix to be rebuilt, but they do nothing if the camera + // is using a custom matrix. Ideally, we would build the necessary matrix + // from scratch here, but we do not have access to the required camera + // intrinsics. We work around this problem by modifying the existing matrix, + // resulting in a new custom matrix with altered near and far clip planes + // that is almost identical to one built from scratch (typically some + // elements differ in the forth or fifth digit). + Ogre::Matrix4 oldNearFarMat = buildSimplePerspectiveMatrix(oldNear, oldFar); + Ogre::Matrix4 newNearFarMat = buildSimplePerspectiveMatrix(nearDist, farDist); + cam->setCustomProjectionMatrix(true, oldCustomProjMat * oldNearFarMat.inverse() * newNearFarMat); + } // Replaced LiSPSMShadowCameraSetup::getShadowCamera() with // FocusedShadowCameraSetup::getShadowCamera(). This is the same solution @@ -624,6 +649,10 @@ void CustomPSSMShadowCameraSetup::getShadowCamera(const Ogre::SceneManager *_sm, // restore near/far cam->setNearClipDistance(oldNear); cam->setFarClipDistance(oldFar); + if (cam->isCustomProjectionMatrixEnabled()) + { + cam->setCustomProjectionMatrix(true, oldCustomProjMat); + } } ////////////////////////////////////////////////// diff --git a/gazebo/rendering/CustomPSSMShadowCameraSetup.hh b/gazebo/rendering/CustomPSSMShadowCameraSetup.hh index a82e7d40c1..3a2d50794a 100644 --- a/gazebo/rendering/CustomPSSMShadowCameraSetup.hh +++ b/gazebo/rendering/CustomPSSMShadowCameraSetup.hh @@ -97,11 +97,16 @@ namespace gazebo /// \brief lightly modified /// FocusedShadowCameraSetup::calculateShadowMappingMatrix(). - void calculateShadowMappingMatrix(const Ogre::SceneManager &_sm, + public: void calculateShadowMappingMatrix(const Ogre::SceneManager &_sm, const Ogre::Camera &_cam, const Ogre::Light &_light, Ogre::Matrix4 *_out_view, Ogre::Matrix4 *_outProj, Ogre::Camera *_outCam) const; + /// \brief Build a simple perspective projection matrix using only near + /// and far clipping planes. + public: Ogre::Matrix4 buildSimplePerspectiveMatrix(const Ogre::Real _near, + const Ogre::Real _far) const; + /// \brief The same as FocusedShadowCameraSetup::buildViewMatrix() except /// resulting matrices are z-up instead of y-up. /// \sa FocusedShadowCameraSetup::buildViewMatrix() From 321b12a217b50ef788b9a7309cf221187f116194 Mon Sep 17 00:00:00 2001 From: Terry Welsh Date: Fri, 19 Aug 2022 09:20:37 -0700 Subject: [PATCH 2/2] Made buildSimplePerspectiveMatrix a static free function. --- gazebo/rendering/CustomPSSMShadowCameraSetup.cc | 9 ++++++--- gazebo/rendering/CustomPSSMShadowCameraSetup.hh | 5 ----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/gazebo/rendering/CustomPSSMShadowCameraSetup.cc b/gazebo/rendering/CustomPSSMShadowCameraSetup.cc index 7e39a93a70..c4570197aa 100644 --- a/gazebo/rendering/CustomPSSMShadowCameraSetup.cc +++ b/gazebo/rendering/CustomPSSMShadowCameraSetup.cc @@ -465,8 +465,10 @@ void CustomPSSMShadowCameraSetup::calculateShadowMappingMatrix( } ////////////////////////////////////////////////// -Ogre::Matrix4 CustomPSSMShadowCameraSetup::buildSimplePerspectiveMatrix( - const Ogre::Real _near, const Ogre::Real _far) const +// Build a simple perspective projection matrix using only near and far clipping +// planes. +static Ogre::Matrix4 buildSimplePerspectiveMatrix( + const Ogre::Real _near, const Ogre::Real _far) { return Ogre::Matrix4(1, 0, 0, 0, 0, 1, 0, 0, @@ -636,7 +638,8 @@ void CustomPSSMShadowCameraSetup::getShadowCamera(const Ogre::SceneManager *_sm, // elements differ in the forth or fifth digit). Ogre::Matrix4 oldNearFarMat = buildSimplePerspectiveMatrix(oldNear, oldFar); Ogre::Matrix4 newNearFarMat = buildSimplePerspectiveMatrix(nearDist, farDist); - cam->setCustomProjectionMatrix(true, oldCustomProjMat * oldNearFarMat.inverse() * newNearFarMat); + cam->setCustomProjectionMatrix(true, oldCustomProjMat * + oldNearFarMat.inverse() * newNearFarMat); } // Replaced LiSPSMShadowCameraSetup::getShadowCamera() with diff --git a/gazebo/rendering/CustomPSSMShadowCameraSetup.hh b/gazebo/rendering/CustomPSSMShadowCameraSetup.hh index 3a2d50794a..24faabba7f 100644 --- a/gazebo/rendering/CustomPSSMShadowCameraSetup.hh +++ b/gazebo/rendering/CustomPSSMShadowCameraSetup.hh @@ -102,11 +102,6 @@ namespace gazebo Ogre::Matrix4 *_out_view, Ogre::Matrix4 *_outProj, Ogre::Camera *_outCam) const; - /// \brief Build a simple perspective projection matrix using only near - /// and far clipping planes. - public: Ogre::Matrix4 buildSimplePerspectiveMatrix(const Ogre::Real _near, - const Ogre::Real _far) const; - /// \brief The same as FocusedShadowCameraSetup::buildViewMatrix() except /// resulting matrices are z-up instead of y-up. /// \sa FocusedShadowCameraSetup::buildViewMatrix()