- Joined
- Mar 29, 2012

- Messages
- 530

I'm back wrestling with special effect, now with the orientation.

I used this library:

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
```

I wanted to make the effect turn with specific TURN_RATE.

So far... this:

JASS:

```
set angle = GetAngleXY(vec.vx[1], vec.vy[1])
set angleZ = GetAnglePointsZ(GetDistance2D(vec.vx[1], vec.vy[1]), vec.vz[1])
// vec.vx[1] -> [target x] - [current position x]
// vec.vy[1] -> [target y] - [current position y]
set .roll = AbsRad(.roll + TURN_RATE * Cos(angle) * Cos(angleZ))
set .pitch = AbsRad(.pitch + TURN_RATE * Sin(angle) * Cos(angleZ))
//AbsRad is used to keep the value between 0-2π (full circle angle)
call OrientEffectAngle(.missile, .roll, .pitch)
```