Merged 'backend' changes from AnimSys2. Many of these changes are necessary for the Dopesheet and other changes I'm currently still stabilising. Those will come in due course.
This commit is contained in:
Joshua Leung 2008-12-19 11:45:46 +00:00
parent 242695011e
commit c752ec9fc4
18 changed files with 339 additions and 106 deletions

@ -24,7 +24,7 @@
* *
* The Original Code is: all of this file. * The Original Code is: all of this file.
* *
* Contributor(s): none yet. * Contributor(s): 2008, Joshua Leung (Animation Cleanup)
* *
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
@ -87,6 +87,8 @@ void testhandles_ipocurve(struct IpoCurve *icu);
void sort_time_ipocurve(struct IpoCurve *icu); void sort_time_ipocurve(struct IpoCurve *icu);
int test_time_ipocurve(struct IpoCurve *icu); int test_time_ipocurve(struct IpoCurve *icu);
void set_interpolation_ipocurve(struct IpoCurve *icu, short ipo);
/* -------- IPO-Curve (Bezier) Calculations ---------- */ /* -------- IPO-Curve (Bezier) Calculations ---------- */
void correct_bezpart(float *v1, float *v2, float *v3, float *v4); void correct_bezpart(float *v1, float *v2, float *v3, float *v4);
@ -101,6 +103,8 @@ void calc_icu(struct IpoCurve *icu, float ctime);
float calc_ipo_time(struct Ipo *ipo, float ctime); float calc_ipo_time(struct Ipo *ipo, float ctime);
void calc_ipo(struct Ipo *ipo, float ctime); void calc_ipo(struct Ipo *ipo, float ctime);
void calc_ipo_range(struct Ipo *ipo, float *start, float *end);
/* ------------ Keyframe Column Tools -------------- */ /* ------------ Keyframe Column Tools -------------- */
void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt); void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt);

@ -62,6 +62,7 @@ int do_ob_key(struct Object *ob);
struct Key *ob_get_key(struct Object *ob); struct Key *ob_get_key(struct Object *ob);
struct KeyBlock *ob_get_keyblock(struct Object *ob); struct KeyBlock *ob_get_keyblock(struct Object *ob);
struct KeyBlock *key_get_keyblock(struct Key *key, int index); struct KeyBlock *key_get_keyblock(struct Key *key, int index);
struct KeyBlock *key_get_named_keyblock(struct Key *key, const char name[]);
// needed for the GE // needed for the GE
void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode); void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode);

@ -299,7 +299,7 @@ void copy_pose(bPose **dst, bPose *src, int copycon)
outPose= MEM_callocN(sizeof(bPose), "pose"); outPose= MEM_callocN(sizeof(bPose), "pose");
BLI_duplicatelist (&outPose->chanbase, &src->chanbase); BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
if (copycon) { if (copycon) {
for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) { for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
@ -401,7 +401,9 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
VECCOPY(pchan->loc, chan->loc); VECCOPY(pchan->loc, chan->loc);
VECCOPY(pchan->size, chan->size); VECCOPY(pchan->size, chan->size);
VECCOPY(pchan->eul, chan->eul);
QUATCOPY(pchan->quat, chan->quat); QUATCOPY(pchan->quat, chan->quat);
pchan->rotmode= chan->rotmode;
Mat4CpyMat4(pchan->chan_mat, (float(*)[4])chan->chan_mat); Mat4CpyMat4(pchan->chan_mat, (float(*)[4])chan->chan_mat);
Mat4CpyMat4(pchan->pose_mat, (float(*)[4])chan->pose_mat); Mat4CpyMat4(pchan->pose_mat, (float(*)[4])chan->pose_mat);
pchan->flag= chan->flag; pchan->flag= chan->flag;
@ -697,7 +699,6 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
bPoseChannel *dchan; bPoseChannel *dchan;
const bPoseChannel *schan; const bPoseChannel *schan;
bConstraint *dcon, *scon; bConstraint *dcon, *scon;
float dquat[4], squat[4];
float dstweight; float dstweight;
int i; int i;
@ -719,23 +720,34 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
/* Do the transformation blend */ /* Do the transformation blend */
if (schan->flag & POSE_ROT) { if (schan->flag & POSE_ROT) {
QUATCOPY(dquat, dchan->quat); /* quat interpolation done separate */
QUATCOPY(squat, schan->quat); if (schan->rotmode == PCHAN_ROT_QUAT) {
if(mode==ACTSTRIPMODE_BLEND) float dquat[4], squat[4];
QuatInterpol(dchan->quat, dquat, squat, srcweight);
else { QUATCOPY(dquat, dchan->quat);
QuatMulFac(squat, srcweight); QUATCOPY(squat, schan->quat);
QuatMul(dchan->quat, dquat, squat); if (mode==ACTSTRIPMODE_BLEND)
QuatInterpol(dchan->quat, dquat, squat, srcweight);
else {
QuatMulFac(squat, srcweight);
QuatMul(dchan->quat, dquat, squat);
}
NormalQuat(dchan->quat);
} }
NormalQuat (dchan->quat);
} }
for (i=0; i<3; i++){ for (i=0; i<3; i++) {
/* blending for loc and scale are pretty self-explanatory... */
if (schan->flag & POSE_LOC) if (schan->flag & POSE_LOC)
dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight); dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
if (schan->flag & POSE_SIZE) if (schan->flag & POSE_SIZE)
dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight); dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
/* euler-rotation interpolation done here instead... */
// FIXME: are these results decent?
if ((schan->flag & POSE_ROT) && (schan->rotmode))
dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
} }
dchan->flag |= schan->flag; dchan->flag |= schan->flag;
} }
@ -749,33 +761,33 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
dst->ctime= src->ctime; dst->ctime= src->ctime;
} }
/* Calculate the extents of given action */
void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden) void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
{ {
const bActionChannel *chan; bActionChannel *chan;
const bConstraintChannel *conchan; bConstraintChannel *conchan;
const IpoCurve *icu; IpoCurve *icu;
float min=999999999.0f, max=-999999999.0; float min=999999999.0f, max=-999999999.0f;
int foundvert=0; int foundvert=0;
if(act) { if (act) {
for (chan=act->chanbase.first; chan; chan=chan->next) { for (chan=act->chanbase.first; chan; chan=chan->next) {
if(incl_hidden || (chan->flag & ACHAN_HIDDEN)==0) { if ((incl_hidden) || (chan->flag & ACHAN_HIDDEN)==0) {
if(chan->ipo) { if (chan->ipo) {
for (icu=chan->ipo->curve.first; icu; icu=icu->next) { for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
if(icu->totvert) { if (icu->totvert) {
min= MIN2 (min, icu->bezt[0].vec[1][0]); min= MIN2(min, icu->bezt[0].vec[1][0]);
max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]); max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
foundvert=1; foundvert=1;
} }
} }
} }
for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) { for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
if(conchan->ipo) { if (conchan->ipo) {
for (icu=conchan->ipo->curve.first; icu; icu=icu->next) { for (icu=conchan->ipo->curve.first; icu; icu=icu->next) {
if(icu->totvert) { if (icu->totvert) {
min= MIN2 (min, icu->bezt[0].vec[1][0]); min= MIN2(min, icu->bezt[0].vec[1][0]);
max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]); max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
foundvert=1; foundvert=1;
} }
} }
@ -867,6 +879,7 @@ void rest_pose(bPose *pose)
for (i=0; i<3; i++) { for (i=0; i<3; i++) {
pchan->loc[i]= 0.0f; pchan->loc[i]= 0.0f;
pchan->quat[i+1]= 0.0f; pchan->quat[i+1]= 0.0f;
pchan->eul[i]= 0.0f;
pchan->size[i]= 1.0f; pchan->size[i]= 1.0f;
} }
pchan->quat[0]= 1.0f; pchan->quat[0]= 1.0f;

@ -180,7 +180,7 @@ static void copy_bonechildren (Bone* newBone, Bone* oldBone)
Bone *curBone, *newChildBone; Bone *curBone, *newChildBone;
/* Copy this bone's list*/ /* Copy this bone's list*/
BLI_duplicatelist (&newBone->childbase, &oldBone->childbase); BLI_duplicatelist(&newBone->childbase, &oldBone->childbase);
/* For each child in the list, update it's children*/ /* For each child in the list, update it's children*/
newChildBone=newBone->childbase.first; newChildBone=newBone->childbase.first;
@ -1216,7 +1216,10 @@ void armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outm
if (pchan==NULL) return; if (pchan==NULL) return;
/* get the inverse matrix of the pchan's transforms */ /* get the inverse matrix of the pchan's transforms */
LocQuatSizeToMat4(pc_trans, pchan->loc, pchan->quat, pchan->size); if (pchan->rotmode)
LocEulSizeToMat4(pc_trans, pchan->loc, pchan->eul, pchan->size);
else
LocQuatSizeToMat4(pc_trans, pchan->loc, pchan->quat, pchan->size);
Mat4Invert(inv_trans, pc_trans); Mat4Invert(inv_trans, pc_trans);
/* Remove the pchan's transforms from it's pose_mat. /* Remove the pchan's transforms from it's pose_mat.
@ -1967,22 +1970,29 @@ void chan_calc_mat(bPoseChannel *chan)
float rmat[3][3]; float rmat[3][3];
float tmat[3][3]; float tmat[3][3];
/* get scaling matrix */
SizeToMat3(chan->size, smat); SizeToMat3(chan->size, smat);
NormalQuat(chan->quat); /* rotations may either be quats or eulers (no rotation modes for now...) */
if (chan->rotmode) {
QuatToMat3(chan->quat, rmat); /* euler rotations (will cause gimble lock... no rotation order to solve that yet) */
EulToMat3(chan->eul, rmat);
}
else {
/* quats are normalised before use to eliminate scaling issues */
NormalQuat(chan->quat);
QuatToMat3(chan->quat, rmat);
}
/* calculate matrix of bone (as 3x3 matrix, but then copy the 4x4) */
Mat3MulMat3(tmat, rmat, smat); Mat3MulMat3(tmat, rmat, smat);
Mat4CpyMat3(chan->chan_mat, tmat); Mat4CpyMat3(chan->chan_mat, tmat);
/* prevent action channels breaking chains */ /* prevent action channels breaking chains */
/* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */ /* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */
if (chan->bone==NULL || !(chan->bone->flag & BONE_CONNECTED)) { if ((chan->bone==NULL) || !(chan->bone->flag & BONE_CONNECTED)) {
VECCOPY(chan->chan_mat[3], chan->loc); VECCOPY(chan->chan_mat[3], chan->loc);
} }
} }
/* transform from bone(b) to bone(b+1), store in chan_mat */ /* transform from bone(b) to bone(b+1), store in chan_mat */

@ -69,6 +69,7 @@
#include "BPY_extern.h" #include "BPY_extern.h"
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
@ -3021,44 +3022,53 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
float len= (curveMax[clamp_axis] - curveMin[clamp_axis]); float len= (curveMax[clamp_axis] - curveMin[clamp_axis]);
float offset; float offset;
/* find bounding-box range where target is located */ /* check to make sure len is not so close to zero that it'll cause errors */
if (ownLoc[clamp_axis] < curveMin[clamp_axis]) { if (IS_EQ(len, 0) == 0) {
/* bounding-box range is before */ /* find bounding-box range where target is located */
offset= curveMin[clamp_axis]; if (ownLoc[clamp_axis] < curveMin[clamp_axis]) {
/* bounding-box range is before */
while (ownLoc[clamp_axis] < offset) offset= curveMin[clamp_axis];
offset -= len;
while (ownLoc[clamp_axis] < offset)
/* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */ offset -= len;
curvetime = (ownLoc[clamp_axis] - offset) / (len);
} /* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */
else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) { curvetime = (ownLoc[clamp_axis] - offset) / (len);
/* bounding-box range is after */ }
offset= curveMax[clamp_axis]; else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) {
/* bounding-box range is after */
while (ownLoc[clamp_axis] > offset) { offset= curveMax[clamp_axis];
if ((offset + len) > ownLoc[clamp_axis])
break; while (ownLoc[clamp_axis] > offset) {
else if ((offset + len) > ownLoc[clamp_axis])
offset += len; break;
else
offset += len;
}
/* now, we calculate as per normal, except using offset instead of curveMax[clamp_axis] */
curvetime = (ownLoc[clamp_axis] - offset) / (len);
}
else {
/* as the location falls within bounds, just calculate */
curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (len);
} }
/* now, we calculate as per normal, except using offset instead of curveMax[clamp_axis] */
curvetime = (ownLoc[clamp_axis] - offset) / (len);
} }
else { else {
/* as the location falls within bounds, just calculate */ /* as length is close to zero, curvetime by default should be 0 (i.e. the start) */
curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (len); curvetime= 0.0f;
} }
} }
else { else {
/* no cyclic, so position is clamped to within the bounding box */ /* no cyclic, so position is clamped to within the bounding box */
if (ownLoc[clamp_axis] <= curveMin[clamp_axis]) if (ownLoc[clamp_axis] <= curveMin[clamp_axis])
curvetime = 0.0; curvetime = 0.0f;
else if (ownLoc[clamp_axis] >= curveMax[clamp_axis]) else if (ownLoc[clamp_axis] >= curveMax[clamp_axis])
curvetime = 1.0; curvetime = 1.0f;
else else if ( IS_EQ((curveMax[clamp_axis] - curveMin[clamp_axis]), 0) == 0 )
curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]); curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]);
else
curvetime = 0.0f;
} }
/* 3. position on curve */ /* 3. position on curve */

@ -102,8 +102,9 @@ int ob_ar[OB_TOTIPO]= {
}; };
int ac_ar[AC_TOTIPO]= { int ac_ar[AC_TOTIPO]= {
AC_LOC_X, AC_LOC_Y, AC_LOC_Z, AC_LOC_X, AC_LOC_Y, AC_LOC_Z,
AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z, AC_EUL_X, AC_EUL_Y, AC_EUL_Z,
AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z,
AC_SIZE_X, AC_SIZE_Y, AC_SIZE_Z AC_SIZE_X, AC_SIZE_Y, AC_SIZE_Z
}; };
@ -584,6 +585,35 @@ float frame_to_float (int cfra) /* see also bsystem_time in object.c */
return ctime; return ctime;
} }
/* Calculate the extents of IPO block's keyframes */
void calc_ipo_range (Ipo *ipo, float *start, float *end)
{
IpoCurve *icu;
float min=999999999.0f, max=-999999999.0f;
short foundvert=0;
if (ipo) {
for (icu=ipo->curve.first; icu; icu=icu->next) {
if (icu->totvert) {
min= MIN2(min, icu->bezt[0].vec[1][0]);
max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
foundvert=1;
}
}
}
/* minimum length is 1 frame */
if (foundvert) {
if (min == max) max += 1.0f;
*start= min;
*end= max;
}
else {
*start= 0.0f;
*end= 1.0f;
}
}
/* ***************************** IPO Curve Sanity ********************************* */ /* ***************************** IPO Curve Sanity ********************************* */
/* The functions here are used in various parts of Blender, usually after some editing /* The functions here are used in various parts of Blender, usually after some editing
* of keyframe data has occurred. They ensure that keyframe data is properly ordered and * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
@ -803,7 +833,6 @@ void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
} }
} }
#if 0 // TODO: enable when we have per-segment interpolation
/* This function sets the interpolation mode for an entire Ipo-Curve. /* This function sets the interpolation mode for an entire Ipo-Curve.
* It is primarily used for patching old files, but is also used in the interface * It is primarily used for patching old files, but is also used in the interface
* to make sure that all segments of the curve use the same interpolation. * to make sure that all segments of the curve use the same interpolation.
@ -824,7 +853,6 @@ void set_interpolation_ipocurve (IpoCurve *icu, short ipo)
for (a=0, bezt=icu->bezt; a<icu->totvert; a++, bezt++) for (a=0, bezt=icu->bezt; a<icu->totvert; a++, bezt++)
bezt->ipo= ipo; bezt->ipo= ipo;
} }
#endif // TODO: enable when we have per-segment interpolation
/* ***************************** Curve Calculations ********************************* */ /* ***************************** Curve Calculations ********************************* */
@ -1028,7 +1056,6 @@ static float eval_driver (IpoDriver *driver, float ipotime)
else else
#endif /* DISABLE_PYTHON */ #endif /* DISABLE_PYTHON */
{ {
Object *ob= driver->ob; Object *ob= driver->ob;
/* must have an object to evaluate */ /* must have an object to evaluate */
@ -1140,7 +1167,7 @@ static float eval_driver (IpoDriver *driver, float ipotime)
} }
/* evaluate and return the value of the given IPO-curve at the specified frame ("evaltime") */ /* evaluate and return the value of the given IPO-curve at the specified frame ("evaltime") */
float eval_icu(IpoCurve *icu, float evaltime) float eval_icu (IpoCurve *icu, float evaltime)
{ {
float cvalue = 0.0f; float cvalue = 0.0f;
@ -1157,7 +1184,7 @@ float eval_icu(IpoCurve *icu, float evaltime)
/* get pointers */ /* get pointers */
BezTriple *bezt, *prevbezt, *lastbezt; BezTriple *bezt, *prevbezt, *lastbezt;
float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac; float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
float cycdx, cycdy, ofs, cycyofs= 0.0; float cycdx, cycdy, ofs, cycyofs= 0.0f;
int a, b; int a, b;
/* get pointers */ /* get pointers */
@ -1192,12 +1219,11 @@ float eval_icu(IpoCurve *icu, float evaltime)
} }
/* evaluation time at or past endpoints? */ /* evaluation time at or past endpoints? */
// TODO: for per-bezt interpolation, replace all icu->ipo with (bezt)->ipo
if (prevbezt->vec[1][0] >= evaltime) { if (prevbezt->vec[1][0] >= evaltime) {
/* before or on first keyframe */ /* before or on first keyframe */
if ((icu->extrap & IPO_DIR) && (icu->ipo != IPO_CONST)) { if ((icu->extrap & IPO_DIR) && (prevbezt->ipo != IPO_CONST)) {
/* linear or bezier interpolation */ /* linear or bezier interpolation */
if (icu->ipo==IPO_LIN) { if (prevbezt->ipo==IPO_LIN) {
/* Use the next center point instead of our own handle for /* Use the next center point instead of our own handle for
* linear interpolated extrapolate * linear interpolated extrapolate
*/ */
@ -1242,9 +1268,9 @@ float eval_icu(IpoCurve *icu, float evaltime)
} }
else if (lastbezt->vec[1][0] <= evaltime) { else if (lastbezt->vec[1][0] <= evaltime) {
/* after or on last keyframe */ /* after or on last keyframe */
if( (icu->extrap & IPO_DIR) && (icu->ipo != IPO_CONST)) { if( (icu->extrap & IPO_DIR) && (lastbezt->ipo != IPO_CONST)) {
/* linear or bezier interpolation */ /* linear or bezier interpolation */
if (icu->ipo==IPO_LIN) { if (lastbezt->ipo==IPO_LIN) {
/* Use the next center point instead of our own handle for /* Use the next center point instead of our own handle for
* linear interpolated extrapolate * linear interpolated extrapolate
*/ */
@ -1289,16 +1315,15 @@ float eval_icu(IpoCurve *icu, float evaltime)
} }
else { else {
/* evaltime occurs somewhere in the middle of the curve */ /* evaltime occurs somewhere in the middle of the curve */
// TODO: chould be optimised by using a binary search instead???
for (a=0; prevbezt && bezt && (a < icu->totvert-1); a++, prevbezt=bezt, bezt++) { for (a=0; prevbezt && bezt && (a < icu->totvert-1); a++, prevbezt=bezt, bezt++) {
/* evaltime occurs within the interval defined by these two keyframes */ /* evaltime occurs within the interval defined by these two keyframes */
if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) { if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
/* value depends on interpolation mode */ /* value depends on interpolation mode */
if (icu->ipo == IPO_CONST) { if (prevbezt->ipo == IPO_CONST) {
/* constant (evaltime not relevant, so no interpolation needed) */ /* constant (evaltime not relevant, so no interpolation needed) */
cvalue= prevbezt->vec[1][1]; cvalue= prevbezt->vec[1][1];
} }
else if (icu->ipo == IPO_LIN) { else if (prevbezt->ipo == IPO_LIN) {
/* linear - interpolate between values of the two keyframes */ /* linear - interpolate between values of the two keyframes */
fac= bezt->vec[1][0] - prevbezt->vec[1][0]; fac= bezt->vec[1][0] - prevbezt->vec[1][0];
@ -1339,7 +1364,7 @@ float eval_icu(IpoCurve *icu, float evaltime)
} }
/* apply y-offset (for 'cyclic extrapolation') to calculated value */ /* apply y-offset (for 'cyclic extrapolation') to calculated value */
cvalue+= cycyofs; cvalue += cycyofs;
} }
/* clamp evaluated value to lie within allowable value range for this channel */ /* clamp evaluated value to lie within allowable value range for this channel */
@ -1467,12 +1492,17 @@ void execute_action_ipo (bActionChannel *achan, bPoseChannel *pchan)
if (achan && achan->ipo && pchan) { if (achan && achan->ipo && pchan) {
IpoCurve *icu; IpoCurve *icu;
/* loop over IPO-curves, getting a pointer to pchan var to write to /* loop over IPO-curves, getting a pointer to pchan var to write to */
* - assume for now that only 'float' channels will ever get written into
*/
for (icu= achan->ipo->curve.first; icu; icu= icu->next) { for (icu= achan->ipo->curve.first; icu; icu= icu->next) {
void *poin= get_pchan_ipo_poin(pchan, icu->adrcode); void *poin= get_pchan_ipo_poin(pchan, icu->adrcode);
if (poin) write_ipo_poin(poin, IPO_FLOAT, icu->curval);
if (poin) {
/* only euler-rotations are of type float-degree, all others are 'float' only */
if (ELEM3(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z))
write_ipo_poin(poin, IPO_FLOAT_DEGR, icu->curval);
else
write_ipo_poin(poin, IPO_FLOAT, icu->curval);
}
} }
} }
} }
@ -1791,6 +1821,7 @@ void clear_delta_obipo(Ipo *ipo)
/* --------------------- Get Pointer API ----------------------------- */ /* --------------------- Get Pointer API ----------------------------- */
/* get pointer to pose-channel's channel, but set appropriate flags first */ /* get pointer to pose-channel's channel, but set appropriate flags first */
// TODO: most channels (except euler rots, which are float-degr) are floats, so do we need type arg?
void *get_pchan_ipo_poin (bPoseChannel *pchan, int adrcode) void *get_pchan_ipo_poin (bPoseChannel *pchan, int adrcode)
{ {
void *poin= NULL; void *poin= NULL;
@ -1813,6 +1844,22 @@ void *get_pchan_ipo_poin (bPoseChannel *pchan, int adrcode)
pchan->flag |= POSE_ROT; pchan->flag |= POSE_ROT;
break; break;
case AC_EUL_X:
poin= &(pchan->eul[0]);
pchan->flag |= POSE_ROT;
//type= IPO_FLOAT_DEGR;
break;
case AC_EUL_Y:
poin= &(pchan->eul[1]);
pchan->flag |= POSE_ROT;
//type= IPO_FLOAT_DEGR;
break;
case AC_EUL_Z:
poin= &(pchan->eul[2]);
pchan->flag |= POSE_ROT;
//type= IPO_FLOAT_DEGR;
break;
case AC_LOC_X: case AC_LOC_X:
poin= &(pchan->loc[0]); poin= &(pchan->loc[0]);
pchan->flag |= POSE_LOC; pchan->flag |= POSE_LOC;

@ -59,6 +59,7 @@
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
@ -1404,3 +1405,18 @@ KeyBlock *key_get_keyblock(Key *key, int index)
return NULL; return NULL;
} }
/* get the appropriate KeyBlock given a name to search for */
KeyBlock *key_get_named_keyblock(Key *key, const char name[])
{
KeyBlock *kb;
if (key && name) {
for (kb= key->block.first; kb; kb= kb->next) {
if (strcmp(name, kb->name)==0)
return kb;
}
}
return NULL;
}

@ -118,6 +118,7 @@
#include "BKE_global.h" // for G #include "BKE_global.h" // for G
#include "BKE_group.h" #include "BKE_group.h"
#include "BKE_image.h" #include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_key.h" //void set_four_ipo #include "BKE_key.h" //void set_four_ipo
#include "BKE_lattice.h" #include "BKE_lattice.h"
#include "BKE_library.h" // for wich_libbase #include "BKE_library.h" // for wich_libbase
@ -3901,6 +3902,7 @@ static void lib_link_screen(FileData *fd, Main *main)
else if(sl->spacetype==SPACE_ACTION) { else if(sl->spacetype==SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)sl; SpaceAction *saction= (SpaceAction *)sl;
saction->action = newlibadr(fd, sc->id.lib, saction->action); saction->action = newlibadr(fd, sc->id.lib, saction->action);
saction->ads.source= newlibadr(fd, sc->id.lib, saction->ads.source);
} }
else if(sl->spacetype==SPACE_IMAGE) { else if(sl->spacetype==SPACE_IMAGE) {
SpaceImage *sima= (SpaceImage *)sl; SpaceImage *sima= (SpaceImage *)sl;
@ -4082,6 +4084,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
else if(sl->spacetype==SPACE_ACTION) { else if(sl->spacetype==SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)sl; SpaceAction *saction= (SpaceAction *)sl;
saction->action = restore_pointer_by_name(newmain, (ID *)saction->action, 1); saction->action = restore_pointer_by_name(newmain, (ID *)saction->action, 1);
saction->ads.source= restore_pointer_by_name(newmain, (ID *)saction->ads.source, 1);
} }
else if(sl->spacetype==SPACE_IMAGE) { else if(sl->spacetype==SPACE_IMAGE) {
SpaceImage *sima= (SpaceImage *)sl; SpaceImage *sima= (SpaceImage *)sl;
@ -5580,7 +5583,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
SpaceLink *sl= sa->spacedata.first; SpaceLink *sl= sa->spacedata.first;
while(sl) { while(sl) {
if(sl->spacetype==SPACE_BUTS) { if(sl->spacetype==SPACE_BUTS) {
SpaceButs *sbuts= (SpaceButs*) sl; //SpaceButs *sbuts= (SpaceButs*) sl;
//XXX sbuts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK; //XXX sbuts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK;
} }
sl= sl->next; sl= sl->next;
@ -8277,6 +8280,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) { if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) {
Scene *sce; Scene *sce;
Ipo *ipo;
IpoCurve *icu;
/* fix IPO-curves to work with new interpolation options */
for (ipo=main->ipo.first; ipo; ipo= ipo->id.next) {
for (icu= ipo->curve.first; icu; icu= icu->next)
set_interpolation_ipocurve(icu, icu->ipo);
}
/* Note, these will need to be added for painting */ /* Note, these will need to be added for painting */
for (sce= main->scene.first; sce; sce= sce->id.next) { for (sce= main->scene.first; sce; sce= sce->id.next) {
@ -8284,6 +8295,43 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sce->toolsettings->imapaint.normal_angle = 80; sce->toolsettings->imapaint.normal_angle = 80;
} }
} }
if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 3)) {
bScreen *sc;
/* adjust default settings for Animation Editors */
for (sc= main->screen.first; sc; sc= sc->id.next) {
ScrArea *sa;
for (sa= sc->areabase.first; sa; sa= sa->next) {
SpaceLink *sl;
for (sl= sa->spacedata.first; sl; sl= sl->next) {
switch (sl->spacetype) {
case SPACE_ACTION:
{
SpaceAction *sact= (SpaceAction *)sl;
sact->mode= SACTCONT_DOPESHEET;
sact->autosnap= SACTSNAP_FRAME;
}
break;
case SPACE_IPO:
{
SpaceIpo *sipo= (SpaceIpo *)sl;
sipo->autosnap= SACTSNAP_FRAME;
}
break;
case SPACE_NLA:
{
SpaceNla *snla= (SpaceNla *)sl;
snla->autosnap= SACTSNAP_FRAME;
}
break;
}
}
}
}
}
if (main->versionfile < 250) { if (main->versionfile < 250) {
bScreen *screen; bScreen *screen;

@ -22,6 +22,7 @@
* *
* Contributor(s): Original design: Reevan McKay * Contributor(s): Original design: Reevan McKay
* Contributor(s): Full recode, Ton Roosendaal, Crete 2005 * Contributor(s): Full recode, Ton Roosendaal, Crete 2005
* Contributor(s): Animation recode, Joshua Leung
* *
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
@ -70,9 +71,13 @@ typedef struct bPoseChannel {
void *dual_quat; void *dual_quat;
void *b_bone_dual_quats; void *b_bone_dual_quats;
float loc[3]; /* written in by actions or transform */ float loc[3]; /* transforms - written in by actions or transform */
float size[3]; float size[3];
float eul[3]; /* rotations - written in by actions or transform (but only euler/quat in use at any one time!) */
float quat[4]; float quat[4];
short rotmode; /* for now either quat (0), or xyz-euler (1) */
short pad;
float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */ float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */
float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat */ float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat */
@ -166,30 +171,39 @@ typedef struct bAction {
ListBase markers; /* TimeMarkers local to this Action for labelling 'poses' */ ListBase markers; /* TimeMarkers local to this Action for labelling 'poses' */
int active_marker; /* Index of active-marker (first marker = 1) */ int active_marker; /* Index of active-marker (first marker = 1) */
int pad; int flag; /* flags for this action */
} bAction; } bAction;
/* ------------- Action Editor --------------------- */ /* ------------- Action Editor --------------------- */
/* Storage for Dopesheet/Grease-Pencil Editor data */
typedef struct bDopeSheet {
ID *source; /* currently ID_SCE (for Dopesheet), and ID_SC (for Grease Pencil) */
ListBase chanbase; /* cache for channels (only initialised when pinned) */ // XXX not used!
int filterflag; /* flags to use for filtering data */
int flag; /* standard flags */
} bDopeSheet;
/* Action Editor Space. This is defined here instead of in DNA_space_types.h */ /* Action Editor Space. This is defined here instead of in DNA_space_types.h */
typedef struct SpaceAction { typedef struct SpaceAction {
struct SpaceLink *next, *prev; struct SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */ ListBase regionbase; /* storage of regions for inactive spaces */
int spacetype; int spacetype;
float blockscale; float blockscale;
struct ScrArea *area;
short blockhandler[8]; short blockhandler[8];
View2D v2d; View2D v2d; /* depricated, copied to region */
bAction *action; /* the currently active action */ bAction *action; /* the currently active action */
bDopeSheet ads; /* the currently active context (when not showing action) */
char mode, autosnap; /* mode: editing context; autosnap: automatic keyframe snapping mode */ char mode, autosnap; /* mode: editing context; autosnap: automatic keyframe snapping mode */
short flag, actnr; /* flag: bitmapped settings; */ short flag, actnr; /* flag: bitmapped settings; */
short pin, lock; /* pin: keep showing current action; actnr: used for finding chosen action from menu; lock: lock time to other windows */ short pin, lock; /* pin: keep showing current action; actnr: used for finding chosen action from menu; lock: lock time to other windows */
short actwidth; /* width of the left-hand side name panel (in pixels?) */ short actwidth; /* width of the left-hand side name panel (in pixels?) */ // XXX depreceated!
float timeslide; /* for Time-Slide transform mode drawing - current frame? */ float timeslide; /* for Time-Slide transform mode drawing - current frame? */
} SpaceAction; } SpaceAction;
@ -220,6 +234,42 @@ typedef enum AGRP_FLAG {
AGRP_MOVED = (1<<31) AGRP_MOVED = (1<<31)
} AGRP_FLAG; } AGRP_FLAG;
/* 'Action' Channel flags */
typedef enum ACT_FLAG {
ACTC_SELECTED = (1<<0),
ACTC_EXPANDED = (1<<1),
} ACT_FLAG;
/* ------------ DopeSheet Flags ------------------ */
/* DopeSheet filter-flag */
typedef enum DOPESHEET_FILTERFLAG {
/* general filtering */
ADS_FILTER_ONLYSEL = (1<<0),
/* datatype-based filtering */
ADS_FILTER_NOOBJ = (1<<4),
ADS_FILTER_NOARM = (1<<5),
ADS_FILTER_NOSHAPEKEYS = (1<<6),
ADS_FILTER_NOIPOS = (1<<7),
ADS_FILTER_NOACTS = (1<<8),
ADS_FILTER_NOCONSTRAINTS = (1<<9),
ADS_FILTER_NOCAM = (1<<10),
ADS_FILTER_NOMAT = (1<<11),
ADS_FILTER_NOLAM = (1<<12),
ADS_FILTER_NOCUR = (1<<13),
/* combination filters (some only used at runtime) */
ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR),
ADS_FILTER_NLADUMMY = (ADS_FILTER_NOACTS|ADS_FILTER_NOSHAPEKEYS|ADS_FILTER_NOOBDATA),
} DOPESHEET_FILTERFLAG;
/* DopeSheet general flags */
//typedef enum DOPESHEET_FLAG {
//} DOPESHEET_FLAG;
/* ------------ Action Editor Flags -------------- */ /* ------------ Action Editor Flags -------------- */
/* SpaceAction flag */ /* SpaceAction flag */
@ -239,7 +289,9 @@ typedef enum SACTION_FLAG {
/* hack for moving pose-markers (temp flag) */ /* hack for moving pose-markers (temp flag) */
SACTION_POSEMARKERS_MOVE = (1<<6), SACTION_POSEMARKERS_MOVE = (1<<6),
/* don't draw action channels using group colours (where applicable) */ /* don't draw action channels using group colours (where applicable) */
SACTION_NODRAWGCOLORS = (1<<7) SACTION_NODRAWGCOLORS = (1<<7),
/* don't draw current frame number beside frame indicator */
SACTION_NODRAWCFRANUM = (1<<8),
} SACTION_FLAG; } SACTION_FLAG;
/* SpaceAction Mode Settings */ /* SpaceAction Mode Settings */
@ -250,7 +302,7 @@ typedef enum SACTCONT_MODES {
SACTCONT_SHAPEKEY, SACTCONT_SHAPEKEY,
/* editing of gpencil data */ /* editing of gpencil data */
SACTCONT_GPENCIL, SACTCONT_GPENCIL,
/* dopesheet (unimplemented... future idea?) */ /* dopesheet */
SACTCONT_DOPESHEET SACTCONT_DOPESHEET
} SACTCONTEXT_MODES; } SACTCONTEXT_MODES;
@ -326,6 +378,13 @@ typedef enum PCHAN_IKFLAG {
BONE_IK_NO_ZDOF_TEMP = (1<<12) BONE_IK_NO_ZDOF_TEMP = (1<<12)
} PCHAN_IKFLAG; } PCHAN_IKFLAG;
/* PoseChannel->rotmode */
typedef enum PCHAN_ROTMODE {
/* quaternion rotations (default, and for older Blender versions) */
PCHAN_ROT_QUAT = 0,
/* euler rotations (xyz only) */
PCHAN_ROT_EUL,
} PCHAN_ROTMODE;
#endif #endif

@ -157,6 +157,7 @@ typedef enum eBone_Flag {
BONE_NO_CYCLICOFFSET = (1<<18), /* when no parent, bone will not get cyclic offset */ BONE_NO_CYCLICOFFSET = (1<<18), /* when no parent, bone will not get cyclic offset */
BONE_EDITMODE_LOCKED = (1<<19), /* bone transforms are locked in EditMode */ BONE_EDITMODE_LOCKED = (1<<19), /* bone transforms are locked in EditMode */
BONE_TRANSFORM_CHILD = (1<<20), /* Indicates that a parent is also being transformed */ BONE_TRANSFORM_CHILD = (1<<20), /* Indicates that a parent is also being transformed */
BONE_UNSELECTABLE = (1<<21), /* bone cannot be selected */
} eBone_Flag; } eBone_Flag;
#endif #endif

@ -76,6 +76,7 @@ typedef struct Camera {
#define CAM_SHOWTITLESAFE 8 #define CAM_SHOWTITLESAFE 8
#define CAM_SHOWNAME 16 #define CAM_SHOWNAME 16
#define CAM_ANGLETOGGLE 32 #define CAM_ANGLETOGGLE 32
#define CAM_DS_EXPAND 64
/* yafray: dof sampling switch */ /* yafray: dof sampling switch */
#define CAM_YF_NO_QMC 512 #define CAM_YF_NO_QMC 512

@ -88,7 +88,8 @@ typedef struct BevPoint {
typedef struct BezTriple { typedef struct BezTriple {
float vec[3][3]; float vec[3][3];
float alfa, weight, radius; /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */ float alfa, weight, radius; /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */
short h1, h2; /* h1, h2: the handle type of the two handles */ short ipo; /* ipo: interpolation mode for segment from this BezTriple to the next */
char h1, h2; /* h1, h2: the handle type of the two handles */
char f1, f2, f3, hide; /* f1, f2, f3: used for selection status, hide: used to indicate whether BezTriple is hidden */ char f1, f2, f3, hide; /* f1, f2, f3: used for selection status, hide: used to indicate whether BezTriple is hidden */
} BezTriple; } BezTriple;
@ -204,6 +205,7 @@ typedef struct Curve {
#define CU_OFFS_PATHDIST 256 #define CU_OFFS_PATHDIST 256
#define CU_FAST 512 /* Font: no filling inside editmode */ #define CU_FAST 512 /* Font: no filling inside editmode */
#define CU_RETOPO 1024 #define CU_RETOPO 1024
#define CU_DS_EXPAND 2048
/* spacemode */ /* spacemode */
#define CU_LEFT 0 #define CU_LEFT 0

@ -349,8 +349,8 @@ typedef struct Ipo {
/* ******* PoseChannel (ID_PO) ********* */ /* ******* PoseChannel (ID_PO) ********* */
#define AC_TOTIPO 10 #define AC_TOTIPO 13
#define AC_TOTNAM 10 #define AC_TOTNAM 13
#define AC_LOC_X 1 #define AC_LOC_X 1
#define AC_LOC_Y 2 #define AC_LOC_Y 2
@ -360,6 +360,10 @@ typedef struct Ipo {
#define AC_SIZE_Y 14 #define AC_SIZE_Y 14
#define AC_SIZE_Z 15 #define AC_SIZE_Z 15
#define AC_EUL_X 16
#define AC_EUL_Y 17
#define AC_EUL_Z 18
#define AC_QUAT_W 25 #define AC_QUAT_W 25
#define AC_QUAT_X 26 #define AC_QUAT_X 26
#define AC_QUAT_Y 27 #define AC_QUAT_Y 27

@ -85,7 +85,8 @@ typedef struct Key {
#define KEY_BSPLINE 2 #define KEY_BSPLINE 2
/* keyblock->flag */ /* keyblock->flag */
#define KEYBLOCK_MUTE 1 #define KEYBLOCK_MUTE 1
#define KEYBLOCK_DS_EXPAND 2
#endif #endif

@ -45,7 +45,7 @@ struct CurveMapping;
typedef struct Lamp { typedef struct Lamp {
ID id; ID id;
short type, pad3; short type, flag;
int mode; int mode;
short colormodel, totex; short colormodel, totex;
@ -113,6 +113,9 @@ typedef struct Lamp {
/* **************** LAMP ********************* */ /* **************** LAMP ********************* */
/* flag */
#define LA_DS_EXPAND 1
/* type */ /* type */
#define LA_LOCAL 0 #define LA_LOCAL 0
#define LA_SUN 1 #define LA_SUN 1

@ -154,6 +154,8 @@ typedef struct Material {
/* flag */ /* flag */
/* for render */ /* for render */
#define MA_IS_USED 1 #define MA_IS_USED 1
/* for dopesheet */
#define MA_DS_EXPAND 2
/* mode (is int) */ /* mode (is int) */
#define MA_TRACEBLE 1 #define MA_TRACEBLE 1

@ -476,8 +476,17 @@ extern Object workob;
#define OB_SHAPE_TEMPLOCK 2 #define OB_SHAPE_TEMPLOCK 2
/* ob->nlaflag */ /* ob->nlaflag */
#define OB_NLA_OVERRIDE 1 #define OB_NLA_OVERRIDE (1<<0)
#define OB_NLA_COLLAPSED 2 #define OB_NLA_COLLAPSED (1<<1)
/* object-channel expanded status */
#define OB_ADS_COLLAPSED (1<<10)
/* object's ipo-block */
#define OB_ADS_SHOWIPO (1<<11)
/* object's constraint channels */
#define OB_ADS_SHOWCONS (1<<12)
/* object's material channels */
#define OB_ADS_SHOWMATS (1<<13)
/* ob->protectflag */ /* ob->protectflag */
#define OB_LOCK_LOCX 1 #define OB_LOCK_LOCX 1

@ -98,7 +98,7 @@ typedef struct SpaceIpo {
short butofs, channel; short butofs, channel;
short showkey, blocktype; short showkey, blocktype;
short menunr, lock; short menunr, lock;
int flag; short flag, autosnap;
float median[3]; float median[3];
rctf tot; rctf tot;
} SpaceIpo; } SpaceIpo;
@ -108,9 +108,10 @@ typedef struct SpaceButs {
ListBase regionbase; /* storage of regions for inactive spaces */ ListBase regionbase; /* storage of regions for inactive spaces */
int spacetype; int spacetype;
float blockscale; float blockscale;
struct RenderInfo *ri;
short blockhandler[8]; short blockhandler[8];
struct RenderInfo *ri;
short cursens, curact; short cursens, curact;
short align, tabo; /* align for panels, tab is old tab */ short align, tabo; /* align for panels, tab is old tab */
@ -638,10 +639,11 @@ typedef struct SpaceImaSel {
#define IMS_INFILESLI 4 #define IMS_INFILESLI 4
/* nla->flag */ /* nla->flag */
#define SNLA_ALLKEYED 1 #define SNLA_ALLKEYED (1<<0)
#define SNLA_ACTIVELAYERS 2 #define SNLA_ACTIVELAYERS (1<<1)
#define SNLA_DRAWTIME 4 #define SNLA_DRAWTIME (1<<2)
#define SNLA_NOTRANSKEYCULL 8 #define SNLA_NOTRANSKEYCULL (1<<3)
#define SNLA_NODRAWCFRANUM (1<<4)
/* time->flag */ /* time->flag */
/* show timing in frames instead of in seconds */ /* show timing in frames instead of in seconds */