by Spike » Tue Mar 10, 2015 8:09 am
input_angles is part of the local input state (you can query specific entries in the input log via getinputstate using values between clientcommandframe(equal to this obtains the current state that can change each frame, and which the server has not been told about yet) and servercommandframe(equal to this is the first frame that has not yet been applied to the latest raw data received from the server).
each client->server packet contains a copy of an input_angles value. this will be present within the SV_RunClientCommand function (assuming its present), and would normally be propogated into the player's v_angle field by the runstandardplayerphysics builtin which is assumed to be there (obviously, you can replace this if you wish, in which case you'll likely want to update v_angle or rewrite much of your ssqc to cope).
at the tail end of runstandardplayerphysics (or your equivelent), there will be some logic to set the player's angles field. typically using this formula: self.angles = [self.v_angle_x*-0.333,self.v_angle_y,self.v_angle_z]; this works around the input/renderer pitch difference, as well as prevents the player model from lying on his back when viewing vertically upward. with skeletal models, you'll probably want to discard the pitch entirely.
your SendEntity will then propogate the player's angle value somehow back to the csqc.
your csqc will receive that value and will then draw the entity using that angle.
basically, what I'm getting at, is that you need to separate the hips angle from the view angle. your player's hips will need to track the view/head angle over time (when moving, you can use the direction of travel to define the hips angle, and otherwise bound it so that its updated to match the view angle if the two angles diverge by more than 20 degrees or so).
but ultimately, you need to stop using input_angles to describe the angles of other players, because doing that really doesn't make sense.
if it IS the local player's entity, then you can override the view angle received from the server with the input_angles value, but if it is any other player, you cannot do that, and HAVE to use a value received from the server.
note that the hips angle can either be determined locally(in csqc), or in ssqc. if its in ssqc then all clients will have the same value. if its in csqc, you can more easily work with input_angles to avoid weirdness when lagged or paused.
also, addentity+PREDRAW_AUTOADD is redundant. you're generating two copies of the same entity.
side note:
distancetraveledtotheright = (neworigin - oldorigin) * v_right;
(the * is a dotproduct).
you can use the same maths to calculate the distance traveled forwards.
you can then rescale this by the distance the animation appears to move by per second, and adjust frame1time or so
self.frame1time += ((neworigin - oldorigin) * v_right) / 320;
note that this will also play the animation backwards if you travel to the left, which might be weird.
assuming the player only travels right, and the current .frame specifies a framegroup/sequence/animation that also travels right at a speed of exactly 320qu per second, this will make your player's feet exactly sync with the ground.
by determining the various strengths of the animations (ie: if travelling left instead, add in more of the move-left animation and decrease the move-right animation), you should be able to blend out the weird animations and thereby keep the player's feet synced with the ground regardless of the direction of travel.
also note that you can use v_forward instead of v_right to determine how far forwards you've gone.
deciding how far through an animation you are is easy. however, deciding which animations to play and the weight of those animations is an art form.
the total weight of all of your animations must equal 1 - any other sum total will result in scaling. you can use the addfrac and retainfrac arguments of skel_build in order to merge the varous animations together into the pose displayed that frame. just update the .frame+.frame1time fields between each call to skel_build to blend in the different animations.
it is unfortunate that .frame has this dual purpose. instead of adding lots of code to preserve its value, my recommendation would be to create a new .action field instead, and (within predraw) decide the .frame values based upon that. you can use the frameforname builtin to look up an animation by name from a model. this means you can provide models with animations used purely by name (allowing you to omit entire animations in certain models, potentially allowing you to use the same code to animate most monster types or whatever).
oh, and regarding your sidenote/question about csqctest, I'm not entirely sure how relevant csqctest still is. it was very much bolted on the side of vanilla quake with lots of random pointless things that are useful to test parts of the engine, but don't really do anything useful in themselves. it also lacks polish (in part because it was never written to be an actual worthwhile mod to play). parts of it are useful, but its not a mod I would recommend anyone use as a base.
I'd release the code for 'spark', which was some standalone mod I was hacking together ages back now, which was meant to include stuff like custom physics, skeletal animation blending, etc etc (ie: all the modern stuff and none of the quake stuff), but I don't own the content or half the qc code, and as such its not really usable as a demonstration of much at all. it would take a lot of work for it to be practical (as well as content so you can actually see it in action), and I have too many other distractions/projects right now.
maybe one day I'll get an itch to publicise+polish it.
.