Files
DayZ-Epoch/SQF/dayz_code/compile/fn_setpitchbank.sqf
icomrade e54b9983dd Replace forEach with Count
Use count where you do not need _forEachIndex variable, it's quicker
than forEach.
2014-05-27 15:37:57 -04:00

124 lines
3.5 KiB
Plaintext

/************************************************************
Set Pitch && Bank
By General Barron ([EMAIL=aw_barron@hotmail.com]aw_barron@hotmail.com[/EMAIL]) && vektorboson
Parameters: [object, pitch, bank]
Returns: nothing
Rotates an object, giving it the specified pitch && bank,
in degrees.
Pitch is 0 when the object is level; 90 when pointing straight
up; && -90 when pointing straight down.
Bank is 0 when level; 90 when the object is rolled to the right,
-90 when rolled to the left, && 180 when rolled upside down.
Note that the object's yaw can be set with the setdir command,
which should be issued before using this function, if required.
The pitch/bank can be leveled out (set to 0) by using the
setdir command.
************************************************************/
//extract parameters
private ["_obj","_pitch","_bank","_yaw","_vdir","_vup","_sign","_rotate"];
_obj = _this select 0;
_pitch = _this select 1;
_bank = _this select 2;
//find the yaw (direction) of the object
//map compass directions go CW, while coordinate (vector) directions go CCW, so we need to flip this
//if we don't flip this, the object will face backwards
_yaw = 360-(getdir _obj);
//----------------------------
//function to rotate a 2d vector around the origin
//----------------------------
_rotate =
{
private ["_v","_d","_x","_y"];
//extract parameters
_v = +(_this select 0); //we don't want to modify the originally passed vector
_d = _this select 1;
//extract old x/y values
_x = _v select 0;
_y = _v select 1;
//if vector is 3d, we don't want to mess up the last element
_v set [0, (cos _d)*_x - (sin _d)*_y];
_v set [1, (sin _d)*_x + (cos _d)*_y];
//return new vector
_v
};
//----------------------------
//find vector dir (pitch)
//----------------------------
//find sign of pitch
_sign = [1,-1] select (_pitch < 0);
//cut off numbers above 180
while {abs _pitch > 180} do {_pitch = _sign*((abs _pitch) - 180)};
//we can't use pitch that is exactly equal to 90, because then the engine doesn't know what 2d compass direction the object is facing
if(abs _pitch == 90) then {_pitch = _sign*(89.9)};
//we can't pitch beyond 90 degrees without changing the facing of our object
//(pitching beyond 90 degrees means that the object's eyes will point in the 2d compass direction that its back used to point)
if(abs _pitch > 90) then
{
//we are rolling upside down; flip our direction (yaw)
_obj setdir (getdir _obj)-180;
_yaw = 360-(getdir _obj);
//use bank to flip upside down
_bank = _bank + 180;
//&& adjust our original pitch
_pitch = (180 - abs _pitch)*_sign;
};
//find appropriate vdir according to our pitch, as if we were facing north
_vdir = [0, cos _pitch, sin _pitch];
//then rotate X & Y around the origin according to object's yaw (direction)
_vdir = [_vdir, _yaw] call _rotate;
//----------------------------
//find vector up (bank)
//----------------------------
//find sign of bank
_sign = [1,-1] select (_bank < 0);
//cut off numbers above 360
while {abs _bank > 360} do {_bank = _sign*((abs _bank) - 360)};
//reflect numbers above 180
if(abs _bank > 180) then {_sign = -1*_sign; _bank = (360-_bank)*_sign};
//find appropriate vup according to our bank, as if we were facing north
_vup = [sin _bank, 0, cos _bank];
//rotate Y & Z elements according to pitch
_vup = [_vup select 0] + ([[_vup select 1, _vup select 2], _pitch] call _rotate);
//rotate X & Y around origin according to yaw
_vup = [_vup, _yaw] call _rotate;
//----------------------------
//apply the vectors
//----------------------------
_obj setVectorDirAndUp [_vdir, _vup];