Author Topic: How do i rotate a godamn angle vector (FIXED)  (Read 2646 times)

how do i take something like the player's muzzle vector and rotate it to the left/right or up/down by a constant x degrees and not have it forget up at different player rotations

Code: [Select]
function gunImage::onFire(%db,%pl,%slot)
{
%up = %pl.getUpVector();
%muzVec = %pl.getMuzzleVector(%slot);
%forward = %pl.getForwardVector();
%muzPoint = %pl.getMuzzlePoint(%slot);

%rightVec = vectorCross(%forward,%up);
%upHack = %pl.getUpVectorHack();

%proj_or[0] = 0.2 SPC %rightVec;
%proj_or[1] = -0.2 SPC %rightVec;
%proj_or[2] = 0.2 SPC %upHack;
%proj_or[3] = -0.2 SPC %upHack;

for(%i=0;%i<4;%i++)
{
%ang = getWord(%proj_or[%i],0);
%axis = getWords(%proj_or[%i],1,3);
%vec = vectorAngleRotate(%muzVec,%axis,%ang);
%p = new (%db.projectileType)()
{
dataBlock = %db.projectile;
initialVelocity = vectorScale(%vec,60);
initialPosition = %muzPoint;
sourceObject = %pl;
sourceSlot = %slot;
client = %pl.client;
};
MissionCleanup.add(%p);
}
}
function vectorAngleRotate(%vec,%axis,%ang)
{
%x = getWord(%vec,0);
%y = getWord(%vec,1);
%z = getWord(%vec,2);
%u = getWord(%axis,0);
%v = getWord(%axis,1);
%w = getWord(%axis,2);
%cos = mCos(%ang);
%sin = mSin(%ang);
return %u*(%u*%x+%v*%y+%w*%z)*(1-%cos)+%x*%cos+(%v*%z-%w*%y)*%sin SPC %u*(%u*%x+%v*%y+%w*%z)*(1-%cos)+%y*%cos+(%w*%x-%u*%z)*%sin SPC %u*(%u*%x+%v*%y+%w*%z)*(1-%cos)+%z*%cos+(%u*%y-%v*%x)*%sin;
}
function player::getUpVectorHack(%pl)
{
%muz = %pl.getMuzzleVector(0);
%forward = %pl.getForwardVector();
%up = %pl.getUpVector();
return vectorAngleRotate(%muz,vectorCross(%forward,%up),$PI/2);
}
heres a vector rotate function which amade did all the work for
input the base vector, the upwards orientation, and the angle

getUpVectorHack is a vector that actually represents the players eye point rotated 90 degrees upwards

the code for the gun fires 4 projectiles all rotated 0.2 radians to the left/right and up/down
« Last Edit: February 26, 2016, 12:05:58 PM by Swollow »

what i would do is either convert an euler angle to a vector and add it to the vector you want to rotate, or convert the vector you want to rotate to an euler and add an euler angle to that

for euler->vector conventions this topic is your friend: http://forum.blockland.us/index.php?topic=270070.0
« Last Edit: February 24, 2016, 12:27:07 PM by Gytyyhgfffff »

i have all those functions i guess im just too dumb to understand how to do it could you provide an example pretty please?

it would be something like this i believe
Code: [Select]
%origVec = %player.getEyeVector();
%euler = VectorToEuler(%origVec);
%euler = VectorAdd(%euler, "90 0 0"); // VectorAdd just adds together any 3Pointf, doesn't matter if it isn't a true vector or not
%resultVec = EulerToVector(%euler);
if anything is wrong it's because i made this on my phone and typing on it is pretty difficult

that doesnt look like it would work but if it does i would be blown away and be very much grateful

it gets worse and worse when you look up/down

i have been wondering this myself and it's a wonderfully simple idea idk how it's so gosh darn difficult to figure out

I don't know anything about the particulars of muzzle vectors, but are you sure you're not dealing with quaternions?

I don't know anything about the particulars of muzzle vectors, but are you sure you're not dealing with quaternions?
Blockland positions/rotations don't use quaternions, so no.

Rotating counterclockwise about the +z axis (i.e. left/right):
Code: [Select]
%x = getWord(%muzzleVector, 0);
%y = getWord(%muzzleVector, 1);
%z = getWord(%muzzleVector, 2);
%a = %x*mCos(%angle)-%y*mSin(%angle);
%b = %x*mSin(%angle)+%y*mCos(%angle);
%c = %z;
%vec = %a SPC %b SPC %c;
This only works if your player's up vector is the +z axis (so it won't necessarily work correctly if they're in a vehicle). You can adapt the below code if it's important that it works in a vehicle.

Rotating around the player's right vector (i.e. up/down) is a bit more fun (your definition of fun may vary) and looks like this:

Where the player's muzzle vector is (x,y,z) and the player's right vector is (u,v,w). The angle of rotation, of course, is θ. Since the player's right vector will always be a unit vector, u2+v2+w2 is always 1, simplifying things a bit. It would be possible to simplify it a bit further if you assume that the player's up vector is always the +z axis, which would make the right vector always lie in the xy plane. This assumption, however, would make the operation not necessarily work if the player is in a vehicle.

This monstrosity should do it:
Code: [Select]
%rightVector = vectorCross(%forwardVector, %upVector);
%x = getWord(%muzzleVector, 0);
%y = getWord(%muzzleVector, 1);
%z = getWord(%muzzleVector, 2);
%u = getWord(%rightVector, 0);
%v = getWord(%rightVector, 1);
%w = getWord(%rightVector, 2);
%a = %u*(%u*%x+%v*%y+%w*%z)*(1-mCos(%angle))+%x*mCos(%angle)+(%v*%z-%w*%y)*mSin(%angle);
%b = %u*(%u*%x+%v*%y+%w*%z)*(1-mCos(%angle))+%y*mCos(%angle)+(%w*%x-%u*%z)*mSin(%angle);
%c = %u*(%u*%x+%v*%y+%w*%z)*(1-mCos(%angle))+%z*mCos(%angle)+(%u*%y-%v*%x)*mSin(%angle);
%vec = %a SPC %b SPC %c;
(Source for second part)

EDIT: To generalize this, replace %muzzleVector with the vector you want to be rotated and %rightVector with the vector you want to rotate your other vector around. The vector you're rotating around needs to be normalized (i.e. length 1) or weird things are probably going to happen.

Note that mCos and mSin both require the supplied angle to be given in radians.
« Last Edit: February 26, 2016, 12:55:00 AM by Amade »

vector math to the rescue.
this is definitely bookmark-worthy, amade, thanks.

the left and right code does not work if properly if your z muzzle vector is not 0 and becomes less and less accurate, however the second piece of code works perfectly

since I'm not a math god could you explain how I would format the first code to have the same affect as the second piece but to the left/right
« Last Edit: February 26, 2016, 12:42:41 AM by Swollow »

the left and right code does not work if properly if your z muzzle vector is not 0 and becomes less and less accurate, however the second piece of code works perfectly

since I'm not a math god could you explain how I would format the first code to have the same affect as the second piece but to the left/right
Just replace the right vector with the up vector

Just replace the right vector with the up vector
same issue, it may be worth noting that %pl.getUpVector() always returns "0 0 1"

same issue
I think it's unlikely that that can be fixed. I'll look into it tomorrow when I have more time.