From a2de3303d3852de11b1a5251913aa8f6cbbcdb50 Mon Sep 17 00:00:00 2001 From: tristan Date: Sat, 22 Dec 2018 12:41:33 +0100 Subject: [PATCH] UPBGE: Genralize override camera projection matrix. Previously due to an issue with orthographic projection, the override camera was always using a projection matrix not computed in the normal way. This introduced branches to detect if the camera was the override camera. But the issue was able to be fixed and let RAS_FramingManager compute camera settings for every camera. To fix the orthographic camera projection issue, LA_BlenderLauncher::InitCamera is now constructing a more complete RAS_CameraData based on the settings created by the function BKE_camera_params_from_view3d, these values are just copied and enought to solve the issue. In the same time we don't need the camera view matrix to get it's position and orientation in KX_KetsjiEngine::PostProcessScene. Only the position and orientation are now passed to KX_KetsjiEngine::EnableCameraOverride and stored which avoid extra computation from the view matrix (inversing) to get these two values. --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 127 ++++++++---------- source/gameengine/Ketsji/KX_KetsjiEngine.h | 7 +- .../Launcher/LA_BlenderLauncher.cpp | 20 +-- 3 files changed, 72 insertions(+), 82 deletions(-) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index f9fd140401e5..8a3a01aded46 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -742,13 +742,14 @@ const KX_ExitInfo& KX_KetsjiEngine::GetExitInfo() const return m_exitInfo; } -void KX_KetsjiEngine::EnableCameraOverride(const std::string& forscene, const mt::mat4& projmat, - const mt::mat4& viewmat, const RAS_CameraData& camdata) +void KX_KetsjiEngine::EnableCameraOverride(const std::string& forscene, const mt::mat3& orientation, + const mt::vec3& position, const RAS_CameraData& camdata) { SetFlag(CAMERA_OVERRIDE, true); + m_overrideSceneName = forscene; - m_overrideCamProjMat = projmat; - m_overrideCamViewMat = viewmat; + m_overrideCamOrientation = orientation; + m_overrideCamPosition = position; m_overrideCamData = camdata; } @@ -859,73 +860,60 @@ mt::mat4 KX_KetsjiEngine::GetCameraProjectionMatrix(KX_Scene *scene, KX_Camera * return cam->GetProjectionMatrix(); } - const bool override_camera = ((m_flags & CAMERA_OVERRIDE) != 0) && (scene->GetName() == m_overrideSceneName) && - (cam->GetName() == "__default__cam__"); + RAS_FrameFrustum frustum{}; + const bool orthographic = !cam->GetCameraData()->m_perspective; + const float nearfrust = cam->GetCameraNear(); + const float farfrust = cam->GetCameraFar(); + const float focallength = cam->GetFocalLength(); + const float camzoom = cam->GetZoom(); + + if (orthographic) { + RAS_FramingManager::ComputeOrtho( + scene->GetFramingType(), + area, + viewport, + cam->GetScale(), + nearfrust, + farfrust, + cam->GetSensorFit(), + cam->GetShiftHorizontal(), + cam->GetShiftVertical(), + frustum); + + if (!cam->GetViewport()) { + frustum.x1 *= camzoom; + frustum.x2 *= camzoom; + frustum.y1 *= camzoom; + frustum.y2 *= camzoom; + } + return m_rasterizer->GetOrthoMatrix( + frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar); - mt::mat4 projmat; - if (override_camera && !m_overrideCamData.m_perspective) { - // needed to get frustum planes for culling - projmat = m_overrideCamProjMat; } else { - RAS_FrameFrustum frustum{}; - const bool orthographic = !cam->GetCameraData()->m_perspective; - const float nearfrust = cam->GetCameraNear(); - const float farfrust = cam->GetCameraFar(); - const float focallength = cam->GetFocalLength(); - - const float camzoom = cam->GetZoom(); - if (orthographic) { - - RAS_FramingManager::ComputeOrtho( - scene->GetFramingType(), - area, - viewport, - cam->GetScale(), - nearfrust, - farfrust, - cam->GetSensorFit(), - cam->GetShiftHorizontal(), - cam->GetShiftVertical(), - frustum); - - if (!cam->GetViewport()) { - frustum.x1 *= camzoom; - frustum.x2 *= camzoom; - frustum.y1 *= camzoom; - frustum.y2 *= camzoom; - } - projmat = m_rasterizer->GetOrthoMatrix( - frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar); - - } - else { - RAS_FramingManager::ComputeFrustum( - scene->GetFramingType(), - area, - viewport, - cam->GetLens(), - cam->GetSensorWidth(), - cam->GetSensorHeight(), - cam->GetSensorFit(), - cam->GetShiftHorizontal(), - cam->GetShiftVertical(), - nearfrust, - farfrust, - frustum); - - if (!cam->GetViewport()) { - frustum.x1 *= camzoom; - frustum.x2 *= camzoom; - frustum.y1 *= camzoom; - frustum.y2 *= camzoom; - } - projmat = m_rasterizer->GetFrustumMatrix(stereoMode, eye, focallength, - frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar); + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + area, + viewport, + cam->GetLens(), + cam->GetSensorWidth(), + cam->GetSensorHeight(), + cam->GetSensorFit(), + cam->GetShiftHorizontal(), + cam->GetShiftVertical(), + nearfrust, + farfrust, + frustum); + + if (!cam->GetViewport()) { + frustum.x1 *= camzoom; + frustum.x2 *= camzoom; + frustum.y1 *= camzoom; + frustum.y2 *= camzoom; } + return m_rasterizer->GetFrustumMatrix(stereoMode, eye, focallength, + frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar); } - - return projmat; } // update graphics @@ -1074,11 +1062,8 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene *scene) // set transformation if (override_camera) { - const mt::mat3x4 trans = mt::mat3x4::ToAffineTransform(m_overrideCamViewMat); - const mt::mat3x4 camtrans = trans.Inverse(); - - activecam->NodeSetLocalPosition(camtrans.TranslationVector3D()); - activecam->NodeSetLocalOrientation(camtrans.RotationMatrix()); + activecam->NodeSetLocalPosition(m_overrideCamPosition); + activecam->NodeSetLocalOrientation(m_overrideCamOrientation); } else { activecam->NodeSetLocalPosition(mt::zero3); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 09886e2a159e..3aa2ea69aaf7 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -215,8 +215,8 @@ class KX_KetsjiEngine : public mt::SimdClassAllocator std::string m_overrideSceneName; RAS_CameraData m_overrideCamData; - mt::mat4 m_overrideCamProjMat; - mt::mat4 m_overrideCamViewMat; + mt::mat3 m_overrideCamOrientation; + mt::vec3 m_overrideCamPosition; /// Categories for profiling display. typedef enum { @@ -381,7 +381,8 @@ class KX_KetsjiEngine : public mt::SimdClassAllocator void GetSceneViewport(KX_Scene *scene, KX_Camera *cam, const RAS_Rect& displayArea, RAS_Rect& area, RAS_Rect& viewport); - void EnableCameraOverride(const std::string& forscene, const mt::mat4& projmat, const mt::mat4& viewmat, const RAS_CameraData& camdata); + void EnableCameraOverride(const std::string& forscene, const mt::mat3& orientation, + const mt::vec3& position, const RAS_CameraData& camdata); // Update animations for object in this scene void UpdateAnimations(KX_Scene *scene); diff --git a/source/gameengine/Launcher/LA_BlenderLauncher.cpp b/source/gameengine/Launcher/LA_BlenderLauncher.cpp index e713a95759ec..6b52d733417c 100644 --- a/source/gameengine/Launcher/LA_BlenderLauncher.cpp +++ b/source/gameengine/Launcher/LA_BlenderLauncher.cpp @@ -32,6 +32,7 @@ extern "C" { # include "BKE_context.h" +# include "BKE_camera.h" // avoid c++ conflict with 'new' # define new _new @@ -112,14 +113,17 @@ void LA_BlenderLauncher::InitCamera() } if (rv3d->persp != RV3D_CAMOB) { - RAS_CameraData camdata = RAS_CameraData(); - camdata.m_lens = m_view3d->lens; - camdata.m_clipstart = m_view3d->near; - camdata.m_clipend = m_view3d->far; - camdata.m_perspective = (rv3d->persp != RV3D_ORTHO); - camdata.m_zoom = 2.0f; - - m_ketsjiEngine->EnableCameraOverride(m_startSceneName, mt::mat4(rv3d->winmat), mt::mat4(rv3d->viewmat), camdata); + CameraParams params; + BKE_camera_params_init(¶ms); + BKE_camera_params_from_view3d(¶ms, m_view3d, rv3d); + + RAS_CameraData camdata = RAS_CameraData(params.lens, params.ortho_scale, params.sensor_x, params.sensor_y, + params.sensor_fit, params.shiftx, params.shifty, params.clipsta, params.clipend, !params.is_ortho, + 3.0f, params.zoom); + + const mt::mat4 viewinv(rv3d->viewinv); + + m_ketsjiEngine->EnableCameraOverride(m_startSceneName, viewinv.RotationMatrix(), viewinv.TranslationVector3D(), camdata); } }