COW Operators: Fix VIEW3D_OT_ rotate move zoom dolly orbit roll pan smoothview and the ndof versions

Fixes camera view locking, camera related transitions and movements with the active object as pivot point
Note there can still be problems if the active object is not selectable
This commit is contained in:
Inês Almeida 2018-05-21 20:29:00 +02:00
parent 13d2df32c7
commit 161ab6109e
Notes: blender-bot 2023-09-13 08:48:34 +02:00
Referenced by commit 381cef1773, Cleanup: remove oudated comment from early COW development
Referenced by issue #54829, COW Operators: 3D View
6 changed files with 102 additions and 66 deletions

View File

@ -125,6 +125,7 @@ void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], bool use_compat)
void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const bool use_compat, const bool use_parent);
void BKE_object_apply_mat4_ex(struct Object *ob, float mat[4][4], struct Object *parent, float parentinv[4][4], const bool use_compat);
void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]);
bool BKE_object_pose_context_check(const struct Object *ob);

View File

@ -2199,17 +2199,25 @@ void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *o
BKE_object_where_is_calc(depsgraph, scene, workob);
}
/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, const bool use_parent)
/**
* Applies the global transformation \a mat to the \a ob using a relative parent space if supplied.
*
* \param mat the global transformation mat that the object should be set object to.
* \param parent the parent space in which this object will be set relative to (should probably always be parent_eval).
* \param use_compat true to ensure that rotations are set using the min difference between the old and new orientation.
*/
void BKE_object_apply_mat4_ex(Object *ob, float mat[4][4], Object *parent, float parentinv[4][4], const bool use_compat)
{
/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
float rot[3][3];
if (use_parent && ob->parent) {
if (parent != NULL) {
float rmat[4][4], diff_mat[4][4], imat[4][4], parent_mat[4][4];
BKE_object_get_parent_matrix(NULL, ob, ob->parent, parent_mat);
BKE_object_get_parent_matrix(NULL, ob, parent, parent_mat);
mul_m4_m4m4(diff_mat, parent_mat, ob->parentinv);
mul_m4_m4m4(diff_mat, parent_mat, parentinv);
invert_m4_m4(imat, diff_mat);
mul_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
@ -2231,6 +2239,12 @@ void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, c
/* BKE_object_mat3_to_rot handles delta rotations */
}
/* XXX: should be removed after COW operators port to use BKE_object_apply_mat4_ex directly */
void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, const bool use_parent)
{
BKE_object_apply_mat4_ex(ob, mat, use_parent ? ob->parent : NULL, ob->parentinv, use_compat);
}
BoundBox *BKE_boundbox_alloc_unit(void)
{
BoundBox *bb;

View File

@ -109,7 +109,8 @@ void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], c
void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist);
void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist);
void ED_view3d_to_object(
const struct Depsgraph *depsgraph, struct Object *ob, const float ofs[3], const float quat[4], const float dist);
void ED_view3d_lastview_store(struct RegionView3D *rv3d);
@ -436,17 +437,21 @@ uint64_t ED_view3d_datamask(const struct Scene *scene, const struct View3D *v3d)
uint64_t ED_view3d_screen_datamask(const struct Scene *scene, const struct bScreen *screen);
bool ED_view3d_offset_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d);
void ED_view3d_persp_switch_from_camera(struct View3D *v3d, struct RegionView3D *rv3d, const char persp);
bool ED_view3d_persp_ensure(struct View3D *v3d, struct ARegion *ar);
void ED_view3d_persp_switch_from_camera(const struct Depsgraph *depsgraph,
struct View3D *v3d, struct RegionView3D *rv3d, const char persp);
bool ED_view3d_persp_ensure(const struct Depsgraph *depsgraph,
struct View3D *v3d, struct ARegion *ar);
/* camera lock functions */
bool ED_view3d_camera_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d);
/* copy the camera to the view before starting a view transformation */
void ED_view3d_camera_lock_init_ex(struct View3D *v3d, struct RegionView3D *rv3d, const bool calc_dist);
void ED_view3d_camera_lock_init(struct View3D *v3d, struct RegionView3D *rv3d);
void ED_view3d_camera_lock_init_ex(const struct Depsgraph *depsgraph,
struct View3D *v3d, struct RegionView3D *rv3d, const bool calc_dist);
void ED_view3d_camera_lock_init(const struct Depsgraph *depsgraph, struct View3D *v3d, struct RegionView3D *rv3d);
/* copy the view to the camera, return true if */
bool ED_view3d_camera_lock_sync(struct View3D *v3d, struct RegionView3D *rv3d);
bool ED_view3d_camera_lock_sync(const struct Depsgraph *depsgraph,
struct View3D *v3d, struct RegionView3D *rv3d);
bool ED_view3d_camera_autokey(
struct Scene *scene, struct ID *id_key,

View File

@ -250,9 +250,11 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
static float lastofs[3] = {0, 0, 0};
bool is_set = false;
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob_act = OBACT(view_layer);
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
Object *ob_act_eval = OBACT(view_layer_eval);
Object *ob_act = DEG_get_original_object(ob_act_eval);
if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
/* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
@ -264,16 +266,16 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
*/
if (ob_act->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
float stroke[3];
BKE_paint_stroke_get_average(scene, ob_act, stroke);
BKE_paint_stroke_get_average(scene, ob_act_eval, stroke);
copy_v3_v3(lastofs, stroke);
}
else {
copy_v3_v3(lastofs, ob_act->obmat[3]);
copy_v3_v3(lastofs, ob_act_eval->obmat[3]);
}
is_set = true;
}
else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) {
Curve *cu = ob_act->data;
Curve *cu = ob_act_eval->data;
EditFont *ef = cu->editfont;
int i;
@ -283,32 +285,32 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
}
mul_v2_fl(lastofs, 1.0f / 4.0f);
mul_m4_v3(ob_act->obmat, lastofs);
mul_m4_v3(ob_act_eval->obmat, lastofs);
is_set = true;
}
else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
/* object mode use boundbox centers */
Base *base;
Base *base_eval;
unsigned int tot = 0;
float select_center[3];
zero_v3(select_center);
for (base = FIRSTBASE(view_layer); base; base = base->next) {
if (TESTBASE(base)) {
for (base_eval = FIRSTBASE(view_layer_eval); base_eval; base_eval = base_eval->next) {
if (TESTBASE(base_eval)) {
/* use the boundbox if we can */
Object *ob = base->object;
Object *ob_eval = base_eval->object;
if (ob->bb && !(ob->bb->flag & BOUNDBOX_DIRTY)) {
if (ob_eval->bb && !(ob_eval->bb->flag & BOUNDBOX_DIRTY)) {
float cent[3];
BKE_boundbox_calc_center_aabb(ob->bb, cent);
BKE_boundbox_calc_center_aabb(ob_eval->bb, cent);
mul_m4_v3(ob->obmat, cent);
mul_m4_v3(ob_eval->obmat, cent);
add_v3_v3(select_center, cent);
}
else {
add_v3_v3(select_center, ob->obmat[3]);
add_v3_v3(select_center, ob_eval->obmat[3]);
}
tot++;
}
@ -371,6 +373,7 @@ static void viewops_data_create(
bContext *C, wmOperator *op, const wmEvent *event,
enum eViewOpsFlag viewops_flag)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ViewOpsData *vod = op->customdata;
RegionView3D *rv3d = vod->rv3d;
@ -381,7 +384,6 @@ static void viewops_data_create(
/* we need the depth info before changing any viewport options */
if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
struct Depsgraph *graph = CTX_data_depsgraph(C);
float fallback_depth_pt[3];
view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
@ -389,7 +391,7 @@ static void viewops_data_create(
negate_v3_v3(fallback_depth_pt, rv3d->ofs);
vod->use_dyn_ofs = ED_view3d_autodist(
graph, vod->ar, vod->v3d,
depsgraph, vod->ar, vod->v3d,
event->mval, vod->dyn_ofs, true, fallback_depth_pt);
}
else {
@ -397,7 +399,7 @@ static void viewops_data_create(
}
if (viewops_flag & VIEWOPS_FLAG_PERSP_ENSURE) {
if (ED_view3d_persp_ensure(vod->v3d, vod->ar)) {
if (ED_view3d_persp_ensure(depsgraph, vod->v3d, vod->ar)) {
/* If we're switching from camera view to the perspective one,
* need to tag viewport update, so camera vuew and borders
* are properly updated.
@ -408,7 +410,7 @@ static void viewops_data_create(
/* set the view from the camera, if view locking is enabled.
* we may want to make this optional but for now its needed always */
ED_view3d_camera_lock_init(vod->v3d, vod->rv3d);
ED_view3d_camera_lock_init(depsgraph, vod->v3d, vod->rv3d);
vod->init.dist = rv3d->dist;
vod->init.camzoom = rv3d->camzoom;
@ -811,7 +813,7 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
vod->prev.event_xy[0] = event_xy[0];
vod->prev.event_xy[1] = event_xy[1];
ED_view3d_camera_lock_sync(vod->v3d, rv3d);
ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, rv3d);
ED_region_tag_redraw(vod->ar);
}
@ -1112,6 +1114,7 @@ static void view3d_ndof_orbit(
/* optional, can be NULL*/
ViewOpsData *vod)
{
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
@ -1119,7 +1122,7 @@ static void view3d_ndof_orbit(
BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
ED_view3d_persp_ensure(v3d, ar);
ED_view3d_persp_ensure(depsgraph, v3d, ar);
rv3d->view = RV3D_VIEW_USER;
@ -1308,6 +1311,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
else {
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
ViewOpsData *vod;
View3D *v3d;
RegionView3D *rv3d;
@ -1328,7 +1332,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* off by default, until changed later this function */
rv3d->rot_angle = 0.0f;
ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
if (ndof->progress != P_FINISHING) {
const bool has_rotation = NDOF_HAS_ROTATE;
@ -1345,7 +1349,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
}
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_region_tag_redraw(vod->ar);
@ -1376,6 +1380,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
return OPERATOR_CANCELLED;
}
else {
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
ViewOpsData *vod;
View3D *v3d;
RegionView3D *rv3d;
@ -1397,7 +1402,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
/* off by default, until changed later this function */
rv3d->rot_angle = 0.0f;
ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
if (ndof->progress == P_FINISHING) {
/* pass */
@ -1446,7 +1451,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
ED_view3d_distance_set(rv3d, dist_backup);
}
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_region_tag_redraw(vod->ar);
@ -1480,6 +1485,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e
return OPERATOR_CANCELLED;
}
else {
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
const wmNDOFMotionData *ndof = event->customdata;
@ -1493,7 +1499,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e
if (!(has_translate || has_zoom))
return OPERATOR_CANCELLED;
ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
if (ndof->progress != P_FINISHING) {
ScrArea *sa = CTX_wm_area(C);
@ -1504,7 +1510,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e
}
}
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_region_tag_redraw(CTX_wm_region(C));
@ -1637,7 +1643,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
vod->prev.event_xy[0] = x;
vod->prev.event_xy[1] = y;
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
ED_region_tag_redraw(vod->ar);
}
@ -2036,7 +2042,7 @@ static void viewzoom_apply_3d(
view3d_boxview_sync(vod->sa, vod->ar);
}
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
ED_region_tag_redraw(vod->ar);
}
@ -2187,7 +2193,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
ED_view3d_depth_tag_update(rv3d);
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, true);
ED_region_tag_redraw(ar);
@ -2381,7 +2387,7 @@ static void viewdolly_apply(ViewOpsData *vod, const int xy[2], const short zoom_
view3d_boxview_sync(vod->sa, vod->ar);
}
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
ED_region_tag_redraw(vod->ar);
}
@ -2482,7 +2488,7 @@ static int viewdolly_exec(bContext *C, wmOperator *op)
ED_view3d_depth_tag_update(rv3d);
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(CTX_data_depsgraph(C), v3d, rv3d);
ED_region_tag_redraw(ar);
@ -2516,7 +2522,8 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (vod->rv3d->persp != RV3D_PERSP) {
if (vod->rv3d->persp == RV3D_CAMOB) {
/* ignore rv3d->lpersp because dolly only makes sense in perspective mode */
ED_view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, RV3D_PERSP);
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
ED_view3d_persp_switch_from_camera(depsgraph, vod->v3d, vod->rv3d, RV3D_PERSP);
}
else {
vod->rv3d->persp = RV3D_PERSP;
@ -3884,7 +3891,8 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
float quat_new[4];
if (view_opposite == RV3D_VIEW_USER) {
ED_view3d_persp_ensure(v3d, ar);
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
ED_view3d_persp_ensure(depsgraph, v3d, ar);
}
if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
@ -4009,7 +4017,7 @@ static void viewroll_apply(ViewOpsData *vod, int x, int UNUSED(y))
view3d_boxview_sync(vod->sa, vod->ar);
}
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
ED_region_tag_redraw(vod->ar);
}

View File

@ -395,14 +395,15 @@ void ED_view3d_lock_clear(View3D *v3d)
* sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera,
* otherwise switching out of camera view may jump to a different part of the scene.
*/
void ED_view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const char persp)
void ED_view3d_persp_switch_from_camera(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d, const char persp)
{
BLI_assert(rv3d->persp == RV3D_CAMOB);
BLI_assert(persp != RV3D_CAMOB);
if (v3d->camera) {
rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
rv3d->dist = ED_view3d_offset_distance(camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
@ -415,7 +416,7 @@ void ED_view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const c
*
* shared with NDOF.
*/
bool ED_view3d_persp_ensure(struct View3D *v3d, ARegion *ar)
bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *ar)
{
RegionView3D *rv3d = ar->regiondata;
const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
@ -429,7 +430,7 @@ bool ED_view3d_persp_ensure(struct View3D *v3d, ARegion *ar)
if (rv3d->persp == RV3D_CAMOB) {
/* If autopersp and previous view was an axis one, switch back to PERSP mode, else reuse previous mode. */
char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
ED_view3d_persp_switch_from_camera(v3d, rv3d, persp);
ED_view3d_persp_switch_from_camera(depsgraph, v3d, rv3d, persp);
}
else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
rv3d->persp = RV3D_PERSP;
@ -463,20 +464,21 @@ bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
* Apply the camera object transformation to the view-port.
* (needed so we can use regular view-port manipulation operators, that sync back to the camera).
*/
void ED_view3d_camera_lock_init_ex(View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
void ED_view3d_camera_lock_init_ex(const Depsgraph* depsgraph, View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
{
if (ED_view3d_camera_lock_check(v3d, rv3d)) {
Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
if (calc_dist) {
/* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
rv3d->dist = ED_view3d_offset_distance(camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
}
ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
ED_view3d_from_object(camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
}
void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
{
ED_view3d_camera_lock_init_ex(v3d, rv3d, true);
ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, true);
}
/**
@ -484,7 +486,7 @@ void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
*
* \return true if the camera is moved.
*/
bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
{
if (ED_view3d_camera_lock_check(v3d, rv3d)) {
ObjectTfmProtectedChannels obtfm;
@ -501,15 +503,17 @@ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
while (root_parent->parent) {
root_parent = root_parent->parent;
}
Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
Object *root_parent_eval = DEG_get_evaluated_object(depsgraph, root_parent);
ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
normalize_m4_m4(tmat, v3d->camera->obmat);
normalize_m4_m4(tmat, camera_eval->obmat);
invert_m4_m4(imat, tmat);
mul_m4_m4m4(diff_mat, view_mat, imat);
mul_m4_m4m4(parent_mat, diff_mat, root_parent->obmat);
mul_m4_m4m4(parent_mat, diff_mat, root_parent_eval->obmat);
BKE_object_tfm_protected_backup(root_parent, &obtfm);
BKE_object_apply_mat4(root_parent, parent_mat, true, false);
@ -526,7 +530,7 @@ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
/* always maintain the same scale */
const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
@ -1344,11 +1348,13 @@ void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist,
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist The view distance from ofs, normally from RegionView3D.dist.
*/
void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], const float dist)
void ED_view3d_to_object(const Depsgraph *depsgraph, Object *ob, const float ofs[3], const float quat[4], const float dist)
{
float mat[4][4];
ED_view3d_to_m4(mat, ofs, quat, dist);
BKE_object_apply_mat4(ob, mat, true, true);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv , true);
}
/** \} */

View File

@ -152,7 +152,7 @@ void ED_view3d_smooth_view_ex(
* we allow camera option locking to initialize the view settings from the camera.
*/
if (sview->camera == NULL && sview->camera_old == NULL) {
ED_view3d_camera_lock_init(v3d, rv3d);
ED_view3d_camera_lock_init(depsgraph, v3d, rv3d);
}
/* store the options we want to end with */
@ -264,7 +264,7 @@ void ED_view3d_smooth_view_ex(
rv3d->dist = sms.dst.dist;
v3d->lens = sms.dst.lens;
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
}
if (rv3d->viewlock & RV3D_BOXVIEW) {
@ -295,6 +295,7 @@ void ED_view3d_smooth_view(
/* only meant for timer usage */
static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool sync_boxview)
{
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
RegionView3D *rv3d = ar->regiondata;
struct SmoothView3DStore *sms = rv3d->sms;
float step, step_inv;
@ -315,7 +316,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool
else {
view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
@ -348,7 +349,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool
rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
@ -436,6 +437,7 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
{
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
View3D *v3d;
ARegion *ar;
RegionView3D *rv3d;
@ -449,7 +451,7 @@ static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag);