Page Menu
Home
Search
Configure Global Search
Log In
Files
F5351
actnlaperf2.patch
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Adriano Macchietto (macchiea)
Nov 13 2013, 1:22 PM
Size
12 KB
Subscribers
None
actnlaperf2.patch
View Options
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
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
3f/31/d4f6b5f09973916371411219c6e3
Event Timeline
Log In to Comment