frame1time in FTE
Posted: Tue Jun 02, 2015 3:49 pm
This issue really makes me nervous.. let's imagine a player with a skeleton with two set of bones. spineupper bone to head bone(including shoulders,arms and weapon bones) control upper movement and hips bone to left foot bone control lower movement.
The hierarchy of bones isSo, first lower bones, than upper bones, just like skeletal.txt said
Now, creating PlayerLowerAnims (used in predraw function) function for playing lower running/idle animation it's simple
Both idle and running animation are looped animations, so self.frame1time += frametime is ok. Now comes the problem.
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 thisto reset the animation, but it will break self.frame1time for legs because both upper bones and lower bones share same frame1time!
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
But animation are not synced well, sometimes they start some time after the shot impulse or they play twice or more for one single shoot impulse.
This code is placed BEFORE lower bones as stated in skeletal.txt
Plus, skeletal.txt said
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
Then I should fix leg.origin to player's spineupper origin (and hoping that it centers the right orientation) and leg.angles to player.angles with vectoangles(v_up, v_forward), but, why? I mean, it's invisible, why makes all this effort?
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
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