[Bf-blender-cvs] [f12b179] master: Fix 73841 : Game Engine - Camera Lens Shift

Dalai Felinto noreply at git.blender.org
Mon Jun 29 15:51:19 CEST 2015


Commit: f12b1790a0f4bb26d99ca151f8794a179e151987
Author: Dalai Felinto
Date:   Mon Jun 29 10:45:27 2015 -0300
Branches: master
https://developer.blender.org/rBf12b1790a0f4bb26d99ca151f8794a179e151987

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

===================================================================

M	source/gameengine/Converter/BL_BlenderDataConversion.cpp
M	source/gameengine/Ketsji/KX_Camera.cpp
M	source/gameengine/Ketsji/KX_Camera.h
M	source/gameengine/Ketsji/KX_KetsjiEngine.cpp
M	source/gameengine/Rasterizer/RAS_CameraData.h
M	source/gameengine/Rasterizer/RAS_FramingManager.cpp
M	source/gameengine/Rasterizer/RAS_FramingManager.h
M	source/gameengine/VideoTexture/ImageRender.cpp

===================================================================

diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 4899eaf..8ccfead 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 4456345..70bcf50 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 eeb836c..41d0172 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 be0cd84..9196371 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 7a6bb54..e2024a4 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 d1a801c..c5f15c9 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 122f0ca..5741a91 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 0850995..7973133 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);




More information about the Bf-blender-cvs mailing list