== Action Editor ==

In the Action Editor, sliders are now drawn beside IPO-Curve and Constraint Channels and for the active Action Channel when the 'Show Sliders' option in the View menu is turned on. This behaves like for shapekeys.

You can change the limits of the sliders by either Ctrl-Clicking or NKEY over the
name of the relevant IPO-Curve channel.


Also, documented the IPO-curve struct a bit. There are a few variables there that
I'm not sure what they are used for.
This commit is contained in:
Joshua Leung 2007-04-25 11:57:02 +00:00
parent d2fb4afb7c
commit fabcaacc51
5 changed files with 224 additions and 43 deletions

@ -40,6 +40,8 @@ struct Object;
struct Lattice;
struct Curve;
struct uiBlock;
struct BezTriple;
struct IpoCurve;
void mesh_to_key(struct Mesh *me, struct KeyBlock *kb);
void key_to_mesh(struct KeyBlock *kb, struct Mesh *me);
@ -61,5 +63,8 @@ void move_keys(struct Object *ob);
void make_rvk_slider(struct uiBlock *block, struct Object *ob, int keynum,
int x, int y, int w, int h, char *tip);
// FIXME: move me somewhere else
struct BezTriple *get_bezt_icu_time(struct IpoCurve *icu, float *frame, float *val);
#endif

@ -196,21 +196,22 @@ typedef struct IpoDriver {
typedef struct IpoCurve {
struct IpoCurve *next, *prev;
struct BPoint *bp;
struct BezTriple *bezt;
struct BPoint *bp; /* are these even used anywhere? */
struct BezTriple *bezt; /* array of BezTriples (sizeof(BezTriple)*totvert. i.e. keyframes */
rctf maxrct, totrct;
rctf maxrct, totrct; /* bounding boxes */
short blocktype, adrcode, vartype;
short totvert;
short ipo, extrap;
short flag, rt;
float ymin, ymax;
unsigned int bitmask;
short blocktype, adrcode, vartype; /* blocktype= ipo-blocktype; adrcode= type of ipo-curve; vartype= 'format' of data */
short totvert; /* total number of BezTriples (i.e. keyframes) on curve */
short ipo, extrap; /* interpolation and extrapolation modes */
short flag, rt; /* flag= settings; rt= ??? */
float ymin, ymax; /* minimum/maximum y-extents for curve */
unsigned int bitmask; /* ??? */
float curval;
float slide_min, slide_max; /* minimum/maximum values for sliders (in action editor) */
float curval; /* value of ipo-curve for current frame */
IpoDriver *driver;
IpoDriver *driver; /* pointer to ipo-driver for this curve */
} IpoCurve;

@ -63,6 +63,7 @@
#include "BKE_action.h"
#include "BKE_ipo.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
/* Everything from source (BIF, BDR, BSE) ------------------------------ */
@ -91,7 +92,7 @@
#include "blendef.h"
#include "mydevice.h"
/* sliders for shapekeys */
static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
{
int i;
@ -116,8 +117,7 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
UI_EMBOSS, UI_HELV, curarea->win);
x = NAMEWIDTH + 1;
y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP)
+ CHANNELHEIGHT/2 - G.v2d->cur.ymin;
y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP) + CHANNELHEIGHT/2 - G.v2d->cur.ymin;
/* make the little 'open the sliders' widget */
BIF_ThemeColor(TH_FACE); // this slot was open...
@ -172,6 +172,169 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
}
static void icu_slider_func(void *voidicu, void *voidignore)
{
/* the callback for the icu sliders ... copies the
* value from the icu->curval into a bezier at the
* right frame on the right ipo curve (creating both the
* ipo curve and the bezier if needed).
*/
IpoCurve *icu= voidicu;
BezTriple *bezt=NULL;
float cfra, icuval;
cfra = frame_to_float(CFRA);
if (G.saction->pin==0 && OBACT)
cfra= get_action_frame(OBACT, cfra);
/* if the ipocurve exists, try to get a bezier
* for this frame
*/
bezt = get_bezt_icu_time(icu, &cfra, &icuval);
/* create the bezier triple if one doesn't exist,
* otherwise modify it's value
*/
if (!bezt) {
insert_vert_ipo(icu, cfra, icu->curval);
}
else {
bezt->vec[1][1] = icu->curval;
}
/* make sure the Ipo's are properly process and
* redraw as necessary
*/
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
allqueue (REDRAWVIEW3D, 0);
allqueue (REDRAWACTION, 0);
allqueue (REDRAWNLA, 0);
allqueue (REDRAWIPO, 0);
allspace(REMAKEIPO, 0);
}
static void make_icu_slider(uiBlock *block, IpoCurve *icu,
int x, int y, int w, int h, char *tip)
{
/* create a slider for the ipo-curve*/
uiBut *but;
if(icu==NULL) return;
if (IS_EQ(icu->slide_max, icu->slide_min)) {
if (IS_EQ(icu->ymax, icu->ymin)) {
if (icu->blocktype == ID_CO) {
/* hack for constraints (and maybe a few others) */
icu->slide_min= 0.0;
icu->slide_max= 1.0;
}
else {
icu->slide_min= -100;
icu->slide_max= 100;
}
}
else {
icu->slide_min= icu->ymin;
icu->slide_max= icu->ymax;
}
}
if (icu->slide_min >= icu->slide_max) {
SWAP(float, icu->slide_min, icu->slide_max);
}
but=uiDefButF(block, NUMSLI, REDRAWVIEW3D, "",
x, y , w, h,
&(icu->curval), icu->slide_min, icu->slide_max,
10, 2, tip);
uiButSetFunc(but, icu_slider_func, icu, NULL);
// no hilite, the winmatrix is not correct later on...
uiButSetFlag(but, UI_NO_HILITE);
}
/* sliders for ipo-curves of active action-channel */
static void action_icu_buts(SpaceAction *saction)
{
bAction *act= saction->action;
bActionChannel *achan;
bConstraintChannel *conchan;
IpoCurve *icu;
char str[64];
float x, y;
uiBlock *block;
/* lets make the action sliders */
/* reset the damn myortho2 or the sliders won't draw/redraw
* correctly *grumble*
*/
mywinset(curarea->win);
myortho2(-0.375, curarea->winx-0.375, G.v2d->cur.ymin, G.v2d->cur.ymax);
sprintf(str, "actionbuttonswin %d", curarea->win);
block= uiNewBlock (&curarea->uiblocks, str,
UI_EMBOSS, UI_HELV, curarea->win);
x = NAMEWIDTH + 1;
y = count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
uiBlockSetEmboss(block, UI_EMBOSSN);
if (G.saction->flag & SACTION_SLIDERS) {
/* sliders are open so draw them */
/* draw backdrop first */
BIF_ThemeColor(TH_FACE); // change this color... it's ugly
glRects(NAMEWIDTH, G.v2d->cur.ymin, NAMEWIDTH+SLIDERWIDTH, G.v2d->cur.ymax);
uiBlockSetEmboss(block, UI_EMBOSS);
for (achan=act->chanbase.first; achan; achan= achan->next) {
if(VISIBLE_ACHAN(achan)) {
y-=CHANNELHEIGHT+CHANNELSKIP;
if (EXPANDED_ACHAN(achan)) {
if (achan->ipo) {
y-=CHANNELHEIGHT+CHANNELSKIP;
if (FILTER_IPO_ACHAN(achan)) {
for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
if (achan->flag & ACHAN_HILIGHTED) {
make_icu_slider(block, icu,
x, y, SLIDERWIDTH-2, CHANNELHEIGHT-2,
"Slider to control current value of IPO-Curve");
}
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
if (achan->constraintChannels.first) {
y-=CHANNELHEIGHT+CHANNELSKIP;
if (FILTER_CON_ACHAN(achan)) {
for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
if ((achan->flag & ACHAN_HILIGHTED) && EDITABLE_CONCHAN(conchan)) {
icu= (IpoCurve *)conchan->ipo->curve.first;
make_icu_slider(block, icu,
x, y, SLIDERWIDTH-2, CHANNELHEIGHT-2,
"Slider to control current value of Constraint Channel");
}
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
}
}
}
}
uiDrawBlock(block);
}
void draw_cfra_action(void)
{
Object *ob;
@ -681,11 +844,9 @@ static void draw_mesh_strips(SpaceAction *saction, Key *key)
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
*/
/* lets not deal with the "speed" Ipo */
if (icu->adrcode==0) continue;
y = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
@ -699,15 +860,13 @@ static void draw_mesh_strips(SpaceAction *saction, Key *key)
glRectf(0, channel_y-CHANNELHEIGHT/2,
frame1_x, channel_y+CHANNELHEIGHT/2);
/* frames one and higher get a saturated orange background
*/
/* frames one and higher get a saturated orange background */
glColor4ub(col2[0], col2[1], col2[2], 0x44);
glRectf(frame1_x, channel_y-CHANNELHEIGHT/2,
G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
glDisable(GL_BLEND);
/* draw the little squares
*/
/* draw the keyframes */
draw_icu_channel(di, icu, y);
}
@ -765,6 +924,7 @@ static void action_blockhandlers(ScrArea *sa)
void drawactionspace(ScrArea *sa, void *spacedata)
{
short ofsx = 0, ofsy = 0;
bAction *act;
Key *key;
float col[3];
short maxymin;
@ -783,6 +943,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
G.saction->action=NULL;
}
key = get_action_mesh_key();
act= G.saction->action;
/* Damn I hate hunting to find my rvk's because
* they have scrolled off of the screen ... this
@ -801,8 +962,10 @@ void drawactionspace(ScrArea *sa, void *spacedata)
* is set to an appropriate value based on whether sliders
* are showing of not
*/
if (key && (G.saction->flag & SACTION_SLIDERS)) ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
else ACTWIDTH = NAMEWIDTH;
if (((key)||(act)) && (G.saction->flag & SACTION_SLIDERS))
ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
else
ACTWIDTH = NAMEWIDTH;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
@ -888,6 +1051,9 @@ void drawactionspace(ScrArea *sa, void *spacedata)
*/
meshactionbuts(G.saction, OBACT, key);
}
else if (act) {
action_icu_buts(G.saction);
}
}
}

@ -2952,7 +2952,7 @@ static void clever_achannel_names(short *mval)
int but=0;
char str[64];
short expand, protect, chantype;
//float slidermin, slidermax;
float slidermin, slidermax;
/* figure out what is under cursor */
act_channel= get_nearest_act_channel(mval, &chantype);
@ -2978,20 +2978,30 @@ static void clever_achannel_names(short *mval)
add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
}
#if 0 /* tempolarily disabled until there is actually something to display */
else if (chantype == ACTTYPE_ICU) {
icu= (IpoCurve *)act_channel;
strcpy(str, getname_ipocurve(icu));
slidermin= icu->ymin; /* ugly hack :) */
slidermax= icu->ymax; /* ugly hack :) */
protect= (icu->flag & IPO_PROTECT);
if (IS_EQ(icu->slide_max, icu->slide_min)) {
if (IS_EQ(icu->ymax, icu->ymin)) {
icu->slide_min= -100.0;
icu->slide_max= 100.0;
}
else {
icu->slide_min= icu->ymin;
icu->slide_max= icu->ymax;
}
}
slidermin= icu->slide_min;
slidermax= icu->slide_max;
//protect= (icu->flag & IPO_PROTECT);
add_numbut(but++, NUM|FLO, "Slider Min:", -10000, slidermax, &slidermin, 0);
add_numbut(but++, NUM|FLO, "Slider Max:", slidermin, 10000, &slidermax, 0);
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
//add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
}
#endif
else {
/* nothing under-cursor */
return;
@ -3001,16 +3011,14 @@ static void clever_achannel_names(short *mval)
/* draw clever-numbut */
if (do_clever_numbuts(str, but, REDRAW)) {
/* restore settings based on type */
#if 0 /* tempolarily disabled until further notice */
if (icu) {
icu->ymin= slidermin; /* ugly hack :) */
icu->ymax= slidermax; /* ugly hack :) */
icu->slide_min= slidermin;
icu->slide_max= slidermax;
if (protect) icu->flag |= IPO_PROTECT;
else icu->flag &= ~IPO_PROTECT;
//if (protect) icu->flag |= IPO_PROTECT;
//else icu->flag &= ~IPO_PROTECT;
}
#endif
/*else */if (conchan) {
else if (conchan) {
strcpy(conchan->name, str);
if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;

@ -126,7 +126,8 @@ static IpoCurve *get_key_icu(Ipo *ipo, int keynum)
return NULL;
}
static BezTriple *get_bezt_icu_time(IpoCurve *icu, float *frame, float *val) {
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