Page MenuHome

bakefixed.patch

File Metadata

Author
Roland Hess (harkyman)
Created
Nov 13 2013, 1:03 PM

bakefixed.patch

Index: source/blender/blenkernel/BKE_action.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/BKE_action.h,v
retrieving revision 1.15
diff -u -r1.15 BKE_action.h
--- source/blender/blenkernel/BKE_action.h 15 Nov 2005 22:39:20 -0000 1.15
+++ source/blender/blenkernel/BKE_action.h 6 Jan 2006 17:13:12 -0000
@@ -135,21 +135,27 @@
/* exported for game engine */
void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode);
void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
+void do_nla(struct Object *ob, int blocktype);
+void do_nla_float(struct Object *ob, int blocktype, float floattime);
/* map global time (frame nr) to strip converted time, doesn't clip */
float get_action_frame(struct Object *ob, float cframe);
/* map strip time to global time (frame nr) */
float get_action_frame_inv(struct Object *ob, float cframe);
+float get_actionstrip_frame(struct bActionStrip *strip, float cframe, int invert);
+
+/* get action frame when using stride */
+float stridechannel_frame(struct Object *ob, struct bActionStrip *strip, struct Path *path, float pathdist, float *stride_offset);
+
#ifdef __cplusplus
};
#endif
/* nla strip flag */
-enum {
- POSE_BLEND = 0,
- POSE_ADD
-};
+#define POSE_BLEND 0x00;
+#define POSE_ADD 0x01;
+#define POSE_MULT 0x02;
#endif
Index: source/blender/blenkernel/BKE_ipo.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/BKE_ipo.h,v
retrieving revision 1.10
diff -u -r1.10 BKE_ipo.h
--- source/blender/blenkernel/BKE_ipo.h 10 Oct 2005 18:05:29 -0000 1.10
+++ source/blender/blenkernel/BKE_ipo.h 6 Jan 2006 17:13:12 -0000
@@ -103,6 +103,8 @@
void clear_delta_obipo(struct Ipo *ipo);
void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt);
void make_cfra_list(struct Ipo *ipo, struct ListBase *elems);
+void add_to_cfra_elem_float(struct ListBase *lb, float cfra);
+void set_posechannel_keyflags(struct bActionChannel *achan, struct bPoseChannel *pchan, float ctime);
/* the sort is an IPO_Channel... */
int IPO_GetChannels(struct Ipo *ipo, short *channels);
Index: source/blender/blenkernel/intern/action.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/intern/action.c,v
retrieving revision 1.50
diff -u -r1.50 action.c
--- source/blender/blenkernel/intern/action.c 14 Dec 2005 14:10:04 -0000 1.50
+++ source/blender/blenkernel/intern/action.c 6 Jan 2006 17:13:13 -0000
@@ -359,15 +359,10 @@
{
float dstweight;
- switch (mode){
- case POSE_BLEND:
- dstweight = 1.0F - srcweight;
- break;
- case POSE_ADD:
- dstweight = 1.0F;
- break;
- default :
- dstweight = 1.0F;
+ if ((mode&ACTSTRIPMODE_ADD) || (mode&ACTSTRIPMODE_MULT)) {
+ dstweight = 1.0F;
+ } else {
+ dstweight = 1.0F - srcweight;
}
VecLerpf(dst->stride_offset, dst->stride_offset, src->stride_offset, srcweight);
@@ -379,23 +374,23 @@
bPoseChannel *dchan;
const bPoseChannel *schan;
bConstraint *dcon, *scon;
- float dquat[4], squat[4];
+ float dquat[4], squat[4], amat[4][4], bmat[4][4], cmat[4][4], dloc[3];
float dstweight;
int i;
- switch (mode){
- case POSE_BLEND:
- dstweight = 1.0F - srcweight;
- break;
- case POSE_ADD:
- dstweight = 1.0F;
- break;
- default :
+ if ((mode&ACTSTRIPMODE_ADD) || (mode&ACTSTRIPMODE_MULT)) {
dstweight = 1.0F;
+ } else {
+ dstweight = 1.0F - srcweight;
}
schan= src->chanbase.first;
for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
+ if (dstweight < .001) { /* accumulate keyflags */
+ dchan->keyflag=schan->keyflag;
+ } else {
+ dchan->keyflag|=schan->keyflag;
+ }
if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
/* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
@@ -403,21 +398,44 @@
if (schan->flag & POSE_ROT) {
QUATCOPY(dquat, dchan->quat);
QUATCOPY(squat, schan->quat);
- if(mode==POSE_BLEND)
- QuatInterpol(dchan->quat, dquat, squat, srcweight);
- else
- QuatAdd(dchan->quat, dquat, squat, srcweight);
- NormalQuat (dchan->quat);
- }
+ if ((mode&ACTSTRIPMODE_ADD)||(mode&ACTSTRIPMODE_MULT)) {
+ if (mode&ACTSTRIPMODE_MULT) {
+ /* poses in mult mode always evaluate quats, if we do it here, it doubles the effect */
+ } else {
+ QuatAdd(dchan->quat, dquat, squat, srcweight);
+ }
+ } else {
+ QuatInterpol(dchan->quat, dquat, squat, srcweight);
+ }
- for (i=0; i<3; i++){
- if (schan->flag & POSE_LOC)
- dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
+ }
+ if (mode&ACTSTRIPMODE_MULT) { /* perturb the source location keys based on local bone rotation */
+ QUATCOPY(dquat, dchan->quat);
+ QUATCOPY(squat, schan->quat);
+ QuatToMat4(dquat,amat);
+ VecCopyf(amat[3],dchan->loc);
+ QuatToMat4(squat,bmat);
+ VecCopyf(bmat[3],schan->loc);
+ Mat4MulMat4(cmat,amat,bmat);
+ Mat4Ortho(cmat);
+ Mat4ToQuat(cmat,dchan->quat);
+ NormalQuat(dchan->quat);
+ VecCopyf(dchan->loc,cmat[3]);
+ }
+
+ for (i=0; i<3; i++){
+ if (schan->flag & POSE_LOC) {
+ if (mode&ACTSTRIPMODE_MULT) {
+ }
+ else {
+ 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);
- }
+ }
dchan->flag |= schan->flag;
+ }
}
for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
/* no 'add' option for constraint blending */
@@ -499,6 +517,7 @@
for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
achan= get_action_channel(act, pchan->name);
pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
+ //pchan->keyflag = 0;
if(achan) {
ipo = achan->ipo;
if (ipo) {
@@ -506,6 +525,8 @@
calc_ipo(ipo, ctime);
/* This call also sets the pchan flags */
execute_action_ipo(achan, pchan);
+ /* Sets keyflags, if available */
+ set_posechannel_keyflags(achan, pchan, ctime);
}
do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime);
}
@@ -605,20 +626,15 @@
}
-static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int mode)
+static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, short mode)
{
NlaIpoChannel *snic, *dnic, *next;
float dstweight;
- switch (mode){
- case POSE_BLEND:
- dstweight = 1.0F - srcweight;
- break;
- case POSE_ADD:
- dstweight = 1.0F;
- break;
- default :
- dstweight = 1.0F;
+ if ((mode&ACTSTRIPMODE_ADD) || (mode&ACTSTRIPMODE_MULT)) {
+ dstweight = 1.0F;
+ } else {
+ dstweight = 1.0F - srcweight;
}
for(snic= src->first; snic; snic= next) {
@@ -668,7 +684,7 @@
}
/* non clipped mapping of strip */
-static float get_actionstrip_frame(bActionStrip *strip, float cframe, int invert)
+float get_actionstrip_frame(bActionStrip *strip, float cframe, int invert)
{
float length, actlength, repeat;
@@ -680,9 +696,7 @@
length = strip->end-strip->start;
if(length==0.0f)
length= 1.0f;
- actlength = strip->actend-strip->actstart;
-
-
+ actlength = strip->actend-strip->actstart;
if(invert)
return length*(cframe - strip->actstart)/(repeat*actlength) + strip->start;
@@ -736,7 +750,7 @@
return cfra;
}
-static float stridechannel_frame(Object *ob, bActionStrip *strip, Path *path, float pathdist, float *stride_offset)
+float stridechannel_frame(Object *ob, bActionStrip *strip, Path *path, float pathdist, float *stride_offset)
{
bAction *act= strip->act;
char *name= strip->stridechannel;
@@ -803,7 +817,13 @@
/* ************** do the action ************ */
-static void do_nla(Object *ob, int blocktype)
+void do_nla(Object *ob, int blocktype)
+{
+ float floattime=(float)G.scene->r.cfra;
+ do_nla_float(ob, blocktype, floattime);
+}
+
+void do_nla_float(Object *ob, int blocktype, float floattime)
{
bPose *tpose= NULL;
Key *key= NULL;
@@ -812,10 +832,14 @@
float striptime, frametime, length, actlength;
float blendfac, stripframe;
int doit, dostride;
+ bPoseChannel *pchan;
if(blocktype==ID_AR) {
copy_pose(&tpose, ob->pose, 1);
rest_pose(ob->pose); // potentially destroying current not-keyed pose
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ pchan->keyflag=0;
+ }
}
else {
key= ob_get_key(ob);
@@ -829,8 +853,8 @@
/* Determine if the current frame is within the strip's range */
length = strip->end-strip->start;
actlength = strip->actend-strip->actstart;
- striptime = (G.scene->r.cfra-(strip->start)) / length;
- stripframe = (G.scene->r.cfra-(strip->start)) ;
+ striptime = (floattime-(strip->start)) / length;
+ stripframe = (floattime-(strip->start));
if (striptime>=0.0){
@@ -849,10 +873,11 @@
if(cu->path) {
/* Find the position on the path */
- ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
+ ctime= bsystem_time(ob, ob->parent, floattime, 0.0);
if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
ctime /= cu->pathlen;
+ ctime -= (strip->actstart/cu->pathlen);
CLAMP(ctime, 0.0, 1.0);
}
pdist = ctime*cu->path->totdist;
@@ -896,6 +921,8 @@
frametime = (striptime * actlength) + strip->actstart;
frametime= nla_time(frametime, (float)strip->repeat);
+
+ //printf("\nstriptime: %f; actlength: %f; frametime: %f; cfra: %f\n\n",striptime,actlength,frametime,floattime);
if(blocktype==ID_AR)
extract_pose_from_action (tpose, strip->act, frametime);
@@ -915,8 +942,9 @@
if(frametime<=0.000001f) frametime= actlength; /* rounding errors... */
frametime= bsystem_time(ob, 0, frametime+strip->actstart, 0.0);
- if(blocktype==ID_AR)
+ if(blocktype==ID_AR) {
extract_pose_from_action (tpose, strip->act, frametime);
+ }
else if(blocktype==ID_OB) {
extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
if(key)
@@ -930,10 +958,10 @@
if (doit){
/* Handle blendin */
- if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
+ if (strip->blendin>0.0 && stripframe<=strip->blendin && floattime>=strip->start){
blendfac = stripframe/strip->blendin;
}
- else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){
+ else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && floattime<=strip->end){
blendfac = (length-stripframe)/(strip->blendout);
}
else
@@ -969,7 +997,7 @@
if(chanbase.first)
BLI_freelistN(&chanbase);
-}
+}
void do_all_pose_actions(Object *ob)
{
Index: source/blender/blenkernel/intern/ipo.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/intern/ipo.c,v
retrieving revision 1.28
diff -u -r1.28 ipo.c
--- source/blender/blenkernel/intern/ipo.c 30 Oct 2005 20:56:18 -0000 1.28
+++ source/blender/blenkernel/intern/ipo.c 6 Jan 2006 17:13:15 -0000
@@ -1810,6 +1810,62 @@
}
}
+void set_posechannel_keyflags(bActionChannel *achan, bPoseChannel *pchan, float ctime)
+{
+ BezTriple *bezt;
+ short a;
+
+ pchan->keyflag = 0;
+ if(achan && achan->ipo) {
+ IpoCurve *icu;
+ for(icu= achan->ipo->curve.first; icu; icu= icu->next) {
+ /* Is there a key near this frame? */
+ bezt= icu->bezt;
+ if(bezt) {
+ a= icu->totvert;
+ while(a--) {
+ if (((ctime-0.5)<bezt->vec[1][0])&&(bezt->vec[1][0]<(ctime+0.5))) {
+ switch (icu->adrcode) {
+ case AC_QUAT_W:
+ pchan->keyflag |= POSEKEY_QUATW;
+ break;
+ case AC_QUAT_X:
+ pchan->keyflag |= POSEKEY_QUATX;
+ break;
+ case AC_QUAT_Y:
+ pchan->keyflag |= POSEKEY_QUATY;
+ break;
+ case AC_QUAT_Z:
+ pchan->keyflag |= POSEKEY_QUATZ;
+ break;
+ case AC_LOC_X:
+ pchan->keyflag |= POSEKEY_LOCX;
+ break;
+ case AC_LOC_Y:
+ pchan->keyflag |= POSEKEY_LOCY;
+ break;
+ case AC_LOC_Z:
+ pchan->keyflag |= POSEKEY_LOCZ;
+ break;
+ case AC_SIZE_X:
+ pchan->keyflag |= POSEKEY_SIZEX;
+ break;
+ case AC_SIZE_Y:
+ pchan->keyflag |= POSEKEY_SIZEY;
+ break;
+ case AC_SIZE_Z:
+ pchan->keyflag |= POSEKEY_SIZEZ;
+ break;
+ }
+ }
+ bezt++;
+ }
+ }
+ }
+ }
+}
+
+
/* exception: it does calc for objects...
* now find out why this routine was used anyway!
*/
@@ -2146,7 +2202,18 @@
cen->sel= bezt->f2;
}
+void add_to_cfra_elem_float(ListBase *lb, float cfra)
+{
+ CfraElem *ce, *cen;
+
+ ce= lb->first;
+
+ cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
+ if(ce) BLI_insertlinkbefore(lb, ce, cen);
+ else BLI_addtail(lb, cen);
+ cen->cfra= cfra;
+}
void make_cfra_list(Ipo *ipo, ListBase *elems)
{
Index: source/blender/blenkernel/intern/object.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/intern/object.c,v
retrieving revision 1.88
diff -u -r1.88 object.c
--- source/blender/blenkernel/intern/object.c 27 Nov 2005 20:49:25 -0000 1.88
+++ source/blender/blenkernel/intern/object.c 6 Jan 2006 17:13:16 -0000
@@ -55,6 +55,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
@@ -108,6 +109,7 @@
/* Local function protos */
static void solve_parenting (Object *ob, Object *par, float slowmat[][4], int simul);
+static void mod_pose_for_matchbone(Object *ob);
float originmat[3][3]; /* after where_is_object(), can be used in other functions (bad!) */
Object workob;
@@ -1831,6 +1833,10 @@
armature_rebuild_pose(ob, ob->data);
do_all_pose_actions(ob);
where_is_pose(ob);
+ if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
+ } else if(ob->nlastrips.first) {
+ mod_pose_for_matchbone(ob);
+ }
}
}
@@ -1838,4 +1844,48 @@
}
}
+static void mod_pose_for_matchbone(Object *ob)
+{
+ bActionStrip *strip;
+ bPoseChannel *pchan;
+ bPose *tpose;
+ float length, actlength, striptime, stripframe;
+ float matchcache[4][4],imat[4][4],tmat[4][4],t2mat[4][4],prevcache[4][4];
+ float blend=1.0f;
+
+ Mat4One(matchcache);
+ /* find most recent nla strip in time scope */
+ for (strip=ob->nlastrips.first; strip; strip=strip->next){
+
+ if (strip->act) { /* so theres an action */
+
+ /* Determine if the current frame is within the strip's range */
+ length = strip->end-strip->start;
+ actlength = strip->actend-strip->actstart;
+ striptime = (G.scene->r.cfra-(strip->start)) / length;
+ stripframe = (G.scene->r.cfra-(strip->start)) ;
+
+ if (striptime>=0.0) {
+ Mat4CpyMat4(prevcache,matchcache);
+ Mat4CpyMat4(matchcache,strip->matchcache);
+ if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
+ blend = stripframe/strip->blendin;
+ } else
+ blend = 1.0;
+ }
+ }
+ }
+
+ tpose=ob->pose;
+ /* if on BlendIn portion of strip, blend this cache and the last one */
+ if (blend<1.0) {
+ Mat4BlendMat4(tmat,prevcache,matchcache,blend);
+ Mat4Invert(imat,tmat);
+ } else {
+ Mat4Invert(imat,matchcache);
+ }
+
+ Mat4MulMat4(tmat,imat,ob->obmat);
+ Mat4CpyMat4(ob->obmat,tmat);
+}
Index: source/blender/blenlib/BLI_arithb.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenlib/BLI_arithb.h,v
retrieving revision 1.22
diff -u -r1.22 BLI_arithb.h
--- source/blender/blenlib/BLI_arithb.h 4 Oct 2005 21:23:19 -0000 1.22
+++ source/blender/blenlib/BLI_arithb.h 6 Jan 2006 17:13:16 -0000
@@ -871,6 +871,8 @@
void tubemap(float x, float y, float z, float *u, float *v);
void spheremap(float x, float y, float z, float *u, float *v);
+
+void ident_m4(float m[][4]);
int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda);
Index: source/blender/blenloader/intern/readfile.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenloader/intern/readfile.c,v
retrieving revision 1.216
diff -u -r1.216 readfile.c
--- source/blender/blenloader/intern/readfile.c 14 Dec 2005 20:36:04 -0000 1.216
+++ source/blender/blenloader/intern/readfile.c 6 Jan 2006 17:13:32 -0000
@@ -5025,6 +5025,8 @@
Scene *sce= main->scene.first;
Camera *cam= main->camera.first;
Material *ma= main->mat.first;
+ bActionStrip *strip;
+
int set_passepartout= 0;
/* deformflag is local in modifier now */
@@ -5048,6 +5050,18 @@
if (arm->ghostsize==0) arm->ghostsize=1;
}
+ /* filling actionstrip match caches */
+ for(ob=main->object.first; ob; ob= ob->id.next) {
+ if (ob->nlastrips.first) {
+ for (strip=ob->nlastrips.first; strip; strip=strip->next) {
+ if (strip->matchcache[0][0]=strip->matchcache[0][1]=strip->matchcache[0][2]=strip->matchcache[0][3]=strip->matchcache[1][0]=strip->matchcache[1][1]=strip->matchcache[1][2]=strip->matchcache[1][3]=strip->matchcache[2][0]=strip->matchcache[2][1]=strip->matchcache[2][2]=strip->matchcache[2][3]=strip->matchcache[3][0]=strip->matchcache[3][1]=strip->matchcache[3][2]=strip->matchcache[3][3]=0)
+ ident_m4(strip->matchcache);
+ }
+ }
+ }
+
+ //while(sce) {
+
for(;sce;sce= sce->id.next) {
/* make 'innervert' the default subdivide type, for backwards compat */
sce->toolsettings->cornertype=1;
Index: source/blender/include/BIF_editaction.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/BIF_editaction.h,v
retrieving revision 1.9
diff -u -r1.9 BIF_editaction.h
--- source/blender/include/BIF_editaction.h 19 Nov 2005 11:06:28 -0000 1.9
+++ source/blender/include/BIF_editaction.h 6 Jan 2006 17:13:32 -0000
@@ -107,6 +107,11 @@
/* contextual get action */
struct bAction *ob_get_action(struct Object *ob);
+/* bake object IPOs into an Action */
+struct bAction *bake_obIPO_to_action(struct Object *ob, int sample, struct ListBase masterkeys);
+struct bAction *bake_full_NLA_to_action (struct Object *ob, struct ListBase masterkeys);
+
+
void remake_action_ipos(struct bAction *act);
Index: source/blender/include/BIF_editnla.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/BIF_editnla.h,v
retrieving revision 1.13
diff -u -r1.13 BIF_editnla.h
--- source/blender/include/BIF_editnla.h 29 Oct 2005 21:27:07 -0000 1.13
+++ source/blender/include/BIF_editnla.h 6 Jan 2006 17:13:32 -0000
@@ -53,7 +53,8 @@
void reset_action_strips(int val);
void synchronize_action_strips(void);
void snap_action_strips(void);
-
+void build_match_caches(void);
+void bake_all_to_action(short val);
#endif
Index: source/blender/include/BSE_editipo.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/BSE_editipo.h,v
retrieving revision 1.21
diff -u -r1.21 BSE_editipo.h
--- source/blender/include/BSE_editipo.h 12 Nov 2005 16:22:10 -0000 1.21
+++ source/blender/include/BSE_editipo.h 6 Jan 2006 17:13:32 -0000
@@ -110,6 +110,7 @@
void set_speed_editipo(float speed);
void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode);
+void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue);
void insertkey_editipo(void);
void common_insertkey(void);
void free_ipokey(struct ListBase *lb);
@@ -130,6 +131,8 @@
void filter_sampledata(float *data, int sfra, int efra);
void sampledata_to_ipocurve(float *data, int sfra, int efra, struct IpoCurve *icu);
void ipo_record(void);
+void bone2objectspace(float obSpaceBoneMat[][4], float obSpace[][4], float restPos[][4]);
+void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4]);
void sethandles_ipo_keys(struct Ipo *ipo, int code);
void snap_ipo_keys(struct Ipo *ipo);
Index: source/blender/include/BSE_time.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/BSE_time.h,v
retrieving revision 1.4
diff -u -r1.4 BSE_time.h
--- source/blender/include/BSE_time.h 4 Nov 2005 11:23:22 -0000 1.4
+++ source/blender/include/BSE_time.h 6 Jan 2006 17:13:32 -0000
@@ -44,6 +44,7 @@
void nextprev_timeline_key(short dir);
void nextprev_timeline_marker(short dir);
void timeline_grab(int mode, int smode);
+void build_nla_timeline(struct Object *ob, struct ListBase *masterkeys);
#endif
Index: source/blender/makesdna/DNA_action_types.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/makesdna/DNA_action_types.h,v
retrieving revision 1.26
diff -u -r1.26 DNA_action_types.h
--- source/blender/makesdna/DNA_action_types.h 15 Nov 2005 22:39:20 -0000 1.26
+++ source/blender/makesdna/DNA_action_types.h 6 Jan 2006 17:13:32 -0000
@@ -50,7 +50,8 @@
short ikflag; /* settings for IK bones */
short pathlen; /* for drawing paths, the amount of frames */
short protectflag;/* protect channels from being transformed */
- short pad, pad1, pad2;
+ short keyflag; /* which aspects of pose generated by keyframes */
+ short pad, pad1;
struct Bone *bone; /* set on read file or rebuild pose */
struct bPoseChannel *parent; /* set on read file or rebuild pose */
@@ -81,6 +82,7 @@
ListBase chanbase;
int flag;
float stride_offset[3];
+ short keyflag, pad1, pad2, pad3;
} bPose;
typedef struct bActionChannel {
@@ -141,6 +143,21 @@
POSE_DONE = 0x0400,
POSE_KEY = 0x1000,
POSE_STRIDE = 0x2000
+};
+
+/* pose keyflags */
+
+enum {
+ POSEKEY_LOCX = 0x001,
+ POSEKEY_LOCY = 0x002,
+ POSEKEY_LOCZ = 0x004,
+ POSEKEY_QUATW = 0x008,
+ POSEKEY_QUATX = 0x010,
+ POSEKEY_QUATY = 0x020,
+ POSEKEY_QUATZ = 0x040,
+ POSEKEY_SIZEX = 0x080,
+ POSEKEY_SIZEY = 0x100,
+ POSEKEY_SIZEZ = 0x200
};
/* PoseChannel constflag (constraint detection) */
Index: source/blender/makesdna/DNA_armature_types.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/makesdna/DNA_armature_types.h,v
retrieving revision 1.26
diff -u -r1.26 DNA_armature_types.h
--- source/blender/makesdna/DNA_armature_types.h 16 Nov 2005 21:03:16 -0000 1.26
+++ source/blender/makesdna/DNA_armature_types.h 6 Jan 2006 17:13:32 -0000
@@ -94,13 +94,14 @@
#define ARM_DELAYDEFORM 0x040
#define ARM_DONT_USE 0x080
#define ARM_MIRROR_EDIT 0x100
-#define ARM_AUTO_IK 0x200
+#define ARM_AUTO_IK 0x200
+#define ARM_MATCHED 0x400
/* armature->drawtype */
#define ARM_OCTA 0
#define ARM_LINE 1
#define ARM_B_BONE 2
-#define ARM_ENVELOPE 3
+#define ARM_ENVELOPE 3
/* armature->deformflag */
#define ARM_DEF_VGROUP 1
Index: source/blender/makesdna/DNA_nla_types.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/makesdna/DNA_nla_types.h,v
retrieving revision 1.9
diff -u -r1.9 DNA_nla_types.h
--- source/blender/makesdna/DNA_nla_types.h 1 Nov 2005 12:44:30 -0000 1.9
+++ source/blender/makesdna/DNA_nla_types.h 6 Jan 2006 17:13:32 -0000
@@ -49,13 +49,17 @@
float stridelen; /* The stridelength (considered when flag & ACT_USESTRIDE) */
float repeat; /* The number of times to repeat the action range */
+ float matchcache[4][4]; /* cache of accumulated matchmove info for quick display */
+
float blendin, blendout;
-
+
+ char matchchannel[32]; /* Pose channel for doing match-moving */
char stridechannel[32]; /* Instead of stridelen, it uses an action channel */
} bActionStrip;
#define ACTSTRIPMODE_BLEND 0
-#define ACTSTRIPMODE_ADD 1
+#define ACTSTRIPMODE_ADD 0x01
+#define ACTSTRIPMODE_MULT 0x02
/* strip->flag */
#define ACTSTRIP_SELECT 0x01
@@ -64,6 +68,7 @@
#define ACTSTRIP_HOLDLASTFRAME 0x08
#define ACTSTRIP_ACTIVE 0x10
#define ACTSTRIP_LOCK_ACTION 0x20
+#define ACTSTRIP_USEMATCH 0x40
#endif
Index: source/blender/src/drawnla.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/drawnla.c,v
retrieving revision 1.28
diff -u -r1.28 drawnla.c
--- source/blender/src/drawnla.c 15 Nov 2005 22:39:20 -0000 1.28
+++ source/blender/src/drawnla.c 6 Jan 2006 17:13:33 -0000
@@ -430,6 +430,7 @@
allqueue(REDRAWNLA, 0);
break;
case B_NLA_PANEL:
+ build_match_caches();
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
allqueue (REDRAWNLA, 0);
allqueue (REDRAWVIEW3D, 0);
@@ -452,54 +453,60 @@
block= uiNewBlock(&curarea->uiblocks, "nla_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(NLA_HANDLER_PROPERTIES); // for close and esc
- if(uiNewPanel(curarea, block, "Transform Properties", "NLA", 10, 230, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Transform Properties", "NLA", 10, 270, 318, 244)==0) return;
/* Determine if an nla strip has been selected */
strip = get_active_nlastrip(&ob);
if (!strip) return;
/* first labels, for simpler align code :) */
- uiDefBut(block, LABEL, 0, "Timeline Range:", 10,180,300,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Blending:", 10,120,300,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Options:", 10,80,300,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Stride Support:", 10,40,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Timeline Range:", 10,220,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Blending:", 10,160,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Options:", 10,120,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Stride Support:", 10,80,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Match Moving:", 10,20,300,19, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NLA_PANEL, "Strip Start:", 10,160,150,19, &strip->start, -1000.0, strip->end-1, 100, 0, "First frame in the timeline");
- uiDefButF(block, NUM, B_NLA_PANEL, "Strip End:", 160,160,150,19, &strip->end, strip->start+1, MAXFRAMEF, 100, 0, "Last frame in the timeline");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Strip Start:", 10,200,150,19, &strip->start, -1000.0, strip->end-1, 100, 0, "First frame in the timeline");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Strip End:", 160,200,150,19, &strip->end, strip->start+1, MAXFRAMEF, 100, 0, "Last frame in the timeline");
- uiDefIconButBitS(block, ICONTOG, ACTSTRIP_LOCK_ACTION, B_NLA_LOCK, ICON_UNLOCKED, 10,140,20,19, &(strip->flag), 0, 0, 0, 0, "Toggles Action end/start to be automatic mapped to strip duration");
+ uiDefIconButBitS(block, ICONTOG, ACTSTRIP_LOCK_ACTION, B_NLA_LOCK, ICON_UNLOCKED, 10,180,20,19, &(strip->flag), 0, 0, 0, 0, "Toggles Action end/start to be automatic mapped to strip duration");
if(strip->flag & ACTSTRIP_LOCK_ACTION) {
char str[40];
sprintf(str, "Action Start: %.2f", strip->actstart);
- uiDefBut(block, LABEL, B_NOP, str, 30,140,140,19, NULL, 0.0, 0.0, 0, 0, "First frame of the action to map to the playrange");
+ uiDefBut(block, LABEL, B_NOP, str, 30,180,140,19, NULL, 0.0, 0.0, 0, 0, "First frame of the action to map to the playrange");
sprintf(str, "Action End: %.2f", strip->actend);
- uiDefBut(block, LABEL, B_NOP, str, 170,140,140,19, NULL, 0.0, 0.0, 0, 0, "Last frame of the action to map to the playrange");
+ uiDefBut(block, LABEL, B_NOP, str, 170,180,140,19, NULL, 0.0, 0.0, 0, 0, "Last frame of the action to map to the playrange");
}
else {
- uiDefButF(block, NUM, B_NLA_PANEL, "Action Start:", 30,140,140,19, &strip->actstart, -1000.0, strip->actend-1, 100, 0, "First frame of the action to map to the playrange");
- uiDefButF(block, NUM, B_NLA_PANEL, "Action End:", 170,140,140,19, &strip->actend, strip->actstart+1, MAXFRAMEF, 100, 0, "Last frame of the action to map to the playrange");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Action Start:", 30,180,140,19, &strip->actstart, -1000.0, strip->actend-1, 100, 0, "First frame of the action to map to the playrange");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Action End:", 170,180,140,19, &strip->actend, strip->actstart+1, MAXFRAMEF, 100, 0, "Last frame of the action to map to the playrange");
}
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NLA_PANEL, "Blendin:", 10,100,150,19, &strip->blendin, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-in");
- uiDefButF(block, NUM, B_NLA_PANEL, "Blendout:", 160,100,150,19, &strip->blendout, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-out");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Blendin:", 10,140,150,19, &strip->blendin, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-in");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Blendout:", 160,140,150,19, &strip->blendout, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-out");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NLA_PANEL, "Repeat:", 10,60,150,19, &strip->repeat, 0.001, 1000.0f, 100, 0, "Number of times the action should repeat");
- uiDefButBitS(block, TOG, ACTSTRIP_HOLDLASTFRAME, B_NLA_PANEL, "Hold", 160,60,75,19, &strip->flag, 0, 0, 0, 0, "Toggles whether to continue displaying the last frame past the end of the strip");
- uiDefButS(block, TOG, B_NLA_PANEL, "Add", 230,60,75,19, &strip->mode, 0, 0, 0, 0, "Toggles additive blending mode");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Repeat:", 10,100,150,19, &strip->repeat, 0.001, 1000.0f, 100, 0, "Number of times the action should repeat");
+ uiDefButBitS(block, TOG, ACTSTRIP_HOLDLASTFRAME, B_NLA_PANEL, "Hold", 160,100,50,19, &strip->flag, 0, 0, 0, 0, "Toggles whether to continue displaying the last frame past the end of the strip");
+ uiDefButBitS(block, TOG, ACTSTRIPMODE_ADD, B_NLA_PANEL, "Add", 210,100,50,19, &strip->mode, 0, 0, 0, 0, "Toggles additive blending mode");
+ uiDefButBitS(block, TOG, ACTSTRIPMODE_MULT, B_NLA_PANEL, "Mult", 260,100,50,19, &strip->mode, 0, 0, 0, 0, "Toggles multiply blending mode");
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, ACTSTRIP_USESTRIDE, B_NLA_PANEL, "Stride Path", 10,20,100,19, &strip->flag, 0, 0, 0, 0, "Plays action based on path position & stride");
- uiDefButBitS(block, TOG, OB_DISABLE_PATH, B_NLA_PANEL, "Disable Path", 110,20,100,19, &ob->ipoflag, 0, 0, 0, 0, "Plays action based on path position & stride");
- uiDefButF(block, NUM, B_NLA_PANEL, "Stride:", 210,20,100,19, &strip->stridelen, 0.0001, 1000.0, 100, 0, "Distance covered by one complete cycle of the action specified in the Action Range");
-
- uiDefButS(block, ROW, B_NLA_PANEL, "X", 10, 0, 33, 19, &strip->stride_axis, 1, 0, 0, 0, "Dominant axis for Stride Bone");
- uiDefButS(block, ROW, B_NLA_PANEL, "Y", 43, 0, 33, 19, &strip->stride_axis, 1, 1, 0, 0, "Dominant axis for Stride Bone");
- uiDefButS(block, ROW, B_NLA_PANEL, "Z", 76, 0, 34, 19, &strip->stride_axis, 1, 2, 0, 0, "Dominant axis for Stride Bone");
+ uiDefButBitS(block, TOG, ACTSTRIP_USESTRIDE, B_NLA_PANEL, "Stride Path", 10,60,100,19, &strip->flag, 0, 0, 0, 0, "Plays action based on path position & stride");
+ uiDefButBitS(block, TOG, OB_DISABLE_PATH, B_NLA_PANEL, "Disable Path", 110,60,100,19, &ob->ipoflag, 0, 0, 0, 0, "Plays action based on path position & stride");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Stride:", 210,60,100,19, &strip->stridelen, 0.0001, 1000.0, 100, 0, "Distance covered by one complete cycle of the action specified in the Action Range");
- uiDefBut(block, TEX, B_NLA_PANEL, "Stride Bone:", 110, 0, 200, 19, strip->stridechannel, 1, 31, 0, 0, "Name of Bone used for stride");
+ uiDefButS(block, ROW, B_NLA_PANEL, "X", 10, 40, 33, 19, &strip->stride_axis, 1, 0, 0, 0, "Dominant axis for Stride Bone");
+ uiDefButS(block, ROW, B_NLA_PANEL, "Y", 43, 40, 33, 19, &strip->stride_axis, 1, 1, 0, 0, "Dominant axis for Stride Bone");
+ uiDefButS(block, ROW, B_NLA_PANEL, "Z", 76, 40, 34, 19, &strip->stride_axis, 1, 2, 0, 0, "Dominant axis for Stride Bone");
+
+ uiDefBut(block, TEX, B_NLA_PANEL, "Stride Bone:", 110, 40, 200, 19, strip->stridechannel, 1, 31, 0, 0, "Name of Bone used for stride");
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, ACTSTRIP_USEMATCH, B_NLA_PANEL, "Use MatchBone", 10, 0, 100, 19, &strip->flag, 0, 0, 0, 0, "Activates this MatchBone moving for this strip.");
+ uiDefBut(block, TEX, B_NLA_PANEL, "MatchBone:", 110, 0, 200, 19, strip->matchchannel, 1, 31, 0, 0, "Name of Bone used for MatchMoving");
}
Index: source/blender/src/editaction.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editaction.c,v
retrieving revision 1.70
diff -u -r1.70 editaction.c
--- source/blender/src/editaction.c 22 Nov 2005 16:35:21 -0000 1.70
+++ source/blender/src/editaction.c 6 Jan 2006 17:13:33 -0000
@@ -68,6 +68,7 @@
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BIF_butspace.h"
@@ -138,11 +139,163 @@
}
}
+bAction* bake_obIPO_to_action (Object *ob, int sample, ListBase masterkeys)
+{
+ bArmature *arm;
+ bAction *result=NULL;
+ bAction *temp;
+ Bone *bone;
+ ID *id;
+ ListBase elems;
+ int oldframe,testframe;
+ char newname[64];
+ float quat[4],tmat[4][4],startpos[4][4];
+ CfraElem *firstcfra, *lastcfra;
+
+ arm = get_armature(ob);
+
+ if (arm) {
+
+ elems.first= elems.last= NULL;
+ make_cfra_list(ob->ipo, &elems);
+
+ if (!elems.first) { /*no IPOs set for the object - guess at frame range*/
+ lastcfra=masterkeys.last;
+ firstcfra=masterkeys.first;
+ add_to_cfra_elem_float(&elems, lastcfra->cfra);
+ add_to_cfra_elem_float(&elems, firstcfra->cfra);
+ }
+
+ if (elems.first) {
+
+ oldframe = CFRA;
+ result = add_empty_action(ID_PO);
+ id = (ID *)ob;
+
+ sprintf (newname, "TESTOBBAKE");
+ rename_id(&result->id, newname);
+
+ if(ob!=G.obedit) { // make sure object is not in edit mode
+ if(ob->ipo) {
+ /* convert the ipo to a list of 'current frame elements' */
+
+ temp = ob->action;
+ ob->action = result;
+
+ /* set the beginning armature location */
+ firstcfra=elems.first;
+ lastcfra=elems.last;
+ CFRA=firstcfra->cfra;
+
+ ob->recalc|=OB_RECALC;
+ ob->recalc|=OB_RECALC_OB;
+ ob->recalc|=OB_RECALC_DATA;
+ object_handle_update(ob);
+ Mat4CpyMat4(startpos,ob->obmat);
+
+ /* loop from first key to last, sampling per specification */
+ for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+sample) {
+ CFRA=testframe;
+
+ ob->recalc|=OB_RECALC;
+ ob->recalc|=OB_RECALC_OB;
+ ob->recalc|=OB_RECALC_DATA;
+ object_handle_update(ob);
+ for (bone = arm->bonebase.first; bone; bone=bone->next) {
+ if (!bone->parent) { /* this is a root bone, so give it a key! */
+ world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos);
+ Mat4ToQuat(tmat,quat);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]);
+ /*insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]);
+ insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]);*/
+ }
+ }
+ }
+ BLI_freelistN(&elems);
+ }
+ }
+ CFRA = oldframe;
+ ob->action=temp;
+ ob->recalc&=OB_RECALC;
+ ob->recalc&=OB_RECALC_OB;
+ ob->recalc&=OB_RECALC_DATA;
+ object_handle_update(ob);
+ }
+ }
+ return result;
+}
+
+bAction* bake_full_NLA_to_action (Object *ob, ListBase masterkeys)
+{
+ bArmature *arm;
+ bPoseChannel *pchan;
+ bAction *result=NULL;
+ bAction *temp;
+ ID *id;
+ int oldframe;
+ char newname[64];
+ CfraElem *keyelem;
+
+ arm = get_armature(ob);
+
+ if (arm) {
+
+ oldframe = CFRA;
+ result = add_empty_action(ID_PO);
+ id = (ID *)ob;
+
+ sprintf (newname, "FINALBAKE");
+ rename_id(&result->id, newname);
+
+ temp = ob->action;
+ ob->action = result;
+
+ if(ob!=G.obedit) { // make sure object is not in edit mode
+ /* set the beginning armature location */
+ for (keyelem=masterkeys.first; keyelem; keyelem=keyelem->next) {
+
+ CFRA=keyelem->cfra;
+ //printf("***Sampled at Frame: %f\n",keyelem->cfra);
+ do_nla_float(ob,ID_AR,keyelem->cfra);
+
+ if (ob->pose) {
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next){
+ /* Apply to keys */
+ if (pchan->keyflag&POSEKEY_LOCX) insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
+ if (pchan->keyflag&POSEKEY_LOCY) insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
+ if (pchan->keyflag&POSEKEY_LOCZ) insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+ if (pchan->keyflag&POSEKEY_QUATW) insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
+ if (pchan->keyflag&POSEKEY_QUATX) insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
+ if (pchan->keyflag&POSEKEY_QUATY) insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
+ if (pchan->keyflag&POSEKEY_QUATZ) insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
+ /*insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z);*/
+ }
+ }
+ }
+ }
+ CFRA = oldframe;
+ ob->action=temp;
+ where_is_pose(ob);
+ where_is_object(ob);
+ }
+ return result;
+}
+
+
bAction* bake_action_with_client (bAction *act, Object *armob, float tolerance)
{
bArmature *arm;
bAction *result=NULL;
- bActionChannel *achan;
+ bActionChannel *achan;
bAction *temp;
bPoseChannel *pchan;
ID *id;
Index: source/blender/src/editipo.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editipo.c,v
retrieving revision 1.87
diff -u -r1.87 editipo.c
--- source/blender/src/editipo.c 13 Dec 2005 14:28:34 -0000 1.87
+++ source/blender/src/editipo.c 6 Jan 2006 17:13:36 -0000
@@ -1927,6 +1927,42 @@
}
+ /* For inserting keys based on the object matrix - not on the current IPO value
+ Generically - it inserts the passed float value into the appropriate IPO */
+void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue)
+{
+ IpoCurve *icu;
+ Object *ob;
+ void *poin= NULL;
+ float cfra;
+ int vartype;
+
+ icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
+
+ if(icu) {
+
+ poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
+
+ if(poin) {
+
+ cfra= frame_to_float(CFRA);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if(actname && actname[0] && GS(id->name)==ID_OB)
+ cfra= get_action_frame((Object *)id, cfra);
+
+ if( GS(id->name)==ID_OB ) {
+ ob= (Object *)id;
+ if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
+ /* actually frametofloat calc again! */
+ cfra-= ob->sf*G.scene->r.framelen;
+ }
+ }
+ insert_vert_ipo(icu, cfra, matrixvalue);
+ }
+ }
+}
+
void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode)
{
IpoCurve *icu;
@@ -4463,4 +4499,21 @@
BIF_undo_push("Set frame to selected Ipo vertex");
}
+void bone2objectspace(float obSpaceBoneMat[][4], float obSpace[][4], float restPos[][4])
+{
+ float imat[4][4];
+
+ Mat4Invert(imat, restPos);
+ Mat4MulMat4(obSpaceBoneMat, obSpace, imat);
+}
+void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4])
+{
+ float imatarm[4][4], imatbone[4][4], tmat[4][4], t2mat[4][4];
+
+ Mat4Invert(imatarm, armPos);
+ Mat4Invert(imatbone, restPos);
+ Mat4MulMat4(tmat, imatarm, worldSpace);
+ Mat4MulMat4(t2mat, tmat, imatbone);
+ Mat4MulMat4(boneSpaceMat, restPos, t2mat);
+}
Index: source/blender/src/editnla.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editnla.c,v
retrieving revision 1.59
diff -u -r1.59 editnla.c
--- source/blender/src/editnla.c 14 Dec 2005 20:36:04 -0000 1.59
+++ source/blender/src/editnla.c 6 Jan 2006 17:13:37 -0000
@@ -43,7 +43,9 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "DNA_armature_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
@@ -56,13 +58,18 @@
#include "DNA_constraint_types.h"
#include "BKE_action.h"
+#include "BKE_armature.h"
#include "BKE_depsgraph.h"
+#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_nla.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
+#include "BIF_editaction.h"
#include "BIF_screen.h"
#include "BIF_interface.h"
#include "BIF_butspace.h"
@@ -81,6 +88,7 @@
#include "BSE_filesel.h"
#include "BDR_editobject.h"
#include "BSE_drawnla.h"
+#include "BSE_time.h"
#include "blendef.h"
#include "mydevice.h"
@@ -99,9 +107,38 @@
static void mouse_nlachannels(short mval[2]);
static void add_nlablock(short mval[2]);
static void convert_nla(short mval[2]);
+static void ident_m4(float m[4][4]);
+static Object *get_object_from_active_strip(void);
+static void add_nla_block_by_name(char name[32], Object *ob, short hold, short mode, float repeat);
+
+static void ident_m4(float m[][4])
+{
+
+ m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0;
+ m[0][1]= m[0][2]= m[0][3]= 0.0;
+ m[1][0]= m[1][2]= m[1][3]= 0.0;
+ m[2][0]= m[2][1]= m[2][3]= 0.0;
+ m[3][0]= m[3][1]= m[3][2]= 0.0;
+}
/* ******************** SPACE: NLA ********************** */
+static Object *get_object_from_active_strip(void) {
+
+ Base *base;
+ bActionStrip *strip;
+
+ for (base=G.scene->base.first; base; base=base->next) {
+ for (strip = base->object->nlastrips.first;
+ strip; strip=strip->next){
+ if (strip->flag & ACTSTRIP_SELECT) {
+ return base->object;
+ }
+ }
+ }
+ return NULL;
+}
+
void shift_nlastrips_up(void) {
Base *base;
@@ -254,6 +291,7 @@
unsigned short event= evt->event;
short val= evt->val;
SpaceNla *snla = curarea->spacedata.first;
+ Object *ob;
int doredraw= 0;
short mval[2];
float dx,dy;
@@ -291,11 +329,13 @@
case EQUALKEY:
case PAGEUPKEY:
shift_nlastrips_up();
+ build_match_caches();
break;
case MINUSKEY:
case PAGEDOWNKEY:
shift_nlastrips_down();
+ build_match_caches();
break;
case AKEY:
@@ -318,11 +358,23 @@
break;
case BKEY:
- borderselect_nla();
+ if (G.qual & LR_SHIFTKEY){
+ val= pupmenu("Bake to Action%t|Bake Object to Action%x1|Bake NLA to Action%x2|Bake All to Action%x3");
+ bake_all_to_action(val);
+ allqueue (REDRAWNLA, 0);
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWIPO, 0);
+ BIF_undo_push("Bake All To Action");
+ build_match_caches();
+ }
+ else {
+ borderselect_nla();
+ }
break;
case CKEY:
convert_nla(mval);
+ build_match_caches();
break;
case DKEY:
@@ -330,11 +382,13 @@
duplicate_nlachannel_keys();
update_for_newframe_muted();
}
+ build_match_caches();
break;
case GKEY:
if (mval[0]>=NLAWIDTH)
transform_nlachannel_keys ('g', 0);
+ build_match_caches();
update_for_newframe_muted();
break;
@@ -344,6 +398,11 @@
scrarea_queue_winredraw(curarea);
}
break;
+
+ case PKEY:
+ build_match_caches();
+ update_for_newframe_muted();
+ break;
case SKEY:
if(G.qual==LR_ALTKEY) {
@@ -362,6 +421,7 @@
transform_nlachannel_keys ('s', 0);
update_for_newframe_muted();
}
+ build_match_caches();
break;
case DELKEY:
@@ -369,6 +429,7 @@
if (mval[0]>=NLAWIDTH)
delete_nlachannel_keys ();
+ build_match_caches();
update_for_newframe_muted();
break;
@@ -536,7 +597,7 @@
calc_action_range(nstrip->act, &nstrip->actstart, &nstrip->actend);
nstrip->start = nstrip->actstart;
nstrip->end = nstrip->actend;
- nstrip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION;
+ nstrip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION|ACTSTRIP_USEMATCH;
find_stridechannel(base->object, nstrip);
set_active_strip(base->object, nstrip);
@@ -544,7 +605,7 @@
nstrip->repeat = 1.0;
BLI_addtail(&base->object->nlastrips, nstrip);
-
+
BIF_undo_push("Convert NLA");
allqueue (REDRAWNLA, 0);
}
@@ -559,6 +620,136 @@
static Base *nla_base=NULL; /* global, bad, bad! put it in nla space later, or recode the 2 functions below (ton) */
+void build_match_caches(void)
+{
+// Base *base;
+// Object *ob=NULL;
+ bArmature *arm=NULL;
+ bPose *opose=NULL;
+ //bAction *action=NULL;
+ float matchframe,length,actlength,striptime,stripframe;
+ float prevmat[4][4],curmat[4][4],imat[4][4],diffmat[4][4];
+ float stride_offset[3];
+ int foundsol,cfrao,invflag;
+ bActionStrip *matchstrip, *strip;
+ bPoseChannel *pchan;
+ Object *ob=NULL;
+
+ ob = get_object_from_active_strip();
+
+ if (ob) {
+ if (ob->nlastrips.first) {
+ /* step through object's nla strips from top (first) to bottom (last, and most effective) */
+ arm=ob->data;
+ for (strip = ob->nlastrips.first; strip; strip=strip->next){
+ matchframe = strip->start;
+ matchstrip = strip;
+ foundsol=0;
+ if (strip->matchchannel && (strip->flag & ACTSTRIP_USEMATCH)) {
+ cfrao= CFRA; /* store original frame number for after we're done playing around */
+
+ while (foundsol==0) { /* find nearest strip above in frame line to match */
+ if (matchstrip->prev) {
+ matchstrip=matchstrip->prev;
+ /* is the strip in line with the match frame? */
+ length = matchstrip->end-matchstrip->start;
+ if (length==0.0f)
+ length= 1.0f;
+ actlength = matchstrip->actend-matchstrip->actstart;
+ striptime = (matchframe-(matchstrip->start)) / length;
+ stripframe = (actlength * ((striptime*matchstrip->repeat)-(int)(striptime*matchstrip->repeat)));
+
+ /* handle strides... modified cut 'n paste from action.c */
+ if ((matchstrip->flag & ACTSTRIP_USESTRIDE) && (ob->ipoflag & OB_DISABLE_PATH)==0){
+ if (ob->parent && ob->parent->type==OB_CURVE){
+ Curve *cu = ob->parent->data;
+ float ctime, pdist;
+
+ if (cu->flag & CU_PATH){
+ /* Ensure we have a valid path */
+ if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(ob->parent, 0);
+ if(cu->path) {
+
+ /* Find the position on the path */
+ ctime= bsystem_time(ob, ob->parent, matchframe, 0.0);
+
+ if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
+ ctime /= cu->pathlen;
+ CLAMP(ctime, 0.0, 1.0);
+ }
+ pdist = ctime*cu->path->totdist;
+
+ if(matchstrip->stridechannel[0]) {
+ striptime= stridechannel_frame(ob->parent, matchstrip, cu->path, pdist, stride_offset);
+ }
+ else {
+ if (matchstrip->stridelen) {
+ striptime = pdist / matchstrip->stridelen;
+ striptime = (float)fmod (striptime, 1.0);
+ }
+ else
+ striptime = 0;
+ }
+
+ stripframe = (striptime * actlength) + strip->actstart;
+ stripframe = bsystem_time(ob, 0, stripframe, 0.0);
+ }
+ }
+ }
+ }
+
+ if (striptime>=0.0) {
+ /* store original pose info - we have to set temp poses here */
+ opose=ob->pose;
+ /* get the final transform matrix in ob space of the matchbone in the action we're matching to */
+ CFRA=stripframe;
+ extract_pose_from_action(ob->pose, matchstrip->act, stripframe);
+ where_is_pose(ob);
+ pchan=get_pose_channel(ob->pose, strip->matchchannel);
+ if (pchan) {
+ Mat4CpyMat4(prevmat,pchan->pose_mat);
+ /* get the final transform matrix in ob space of the matchbone at the start of the current action */
+ CFRA=1;
+ extract_pose_from_action(ob->pose, strip->act, 1);
+ where_is_pose(ob);
+ pchan=get_pose_channel(ob->pose, strip->matchchannel);
+ if (pchan) {
+ Mat4CpyMat4(curmat,pchan->pose_mat);
+ /* we have both matrices - now, find the difference between the two, normalize it and store it for use in object.c */
+ invflag=Mat4Invert(imat,prevmat);
+ Mat4MulMat4(diffmat,imat,curmat);
+ Mat4Ortho(diffmat);
+ Mat4MulMat4(strip->matchcache,matchstrip->matchcache,diffmat);
+ Mat4Ortho(strip->matchcache);
+ }
+ } else {
+ /* No Pose Channel for %s - setting to identity */
+ Mat4CpyMat4(strip->matchcache,matchstrip->matchcache);
+ }
+ foundsol=1;
+ } else { /* Previous Strip not in frame alignment: So do a temporary forward of previous cache
+ Could be replaced later on successful frame check */
+ Mat4CpyMat4(strip->matchcache,matchstrip->matchcache);
+ }
+ } else { /* No Previous Strip: Init to Identity Matrix */
+ ident_m4(strip->matchcache);
+ foundsol=1;
+ }
+ }
+ CFRA= cfrao;
+ } else {
+ /* no match moving set for this strip - find and forward the previous matchcache */
+ if (matchstrip->prev) {
+ Mat4CpyMat4(strip->matchcache,matchstrip->prev->matchcache);
+ } else { /* this the first strip, so use the identity matrix */
+ ident_m4(strip->matchcache);
+ }
+ }
+ }
+ }
+ }
+}
+
static void add_nla_block(short event)
{
bAction *act=NULL;
@@ -592,9 +783,10 @@
if(strip->start>strip->end-2)
strip->end= strip->start+100;
- strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION;
+ strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION|ACTSTRIP_USEMATCH;
find_stridechannel(nla_base->object, strip);
+
set_active_strip(nla_base->object, strip);
strip->repeat = 1.0;
@@ -606,6 +798,59 @@
BIF_undo_push("Add NLA strip");
}
+static void add_nla_block_by_name(char name[32], Object *ob, short hold, short mode, float repeat)
+{
+ bAction *act=NULL;
+ bActionStrip *strip;
+ int cur;
+
+ if (name){
+ for (cur = 1, act=G.main->action.first; act; act=act->id.next, cur++){
+ if (strcmp(name,act->id.name)==0) {
+ break;
+ }
+ }
+ }
+
+ /* Bail out if no action was chosen */
+ if (!act){
+ return;
+ }
+
+ /* Initialize the new action block */
+ strip = MEM_callocN(sizeof(bActionStrip), "bActionStrip");
+
+ deselect_nlachannel_keys(0);
+
+ /* Link the action to the strip */
+ strip->act = act;
+ calc_action_range(strip->act, &strip->actstart, &strip->actend);
+ strip->start = G.scene->r.cfra; /* could be mval[0] another time... */
+ strip->end = strip->start + (strip->actend-strip->actstart);
+ /* simple prevention of zero strips */
+ if(strip->start>strip->end-2)
+ strip->end= strip->start+100;
+
+ strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION|ACTSTRIP_USEMATCH;
+
+ if (hold==1)
+ strip->flag = strip->flag|ACTSTRIP_HOLDLASTFRAME;
+
+ strip->mode = mode;
+
+ find_stridechannel(ob, strip);
+
+ set_active_strip(ob, strip);
+
+ strip->repeat = repeat;
+
+ act->id.us++;
+
+ BLI_addtail(&ob->nlastrips, strip);
+
+ BIF_undo_push("Add NLA strip");
+}
+
static void add_nla_databrowse_callback(unsigned short val)
{
/* val is not used, databrowse needs it to optional pass an event */
@@ -1760,4 +2005,76 @@
base->object->flag= base->flag;
}
+}
+
+void bake_all_to_action(short val)
+{
+ Object *ob=NULL;
+ bAction *newAction=NULL;
+ bAction *finalAction=NULL;
+ Ipo *ipo=NULL;
+ ID *id;
+ short hold, mode, cfra;
+ float repeat;
+ int sample;
+ ListBase masterkeys;
+ CfraElem *ce;
+
+ ob = get_object_from_active_strip();
+ build_match_caches();
+ if (ob) {
+
+ cfra=CFRA;
+ /* create master list of NLA action keys */
+ masterkeys.first=masterkeys.last=NULL;
+ build_nla_timeline(ob, &masterkeys);
+
+ /* burn object-level motion into a new action */
+ if (ob->flag&OB_ARMATURE) {
+ if ((val==1)||(val==3)) {
+ sample=10;
+ newAction = bake_obIPO_to_action(ob,sample,masterkeys);
+ if (newAction) {
+ /* add the new Action to NLA as a strip */
+ hold=1;
+ mode=ACTSTRIPMODE_MULT;
+ repeat=1.0;
+ CFRA=1;
+ add_nla_block_by_name(newAction->id.name, ob, hold, mode, repeat);
+ }
+ }
+ if ((val==2)||(val==3)) {
+ finalAction = bake_full_NLA_to_action(ob,masterkeys);
+ if (finalAction) {
+ hold=1;
+ mode=ACTSTRIPMODE_BLEND;
+ repeat=1;
+ ce=masterkeys.first;
+ CFRA=ce->cfra;
+ add_nla_block_by_name(finalAction->id.name, ob, hold, mode, repeat);
+ }
+ BLI_freelistN(&masterkeys);
+ }
+ if ((newAction) && ((val==1)||(val==3))) {
+ /* unlink the object's IPO */
+ ipo=ob->ipo;
+ if (ipo) {
+ id = &ipo->id;
+ if (id->us > 0)
+ id->us--;
+ ob->ipo = NULL;
+ }
+
+ /* clear any parent relationships */
+ if (ob->parent) {
+ ob->parent=NULL;
+ }
+
+ /* clear object-level constraints - doesn't work yet, not sure why */
+ /*if (ob->constraints.first)
+ free_constraints (ob->constraints);*/
+ }
+ }
+ CFRA=cfra;
+ }
}
Index: source/blender/src/edittime.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/edittime.c,v
retrieving revision 1.14
diff -u -r1.14 edittime.c
--- source/blender/src/edittime.c 4 Nov 2005 21:45:44 -0000 1.14
+++ source/blender/src/edittime.c 6 Jan 2006 17:13:38 -0000
@@ -46,14 +46,18 @@
#include "BLI_arithb.h"
#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_object_types.h"
#include "DNA_material_types.h"
+#include "DNA_nla_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
+#include "BKE_action.h"
+#include "BKE_displist.h"
#include "BKE_ipo.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
@@ -81,6 +85,7 @@
/* declarations */
void winqreadtimespace(ScrArea *, void *, BWinEvent *);
+static void sort_unique_frames(ListBase *masterkeys);
/* ************* Timeline marker code **************** */
@@ -283,6 +288,202 @@
return closest;
}
+void build_nla_timeline(Object *ob, ListBase *masterkeys) {
+ bActionStrip *curstrip;
+ bAction *act;
+ bActionChannel *achan;
+ ListBase elems, fracelems, chanelems;
+ CfraElem *ce, *cehi, *celo;
+ float hiframe, loframe, repeat, endframe, startframe, cut=0;
+ float cfra,pathlen;
+ int i,dostride;
+ BezTriple bezt;
+
+ add_to_cfra_elem_float(masterkeys, 1);
+
+ if (ob->nlastrips.first) {
+ for (curstrip=ob->nlastrips.first; curstrip; curstrip=curstrip->next) {
+ elems.first=elems.last=NULL;
+ /* create list of current action strip's IPOs (in Action time)*/
+ act = curstrip->act;
+ for (achan=act->chanbase.first; achan; achan=achan->next){
+ chanelems.first= chanelems.last= NULL;
+ make_cfra_list(achan->ipo, &chanelems);
+ addlisttolist(&elems,&chanelems);
+ BLI_freelist(&chanelems);
+ }
+
+ startframe=curstrip->actstart;
+ endframe=curstrip->actend;
+ repeat=1;
+ dostride=0;
+
+ /* obtain repeat values, either by panel, stride or stride/path */
+ if ((curstrip->flag & ACTSTRIP_USESTRIDE) && (ob->ipoflag & OB_DISABLE_PATH)==0 && ob->parent && ob->parent->type==OB_CURVE) {
+ Curve *cu = ob->parent->data;
+ if (cu->flag & CU_PATH){
+ /* Ensure we have a valid path */
+ if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(ob->parent, 0);
+ if(cu->path) {
+ if (curstrip->stridelen>.001) { /* stride length is set in n-key panel */
+ repeat=cu->path->totdist/curstrip->stridelen;
+ pathlen=cu->pathlen;
+ dostride=1;
+ } else { /* calculated with stride bone - argh! */
+ achan = get_action_channel(act, curstrip->stridechannel);
+ if(achan && achan->ipo) {
+ IpoCurve *icu= NULL;
+ int foundvert= 0;
+ float minx=0.0f, maxx=0.0f, miny=0.0f, maxy=0.0f;
+ int stride_axis= curstrip->stride_axis;
+
+ if(stride_axis==0) stride_axis= AC_LOC_X;
+ else if(stride_axis==1) stride_axis= AC_LOC_Y;
+ else stride_axis= AC_LOC_Z;
+
+ /* calculate the min/max */
+ for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+ if(icu->adrcode==stride_axis) {
+ if(icu->totvert>1) {
+ foundvert= 1;
+ minx= icu->bezt[0].vec[1][0];
+ maxx= icu->bezt[icu->totvert-1].vec[1][0];
+
+ miny= icu->bezt[0].vec[1][1];
+ maxy= icu->bezt[icu->totvert-1].vec[1][1];
+ }
+ break;
+ }
+ }
+
+ if(foundvert && miny!=maxy) {
+ repeat=cu->path->totdist/fabs(maxy-miny);
+ pathlen=cu->pathlen;
+ dostride=1;
+ } else {
+ }
+ }
+ }
+ }
+ }
+ } else {
+ repeat=curstrip->repeat;
+ endframe=curstrip->actend;
+ }
+
+ if ((repeat-floor(repeat)) > 0.00001) { /* copy element list for later use with fractional repeat */
+ fracelems.first= fracelems.last= NULL;
+ for (achan=act->chanbase.first; achan; achan=achan->next){
+ chanelems.first= chanelems.last= NULL;
+ make_cfra_list(achan->ipo, &chanelems);
+ addlisttolist(&fracelems,&chanelems);
+ BLI_freelist(&chanelems);
+ }
+ }
+
+ if (repeat > 1) { /* handle integer portion of repeat */
+ sort_unique_frames(&elems);
+ for (ce=elems.first; ce; ce=ce->next) {
+ for (i=2; i<=floor(repeat); i++) {
+ if (dostride==1) {
+ cfra=ce->cfra+((endframe-startframe)*(i-1));
+ } else {
+ cfra=ce->cfra+(((endframe-startframe)/repeat)*(i-1));
+ }
+ add_to_cfra_elem_float(&elems, cfra);
+ }
+ }
+ }
+
+ if ((repeat-floor(repeat)) > 0.00001) { /* add fractional element list to end of list */
+ sort_unique_frames(&fracelems);
+ cut = endframe * (repeat-floor(repeat));
+ for (ce=fracelems.first; ce; ce=ce->next) {
+ if (ce->cfra<=cut) {
+ if (dostride==1) {
+ cfra=ce->cfra+((endframe-startframe)*(floor(repeat)));
+ } else {
+ cfra=ce->cfra+(((endframe-startframe)/repeat)*(floor(repeat)));
+ }
+ add_to_cfra_elem_float(&elems, cfra);
+ }
+ }
+ BLI_freelistN(&fracelems);
+ /* add keyframe holder on last frame of strip, as this algo won't catch it */
+ add_to_cfra_elem_float(&elems, endframe);
+ }
+
+ /* convert cfras in this list into NLA timeline values */
+ sort_unique_frames(&elems);
+
+ for (ce=elems.first; ce; ce=ce->next) {
+ if (dostride==0) {
+ ce->cfra = get_actionstrip_frame(curstrip,ce->cfra,1);
+ } else {
+ ce->cfra = (((ce->cfra-curstrip->actstart)/repeat)*(pathlen/(endframe-startframe)))+curstrip->actstart;
+ }
+ }
+
+ celo=elems.first;
+ cehi=elems.last;
+ loframe=celo->cfra;
+ hiframe=cehi->cfra;
+
+ sort_unique_frames(masterkeys);
+ /* if not using add or multiply mode, wipe out underlying keys from master list */
+ /*if ((!(curstrip->mode&ACTSTRIPMODE_ADD)) && (!(curstrip->mode&ACTSTRIPMODE_MULT))) {
+ for (ce=masterkeys->first; ce; ce=ce->next) {
+ if ((ce->cfra>loframe) && (ce->cfra<hiframe)) {
+ if (ce->prev) {
+ ce=ce->prev;
+ BLI_freelinkN(masterkeys,ce->next);
+ }
+ else {
+ if (ce->next) {
+ ce=ce->next;
+ BLI_freelinkN(masterkeys,ce->prev);
+ }
+ }
+ }
+ }
+ }*/
+
+ /* add this keyframe list to the master list */
+ addlisttolist(masterkeys, &elems);
+
+ BLI_freelist(&elems); /* free the current strip's frame list */
+ }
+
+ /* sort the list and remove doubles */
+ sort_unique_frames(masterkeys);
+ }
+}
+
+static void sort_unique_frames(ListBase *masterkeys) {
+ CfraElem *outloop, *inloop;
+ float cfra;
+
+ if (masterkeys->first) {
+ for (outloop=masterkeys->last; outloop; outloop=outloop->prev) {
+ for (inloop=outloop->prev; inloop; inloop=inloop->prev) {
+ if (inloop->cfra>outloop->cfra) {
+ cfra=inloop->cfra;
+ inloop->cfra=outloop->cfra;
+ outloop->cfra=cfra;
+ }
+ }
+ }
+ for (outloop=masterkeys->last; outloop; outloop=outloop->prev) {
+ if ((outloop->prev) && (outloop->cfra==outloop->prev->cfra)) {
+ if (outloop->next) {
+ outloop=outloop->next;
+ BLI_freelinkN(masterkeys,outloop->prev);
+ }
+ }
+ }
+ }
+}
+
void nextprev_timeline_key(short dir)
{
/*mostly copied from drawobject.c, draw_object() AND editipo.c, movekey_obipo() */
Index: source/gameengine/Converter/BL_ActionActuator.cpp
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/gameengine/Converter/BL_ActionActuator.cpp,v
retrieving revision 1.14
diff -u -r1.14 BL_ActionActuator.cpp
--- source/gameengine/Converter/BL_ActionActuator.cpp 29 Nov 2005 12:45:18 -0000 1.14
+++ source/gameengine/Converter/BL_ActionActuator.cpp 6 Jan 2006 17:13:38 -0000
@@ -383,7 +383,7 @@
/* Find percentages */
newweight = (m_blendframe/(float)m_blendin);
- blend_poses(m_pose, m_blendpose, 1.0 - newweight, POSE_BLEND);
+ blend_poses(m_pose, m_blendpose, 1.0 - newweight, 0);
/* Increment current blending percentage */
m_blendframe = (curtime - m_blendstart)*KX_FIXED_FRAME_PER_SEC;

Event Timeline