Page MenuHome

actnlaperf2.patch

actnlaperf2.patch

Index: source/blender/src/drawaction.c
===================================================================
--- source/blender/src/drawaction.c (revision 13599)
+++ source/blender/src/drawaction.c (working copy)
@@ -98,6 +98,8 @@
#include "interface.h"
#include "mydevice.h"
+#include <GL/gl.h>
+
/********************************** Slider Stuff **************************** */
/* sliders for shapekeys */
@@ -1194,197 +1196,288 @@
abn->modified = 1;
}
-/* helper function - find actkeycolumn that occurs on cframe */
-static ActKeyColumn *cfra_find_actkeycolumn (ListBase *keys, float cframe)
+static ActKeysInc *init_aki_data()
{
- ActKeyColumn *ak;
+ static ActKeysInc aki;
- if (keys==NULL)
+ /* init data of static struct here */
+ if ((curarea->spacetype == SPACE_ACTION) && NLA_ACTION_SCALED)
+ aki.ob= OBACT;
+ else if (curarea->spacetype == SPACE_NLA)
+ aki.ob= NULL; // FIXME
+ else
+ aki.ob= NULL;
+
+ aki.start= G.v2d->cur.xmin - 10;
+ aki.end= G.v2d->cur.xmax + 10;
+
+ /* only pass pointer for Action Editor if enabled (for now) */
+ if ((curarea->spacetype == SPACE_ACTION) && (G.saction->flag & SACTION_HORIZOPTIMISEON))
+ return &aki;
+ else
return NULL;
-
- for (ak= keys->first; ak; ak= ak->next) {
- if (ak->cfra == cframe)
- return ak;
+}
+
+static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt)
+{
+ /* when aki == NULL, we don't care about range */
+ if (aki == NULL)
+ return 1;
+
+ /* if nla-scaling is in effect, apply appropriate scaling adjustments */
+ if (aki->ob) {
+ float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]);
+ return IN_RANGE(frame, aki->start, aki->end);
}
-
- return NULL;
+ else {
+ /* check if in range */
+ return IN_RANGE(bezt->vec[1][0], aki->start, aki->end);
+ }
}
-/* Draw a simple diamond shape with a filled in center (in screen space) */
-static void draw_key_but(int x, int y, short w, short h, int sel)
+void draw_object_channel(gla2DDrawInfo *di, Object *ob, float ypos)
{
- int xmin= x, ymin= y;
- int xmax= x+w-1, ymax= y+h-1;
- int xc= (xmin+xmax)/2, yc= (ymin+ymax)/2;
+ bConstraintChannel *conchan;
+
+ if (ob) {
+ /* draw object keyframes */
+ if (ob->ipo)
+ draw_ipo_channel(di, ob->ipo, ypos);
+
+ /* draw constraint keyframes */
+ for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (conchan->ipo)
+ draw_ipo_channel(di, conchan->ipo, ypos);
+ }
+ }
+}
+
+/* finds the first key before t using a binary search */
+int find_key(IpoCurve* icu, float t)
+{
+ int lbound = 0;
+ int ubound = icu->totvert;
+ int idx = 0;
+ int diff;
- /* interior - hardcoded colours (for selected and unselected only) */
- if (sel) glColor3ub(0xF1, 0xCA, 0x13);
- else glColor3ub(0xE9, 0xE9, 0xE9);
+ /* handle common trivial scenarios */
+ if (t < icu->bezt[idx].vec[1][0]) {
+ return 0;
+ }
+ if (t > icu->bezt[icu->totvert - 1].vec[1][0]) {
+ return icu->totvert - 1;
+ }
- glBegin(GL_QUADS);
- glVertex2i(xc, ymin);
- glVertex2i(xmax, yc);
- glVertex2i(xc, ymax);
- glVertex2i(xmin, yc);
- glEnd();
+ while (ubound - lbound > 1) {
+ diff = (ubound - lbound) / 2;
+ idx = lbound + diff;
+
+ if (icu->bezt[idx].vec[1][0] < t) {
+ lbound += diff;
+ } else {
+ ubound = lbound + diff;
+ }
+ }
-
- /* outline */
- glColor3ub(0, 0, 0);
-
- glBegin(GL_LINE_LOOP);
- glVertex2i(xc, ymin);
- glVertex2i(xmax, yc);
- glVertex2i(xc, ymax);
- glVertex2i(xmin, yc);
- glEnd();
+ return idx;
}
-static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos)
+/* batch draw all of the keyframes in an ipo curve using GL_QUADS */
+void draw_icu_keyframes(gla2DDrawInfo *di, ActKeysInc *aki, IpoCurve* icu, float ypos, int selected)
{
- ActKeyColumn *ak;
- ActKeyBlock *ab;
+ BezTriple *bezt;
+ int v;
+ int sc_x, sc_y;
+ int last_sc_x = -1;
+ int start, end;
+ const int keysize = 4;
+ const int bordsize = keysize + 1;
+
+ if (!icu || !icu->totvert) {
+ return;
+ }
- glEnable(GL_BLEND);
+ /* find the first visible start key and the last visible end key */
+ if (aki == NULL) {
+ start = 0;
+ end = icu->totvert - 1;
+ } else if (aki->ob) {
+ start = find_key(icu, get_action_frame(aki->ob, aki->start));
+ end = find_key(icu, get_action_frame(aki->ob, aki->end));
+ } else {
+ start = find_key(icu, aki->start);
+ end = find_key(icu, aki->end);
+ }
- /* draw keyblocks */
- if (blocks) {
- for (ab= blocks->first; ab; ab= ab->next) {
- short startCurves, endCurves, totCurves;
+ gla2DDrawTranslatePt(di, icu->bezt[start].vec[1][0], ypos, &sc_x, &sc_y);
+ last_sc_x = sc_x - 2;
+
+ /* for efficiency we need to batch draw the all the keyframe borders first */
+ glColor3ub(0, 0, 0);
+ glBegin(GL_QUADS);
+ for (v=start; v<= end; v++) {
+ bezt = &icu->bezt[v];
+ if(BEZSELECTED(bezt) == selected) {
+ gla2DDrawTranslatePt(di, bezt->vec[1][0], ypos, &sc_x, &sc_y);
- /* 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;
-
- /* get co-ordinates of block */
- gla2DDrawTranslatePt(di, ab->start, ypos, &sc_xa, &sc_ya);
- gla2DDrawTranslatePt(di, ab->end, ypos, &sc_xb, &sc_yb);
-
- /* draw block */
- if (ab->sel)
- BIF_ThemeColor4(TH_STRIP_SELECT);
- else
- BIF_ThemeColor4(TH_STRIP);
- glRectf(sc_xa, sc_ya-3, sc_xb, sc_yb+5);
+ /* avoid redrawing over the same pixels */
+ if (sc_x - last_sc_x > 1) {
+ glVertex2i(sc_x, sc_y - bordsize);
+ glVertex2i(sc_x + bordsize, sc_y);
+ glVertex2i(sc_x, sc_y + bordsize);
+ glVertex2i(sc_x - bordsize, sc_y);
+ last_sc_x = sc_x;
}
}
}
+ glEnd();
- /* draw keys */
- if (keys) {
- for (ak= keys->first; ak; ak= ak->next) {
- int sc_x, sc_y;
+ gla2DDrawTranslatePt(di, icu->bezt[start].vec[1][0], ypos, &sc_x, &sc_y);
+ last_sc_x = sc_x - 2;
+
+ if (selected) {
+ glColor3ub(0xF1, 0xCA, 0x13);
+ } else {
+ glColor3ub(0xE9, 0xE9, 0xE9);
+ }
+
+ /* draw the yellow keyframe cores */
+ glBegin(GL_QUADS);
+ for (v = start; v <= end; v++) {
+ bezt = &icu->bezt[v];
+ if(BEZSELECTED(bezt) == selected) {
+ gla2DDrawTranslatePt(di, bezt->vec[1][0], ypos, &sc_x, &sc_y);
- /* get co-ordinate to draw at */
- gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y);
-
- /* draw using icons - old way which is slower but more proven */
- //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);
-
- /* draw using OpenGL - slightly uglier but faster */
- draw_key_but(sc_x-5, sc_y-4, 11, 11, (ak->sel & SELECT));
- }
+ if (sc_x - last_sc_x > 1) {
+ glVertex2i(sc_x, sc_y - keysize);
+ glVertex2i(sc_x + keysize, sc_y);
+ glVertex2i(sc_x, sc_y + keysize);
+ glVertex2i(sc_x - keysize, sc_y);
+ last_sc_x = sc_x;
+ }
+ }
}
-
- glDisable(GL_BLEND);
+ glEnd();
}
-
-static ActKeysInc *init_aki_data()
+void draw_block(gla2DDrawInfo *di, float tstart, float tend, float ypos, int selected)
{
- static ActKeysInc aki;
+ int sc_xa, sc_ya;
+ int sc_xb, sc_yb;
+ gla2DDrawTranslatePt(di, tstart, ypos, &sc_xa, &sc_ya);
+ gla2DDrawTranslatePt(di, tend, ypos, &sc_xb, &sc_yb);
- /* init data of static struct here */
- if ((curarea->spacetype == SPACE_ACTION) && NLA_ACTION_SCALED)
- aki.ob= OBACT;
- else if (curarea->spacetype == SPACE_NLA)
- aki.ob= NULL; // FIXME
- else
- aki.ob= NULL;
-
- aki.start= G.v2d->cur.xmin - 10;
- aki.end= G.v2d->cur.xmax + 10;
-
- /* only pass pointer for Action Editor if enabled (for now) */
- if ((curarea->spacetype == SPACE_ACTION) && (G.saction->flag & SACTION_HORIZOPTIMISEON))
- return &aki;
- else
- return NULL;
+ if (selected) {
+ BIF_ThemeColor4(TH_STRIP_SELECT);
+ } else {
+ BIF_ThemeColor4(TH_STRIP);
+ }
+ glRectf(sc_xa + 1, sc_ya-2, sc_xb - 1, sc_yb+2);
}
-void draw_object_channel(gla2DDrawInfo *di, Object *ob, float ypos)
+void draw_icu_keyblocks(gla2DDrawInfo *di, ActKeysInc *aki, IpoCurve* icu, float ypos)
{
- ListBase keys = {0, 0};
- ListBase blocks = {0, 0};
- ActKeysInc *aki = init_aki_data();
-
- ob_to_keylist(ob, &keys, &blocks, aki);
- draw_keylist(di, &keys, &blocks, ypos);
+ BezTriple *bezt = icu->bezt;
+ BezTriple *kbstart, *kbend, *prev;
+ int v;
+ int selected = 0;
- BLI_freelistN(&keys);
- BLI_freelistN(&blocks);
+ kbstart = kbend = bezt;
+ bezt++;
+ for (v=1; v<icu->totvert + 1; v++, bezt++) {
+ kbend = bezt;
+ prev = kbend - 1;
+
+ if (BEZSELECTED(prev)) {
+ selected = 1;
+ }
+
+ if (v == icu->totvert ||
+ IS_EQ(kbend->vec[1][1], prev->vec[1][1]) == 0 ||
+ IS_EQ(kbend->vec[1][1], kbend->vec[0][1]) == 0 ||
+ IS_EQ(prev->vec[1][1], prev->vec[2][1]) == 0
+ ) {
+
+ if (kbstart < prev) {
+ draw_block(di, kbstart->vec[1][0], prev->vec[1][0], ypos, selected);
+ }
+
+ kbstart = kbend = bezt;
+ selected = 0;
+ }
+ }
}
-void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, float ypos)
+void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, float ypos)
{
- ListBase keys = {0, 0};
- ListBase blocks = {0, 0};
ActKeysInc *aki = init_aki_data();
- ipo_to_keylist(ipo, &keys, &blocks, aki);
- draw_keylist(di, &keys, &blocks, ypos);
-
- BLI_freelistN(&keys);
- BLI_freelistN(&blocks);
+ draw_icu_keyblocks(di, aki, icu, ypos);
+ draw_icu_keyframes(di, aki, icu, ypos, 0);
+ draw_icu_keyframes(di, aki, icu, ypos, 1);
}
-void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, float ypos)
+void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, float ypos)
{
- ListBase keys = {0, 0};
- ListBase blocks = {0, 0};
+ IpoCurve *icu;
ActKeysInc *aki = init_aki_data();
-
- icu_to_keylist(icu, &keys, &blocks, aki);
- draw_keylist(di, &keys, &blocks, ypos);
- BLI_freelistN(&keys);
- BLI_freelistN(&blocks);
+ if (ipo) {
+ /* draw blocks */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ draw_icu_keyblocks(di, aki, icu, ypos);
+ }
+ /* draw unselected */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ draw_icu_keyframes(di, aki, icu, ypos, 0);
+ }
+ /* draw selected */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ draw_icu_keyframes(di, aki, icu, ypos, 1);
+ }
+ }
}
void draw_agroup_channel(gla2DDrawInfo *di, bActionGroup *agrp, float ypos)
-{
- ListBase keys = {0, 0};
- ListBase blocks = {0, 0};
- ActKeysInc *aki = init_aki_data();
+{
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
- agroup_to_keylist(agrp, &keys, &blocks, aki);
- draw_keylist(di, &keys, &blocks, ypos);
- BLI_freelistN(&keys);
- BLI_freelistN(&blocks);
+ if (agrp) {
+ /* loop through action channels */
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ /* firstly, add keys from action channel's ipo block */
+ if (achan->ipo)
+ draw_ipo_channel(di, achan->ipo, ypos);
+
+ /* then, add keys from constraint channels */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo)
+ draw_ipo_channel(di, conchan->ipo, ypos);
+ }
+ }
+ }
}
void draw_action_channel(gla2DDrawInfo *di, bAction *act, float ypos)
{
- ListBase keys = {0, 0};
- ActKeysInc *aki = init_aki_data();
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
- action_to_keylist(act, &keys, NULL, aki);
- draw_keylist(di, &keys, NULL, ypos);
- BLI_freelistN(&keys);
+ 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)
+ draw_ipo_channel(di, achan->ipo, ypos);
+
+ /* then, add keys from constraint channels */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo)
+ draw_ipo_channel(di, conchan->ipo, ypos);
+ }
+ }
+ }
}
/* --------------- Conversion: data -> keyframe list ------------------ */
@@ -1409,23 +1502,6 @@
}
}
-static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt)
-{
- /* when aki == NULL, we don't care about range */
- if (aki == NULL)
- return 1;
-
- /* if nla-scaling is in effect, apply appropriate scaling adjustments */
- if (aki->ob) {
- float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]);
- return IN_RANGE(frame, aki->start, aki->end);
- }
- else {
- /* check if in range */
- return IN_RANGE(bezt->vec[1][0], aki->start, aki->end);
- }
-}
-
void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
{
BezTriple *bezt;

File Metadata

Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
3f/31/d4f6b5f09973916371411219c6e3

Event Timeline