From 8dbeba57cdf28f5f3f385f19d4759a65fe0f1b80 Mon Sep 17 00:00:00 2001 From: cutealien Date: Thu, 16 Jun 2022 13:59:58 +0000 Subject: [PATCH] Fix camera render when it wasn't animated. Tiny improvement for fps camera animator. Add documentation. Cameras can render even when they are not in the scenemanager or onAnimate didn't get called for example because they are their parent are invisible. So let's be safe and add another call to updateAbsolutePosition(). Some cost, but usually we don't have that many rendering cameras, so shouldn't matter (if it ever matters I suppose we could override OnAnimate and add a flag if it _was_ animated since last render call. Maybe that's even useful in general for SceneNodes?). Similar CSceneNodeAnimatorCameraFPS was using getAbsolutePosition which was only updated after animators, so it was one frame behind. And documented ICameraSceneNode functions a bit. Especially updateMatrices is a bit of a confusing name unfortunately. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6406 dfc29bdd-3216-0410-991c-e03cc46cb475 --- include/ICameraSceneNode.h | 17 ++++++++++++----- source/Irrlicht/CCameraSceneNode.cpp | 1 + source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/ICameraSceneNode.h b/include/ICameraSceneNode.h index feb3cef..101c756 100644 --- a/include/ICameraSceneNode.h +++ b/include/ICameraSceneNode.h @@ -121,19 +121,23 @@ namespace scene virtual f32 getFOV() const =0; //! Sets the value of the near clipping plane. (default: 1.0f) - /** \param zn: New z near value. */ + /** Also changes projection matrix and resets IsOrthogonal flag. + \param zn: New z near value. */ virtual void setNearValue(f32 zn) =0; //! Sets the value of the far clipping plane (default: 2000.0f) - /** \param zf: New z far value. */ + /** Also changes projection matrix and resets IsOrthogonal flag. + \param zf: New z far value. */ virtual void setFarValue(f32 zf) =0; //! Sets the aspect ratio (default: 4.0f / 3.0f) - /** \param aspect: New aspect ratio. */ + /** Also changes projection matrix and resets IsOrthogonal flag. + \param aspect: New aspect ratio. */ virtual void setAspectRatio(f32 aspect) =0; //! Sets the field of view (Default: PI / 2.5f) - /** \param fovy: New field of view in radians. */ + /** Also changes projection matrix and resets IsOrthogonal flag. + \param fovy: New field of view in radians. */ virtual void setFOV(f32 fovy) =0; //! Get the view frustum. @@ -165,7 +169,10 @@ namespace scene @see getTargetAndRotationBinding() */ virtual void bindTargetAndRotation(bool bound) =0; - //! Updates the matrices without uploading them to the driver + //! Updates the view matrix and frustum without uploading the matrix to the driver. + /** You need this when you want an up-to-date camera view matrix & frustum before the render() call. + Usually you should call updateAbsolutePosition() before calling this. + Despite it's function name, the projection matrix is not touched. */ virtual void updateMatrices() = 0; //! Queries if the camera scene node's rotation and its target position are bound together. diff --git a/source/Irrlicht/CCameraSceneNode.cpp b/source/Irrlicht/CCameraSceneNode.cpp index 600a1c5..3c97ee5 100644 --- a/source/Irrlicht/CCameraSceneNode.cpp +++ b/source/Irrlicht/CCameraSceneNode.cpp @@ -252,6 +252,7 @@ void CCameraSceneNode::OnRegisterSceneNode() //! render void CCameraSceneNode::render() { + updateAbsolutePosition(); // depending on that call in onAnimate is risky (might not be in SceneManager or it or it's parent might be invisible and still should render) updateMatrices(); video::IVideoDriver* driver = SceneManager->getVideoDriver(); diff --git a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp index ce18bfd..8d9d4af 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp @@ -110,7 +110,6 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) if (firstUpdate) { - camera->updateAbsolutePosition(); if (CursorControl ) { CursorControl->setPosition(0.5f, 0.5f); @@ -144,6 +143,7 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) LastAnimationTime = timeMs; // Update rotation + camera->updateAbsolutePosition(); core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition()); core::vector3df relativeRotation = target.getHorizontalAngle();