This is by far the
most interesting function I've found out of here. While what it does is a simple matrix transformation, the way it does it is outstanding
Definitively worth to check.
EDIT:
Just did an small script example applying that function. Put a plane flying and well visible by the player, and then execute the script:
// Loop.sqf
// Example:
// [plane1]execVM"loop.sqf"
private["_plane", "_vdir", "_dirini", "_roll", "_climb", "_climb2", "_i", "_rh", "_rv", "_res", "_particle"];
_plane = _this select 0;
setdir3d = compile (preprocessFileLineNumbers "setdir3d.sqf");
_particle = "#particlesource" createVehicle getPos _plane;
_particle setParticleParams [["\Ca\Data\ParticleEffects\FireAndSmokeAnim\SmokeAnim.p3d", 8, 3, 1], "", "Billboard", 100, 5, [0, -4, 0], [0,
0, 0], 2, 25.50 , 20, 0.6, [1, 2.5, 3, 4], [[1, 0.1, 0.1, 0], [1, 0.1, 0.1, 0.6], [1, 0.25, 0.25, 0.5], [1, 0.5, 0.5, 0]], [], 0, 0, "", "",
_plane];
_particle setDropInterval 0.01;
_vdir = vectorDir _plane;
_dirn = (_vdir select 0) atan2 (_vdir select 1);
_roll = 0;
_climb = 0;
_climb2 = 0;
_speed = sqrt((velocity _plane select 0)^2 + (velocity _plane select 1)^2);
for [{_i = 0},{_i < 3},{_i = _i + 1}] do
{
_climb = 0;
_climb2 = 0;
switch (_i) do
{
case 0:
{
TitleText["First loop", "PLAIN DOWN"];};
case 1
:{
TitleText["Second loop", "PLAIN DOWN"];
};
case 2:
{
TitleText["Last loop and barrel", "PLAIN DOWN"];
};
};
while {_climb < 359} do
{
// vector based on climb angle converted into _rh and _rv, later these will be used to mount the final velocity vector
_rh = cos(_climb)*_speed;
_rv = sin(_climb)*_speed;
// We set the resulting velocity vector of the plane based on its horizontal direction and climb angle
_plane setVelocity [sin(_dirn)*_rh,cos(_dirn)*_rh,sin(_climb2)*_rv];
// Now we apply the horizontal direction, climb angle and roll to plane's 3D model.
_res = [_plane, [_dirn, _climb, _roll]] call setdir3d;
// Lets keep pulling the stick back to keep doing vertical loops
_climb = _climb + 0.5;
// If _i == 2, lets roll a bit too
if (_i == 2) then {_roll = _roll + 2};
_climb2 = _climb;
if (_climb > 180) then {_climb2 = 360 - _climb};
Sleep 0.002;
};
};
Sleep 5;
deleteVehicle _particle;