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:
Diffstat (limited to 'source/blender/src/drawaction.c')
-rw-r--r--source/blender/src/drawaction.c583
1 files changed, 583 insertions, 0 deletions
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
new file mode 100644
index 00000000000..77319e5804b
--- /dev/null
+++ b/source/blender/src/drawaction.c
@@ -0,0 +1,583 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Drawing routines for the Action window type
+ */
+
+/* System includes ----------------------------------------------------- */
+
+#include <math.h>
+#include <stdlib.h>
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BMF_Api.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+/* Types --------------------------------------------------------------- */
+#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_constraint_types.h"
+
+#include "BKE_action.h"
+#include "BKE_global.h"
+
+/* Everything from source (BIF, BDR, BSE) ------------------------------ */
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+#include "BIF_resources.h"
+#include "BIF_screen.h"
+#include "BIF_interface.h"
+#include "BIF_mywindow.h"
+
+#include "BDR_editcurve.h"
+#include "BSE_view.h"
+#include "BSE_drawipo.h"
+#include "BSE_editaction_types.h"
+#include "BDR_drawaction.h"
+
+/* 'old' stuff": defines and types, and own include -------------------- */
+
+#include "blendef.h"
+
+/* local functions ----------------------------------------------------- */
+void drawactionspace(void);
+static void draw_channel_names(void);
+static void draw_channel_strips(SpaceAction *saction);
+int count_action_levels(bAction *act);
+static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert);
+static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert);
+static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert);
+static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos);
+
+
+/* implementation ------------------------------------------------------ */
+void draw_cfra_action(void)
+{
+ Object *ob;
+ float vec[2];
+
+ vec[0]= (G.scene->r.cfra);
+ vec[0]*= G.scene->r.framelen;
+
+ vec[1]= G.v2d->cur.ymin;
+ glColor3ub(0x60, 0xc0, 0x40);
+ glLineWidth(2.0);
+
+ glBegin(GL_LINE_STRIP);
+ glVertex2fv(vec);
+ vec[1]= G.v2d->cur.ymax;
+ glVertex2fv(vec);
+ glEnd();
+
+ ob= (G.scene->basact) ? (G.scene->basact->object) : 0;
+ if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
+ vec[0]-= ob->sf;
+
+ glColor3ub(0x10, 0x60, 0);
+
+ glBegin(GL_LINE_STRIP);
+ glVertex2fv(vec);
+ vec[1]= G.v2d->cur.ymin;
+ glVertex2fv(vec);
+ glEnd();
+ }
+
+ glLineWidth(1.0);
+}
+
+static void draw_channel_names(void)
+{
+ short ofsx, ofsy = 0;
+
+ bAction *act;
+ bActionChannel *chan;
+ bConstraintChannel *conchan;
+ float x, y;
+
+ myortho2 (0, ACTWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax); // Scaling
+
+ /* Blank out the area */
+ if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
+ if(G.v2d->scroll) {
+ ofsx= curarea->winrct.xmin;
+ ofsy= curarea->winrct.ymin;
+ glViewport(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, ACTWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB));
+ glScissor(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, ACTWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB));
+ }
+ }
+
+ glClearColor(.8, .8, .8, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* Clip to the scrollable area */
+
+ glColor3ub(0x00, 0x00, 0x00);
+
+ act=G.saction->action;
+ x = 0.0;
+
+ if (act) {
+ y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
+
+ for (chan=act->chanbase.first; chan; chan=chan->next){
+ glColor3ub(0xAA, 0xAA, 0xAA);
+ glRectf(x, y-CHANNELHEIGHT/2, (float)ACTWIDTH, y+CHANNELHEIGHT/2);
+
+ if (chan->flag & ACHAN_SELECTED)
+ glColor3ub(255, 255, 255);
+ else
+ glColor3ub(0, 0, 0);
+ glRasterPos2f(x+8, y-4);
+ BMF_DrawString(G.font, chan->name);
+ y-=CHANNELHEIGHT+CHANNELSKIP;
+
+ /* Draw constraint channels */
+ for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
+ if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
+ glColor3ub(255, 255, 255);
+ else
+ glColor3ub(0, 0, 0);
+
+ glRasterPos2f(x+32, y-4);
+ BMF_DrawString(G.font, conchan->name);
+ y-=CHANNELHEIGHT+CHANNELSKIP;
+ }
+ }
+ }
+
+
+ myortho2 (0, ACTWIDTH, 0, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); // Scaling
+
+ glShadeModel(GL_SMOOTH);
+
+ y=9;
+
+ /* Draw sexy shaded block thingies */
+ glEnable (GL_BLEND);
+ glBegin(GL_QUAD_STRIP);
+ glColor4ub (0xCC,0xCC,0xCC,0x00);
+ glVertex2f (0,SCROLLB*2-y);
+ glVertex2f (ACTWIDTH,SCROLLB*2-y);
+
+ glColor4ub (0xCC,0xCC,0xCC,0xFF);
+ glVertex2f (0,SCROLLB-y);
+ glVertex2f (ACTWIDTH,SCROLLB-y);
+
+ glColor4ub (0xCC,0xCC,0xCC,0xFF);
+ glVertex2f (0,0-y);
+ glVertex2f (ACTWIDTH,0-y);
+
+ glEnd();
+
+/* y=( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB);
+
+ glBegin(GL_QUAD_STRIP);
+ glColor4ub (0x88,0x88,0x88,0xFF);
+ glVertex2f (0,y);
+ glVertex2f (ACTWIDTH,y);
+ glColor4ub (0x88,0x88,0x88,0x00);
+ glVertex2f (0,y-SCROLLB);
+ glVertex2f (ACTWIDTH,y-SCROLLB);
+
+ glEnd();
+*/
+ glDisable (GL_BLEND);
+
+ glShadeModel(GL_FLAT);
+
+}
+
+int count_action_levels(bAction *act)
+{
+ int y=0;
+ bActionChannel *achan;
+
+ if (!act)
+ return 0;
+
+ for (achan=act->chanbase.first; achan; achan=achan->next){
+ y+=1;
+ y+=BLI_countlist(&achan->constraintChannels);
+ }
+
+ return y;
+}
+ /** Draw a nicely beveled button (in screen space) */
+void draw_bevel_but(int x, int y, int w, int h, int sel)
+{
+ int xmin= x, ymin= y;
+ int xmax= x+w-1, ymax= y+h-1;
+ int i;
+
+ glColor3ub(0,0,0);
+ glBegin(GL_LINE_LOOP);
+ glVertex2i(xmin, ymin);
+ glVertex2i(xmax, ymin);
+ glVertex2i(xmax, ymax);
+ glVertex2i(xmin, ymax);
+ glEnd();
+
+ glBegin(GL_LINE_LOOP);
+ if (sel) glColor3ub(0xD0, 0x7E, 0x06);
+ else glColor3ub(0x8C, 0x8C, 0x8C);
+ glVertex2i(xmax-1, ymin+1);
+ glVertex2i(xmax-1, ymax-1);
+ if (sel) glColor3ub(0xF4, 0xEE, 0x8E);
+ else glColor3ub(0xDF, 0xDF, 0xDF);
+ glVertex2i(xmin+1, ymax-1);
+ glVertex2i(xmin+1, ymin+1);
+ glEnd();
+
+ if (sel) glColor3ub(0xF1, 0xCA, 0x13);
+ else glColor3ub(0xAC, 0xAC, 0xAC);
+ glBegin(GL_LINES);
+ for (i=xmin+2; i<=xmax-2; i++) {
+ glVertex2f(i, ymin+2);
+ glVertex2f(i, ymax-1);
+ }
+ glEnd();
+}
+
+static void draw_channel_strips(SpaceAction *saction)
+{
+ rcti scr_rct;
+ gla2DDrawInfo *di;
+ bAction *act;
+ bActionChannel *chan;
+ bConstraintChannel *conchan;
+ float y;
+
+ act= saction->action;
+ if (!act)
+ return;
+
+ scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH;
+ scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin-SCROLLB;
+ scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
+ scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax;
+ di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
+
+ y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
+
+ for (chan=act->chanbase.first; chan; chan=chan->next){
+ int frame1_x, channel_y;
+
+ gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
+
+ glEnable(GL_BLEND);
+ if (chan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x22);
+ else glColor4b(0x55, 0x22, 0x11, 0x22);
+ glRectf(0, channel_y-CHANNELHEIGHT/2, frame1_x, channel_y+CHANNELHEIGHT/2);
+
+ if (chan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x44);
+ else glColor4b(0x55, 0x22, 0x11, 0x44);
+ glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
+ glDisable(GL_BLEND);
+
+ draw_ipo_channel(di, chan->ipo, 0, y);
+
+ /* Increment the step */
+ y-=CHANNELHEIGHT+CHANNELSKIP;
+
+
+ /* Draw constraint channels */
+ for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
+ gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
+ glEnable(GL_BLEND);
+ if (conchan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x22);
+ else glColor4b(0x55, 0x22, 0x11, 0x22);
+ glRectf(0, channel_y-CHANNELHEIGHT/2+4, frame1_x, channel_y+CHANNELHEIGHT/2-4);
+
+ if (conchan->flag & ACHAN_SELECTED) glColor4b(0x11, 0x22, 0x55, 0x44);
+ else glColor4b(0x55, 0x22, 0x11, 0x44);
+ glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4);
+ glDisable(GL_BLEND);
+
+ draw_ipo_channel(di, conchan->ipo, 0, y);
+ y-=CHANNELHEIGHT+CHANNELSKIP;
+ }
+ }
+
+ glaEnd2DDraw(di);
+}
+
+void drawactionspace(void)
+{
+
+ short ofsx = 0, ofsy = 0;
+
+ if (!G.saction)
+ return;
+
+
+ if (!G.saction->pin) {
+ if (OBACT)
+ G.saction->action = OBACT->action;
+ else
+ G.saction->action=NULL;
+ }
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
+
+ calc_scrollrcts(G.v2d, curarea->winx, curarea->winy);
+
+ if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
+ if(G.v2d->scroll) {
+ ofsx= curarea->winrct.xmin;
+ ofsy= curarea->winrct.ymin;
+ glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
+ glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
+ }
+ }
+
+ glClearColor(.45, .45, .45, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+
+ /* Draw backdrop */
+ calc_ipogrid();
+ draw_ipogrid();
+
+ /* Draw channel strips */
+ draw_channel_strips(G.saction);
+
+ /* Draw current frame */
+ glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
+ glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
+ myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+ draw_cfra_action();
+
+ /* Draw scroll */
+ mywinset(curarea->win);
+ if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
+ myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5);
+ if(G.v2d->scroll) drawscroll(0);
+ }
+
+ /* Draw channel names */
+ draw_channel_names();
+
+ curarea->win_swap= WIN_BACK_OK;
+}
+
+void draw_channel_name(const char* name, short type, float ypos, int selected)
+{
+}
+
+static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos)
+{
+ int v;
+
+ if (!blist)
+ return;
+
+ for (v = 0; v<totvert; v++){
+ if (v==0 || (blist[v]->vec[1][0] != blist[v-1]->vec[1][0])){
+ int sc_x, sc_y;
+ gla2DDrawTranslatePt(di, blist[v]->vec[1][0], ypos, &sc_x, &sc_y);
+ draw_bevel_but(sc_x-2, sc_y-5, 7, 13, (blist[v]->f2 & 1));
+ }
+ }
+}
+
+void draw_object_channel(gla2DDrawInfo *di, Object *ob, int flags, float ypos)
+{
+ BezTriple **blist;
+ int totvert;
+
+ blist = ob_to_keylist(ob, flags, &totvert);
+ if (blist){
+ draw_keylist(di,totvert, blist, ypos);
+ MEM_freeN(blist);
+ }
+}
+
+void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, int flags, float ypos)
+{
+ BezTriple **blist;
+ int totvert;
+
+ blist = ipo_to_keylist(ipo, flags, &totvert);
+ if (blist){
+ draw_keylist(di,totvert, blist, ypos);
+ MEM_freeN(blist);
+ }
+}
+
+void draw_action_channel(gla2DDrawInfo *di, bAction *act, int flags, float ypos)
+{
+ BezTriple **blist;
+ int totvert;
+
+ blist = action_to_keylist(act, flags, &totvert);
+ if (blist){
+ draw_keylist(di,totvert, blist, ypos);
+ MEM_freeN(blist);
+ }
+}
+
+static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert)
+{
+ IpoCurve *icu;
+ int v, count=0;
+
+ BezTriple **list = NULL;
+
+ if (ob){
+
+ /* Count Object Keys */
+ if (ob->ipo){
+ for (icu=ob->ipo->curve.first; icu; icu=icu->next){
+ count+=icu->totvert;
+ }
+ }
+
+ /* Count Constraint Keys */
+ /* Count object data keys */
+
+ /* Build the list */
+ if (count){
+ list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
+ count=0;
+
+ /* Add object keyframes */
+ for (icu=ob->ipo->curve.first; icu; icu=icu->next){
+ for (v=0; v<icu->totvert; v++){
+ list[count++]=&icu->bezt[v];
+ }
+ }
+
+ /* Add constraint keyframes */
+ /* Add object data keyframes */
+
+ /* Sort */
+ qsort(list, count, sizeof(BezTriple*), bezt_compare);
+ }
+ }
+ (*totvert)=count;
+ return list;
+}
+
+static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert)
+{
+ IpoCurve *icu;
+ int v, count=0;
+
+ BezTriple **list = NULL;
+
+ if (ipo){
+ /* Count required keys */
+ for (icu=ipo->curve.first; icu; icu=icu->next){
+ count+=icu->totvert;
+ }
+
+ /* Build the list */
+ if (count){
+ list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
+ count=0;
+
+ for (icu=ipo->curve.first; icu; icu=icu->next){
+ for (v=0; v<icu->totvert; v++){
+ list[count++]=&icu->bezt[v];
+ }
+ }
+ qsort(list, count, sizeof(BezTriple*), bezt_compare);
+ }
+ }
+ (*totvert)=count;
+ return list;
+}
+
+static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert)
+{
+ IpoCurve *icu;
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+ int v, count=0;
+
+ BezTriple **list = NULL;
+
+ if (act){
+ /* Count required keys */
+ for (achan=act->chanbase.first; achan; achan=achan->next){
+ /* Count transformation keys */
+ for (icu=achan->ipo->curve.first; icu; icu=icu->next)
+ count+=icu->totvert;
+
+ /* Count constraint keys */
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
+ count+=icu->totvert;
+
+
+ }
+
+ /* Build the list */
+ if (count){
+ list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
+ count=0;
+
+ for (achan=act->chanbase.first; achan; achan=achan->next){
+ /* Add transformation keys */
+ for (icu=achan->ipo->curve.first; icu; icu=icu->next){
+ for (v=0; v<icu->totvert; v++)
+ list[count++]=&icu->bezt[v];
+ }
+
+ /* Add constraint keys */
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
+ for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
+ for (v=0; v<icu->totvert; v++)
+ list[count++]=&icu->bezt[v];
+ }
+
+ }
+ qsort(list, count, sizeof(BezTriple*), bezt_compare);
+
+ }
+ }
+ (*totvert)=count;
+ return list;
+}
+