Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2010-05-06 23:54:43 +0400
committerJoseph Eagar <joeedh@gmail.com>2010-05-06 23:54:43 +0400
commit9610515b22dcf0450aca9c3794700380851753a9 (patch)
tree23b4be78bc917090113ca661259578629c527afe /source/blender/editors
parent6e3812d7bc645b0731cf17a0d7d82d1bdac7d678 (diff)
keyframe transform, both through dopesheet/action editor and graph editor, works a bit better with handles. handles now follow keyframes properly in frame snap mode, in situations where they would move (but the keyframe would not) in undesirable ways before. also hopefully fixed vector scope crash in image editor. and disabled snapping to seconds (ever); this can be a seperate option, silently switching to second snapping in frame snapping mode is absolutely evil. also, the action editor draws in hundredth of seconds, not seconds, so it didn't even work. Aligorith: I hope this code is ok, if not feel free to rewrite it.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/interface/interface_draw.c8
-rw-r--r--source/blender/editors/transform/transform.c47
-rw-r--r--source/blender/editors/transform/transform.h5
-rw-r--r--source/blender/editors/transform/transform_conversions.c112
-rw-r--r--source/blender/editors/transform/transform_generics.c15
5 files changed, 142 insertions, 45 deletions
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index aa111bffaa9..74324a244de 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1088,8 +1088,12 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti
glTranslatef(centerx, centery, 0.f);
glScalef(diam, diam, 0.f);
- glVertexPointer(2, GL_FLOAT, 0, scopes->vecscope);
- glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+
+ /*apparently this can sometimes be NULL? - joeedh*/
+ if (scopes) {
+ glVertexPointer(2, GL_FLOAT, 0, scopes->vecscope);
+ glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+ }
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 7c98ca44fba..7f0bc6627d2 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -202,17 +202,32 @@ void projectIntView(TransInfo *t, float *vec, int *adr)
UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1);
}
- else if(ELEM3(t->spacetype, SPACE_IPO, SPACE_NLA, SPACE_ACTION)) {
+ else if(t->spacetype == SPACE_ACTION) {
+ SpaceAction *sact = t->sa->spacedata.first;
int out[2] = {0, 0};
- UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1);
+ if (sact->flag & SACTION_DRAWTIME) {
+ //vec[0] = vec[0]/((t->scene->r.frs_sec / t->scene->r.frs_sec_base));
+
+ UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1);
+ } else {
+ UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1);
+ }
+
+ adr[0]= out[0];
+ adr[1]= out[1];
+ }
+ else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) {
+ int out[2] = {0, 0};
+
+ UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1);
adr[0]= out[0];
adr[1]= out[1];
}
else if(t->spacetype==SPACE_SEQ) { /* XXX not tested yet, but should work */
int out[2] = {0, 0};
- UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1);
+ UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out+1);
adr[0]= out[0];
adr[1]= out[1];
}
@@ -5285,12 +5300,12 @@ static short getAnimEdit_DrawTime(TransInfo *t)
/* This function is used by Animation Editor specific transform functions to do
* the Snap Keyframe to Nearest Frame/Marker
*/
-static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, AnimData *adt, short autosnap)
+static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, AnimData *adt, short autosnap)
{
/* snap key to nearest frame? */
if (autosnap == SACTSNAP_FRAME) {
const Scene *scene= t->scene;
- const short doTime= getAnimEdit_DrawTime(t);
+ const short doTime= 0; //XXX doesn't work - getAnimEdit_DrawTime(t);
const double secf= FPS;
double val;
@@ -5332,6 +5347,14 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, AnimData *adt, sho
else
*(td->val)= val;
}
+
+ if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) {
+ td2d->h1[0] = td2d->ih1[0] + *td->val - td->ival;
+ }
+
+ if ((td->flag & TD_MOVEHANDLE2) && td2d->h2) {
+ td2d->h2[0] = td2d->ih2[0] + *td->val - td->ival;
+ }
}
/* ----------------- Translation ----------------------- */
@@ -5394,6 +5417,7 @@ static void headerTimeTranslate(TransInfo *t, char *str)
static void applyTimeTranslate(TransInfo *t, float sval)
{
TransData *td = t->data;
+ TransData2D *td2d = t->data2d;
Scene *scene = t->scene;
int i;
@@ -5402,16 +5426,18 @@ static void applyTimeTranslate(TransInfo *t, float sval)
const short autosnap= getAnimEdit_SnapMode(t);
- float deltax, val;
+ float deltax, val, valprev;
/* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
- for (i = 0 ; i < t->total; i++, td++) {
+ for (i = 0 ; i < t->total; i++, td++, td2d++) {
/* it is assumed that td->extra is a pointer to the AnimData,
* whose active action is where this keyframe comes from
* (this is only valid when not in NLA)
*/
AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL;
+ valprev = *td->val;
+
/* check if any need to apply nla-mapping */
if (adt && t->spacetype != SPACE_SEQ) {
deltax = t->values[0];
@@ -5441,7 +5467,7 @@ static void applyTimeTranslate(TransInfo *t, float sval)
}
/* apply nearest snapping */
- doAnimEdit_SnapFrame(t, td, adt, autosnap);
+ doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
}
}
@@ -5652,6 +5678,7 @@ static void headerTimeScale(TransInfo *t, char *str) {
static void applyTimeScale(TransInfo *t) {
Scene *scene = t->scene;
TransData *td = t->data;
+ TransData2D *td2d = t->data2d;
int i;
const short autosnap= getAnimEdit_SnapMode(t);
@@ -5659,7 +5686,7 @@ static void applyTimeScale(TransInfo *t) {
const double secf= FPS;
- for (i = 0 ; i < t->total; i++, td++) {
+ for (i = 0 ; i < t->total; i++, td++, td2d++) {
/* it is assumed that td->extra is a pointer to the AnimData,
* whose active action is where this keyframe comes from
* (this is only valid when not in NLA)
@@ -5685,7 +5712,7 @@ static void applyTimeScale(TransInfo *t) {
*(td->val) += startx;
/* apply nearest snapping */
- doAnimEdit_SnapFrame(t, td, adt, autosnap);
+ doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
}
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index ef13634a6ae..c1e62eb563c 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -151,6 +151,9 @@ typedef struct TransDataExtension {
typedef struct TransData2D {
float loc[3]; /* Location of data used to transform (x,y,0) */
float *loc2d; /* Pointer to real 2d location of data */
+
+ float *h1, *h2; /* Pointer to handle locations, if handles aren't being moved independantly*/
+ float ih1[2], ih2[2];
} TransData2D;
/* we need to store 2 handles for each transdata incase the other handle wasnt selected */
@@ -427,6 +430,8 @@ typedef struct TransInfo {
#define TD_NOTIMESNAP (1 << 14) /* for Graph Editor autosnap, indicates that point should not undergo autosnapping */
#define TD_INTVALUES (1 << 15) /* for Graph Editor - curves that can only have int-values need their keyframes tagged with this */
#define TD_MIRROR_EDGE (1 << 16) /* For editmode mirror, clamp to x = 0 */
+#define TD_MOVEHANDLE1 (1 << 17) /* For fcurve handles, move them along with their keyframes */
+#define TD_MOVEHANDLE2 (1 << 18)
/* transsnap->status */
#define SNAP_FORCED 1
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 0e11058a244..3f9b6df0718 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2972,9 +2972,8 @@ static int count_fcurve_keys(FCurve *fcu, char side, float cfra)
bezt->f1 |= SELECT;
bezt->f3 |= SELECT;
- /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
- count += 3;
+ count += 1;
}
}
@@ -3023,9 +3022,10 @@ static void TimeToTransData(TransData *td, float *time, AnimData *adt)
* The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
* on the named side are used.
*/
-static TransData *FCurveToTransData(TransData *td, FCurve *fcu, AnimData *adt, char side, float cfra)
+static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FCurve *fcu, AnimData *adt, char side, float cfra)
{
BezTriple *bezt;
+ TransData2D *td2d = *td2dv;
int i;
if (fcu == NULL)
@@ -3036,19 +3036,24 @@ static TransData *FCurveToTransData(TransData *td, FCurve *fcu, AnimData *adt, c
if (BEZSELECTED(bezt)) {
/* only add if on the right 'side' of the current frame */
if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
- /* each control point needs to be added separetely */
- TimeToTransData(td, bezt->vec[0], adt);
- td++;
-
TimeToTransData(td, bezt->vec[1], adt);
- td++;
- TimeToTransData(td, bezt->vec[2], adt);
+ /*set flags to move handles as necassary*/
+ td->flag |= TD_MOVEHANDLE1|TD_MOVEHANDLE2;
+ td2d->h1 = bezt->vec[0];
+ td2d->h2 = bezt->vec[2];
+
+ VECCOPY2D(td2d->ih1, td2d->h1);
+ VECCOPY2D(td2d->ih2, td2d->h2);
+
td++;
+ td2d++;
}
}
}
+ *td2dv = td2d;
+
return td;
}
@@ -3116,6 +3121,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
{
Scene *scene= t->scene;
TransData *td = NULL;
+ TransData2D *td2d = NULL;
tGPFtransdata *tfd = NULL;
bAnimContext ac;
@@ -3179,7 +3185,9 @@ static void createTransActionData(bContext *C, TransInfo *t)
t->total= count;
t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(Action Editor)");
+ t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "transdata2d");
td= t->data;
+ td2d = t->data2d;
if (ac.datatype == ANIMCONT_GPENCIL) {
if (t->mode == TFM_TIME_SLIDE) {
@@ -3216,7 +3224,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
else
cfra = (float)CFRA;
- td= FCurveToTransData(td, fcu, adt, t->frame_side, cfra);
+ td= ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra);
//}
}
@@ -3248,8 +3256,11 @@ static void createTransActionData(bContext *C, TransInfo *t)
/* Helper function for createTransGraphEditData, which is reponsible for associating
* source data with transform data
*/
-static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, float *loc, float *cent, short selected, short ishandle, short intvals)
+static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, BezTriple *bezt, int bi, short selected, short ishandle, short intvals)
{
+ float *loc = bezt->vec[bi];
+ float *cent = bezt->vec[1];
+
/* New location from td gets dumped onto the old-location of td2d, which then
* gets copied to the actual data at td2d->loc2d (bezt->vec[n])
*
@@ -3280,7 +3291,17 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
VECCOPY(td->center, cent);
VECCOPY(td->iloc, td->loc);
}
-
+
+ if (td->flag & TD_MOVEHANDLE1) {
+ td2d->h1 = bezt->vec[0];
+ VECCOPY2D(td2d->ih1, td2d->h1);
+ } else td2d->h1 = NULL;
+
+ if (td->flag & TD_MOVEHANDLE2) {
+ td2d->h2 = bezt->vec[2];
+ VECCOPY2D(td2d->ih2, td2d->h2);
+ } else td2d->h2 = NULL;
+
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
@@ -3300,7 +3321,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
td->flag |= TD_NOTIMESNAP;
if (intvals)
td->flag |= TD_INTVALUES;
-
+
unit_m3(td->mtx);
unit_m3(td->smtx);
}
@@ -3362,11 +3383,11 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
/* F-Curve may not have any keyframes */
if (fcu->bezt == NULL)
continue;
-
+
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */
for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
- if (sipo->around == V3D_LOCAL) {
+ if (sipo->around == V3D_LOCAL && !ELEM(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE)) {
/* for local-pivot we only need to count the number of selected handles only, so that centerpoints don't
* don't get moved wrong
*/
@@ -3376,7 +3397,15 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
}
else if (bezt->f2 & SELECT) count++; // TODO: could this cause problems?
}
- else {
+ else if (ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE)) {
+ /* for 'normal' pivots - just include anything that is selected.
+ this works a bit differently in translation modes */
+ if (bezt->f2 & SELECT) count++;
+ else {
+ if (bezt->f1 & SELECT) count++;
+ if (bezt->f3 & SELECT) count++;
+ }
+ } else {
/* for 'normal' pivots - just include anything that is selected */
if (bezt->f1 & SELECT) count++;
if (bezt->f2 & SELECT) count++;
@@ -3429,23 +3458,32 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
TransDataCurveHandleFlags *hdata = NULL;
short h1=1, h2=1;
- /* only include handles if selected, irrespective of the interpolation modes */
- if (bezt->f1 & SELECT) {
- hdata = initTransDataCurveHandles(td, bezt);
- bezt_to_transdata(td++, td2d++, adt, bezt->vec[0], bezt->vec[1], 1, 1, intvals);
- }
- else
- h1= 0;
- if (bezt->f3 & SELECT) {
- if (hdata==NULL)
+ /* only include handles if selected, irrespective of the interpolation modes.
+ also, only treat handles specially if the center point isn't selected. */
+ if (!ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE) || !(bezt->f2 & SELECT)) {
+ if (bezt->f1 & SELECT) {
hdata = initTransDataCurveHandles(td, bezt);
- bezt_to_transdata(td++, td2d++, adt, bezt->vec[2], bezt->vec[1], 1, 1, intvals);
+ bezt_to_transdata(td++, td2d++, adt, bezt, 0, 1, 1, intvals);
+ } else
+ h1= 0;
+
+ if (bezt->f3 & SELECT) {
+ if (hdata==NULL)
+ hdata = initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, adt, bezt, 2, 1, 1, intvals);
+ } else
+ h2= 0;
}
- else
- h2= 0;
-
- /* only include main vert if selected */
+
if (bezt->f2 & SELECT) {
+ /*move handles relative to center*/
+ if (ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE)) {
+ if (bezt->f1 & SELECT) td->flag |= TD_MOVEHANDLE1;
+ if (bezt->f3 & SELECT) td->flag |= TD_MOVEHANDLE2;
+ }
+
+ /* only include main vert if selected */
+
/* if scaling around individuals centers, do not include keyframes */
if (sipo->around != V3D_LOCAL) {
/* if handles were not selected, store their selection status */
@@ -3454,7 +3492,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
hdata = initTransDataCurveHandles(td, bezt);
}
- bezt_to_transdata(td++, td2d++, adt, bezt->vec[1], bezt->vec[1], 1, 0, intvals);
+ bezt_to_transdata(td++, td2d++, adt, bezt, 1, 1, 0, intvals);
}
/* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...):
@@ -3700,7 +3738,7 @@ void flushTransGraphData(TransInfo *t)
break;
}
}
-
+
/* we need to unapply the nla-mapping from the time in some situations */
if (adt)
td2d->loc2d[0]= BKE_nla_tweakedit_remap(adt, td2d->loc[0], NLATIME_CONVERT_UNMAP);
@@ -3712,6 +3750,16 @@ void flushTransGraphData(TransInfo *t)
td2d->loc2d[1]= (float)((int)td2d->loc[1]);
else
td2d->loc2d[1]= td2d->loc[1];
+
+ if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) {
+ td2d->h1[0] = td2d->ih1[0] + td->loc[0] - td->iloc[0];
+ td2d->h1[1] = td2d->ih1[1] + td->loc[1] - td->iloc[1];
+ }
+
+ if ((td->flag & TD_MOVEHANDLE2) && td2d->h2) {
+ td2d->h2[0] = td2d->ih2[0] + td->loc[0] - td->iloc[0];
+ td2d->h2[1] = td2d->ih2[1] + td->loc[1] - td->iloc[1];
+ }
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 59961f5812c..99793f4010a 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1167,6 +1167,7 @@ static void restoreElement(TransData *td) {
if (td->val) {
*td->val = td->ival;
}
+
if (td->ext && (td->flag&TD_NO_EXT)==0) {
if (td->ext->rot) {
VECCOPY(td->ext->rot, td->ext->irot);
@@ -1188,11 +1189,23 @@ static void restoreElement(TransData *td) {
void restoreTransObjects(TransInfo *t)
{
TransData *td;
-
+ TransData2D *td2d;
+
for (td = t->data; td < t->data + t->total; td++) {
restoreElement(td);
}
+ for (td2d=t->data2d; t->data2d && td2d < t->data2d + t->total; td2d++) {
+ if (td2d->h1) {
+ td2d->h1[0] = td2d->ih1[0];
+ td2d->h1[1] = td2d->ih1[1];
+ }
+ if (td2d->h2) {
+ td2d->h2[0] = td2d->ih2[0];
+ td2d->h2[1] = td2d->ih2[1];
+ }
+ }
+
unit_m3(t->mat);
recalcData(t);