Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-11-14 07:54:23 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-11-14 07:54:23 +0400
commita34fed3f2c1924c1487c4e159d3825697b08841c (patch)
tree497462f25d5ae94edce0515b6de2f01f8517f416 /source/blender/blenkernel/intern/camera.c
parentfea58943ecf32daa5bd828656d5e1157e6de984a (diff)
VIEW3D_OT_camera_to_view_selected operator to move the camera to frame
all selected, renderable objects.
Diffstat (limited to 'source/blender/blenkernel/intern/camera.c')
-rw-r--r--source/blender/blenkernel/intern/camera.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 145eb9363e9..0f973273b32 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -41,6 +41,7 @@
#include "BKE_animsys.h"
#include "BKE_camera.h"
+#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -394,3 +395,109 @@ void camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
}
+
+typedef struct CameraViewFrameData {
+ float frame_tx[4][3];
+ float normal_tx[4][3];
+ float dist_vals[4];
+ unsigned int tot;
+} CameraViewFrameData;
+
+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++) {
+ float nd= -dist_to_plane_v3(co, data->frame_tx[i], data->normal_tx[i]);
+ if (nd < data->dist_vals[i]) {
+ data->dist_vals[i]= nd;
+ }
+ }
+
+ data->tot++;
+}
+
+/* dont move the camera, just yield the fit location */
+int camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3])
+{
+ float plane_tx[4][3];
+ float rot_obmat[3][3];
+ const float zero[3]= {0,0,0};
+ CameraViewFrameData data_cb;
+
+ unsigned int i;
+
+ camera_view_frame(scene, camera_ob->data, data_cb.frame_tx);
+
+ copy_m3_m4(rot_obmat, camera_ob->obmat);
+ normalize_m3(rot_obmat);
+
+ for (i= 0; i < 4; i++) {
+ mul_m3_v3(rot_obmat, data_cb.frame_tx[i]);
+ }
+
+ 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]);
+ }
+
+ /* initialize callback data */
+ data_cb.dist_vals[0]=
+ data_cb.dist_vals[1]=
+ data_cb.dist_vals[2]=
+ data_cb.dist_vals[3]= 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);
+
+ if (data_cb.tot <= 1) {
+ return FALSE;
+ }
+ else {
+ float plane_isect_1[3], plane_isect_1_other[3];
+ float plane_isect_2[3], plane_isect_2_other[3];
+
+ 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++) {
+ mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], data_cb.dist_vals[i]);
+ }
+
+ if ( (isect_plane_plane_v3(plane_isect_1, plane_isect_1_other,
+ plane_tx[0], data_cb.normal_tx[0],
+ plane_tx[2], data_cb.normal_tx[2]) == 0) ||
+ (isect_plane_plane_v3(plane_isect_2, plane_isect_2_other,
+ plane_tx[1], data_cb.normal_tx[1],
+ plane_tx[3], data_cb.normal_tx[3]) == 0))
+ {
+ /* this is very unlikely */
+ return FALSE;
+ }
+ else {
+
+ add_v3_v3(plane_isect_1_other, plane_isect_1);
+ add_v3_v3(plane_isect_2_other, plane_isect_2);
+
+ if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
+ plane_isect_2, plane_isect_2_other,
+ plane_isect_pt_1, plane_isect_pt_2) == 0)
+ {
+ return FALSE;
+ }
+ else {
+ float cam_plane_no[3]= {0.0f, 0.0f, -1.0f};
+ float tvec[3];
+ mul_m3_v3(rot_obmat, cam_plane_no);
+
+ sub_v3_v3v3(tvec, plane_isect_pt_2, plane_isect_pt_1);
+ copy_v3_v3(r_co, dot_v3v3(tvec, cam_plane_no) > 0.0f ?
+ plane_isect_pt_1 : plane_isect_pt_2);
+
+ return TRUE;
+ }
+ }
+ }
+}