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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to