[Bf-blender-cvs] [dd7469d] multiview: Support for Basica camera rendering

Dalai Felinto noreply at git.blender.org
Sat May 24 00:39:52 CEST 2014


Commit: dd7469df12c46a7b50808d7f840752a994e78e43
Author: Dalai Felinto
Date:   Fri May 23 15:53:50 2014 -0300
https://developer.blender.org/rBdd7469df12c46a7b50808d7f840752a994e78e43

Support for Basica camera rendering

Note: as of now this is creating multiple camera datablocks (and
unlinked objects) in the scene. I tried freeing them in the
render_free_stereo() routine, but it only set usercount to zero (so they
are still visible) and I get a crash when I leave Blender.

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

M	source/blender/blenkernel/BKE_camera.h
M	source/blender/blenkernel/intern/camera.c
M	source/blender/render/extern/include/RE_pipeline.h
M	source/blender/render/intern/include/render_types.h
M	source/blender/render/intern/source/initrender.c
M	source/blender/render/intern/source/pipeline.c
M	source/blender/render/intern/source/render_result.c

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

diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index e50e341..50a7aee 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -122,6 +122,7 @@ bool BKE_camera_view_frame_fit_to_scene(struct Scene *scene, struct View3D *v3d,
                                         float r_co[3]);
 
 struct Object *BKE_camera_multiview_advanced(struct Scene *scene, struct RenderData *rd, struct Object *camera, const char *suffix);
+void BKE_camera_multiview_basic(struct Object *camera, const bool left);
 void BKE_camera_stereo_matrices(struct Object *camera, float r_viewmat[4][4], float *r_shift, const bool left);
 
 #ifdef __cplusplus
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 2768a80..2e00039 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -601,6 +601,56 @@ bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object
 	}
 }
 
+/* transforms the camera matrix to the correct stereo eye to be rendered */
+void BKE_camera_multiview_basic(Object *camera, const bool left)
+{
+	Camera *data = (Camera *)camera->data;
+	float *r_shift = &data->shiftx;
+	float interocular_distance, convergence_distance, angle;
+	short convergence_mode;
+	float tmpmat[4][4];
+
+	float distance;
+	float rotmat[3][3] = MAT3_UNITY;
+
+	interocular_distance = data->stereo.interocular_distance;
+	convergence_distance = data->stereo.convergence_distance;
+	convergence_mode = data->stereo.convergence_mode;
+
+	/* rotation */
+	if (convergence_mode == CAM_S3D_TOE) {
+		angle = -atan((interocular_distance * 0.5f) / convergence_distance);
+
+		if (left)
+			angle = -angle;
+
+		rotmat[0][0] = cos(angle);
+		rotmat[2][0] = -sin(angle);
+		rotmat[0][2] = sin(angle);
+		rotmat[2][2] = cos(angle);
+	}
+
+	copy_m4_m4(tmpmat, camera->obmat);
+	mul_m4_m4m3(camera->obmat, tmpmat, rotmat);
+
+	/* translation */
+	if (left)
+		distance = -interocular_distance * 0.5f;
+	else
+		distance =  interocular_distance * 0.5f;
+
+	translate_m4(camera->obmat, distance, 0.0f, 0.0f);
+
+	/* prepare the camera shift for the projection matrix */
+	/* Note: in viewport, parallel renders as offaxis, but in render it does parallel */
+	if (convergence_mode == CAM_S3D_OFFAXIS) {
+		if (left)
+			*r_shift += ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * 0.5f;
+		else
+			*r_shift -= ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * 0.5f;
+	}
+}
+
 void BKE_camera_stereo_matrices(Object *camera, float r_viewmat[4][4], float *r_shift, const bool left)
 {
 	/* viewmat = MODELVIEW_MATRIX */
@@ -608,12 +658,7 @@ void BKE_camera_stereo_matrices(Object *camera, float r_viewmat[4][4], float *r_
 	float interocular_distance, convergence_distance, angle;
 	short convergence_mode;
 	float tmpviewmat[4][4];
-
-	float transmat[4][4] = {
-	      {1,0,0,0},
-	      {0,1,0,0},
-	      {0,0,1,0},
-	      {0,0,0,1} };
+	float transmat[4][4] = MAT4_UNITY;
 
 	interocular_distance = data->stereo.interocular_distance;
 	convergence_distance = data->stereo.convergence_distance;
@@ -621,9 +666,9 @@ void BKE_camera_stereo_matrices(Object *camera, float r_viewmat[4][4], float *r_
 
 	invert_m4_m4(tmpviewmat, camera->obmat);
 
-	/* rotate */
+	/* rotation */
 	if (convergence_mode == CAM_S3D_TOE) {
-		angle = atan((interocular_distance * 0.5) / convergence_distance);
+		angle = atan((interocular_distance * 0.5f) / convergence_distance);
 
 		if (left)
 			angle = -angle;
@@ -634,27 +679,24 @@ void BKE_camera_stereo_matrices(Object *camera, float r_viewmat[4][4], float *r_
 		transmat[2][2] = cos(angle);
 	}
 
-	/* move */
+	/* translation */
 	if (left) {
-		transmat[3][0] = interocular_distance * 0.5 ;
+		transmat[3][0] = interocular_distance * 0.5f;
 	}
 	else {
-		transmat[3][0] = interocular_distance * -0.5 ;
+		transmat[3][0] = interocular_distance * -0.5f;
 	}
 	
 	/* apply */
-	mul_m4_m4m4( tmpviewmat, transmat, tmpviewmat) ;
-
-	/* copy  */
-	copy_m4_m4(r_viewmat, tmpviewmat);
+	mul_m4_m4m4(r_viewmat, transmat, tmpviewmat);
 
 	/* prepare the camera shift for the projection matrix */
 	/* Note: in viewport, parallel renders as offaxis, but in render it does parallel */
 	if (ELEM(convergence_mode, CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL)) {
 		if (left)
-			*r_shift += ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * 0.5;
+			*r_shift += ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * 0.5f;
 		else
-			*r_shift -= ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * 0.5;
+			*r_shift -= ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * 0.5f;
 	}
 }
 
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 9982c33..92b1b00 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -230,6 +230,7 @@ bool RE_RenderResult_is_stereo(RenderResult *res);
 void RE_InitState(struct Render *re, struct Render *source, struct RenderData *rd, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect);
 
 /* set up the viewplane/perspective matrix, three choices */
+struct Object *RE_GetCameraStereo(struct Render *re, const bool left);
 struct Object *RE_GetViewCamera(struct Render *re);
 struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */
 void RE_SetCamera(struct Render *re, struct Object *camera);
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 9eace28..8aaa654 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -192,6 +192,8 @@ struct Render
 	RenderData r;
 	World wrld;
 	struct Object *camera_override;
+	struct Object *camera_left; /* ghost camera, made for render in stereo */
+	struct Object *camera_right; /* ghost camera, made for render in stereo */
 	unsigned int lay;
 	
 	ListBase parts;
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 9bc3ccf..16d8815 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -433,6 +433,12 @@ void make_sample_tables(Render *re)
 
 
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+struct Object *RE_GetCameraStereo(Render *re, const bool left)
+{
+	Object *ob_cam = left ? re->camera_left : re->camera_right;
+	return ob_cam ? ob_cam : RE_GetCamera(re);
+}
+
 struct Object *RE_GetViewCamera(Render *re)
 {
 	RenderView *rv;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 645c3b2..bd344ff 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -69,6 +69,7 @@
 #include "BKE_scene.h"
 #include "BKE_sequencer.h"
 #include "BKE_writeavi.h"  /* <------ should be replaced once with generic movie module */
+#include "BKE_object.h"
 
 #include "PIL_time.h"
 #include "IMB_colormanagement.h"
@@ -133,6 +134,8 @@ Render R;
 
 static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override, const char *view);
 
+static void render_free_stereo(Render *re);
+
 static volatile int g_break = 0;
 static int thread_break(void *UNUSED(arg))
 {
@@ -2810,6 +2813,40 @@ static void update_physics_cache(Render *re, Scene *scene, int UNUSED(anim_init)
 
 	BKE_ptcache_bake(&baker);
 }
+
+/* setup stereo basic cameras when needed */
+static void render_initialize_stereo(Render *re, RenderData *rd)
+{
+	/* investigate why do I need to click twice in the button */
+	if ((rd->scemode & R_MULTIVIEW) &&
+	     rd->views_setup == SCE_VIEWS_SETUP_BASIC) {
+		Object *camera = RE_GetCamera(re);
+
+		re->camera_left = BKE_object_copy(camera);
+		re->camera_left->data =  BKE_camera_copy(camera->data);
+		BKE_camera_multiview_basic(re->camera_left, true);
+
+		re->camera_right = BKE_object_copy(camera);
+		re->camera_right->data =  BKE_camera_copy(camera->data);
+		BKE_camera_multiview_basic(re->camera_right, false);
+	}
+}
+
+static void render_free_stereo(Render *re)
+{
+	//XXX MV I need a cleaner way to free the objects
+	return;
+	if (re->camera_left) {
+		BKE_camera_free(re->camera_left->data);
+		BKE_object_free(re->camera_left);
+	}
+
+	if (re->camera_right) {
+		BKE_camera_free(re->camera_right->data);
+		BKE_object_free(re->camera_right);
+	}
+}
+
 /* evaluating scene options for general Blender render */
 static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, Scene *scene, SceneRenderLayer *srl,
                                        Object *camera_override, unsigned int lay_override, int anim, int anim_init)
@@ -2842,9 +2879,14 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain,
 	re->scene = scene;
 	re->scene_color_manage = BKE_scene_check_color_management_enabled(scene);
 	re->camera_override = camera_override;
+	re->camera_left = NULL;
+	re->camera_right = NULL;
 	re->lay = lay_override ? lay_override : scene->lay;
 	re->i.localview = (re->lay & 0xFF000000) != 0;
-	
+
+	/* init left and right cameras */
+	render_initialize_stereo(re, rd);
+
 	/* not too nice, but it survives anim-border render */
 	if (anim) {
 		render_update_anim_renderdata(re, &scene->r);
@@ -2872,8 +2914,10 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain,
 	}
 	
 	RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect);
-	if (!re->ok)  /* if an error was printed, abort */
+	if (!re->ok)  /* if an error was printed, abort */ {
+		render_free_stereo(re);
 		return 0;
+	}
 	
 	/* initstate makes new result, have to send changed tags around */
 	ntreeCompositTagRender(re->scene);
@@ -2950,6 +2994,8 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
 
 	BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_R

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list