The hierarchy of bones is
Code: Select all
root,spine,hips,thigh_r,leg_r,foot_r,thigh_l,leg_l,foot_l,spine2,neck,head,clavicle_r,armupper_r,armlower_r,hand_r,weapon_r,thumb1_r,thumb2_r,finger1_r,finger2_r,holster_r,clavicle_l,armupper_l,armlower_l,hand_l,weapon_l,thumb1_l,thumb2_l,finger1_l,finger2_l,holster_l
Now, creating PlayerLowerAnims (used in predraw function) function for playing lower running/idle animation it's simple
Code: Select all
void PlayerLowerAnims()
{
if(self.velocity_x > 20||self.velocity_y > 20||self.velocity_x < -20||self.velocity_y < -20){
self.frame = animRun;
self.frame1time += frametime;
skel_build(self.skeletonindex, self, self.modelindex, 0, bHips, bFootL, 1);
}
else{
self.frame = animIdle;
self.frame1time += frametime;
skel_build(self.skeletonindex, self, self.modelindex, 0, bHips, bFootL, 1);//build lower part
}
}
Imagine that I want to add a PlayerUpperAnims to control fire animations from spineupper and up. Fire animations are non-looped, so self.frame1time += frametime it's not good, because frame1time animation, after the shot impulse, must be set to 0 just like this
Code: Select all
if(self.weaponFpvShot == TRUE){
self.frame = animFirePistol;
self.frame1time += frametime;
skel_build(self.skeletonindex, self, self.modelindex, 0, bSpine2, bHolsterL, 1);
}
else{
self.frame = 0;
self.frame1time = 0;
skel_build(self.skeletonindex, self, self.modelindex, 0, bSpine2, bHolsterL, 1);
}
Just note that the above method works beautifully for weapon view models in CSQC but just because weapon entity doesn't share frame1time with anyone else!!
Spike once told me, to play animation discarding looping, to do like this
Code: Select all
duration = frameduration(self.modelindex, animFirePistol);
if(self.weaponFpvShot == TRUE){
//non-loop animation code
self.frame = animFirePistol;
t = self.frame1time / duration;
self.frame1time = (t-floor(t))*(duration/0.8);
//build upper bones
skel_build(self.skeletonindex, self, self.modelindex, 0, bSpine2, bHolsterL, 1);//build upper part
}
This code is placed BEFORE lower bones as stated in skeletal.txt
Which it's not incorrect: torso + legs separaration WILL work. The problem is frame duration / looping separation for upper bones animations and lower bones animations.Separation of torso+legs can also be achieved, by calling skel_build multiple times with separate bone ranges.
If your model is arranged with the legs as the early bones, and the torso as the later bones, you can use skel_find_bone to find the lower spine bone, and animate the two bone groups separately by updating the animation fields for torso, then for legs.
Plus, skeletal.txt said
How can I assign a null entity to .frame?Note that you can simply pass something other than 'self' for the legs, and it'll use the animation fields from a different (invisible) entity instead.
I mean, to be valid, this invisible entity (for example named legs)should be spawn in CSQC_Init. It should be set same model of player, it should be created a skeleton in Startup player function
Code: Select all
if (!legs.skeletonindex){
legs.skeletonindex = skel_create(legs.modelindex);
}
And, at last, how can I draw those frames if it's not "self" which it's playing it but, instead, that invisible legs entity?
This last phrase Spike wrote it's really difficult to understand.
I also thought:"well I can use self.frame and self.frame2!" I set self.frame to upper animations and self.frame2 for lower bones and I play them simoultaneously. Yes, but how? self.frame2 implicates the use of self.lerpfrac, wich set to 0.5 plays self.frame and self.frame2 at 50%, but, of course, they appear as "melted" together, which it's not what I need.
It would be great to use, in this case, self.lerpfrac = middlebone; and, for middlebone, use the bone that divides upper animations from lower ones.
Sorry for the long post but this topic is not clearly described anywhere.
Ideas?
Thanks A LOT for any input