From 1e12387a33e1063e74f9c44ab7d504721a0509f5 Mon Sep 17 00:00:00 2001 From: divverent Date: Thu, 13 Dec 2012 14:44:12 +0000 Subject: [PATCH 1/1] skel_build: normalize the per-bone matrices Looks a lot better if animations are "mismatched" in some evil ways. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11859 d7cf8633-e32d-0410-b094-e92efae38249 --- clvm_cmds.c | 13 +++++++------ svvm_cmds.c | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/clvm_cmds.c b/clvm_cmds.c index d49eab56..c7b24a4a 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -3970,7 +3970,7 @@ static void VM_CL_skel_build(prvm_prog_t *prog) int blendindex; framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS]; frameblend_t frameblend[MAX_FRAMEBLENDS]; - matrix4x4_t blendedmatrix; + matrix4x4_t bonematrix; matrix4x4_t matrix; PRVM_G_FLOAT(OFS_RETURN) = 0; if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex])) @@ -3982,17 +3982,18 @@ static void VM_CL_skel_build(prvm_prog_t *prog) VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model, cl.time); blendfrac = 1.0f - retainfrac; for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++) - frameblend[numblends].lerp *= blendfrac; + ; for (bonenum = firstbone;bonenum <= lastbone;bonenum++) { - memset(&blendedmatrix, 0, sizeof(blendedmatrix)); - Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac); + memset(&bonematrix, 0, sizeof(bonematrix)); for (blendindex = 0;blendindex < numblends;blendindex++) { Matrix4x4_FromBonePose7s(&matrix, model->num_posescale, model->data_poses7s + 7 * (frameblend[blendindex].subframe * model->num_bones + bonenum)); - Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp); + Matrix4x4_Accumulate(&bonematrix, &matrix, frameblend[blendindex].lerp); } - skeleton->relativetransforms[bonenum] = blendedmatrix; + Matrix4x4_Normalize3(&bonematrix, &bonematrix); + Matrix4x4_Scale(&skeleton->relativetransforms[bonenum], retainfrac, retainfrac); + Matrix4x4_Accumulate(&skeleton->relativetransforms[bonenum], &bonematrix, blendfrac); } PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1; } diff --git a/svvm_cmds.c b/svvm_cmds.c index 172827d2..1c5c00a6 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -2912,7 +2912,7 @@ static void VM_SV_skel_build(prvm_prog_t *prog) int blendindex; framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS]; frameblend_t frameblend[MAX_FRAMEBLENDS]; - matrix4x4_t blendedmatrix; + matrix4x4_t bonematrix; matrix4x4_t matrix; PRVM_G_FLOAT(OFS_RETURN) = 0; if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex])) @@ -2924,17 +2924,18 @@ static void VM_SV_skel_build(prvm_prog_t *prog) VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model, sv.time); blendfrac = 1.0f - retainfrac; for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++) - frameblend[numblends].lerp *= blendfrac; + ; for (bonenum = firstbone;bonenum <= lastbone;bonenum++) { - memset(&blendedmatrix, 0, sizeof(blendedmatrix)); - Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac); + memset(&bonematrix, 0, sizeof(bonematrix)); for (blendindex = 0;blendindex < numblends;blendindex++) { Matrix4x4_FromBonePose7s(&matrix, model->num_posescale, model->data_poses7s + 7 * (frameblend[blendindex].subframe * model->num_bones + bonenum)); - Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp); + Matrix4x4_Accumulate(&bonematrix, &matrix, frameblend[blendindex].lerp); } - skeleton->relativetransforms[bonenum] = blendedmatrix; + Matrix4x4_Normalize3(&bonematrix, &bonematrix); + Matrix4x4_Scale(&skeleton->relativetransforms[bonenum], retainfrac, retainfrac); + Matrix4x4_Accumulate(&skeleton->relativetransforms[bonenum], &bonematrix, blendfrac); } PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1; } -- 2.39.2