diff options
author | Joshua Leung <aligorith@gmail.com> | 2007-06-19 13:46:52 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2007-06-19 13:46:52 +0400 |
commit | 3caf086137d08be3285fcffd832ba9bc7f0bdb4f (patch) | |
tree | 6ba7a6ae1e0317ff36e68dd9d369779ba7c99b05 /source/blender/src/drawaction.c | |
parent | e3ed38be6bf201f2816374bae973c7f4535d7b87 (diff) |
== Action Editor - Long Keyframes ==
I've recoded the way long keyframes work a bit, so that more cases are handled accurately. Now, it takes into account the number of IPO-curves that have keyframes in them on the start/end frame of the long-keyframe, instead of just taking the total number of IPO-curves present for the channel being drawn.
Diffstat (limited to 'source/blender/src/drawaction.c')
-rw-r--r-- | source/blender/src/drawaction.c | 301 |
1 files changed, 176 insertions, 125 deletions
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 6576dac1d2c..f1aba590358 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -926,6 +926,8 @@ static void action_blockhandlers(ScrArea *sa) uiDrawBlocksPanels(sa, 0); } +/* ************************* Action Editor Space ***************************** */ + void drawactionspace(ScrArea *sa, void *spacedata) { short ofsx = 0, ofsy = 0; @@ -1077,9 +1079,131 @@ void drawactionspace(ScrArea *sa, void *spacedata) curarea->win_swap= WIN_BACK_OK; } -static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos, int totcurve) +/* *************************** Keyframe Drawing *************************** */ + +static void add_bezt_to_keycolumnslist(ListBase *keys, BezTriple *bezt) +{ + /* The equivilant of add_to_cfra_elem except this version + * makes ActKeyColumns - one of the two datatypes required + * for action editor drawing. + */ + ActKeyColumn *ak, *akn; + + if (!(keys) || !(bezt)) return; + + /* try to find a keyblock that starts on the previous beztriple */ + for (ak= keys->first; ak; ak= ak->next) { + /* do because of double keys */ + if (ak->cfra == bezt->vec[1][0]) { + /* set selection status and 'touched' status */ + if (BEZSELECTED(bezt)) ak->sel = SELECT; + ak->modified += 1; + + return; + } + else if (ak->cfra > bezt->vec[1][0]) break; + } + + /* add new block */ + akn= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn"); + if (ak) BLI_insertlinkbefore(keys, ak, akn); + else BLI_addtail(keys, akn); + + akn->cfra= bezt->vec[1][0]; + akn->modified += 1; + + // TODO: handle type = bezt->h1 or bezt->h2 + akn->handle_type= 0; + + if (BEZSELECTED(bezt)) + akn->sel = SELECT; + else + akn->sel = 0; +} + +static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index) +{ + /* The equivilant of add_to_cfra_elem except this version + * makes ActKeyBlocks - one of the two datatypes required + * for action editor drawing. + */ + ActKeyBlock *ab, *abn; + BezTriple *beztn=NULL, *prev=NULL; + BezTriple *bezt; + int v; + + /* get beztriples */ + beztn= (icu->bezt + index); + + for (v=0, bezt=icu->bezt; v<icu->totvert; v++, bezt++) { + /* skip if beztriple is current */ + if (v != index) { + /* check if beztriple is immediately before */ + if (beztn->vec[1][0] > bezt->vec[1][0]) { + /* check if closer than previous was */ + if (prev) { + if (prev->vec[1][0] < bezt->vec[1][0]) + prev= bezt; + } + else { + prev= bezt; + } + } + } + } + + /* check if block needed - same value? */ + if ((!prev) || (!beztn)) + return; + if (beztn->vec[1][1] != prev->vec[1][1]) + return; + + /* try to find a keyblock that starts on the previous beztriple */ + for (ab= blocks->first; ab; ab= ab->next) { + /* check if alter existing block or add new block */ + if (ab->start == prev->vec[1][0]) { + /* set selection status and 'touched' status */ + if (BEZSELECTED(beztn)) ab->sel = SELECT; + ab->modified += 1; + + return; + } + else if (ab->start > prev->vec[1][0]) break; + } + + /* add new block */ + abn= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock"); + if (ab) BLI_insertlinkbefore(blocks, ab, abn); + else BLI_addtail(blocks, abn); + + abn->start= prev->vec[1][0]; + abn->end= beztn->vec[1][0]; + abn->val= beztn->vec[1][1]; + + if (BEZSELECTED(prev) || BEZSELECTED(beztn)) + abn->sel = SELECT; + abn->modified = 1; +} + +/* helper function - find actkeycolumn that occurs on cframe */ +static ActKeyColumn *cfra_find_actkeycolumn (ListBase *keys, float cframe) { - CfraElem *ce; + ActKeyColumn *ak; + + if (keys==NULL) + return NULL; + + for (ak= keys->first; ak; ak= ak->next) { + if (ak->cfra == cframe) + return ak; + } + + return NULL; +} + +static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos) +{ + ActKeyColumn *ak; ActKeyBlock *ab; glEnable(GL_BLEND); @@ -1087,8 +1211,22 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl /* draw keyblocks */ if (blocks) { for (ab= blocks->first; ab; ab= ab->next) { - /* only draw keyblock if it appears in all curves sampled */ - if (ab->totcurve == totcurve) { + short startCurves, endCurves, totCurves; + + /* find out how many curves occur at each keyframe */ + ak= cfra_find_actkeycolumn(keys, ab->start); + startCurves = (ak)? ak->totcurve: 0; + + ak= cfra_find_actkeycolumn(keys, ab->end); + endCurves = (ak)? ak->totcurve: 0; + + /* only draw keyblock if it appears in at all of the keyframes at lowest end */ + if (!startCurves && !endCurves) + continue; + else + totCurves = (startCurves>endCurves)? endCurves: startCurves; + + if (ab->totcurve >= totCurves) { int sc_xa, sc_ya; int sc_xb, sc_yb; @@ -1108,13 +1246,13 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl /* draw keys */ if (keys) { - for (ce= keys->first; ce; ce= ce->next) { + for (ak= keys->first; ak; ak= ak->next) { int sc_x, sc_y; /* get co-ordinate to draw at */ - gla2DDrawTranslatePt(di, ce->cfra, ypos, &sc_x, &sc_y); + gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y); - if(ce->sel & 1) BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE2, 1.0f); + if(ak->sel & 1) BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE2, 1.0f); else BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE3, 1.0f); } } @@ -1126,10 +1264,9 @@ void draw_object_channel(gla2DDrawInfo *di, Object *ob, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; - int totcurve; - totcurve= ob_to_keylist(ob, &keys, &blocks); - draw_keylist(di, &keys, &blocks, ypos, totcurve); + ob_to_keylist(ob, &keys, &blocks); + draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); BLI_freelistN(&blocks); @@ -1139,10 +1276,9 @@ void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, float ypos) { ListBase keys = {0, 0}; ListBase blocks = {0, 0}; - int totcurve; - totcurve= ipo_to_keylist(ipo, &keys, &blocks); - draw_keylist(di, &keys, &blocks, ypos, totcurve); + ipo_to_keylist(ipo, &keys, &blocks); + draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); BLI_freelistN(&blocks); @@ -1154,7 +1290,7 @@ void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, float ypos) ListBase blocks = {0, 0}; icu_to_keylist(icu, &keys, &blocks); - draw_keylist(di, &keys, &blocks, ypos, 1); + draw_keylist(di, &keys, &blocks, ypos); BLI_freelistN(&keys); BLI_freelistN(&blocks); @@ -1165,116 +1301,35 @@ void draw_action_channel(gla2DDrawInfo *di, bAction *act, float ypos) ListBase keys = {0, 0}; action_to_keylist(act, &keys, NULL); - draw_keylist(di, &keys, NULL, ypos, 0); + draw_keylist(di, &keys, NULL, ypos); BLI_freelistN(&keys); } -static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index) -{ - /* The equivilant of add_to_cfra_elem except this version - * makes ActKeyBlocks - one of the two datatypes required - * for action editor drawing. - */ - ActKeyBlock *ab, *abn; - BezTriple *beztn=NULL, *prev=NULL; - BezTriple *bezt; - int v; - - /* get beztriples */ - beztn= (icu->bezt + index); - /* The following search for previous beztriple doesn't work - * that great on actions with a large amount of keys. There - * are a few commented out shortcuts for these cases, which will - * remain so until the definitive point where slowdown starts to - * bite is determined. - */ - //if (icu->totvert > 3500) { - // if (index >= 1) - // prev= (icu->bezt + (index - 1)); - //} - //else { - for (v=0, bezt=icu->bezt; v<icu->totvert; v++, bezt++) { - /* skip if beztriple is current */ - if (v != index) { - /* check if beztriple is immediately before */ - if (beztn->vec[1][0] > bezt->vec[1][0]) { - /* check if closer than previous was */ - if (prev) { - if (prev->vec[1][0] < bezt->vec[1][0]) - prev= bezt; - } - else { - prev= bezt; - } - } - } - } - //} - - /* check if block needed - same value? */ - if ((!prev) || (!beztn)) - return; - if (beztn->vec[1][1] != prev->vec[1][1]) - return; - - /* try to find a keyblock that starts on the previous beztriple */ - for (ab= blocks->first; ab; ab= ab->next) { - /* check if alter existing block or add new block */ - if (ab->start == prev->vec[1][0]) { - /* set selection status and 'touched' status */ - if (BEZSELECTED(beztn)) ab->sel = SELECT; - ab->modified += 1; - - return; - } - else if (ab->start > prev->vec[1][0]) break; - } - - /* add new block */ - abn= MEM_callocN(sizeof(ActKeyBlock), "add_bezt_to_keyblockslist"); - if (ab) BLI_insertlinkbefore(blocks, ab, abn); - else BLI_addtail(blocks, abn); - - abn->start= prev->vec[1][0]; - abn->end= beztn->vec[1][0]; - abn->val= beztn->vec[1][1]; - - if (BEZSELECTED(prev) || BEZSELECTED(beztn)) - abn->sel = SELECT; - else - abn->sel = 0; - abn->modified += 1; -} - -int ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks) +void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks) { bConstraintChannel *conchan; - int totcurve = 0; if (ob) { /* Add object keyframes */ - if (ob->ipo) { - totcurve += ipo_to_keylist(ob->ipo, keys, blocks); - } + if (ob->ipo) + ipo_to_keylist(ob->ipo, keys, blocks); /* Add constraint keyframes */ for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next){ - if(conchan->ipo) { - totcurve += ipo_to_keylist(conchan->ipo, keys, blocks); - } + if(conchan->ipo) + ipo_to_keylist(conchan->ipo, keys, blocks); } /* Add object data keyframes */ // TODO?? } - - return totcurve; } void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) { BezTriple *bezt; - ActKeyBlock *ab, *abn; + ActKeyColumn *ak; + ActKeyBlock *ab; int v; if (icu && icu->totvert) { @@ -1282,15 +1337,21 @@ void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) bezt= icu->bezt; for (v=0; v<icu->totvert; v++, bezt++) { - add_to_cfra_elem(keys, bezt); + add_bezt_to_keycolumnslist(keys, bezt); if (blocks) add_bezt_to_keyblockslist(blocks, icu, v); } - /* update the number of curves the blocks have appeared in */ + /* update the number of curves that elements have appeared in */ + if (keys) { + for (ak= keys->first; ak; ak= ak->next) { + if (ak->modified) { + ak->modified = 0; + ak->totcurve += 1; + } + } + } if (blocks) { - for (ab= blocks->first; ab; ab= abn) { - abn= ab->next; - + for (ab= blocks->first; ab; ab= ab->next) { if (ab->modified) { ab->modified = 0; ab->totcurve += 1; @@ -1300,44 +1361,34 @@ void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks) } } -int ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks) +void ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks) { IpoCurve *icu; - int totcurve = 0; if (ipo) { - for (icu= ipo->curve.first; icu; icu= icu->next) { + for (icu= ipo->curve.first; icu; icu= icu->next) icu_to_keylist(icu, keys, blocks); - totcurve++; - } } - - return totcurve; } -int action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks) +void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks) { bActionChannel *achan; bConstraintChannel *conchan; - int totcurve = 0; if (act) { /* loop through action channels */ for (achan= act->chanbase.first; achan; achan= achan->next) { /* firstly, add keys from action channel's ipo block */ - if (achan->ipo) { - totcurve+= ipo_to_keylist(achan->ipo, keys, blocks); - } + if (achan->ipo) + ipo_to_keylist(achan->ipo, keys, blocks); /* then, add keys from constraint channels */ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) { - if (conchan->ipo) { - totcurve+= ipo_to_keylist(achan->ipo, keys, blocks); - } + if (conchan->ipo) + ipo_to_keylist(achan->ipo, keys, blocks); } } } - - return totcurve; } |