forked from bartvdbraak/blender
== Action Editor -> Auto-Snap ==
There's a new selection-box on the header of the action editor, which sets the mode of auto-snapping for transforms. By default auto-snapping is off. There are 3 modes of auto-snap: * Off - transforms per normal * Frame Step - grid-step transform (may have errors with scaled actions) * Nearest Frame - true snap-to-frame (takes into account nla-scaling) These translate to the following hotkeys when transforming: * Off - no keys press/held (as it's always been) * Frame Step - Ctrl (as it's always been) * Nearest Frame - Shift (replaces old shift-key behaviour which was not useful)
This commit is contained in:
parent
9b3862b4c0
commit
970dbb2e79
@ -116,7 +116,7 @@ typedef struct SpaceAction {
|
||||
|
||||
View2D v2d;
|
||||
bAction *action;
|
||||
int flag;
|
||||
short flag, autosnap;
|
||||
short pin, actnr, lock, actwidth;
|
||||
float timeslide;
|
||||
} SpaceAction;
|
||||
@ -132,6 +132,11 @@ typedef struct SpaceAction {
|
||||
#define SACTION_MOVING 1 /* during transform */
|
||||
#define SACTION_SLIDERS 2 /* show sliders (if relevant) - limited to shape keys for now */
|
||||
|
||||
/* SpaceAction AutoSnap Settings */
|
||||
#define SACTSNAP_OFF 0 /* no auto-snap */
|
||||
#define SACTSNAP_STEP 1 /* snap to 1.0 frame intervals */
|
||||
#define SACTSNAP_FRAME 2 /* snap to actual frames (nla-action time) */
|
||||
|
||||
/* Pose->flag */
|
||||
#define POSE_RECALC 1
|
||||
#define POSE_LOCKED 2
|
||||
|
@ -1092,6 +1092,27 @@ void transform_actionchannel_keys(int mode, int dummy)
|
||||
if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
|
||||
PIL_sleep_ms(1);
|
||||
} else {
|
||||
short autosnap= 0;
|
||||
|
||||
/* determine mode of keyframe snapping/autosnap */
|
||||
if (mode != 't') {
|
||||
switch (G.saction->autosnap) {
|
||||
case SACTSNAP_OFF:
|
||||
if (G.qual == LR_CTRLKEY)
|
||||
autosnap= SACTSNAP_STEP;
|
||||
else if (G.qual == LR_SHIFTKEY)
|
||||
autosnap= SACTSNAP_FRAME;
|
||||
else
|
||||
autosnap= SACTSNAP_OFF;
|
||||
break;
|
||||
case SACTSNAP_STEP:
|
||||
autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_STEP;
|
||||
break;
|
||||
case SACTSNAP_FRAME:
|
||||
autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<tvtot; i++){
|
||||
tv[i].loc[0]=tv[i].oldloc[0];
|
||||
@ -1113,11 +1134,14 @@ void transform_actionchannel_keys(int mode, int dummy)
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
deltax = cval[0]-sval[0];
|
||||
deltax = cval[0] - sval[0];
|
||||
fac= deltax;
|
||||
|
||||
apply_keyb_grid(&fac, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID);
|
||||
|
||||
if (autosnap == SACTSNAP_STEP) {
|
||||
/* NOTE: this doesn't take into account NLA scaling */
|
||||
fac= 1.0f*floor(fac/1.0f + 0.5f);
|
||||
}
|
||||
|
||||
tv[i].loc[0]+=fac;
|
||||
break;
|
||||
case 's':
|
||||
@ -1125,8 +1149,11 @@ void transform_actionchannel_keys(int mode, int dummy)
|
||||
deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
|
||||
fac= fabs(deltax/startx);
|
||||
|
||||
apply_keyb_grid(&fac, 0.0, 0.2, 0.1, U.flag & USER_AUTOSIZEGRID);
|
||||
|
||||
if (autosnap == SACTSNAP_STEP) {
|
||||
/* NOTE: this doesn't take into account NLA scaling */
|
||||
fac= 1.0f*floor(fac/1.0f + 0.5f);
|
||||
}
|
||||
|
||||
if (invert){
|
||||
if (i % 03 == 0){
|
||||
memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i+2].oldloc));
|
||||
@ -1147,6 +1174,26 @@ void transform_actionchannel_keys(int mode, int dummy)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* snap key to nearest frame? */
|
||||
if (autosnap == SACTSNAP_FRAME) {
|
||||
float snapval;
|
||||
|
||||
/* convert frame to nla-action time (if needed) */
|
||||
if (G.saction->pin==0 && OBACT)
|
||||
snapval= get_action_frame_inv(OBACT, tv[i].loc[0]);
|
||||
else
|
||||
snapval= tv[i].loc[0];
|
||||
|
||||
/* snap to nearest frame */
|
||||
snapval= (float)(floor(snapval+0.5));
|
||||
|
||||
/* convert frame out of nla-action time */
|
||||
if (G.saction->pin==0 && OBACT)
|
||||
tv[i].loc[0]= get_action_frame(OBACT, snapval);
|
||||
else
|
||||
tv[i].loc[0]= snapval;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode=='s'){
|
||||
@ -1308,6 +1355,28 @@ void transform_meshchannel_keys(char mode, Key *key)
|
||||
if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
|
||||
PIL_sleep_ms(1);
|
||||
} else {
|
||||
short autosnap= 0;
|
||||
|
||||
/* determine mode of keyframe snapping/autosnap */
|
||||
if (mode != 't') {
|
||||
switch (G.saction->autosnap) {
|
||||
case SACTSNAP_OFF:
|
||||
if (G.qual == LR_CTRLKEY)
|
||||
autosnap= SACTSNAP_STEP;
|
||||
else if (G.qual == LR_SHIFTKEY)
|
||||
autosnap= SACTSNAP_FRAME;
|
||||
else
|
||||
autosnap= SACTSNAP_OFF;
|
||||
break;
|
||||
case SACTSNAP_STEP:
|
||||
autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
|
||||
break;
|
||||
case SACTSNAP_FRAME:
|
||||
autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<tvtot; i++){
|
||||
tv[i].loc[0]=tv[i].oldloc[0];
|
||||
|
||||
@ -1316,8 +1385,10 @@ void transform_meshchannel_keys(char mode, Key *key)
|
||||
deltax = cval[0]-sval[0];
|
||||
fac= deltax;
|
||||
|
||||
apply_keyb_grid(&fac, 0.0, 1.0, 0.1,
|
||||
U.flag & USER_AUTOGRABGRID);
|
||||
if (autosnap == SACTSNAP_STEP) {
|
||||
/* NOTE: this doesn't take into account NLA scaling */
|
||||
fac= 1.0f*floor(fac/1.0f + 0.5f);
|
||||
}
|
||||
|
||||
tv[i].loc[0]+=fac;
|
||||
break;
|
||||
@ -1328,8 +1399,10 @@ void transform_meshchannel_keys(char mode, Key *key)
|
||||
-curarea->winrct.xmin)/2);
|
||||
fac= fabs(deltax/startx);
|
||||
|
||||
apply_keyb_grid(&fac, 0.0, 0.2, 0.1,
|
||||
U.flag & USER_AUTOSIZEGRID);
|
||||
if (autosnap == SACTSNAP_FRAME) {
|
||||
/* NOTE: this doesn't take into account NLA scaling */
|
||||
fac= 1.0f*floor(fac/1.0f + 0.5f);
|
||||
}
|
||||
|
||||
if (invert){
|
||||
if (i % 03 == 0){
|
||||
@ -1351,6 +1424,11 @@ void transform_meshchannel_keys(char mode, Key *key)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* auto-snap key to nearest frame? */
|
||||
if (autosnap == SACTSNAP_FRAME) {
|
||||
tv[i].loc[0]= (float)(floor(tv[i].loc[0]+0.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Display a message showing the magnitude of
|
||||
|
@ -1270,14 +1270,23 @@ void action_buttons(void)
|
||||
|
||||
uiClearButLock();
|
||||
|
||||
/* draw LOCK */
|
||||
/* draw AUTOSNAP */
|
||||
xco+= 8;
|
||||
|
||||
uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF,
|
||||
"Auto-Snap Keys %t|Off %x0|Frame Step %x1|Nearest Frame %x2",
|
||||
xco,0,XIC+10,YIC, &(G.saction->autosnap), 0, 1, 0, 0,
|
||||
"Auto-snapping mode for keys when transforming");
|
||||
|
||||
xco+= (XIC + 18);
|
||||
|
||||
/* draw LOCK*/
|
||||
|
||||
uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco, 0, XIC, YIC,
|
||||
&(G.saction->lock), 0, 0, 0, 0,
|
||||
"Updates other affected window spaces automatically "
|
||||
"to reflect changes in real time");
|
||||
|
||||
|
||||
/* always as last */
|
||||
curarea->headbutlen = xco + 2*XIC;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user