forked from bartvdbraak/blender
BGE: allow action blending by bringing back blend_poses() as game_blend_poses, the new animation system doesnt use it but doesnt have a replacement function so it can be kept for the BGE only.
This commit is contained in:
parent
6c139156cf
commit
c3b8db4833
@ -137,7 +137,7 @@ void framechange_poses_clear_unkeyed(void);
|
||||
void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, char groupname[], float cframe);
|
||||
|
||||
/* exported for game engine */
|
||||
void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode);
|
||||
void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, short mode*/); /* was blend_poses */
|
||||
void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
|
||||
|
||||
/* for proxy */
|
||||
|
@ -581,6 +581,77 @@ void game_copy_pose(bPose **dst, bPose *src)
|
||||
*dst=out;
|
||||
}
|
||||
|
||||
|
||||
/* Only allowed for Poses with identical channels */
|
||||
void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/)
|
||||
{
|
||||
short mode= ACTSTRIPMODE_BLEND;
|
||||
|
||||
bPoseChannel *dchan;
|
||||
const bPoseChannel *schan;
|
||||
bConstraint *dcon, *scon;
|
||||
float dstweight;
|
||||
int i;
|
||||
|
||||
switch (mode){
|
||||
case ACTSTRIPMODE_BLEND:
|
||||
dstweight = 1.0F - srcweight;
|
||||
break;
|
||||
case ACTSTRIPMODE_ADD:
|
||||
dstweight = 1.0F;
|
||||
break;
|
||||
default :
|
||||
dstweight = 1.0F;
|
||||
}
|
||||
|
||||
schan= src->chanbase.first;
|
||||
for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
|
||||
if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
|
||||
/* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
|
||||
|
||||
/* Do the transformation blend */
|
||||
if (schan->flag & POSE_ROT) {
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
|
||||
/* no 'add' option for constraint blending */
|
||||
dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
|
||||
}
|
||||
}
|
||||
|
||||
/* this pose is now in src time */
|
||||
dst->ctime= src->ctime;
|
||||
}
|
||||
|
||||
void game_free_pose(bPose *pose)
|
||||
{
|
||||
if (pose) {
|
||||
@ -1039,75 +1110,6 @@ static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src,
|
||||
VecAddf(dst->cyclic_offset, dst->cyclic_offset, src->cyclic_offset);
|
||||
}
|
||||
|
||||
|
||||
/* Only allowed for Poses with identical channels */
|
||||
void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
|
||||
{
|
||||
bPoseChannel *dchan;
|
||||
const bPoseChannel *schan;
|
||||
bConstraint *dcon, *scon;
|
||||
float dstweight;
|
||||
int i;
|
||||
|
||||
switch (mode){
|
||||
case ACTSTRIPMODE_BLEND:
|
||||
dstweight = 1.0F - srcweight;
|
||||
break;
|
||||
case ACTSTRIPMODE_ADD:
|
||||
dstweight = 1.0F;
|
||||
break;
|
||||
default :
|
||||
dstweight = 1.0F;
|
||||
}
|
||||
|
||||
schan= src->chanbase.first;
|
||||
for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
|
||||
if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
|
||||
/* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
|
||||
|
||||
/* Do the transformation blend */
|
||||
if (schan->flag & POSE_ROT) {
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
|
||||
/* no 'add' option for constraint blending */
|
||||
dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
|
||||
}
|
||||
}
|
||||
|
||||
/* this pose is now in src time */
|
||||
dst->ctime= src->ctime;
|
||||
}
|
||||
|
||||
typedef struct NlaIpoChannel {
|
||||
struct NlaIpoChannel *next, *prev;
|
||||
float val;
|
||||
|
@ -409,7 +409,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
|
||||
/* Find percentages */
|
||||
newweight = (m_blendframe/(float)m_blendin);
|
||||
// XXX blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND);
|
||||
game_blend_poses(m_pose, m_blendpose, 1.0 - newweight);
|
||||
|
||||
/* Increment current blending percentage */
|
||||
m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
|
||||
|
@ -43,6 +43,9 @@ float BL_ScalarInterpolator::GetValue(float currentTime) const {
|
||||
}
|
||||
|
||||
BL_InterpolatorList::BL_InterpolatorList(struct AnimData *adt) {
|
||||
if(adt->action==NULL)
|
||||
return;
|
||||
|
||||
for(FCurve *fcu= (FCurve *)adt->action->curves.first; fcu; fcu= (FCurve *)fcu->next) {
|
||||
if(fcu->rna_path) {
|
||||
BL_ScalarInterpolator *new_ipo = new BL_ScalarInterpolator(fcu);
|
||||
|
Loading…
Reference in New Issue
Block a user