/************************************************************ 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];