From dc3f9b9c3ee64e2f98eba5eca882daf3035e0503 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 28 Nov 2013 15:01:53 +1100 Subject: View3D: split camera controlling parts of fly mode into their own functions --- source/blender/editors/space_view3d/CMakeLists.txt | 1 + .../editors/space_view3d/view3d_camera_control.c | 364 +++++++++++++++++++++ source/blender/editors/space_view3d/view3d_fly.c | 233 +------------ .../blender/editors/space_view3d/view3d_intern.h | 14 + 4 files changed, 394 insertions(+), 218 deletions(-) create mode 100644 source/blender/editors/space_view3d/view3d_camera_control.c (limited to 'source/blender/editors/space_view3d') diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 7d5cff6a2d0..af89c5307b6 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -46,6 +46,7 @@ set(SRC drawvolume.c space_view3d.c view3d_buttons.c + view3d_camera_control.c view3d_draw.c view3d_edit.c view3d_fly.c diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c new file mode 100644 index 00000000000..2797125485c --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_camera_control.c @@ -0,0 +1,364 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_camera_control.c + * \ingroup spview3d + * + * The purpose of View3DCameraControl is to allow editing \a rv3d manipulation + * (mainly \a ofs and \a viewquat) for the purpose of view navigation + * without having to worry about positioning the camera, its parent... + * or other details. + * + * + * Typical view-control usage: + * + * - aquire a view-control (#ED_view3d_control_aquire). + * - modify ``rv3d->ofs``, ``rv3d->viewquat``. + * - update the view data (#ED_view3d_control_aquire) - within a loop which draws the viewport. + * - finish and release the view-control (#ED_view3d_control_release), + * either keeping the current view or restoring the initial view. + * + * Notes: + * + * - when acquiring ``rv3d->dist`` is set to zero + * (so ``rv3d->ofs`` is always the view-point) + * - updating can optionally keyframe the camera object. + */ + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_camera_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BKE_object.h" + +#include "BKE_depsgraph.h" /* for object updating */ + +#include "ED_keyframing.h" +#include "ED_screen.h" + +#include "view3d_intern.h" /* own include */ + +#include "BLI_strict_flags.h" + + +typedef struct View3DCameraControl { + + /* -------------------------------------------------------------------- */ + /* Context (assign these to vars before use) */ + Scene *ctx_scene; + View3D *ctx_v3d; + RegionView3D *ctx_rv3d; + + + /* -------------------------------------------------------------------- */ + /* internal vars */ + + /* for parenting calculation */ + float view_mat_prev[4][4]; + + + /* -------------------------------------------------------------------- */ + /* optional capabilities */ + + bool use_parent_root; + + + /* -------------------------------------------------------------------- */ + /* intial values */ + + /* root most parent */ + Object *root_parent; + + /* backup values */ + float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ + float ofs_backup[3]; /* backup the views offset in case the user cancels flying in non camera mode */ + + /* backup the views quat in case the user cancels flying in non camera mode. + * (quat for view, eul for camera) */ + float rot_backup[4]; + char persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ + + /* are we flying an ortho camera in perspective view, + * which was originally in ortho view? + * could probably figure it out but better be explicit */ + bool is_ortho_cam; + + void *obtfm; /* backup the objects transform */ +} View3DCameraControl; + + +BLI_INLINE Object *view3d_cameracontrol_object(View3DCameraControl *vctrl) +{ + return vctrl->root_parent ? vctrl->root_parent : vctrl->ctx_v3d->camera; +} + + +/** + * Returns the object which is being manipulated or NULL. + */ +Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl) +{ + RegionView3D *rv3d = vctrl->ctx_rv3d; + + if (rv3d->persp == RV3D_CAMOB) { + return view3d_cameracontrol_object(vctrl); + } + else { + return NULL; + } +} + + +/** + * Creates a #View3DControl handle and sets up + * the view for first-person style navigation. + */ +struct View3DCameraControl *ED_view3d_cameracontrol_aquire( + Scene *scene, View3D *v3d, RegionView3D *rv3d, + const bool use_parent_root) +{ + View3DCameraControl *vctrl; + + vctrl = MEM_callocN(sizeof(View3DCameraControl), __func__); + + /* Store context */ + vctrl->ctx_scene = scene; + vctrl->ctx_v3d = v3d; + vctrl->ctx_rv3d = rv3d; + + vctrl->use_parent_root = use_parent_root; + + vctrl->persp_backup = rv3d->persp; + vctrl->dist_backup = rv3d->dist; + + /* check for flying ortho camera - which we cant support well + * we _could_ also check for an ortho camera but this is easier */ + if ((rv3d->persp == RV3D_CAMOB) && + (rv3d->is_persp == false)) + { + ((Camera *)v3d->camera->data)->type = CAM_PERSP; + vctrl->is_ortho_cam = true; + } + + if (rv3d->persp == RV3D_CAMOB) { + Object *ob_back; + if (use_parent_root && (vctrl->root_parent = v3d->camera->parent)) { + while (vctrl->root_parent->parent) + vctrl->root_parent = vctrl->root_parent->parent; + ob_back = vctrl->root_parent; + } + else { + ob_back = v3d->camera; + } + + /* store the original camera loc and rot */ + vctrl->obtfm = BKE_object_tfm_backup(ob_back); + + BKE_object_where_is_calc(scene, v3d->camera); + negate_v3_v3(rv3d->ofs, v3d->camera->obmat[3]); + + rv3d->dist = 0.0; + } + else { + float tvec[3]; + /* perspective or ortho */ + if (rv3d->persp == RV3D_ORTHO) + rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */ + + copy_qt_qt(vctrl->rot_backup, rv3d->viewquat); + copy_v3_v3(vctrl->ofs_backup, rv3d->ofs); + + /* the dist defines a vector that is infront of the offset + * to rotate the view about. + * this is no good for fly mode because we + * want to rotate about the viewers center. + * but to correct the dist removal we must + * alter offset so the view doesn't jump. */ + + rv3d->dist = 0.0f; + + copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup); + mul_mat3_m4_v3(rv3d->viewinv, tvec); + sub_v3_v3(rv3d->ofs, tvec); + /* Done with correcting for the dist */ + } + + ED_view3d_to_m4(vctrl->view_mat_prev, rv3d->ofs, rv3d->viewquat, rv3d->dist); + + return vctrl; +} + + +/** + * Updates cameras from the ``rv3d`` values, optionally auto-keyframing. + */ +void ED_view3d_cameracontrol_update( + View3DCameraControl *vctrl, + /* args for keyframing */ + const bool use_autokey, + struct bContext *C, const bool do_rotate, const bool do_translate) +{ + /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ + + Scene *scene = vctrl->ctx_scene; + View3D *v3d = vctrl->ctx_v3d; + RegionView3D *rv3d = vctrl->ctx_rv3d; + + ID *id_key; + + /* transform the parent or the camera? */ + if (vctrl->root_parent) { + Object *ob_update; + + float view_mat[4][4]; + float prev_view_imat[4][4]; + float diff_mat[4][4]; + float parent_mat[4][4]; + + invert_m4_m4(prev_view_imat, vctrl->view_mat_prev); + ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); + mul_m4_m4m4(diff_mat, view_mat, prev_view_imat); + mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat); + + BKE_object_apply_mat4(vctrl->root_parent, parent_mat, true, false); + + ob_update = v3d->camera->parent; + while (ob_update) { + DAG_id_tag_update(&ob_update->id, OB_RECALC_OB); + ob_update = ob_update->parent; + } + + copy_m4_m4(vctrl->view_mat_prev, view_mat); + + id_key = &vctrl->root_parent->id; + } + else { + float view_mat[4][4]; + float size_mat[4][4]; + float size_back[3]; + + /* even though we handle the size matrix, this still changes over time */ + copy_v3_v3(size_back, v3d->camera->size); + + ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); + size_to_mat4(size_mat, v3d->camera->size); + mul_m4_m4m4(view_mat, view_mat, size_mat); + + BKE_object_apply_mat4(v3d->camera, view_mat, true, true); + + copy_v3_v3(v3d->camera->size, size_back); + + id_key = &v3d->camera->id; + } + + /* record the motion */ + if (use_autokey && autokeyframe_cfra_can_key(scene, id_key)) { + ListBase dsources = {NULL, NULL}; + + /* add data-source override for the camera object */ + ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL); + + /* insert keyframes + * 1) on the first frame + * 2) on each subsequent frame + * TODO: need to check in future that frame changed before doing this + */ + if (do_rotate) { + struct KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + } + if (do_translate) { + struct KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + } + + /* free temp data */ + BLI_freelistN(&dsources); + } +} + + +/** + * Release view control. + * + * \param restore Sets the view state to the values that were set + * before #ED_view3d_control_aquire was called. + */ +void ED_view3d_cameracontrol_release( + View3DCameraControl *vctrl, + const bool restore) +{ + View3D *v3d = vctrl->ctx_v3d; + RegionView3D *rv3d = vctrl->ctx_rv3d; + + rv3d->dist = vctrl->dist_backup; + if (restore) { + /* Revert to original view? */ + if (vctrl->persp_backup == RV3D_CAMOB) { /* a camera view */ + Object *ob_back = view3d_cameracontrol_object(vctrl); + + /* store the original camera loc and rot */ + BKE_object_tfm_restore(ob_back, vctrl->obtfm); + + DAG_id_tag_update(&ob_back->id, OB_RECALC_OB); + } + else { + /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ + copy_qt_qt(rv3d->viewquat, vctrl->rot_backup); + rv3d->persp = vctrl->persp_backup; + } + /* always, is set to zero otherwise */ + copy_v3_v3(rv3d->ofs, vctrl->ofs_backup); + } + else if (vctrl->persp_backup == RV3D_CAMOB) { /* camera */ + DAG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), OB_RECALC_OB); + + /* always, is set to zero otherwise */ + copy_v3_v3(rv3d->ofs, vctrl->ofs_backup); + } + else { /* not camera */ + float tvec[3]; + + /* Apply the fly mode view */ + /* restore the dist */ + copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup); + mul_mat3_m4_v3(rv3d->viewinv, tvec); + add_v3_v3(rv3d->ofs, tvec); + /* Done with correcting for the dist */ + } + + if (vctrl->is_ortho_cam) { + ((Camera *)v3d->camera->data)->type = CAM_ORTHO; + } + + if (vctrl->obtfm) { + MEM_freeN(vctrl->obtfm); + } + + MEM_freeN(vctrl); +} diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 373e57d5708..d225a2df2da 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -28,35 +28,28 @@ //#define NDOF_FLY_DEBUG //#define NDOF_FLY_DRAW_TOOMUCH /* is this needed for ndof? - commented so redraw doesnt thrash - campbell */ -#include "DNA_anim_types.h" -#include "DNA_scene_types.h" + #include "DNA_object_types.h" -#include "DNA_camera_types.h" #include "MEM_guardedalloc.h" #include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_object.h" #include "BKE_report.h" -#include "BKE_depsgraph.h" /* for fly mode updating */ - #include "BIF_gl.h" #include "WM_api.h" #include "WM_types.h" -#include "ED_keyframing.h" #include "ED_screen.h" #include "ED_space_api.h" #include "PIL_time.h" /* smoothview */ #include "view3d_intern.h" /* own include */ + /* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ enum { FLY_MODAL_CANCEL = 1, @@ -205,24 +198,6 @@ typedef struct FlyInfo { float xlock_momentum, zlock_momentum; /* nicer dynamics */ float grid; /* world scale 1.0 default */ - /* root most parent */ - Object *root_parent; - - /* backup values */ - float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ - float ofs_backup[3]; /* backup the views offset in case the user cancels flying in non camera mode */ - - /* backup the views quat in case the user cancels flying in non camera mode. - * (quat for view, eul for camera) */ - float rot_backup[4]; - short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ - - /* are we flying an ortho camera in perspective view, - * which was originally in ortho view? - * could probably figure it out but better be explicit */ - bool is_ortho_cam; - void *obtfm; /* backup the objects transform */ - /* compare between last state */ double time_lastwheel; /* used to accelerate when using the mousewheel a lot */ double time_lastdraw; /* time between draws */ @@ -232,8 +207,7 @@ typedef struct FlyInfo { /* use for some lag */ float dvec_prev[3]; /* old for some lag */ - /* for parenting calculation */ - float view_mat_prev[4][4]; + struct View3DCameraControl *v3d_camera_control; } FlyInfo; @@ -359,65 +333,10 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent if (fabsf(upvec[2]) < 0.1f) { fly->zlock = FLY_AXISLOCK_STATE_IDLE; } - upvec[0] = 0; - upvec[1] = 0; - upvec[2] = 0; - fly->persp_backup = fly->rv3d->persp; - fly->dist_backup = fly->rv3d->dist; - - /* check for flying ortho camera - which we cant support well - * we _could_ also check for an ortho camera but this is easier */ - if ((fly->rv3d->persp == RV3D_CAMOB) && - (fly->rv3d->is_persp == false)) - { - ((Camera *)fly->v3d->camera->data)->type = CAM_PERSP; - fly->is_ortho_cam = true; - } - - if (fly->rv3d->persp == RV3D_CAMOB) { - Object *ob_back; - if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (fly->root_parent = fly->v3d->camera->parent)) { - while (fly->root_parent->parent) - fly->root_parent = fly->root_parent->parent; - ob_back = fly->root_parent; - } - else { - ob_back = fly->v3d->camera; - } - - /* store the original camera loc and rot */ - fly->obtfm = BKE_object_tfm_backup(ob_back); - - BKE_object_where_is_calc(fly->scene, fly->v3d->camera); - negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); - - fly->rv3d->dist = 0.0; - } - else { - /* perspective or ortho */ - if (fly->rv3d->persp == RV3D_ORTHO) - fly->rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */ - - copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat); - copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs); - - /* the dist defines a vector that is infront of the offset - * to rotate the view about. - * this is no good for fly mode because we - * want to rotate about the viewers center. - * but to correct the dist removal we must - * alter offset so the view doesn't jump. */ - - fly->rv3d->dist = 0.0f; - - upvec[2] = fly->dist_backup; /* x and y are 0 */ - mul_m3_v3(mat, upvec); - sub_v3_v3(fly->rv3d->ofs, upvec); - /* Done with correcting for the dist */ - } - - ED_view3d_to_m4(fly->view_mat_prev, fly->rv3d->ofs, fly->rv3d->viewquat, fly->rv3d->dist); + fly->v3d_camera_control = ED_view3d_cameracontrol_aquire( + fly->scene, fly->v3d, fly->rv3d, + (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); /* center the mouse, probably the UI mafia are against this but without its quite annoying */ WM_cursor_warp(win, fly->ar->winrct.xmin + fly->ar->winx / 2, fly->ar->winrct.ymin + fly->ar->winy / 2); @@ -428,9 +347,6 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent static int flyEnd(bContext *C, FlyInfo *fly) { RegionView3D *rv3d = fly->rv3d; - View3D *v3d = fly->v3d; - - float upvec[3]; if (fly->state == FLY_RUNNING) return OPERATOR_RUNNING_MODAL; @@ -443,54 +359,11 @@ static int flyEnd(bContext *C, FlyInfo *fly) ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel); - rv3d->dist = fly->dist_backup; - if (fly->state == FLY_CANCEL) { - /* Revert to original view? */ - if (fly->persp_backup == RV3D_CAMOB) { /* a camera view */ - Object *ob_back; - ob_back = (fly->root_parent) ? fly->root_parent : fly->v3d->camera; - - /* store the original camera loc and rot */ - BKE_object_tfm_restore(ob_back, fly->obtfm); - - DAG_id_tag_update(&ob_back->id, OB_RECALC_OB); - } - else { - /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ - copy_qt_qt(rv3d->viewquat, fly->rot_backup); - rv3d->persp = fly->persp_backup; - } - /* always, is set to zero otherwise */ - copy_v3_v3(rv3d->ofs, fly->ofs_backup); - } - else if (fly->persp_backup == RV3D_CAMOB) { /* camera */ - DAG_id_tag_update(fly->root_parent ? &fly->root_parent->id : &v3d->camera->id, OB_RECALC_OB); - - /* always, is set to zero otherwise */ - copy_v3_v3(rv3d->ofs, fly->ofs_backup); - } - else { /* not camera */ - - /* Apply the fly mode view */ - /* restore the dist */ - float mat[3][3]; - upvec[0] = upvec[1] = 0; - upvec[2] = fly->dist_backup; /* x and y are 0 */ - copy_m3_m4(mat, rv3d->viewinv); - mul_m3_v3(mat, upvec); - add_v3_v3(rv3d->ofs, upvec); - /* Done with correcting for the dist */ - } - - if (fly->is_ortho_cam) { - ((Camera *)fly->v3d->camera->data)->type = CAM_ORTHO; - } + ED_view3d_cameracontrol_release(fly->v3d_camera_control, fly->state == FLY_CANCEL); rv3d->rflag &= ~RV3D_NAVIGATING; //XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */ - if (fly->obtfm) - MEM_freeN(fly->obtfm); if (fly->ndof) MEM_freeN(fly->ndof); @@ -739,86 +612,10 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event) } } -static void flyMoveCamera(bContext *C, RegionView3D *rv3d, FlyInfo *fly, - const bool do_rotate, const bool do_translate) +static void flyMoveCamera(bContext *C, FlyInfo *fly, + const bool do_rotate, const bool do_translate) { - /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ - - View3D *v3d = fly->v3d; - Scene *scene = fly->scene; - ID *id_key; - - /* transform the parent or the camera? */ - if (fly->root_parent) { - Object *ob_update; - - float view_mat[4][4]; - float prev_view_imat[4][4]; - float diff_mat[4][4]; - float parent_mat[4][4]; - - invert_m4_m4(prev_view_imat, fly->view_mat_prev); - ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); - mul_m4_m4m4(diff_mat, view_mat, prev_view_imat); - mul_m4_m4m4(parent_mat, diff_mat, fly->root_parent->obmat); - - BKE_object_apply_mat4(fly->root_parent, parent_mat, true, false); - - // BKE_object_where_is_calc(scene, fly->root_parent); - - ob_update = v3d->camera->parent; - while (ob_update) { - DAG_id_tag_update(&ob_update->id, OB_RECALC_OB); - ob_update = ob_update->parent; - } - - copy_m4_m4(fly->view_mat_prev, view_mat); - - id_key = &fly->root_parent->id; - } - else { - float view_mat[4][4]; - float size_mat[4][4]; - float size_back[3]; - - /* even though we handle the size matrix, this still changes over time */ - copy_v3_v3(size_back, v3d->camera->size); - - ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); - size_to_mat4(size_mat, v3d->camera->size); - mul_m4_m4m4(view_mat, view_mat, size_mat); - - BKE_object_apply_mat4(v3d->camera, view_mat, true, true); - - copy_v3_v3(v3d->camera->size, size_back); - - id_key = &v3d->camera->id; - } - - /* record the motion */ - if (autokeyframe_cfra_can_key(scene, id_key)) { - ListBase dsources = {NULL, NULL}; - - /* add datasource override for the camera object */ - ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL); - - /* insert keyframes - * 1) on the first frame - * 2) on each subsequent frame - * TODO: need to check in future that frame changed before doing this - */ - if (do_rotate) { - KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); - } - if (do_translate) { - KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); - } - - /* free temp data */ - BLI_freelistN(&dsources); - } + ED_view3d_cameracontrol_update(fly->v3d_camera_control, true, C, do_rotate, do_translate); } static int flyApply(bContext *C, FlyInfo *fly) @@ -1073,7 +870,7 @@ static int flyApply(bContext *C, FlyInfo *fly) interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * FLY_SMOOTH_FAC)))); if (rv3d->persp == RV3D_CAMOB) { - Object *lock_ob = fly->root_parent ? fly->root_parent : fly->v3d->camera; + Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control); if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0; if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0; if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0; @@ -1086,7 +883,7 @@ static int flyApply(bContext *C, FlyInfo *fly) (fly->zlock != FLY_AXISLOCK_STATE_OFF) || ((moffset[0] || moffset[1]) && !fly->pan_view)); const bool do_translate = (fly->speed != 0.0f || fly->pan_view); - flyMoveCamera(C, rv3d, fly, do_rotate, do_translate); + flyMoveCamera(C, fly, do_rotate, do_translate); } } @@ -1149,7 +946,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly) if (rv3d->persp == RV3D_CAMOB) { /* respect camera position locks */ - Object *lock_ob = fly->root_parent ? fly->root_parent : fly->v3d->camera; + Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control); if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f; if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f; if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f; @@ -1223,7 +1020,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly) fly->redraw = true; if (rv3d->persp == RV3D_CAMOB) { - flyMoveCamera(C, rv3d, fly, do_rotate, do_translate); + flyMoveCamera(C, fly, do_rotate, do_translate); } } @@ -1269,7 +1066,7 @@ static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event) bool do_draw = false; FlyInfo *fly = op->customdata; RegionView3D *rv3d = fly->rv3d; - Object *fly_object = fly->root_parent ? fly->root_parent : fly->v3d->camera; + Object *fly_object = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control); fly->redraw = 0; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index a496bbba72f..9bca5345e82 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -204,6 +204,20 @@ void viewdolly_modal_keymap(struct wmKeyConfig *keyconf); void VIEW3D_OT_properties(struct wmOperatorType *ot); void view3d_buttons_register(struct ARegionType *art); +/* view3d_camera_control.c */ +struct View3DCameraControl *ED_view3d_cameracontrol_aquire( + Scene *scene, View3D *v3d, RegionView3D *rv3d, + const bool use_parent_root); +void ED_view3d_cameracontrol_update( + struct View3DCameraControl *vctrl, + const bool use_autokey, + struct bContext *C, const bool do_rotate, const bool do_translate); +void ED_view3d_cameracontrol_release( + struct View3DCameraControl *vctrl, + const bool restore); +Object *ED_view3d_cameracontrol_object_get( + struct View3DCameraControl *vctrl); + /* view3d_toolbar.c */ void VIEW3D_OT_toolshelf(struct wmOperatorType *ot); void view3d_toolshelf_register(struct ARegionType *art); -- cgit v1.2.3