[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17217] branches/animsys2/source/blender/ src/drawipo.c: AnimSys2: IPO Drawing-Code (Part 1 of Cleanup)
Joshua Leung
aligorith at gmail.com
Wed Oct 29 12:25:14 CET 2008
Revision: 17217
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17217
Author: aligorith
Date: 2008-10-29 12:25:14 +0100 (Wed, 29 Oct 2008)
Log Message:
-----------
AnimSys2: IPO Drawing-Code (Part 1 of Cleanup)
Started cleaning up the drawing-code for IPO-curves.
* draw_ipocurves() has been cleaned up, with the inner loops being split out into two separate helper functions. The same will need to be done with some of the other functions too.
* Removed the ugly global pickselcode. This was only used in this file under certain conditions, so it seems fine to remove it.
* Usual formatting and commenting tweaks to make this code less intimidating. This is in preparation for some future work on IPO-curves...
Modified Paths:
--------------
branches/animsys2/source/blender/src/drawipo.c
Modified: branches/animsys2/source/blender/src/drawipo.c
===================================================================
--- branches/animsys2/source/blender/src/drawipo.c 2008-10-29 11:20:02 UTC (rev 17216)
+++ branches/animsys2/source/blender/src/drawipo.c 2008-10-29 11:25:14 UTC (rev 17217)
@@ -1341,237 +1341,297 @@
}
}
-int pickselcode;
-
-static void init_pickselcode(void)
+/* draw one repeat of an ipo-curve - bitflag curve only (this is evil stuff to expose to user like this) */
+static void draw_ipocurve_repeat_bits (IpoCurve *icu, float cycxofs)
{
- pickselcode= 1;
+ BezTriple *bezt= icu->bezt;
+ int a;
+
+ /* loop over each keyframe, drawing a line extending from that point */
+ for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
+ int val= (int)bezt->vec[1][1];
+ int b= 0;
+
+ /* for each bit in the int, draw a line if the keyframe incorporates it */
+ for (b = 0; b < 31; b++) {
+ if (val & (1<<b)) {
+ float v1[2];
+
+ /* value stays constant */
+ v1[1]= b+1;
+
+ glBegin(GL_LINE_STRIP);
+ /* extend left too if first keyframe, and not cyclic extrapolation */
+ if ((a == 0) && !(icu->extrap & IPO_CYCL)) {
+ v1[0]= G.v2d->cur.xmin+cycxofs;
+ glVertex2fv(v1);
+ }
+
+ /* must pass through current keyframe */
+ v1[0]= bezt->vec[1][0] + cycxofs;
+ glVertex2fv(v1);
+
+ /* 1. if there is a next keyframe, extend until then OR
+ * 2. extend until 'infinity' if not cyclic extrapolation
+ */
+ if ((a+1) < icu->totvert) v1[0]= (bezt+1)->vec[1][0]+cycxofs;
+ else if ((icu->extrap & IPO_CYCL)==0) v1[0]= G.v2d->cur.xmax+cycxofs;
+
+ glVertex2fv(v1);
+ glEnd();
+ }
+ }
+ }
}
+/* draw one repeat of an ipo-curve - normal curve */
+static void draw_ipocurve_repeat_normal (IpoCurve *icu, float cycxofs, float cycyofs, float *facp)
+{
+ BezTriple *prevbezt= icu->bezt;
+ BezTriple *bezt= prevbezt+1;
+ float v1[2], v2[2], v3[2], v4[2];
+ float *fp, data[120];
+ float fac= *(facp);
+ int b= icu->totvert-1;
+ int resol;
+
+ glBegin(GL_LINE_STRIP);
+
+ /* extrapolate to left? */
+ if ((icu->extrap & IPO_CYCL)==0) {
+ /* left-side of view comes before first keyframe, so need to extend as not cyclic */
+ if (prevbezt->vec[1][0] > G.v2d->cur.xmin) {
+ v1[0]= G.v2d->cur.xmin;
+
+ /* y-value depends on the interpolation */
+ if ((icu->extrap==IPO_HORIZ) || (icu->ipo==IPO_CONST) || (icu->totvert==1)) {
+ /* just extend across the first keyframe's value */
+ v1[1]= prevbezt->vec[1][1];
+ }
+ else if (icu->ipo==IPO_LIN) {
+ /* extrapolate linear dosnt use the handle, use the next points center instead */
+ fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]);
+ }
+ else {
+ /* based on angle of handle 1 (relative to keyframe) */
+ fac= (prevbezt->vec[0][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[0][1]-prevbezt->vec[1][1]);
+ }
+
+ glVertex2fv(v1);
+ }
+ }
+
+ /* if only one keyframe, add it now */
+ if (icu->totvert == 1) {
+ v1[0]= prevbezt->vec[1][0] + cycxofs;
+ v1[1]= prevbezt->vec[1][1] + cycyofs;
+ glVertex2fv(v1);
+ }
+
+ /* draw curve between first and last keyframe (if there are enough to do so) */
+ while (b--) {
+ // TODO: per segment interpolation still needs to be added here...
+ if (icu->ipo==IPO_CONST) {
+ /* Constant-Interpolation: draw segment between previous keyframe and next, but holding same value */
+ v1[0]= prevbezt->vec[1][0]+cycxofs;
+ v1[1]= prevbezt->vec[1][1]+cycyofs;
+ glVertex2fv(v1);
+
+ v1[0]= bezt->vec[1][0]+cycxofs;
+ v1[1]= prevbezt->vec[1][1]+cycyofs;
+ glVertex2fv(v1);
+ }
+ else if (icu->ipo==IPO_LIN) {
+ /* Linear interpolation: just add one point (which should add a new line segment) */
+ v1[0]= prevbezt->vec[1][0]+cycxofs;
+ v1[1]= prevbezt->vec[1][1]+cycyofs;
+ glVertex2fv(v1);
+ }
+ else {
+ /* Bezier-Interpolation: draw curve as series of segments between keyframes
+ * - resol determines number of points to sample in between keyframes
+ */
+
+ /* resol not depending on horizontal resolution anymore, drivers for example... */
+ if (icu->driver)
+ resol= 32;
+ else
+ resol= 3.0*sqrt(bezt->vec[1][0] - prevbezt->vec[1][0]);
+
+ if (resol < 2) {
+ /* only draw one */
+ v1[0]= prevbezt->vec[1][0]+cycxofs;
+ v1[1]= prevbezt->vec[1][1]+cycyofs;
+ glVertex2fv(v1);
+ }
+ else {
+ /* clamp resolution to max of 32 */
+ if (resol > 32) resol= 32;
+
+ v1[0]= prevbezt->vec[1][0]+cycxofs;
+ v1[1]= prevbezt->vec[1][1]+cycyofs;
+ v2[0]= prevbezt->vec[2][0]+cycxofs;
+ v2[1]= prevbezt->vec[2][1]+cycyofs;
+
+ v3[0]= bezt->vec[0][0]+cycxofs;
+ v3[1]= bezt->vec[0][1]+cycyofs;
+ v4[0]= bezt->vec[1][0]+cycxofs;
+ v4[1]= bezt->vec[1][1]+cycyofs;
+
+ correct_bezpart(v1, v2, v3, v4);
+
+ forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, 3);
+ forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data+1, resol, 3);
+
+ for (fp= data; resol; resol--, fp+= 3)
+ glVertex2fv(fp);
+ }
+ }
+
+ /* get next pointers */
+ prevbezt= bezt;
+ bezt++;
+
+ /* last point? */
+ if (b == 0) {
+ v1[0]= prevbezt->vec[1][0]+cycxofs;
+ v1[1]= prevbezt->vec[1][1]+cycyofs;
+ glVertex2fv(v1);
+ }
+ }
+
+ /* extrapolate to right? (see code for left-extrapolation above too) */
+ if ((icu->extrap & IPO_CYCL)==0) {
+ if(prevbezt->vec[1][0] < G.v2d->cur.xmax) {
+ v1[0]= G.v2d->cur.xmax;
+
+ /* y-value depends on the interpolation */
+ if ((icu->extrap==IPO_HORIZ) || (icu->ipo==IPO_CONST) || (icu->totvert==1)) {
+ /* based on last keyframe's value */
+ v1[1]= prevbezt->vec[1][1];
+ }
+ else if (icu->ipo==IPO_LIN) {
+ /* extrapolate linear dosnt use the handle, use the previous points center instead */
+ bezt = prevbezt-1;
+ fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]);
+ }
+ else {
+ /* based on angle of handle 1 (relative to keyframe) */
+ fac= (prevbezt->vec[2][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[2][1]-prevbezt->vec[1][1]);
+ }
+
+ glVertex2fv(v1);
+ }
+ }
+
+ glEnd();
+
+ /* return fac, as we alter it */
+ *(facp) = fac;
+}
+
+/* draw all ipo-curves */
static void draw_ipocurves(int sel)
{
EditIpo *ei;
- IpoCurve *icu;
- BezTriple *bezt, *prevbezt;
- float *fp, fac, data[120], v1[2], v2[2], v3[2], v4[2];
- float cycdx=0, cycdy=0, cycxofs, cycyofs;
- int a, b, resol, cycount, val, nr;
+ int nr, val, pickselcode=0;
+ /* if we're drawing for GL_SELECT, reset pickselcode first
+ * - there's only one place that will do this, so it should be fine
+ */
+ if (G.f & G_PICKSEL)
+ pickselcode= 1;
ei= G.sipo->editipo;
- for(nr=0; nr<G.sipo->totipo; nr++, ei++) {
+ for (nr=0; nr<G.sipo->totipo; nr++, ei++) {
if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) {
-
- if(G.f & G_PICKSEL) {
+ /* val is used to indicate if curve can be edited */
+ if (G.f & G_PICKSEL) {
+ /* when using OpenGL to select stuff (on mouseclick) */
glLoadName(pickselcode++);
val= 1;
}
else {
- val= (ei->flag & (IPO_SELECT+IPO_EDIT))!=0;
+ /* filter to only draw those that are selected or unselected (based on drawing mode */
+ val= (ei->flag & (IPO_SELECT+IPO_EDIT)) != 0;
val= (val==sel);
}
- if(val) {
+ /* only draw those curves that we can draw */
+ if (val) {
+ IpoCurve *icu= ei->icu;
+ float cycdx=0.0f, cycdy=0.0f, cycxofs=0.0f, cycyofs=0.0f;
+ const int lastindex= (icu->totvert-1);
+ float fac= 0.0f;
+ int cycount=1;
- cycyofs= cycxofs= 0.0;
- cycount= 1;
-
- icu= ei->icu;
-
- /* curve */
- if(G.sipo->showkey) BIF_ThemeColor(TH_TEXT);
+ /* set color for curve curve:
+ * - bitflag curves (evil) must always be drawn coloured as they cannot work with IPO-Keys
+ * - when IPO-Keys are shown, individual curves are not editable, so we show by drawing them all black
+ */
+ if ((G.sipo->showkey) && (ei->disptype!=IPO_DISPBITS)) BIF_ThemeColor(TH_TEXT);
else cpack(ei->col);
- /* cyclic */
- if(icu->extrap & IPO_CYCL) {
- cycdx= (icu->bezt+icu->totvert-1)->vec[1][0] - icu->bezt->vec[1][0];
- cycdy= (icu->bezt+icu->totvert-1)->vec[1][1] - icu->bezt->vec[1][1];
- if(cycdx>0.01) {
-
- while(icu->bezt->vec[1][0]+cycxofs > G.v2d->cur.xmin) {
- cycxofs-= cycdx;
- if(icu->extrap & IPO_DIR) cycyofs-= cycdy;
+ /* cyclic curves - get offset and number of repeats to display */
+ if (icu->extrap & IPO_CYCL) {
+ BezTriple *bezt= icu->bezt;
+ BezTriple *lastbezt= bezt + lastindex;
+
+ /* calculate cycle length and amplitude */
+ cycdx= lastbezt->vec[1][0] - bezt->vec[1][0];
+ cycdy= lastbezt->vec[1][1] - bezt->vec[1][1];
+
+ /* check that the cycle does have some length */
+ if (cycdx > 0.01) {
+ /* count cycles before first frame */
+ while (icu->bezt->vec[1][0]+cycxofs > G.v2d->cur.xmin) {
+ cycxofs -= cycdx;
+ if (icu->extrap & IPO_DIR) cycyofs-= cycdy;
cycount++;
}
- bezt= icu->bezt+(icu->totvert-1);
- fac= 0.0;
- while(bezt->vec[1][0]+fac < G.v2d->cur.xmax) {
+
+ /* count cycles after last frame (and adjust offset) */
+ fac= 0.0f;
+ while (lastbezt->vec[1][0]+fac < G.v2d->cur.xmax) {
cycount++;
- fac+= cycdx;
+ fac += cycdx;
}
}
}
- while(cycount--) {
+ /* repeat process for each repeat */
+ while (cycount--) {
+ /* bitflag curves are drawn differently to normal curves */
+ if (ei->disptype==IPO_DISPBITS)
+ draw_ipocurve_repeat_bits(icu, cycxofs);
+ else
+ draw_ipocurve_repeat_normal(icu, cycxofs, cycyofs, &fac);
- if(ei->disptype==IPO_DISPBITS) {
-
- /* lines */
- cpack(ei->col);
- bezt= icu->bezt;
- a= icu->totvert;
-
- while(a--) {
- val= bezt->vec[1][1];
- b= 0;
-
- while(b<31) {
- if(val & (1<<b)) {
- v1[1]= b+1;
-
- glBegin(GL_LINE_STRIP);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list