diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h index fdd176e0e64..f0c530808a7 100644 --- a/source/blender/blenkernel/BKE_ipo.h +++ b/source/blender/blenkernel/BKE_ipo.h @@ -24,7 +24,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): 2008, Joshua Leung (Animation Cleanup) * * ***** END GPL LICENSE BLOCK ***** */ @@ -87,6 +87,8 @@ void testhandles_ipocurve(struct IpoCurve *icu); void sort_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 ---------- */ 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); void calc_ipo(struct Ipo *ipo, float ctime); +void calc_ipo_range(struct Ipo *ipo, float *start, float *end); + /* ------------ Keyframe Column Tools -------------- */ void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt); diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index faf8692b89a..0557120a3aa 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -62,6 +62,7 @@ int do_ob_key(struct Object *ob); struct Key *ob_get_key(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_named_keyblock(struct Key *key, const char name[]); // needed for the GE void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 1c720cea21f..98f8a83f809 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -299,7 +299,7 @@ void copy_pose(bPose **dst, bPose *src, int copycon) outPose= MEM_callocN(sizeof(bPose), "pose"); - BLI_duplicatelist (&outPose->chanbase, &src->chanbase); + BLI_duplicatelist(&outPose->chanbase, &src->chanbase); if (copycon) { 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->size, chan->size); + VECCOPY(pchan->eul, chan->eul); QUATCOPY(pchan->quat, chan->quat); + pchan->rotmode= chan->rotmode; Mat4CpyMat4(pchan->chan_mat, (float(*)[4])chan->chan_mat); Mat4CpyMat4(pchan->pose_mat, (float(*)[4])chan->pose_mat); pchan->flag= chan->flag; @@ -697,7 +699,6 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode) bPoseChannel *dchan; const bPoseChannel *schan; bConstraint *dcon, *scon; - float dquat[4], squat[4]; float dstweight; int i; @@ -719,23 +720,34 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode) /* Do the transformation blend */ if (schan->flag & POSE_ROT) { - QUATCOPY(dquat, dchan->quat); - QUATCOPY(squat, schan->quat); - if(mode==ACTSTRIPMODE_BLEND) - QuatInterpol(dchan->quat, dquat, squat, srcweight); - else { - QuatMulFac(squat, srcweight); - QuatMul(dchan->quat, dquat, squat); + /* quat interpolation done separate */ + if (schan->rotmode == PCHAN_ROT_QUAT) { + float dquat[4], squat[4]; + + QUATCOPY(dquat, dchan->quat); + QUATCOPY(squat, schan->quat); + 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) dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight); if (schan->flag & POSE_SIZE) 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; } @@ -749,33 +761,33 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode) dst->ctime= src->ctime; } - +/* Calculate the extents of given action */ void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden) { - const bActionChannel *chan; - const bConstraintChannel *conchan; - const IpoCurve *icu; - float min=999999999.0f, max=-999999999.0; + bActionChannel *chan; + bConstraintChannel *conchan; + IpoCurve *icu; + float min=999999999.0f, max=-999999999.0f; int foundvert=0; - if(act) { + if (act) { for (chan=act->chanbase.first; chan; chan=chan->next) { - if(incl_hidden || (chan->flag & ACHAN_HIDDEN)==0) { - if(chan->ipo) { + if ((incl_hidden) || (chan->flag & ACHAN_HIDDEN)==0) { + if (chan->ipo) { for (icu=chan->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]); + 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; } } } 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) { - if(icu->totvert) { - min= MIN2 (min, icu->bezt[0].vec[1][0]); - max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]); + 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; } } @@ -867,6 +879,7 @@ void rest_pose(bPose *pose) for (i=0; i<3; i++) { pchan->loc[i]= 0.0f; pchan->quat[i+1]= 0.0f; + pchan->eul[i]= 0.0f; pchan->size[i]= 1.0f; } pchan->quat[0]= 1.0f; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 8bb694f45e8..0b5925a0b38 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -180,7 +180,7 @@ static void copy_bonechildren (Bone* newBone, Bone* oldBone) Bone *curBone, *newChildBone; /* 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*/ 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; /* 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); /* 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 tmat[3][3]; + /* get scaling matrix */ SizeToMat3(chan->size, smat); - NormalQuat(chan->quat); - - QuatToMat3(chan->quat, rmat); + /* rotations may either be quats or eulers (no rotation modes for now...) */ + if (chan->rotmode) { + /* 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); - Mat4CpyMat3(chan->chan_mat, tmat); /* prevent action channels breaking chains */ /* 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); } - } /* transform from bone(b) to bone(b+1), store in chan_mat */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b8bfb002075..cbdcfa56ff2 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -69,6 +69,7 @@ #include "BPY_extern.h" #endif + #ifdef HAVE_CONFIG_H #include #endif @@ -3021,44 +3022,53 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta float len= (curveMax[clamp_axis] - curveMin[clamp_axis]); float offset; - /* find bounding-box range where target is located */ - if (ownLoc[clamp_axis] < curveMin[clamp_axis]) { - /* bounding-box range is before */ - offset= curveMin[clamp_axis]; - - while (ownLoc[clamp_axis] < offset) - offset -= len; - - /* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */ - curvetime = (ownLoc[clamp_axis] - offset) / (len); - } - else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) { - /* bounding-box range is after */ - offset= curveMax[clamp_axis]; - - while (ownLoc[clamp_axis] > offset) { - if ((offset + len) > ownLoc[clamp_axis]) - break; - else - offset += len; + /* check to make sure len is not so close to zero that it'll cause errors */ + if (IS_EQ(len, 0) == 0) { + /* find bounding-box range where target is located */ + if (ownLoc[clamp_axis] < curveMin[clamp_axis]) { + /* bounding-box range is before */ + offset= curveMin[clamp_axis]; + + while (ownLoc[clamp_axis] < offset) + offset -= len; + + /* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */ + curvetime = (ownLoc[clamp_axis] - offset) / (len); + } + else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) { + /* bounding-box range is after */ + offset= curveMax[clamp_axis]; + + while (ownLoc[clamp_axis] > offset) { + if ((offset + len) > ownLoc[clamp_axis]) + 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 { - /* as the location falls within bounds, just calculate */ - curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (len); + /* as length is close to zero, curvetime by default should be 0 (i.e. the start) */ + curvetime= 0.0f; } } else { /* no cyclic, so position is clamped to within the bounding box */ if (ownLoc[clamp_axis] <= curveMin[clamp_axis]) - curvetime = 0.0; + curvetime = 0.0f; else if (ownLoc[clamp_axis] >= curveMax[clamp_axis]) - curvetime = 1.0; - else + curvetime = 1.0f; + 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]); + else + curvetime = 0.0f; } /* 3. position on curve */ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 8407c66d584..e5c58860cf5 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -102,8 +102,9 @@ int ob_ar[OB_TOTIPO]= { }; int ac_ar[AC_TOTIPO]= { - AC_LOC_X, AC_LOC_Y, AC_LOC_Z, - AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z, + AC_LOC_X, AC_LOC_Y, AC_LOC_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 }; @@ -584,6 +585,35 @@ float frame_to_float (int cfra) /* see also bsystem_time in object.c */ 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 ********************************* */ /* 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 @@ -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. * 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. @@ -824,7 +853,6 @@ void set_interpolation_ipocurve (IpoCurve *icu, short ipo) for (a=0, bezt=icu->bezt; atotvert; a++, bezt++) bezt->ipo= ipo; } -#endif // TODO: enable when we have per-segment interpolation /* ***************************** Curve Calculations ********************************* */ @@ -1028,7 +1056,6 @@ static float eval_driver (IpoDriver *driver, float ipotime) else #endif /* DISABLE_PYTHON */ { - Object *ob= driver->ob; /* 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") */ -float eval_icu(IpoCurve *icu, float evaltime) +float eval_icu (IpoCurve *icu, float evaltime) { float cvalue = 0.0f; @@ -1157,7 +1184,7 @@ float eval_icu(IpoCurve *icu, float evaltime) /* get pointers */ BezTriple *bezt, *prevbezt, *lastbezt; 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; /* get pointers */ @@ -1192,12 +1219,11 @@ float eval_icu(IpoCurve *icu, float evaltime) } /* evaluation time at or past endpoints? */ - // TODO: for per-bezt interpolation, replace all icu->ipo with (bezt)->ipo if (prevbezt->vec[1][0] >= evaltime) { /* 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 */ - if (icu->ipo==IPO_LIN) { + if (prevbezt->ipo==IPO_LIN) { /* Use the next center point instead of our own handle for * linear interpolated extrapolate */ @@ -1242,9 +1268,9 @@ float eval_icu(IpoCurve *icu, float evaltime) } else if (lastbezt->vec[1][0] <= evaltime) { /* 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 */ - if (icu->ipo==IPO_LIN) { + if (lastbezt->ipo==IPO_LIN) { /* Use the next center point instead of our own handle for * linear interpolated extrapolate */ @@ -1289,16 +1315,15 @@ float eval_icu(IpoCurve *icu, float evaltime) } else { /* 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++) { /* evaltime occurs within the interval defined by these two keyframes */ if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) { /* value depends on interpolation mode */ - if (icu->ipo == IPO_CONST) { + if (prevbezt->ipo == IPO_CONST) { /* constant (evaltime not relevant, so no interpolation needed) */ 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 */ 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 */ - cvalue+= cycyofs; + cvalue += cycyofs; } /* 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) { IpoCurve *icu; - /* 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 - */ + /* loop over IPO-curves, getting a pointer to pchan var to write to */ for (icu= achan->ipo->curve.first; icu; icu= icu->next) { 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 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 *poin= NULL; @@ -1813,6 +1844,22 @@ void *get_pchan_ipo_poin (bPoseChannel *pchan, int adrcode) pchan->flag |= POSE_ROT; 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: poin= &(pchan->loc[0]); pchan->flag |= POSE_LOC; diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index a34da4377b1..5540a262a1d 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -59,6 +59,7 @@ #include "BLI_blenlib.h" + #ifdef HAVE_CONFIG_H #include #endif @@ -1404,3 +1405,18 @@ KeyBlock *key_get_keyblock(Key *key, int index) 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; +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 29624383474..2e969a71b0c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -118,6 +118,7 @@ #include "BKE_global.h" // for G #include "BKE_group.h" #include "BKE_image.h" +#include "BKE_ipo.h" #include "BKE_key.h" //void set_four_ipo #include "BKE_lattice.h" #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) { SpaceAction *saction= (SpaceAction *)sl; 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) { SpaceImage *sima= (SpaceImage *)sl; @@ -4082,6 +4084,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene) else if(sl->spacetype==SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)sl; 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) { SpaceImage *sima= (SpaceImage *)sl; @@ -5580,7 +5583,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) SpaceLink *sl= sa->spacedata.first; while(sl) { 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; } 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)) { 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 */ 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; } } + 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) { bScreen *screen; diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 73a20512470..4095239bfed 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -22,6 +22,7 @@ * * Contributor(s): Original design: Reevan McKay * Contributor(s): Full recode, Ton Roosendaal, Crete 2005 + * Contributor(s): Animation recode, Joshua Leung * * ***** END GPL LICENSE BLOCK ***** */ @@ -70,9 +71,13 @@ typedef struct bPoseChannel { void *dual_quat; 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 eul[3]; /* rotations - written in by actions or transform (but only euler/quat in use at any one time!) */ 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 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' */ int active_marker; /* Index of active-marker (first marker = 1) */ - int pad; + int flag; /* flags for this action */ } bAction; /* ------------- 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 */ typedef struct SpaceAction { struct SpaceLink *next, *prev; ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; float blockscale; - struct ScrArea *area; short blockhandler[8]; - View2D v2d; + View2D v2d; /* depricated, copied to region */ 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 */ 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 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? */ } SpaceAction; @@ -220,6 +234,42 @@ typedef enum AGRP_FLAG { AGRP_MOVED = (1<<31) } 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 -------------- */ /* SpaceAction flag */ @@ -239,7 +289,9 @@ typedef enum SACTION_FLAG { /* hack for moving pose-markers (temp flag) */ SACTION_POSEMARKERS_MOVE = (1<<6), /* 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; /* SpaceAction Mode Settings */ @@ -250,7 +302,7 @@ typedef enum SACTCONT_MODES { SACTCONT_SHAPEKEY, /* editing of gpencil data */ SACTCONT_GPENCIL, - /* dopesheet (unimplemented... future idea?) */ + /* dopesheet */ SACTCONT_DOPESHEET } SACTCONTEXT_MODES; @@ -326,6 +378,13 @@ typedef enum PCHAN_IKFLAG { BONE_IK_NO_ZDOF_TEMP = (1<<12) } 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 diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 93cb9f59860..790b9835b68 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -157,6 +157,7 @@ typedef enum eBone_Flag { 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_TRANSFORM_CHILD = (1<<20), /* Indicates that a parent is also being transformed */ + BONE_UNSELECTABLE = (1<<21), /* bone cannot be selected */ } eBone_Flag; #endif diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h index 6db8358affe..cfca4523dd8 100644 --- a/source/blender/makesdna/DNA_camera_types.h +++ b/source/blender/makesdna/DNA_camera_types.h @@ -76,6 +76,7 @@ typedef struct Camera { #define CAM_SHOWTITLESAFE 8 #define CAM_SHOWNAME 16 #define CAM_ANGLETOGGLE 32 +#define CAM_DS_EXPAND 64 /* yafray: dof sampling switch */ #define CAM_YF_NO_QMC 512 diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index f809cac037d..eb8814171ce 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -88,7 +88,8 @@ typedef struct BevPoint { typedef struct BezTriple { float vec[3][3]; 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 */ } BezTriple; @@ -204,6 +205,7 @@ typedef struct Curve { #define CU_OFFS_PATHDIST 256 #define CU_FAST 512 /* Font: no filling inside editmode */ #define CU_RETOPO 1024 +#define CU_DS_EXPAND 2048 /* spacemode */ #define CU_LEFT 0 diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h index 432399e3581..6d928646b3d 100644 --- a/source/blender/makesdna/DNA_ipo_types.h +++ b/source/blender/makesdna/DNA_ipo_types.h @@ -349,8 +349,8 @@ typedef struct Ipo { /* ******* PoseChannel (ID_PO) ********* */ -#define AC_TOTIPO 10 -#define AC_TOTNAM 10 +#define AC_TOTIPO 13 +#define AC_TOTNAM 13 #define AC_LOC_X 1 #define AC_LOC_Y 2 @@ -360,6 +360,10 @@ typedef struct Ipo { #define AC_SIZE_Y 14 #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_X 26 #define AC_QUAT_Y 27 diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h index 9e49bcfcb9a..13379c44a89 100644 --- a/source/blender/makesdna/DNA_key_types.h +++ b/source/blender/makesdna/DNA_key_types.h @@ -85,7 +85,8 @@ typedef struct Key { #define KEY_BSPLINE 2 /* keyblock->flag */ -#define KEYBLOCK_MUTE 1 +#define KEYBLOCK_MUTE 1 +#define KEYBLOCK_DS_EXPAND 2 #endif diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index f8f2255c1a7..c544be7e388 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -45,7 +45,7 @@ struct CurveMapping; typedef struct Lamp { ID id; - short type, pad3; + short type, flag; int mode; short colormodel, totex; @@ -113,6 +113,9 @@ typedef struct Lamp { /* **************** LAMP ********************* */ +/* flag */ +#define LA_DS_EXPAND 1 + /* type */ #define LA_LOCAL 0 #define LA_SUN 1 diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index d2bb93162d0..d3c294a3d36 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -154,6 +154,8 @@ typedef struct Material { /* flag */ /* for render */ #define MA_IS_USED 1 + /* for dopesheet */ +#define MA_DS_EXPAND 2 /* mode (is int) */ #define MA_TRACEBLE 1 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index b885bbf084e..f3d18e0559b 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -476,8 +476,17 @@ extern Object workob; #define OB_SHAPE_TEMPLOCK 2 /* ob->nlaflag */ -#define OB_NLA_OVERRIDE 1 -#define OB_NLA_COLLAPSED 2 +#define OB_NLA_OVERRIDE (1<<0) +#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 */ #define OB_LOCK_LOCX 1 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index d1af38b9e25..cdf29294197 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -98,7 +98,7 @@ typedef struct SpaceIpo { short butofs, channel; short showkey, blocktype; short menunr, lock; - int flag; + short flag, autosnap; float median[3]; rctf tot; } SpaceIpo; @@ -108,9 +108,10 @@ typedef struct SpaceButs { ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; float blockscale; - struct RenderInfo *ri; - + short blockhandler[8]; + + struct RenderInfo *ri; short cursens, curact; short align, tabo; /* align for panels, tab is old tab */ @@ -638,10 +639,11 @@ typedef struct SpaceImaSel { #define IMS_INFILESLI 4 /* nla->flag */ -#define SNLA_ALLKEYED 1 -#define SNLA_ACTIVELAYERS 2 -#define SNLA_DRAWTIME 4 -#define SNLA_NOTRANSKEYCULL 8 +#define SNLA_ALLKEYED (1<<0) +#define SNLA_ACTIVELAYERS (1<<1) +#define SNLA_DRAWTIME (1<<2) +#define SNLA_NOTRANSKEYCULL (1<<3) +#define SNLA_NODRAWCFRANUM (1<<4) /* time->flag */ /* show timing in frames instead of in seconds */