[Bf-blender-cvs] [a79a8fa] asset-experiments: Full WIP work to get better control regarding 'camera' aspect of objects.

Bastien Montagne noreply at git.blender.org
Wed Dec 17 21:57:56 CET 2014


Commit: a79a8fa111cf7486356c9fdec4852edf85c2be19
Author: Bastien Montagne
Date:   Wed Dec 17 21:54:11 2014 +0100
Branches: asset-experiments
https://developer.blender.org/rBa79a8fa111cf7486356c9fdec4852edf85c2be19

Full WIP work to get better control regarding 'camera' aspect of objects.

First expose a method in Object RNA to get camera projection matrix (done).

Then, expose a method to get camera position (and scale for ortho) so that
it fits a given set of coordinates (still unfinished).

this among other things implied rewriting `BKE_camera_view_frame_fit_to_scene()`
underlying logic so that it uses `CameraParams` system, instead of `BKE_camera_view_frame()` one.

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

M	source/blender/blenkernel/BKE_camera.h
M	source/blender/blenkernel/intern/camera.c
M	source/blender/editors/space_view3d/view3d_view.c
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/makesrna/intern/rna_object_api.c

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

diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 01b401c..045486d 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -118,7 +118,7 @@ void BKE_camera_view_frame_ex(struct Scene *scene, struct Camera *camera, float
 void BKE_camera_view_frame(struct Scene *scene, struct Camera *camera, float r_vec[4][3]);
 
 bool BKE_camera_view_frame_fit_to_scene(struct Scene *scene, struct View3D *v3d, struct Object *camera_ob,
-                                        float r_co[3]);
+                                        float r_co[3], float *r_scale);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 1402f62..d3b8081 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -330,6 +330,8 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win
 	dx = params->shiftx * viewfac + winx * params->offsetx;
 	dy = params->shifty * viewfac + winy * params->offsety;
 
+	//~ printf("dx: %f, dy: %f\n", dx, dy);
+
 	viewplane.xmin += dx;
 	viewplane.ymin += dy;
 	viewplane.xmax += dx;
@@ -458,12 +460,12 @@ void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
 	                         dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
 }
 
+#define CAMERA_VIEWFRAME_NUM_PLANES 4
 
 typedef struct CameraViewFrameData {
-	float plane_tx[4][4];  /* 4 planes (not 4x4 matrix)*/
-	float frame_tx[4][3];
-	float normal_tx[4][3];
-	float dist_vals_sq[4];  /* distance squared (signed) */
+	float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4];  /* 6 planes */
+	float normal_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
+	float dist_vals_sq[CAMERA_VIEWFRAME_NUM_PLANES];  /* distance squared (signed) */
 	unsigned int tot;
 } CameraViewFrameData;
 
@@ -472,7 +474,7 @@ static void camera_to_frame_view_cb(const float co[3], void *user_data)
 	CameraViewFrameData *data = (CameraViewFrameData *)user_data;
 	unsigned int i;
 
-	for (i = 0; i < 4; i++) {
+	for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
 		float nd = dist_signed_squared_to_plane_v3(co, data->plane_tx[i]);
 		if (nd < data->dist_vals_sq[i]) {
 			data->dist_vals_sq[i] = nd;
@@ -483,56 +485,134 @@ static void camera_to_frame_view_cb(const float co[3], void *user_data)
 }
 
 /* don't move the camera, just yield the fit location */
-/* only valid for perspective cameras */
-bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3])
+/* r_scale only valid/useful for ortho cameras */
+bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3], float *r_scale)
 {
-	float shift[2];
-	float plane_tx[4][3];
+	CameraParams params;
+	float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
 	float rot_obmat[3][3];
-	const float zero[3] = {0, 0, 0};
+	float rot_obmat_transposed_inversed[4][4];
 	CameraViewFrameData data_cb;
 
 	unsigned int i;
 
-	BKE_camera_view_frame(scene, camera_ob->data, data_cb.frame_tx);
+	/* just in case */
+	*r_scale = 1.0f;
 
-	copy_m3_m4(rot_obmat, camera_ob->obmat);
-	normalize_m3(rot_obmat);
+	/* setup parameters */
+	BKE_camera_params_init(&params);
+	BKE_camera_params_from_object(&params, camera_ob);
 
-	for (i = 0; i < 4; i++) {
-		/* normalize so Z is always 1.0f*/
-		mul_v3_fl(data_cb.frame_tx[i], 1.0f / data_cb.frame_tx[i][2]);
+	/* compute matrix, viewplane, .. */
+	if (scene) {
+		BKE_camera_params_compute_viewplane(&params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
 	}
-
-	/* get the shift back out of the frame */
-	shift[0] = (data_cb.frame_tx[0][0] +
-	            data_cb.frame_tx[1][0] +
-	            data_cb.frame_tx[2][0] +
-	            data_cb.frame_tx[3][0]) / 4.0f;
-	shift[1] = (data_cb.frame_tx[0][1] +
-	            data_cb.frame_tx[1][1] +
-	            data_cb.frame_tx[2][1] +
-	            data_cb.frame_tx[3][1]) / 4.0f;
-
-	for (i = 0; i < 4; i++) {
-		mul_m3_v3(rot_obmat, data_cb.frame_tx[i]);
+	else {
+		BKE_camera_params_compute_viewplane(&params, 1, 1, 1.0f, 1.0f);
 	}
+	BKE_camera_params_compute_matrix(&params);
 
-	for (i = 0; i < 4; i++) {
-		normal_tri_v3(data_cb.normal_tx[i], zero, data_cb.frame_tx[i], data_cb.frame_tx[(i + 1) % 4]);
-		plane_from_point_normal_v3(data_cb.plane_tx[i], data_cb.frame_tx[i], data_cb.normal_tx[i]);
+	copy_m3_m4(rot_obmat, camera_ob->obmat);
+	normalize_m3(rot_obmat);
+	/* To transform a plane in its homogeneous representation (4d vector),
+	 * we need the inverse of the transpose of the transform matrix... */
+	copy_m4_m3(rot_obmat_transposed_inversed, rot_obmat);
+	transpose_m4(rot_obmat_transposed_inversed);
+	invert_m4(rot_obmat_transposed_inversed);
+
+	print_m4_id(params.winmat);
+
+	/* Easy frustum plane extraction fro; a projection matrix:
+	 *
+	 * https://fgiesen.wordpress.com/2012/08/31/frustum-planes-from-the-projection-matrix/
+	 * http://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf
+	 */
+
+	/* Right plane */
+	data_cb.plane_tx[0][0] = params.winmat[0][3] - params.winmat[0][0];
+	data_cb.plane_tx[0][1] = params.winmat[1][3] - params.winmat[1][0];
+	data_cb.plane_tx[0][2] = params.winmat[2][3] - params.winmat[2][0];
+	data_cb.plane_tx[0][3] = params.winmat[3][3] - params.winmat[3][0];
+	mul_m4_v4(rot_obmat_transposed_inversed, data_cb.plane_tx[0]);
+	normalize_v3_v3(data_cb.normal_tx[0], data_cb.plane_tx[0]);
+
+	/* Bottom plane */
+	data_cb.plane_tx[1][0] = params.winmat[0][3] + params.winmat[0][1];
+	data_cb.plane_tx[1][1] = params.winmat[1][3] + params.winmat[1][1];
+	data_cb.plane_tx[1][2] = params.winmat[2][3] + params.winmat[2][1];
+	data_cb.plane_tx[1][3] = params.winmat[3][3] + params.winmat[3][1];
+	mul_m4_v4(rot_obmat_transposed_inversed, data_cb.plane_tx[1]);
+	normalize_v3_v3(data_cb.normal_tx[1], data_cb.plane_tx[1]);
+
+	/* Left plane */
+	data_cb.plane_tx[2][0] = params.winmat[0][3] + params.winmat[0][0];
+	data_cb.plane_tx[2][1] = params.winmat[1][3] + params.winmat[1][0];
+	data_cb.plane_tx[2][2] = params.winmat[2][3] + params.winmat[2][0];
+	data_cb.plane_tx[2][3] = params.winmat[3][3] + params.winmat[3][0];
+	mul_m4_v4(rot_obmat_transposed_inversed, data_cb.plane_tx[2]);
+	normalize_v3_v3(data_cb.normal_tx[2], data_cb.plane_tx[2]);
+
+	/* Top plane */
+	data_cb.plane_tx[3][0] = params.winmat[0][3] - params.winmat[0][1];
+	data_cb.plane_tx[3][1] = params.winmat[1][3] - params.winmat[1][1];
+	data_cb.plane_tx[3][2] = params.winmat[2][3] - params.winmat[2][1];
+	data_cb.plane_tx[3][3] = params.winmat[3][3] - params.winmat[3][1];
+	mul_m4_v4(rot_obmat_transposed_inversed, data_cb.plane_tx[3]);
+	normalize_v3_v3(data_cb.normal_tx[3], data_cb.plane_tx[3]);
+
+	for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
+		print_v4_id(data_cb.plane_tx[i]);
+		print_v3_id(data_cb.normal_tx[i]);
 	}
 
 	/* initialize callback data */
 	copy_v4_fl(data_cb.dist_vals_sq, FLT_MAX);
 	data_cb.tot = 0;
 	/* run callback on all visible points */
-	BKE_scene_foreach_display_point(scene, v3d, BA_SELECT,
-	                                camera_to_frame_view_cb, &data_cb);
+	BKE_scene_foreach_display_point(scene, v3d, BA_SELECT, camera_to_frame_view_cb, &data_cb);
 
 	if (data_cb.tot <= 1) {
 		return false;
 	}
+
+	if (params.is_ortho) {
+		float dists[CAMERA_VIEWFRAME_NUM_PLANES];
+		float cam_plane_x[3] = {1.0f, 0.0f, 0.0f};
+		float cam_plane_y[3] = {0.0f, 1.0f, 0.0f};
+		float cam_plane_z[3] = {0.0f, 0.0f, 1.0f};
+
+		mul_m3_v3(rot_obmat, cam_plane_x);
+		mul_m3_v3(rot_obmat, cam_plane_y);
+		mul_m3_v3(rot_obmat, cam_plane_z);
+
+		/* apply the dist-from-plane's to the transformed plane points */
+		for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
+			dists[i] = sqrtf_signed(data_cb.dist_vals_sq[i]);
+			printf("dist[%d]: %f\n", i, dists[i]);
+		}
+
+		printf("x diff: %f; y diff: %f, z diff: %f\n", (dists[0] + dists[2]) / 2.0f, (dists[1] + dists[3]) / 2.0f, (dists[4] + dists[5]) / 2.0f);
+
+		zero_v3(r_co);
+		print_v3_id(r_co);
+		madd_v3_v3fl(r_co, cam_plane_x, -(dists[0] - dists[2]) / 2.0f);
+		madd_v3_v3fl(r_co, cam_plane_y, -(dists[3] - dists[1]) / 2.0f);
+		madd_v3_v3fl(r_co, cam_plane_z, -dists[4] + 1.0f);
+		if ((dists[0] + dists[2]) > (dists[1] + dists[3])) {
+			*r_scale = params.ortho_scale - (dists[1] + dists[3]) * (params.viewplane.xmax - params.viewplane.xmin) / (params.viewplane.ymax - params.viewplane.ymin);
+		}
+		else {
+			*r_scale = params.ortho_scale - (dists[0] + dists[2]) * (params.viewplane.ymax - params.viewplane.ymin) / (params.viewplane.xmax - params.viewplane.xmin);
+		}
+		print_v3_id(r_co);
+		printf("r_scale: %f\n", *r_scale);
+
+		//~ r_co[0] = camera_ob->obmat[3][0] + (dists[0] + dists[2]) / 2.0f;
+		//~ r_co[1] = camera_ob->obmat[3][1] + (dists[1] + dists[3]) / 2.0f;
+		//~ r_co[2] = camera_ob->obmat[3][2];
+
+		return true;
+	}
 	else {
 		float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
 		float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
@@ -540,7 +620,7 @@ bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object
 		float plane_isect_pt_1[3], plane_isect_pt_2[3];
 
 		/* apply the dist-from-plane's to the transformed plane points */
-		for (i = 0; i < 4; i++) {
+		for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
 			mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], sqrtf_signed(data_cb.dist_vals_sq[i]));
 		}
 
@@ -578,18 +658,20 @@ bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object
 
 				/* offset shift */
 				normalize_v3(plane_isect_1_no);
-				madd_v3_v3fl(r_co, plane_isect_1_no, shift[1] * -plane_isect_delta_len);
+				madd_v3_v3fl(r_co, plane_isect_1_no, params.shifty * plane_isect_delta_len);
 			}
 			else {
 				copy_v3_v3(r_co, plane_isect_pt_2);
 
 				/* offset shift */
 				normalize_v3(plane_isect_2_no);
-				madd_v3_v3fl(r_co, plane_isect_2_no, shift[0] * -plane_isect_delta_len);
+				madd_v3_v3fl(r_co, plane_isect_2_no, params.shiftx * plane_isect_delta_len);
 			}
 
-
 			return true;
 		}
 	}
 }
+
+//~ bool BKE_camera_view_frame_fit_to_coordinates(Scene *scene, , Object *camera_ob, float r_co[3])
+
diff --gi

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list