by Spike » Wed May 11, 2011 11:37 am
to animate something in csqc, you have a few different fields.
.frame
.frame2
.lerpfrac
.frame1time
.frame2time
What these fields provide you is 4-way interpolation.
if .frame refers to a framegroup, then that framegroup will be animated using the frame1time field, specifically this field says the time offset of the animation. You can change the speed of the animation by adding different amounts relative to the current frame time. Adding distance moved may be a good value for walking animations, for instance.
When your model is meant to start shooting, its time to blend. You can blend by setting the .frame to the new frame, the .frame2 field to the old frame, and the .lerpfrac field to the amount of frame2 to use (0 to 1). Over time, reduce the influence of frame2 by reducing lerpfrac to 0. Make sure you keep the animation times running.
for ssqc code, the frame1time/frame2time is defined to be (curtime - frameXstarttime), for the most part. csqc has more control, but it generally has to update the field each frame.
if your model does not use framegroups, then you only have the 3 fields, frame, frame2, lerpfrac, that need to be considered. Creating viable animations is more awkward here, however.
The description above applies whether the model is skeletal or not.
There are additional extensions which provide direct skeletal control.
One of them is FTE's basebone stuff, which adds 6 additional fields:
.basebone
.baseframe
.baseframe2
.baselerpfrac
.baseframe2time
.baseframe1time
these fields can be used to animate a models legs or so sepearately from the torso. Specificially, they work just as the fields descibed earlier, except apply to bones 0 up to the bone specified by basebone, while the standard fields described earlier affect bones between basebone and the max. So you can split the model into two separate logical animations. DP does not support them however.
The other is the skeletal objects extension, which is fairly complicated.
There is a builtin which creates a new skeletal object, as well as a builtin that destroys one.
You can attach an individual skeletal object to one or multiple entities. All entities using that skeletal object will have their animations overridden by the object's bonestate. You can copy the bonestate from an entity into a skeletal object by using skel_build. This builtin takes a bone range, which permits you to copy only a subset of the bones. So you can set your animation for the legs, copy the legs, set the animation for the torso, then copy that part over too. There is again a 'frac' value to copy in, which means that you can apply various percentages if you wish to blend in multiple animations.
You can call skel_build using any source modelindex you want. This permits you to copy animations from other models if you're too lazy to create animations for every model, for instance, or if you have each framegroup stored seperately from the mesh itself (like doom3/md5 does). They need to be compatible or it makes no sense, of course. Its plausable that if you have a specific bone heirachy used for every single model player model, then you can have meshes that can be positioned over arbitary attachment points like hats or so, even if each player model has different actual animations (hats with rims that bob, rather than statically positioned hats that don't react to the animations of the player other than moving just their origin).
Additionally, there are a couple of extra builtins which allow you to specify the precise angles/offset of specific bones. This is useful for torsos or necks if you want to angle it separately from the rest of the model. Using some maths, you can get eyeballs on stalks to twist in weird ways to always watch the camera, or directly control segments of a robe to give a somewhat realisitic swinging animation.
Basically, you need your bone ordering to be somewhat logical, or the bone ranges that the builtins accept will not make sense. The builtins do not understand groups of bones in any way other than as a range of bones. The group of bones that are the lower body are logically everything up to the hip bone. All leg bones must be numerically lower than this terminating hip bone. As an example. Then you can use skel_build on 0-to-hip, and hip-to-max. The same would apply if you wanted to control only one arm, in which case you would want every bone from the shoulder to the finger tips to be in a single consecutive list so that you can control them all in one go.
Again, framegroups are also optional, but using them properly and where it makes sense is likely to result in simpler code.
.