[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