- Joined
- Dec 13, 2009

- Messages
- 335

Working with yaw, pitch, and roll to adjust the orientation of a special effect to a desired direction is tedious, especially since Blizzard defined yaw and roll incorrectly, swapped their definitions, and the order in which they are applied.

This small function takes care of the math required to find the correct yaw, pitch, and roll angles and allows you to orient a special effect directly towards an input vector.

This small function takes care of the math required to find the correct yaw, pitch, and roll angles and allows you to orient a special effect directly towards an input vector.

JASS:

```
library OrientEffect
//============================================================================================
//OrientEffect by Cyclotrutan
//============================================================================================
//This function sets the orientation of a special effect such that it points towards the input
//direction. The special effect model must be pointing towards x-direction by default, such as
//most missile models. It will not work on vertically oriented effects such as StarfallCaster.
//Using the standard definition of yaw, pitch, and roll (which is different from Blizzard's
//definition), the special effect's intrinsic rotation will correspond to roll = 0. As a
//result, there is a discontinuity when the special effect is oriented towards the z-axis.
//There are three possible input functions:
//OrientEffectVector(whichEffect,x,y,z) orients the special effect in the direction of a
//vector with arbitrary length.
//OrientEffectCoordinates(whichEffect,x,y,z) subtracts the special effect's own position and
//orients the special effect in the direction of the input coordinates on the map.
//OrientEffectAngle(whichEffect,phi,theta) orients the special effect towards the azimuthal
//angle phi ranging from 0 to 2pi and the polar angle theta ranging from -pi/2 to pi/2.
//============================================================================================
private function OrientEffect takes effect whichEffect, real x, real y, real z returns nothing
local real norm
local real yaw //normal people yaw, blizzard roll
local real pitch
local real roll //normal people roll, blizzard yaw
local real N
local real cp
set norm = 1.00001*SquareRoot(x*x + y*y + z*z)
if norm == 0 then
return
endif
set x = x/norm
set y = y/norm
set z = z/norm
set N = SquareRoot(x*x + y*y)
if N == 0 then
if z > 0 then
call BlzSetSpecialEffectOrientation( whichEffect , 0 , -bj_PI/2 , 0 )
else
call BlzSetSpecialEffectOrientation( whichEffect , 0 , bj_PI/2 , 0 )
endif
return
endif
if y >= 0 then
set pitch = -Asin(x*z/N)
set cp = Cos(pitch)
set roll = Asin(y*z/(N*cp))
set yaw = Acos(x/cp)
else
set pitch = Asin(x*z/N) + bj_PI
set cp = Cos(pitch)
set roll = -Asin(y*z/(N*cp)) + bj_PI
set yaw = Acos(x/cp)
endif
call BlzSetSpecialEffectOrientation( whichEffect , roll , pitch , yaw )
endfunction
function OrientEffectVector takes effect whichEffect, real x, real y, real z returns nothing
call OrientEffect(whichEffect , x , y , z)
endfunction
function OrientEffectCoordinates takes effect whichEffect, real x, real y, real z returns nothing
call OrientEffect(whichEffect , x - BlzGetLocalSpecialEffectX(whichEffect) , y - BlzGetLocalSpecialEffectY(whichEffect) , z - BlzGetLocalSpecialEffectZ(whichEffect))
endfunction
function OrientEffectAngle takes effect whichEffect, real phi, real theta returns nothing
call OrientEffect(whichEffect , Cos(phi)*Cos(theta) , Sin(phi)*Cos(theta) , Sin(theta))
endfunction
endlibrary
```

Last edited: