• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Operating special effect orientation

Status
Not open for further replies.
Level 13
Joined
Mar 29, 2012
Messages
530
Hello guys

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
And have these three elements in variables: roll, pitch, and yaw.

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)
But the effect just spinning around smoothly.
 
Level 39
Joined
Feb 27, 2007
Messages
5,010
Blizzard fixed their angle definitions in a patch so you can use the pitch/yaw/roll natives directly. No need for this library, which will instead rotate in incorrect ways since the math is different.

Why are you multiplying two wines/cosines together? Your angle should just go up by TURN_RATE*timerperiod every interval. Those angles shouldn’t be involved at all.
 
Status
Not open for further replies.
Top