huh?
makevectors itself doesn't affect any entity.
when given the angle '0 0 0' (identity) it returns the identity matrix, that is, v_forward='1 0 0', v_right = '0 1 0', v_up = ' 0 0 1'. pass in 90 degrees in some axis and everything will rotate around by 90 degrees.
sure, if you pass self.v_angles then the result is correct for self's orientation... as expected...
your two set_bone calls apply to different bones, neither replaces the other because they write out different bone matricies. remember that the child bone's matrix is expressed as relative to its parent, thus changing the parent affects both (without destroying any information in the child, but will destroy/replace existing animation data in the parent bone's pose), while changing the child affects only the child (and will destroy any existing information in the child's pose).
your second example will set the belly orientation to that of the pelvis, and set the belly's position to some weird fecked up angle value, so it moves forwards/back based upon angle.
which really doesn't make any sense at all.
in order to set a bone to an absolute world orientation+position, you must multiply the desired child position by the inverse of the parent's orientation+position. this cancels out the inherited position of the parent giving you a rotation to the child, which can be stored in the bone's pose. QC kinda sucks for matrix maths (and matrix inversion is nasty), so you'll want to avoid that and either use skel_set_bone_world (so the engine does the inversion stuff for you) or use skel_mul_bone(s) so you can just specify a rotation from its previous position.
if you merely want to move a bone, you should query that bone's current (rel) orientation, then discard its translation and call set_bone with v_forward/right/up still set to the queried bone orientation.
most of the time, you'll want to avoid ever using skel_set_bone (the one exception here is for the root bone), and to exclusively use skel_mul_bone. called after skel_build combos and combined with makevectors you can express the rotation of a bone relative to its parent bone in a fairly convienient way, without needing to care about its current orientation.
Code: Select all
float spine = skel_find_bone(self.skeletonindex, "spine");
gettaginfo(self, spine); //set v_forward, v_right, v_up. discard world coord
vector spineang = vectoangles(v_forward, v_up); //convert the orientation to eular angles. lets hope its correctly normalised (in which case v_right is surplus to requirements).
spineang_x *= -1; //stupid vectoangle/mdl bug
//spineang is now the bone's current angle in world space. which is handy, because input_angles is in world space too
makevectors([input_angles_x - spineang_x, input_angles_y - spineang_y, 0]); //determine the new orientation relative to the old, in eular angles. note that eular angles suck, but we're discarding the roll angle anyway. writes v_forward and friends.
skel_mul_bone(self.skeletonindex, spine, '0 0 0'); //rotate the spine bone by the v_forward and friends values.
bones above your spine will now be facing your input_angles. bones below the spine will still be facing the entity angles, as they were before adding this code.
or something, hell, I don't know. I hate matricies. you figure it out.
of course if you just use the entity angle in the first place instead of gettaginfo+vectoangles, you can save a lot of work for the engine as well as allowing pelvis angle wobbles to affect the torso.