View3D: split camera controlling parts of fly mode into their own functions
This commit is contained in:
@@ -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
|
||||
|
||||
364
source/blender/editors/space_view3d/view3d_camera_control.c
Normal file
364
source/blender/editors/space_view3d/view3d_camera_control.c
Normal file
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user