Fix T68250: Camera keyframing (Walk/Fly) despite canceling movement
Reviewers: campbellbarton (thx!) Maniphest Tasks: T68250 Differential Revision: https://developer.blender.org/D5418
This commit is contained in:
@@ -155,6 +155,8 @@ typedef struct FlyInfo {
|
||||
* without moving the direction there looking */
|
||||
bool use_freelook;
|
||||
|
||||
bool anim_playing; /* needed for autokeyframing */
|
||||
|
||||
int mval[2]; /* latest 2D mouse values */
|
||||
int center_mval[2]; /* center mouse values */
|
||||
float width, height; /* camera viewport dimensions */
|
||||
@@ -185,6 +187,9 @@ typedef struct FlyInfo {
|
||||
|
||||
} FlyInfo;
|
||||
|
||||
/* prototypes */
|
||||
static int flyApply(bContext *C, struct FlyInfo *fly, bool force_autokey);
|
||||
|
||||
static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
|
||||
{
|
||||
FlyInfo *fly = arg;
|
||||
@@ -261,6 +266,7 @@ enum {
|
||||
|
||||
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
rctf viewborder;
|
||||
|
||||
@@ -308,6 +314,7 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent
|
||||
fly->grid = 1.0f;
|
||||
fly->use_precision = false;
|
||||
fly->use_freelook = false;
|
||||
fly->anim_playing = ED_screen_animation_playing(wm);
|
||||
|
||||
#ifdef NDOF_FLY_DRAW_TOOMUCH
|
||||
fly->redraw = 1;
|
||||
@@ -374,6 +381,18 @@ static int flyEnd(bContext *C, FlyInfo *fly)
|
||||
if (fly->state == FLY_RUNNING) {
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
else if (fly->state == FLY_CONFIRM) {
|
||||
/* Needed for auto_keyframe. */
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
if (fly->ndof) {
|
||||
flyApply_ndof(C, fly, true);
|
||||
}
|
||||
else
|
||||
#endif /* WITH_INPUT_NDOF */
|
||||
{
|
||||
flyApply(C, fly, true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NDOF_FLY_DEBUG
|
||||
puts("\n-- fly end --");
|
||||
@@ -672,12 +691,19 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static void flyMoveCamera(bContext *C, 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,
|
||||
const bool is_confirm)
|
||||
{
|
||||
ED_view3d_cameracontrol_update(fly->v3d_camera_control, true, C, do_rotate, do_translate);
|
||||
/* we only consider autokeying on playback or if user confirmed fly on the same frame
|
||||
* otherwise we get a keyframe even if the user cancels. */
|
||||
const bool use_autokey = is_confirm || fly->anim_playing;
|
||||
ED_view3d_cameracontrol_update(fly->v3d_camera_control, use_autokey, C, do_rotate, do_translate);
|
||||
}
|
||||
|
||||
static int flyApply(bContext *C, FlyInfo *fly)
|
||||
static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
|
||||
{
|
||||
#define FLY_ROTATE_FAC 10.0f /* more is faster */
|
||||
#define FLY_ZUP_CORRECT_FAC 0.1f /* amount to correct per step */
|
||||
@@ -948,7 +974,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, fly, do_rotate, do_translate);
|
||||
flyMoveCamera(C, fly, do_rotate, do_translate, is_confirm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -980,7 +1006,7 @@ static void flyApply_ndof(bContext *C, FlyInfo *fly)
|
||||
fly->redraw = true;
|
||||
|
||||
if (fly->rv3d->persp == RV3D_CAMOB) {
|
||||
flyMoveCamera(C, fly, has_rotate, has_translate);
|
||||
flyMoveCamera(C, fly, has_rotate, has_translate, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1035,13 +1061,13 @@ static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
if (fly->ndof) { /* 3D mouse overrules [2D mouse + timer] */
|
||||
if (event->type == NDOF_MOTION) {
|
||||
flyApply_ndof(C, fly);
|
||||
flyApply_ndof(C, fly, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* WITH_INPUT_NDOF */
|
||||
if (event->type == TIMER && event->customdata == fly->timer) {
|
||||
flyApply(C, fly);
|
||||
flyApply(C, fly, false);
|
||||
}
|
||||
|
||||
do_draw |= fly->redraw;
|
||||
|
||||
@@ -65,9 +65,6 @@
|
||||
/* ensure the target position is one we can reach, see: T45771 */
|
||||
#define USE_PIXELSIZE_NATIVE_SUPPORT
|
||||
|
||||
/* prototypes */
|
||||
static float getVelocityZeroTime(const float gravity, const float velocity);
|
||||
|
||||
/* NOTE: these defines are saved in keymap files,
|
||||
* do not change values but just add new ones */
|
||||
enum {
|
||||
@@ -199,6 +196,8 @@ typedef struct WalkInfo {
|
||||
short state;
|
||||
bool redraw;
|
||||
|
||||
bool anim_playing; /* needed for autokeyframing */
|
||||
|
||||
int prev_mval[2]; /* previous 2D mouse values */
|
||||
int center_mval[2]; /* center mouse values */
|
||||
int moffset[2];
|
||||
@@ -264,6 +263,10 @@ typedef struct WalkInfo {
|
||||
|
||||
} WalkInfo;
|
||||
|
||||
/* prototypes */
|
||||
static int walkApply(bContext *C, struct WalkInfo *walk, bool force_autokey);
|
||||
static float getVelocityZeroTime(const float gravity, const float velocity);
|
||||
|
||||
static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg)
|
||||
{
|
||||
/* draws an aim/cross in the center */
|
||||
@@ -420,6 +423,7 @@ static float userdef_speed = -1.f;
|
||||
|
||||
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
@@ -512,6 +516,8 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
|
||||
walk->ndof = NULL;
|
||||
#endif
|
||||
|
||||
walk->anim_playing = ED_screen_animation_playing(wm);
|
||||
|
||||
walk->time_lastdraw = PIL_check_seconds_timer();
|
||||
|
||||
walk->draw_handle_pixel = ED_region_draw_cb_activate(
|
||||
@@ -563,6 +569,18 @@ static int walkEnd(bContext *C, WalkInfo *walk)
|
||||
if (walk->state == WALK_RUNNING) {
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
else if (walk->state == WALK_CONFIRM) {
|
||||
/* Needed for auto_keyframe. */
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
if (walk->ndof) {
|
||||
walkApply_ndof(C, walk, true);
|
||||
}
|
||||
else
|
||||
#endif /* WITH_INPUT_NDOF */
|
||||
{
|
||||
walkApply(C, walk, true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NDOF_WALK_DEBUG
|
||||
puts("\n-- walk end --");
|
||||
@@ -885,9 +903,15 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
|
||||
static void walkMoveCamera(bContext *C,
|
||||
WalkInfo *walk,
|
||||
const bool do_rotate,
|
||||
const bool do_translate)
|
||||
const bool do_translate,
|
||||
const bool is_confirm)
|
||||
{
|
||||
ED_view3d_cameracontrol_update(walk->v3d_camera_control, true, C, do_rotate, do_translate);
|
||||
/* we only consider autokeying on playback or if user confirmed walk on the same frame
|
||||
* otherwise we get a keyframe even if the user cancels. */
|
||||
const bool use_autokey = is_confirm || walk->anim_playing;
|
||||
|
||||
ED_view3d_cameracontrol_update(
|
||||
walk->v3d_camera_control, use_autokey, C, do_rotate, do_translate);
|
||||
}
|
||||
|
||||
static float getFreeFallDistance(const float gravity, const float time)
|
||||
@@ -900,7 +924,7 @@ static float getVelocityZeroTime(const float gravity, const float velocity)
|
||||
return velocity / gravity;
|
||||
}
|
||||
|
||||
static int walkApply(bContext *C, WalkInfo *walk)
|
||||
static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
|
||||
{
|
||||
#define WALK_ROTATE_FAC 2.2f /* more is faster */
|
||||
#define WALK_TOP_LIMIT DEG2RADF(85.0f)
|
||||
@@ -945,7 +969,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
|
||||
/* Should we redraw? */
|
||||
if ((walk->active_directions) || moffset[0] || moffset[1] ||
|
||||
walk->teleport.state == WALK_TELEPORT_STATE_ON ||
|
||||
walk->gravity_state != WALK_GRAVITY_STATE_OFF) {
|
||||
walk->gravity_state != WALK_GRAVITY_STATE_OFF || is_confirm) {
|
||||
float dvec_tmp[3];
|
||||
|
||||
/* time how fast it takes for us to redraw,
|
||||
@@ -1237,7 +1261,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
const bool do_rotate = (moffset[0] || moffset[1]);
|
||||
const bool do_translate = (walk->speed != 0.0f);
|
||||
walkMoveCamera(C, walk, do_rotate, do_translate);
|
||||
walkMoveCamera(C, walk, do_rotate, do_translate, is_confirm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1277,7 +1301,7 @@ static void walkApply_ndof(bContext *C, WalkInfo *walk)
|
||||
walk->redraw = true;
|
||||
|
||||
if (walk->rv3d->persp == RV3D_CAMOB) {
|
||||
walkMoveCamera(C, walk, has_rotate, has_translate);
|
||||
walkMoveCamera(C, walk, has_rotate, has_translate, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1333,13 +1357,13 @@ static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
if (walk->ndof) { /* 3D mouse overrules [2D mouse + timer] */
|
||||
if (event->type == NDOF_MOTION) {
|
||||
walkApply_ndof(C, walk);
|
||||
walkApply_ndof(C, walk, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* WITH_INPUT_NDOF */
|
||||
if (event->type == TIMER && event->customdata == walk->timer) {
|
||||
walkApply(C, walk);
|
||||
walkApply(C, walk, false);
|
||||
}
|
||||
|
||||
do_draw |= walk->redraw;
|
||||
|
||||
Reference in New Issue
Block a user