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!
This commit is contained in:
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -48,7 +48,10 @@ typedef struct KeyBlock {
|
||||
int pad;
|
||||
|
||||
void *data;
|
||||
|
||||
char name[32];
|
||||
|
||||
float slidermin;
|
||||
float slidermax;
|
||||
} KeyBlock;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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, ACTWIDTH, 0, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); // Scaling
|
||||
myortho2 (0, NAMEWIDTH, 0,
|
||||
(ofsy+G.v2d->mask.ymax) -
|
||||
(ofsy+G.v2d->mask.ymin-SCROLLB)); // Scaling
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
y=9;
|
||||
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);
|
||||
/* 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 (ACTWIDTH,SCROLLB-y);
|
||||
glColor4ub (0xCC,0xCC,0xCC,0xFF);
|
||||
glVertex2f (0,SCROLLB-y);
|
||||
glVertex2f (NAMEWIDTH,SCROLLB-y);
|
||||
|
||||
glColor4ub (0xCC,0xCC,0xCC,0xFF);
|
||||
glVertex2f (0,0-y);
|
||||
glVertex2f (ACTWIDTH,0-y);
|
||||
glColor4ub (0xCC,0xCC,0xCC,0xFF);
|
||||
glVertex2f (0,0-y);
|
||||
glVertex2f (NAMEWIDTH,0-y);
|
||||
|
||||
glEnd();
|
||||
glEnd();
|
||||
*/
|
||||
|
||||
/* y=( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB);
|
||||
/* 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);
|
||||
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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DELKEY:
|
||||
case XKEY:
|
||||
if (mval[0]<ACTWIDTH)
|
||||
delete_actionchannels ();
|
||||
else
|
||||
delete_actionchannel_keys ();
|
||||
break;
|
||||
case GKEY:
|
||||
if (mval[0]>=ACTWIDTH)
|
||||
transform_actionchannel_keys ('g');
|
||||
break;
|
||||
case SKEY:
|
||||
if (mval[0]>=ACTWIDTH)
|
||||
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);
|
||||
}
|
||||
else{
|
||||
deselect_actionchannel_keys (act, 1);
|
||||
allqueue (REDRAWACTION, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
allqueue (REDRAWIPO, 0);
|
||||
else {
|
||||
if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){
|
||||
duplicate_actionchannel_keys();
|
||||
remake_action_ipos(act);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DELKEY:
|
||||
|
||||
case XKEY:
|
||||
if (key) {
|
||||
delete_meshchannel_keys(key);
|
||||
}
|
||||
else {
|
||||
if (mval[0]<NAMEWIDTH)
|
||||
delete_actionchannels ();
|
||||
else
|
||||
delete_actionchannel_keys ();
|
||||
}
|
||||
break;
|
||||
|
||||
case GKEY:
|
||||
if (mval[0]>=ACTWIDTH) {
|
||||
if (key) {
|
||||
transform_meshchannel_keys('g', key);
|
||||
}
|
||||
else {
|
||||
transform_actionchannel_keys ('g');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SKEY:
|
||||
if (mval[0]>=ACTWIDTH) {
|
||||
if (key) {
|
||||
transform_meshchannel_keys('s', key);
|
||||
}
|
||||
else {
|
||||
transform_actionchannel_keys ('s');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AKEY:
|
||||
if (key) {
|
||||
if (mval[0]<ACTWIDTH){
|
||||
/* to do ??? */
|
||||
}
|
||||
else{
|
||||
deselect_meshchannel_keys(key, 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
* 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();
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
*/
|
||||
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 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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user