[Bf-blender-cvs] [88ffc97] asset-experiments: Finalized working new 'fit in camera view' code.
Bastien Montagne
noreply at git.blender.org
Thu Dec 18 15:28:31 CET 2014
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(¶ms);
- BKE_camera_params_from_object(¶ms, camera_ob);
+ BKE_camera_params_init(params);
+ BKE_camera_params_from_object(params, ob);
/* compute matrix, viewplane, .. */
if (scene) {
- BKE_camera_params_compute_viewplane(¶ms, 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(¶ms, 1, 1, 1.0f, 1.0f);
+ BKE_camera_params_compute_viewplane(params, 1, 1, 1.0f, 1.0f);
}
- BKE_camera_params_compute_matrix(¶ms);
+ 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. @@
More information about the Bf-blender-cvs
mailing list