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:
authorChris Want <cwant@ualberta.ca>2003-07-21 03:04:09 +0400
committerChris Want <cwant@ualberta.ca>2003-07-21 03:04:09 +0400
commitcf495e6655de7e7dce5115d487460a33fcb8b488 (patch)
tree88c14a4ba94f610ccf909bd68af4b0f786cee4e6
parent9a9cb5448b090ff88c6c46fec312c7f98941c248 (diff)
Support for using the action window as a tool for modifying
(mesh or lattice) RVK IpoCurves: support currently includes: - RVK sliders. Pressing the little triangle next to the word 'sliders' in the channel names opens them up. - NKEY in the area where the key block names are allows the user to change the name of the keyblock, and the max and min values of the RVK sliders. - ability to visualize the keyframes for the IpoCurves when the object is selected. - right mouse can be used to select the keys - border select in the main area can be used to border select keys. - AKEY selects/deselects all of the keys - GKEY and SKEY can be used to grab or scale the key selections. - XKEY deletes the selected keys. - DKEY duplicated the selected keys. - VKEY, HKEY and shift-HKEY change the bezier handles for the selected keys. Please, please, please test!
-rw-r--r--source/blender/include/BSE_editaction.h6
-rw-r--r--source/blender/include/BSE_editaction_types.h3
-rw-r--r--source/blender/include/BSE_editipo.h4
-rw-r--r--source/blender/makesdna/DNA_key_types.h5
-rw-r--r--source/blender/src/drawaction.c475
-rw-r--r--source/blender/src/drawipo.c2
-rw-r--r--source/blender/src/editaction.c872
-rw-r--r--source/blender/src/editipo.c2
-rw-r--r--source/blender/src/editkey.c207
-rw-r--r--source/blender/src/headerbuttons.c22
-rw-r--r--source/blender/src/toolbox.c6
11 files changed, 1415 insertions, 189 deletions
diff --git a/source/blender/include/BSE_editaction.h b/source/blender/include/BSE_editaction.h
index 5e88ba90bf2..13539c111f0 100644
--- a/source/blender/include/BSE_editaction.h
+++ b/source/blender/include/BSE_editaction.h
@@ -39,6 +39,7 @@ struct bPoseChannel;
struct Object;
struct Ipo;
struct BWinEvent;
+struct Key;
struct bActionChannel* get_hilighted_action_channel(struct bAction* action);
void set_exprap_action(int mode);
@@ -49,10 +50,13 @@ void set_action_key (struct bAction *act, struct bPoseChannel *chan, int adrcode
struct bAction *add_empty_action(void);
void deselect_actionchannel_keys (struct bAction *act, int test);
void deselect_actionchannels (struct bAction *act, int test);
+void deselect_meshchannel_keys (struct Key *key, int test);
void winqreadactionspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
void remake_action_ipos(struct bAction *act);
void select_actionchannel_by_name (struct bAction *act, char *name, int select);
struct bAction *bake_action_with_client (struct bAction *act, struct Object *arm, float tolerance);
-
+struct Key *get_action_mesh_key(void);
+int get_nearest_key_num(struct Key *key, short *mval, float *x);
+void stupid_damn_numbuts_action(void);
#endif /* BSE_EDITACTION_H */
diff --git a/source/blender/include/BSE_editaction_types.h b/source/blender/include/BSE_editaction_types.h
index 16e4890daef..4df6c6712fb 100644
--- a/source/blender/include/BSE_editaction_types.h
+++ b/source/blender/include/BSE_editaction_types.h
@@ -35,7 +35,8 @@
#define CHANNELHEIGHT 16
#define CHANNELSKIP 2
-#define ACTWIDTH 128
+#define NAMEWIDTH 128
+#define SLIDERWIDTH 125
#define CHANNEL_FILTER_LOC 0x00000001 /* Show location keys */
#define CHANNEL_FILTER_ROT 0x00000002 /* Show rotation keys */
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index 3522056f21e..9ae57db0a22 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -90,6 +90,7 @@ void move_to_frame(void);
void do_ipowin_buts(short event);
void do_ipo_selectbuttons(void);
struct EditIpo *get_editipo(void);
+struct Ipo *get_ipo(struct ID *from, short type, int make);
struct IpoCurve *get_ipocurve(struct ID *from, short type, int adrcode, struct Ipo* useipo);
void insert_vert_ipo(struct IpoCurve *icu, float x, float y);
void add_vert_ipo(void);
@@ -116,6 +117,7 @@ void common_insertkey(void);
void free_ipokey(struct ListBase *lb);
void add_to_ipokey(struct ListBase *lb, struct BezTriple *bezt, int nr, int len);
void make_ipokey(void);
+void make_ipokey_spec(struct ListBase *lb, struct Ipo *ipo);
void make_ipokey_transform(struct Object *ob, struct ListBase *lb, int sel);
void update_ipokey_val(void);
void set_tob_old(float *old, float *poin);
@@ -141,6 +143,8 @@ int fullselect_ipo_keys(struct Ipo *ipo);
int add_trans_ipo_keys(struct Ipo *ipo, struct TransVert *tv, int tvtot);
void duplicate_ipo_keys(struct Ipo *ipo);
void borderselect_ipo_key(struct Ipo *ipo, float xmin, float xmax, int val);
+void borderselect_icu_key(struct IpoCurve *icu, float xmin, float xmax,
+ int (*select_function)(struct BezTriple *));
void select_ipo_key(struct Ipo *ipo, float selx, int sel);
void select_icu_key(struct IpoCurve *icu, float selx, int selectmode);
int select_bezier_add(struct BezTriple *bezt);
diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h
index 55f6d81aa06..6c36febbff7 100644
--- a/source/blender/makesdna/DNA_key_types.h
+++ b/source/blender/makesdna/DNA_key_types.h
@@ -48,7 +48,10 @@ typedef struct KeyBlock {
int pad;
void *data;
-
+ char name[32];
+
+ float slidermin;
+ float slidermax;
} KeyBlock;
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index 80af4d27676..482fb4448e6 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -60,6 +60,8 @@
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_key_types.h"
#include "BKE_action.h"
#include "BKE_global.h"
@@ -76,12 +78,17 @@
#include "BDR_editcurve.h"
#include "BSE_view.h"
#include "BSE_drawipo.h"
+#include "BSE_editaction.h"
#include "BSE_editaction_types.h"
#include "BDR_drawaction.h"
/* 'old' stuff": defines and types, and own include -------------------- */
#include "blendef.h"
+#include "interface.h"
+#include "mydevice.h"
+
+#include "BKE_ipo.h"
/* local functions ----------------------------------------------------- */
void drawactionspace(ScrArea *sa, void *spacedata);
@@ -91,10 +98,93 @@ 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 BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert);
static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos);
-
+void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos);
+static void draw_action_mesh_names(Key *key);
/* implementation ------------------------------------------------------ */
+
+extern void make_rvk_slider(uiBlock *block, Key *key, int i,
+ int x, int y, int w, int h); /* editkey.c */
+extern short showsliders; /* editaction .c */
+extern short ACTWIDTH;
+
+void meshactionbuts(SpaceAction *saction, Key *key)
+{
+ int i;
+ char str[64];
+ char keyname[32];
+ float x, y, ybase;
+ uiBlock *block;
+ uiBut *but;
+ short ofsx, ofsy = 0;
+#define RVKBGCOL .6, .6, .8
+#define XIC 20
+#define YIC 20
+
+ /* lets make the rvk sliders */
+
+ /* reset the damn myortho2 or the sliders won't draw/redraw
+ * correctly *grumble*
+ */
+ mywinset(curarea->win);
+ myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5);
+
+ sprintf(str, "actionbuttonswin %d", curarea->win);
+ block= uiNewBlock (&curarea->uiblocks, str,
+ UI_EMBOSSX, UI_HELV, curarea->win);
+
+ x = NAMEWIDTH + 1;
+ y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP)
+ - CHANNELHEIGHT/2 - G.v2d->cur.ymin;
+
+ uiBlockSetCol(block, BUTPURPLE);
+
+ /* make the little 'open the sliders' widget */
+ glColor3f(RVKBGCOL);
+ glRects(2, y + 2*CHANNELHEIGHT - 2,
+ ACTWIDTH - 2, y + CHANNELHEIGHT + 2);
+ glColor3ub(0, 0, 0);
+ glRasterPos2f(4, y + CHANNELHEIGHT + 6);
+ BMF_DrawString(G.font, "Sliders");
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ if (!showsliders) {
+ ACTWIDTH = NAMEWIDTH;
+ uiDefIconButS(block, TOG, B_FLIPINFOMENU,
+ ICON_DISCLOSURE_TRI_RIGHT,
+ NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
+ XIC,YIC-2,
+ &(showsliders), 0, 0, 0, 0,
+ "Show action window sliders");
+ }
+ else {
+ uiDefIconButS(block, TOG, B_FLIPINFOMENU,
+ ICON_DISCLOSURE_TRI_DOWN,
+ NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
+ XIC,YIC-2,
+ &(showsliders), 0, 0, 0, 0,
+ "Hide action window sliders");
+ ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
+
+ /* sliders are open so draw them */
+ glColor3f(RVKBGCOL);
+ glRects(NAMEWIDTH, 0, NAMEWIDTH+SLIDERWIDTH, curarea->winy);
+ uiBlockSetEmboss(block, UI_EMBOSSX);
+ for (i=1 ; i < key->totkey ; ++ i) {
+ make_rvk_slider(block, key, i,
+ x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1);
+
+ y-=CHANNELHEIGHT+CHANNELSKIP;
+
+ }
+ }
+ uiDrawBlock(block);
+
+}
+
void draw_cfra_action(void)
{
Object *ob;
@@ -129,24 +219,105 @@ void draw_cfra_action(void)
glLineWidth(1.0);
}
+
+static void draw_action_channel_names(bAction *act) {
+ bActionChannel *chan;
+ bConstraintChannel *conchan;
+ float x, y;
+
+ x = 0.0;
+ 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)NAMEWIDTH, 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;
+ }
+ }
+}
+
+
+static void draw_action_mesh_names(Key *key) {
+ /* draws the names of the rvk keys in the
+ * left side of the action window
+ */
+ int i;
+ char keyname[32];
+ float x, y;
+ KeyBlock *kb;
+
+ x = 0.0;
+ y= key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+
+ kb= key->block.first;
+
+ for (i=1 ; i < key->totkey ; ++ i) {
+ glColor3ub(0xAA, 0xAA, 0xAA);
+ glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
+
+ glColor3ub(0, 0, 0);
+
+ glRasterPos2f(x+8, y-4);
+ kb = kb->next;
+ /* Blender now has support for named
+ * key blocks. If a name hasn't
+ * been set for an key block then
+ * just display the key number --
+ * otherwise display the name stored
+ * in the keyblock.
+ */
+ if (kb->name[0] == '\0') {
+ sprintf(keyname, "Key %d", i);
+ BMF_DrawString(G.font, keyname);
+ }
+ else {
+ BMF_DrawString(G.font, kb->name);
+ }
+
+ y-=CHANNELHEIGHT+CHANNELSKIP;
+
+ }
+}
+
static void draw_channel_names(void)
{
short ofsx, ofsy = 0;
-
+ float y;
bAction *act;
- bActionChannel *chan;
- bConstraintChannel *conchan;
- float x, y;
-
- myortho2 (0, ACTWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax); // Scaling
+ Key *key;
+
+ myortho2 (0, NAMEWIDTH, 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));
+ glViewport(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, NAMEWIDTH,
+ (ofsy+G.v2d->mask.ymax) -
+ (ofsy+G.v2d->mask.ymin-SCROLLB));
+ glScissor(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, NAMEWIDTH,
+ (ofsy+G.v2d->mask.ymax) -
+ (ofsy+G.v2d->mask.ymin-SCROLLB));
}
}
@@ -158,76 +329,67 @@ static void draw_channel_names(void)
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);
+
+ if (act) {
+ /* if there is a selected action then
+ * draw the channel names
+ */
+ draw_action_channel_names(act);
+ }
+ else {
+ if ( (key = get_action_mesh_key()) ) {
+ /* if there is a mesh selected with rvk's,
+ * then draw the RVK names
+ */
+ draw_action_mesh_names(key);
+ }
+ }
+
+ myortho2 (0, NAMEWIDTH, 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);
+ y=9;
+
+ /* Draw sexy shaded block thingies
+ Reevan: if you start developing this stuff again
+ you can have your blend's back
+
+ glEnable (GL_BLEND);
+ glBegin(GL_QUAD_STRIP);
+ glColor4ub (0xCC,0xCC,0xCC,0x00);
+ glVertex2f (0,SCROLLB*2-y);
+ glVertex2f (NAMEWIDTH,SCROLLB*2-y);
+
+ glColor4ub (0xCC,0xCC,0xCC,0xFF);
+ glVertex2f (0,SCROLLB-y);
+ glVertex2f (NAMEWIDTH,SCROLLB-y);
+
+ glColor4ub (0xCC,0xCC,0xCC,0xFF);
+ glVertex2f (0,0-y);
+ glVertex2f (NAMEWIDTH,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 (NAMEWIDTH,y);
+ glColor4ub (0x88,0x88,0x88,0x00);
+ glVertex2f (0,y-SCROLLB);
+ glVertex2f (NAMEWIDTH,y-SCROLLB);
- glEnd();
-*/
- glDisable (GL_BLEND);
+ glEnd();
+ */
+ glDisable (GL_BLEND);
- glShadeModel(GL_FLAT);
+ glShadeModel(GL_FLAT);
}
@@ -345,21 +507,96 @@ static void draw_channel_strips(SpaceAction *saction)
glaEnd2DDraw(di);
}
+static void draw_mesh_strips(SpaceAction *saction, Key *key)
+{
+ /* draw the RVK keyframes as those little square button things
+ */
+ rcti scr_rct;
+ gla2DDrawInfo *di;
+ float y, ybase;
+ IpoCurve *icu;
+
+ if (!key->ipo) 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);
+
+ ybase = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+
+ for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+
+ int frame1_x, channel_y;
+
+ /* lets not deal with the "speed" Ipo
+ */
+ if (icu->adrcode==0) continue;
+
+ y = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
+ gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
+
+ /* all frames that have a frame number less than one
+ * get a desaturated orange background
+ */
+ glEnable(GL_BLEND);
+ glColor4b(0x55, 0x22, 0x11, 0x22);
+ glRectf(0, channel_y-CHANNELHEIGHT/2,
+ frame1_x, channel_y+CHANNELHEIGHT/2);
+
+ /* frames one and higher get a saturated orange background
+ */
+ glColor4b(0x55, 0x22, 0x11, 0x44);
+ glRectf(frame1_x, channel_y-CHANNELHEIGHT/2,
+ G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
+ glDisable(GL_BLEND);
+
+ /* draw the little squares
+ */
+ draw_icu_channel(di, icu, 0, y);
+ }
+
+ glaEnd2DDraw(di);
+}
+
void drawactionspace(ScrArea *sa, void *spacedata)
{
short ofsx = 0, ofsy = 0;
-
+ Key *key;
+ short maxymin;
+
if (!G.saction)
return;
-
if (!G.saction->pin) {
if (OBACT)
G.saction->action = OBACT->action;
else
G.saction->action=NULL;
}
+ key = get_action_mesh_key();
+
+ /* Damn I hate hunting to find my rvk's because
+ * they have scrolled off of the screen ... this
+ * oughta fix it
+ */
+
+ if (key) {
+ if (G.v2d->cur.ymin < -CHANNELHEIGHT)
+ G.v2d->cur.ymin = -CHANNELHEIGHT;
+
+ maxymin = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+ if (G.v2d->cur.ymin > maxymin) G.v2d->cur.ymin = maxymin;
+ }
+
+ /* Lets make sure the width of the left hand of the screen
+ * is set to an appropriate value based on whether sliders
+ * are showing of not
+ */
+ if (key && showsliders) ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
+ else ACTWIDTH = NAMEWIDTH;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
@@ -369,15 +606,20 @@ void drawactionspace(ScrArea *sa, void *spacedata)
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);
+ 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);
+ myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax,
+ G.v2d->cur.ymin, G.v2d->cur.ymax);
/* Draw backdrop */
calc_ipogrid();
@@ -386,25 +628,49 @@ void drawactionspace(ScrArea *sa, void *spacedata)
/* Draw channel strips */
draw_channel_strips(G.saction);
+ if (key) {
+ /* if there is a mesh with rvk's selected,
+ * then draw the key frames in the action window
+ */
+ draw_mesh_strips(G.saction, key);
+ /*meshactionbuts(G.saction, key);*/
+ }
+
+
/* 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);
+ 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);
+ 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();
+ if ( key ) {
+ /* if there is a mesh with rvk's selected,
+ * then draw the key frames in the action window
+ */
+ meshactionbuts(G.saction, key);
+ }
+
curarea->win_swap= WIN_BACK_OK;
}
+
void draw_channel_name(const char* name, short type, float ypos, int selected)
{
}
@@ -449,6 +715,20 @@ void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, int flags, float ypos)
}
}
+void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos)
+{
+ /* draw the keys for an IpoCurve
+ */
+ BezTriple **blist;
+ int totvert;
+
+ blist = icu_to_keylist(icu, 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;
@@ -503,6 +783,31 @@ static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert)
return list;
}
+static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert)
+{
+ /* compile a list of all bezier triples in an
+ * IpoCurve.
+ */
+ int v, count = 0;
+
+ BezTriple **list = NULL;
+
+ count=icu->totvert;
+
+ if (count){
+ list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
+ count=0;
+
+ 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 **ipo_to_keylist(Ipo *ipo, int flags, int *totvert)
{
IpoCurve *icu;
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index 0fa5e6d365f..e82e19b3cff 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -94,7 +94,7 @@ static int ipomachtx, ipomachty;
static int vertymin, vertymax, horxmin, horxmax; /* globals om LEFTMOUSE op scrollbar te testen */
-
+extern short ACTWIDTH;
static void scroll_prstr(float x, float y, float val, char dir, int disptype)
{
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 01f0ff4ff2b..dbde1c22d84 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -57,6 +57,9 @@
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_lattice_types.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
@@ -67,6 +70,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_action.h"
+#include "BKE_key.h"
#include "BIF_gl.h"
#include "BIF_mywindow.h"
@@ -107,17 +111,24 @@ static void mouse_actionchannels(bAction *act, short *mval,
short *mvalo, int selectmode);
static void borderselect_action(void);
static void mouse_action(int selectmode);
+static void mouse_mesh_action(int selectmode, Key *key);
static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, bConstraintChannel **conchan);
+static void sethandles_actionchannel_keys(int code);
static void delete_actionchannels(void);
static void delete_actionchannel_keys(void);
static void duplicate_actionchannel_keys(void);
static void transform_actionchannel_keys(char mode);
+static void transform_meshchannel_keys(char mode, Key *key);
static void select_poseelement_by_name (char *name, int select);
static void hilight_channel (bAction *act, bActionChannel *chan, short hilight);
static void set_action_key_time (bAction *act, bPoseChannel *chan, int adrcode, short makecurve, float time);
+static void clever_numbuts_meshaction(Key *key, short* mval);
/* Implementation */
+short showsliders = 0;
+short ACTWIDTH = NAMEWIDTH;
+
static void select_poseelement_by_name (char *name, int select)
{
/* Synchs selection of channels with selection of object elements in posemode */
@@ -277,6 +288,40 @@ void remake_action_ipos(bAction *act)
}
}
+void remake_meshaction_ipos(Ipo *ipo)
+{
+ /* this puts the bezier triples in proper
+ * order and makes sure the bezier handles
+ * aren't too strange.
+ */
+ IpoCurve *icu;
+
+ for (icu = ipo->curve.first; icu; icu=icu->next){
+ sort_time_ipocurve(icu);
+ testhandles_ipocurve(icu);
+ }
+}
+
+static void meshkey_do_redraw(Key *key)
+{
+ remake_meshaction_ipos(key->ipo);
+ do_all_ipos();
+ do_spec_key(key);
+
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+
+}
+
+static void duplicate_meshchannel_keys(Key *key)
+{
+ duplicate_ipo_keys(key->ipo);
+ transform_meshchannel_keys ('g', key);
+}
+
+
static void duplicate_actionchannel_keys(void)
{
bAction *act;
@@ -396,6 +441,110 @@ static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel,
return firstchan;
}
+static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
+{
+ /* This function tries to find the RVK key that is
+ * closest to the user's mouse click
+ */
+ Key *key;
+ IpoCurve *icu;
+ IpoCurve *firsticu=NULL;
+ int foundsel=0;
+ float firstvert=-1, foundx=-1;
+ int i;
+ short mval[2];
+ float ymin, ymax, ybase;
+ rctf rectf;
+
+ *index=0;
+
+ key = get_action_mesh_key();
+
+ /* lets get the mouse position and process it so
+ * we can start testing selections
+ */
+ getmouseco_areawin (mval);
+ mval[0]-=7;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
+ mval[0]+=14;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
+
+ ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
+ *sel=0;
+
+ /* lets loop through the IpoCurves trying to find the closest
+ * bezier
+ */
+ for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+ /* lets not deal with the "speed" Ipo
+ */
+ if (!icu->adrcode) continue;
+
+ ymax = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
+ ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
+
+ /* Does this curve coorespond to the right
+ * strip?
+ */
+ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){
+
+ /* loop through the beziers in the curve
+ */
+ for (i=0; i<icu->totvert; i++){
+
+ /* Is this bezier in the right area?
+ */
+ if (icu->bezt[i].vec[1][0] > rectf.xmin &&
+ icu->bezt[i].vec[1][0] <= rectf.xmax ){
+
+ /* if no other curves have been picked ...
+ */
+ if (!firsticu){
+ /* mark this curve/bezier as the first
+ * selected
+ */
+ firsticu=icu;
+ firstvert=icu->bezt[i].vec[1][0];
+
+ /* sel = (is the bezier is already selected) ? 1 : 0;
+ */
+ *sel = icu->bezt[i].f2 & 1;
+ }
+
+ /* if the bezier is selected ...
+ */
+ if (icu->bezt[i].f2 & 1){
+ /* if we haven't found a selected one yet ...
+ */
+ if (!foundsel){
+ /* record the found x value
+ */
+ foundsel=1;
+ foundx = icu->bezt[i].vec[1][0];
+ }
+ }
+
+ /* if the bezier is unselected and not at the x
+ * position of a previous found selected bezier ...
+ */
+ else if (foundsel && icu->bezt[i].vec[1][0] != foundx){
+ /* lets return this found curve/bezier
+ */
+ *index=icu->bezt[i].vec[1][0];
+ *sel = 0;
+ return icu;
+ }
+ }
+ }
+ }
+ }
+
+ /* return what we've found
+ */
+ *index=firstvert;
+ return firsticu;
+}
+
static void mouse_action(int selectmode)
{
bAction *act;
@@ -439,6 +588,63 @@ static void mouse_action(int selectmode)
}
}
+static void mouse_mesh_action(int selectmode, Key *key)
+{
+ /* Handle a right mouse click selection in an
+ * action window displaying RVK data
+ */
+
+ IpoCurve *icu;
+ short sel;
+ float selx;
+ short mval[2];
+
+ /* going to assume that the only reason
+ * we got here is because it has been
+ * determined that we are a mesh with
+ * the right properties (i.e., have key
+ * data, etc)
+ */
+
+ /* get the click location, and the cooresponding
+ * ipo curve and selection time value
+ */
+ getmouseco_areawin (mval);
+ icu = get_nearest_meshchannel_key(&selx, &sel);
+
+ if (icu){
+ if (selectmode == SELECT_REPLACE) {
+ /* if we had planned to replace the
+ * selection, then we will first deselect
+ * all of the keys, and if the clicked on
+ * key had been unselected, we will select
+ * it, otherwise, we are done.
+ */
+ deselect_meshchannel_keys(key, 0);
+
+ if (sel == 0)
+ selectmode = SELECT_ADD;
+ else
+ /* the key is selected so we should
+ * deselect -- but everything is now deselected
+ * so we are done.
+ */
+ return;
+ }
+
+ /* select the key using the given mode
+ * and redraw as mush stuff as needed.
+ */
+ select_icu_key(icu, selx, selectmode);
+
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+
+ }
+}
+
static void borderselect_action(void)
{
rcti rect;
@@ -496,6 +702,61 @@ static void borderselect_action(void)
}
}
+static void borderselect_mesh(Key *key)
+{
+ rcti rect;
+ int val, adrcodemax, adrcodemin;
+ short mval[2];
+ float xmin, xmax;
+ int (*select_function)(BezTriple *);
+ IpoCurve *icu;
+
+ if ( (val = get_border(&rect, 3)) ){
+ /* set the selection function based on what
+ * mouse button had been used in the border
+ * select
+ */
+ if (val == LEFTMOUSE)
+ select_function = select_bezier_add;
+ else
+ select_function = select_bezier_subtract;
+
+ /* get the minimum and maximum adrcode numbers
+ * for the IpoCurves (this is the number that
+ * relates an IpoCurve to the keyblock it
+ * controls).
+ */
+ mval[0]= rect.xmin;
+ mval[1]= rect.ymin+2;
+ adrcodemax = get_nearest_key_num(key, mval, &xmin);
+ adrcodemax = (adrcodemax >= key->totkey) ? key->totkey : adrcodemax;
+
+ mval[0]= rect.xmax;
+ mval[1]= rect.ymax-2;
+ adrcodemin = get_nearest_key_num(key, mval, &xmax);
+ adrcodemin = (adrcodemin < 1) ? 1 : adrcodemin;
+
+ /* Lets loop throug the IpoCurves and do borderselect
+ * on the curves with adrcodes in our selected range.
+ */
+ for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+ /* lets not deal with the "speed" Ipo
+ */
+ if (!icu->adrcode) continue;
+ if ( (icu->adrcode >= adrcodemin) &&
+ (icu->adrcode <= adrcodemax) ) {
+ borderselect_icu_key(icu, xmin, xmax, select_function);
+ }
+ }
+
+ /* redraw stuff */
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ }
+}
+
+
bActionChannel* get_hilighted_action_channel(bAction* action)
{
bActionChannel *chan;
@@ -1017,6 +1278,192 @@ static void transform_actionchannel_keys(char mode)
MEM_freeN (tv);
}
+static void transform_meshchannel_keys(char mode, Key *key)
+{
+ /* this is the function that determines what happens
+ * to those little blocky rvk key things you have selected
+ * after you press a 'g' or an 's'. I'd love to say that
+ * I have an intimate knowledge of all of what this function
+ * is doing, but instead I'm just going to pretend.
+ */
+ TransVert *tv;
+ int /*sel=0,*/ i;
+ short mvals[2], mvalc[2], cent[2];
+ float sval[2], cval[2], lastcval[2];
+ short cancel=0;
+ float fac=0.0F;
+ int loop=1;
+ int tvtot=0;
+ float deltax, startx;
+ float cenf[2];
+ int invert=0, firsttime=1;
+ char str[256];
+
+ /* count all of the selected beziers, and
+ * set all 3 control handles to selected
+ */
+ tvtot=fullselect_ipo_keys(key->ipo);
+
+ /* If nothing is selected, bail out
+ */
+ if (!tvtot)
+ return;
+
+
+ /* Build the transvert structure
+ */
+ tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
+ tvtot=0;
+
+ tvtot = add_trans_ipo_keys(key->ipo, tv, tvtot);
+
+ /* Do the event loop
+ */
+ cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2;
+ cent[1] = curarea->winy + (G.saction->v2d.hor.ymax)/2;
+ areamouseco_to_ipoco(G.v2d, cent, &cenf[0], &cenf[1]);
+
+ getmouseco_areawin (mvals);
+ areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]);
+
+ startx=sval[0];
+ while (loop) {
+ /* Get the input
+ * If we're cancelling, reset transformations
+ * Else calc new transformation
+ * Perform the transformations
+ */
+ while (qtest()) {
+ short val;
+ unsigned short event= extern_qread(&val);
+
+ if (val) {
+ switch (event) {
+ case LEFTMOUSE:
+ case SPACEKEY:
+ case RETKEY:
+ loop=0;
+ break;
+ case XKEY:
+ break;
+ case ESCKEY:
+ case RIGHTMOUSE:
+ cancel=1;
+ loop=0;
+ break;
+ default:
+ arrows_move_cursor(event);
+ break;
+ };
+ }
+ }
+
+ if (cancel) {
+ for (i=0; i<tvtot; i++) {
+ tv[i].loc[0]=tv[i].oldloc[0];
+ tv[i].loc[1]=tv[i].oldloc[1];
+ }
+ }
+ else {
+ getmouseco_areawin (mvalc);
+ areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]);
+
+ if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
+ PIL_sleep_ms(1);
+ } else {
+ for (i=0; i<tvtot; i++){
+ tv[i].loc[0]=tv[i].oldloc[0];
+
+ switch (mode){
+ case 'g':
+ deltax = cval[0]-sval[0];
+ fac= deltax;
+
+ apply_keyb_grid(&fac, 0.0, 1.0, 0.1,
+ U.flag & AUTOGRABGRID);
+
+ tv[i].loc[0]+=fac;
+ break;
+ case 's':
+ startx=mvals[0]-(ACTWIDTH/2+(curarea->winrct.xmax
+ -curarea->winrct.xmin)/2);
+ deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax
+ -curarea->winrct.xmin)/2);
+ fac= fabs(deltax/startx);
+
+ apply_keyb_grid(&fac, 0.0, 0.2, 0.1,
+ U.flag & AUTOSIZEGRID);
+
+ if (invert){
+ if (i % 03 == 0){
+ memcpy (tv[i].loc, tv[i].oldloc,
+ sizeof(tv[i+2].oldloc));
+ }
+ if (i % 03 == 2){
+ memcpy (tv[i].loc, tv[i].oldloc,
+ sizeof(tv[i-2].oldloc));
+ }
+
+ fac*=-1;
+ }
+ startx= (G.scene->r.cfra);
+
+ tv[i].loc[0]-= startx;
+ tv[i].loc[0]*=fac;
+ tv[i].loc[0]+= startx;
+
+ break;
+ }
+ }
+ }
+ /* Display a message showing the magnitude of
+ * the grab/scale we are performing
+ */
+ if (mode=='s'){
+ sprintf(str, "sizeX: %.3f", fac);
+ headerprint(str);
+ }
+ else if (mode=='g'){
+ sprintf(str, "deltaX: %.3f", fac);
+ headerprint(str);
+ }
+
+ if (G.saction->lock){
+ /* doubt any of this code ever gets
+ * executed, but it might in the
+ * future
+ */
+
+ do_all_actions();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+ force_draw_all();
+ }
+ else {
+ addqueue (curarea->win, REDRAWALL, 0);
+ force_draw ();
+ }
+ }
+
+ lastcval[0]= cval[0];
+ lastcval[1]= cval[1];
+ firsttime= 0;
+ }
+
+ /* fix up the Ipocurves and redraw stuff
+ */
+ meshkey_do_redraw(key);
+
+ MEM_freeN (tv);
+
+ /* did you understand all of that? I pretty much understand
+ * what it does, but the specifics seem a little weird and crufty.
+ */
+}
+
+
void deselect_actionchannel_keys (bAction *act, int test)
{
bActionChannel *chan;
@@ -1059,6 +1506,26 @@ void deselect_actionchannel_keys (bAction *act, int test)
}
}
+void deselect_meshchannel_keys (Key *key, int test)
+{
+ /* should deselect the rvk keys
+ */
+ int sel=1;
+
+ /* Determine if this is selection or deselection */
+ if (test){
+ if (is_ipo_key_selected(key->ipo)){
+ sel = 0;
+ }
+ }
+ else {
+ sel=0;
+ }
+
+ /* Set the flags */
+ set_ipo_key_selection(key->ipo, sel);
+}
+
void deselect_actionchannels (bAction *act, int test)
{
bActionChannel *chan;
@@ -1125,6 +1592,12 @@ static void hilight_channel (bAction *act, bActionChannel *chan, short select)
}
}
+/* select_mode = SELECT_REPLACE
+ * = SELECT_ADD
+ * = SELECT_SUBTRACT
+ * = SELECT_INVERT
+ */
+
static int select_channel(bAction *act, bActionChannel *chan,
int selectmode) {
/* Select the channel based on the selection mode
@@ -1277,6 +1750,15 @@ static void mouse_actionchannels(bAction *act, short *mval,
allqueue (REDRAWNLA, 0);
}
+static void delete_meshchannel_keys(Key *key)
+{
+ if (!okee("Erase selected keys"))
+ return;
+
+ delete_ipo_keys(key->ipo);
+
+ meshkey_do_redraw(key);
+}
static void delete_actionchannel_keys(void)
{
@@ -1369,6 +1851,13 @@ static void delete_actionchannels (void)
}
+static void sethandles_meshchannel_keys(int code, Key *key)
+{
+ sethandles_ipo_keys(key->ipo, code);
+
+ meshkey_do_redraw(key);
+}
+
static void sethandles_actionchannel_keys(int code)
{
bAction *act;
@@ -1660,7 +2149,8 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
short mval[2];
float dx,dy;
int cfra;
-
+ Key *key;
+
if(curarea->win==0) return;
saction= curarea->spacedata.first;
@@ -1674,6 +2164,8 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
getmouseco_areawin(mval);
+ key = get_action_mesh_key();
+
switch(event) {
case UI_BUT_EVENT:
do_blenderbuttons(val);
@@ -1690,92 +2182,172 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case DKEY:
- if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){
- duplicate_actionchannel_keys();
- remake_action_ipos(act);
+ if (key) {
+ if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH) {
+ duplicate_meshchannel_keys(key);
+ }
+ }
+ else {
+ if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){
+ duplicate_actionchannel_keys();
+ remake_action_ipos(act);
+ }
}
break;
+
case DELKEY:
+
case XKEY:
- if (mval[0]<ACTWIDTH)
- delete_actionchannels ();
- else
- delete_actionchannel_keys ();
+ if (key) {
+ delete_meshchannel_keys(key);
+ }
+ else {
+ if (mval[0]<NAMEWIDTH)
+ delete_actionchannels ();
+ else
+ delete_actionchannel_keys ();
+ }
break;
+
case GKEY:
- if (mval[0]>=ACTWIDTH)
- transform_actionchannel_keys ('g');
+ if (mval[0]>=ACTWIDTH) {
+ if (key) {
+ transform_meshchannel_keys('g', key);
+ }
+ else {
+ transform_actionchannel_keys ('g');
+ }
+ }
break;
+
case SKEY:
- if (mval[0]>=ACTWIDTH)
- transform_actionchannel_keys ('s');
+ if (mval[0]>=ACTWIDTH) {
+ if (key) {
+ transform_meshchannel_keys('s', key);
+ }
+ else {
+ transform_actionchannel_keys ('s');
+ }
+ }
break;
+
case AKEY:
- if (mval[0]<ACTWIDTH){
- deselect_actionchannels (act, 1);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
+ if (key) {
+ if (mval[0]<ACTWIDTH){
+ /* to do ??? */
+ }
+ else{
+ deselect_meshchannel_keys(key, 1);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ }
}
- else{
- deselect_actionchannel_keys (act, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
+ else {
+ if (mval[0]<NAMEWIDTH){
+ deselect_actionchannels (act, 1);
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ }
+ else if (mval[0]>ACTWIDTH){
+ deselect_actionchannel_keys (act, 1);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ }
}
break;
- /*** set the Ipo handles ***/
case VKEY:
- sethandles_actionchannel_keys(HD_VECT);
+ if (key) {
+ sethandles_meshchannel_keys(HD_VECT, key);
+ /* to do */
+ }
+ else {
+ sethandles_actionchannel_keys(HD_VECT);
+ }
break;
case HKEY:
- if(G.qual & LR_SHIFTKEY) sethandles_actionchannel_keys(HD_AUTO);
- else sethandles_actionchannel_keys(HD_ALIGN);
+ if (key) {
+ if(G.qual & LR_SHIFTKEY) {
+ sethandles_meshchannel_keys(HD_AUTO, key);
+ }
+ else {
+ sethandles_meshchannel_keys(HD_ALIGN, key);
+ }
+ }
+ else {
+ if(G.qual & LR_SHIFTKEY) {
+ sethandles_actionchannel_keys(HD_AUTO);
+ }
+ else {
+ sethandles_actionchannel_keys(HD_ALIGN);
+ }
+ }
break;
-
+
/*** set the Ipo type ***/
case TKEY:
- set_ipotype_actionchannels();
+ if (key) {
+ /* to do */
+ }
+ else {
+ set_ipotype_actionchannels();
+ }
break;
case BKEY:
- /* If the border select is initiated in the
- * part of the action window where the channel
- * names reside, then select the channels
- */
- if (mval[0]<ACTWIDTH){
- borderselect_function(mouse_actionchannels);
+ if (key) {
+ if (mval[0]<ACTWIDTH){
+ /* to do?? */
+ }
+ else {
+ borderselect_mesh(key);
+ }
}
+ else {
- /* If the border select is initiated in the
- * vertical scrollbar, then (de)select all keys
- * for the channels in the selection region
- */
- else if (IN_2D_VERT_SCROLL(mval)) {
- borderselect_function(select_all_keys_channels);
- }
+ /* If the border select is initiated in the
+ * part of the action window where the channel
+ * names reside, then select the channels
+ */
+ if (mval[0]<NAMEWIDTH){
+ borderselect_function(mouse_actionchannels);
+ }
+ else if (mval[0]>ACTWIDTH){
+
+ /* If the border select is initiated in the
+ * vertical scrollbar, then (de)select all keys
+ * for the channels in the selection region
+ */
+ if (IN_2D_VERT_SCROLL(mval)) {
+ borderselect_function(select_all_keys_channels);
+ }
- /* If the border select is initiated in the
- * horizontal scrollbar, then (de)select all keys
- * for the keyframes in the selection region
- */
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- borderselect_function(select_all_keys_frames);
- }
+ /* If the border select is initiated in the
+ * horizontal scrollbar, then (de)select all keys
+ * for the keyframes in the selection region
+ */
+ else if (IN_2D_HORIZ_SCROLL(mval)) {
+ borderselect_function(select_all_keys_frames);
+ }
- /* Other wise, select the action keys
- */
- else {
- borderselect_action();
+ /* Other wise, select the action keys
+ */
+ else {
+ borderselect_action();
+ }
+ }
}
break;
+
case RIGHTMOUSE:
/* Right clicking in the channel area selects the
* channel or constraint channel
*/
- if (mval[0]<ACTWIDTH) {
+ if (mval[0]<NAMEWIDTH) {
if(G.qual & LR_SHIFTKEY)
mouse_actionchannels(act, mval, NULL,
SELECT_INVERT);
@@ -1783,40 +2355,50 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
mouse_actionchannels(act, mval, NULL,
SELECT_REPLACE);
}
+ else if (mval[0]>ACTWIDTH) {
+
+ /* Right clicking in the vertical scrollbar selects
+ * all of the keys for that channel at that height
+ */
+ if (IN_2D_VERT_SCROLL(mval)) {
+ if(G.qual & LR_SHIFTKEY)
+ select_all_keys_channels(act, mval, NULL,
+ SELECT_INVERT);
+ else
+ select_all_keys_channels(act, mval, NULL,
+ SELECT_REPLACE);
+ }
- /* Right clicking in the vertical scrollbar selects
- * all of the keys for that channel at that height
- */
- else if (IN_2D_VERT_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_channels(act, mval, NULL,
- SELECT_INVERT);
- else
- select_all_keys_channels(act, mval, NULL,
- SELECT_REPLACE);
- }
-
- /* Right clicking in the horizontal scrollbar selects
- * all of the keys within 0.5 of the nearest integer
- * frame
- */
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_frames(act, mval, NULL,
- SELECT_INVERT);
- else
- select_all_keys_frames(act, mval, NULL,
- SELECT_REPLACE);
- }
-
- /* Clicking in the main area of the action window
- * selects keys
- */
- else {
- if(G.qual & LR_SHIFTKEY)
- mouse_action(SELECT_INVERT);
- else
- mouse_action(SELECT_REPLACE);
+ /* Right clicking in the horizontal scrollbar selects
+ * all of the keys within 0.5 of the nearest integer
+ * frame
+ */
+ else if (IN_2D_HORIZ_SCROLL(mval)) {
+ if(G.qual & LR_SHIFTKEY)
+ select_all_keys_frames(act, mval, NULL,
+ SELECT_INVERT);
+ else
+ select_all_keys_frames(act, mval, NULL,
+ SELECT_REPLACE);
+ }
+
+ /* Clicking in the main area of the action window
+ * selects keys
+ */
+ else {
+ if (key) {
+ if(G.qual & LR_SHIFTKEY)
+ mouse_mesh_action(SELECT_INVERT, key);
+ else
+ mouse_mesh_action(SELECT_REPLACE, key);
+ }
+ else {
+ if(G.qual & LR_SHIFTKEY)
+ mouse_action(SELECT_INVERT);
+ else
+ mouse_action(SELECT_REPLACE);
+ }
+ }
}
break;
@@ -1854,3 +2436,119 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
+Key *get_action_mesh_key(void) {
+ /* gets the key data from the currently selected
+ * mesh/lattice. If a mesh is not selected, or does not have
+ * key data, then we return NULL (currently only
+ * returns key data for RVK type meshes). If there
+ * is an action that is pinned, return null
+ */
+ Object *ob;
+ Key *key;
+
+ ob = OBACT;
+ if (!ob) return NULL;
+
+ if (G.saction->pin) return NULL;
+
+ if (ob->type==OB_MESH ) {
+ key = ((Mesh *)ob->data)->key;
+ }
+ else if (ob->type==OB_LATTICE ) {
+ key = ((Lattice *)ob->data)->key;
+ }
+ else return NULL;
+
+ if (key) {
+ if (key->type == KEY_RELATIVE)
+ return key;
+ }
+
+ return NULL;
+}
+
+int get_nearest_key_num(Key *key, short *mval, float *x) {
+ /* returns the key num that cooresponds to the
+ * y value of the mouse click. Does not check
+ * if this is a valid keynum. Also gives the Ipo
+ * x coordinate.
+ */
+ int num;
+ float ybase, y;
+
+ areamouseco_to_ipoco(G.v2d, mval, x, &y);
+
+ ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
+ num = (int) ((ybase - y) / (CHANNELHEIGHT+CHANNELSKIP));
+
+ return (num + 1);
+}
+
+static void clever_keyblock_names(Key *key, short* mval){
+ int but=0, i, keynum;
+ char str[64];
+ float x, min, max;
+ KeyBlock *kb;
+ /* get the keynum cooresponding to the y value
+ * of the mouse pointer, return if this is
+ * an invalid key number (and we don't deal
+ * with the speed ipo).
+ */
+
+ keynum = get_nearest_key_num(key, mval, &x);
+ if ( (keynum < 1) || (keynum >= key->totkey) )
+ return;
+
+ kb= key->block.first;
+ for (i=0; i<keynum; ++i) kb = kb->next;
+
+ if (kb->name[0] == '\0') {
+ sprintf(str, "Key %d", keynum);
+ }
+ else {
+ strcpy(str, kb->name);
+ }
+
+ if ( (kb->slidermin >= kb->slidermax) ) {
+ kb->slidermin = 0.0;
+ kb->slidermax = 1.0;
+ }
+
+ add_numbut(but++, TEX, "KB: ", 0, 24, str,
+ "Does this really need a tool tip?");
+ add_numbut(but++, NUM|FLO, "Slider min:",
+ -10000, kb->slidermax, &kb->slidermin, 0);
+ add_numbut(but++, NUM|FLO, "Slider max:",
+ kb->slidermin, 10000, &kb->slidermax, 0);
+
+ if (do_clever_numbuts(str, but, REDRAW)) {
+ strcpy(kb->name, str);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWIPO, 0);
+ }
+
+
+}
+
+void stupid_damn_numbuts_action(void){
+ /* I think this function might have been
+ * deemed clever if it could have been
+ * called from the event processing
+ * routine in this file -- rather than having
+ * to go from the NKEY event from blenderqread
+ * in toets.c (which returns 0 so nobody else
+ * can use the NKEY) then into the clever_numbuts
+ * routine in toolbox.c, the finally to this
+ * function. Grumble, grumble, grumble ...
+ */
+
+ Key *key;
+ short mval[2];
+
+ if ( (key = get_action_mesh_key()) ) {
+ getmouseco_areawin (mval);
+ if (mval[0]<NAMEWIDTH) {
+ clever_keyblock_names(key, mval);
+ }
+ }
+}
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index b0cf75ff7da..b799d9d99f0 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -1866,7 +1866,7 @@ EditIpo *get_editipo()
}
-static Ipo *get_ipo(ID *from, short type, int make)
+Ipo *get_ipo(ID *from, short type, int make)
{
Object *ob;
Material *ma;
diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c
index 0d8b04339c1..3f8a3e98705 100644
--- a/source/blender/src/editkey.c
+++ b/source/blender/src/editkey.c
@@ -69,6 +69,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_object.h"
+#include "BKE_displist.h"
#include "BIF_editkey.h"
#include "BIF_editview.h"
@@ -76,6 +77,7 @@
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
+#include "BIF_interface.h"
#include "BSE_editipo.h"
#include "BSE_trans_types.h"
@@ -85,9 +87,200 @@
#include "blendef.h"
#include "mydevice.h"
#include "ipo.h"
+#include "interface.h"
extern ListBase editNurb; /* in editcurve.c */
+/* temporary storage for slider values */
+float meshslidervals[32] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+static IpoCurve *get_key_icu(Key *key, int keynum) {
+ /* return the Ipocurve that has the specified
+ * keynum as ardcode -- return NULL if no such
+ * curve exists.
+ */
+ IpoCurve *icu;
+ if (!(key->ipo)) {
+ key->ipo = get_ipo(key, ID_KE, 1);
+ return NULL;
+ }
+
+
+ for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+ if (!icu->adrcode) continue;
+ if (icu->adrcode == keynum) return icu;
+ }
+
+ return NULL;
+}
+
+static BezTriple *get_bezt_icu_time(IpoCurve *icu, float *frame, float *val) {
+ /* this function tries to find a bezier that is within
+ * 0.25 time units from the specified frame. If there
+ * are more than one such beziers, it returns the
+ * closest one.
+ */
+ int i;
+ float d, dmin = 0.25, newframe;
+ BezTriple *bezt = NULL;
+
+ newframe = *frame;
+
+ for (i=0; i<icu->totvert; i++){
+ d = fabs(icu->bezt[i].vec[1][0] - *frame);
+ if (d < dmin) {
+ dmin = d;
+ newframe = icu->bezt[i].vec[1][0];
+ *val = icu->bezt[i].vec[1][1];
+ bezt = icu->bezt + i;
+ }
+ }
+
+ *frame = newframe;
+ return bezt;
+}
+
+static void rvk_slider_func(void *voidkey, void *voidkeynum) {
+ /* the callback for the rvk sliders ... copies the
+ * value from the temporary array into a bezier at the
+ * right frame on the right ipo curve (creating both the
+ * ipo curve and the bezier if needed).
+ */
+ int *keynum = (int *) voidkeynum;
+ Key *key = (Key *) voidkey;
+ float cfra, rvkval;
+ IpoCurve *icu=NULL;
+ BezTriple *bezt=NULL;
+
+ cfra = frame_to_float(CFRA);
+
+ icu = get_key_icu(key, *keynum);
+
+ if (icu) {
+ /* if the ipocurve exists, try to get a bezier
+ * for this frame
+ */
+ bezt = get_bezt_icu_time(icu, &cfra, &rvkval);
+ }
+ else {
+ /* create an IpoCurve if one doesn't already
+ * exist.
+ */
+ icu = get_ipocurve(key->from, GS(key->from->name),
+ *keynum, key->ipo);
+ }
+
+ /* create the bezier triple if one doesn't exist,
+ * otherwise modify it's value
+ */
+ if (!bezt) {
+ insert_vert_ipo(icu, cfra, meshslidervals[*keynum]);
+ }
+ else {
+ bezt->vec[1][1] = meshslidervals[*keynum];
+ }
+
+ /* make sure the Ipo's are properly process and
+ * redraw as necessary
+ */
+ sort_time_ipocurve(icu);
+ testhandles_ipocurve(icu);
+
+ do_all_ipos();
+ do_spec_key(key);
+ /* if I'm deformed by a lattice, update my
+ * displists
+ */
+ makeDispList(OBACT);
+
+ /* if I'm a lattice, update the displists of
+ * my children
+ */
+ if (OBACT->type==OB_LATTICE ) {
+ Base *base;
+
+ base= FIRSTBASE;
+ while(base) {
+ if (base->object->parent == OBACT) {
+ makeDispList(base->object);
+ }
+ base= base->next;
+ }
+ }
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+
+}
+
+static float getrvkval(Key *key, int keynum) {
+ /* get the value of the rvk from the
+ * ipo curve at the current time -- return 0
+ * if no ipo curve exists
+ */
+ IpoCurve *icu=NULL;
+ BezTriple *bezt=NULL;
+ float rvkval = 0.0;
+ float cfra;
+
+ cfra = frame_to_float(CFRA);
+ icu = get_key_icu(key, keynum);
+ if (icu) {
+ bezt = get_bezt_icu_time(icu, &cfra, &rvkval);
+ if (!bezt) {
+ rvkval = eval_icu(icu, cfra);
+ }
+ }
+
+ return rvkval;
+
+}
+
+void make_rvk_slider(uiBlock *block, Key *key, int keynum,
+ int x, int y, int w, int h)
+{
+ /* create a slider for the rvk */
+ uiBut *but;
+ KeyBlock *kb;
+ float min, max;
+ int i;
+
+ /* dang, need to pass a pointer to int to uiButSetFunc
+ * that is on the heap, not the stack ... hence this
+ * kludgy static array
+ */
+ static int keynums[] = {0,1,2,3,4,5,6,7,
+ 8,9,10,11,12,13,14,15,
+ 16,17,18,19,20,21,22,23,
+ 24,25,26,27,28,29,30,31};
+
+ meshslidervals[keynum] = getrvkval(key, keynum);
+
+ kb= key->block.first;
+ for (i=0; i<keynum; ++i) kb = kb->next;
+
+ if ( (kb->slidermin >= kb->slidermax) ) {
+ kb->slidermin = 0.0;
+ kb->slidermax = 1.0;
+ }
+
+ min = (kb->slidermin < meshslidervals[keynum]) ?
+ kb->slidermin: meshslidervals[keynum];
+
+ max = (kb->slidermax > meshslidervals[keynum]) ?
+ kb->slidermax: meshslidervals[keynum];
+
+ but=uiDefButF(block, NUMSLI, REDRAWVIEW3D, "",
+ x, y , w, h,
+ meshslidervals+keynum, min, max, 10, 2,
+ "Slider to control rvk");
+ uiButSetFunc(but, rvk_slider_func, key, keynums+keynum);
+}
+
static void default_key_ipo(Key *key)
{
IpoCurve *icu;
@@ -168,10 +361,20 @@ void insert_meshkey(Mesh *me)
Key *key;
KeyBlock *kb, *kkb;
float curpos;
-
+ short rel;
+
if(me->key==0) {
me->key= add_key( (ID *)me);
- default_key_ipo(me->key);
+ rel = pupmenu("Relative Vertex Keys? %t|Yes Please! %x1"
+ "|Naw, the other kind %x2");
+ switch (rel) {
+ case 1:
+ me->key->type = KEY_RELATIVE;
+ break;
+ default:
+ default_key_ipo(me->key);
+ break;
+ }
}
key= me->key;
diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c
index eaa66bd5b22..1a7b24aff85 100644
--- a/source/blender/src/headerbuttons.c
+++ b/source/blender/src/headerbuttons.c
@@ -4032,17 +4032,25 @@ void action_buttons(void)
uiDefIconBut(block, BUT, B_ACTHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms window to home view showing all items (HOMEKEY)");
- /* NAME ETC */
- ob=OBACT;
- from = (ID*) ob;
+ if (!get_action_mesh_key()) {
+ /* NAME ETC */
+ ob=OBACT;
+ from = (ID*) ob;
- xco= std_libbuttons(block, xco+1.5*XIC, B_ACTPIN, &G.saction->pin, B_ACTIONBROWSE, (ID*)G.saction->action, from, &(G.saction->actnr), B_ACTALONE, B_ACTLOCAL, B_ACTIONDELETE, 0, 0);
+ xco= std_libbuttons(block, xco+1.5*XIC, B_ACTPIN, &G.saction->pin,
+ B_ACTIONBROWSE, (ID*)G.saction->action,
+ from, &(G.saction->actnr), B_ACTALONE,
+ B_ACTLOCAL, B_ACTIONDELETE, 0, 0);
#ifdef __NLA_BAKE
- /* Draw action baker */
- uiDefBut(block, BUT, B_ACTBAKE, "Bake", xco+=XIC, 0, 64, YIC, 0, 0, 0, 0, 0, "Generates an Action with the constraint effects converted into ipo keys");
- xco+=64;
+ /* Draw action baker */
+ uiDefBut(block, BUT, B_ACTBAKE, "Bake",
+ xco+=XIC, 0, 64, YIC, 0, 0, 0, 0, 0,
+ "Generate an action with the constraint "
+ "effects converted into ipo keys");
+ xco+=64;
#endif
+ }
uiClearButLock();
/* draw LOCK */
diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c
index 364193c52e1..4c879b5a94e 100644
--- a/source/blender/src/toolbox.c
+++ b/source/blender/src/toolbox.c
@@ -1452,9 +1452,9 @@ void clever_numbuts(void)
else if(curarea->spacetype==SPACE_OOPS) {
clever_numbuts_oops();
}
-// else if(curarea->spacetype==SPACE_ACTION){
-// stupid_damn_numbuts_action();
-// }
+ else if(curarea->spacetype==SPACE_ACTION){
+ stupid_damn_numbuts_action();
+ }
else if(curarea->spacetype==SPACE_FILE) {
clever_numbuts_filesel();
}