diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2015-06-29 16:45:27 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2015-06-29 16:45:27 +0300 |
commit | f12b1790a0f4bb26d99ca151f8794a179e151987 (patch) | |
tree | 39bb3cf3c85fbd8c91df5e867e38a477958004d9 /source | |
parent | 3d12d4b94f9bff6ea810179e22a5e3e018541f31 (diff) |
Fix 73841 : Game Engine - Camera Lens Shift
This is essential for video projection, and the alternative until now was to manually change the projection matrix via Python.
( http://www.blender.org/manual/game_engine/camera/introduction.html#camera-lens-shift
- this page will be removed as soon as I commit this)
Also this is working for perspective and orto cameras BUT if the sensor is not AUTO it will only look correct in blenderplayer (this is an unrelated bug, but just in case someone runs into it while testing this, now you know why you got the issue).
Kudos for the BlenderVR project for supporting this feature development.
Differential Revision: https://developer.blender.org/D1379
Diffstat (limited to 'source')
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Camera.cpp | 16 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Camera.h | 4 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 4 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_CameraData.h | 5 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_FramingManager.cpp | 52 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_FramingManager.h | 8 | ||||
-rw-r--r-- | source/gameengine/VideoTexture/ImageRender.cpp | 6 |
8 files changed, 83 insertions, 14 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 4899eafd84c..8ccfeadea7b 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1461,7 +1461,7 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { Camera* ca = static_cast<Camera*>(ob->data); - RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->sensor_x, ca->sensor_y, ca->sensor_fit, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist); + RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->sensor_x, ca->sensor_y, ca->sensor_fit, ca->shiftx, ca->shifty, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist); KX_Camera *gamecamera; gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 4456345e1d9..70bcf505f2e 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -224,6 +224,22 @@ short KX_Camera::GetSensorFit() const return m_camdata.m_sensor_fit; } +/** + * Gets the horizontal shift of the sensor - for camera matching. + */ +float KX_Camera::GetShiftHorizontal() const +{ + return m_camdata.m_shift_x; +} + +/** + * Gets the vertical shift of the sensor - for camera matching. + */ +float KX_Camera::GetShiftVertical() const +{ + return m_camdata.m_shift_y; +} + float KX_Camera::GetCameraNear() const { return m_camdata.m_clipstart; diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index eeb836c44b8..41d0172f2cd 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -206,6 +206,10 @@ public: float GetSensorHeight() const; /** Gets the mode FOV is calculating from sensor dimensions */ short GetSensorFit() const; + /** Gets the horizontal shift of the sensor - for camera matching */ + float GetShiftHorizontal() const; + /** Gets the vertical shift of the sensor - for camera matching */ + float GetShiftVertical() const; /** Gets the near clip distance. */ float GetCameraNear() const; /** Gets the far clip distance. */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index be0cd8433f7..91963713dad 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1159,6 +1159,8 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) nearfrust, farfrust, cam->GetSensorFit(), + cam->GetShiftHorizontal(), + cam->GetShiftVertical(), frustum ); if (!cam->GetViewport()) { @@ -1179,6 +1181,8 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) cam->GetSensorWidth(), cam->GetSensorHeight(), cam->GetSensorFit(), + cam->GetShiftHorizontal(), + cam->GetShiftVertical(), nearfrust, farfrust, frustum diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index 7a6bb541a1a..e2024a4a55d 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -39,6 +39,8 @@ struct RAS_CameraData float m_sensor_x; float m_sensor_y; short m_sensor_fit; + float m_shift_x; + float m_shift_y; float m_clipstart; float m_clipend; bool m_perspective; @@ -50,6 +52,7 @@ struct RAS_CameraData float m_focallength; RAS_CameraData(float lens = 35.0, float scale = 6.0, float sensor_x = 32.0, float sensor_y = 18.0, short sensor_fit = 0, + float shift_x = 0.0, float shift_y = 0.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true, float focallength = 3.0, bool viewport = false, int viewportleft = 0, int viewportbottom = 0, int viewportright = 0, int viewporttop = 0) : @@ -58,6 +61,8 @@ struct RAS_CameraData m_sensor_x(sensor_x), m_sensor_y(sensor_y), m_sensor_fit(sensor_fit), + m_shift_x(shift_x), + m_shift_y(shift_y), m_clipstart(clipstart), m_clipend(clipend), m_perspective(perspective), diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.cpp b/source/gameengine/Rasterizer/RAS_FramingManager.cpp index d1a801c52f8..c5f15c9ad21 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.cpp +++ b/source/gameengine/Rasterizer/RAS_FramingManager.cpp @@ -41,15 +41,21 @@ ComputeDefaultFrustum( const float lens, const float sensor_x, const float sensor_y, const short sensor_fit, + const float shift_x, + const float shift_y, const float design_aspect_ratio, RAS_FrameFrustum & frustum ) { + float size; float halfSize; float sizeX; float sizeY; + float offsetX; + float offsetY; if (sensor_fit==RAS_SENSORFIT_AUTO) { - halfSize = (sensor_x / 2.f) * camnear / lens; + size = sensor_x * camnear / lens; + halfSize = size * 0.5f; if (design_aspect_ratio > 1.f) { // halfsize defines the width @@ -62,20 +68,25 @@ ComputeDefaultFrustum( } } else if (sensor_fit==RAS_SENSORFIT_HOR) { - halfSize = (sensor_x / 2.f) * camnear / lens; + size = sensor_x * camnear / lens; + halfSize = size * 0.5f; sizeX = halfSize; sizeY = halfSize/design_aspect_ratio; } else { - halfSize = (sensor_y / 2.f) * camnear / lens; + size = sensor_y * camnear / lens; + halfSize = size * 0.5f; sizeX = halfSize * design_aspect_ratio; sizeY = halfSize; } - - frustum.x2 = sizeX; - frustum.x1 = -frustum.x2; - frustum.y2 = sizeY; - frustum.y1 = -frustum.y2; + + offsetX = size * shift_x; + offsetY = size * shift_y; + + frustum.x2 = sizeX + offsetX; + frustum.x1 = -sizeX + offsetX; + frustum.y2 = sizeY + offsetY; + frustum.y1 = -sizeY + offsetY; frustum.camnear = camnear; frustum.camfar = camfar; } @@ -88,12 +99,16 @@ ComputeDefaultOrtho( const float scale, const float design_aspect_ratio, const short sensor_fit, + const float shift_x, + const float shift_y, RAS_FrameFrustum & frustum ) { float halfSize = scale*0.5f; float sizeX; float sizeY; + float offsetX; + float offsetY; if (sensor_fit==RAS_SENSORFIT_AUTO) { if (design_aspect_ratio > 1.f) { @@ -114,11 +129,14 @@ ComputeDefaultOrtho( sizeX = halfSize * design_aspect_ratio; sizeY = halfSize; } - - frustum.x2 = sizeX; - frustum.x1 = -frustum.x2; - frustum.y2 = sizeY; - frustum.y1 = -frustum.y2; + + offsetX = scale * shift_x; + offsetY = scale * shift_y; + + frustum.x2 = sizeX + offsetX; + frustum.x1 = -sizeX + offsetX; + frustum.y2 = sizeY + offsetY; + frustum.y1 = -sizeY + offsetY; frustum.camnear = camnear; frustum.camfar = camfar; } @@ -221,6 +239,8 @@ ComputeFrustum( const RAS_Rect &viewport, const float lens, const float sensor_x, const float sensor_y, const short sensor_fit, + const float shift_x, + const float shift_y, const float camnear, const float camfar, RAS_FrameFrustum &frustum @@ -249,6 +269,8 @@ ComputeFrustum( sensor_x, sensor_y, sensor_fit, + shift_x, + shift_y, design_aspect_ratio, frustum ); @@ -315,6 +337,8 @@ RAS_FramingManager:: const float camnear, const float camfar, const short sensor_fit, + const float shift_x, + const float shift_y, RAS_FrameFrustum &frustum ) { @@ -340,6 +364,8 @@ RAS_FramingManager:: scale, design_aspect_ratio, sensor_fit, + shift_x, + shift_y, frustum ); diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h index 122f0ca46ec..5741a91939e 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.h +++ b/source/gameengine/Rasterizer/RAS_FramingManager.h @@ -236,6 +236,8 @@ public : const float camnear, const float camfar, const short sensor_fit, + const float shift_x, + const float shift_y, RAS_FrameFrustum &frustum ); @@ -247,6 +249,8 @@ public : const RAS_Rect &viewport, const float lens, const float sensor_x, const float sensor_y, const short sensor_fit, + const float shift_x, + const float shift_y, const float camnear, const float camfar, RAS_FrameFrustum &frustum @@ -260,6 +264,8 @@ public : const float lens, const float sensor_x, const float sensor_y, const short sensor_fit, + const float shift_x, + const float shift_y, const float design_aspect_ratio, RAS_FrameFrustum & frustum ); @@ -272,6 +278,8 @@ public : const float scale, const float design_aspect_ratio, const short sensor_fit, + const float shift_x, + const float shift_y, RAS_FrameFrustum & frustum ); diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 0850995eaaf..797313366cd 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -240,6 +240,8 @@ void ImageRender::Render() float lens = m_camera->GetLens(); float sensor_x = m_camera->GetSensorWidth(); float sensor_y = m_camera->GetSensorHeight(); + float shift_x = m_camera->GetShiftHorizontal(); + float shift_y = m_camera->GetShiftVertical(); bool orthographic = !m_camera->GetCameraData()->m_perspective; float nearfrust = m_camera->GetCameraNear(); float farfrust = m_camera->GetCameraFar(); @@ -260,6 +262,8 @@ void ImageRender::Render() m_camera->GetScale(), aspect_ratio, m_camera->GetSensorFit(), + shift_x, + shift_y, frustrum ); @@ -274,6 +278,8 @@ void ImageRender::Render() sensor_x, sensor_y, RAS_SENSORFIT_AUTO, + shift_x, + shift_y, aspect_ratio, frustrum); |