How Do I Make An Entity Rotate Around Its Own Axis?
Hello,
I'm having trouble trying to make entities rotate around their own axes instead of the world's in QC, for example if they're pointing straight forward using only angles_y to rotate it works just fine, but what about when they're tilted (angles_x or angles_z != 0), how can it be done? I tried using v_up, sin, cos and crossproduct to no avail. If it's actually possible, how do I do it?
Any help will be appreciated.
Func_rotate
#3118 posted by
madfox on 2023/12/23 22:07:58
There is a mod called "extras_r4" from Hipnotic, that uses rotating models with usefull info.
Here is a link from Khreator.
https://github.com/khreathor/extras_r5/blob/master/progs.src
Also I put a link on quaketastic with some info.
There is also a rotatetut.zip.
https://www.quaketastic.com/files/rotate.html
Hope it's of any help.
#3117
#3119 posted by Spoike on 2023/12/24 17:31:42
but they do use their own rotations... just note that bmodels normally have their origin (aka pivot) at 0,0,0 - I assume that's what you're referring to?
if so just throw in an 'origin'-textured cube brush and its midpoint will become your bmodel's new origin/pivot and then you can vectoangles or whatever however you want.
also, angles are pitch, yaw, roll, with a bug where mdls have the wrong sign for their pitch(x) values, which vectoangles (but not makevectors) replicates.
so if you are using vectoangles to compute a bmosel's angles then you must flip (*-1) the _x part of vectoangles return value.
mathematically, the eular angles rotate(yaw, y) around the up(z) axis, the rotate(pitch, x) around the right(y) axis, and then finally rotate(roll, z) around the forward(x) axis... the fact that these operations are all ordered make life a real pain.
some engines provide a two-arg form of vectoangles which takes a up vector as an extra arg beyond the normal forward vector, which allows it to compute the correct roll angles instead of just pitch+yaw.
this allows the qc to do use makevectors to provide a 3x3 matrix with forward/left/up rows, transform those vectors in weird ways and then vectoangles2 then back to usable angles (remembering to then fix up the pitch... stoopid bug). its still really messy of course, but still easier than figuring out all the ordering mess of eular angles!
@Spoike, @madfox
Thanks guys, made a bit of progress. Turns out I may need a rotation matrix, need to figure out how to multiply them in QC.
I forgot to be more specific: I'm experimenting with making a spaceship combat mod, and some ships have turrets mounted on them, and to make it simpler those turrets can only yaw (relative to the ship), they work fine when there's nothing to attack and they just match the ship's angles, but when they're turned elsewhere, especially when the ship is tilted, they look funny because I initially tell them to always match the ship's X and Z angles, and the Y angle is different because the turret is looking at an enemy.
I hope I explained it well...
Maffs
#3121 posted by Spoike on 2023/12/25 00:01:28
Something like this:
void rotatevectorsbyangle(vector angle)
{
vector oldx=v_forward, oldy='0 0 0'-v_right, oldz=v_up;
angle_x = -angle_x;
makevectors(angle);
vector angx=v_forward, angy='0 0 0'-v_right, angz=v_up;
v_forward_x = angx_x*oldx_x + angx_y*oldy_x + angx_z*oldz_x;
v_forward_y = angx_x*oldx_y + angx_y*oldy_y + angx_z*oldz_y;
v_forward_z = angx_x*oldx_z + angx_y*oldy_z + angx_z*oldz_z;
v_right_x = angy_x*oldx_x + angy_y*oldy_x + angy_z*oldz_x;
v_right_y = angy_x*oldx_y + angy_y*oldy_y + angy_z*oldz_y;
v_right_z = angy_x*oldx_z + angy_y*oldy_z + angy_z*oldz_z;
v_up_x = angz_x*oldx_x + angz_y*oldy_x + angz_z*oldz_x;
v_up_y = angz_x*oldx_y + angz_y*oldy_y + angz_z*oldz_y;
v_up_z = angz_x*oldx_z + angz_y*oldy_z + angz_z*oldz_z;
v_right = '0 0 0'-v_right;
}
IIRC the initial v_forward/v_right/v_up must be the parent's vectors (from makevectors - beware pitch sign). the 'angle' arg is the child's angles relative to its parent ent.
You can then use vectoangles2 to compute your child model's angles, but if its an older engine then it'll ignore the up vector and give you a roll angle of 0 which will be glitchy if your parent is freely pitching/rolling.
actual 6dof stuff will require you to make clientside changes so the player's view angles don't get bounded weirdly etc.
#3121
Many thanks, works like a charm!