by Spike » Wed Jun 03, 2015 12:48 pm
skel_build(self.legstime, self, self.modelindex, 0, bHips, bFootL, 1);
NO!
self.legstime is NOT a skeletal object. Why would you do that?
retainfrac and addfrac are quite simple:
objectbonematrix = (objectbonematrix * retainfrac) + (modelbonematrix * addfrac);
this means that you can have multiple animations blending together to update a single bone.
actually, its more complex than that:
objectbonematrix = (objectbonematrix * retainfrac) + (modelbonematrix[ent.frame2] * addfrac * ent.lerpfrac) + (modelbonematrix[ent.frame] * addfrac * (1-ent.lerpfrac));
Actually, its more complex than that:
if (omitted(addfrac)) addfrac = 1-retainfrac;
objectbonematrix *= retainfrac;
f = ent.frame;
pose = floor(ent.frame1time / modelframe[f].framerate);
frac = (ent.frame1time / modelframe[f].framerate) - pose;
objectbonematrix += addfrac * (1-ent.lerpfrac) * (modelframe[f].pose[clampormoduloiflooping(modelframe[f].looping, pose+1, modelframe[f].numposes)] * frac + modelframe[f].pose[clampormoduloiflooping(modelframe[f].looping, pose+0, modelframe[f].numposes) * (1-frac));
f = ent.frame2;
pose = floor(ent.frame2time / modelframe[f].framerate);
frac = (ent.frame2time / modelframe[f].framerate) - pose;
objectbonematrix += addfrac * ent.lerpfrac * (modelframe[f].pose[clampormoduloiflooping(modelframe[f].looping, pose+1, modelframe[f].numposes)] * frac + modelframe[f].pose[clampormoduloiflooping(modelframe[f].looping, pose+0, modelframe[f].numposes) * (1-frac));
Actually, its more complex than that:
... frame3, frame3time, lerpfrac3, frame4, frame4time, lerpfrac4 fields exist. which provide 8-way animation (or 4-way, if your model doesn't use framegroups properly).
with all four added together, scaled by addfrac and their own lerpfrac weights, and then with the existing bone added scaled by retainfrac.
MATHS! just what you always wanted!
Actually, its more complex than that:
baseframe, baseframe2, baseframe1time, baseframe2time, baselerpfrac, basebone exist, which allows you to use different frame fields based upon the bone number (but 8-way is pure overkill). This is some WIP extension I never quite documented properly, in part because the server equivelent of it is more useful due to ssqc not being able to send skeletal objects over the net in combination with the fact that I never made a network protocol for it.
(the basebone field specifies the first bone that is logically no longer part of the 'base' group, with the first bone in the model being the first bone of this group, 0 thus means that the group is empty and thus the other base* fields are irrelevant).
Actually, I'm tempted to mention halflife model formats with its bone controller stuff, but I value my sanity too much.
Oh yeah, this is all per bone(or per-bonerange, as far as skel_build is concerned, for efficiency).
when you have torso and legs, you're updating two bone ranges independantly.
when you have a forwards animation and a sideways animation, and your player is moving diagonally, you want to update the lower bonerange TWICE, once with each animation that is active. this is where your addfrac/retainfrac arguments become useful. with this, you can avoid using frame2+lerpfrac entirely, if you feel that way inclined. or you can have 1024-way animation blending or whatever... if you have that many animations anyway.
if you scale each animation's weight by the total weights currently active, you can avoid any rescaling of your model (but you'll need to ensure that inactive animations still drop to 0 somehow, ideally linearly).
.