From 5b93d5301803c197d40a72a295db0a0a0f2b115f Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Tue, 4 Dec 2012 17:27:36 +0100 Subject: [PATCH] experimental animation blending (set _animblend 1 to test it) --- qcsrc/client/autocvars.qh | 1 + qcsrc/client/csqcmodel_hooks.qc | 10 ++-- qcsrc/client/player_skeleton.qc | 90 +++++++++++++++++++++++++++++++++ qcsrc/client/player_skeleton.qh | 2 + qcsrc/client/progs.src | 2 + 5 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 qcsrc/client/player_skeleton.qc create mode 100644 qcsrc/client/player_skeleton.qh diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 0d4513f92..85829e809 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -402,3 +402,4 @@ string autocvar__cl_playermodel; float autocvar_cl_precacheplayermodels; float autocvar_cl_deathglow; float autocvar_developer_csqcentities; +float autocvar__animblend; diff --git a/qcsrc/client/csqcmodel_hooks.qc b/qcsrc/client/csqcmodel_hooks.qc index 7caa36c56..d850ef3d3 100644 --- a/qcsrc/client/csqcmodel_hooks.qc +++ b/qcsrc/client/csqcmodel_hooks.qc @@ -588,7 +588,7 @@ void CSQCModel_Hook_PreDraw(float isplayer) else { // we know that frame3 and frame4 fields, used by InterpolateAnimation, are left alone - but that is all we know! - float doblend = FALSE; + float doblend = autocvar__animblend; float flg = 0; if(self == csqcplayer) { @@ -630,12 +630,14 @@ void CSQCModel_Hook_PreDraw(float isplayer) CSQCModel_InterpolateAnimation_2To4_Do(); if(doblend) { - // build a skeletonobject + skeleton_from_frames(self); } else { - // remove skeletonobject if any - // all is done + free_skeleton_from_frames(self); + // just in case, clear these + self.lerpfrac3 = 0; + self.lerpfrac4 = 0; } } } diff --git a/qcsrc/client/player_skeleton.qc b/qcsrc/client/player_skeleton.qc new file mode 100644 index 000000000..25ab266ea --- /dev/null +++ b/qcsrc/client/player_skeleton.qc @@ -0,0 +1,90 @@ +.float skeleton_modelindex; +#define BONETYPE_LOWER 0 +#define BONETYPE_UPPER 1 +#define MAX_BONES 128 +.float skeleton_bonetype[MAX_BONES]; +.float skeleton_aimbone; +.float skeleton_numbones; + +void skeleton_identifybones(entity e) +{ + float s = e.skeletonindex; + float n = (e.skeleton_numbones = skel_get_numbones(s)); + e.skeleton_aimbone = 0; + float i; + for(i = 1; i <= n; ++i) + { + float t = BONETYPE_LOWER; + float p = skel_get_boneparent(s, i); + if(p > 0) + t = e.(skeleton_bonetype[p-1]); + string nm = skel_get_bonename(s, i); + if(nm == "spine2") + t = BONETYPE_UPPER; + if(nm == "upperarm_R") + e.skeleton_aimbone = i; + e.(skeleton_bonetype[i-1]) = t; + } +} + +void free_skeleton_from_frames(entity e) +{ + if(e.skeletonindex) + { + skel_delete(e.skeletonindex); + e.skeletonindex = 0; + } +} + +void skeleton_from_frames(entity e) +{ + float m = e.modelindex; + if(m != e.skeleton_modelindex) + { + if(e.skeletonindex) + { + skel_delete(e.skeletonindex); + e.skeletonindex = 0; + } + m = (e.skeleton_modelindex = e.modelindex); + if(m) + { + e.skeletonindex = skel_create(m); + skeleton_identifybones(e); + } + } + float s = e.skeletonindex; + if(!s) + return; + float bone; + float n = e.skeleton_numbones; + float savelerpfrac = e.lerpfrac; + float savelerpfrac3 = e.lerpfrac3; + float savelerpfrac4 = e.lerpfrac4; + for(bone = 0; bone < n; ) + { + float firstbone = bone; + float bonetype = e.skeleton_bonetype[bone]; + for(++bone; (bone < n) && (e.skeleton_bonetype[bone] == bonetype); ++bone) + ; + float lastbone = bone - 1; + if(bonetype == BONETYPE_LOWER) + { + // only show frames 1+3 + e.lerpfrac = 0; + e.lerpfrac3 = savelerpfrac3 * 2; + e.lerpfrac4 = 0; + } + else + { + // only show frames 2+4 + e.lerpfrac = savelerpfrac * 2; + e.lerpfrac3 = 0; + e.lerpfrac4 = savelerpfrac4 * 2; + } + skel_build(s, e, m, 0, firstbone + 1, bone); + } + e.lerpfrac = savelerpfrac; + e.lerpfrac3 = savelerpfrac; + e.lerpfrac4 = savelerpfrac; +} diff --git a/qcsrc/client/player_skeleton.qh b/qcsrc/client/player_skeleton.qh new file mode 100644 index 000000000..292cfca09 --- /dev/null +++ b/qcsrc/client/player_skeleton.qh @@ -0,0 +1,2 @@ +void free_skeleton_from_frames(entity e); +void skeleton_from_frames(entity e); diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 8c98a07b7..9d968f1fe 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -50,6 +50,7 @@ vehicles/vehicles.qh ../csqcmodellib/cl_model.qh ../csqcmodellib/cl_player.qh projectile.qh +player_skeleton.qh sortlist.qc miscfunctions.qc @@ -112,6 +113,7 @@ command/cl_cmd.qc ../warpzonelib/client.qc tturrets.qc +player_skeleton.qc ../common/animdecide.qc ../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail -- 2.39.2