Commit: 88ffc9767ce0c7296fef20cc87abeb8e1a4ee0c8
Author: Bastien Montagne
Date:   Thu Dec 18 15:26:34 2014 +0100
Branches: asset-experiments
https://developer.blender.org/rB88ffc9767ce0c7296fef20cc87abeb8e1a4ee0c8

Finalized working new 'fit in camera view' code.

Now for any object, we have an rna func to call with a set of (flatten :/)
coordinates, and we get back location this object should be to 'see'
all given points.

Would need more refinements, but will do for now.

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

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_api.c

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

diff --git a/source/blender/blenkernel/BKE_camera.h 
b/source/blender/blenkernel/BKE_camera.h
index 045486d..6f73cb4 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -119,6 +119,8 @@ void BKE_camera_view_frame(struct Scene *scene, struct 
Camera *camera, float r_v
 
 bool BKE_camera_view_frame_fit_to_scene(struct Scene *scene, struct View3D 
*v3d, struct Object *camera_ob,
                                         float r_co[3], float *r_scale);
+bool BKE_camera_view_frame_fit_to_coordinates(struct Scene *scene, float 
(*cos)[3], int num_cos,
+                                              struct Object *camera_ob, 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 d3b8081..6e94242 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -463,10 +463,18 @@ void BKE_camera_view_frame(Scene *scene, Camera *camera, 
float r_vec[4][3])
 #define CAMERA_VIEWFRAME_NUM_PLANES 4
 
 typedef struct CameraViewFrameData {
-       float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4];  /* 6 planes */
+       float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4];  /* 4 planes */
        float normal_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
        float dist_vals_sq[CAMERA_VIEWFRAME_NUM_PLANES];  /* distance squared 
(signed) */
        unsigned int tot;
+
+       /* Ortho camera only. */
+       bool is_ortho;
+       float camera_no[3];
+       float dist_to_cam;
+
+       /* Not used by callbacks... */
+       float rot_cammat[3][3];
 } CameraViewFrameData;
 
 static void camera_to_frame_view_cb(const float co[3], void *user_data)
@@ -481,135 +489,121 @@ static void camera_to_frame_view_cb(const float co[3], 
void *user_data)
                }
        }
 
+       if (data->is_ortho) {
+               float d = dot_v3v3(data->camera_no, co);
+               if (d < data->dist_to_cam) {
+                       data->dist_to_cam = d;
+               }
+       }
+
        data->tot++;
 }
 
-/* don't move the camera, just yield the fit location */
-/* 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)
+static void bke_camera_frame_fit_data_init(Scene *scene, Object *ob, 
CameraParams *params, CameraViewFrameData *data)
 {
-       CameraParams params;
-       float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
-       float rot_obmat[3][3];
-       float rot_obmat_transposed_inversed[4][4];
-       CameraViewFrameData data_cb;
-
+       float rot_cammat_transposed_inversed[4][4];
        unsigned int i;
 
-       /* just in case */
-       *r_scale = 1.0f;
-
        /* setup parameters */
-       BKE_camera_params_init(&params);
-       BKE_camera_params_from_object(&params, camera_ob);
+       BKE_camera_params_init(params);
+       BKE_camera_params_from_object(params, ob);
 
        /* compute matrix, viewplane, .. */
        if (scene) {
-               BKE_camera_params_compute_viewplane(&params, scene->r.xsch, 
scene->r.ysch, scene->r.xasp, scene->r.yasp);
+               BKE_camera_params_compute_viewplane(params, scene->r.xsch, 
scene->r.ysch, scene->r.xasp, scene->r.yasp);
        }
        else {
-               BKE_camera_params_compute_viewplane(&params, 1, 1, 1.0f, 1.0f);
+               BKE_camera_params_compute_viewplane(params, 1, 1, 1.0f, 1.0f);
        }
-       BKE_camera_params_compute_matrix(&params);
+       BKE_camera_params_compute_matrix(params);
 
-       copy_m3_m4(rot_obmat, camera_ob->obmat);
-       normalize_m3(rot_obmat);
+       /* initialize callback data */
+       copy_m3_m4(data->rot_cammat, ob->obmat);
+       normalize_m3(data->rot_cammat);
        /* 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);
+       copy_m4_m3(rot_cammat_transposed_inversed, data->rot_cammat);
+       transpose_m4(rot_cammat_transposed_inversed);
+       invert_m4(rot_cammat_transposed_inversed);
 
-       print_m4_id(params.winmat);
-
-       /* Easy frustum plane extraction fro; a projection matrix:
+       /* Easy frustum plane extraction from a projection matrix (homogeneous 
4d vector representations of planes):
         *
         * 
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]);
+       data->plane_tx[0][0] = params->winmat[0][3] - params->winmat[0][0];
+       data->plane_tx[0][1] = params->winmat[1][3] - params->winmat[1][0];
+       data->plane_tx[0][2] = params->winmat[2][3] - params->winmat[2][0];
+       data->plane_tx[0][3] = params->winmat[3][3] - params->winmat[3][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]);
+       data->plane_tx[1][0] = params->winmat[0][3] + params->winmat[0][1];
+       data->plane_tx[1][1] = params->winmat[1][3] + params->winmat[1][1];
+       data->plane_tx[1][2] = params->winmat[2][3] + params->winmat[2][1];
+       data->plane_tx[1][3] = params->winmat[3][3] + params->winmat[3][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]);
+       data->plane_tx[2][0] = params->winmat[0][3] + params->winmat[0][0];
+       data->plane_tx[2][1] = params->winmat[1][3] + params->winmat[1][0];
+       data->plane_tx[2][2] = params->winmat[2][3] + params->winmat[2][0];
+       data->plane_tx[2][3] = params->winmat[3][3] + params->winmat[3][0];
 
        /* 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]);
+       data->plane_tx[3][0] = params->winmat[0][3] - params->winmat[0][1];
+       data->plane_tx[3][1] = params->winmat[1][3] - params->winmat[1][1];
+       data->plane_tx[3][2] = params->winmat[2][3] - params->winmat[2][1];
+       data->plane_tx[3][3] = params->winmat[3][3] - params->winmat[3][1];
 
+       /* Rotate planes and get normals from them */
        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]);
+               mul_m4_v4(rot_cammat_transposed_inversed, data->plane_tx[i]);
+               normalize_v3_v3(data->normal_tx[i], data->plane_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);
+       copy_v4_fl(data->dist_vals_sq, FLT_MAX);
+       data->tot = 0;
+       data->is_ortho = params->is_ortho;
+       if (params->is_ortho) {
+               float camera_no[3] = {0.0f, 0.0f, -1.0f};
+
+               mul_m3_v3(data->rot_cammat, camera_no);
+               copy_v3_v3(data->camera_no, camera_no);
+               data->dist_to_cam = FLT_MAX;
+       }
+}
 
-       if (data_cb.tot <= 1) {
+static bool bke_camera_frame_fit_compute_from_data(CameraParams *params, 
CameraViewFrameData *data, float r_co[3], float *r_scale)
+{
+       float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
+       unsigned int i;
+
+       if (data->tot <= 1) {
                return false;
        }
 
-       if (params.is_ortho) {
+       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);
+               float *cam_axis_x = data->rot_cammat[0];
+               float *cam_axis_y = data->rot_cammat[1];
+               float *cam_axis_z = data->rot_cammat[2];
 
                /* 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]);
+                       dists[i] = sqrtf_signed(data->dist_vals_sq[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);
+               madd_v3_v3fl(r_co, cam_axis_x, -(dists[0] - dists[2]) / 2.0f);
+               madd_v3_v3fl(r_co, cam_axis_y, -(dists[3] - dists[1]) / 2.0f);
+               madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - 
params->clipsta));
                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);
+                       *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);
+                       *r_scale = params->ortho_scale - (dists[0] + dists[2]) 
* (params->viewplane.ymax - params->viewplane.ymi

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