# [General]Calculation of Yaw, Roll, Pitch and Space Rotation for Effects

#### maxodors

Level 7
I wanted to ask for some help with the math on Yaw, Roll, Pitch and Space Rotation. Unfortunately, my math skills are not the best. I am building a map on 1.26 and , therefore, I use MemoryHack for these functions. However, calculations in this memory hack are not correct. Therefore, I thought that maybe someone knowledgeable about 3D rotation math can help me.

JASS:
``````// Effect Rotation API Radians
function GetObjectYawRad takes integer pObject returns real // Z | Yaw | returns Degrees!
local integer pMatrix   = 0
local real r11          = 0.
local real r21          = 0.
local real r31          = 0.
local real yaw          = 0.
local real pitch        = 0.

if pObject > 0 then
set pMatrix = ReadRealMemory( pObject + 0x28 )

if pMatrix > 0 then
set r11   = ReadRealFloat( pMatrix + 0x108 )
set r21   = ReadRealFloat( pMatrix + 0x114 )
set r31   = ReadRealFloat( pMatrix + 0x120 )
set pitch = -Asin( r31 ) // Atan2( -r31, SquareRoot( Pow( r32, 2 ) + Pow( r33, 2 ) ) )
set yaw   = -Atan2( r21, r11 )

if yaw < 0 then
set yaw = 6.28319 + yaw
endif
endif
endif

return yaw
endfunction

function GetObjectPitchRad takes integer pObject returns real // Y | returns Degrees!
local integer pMatrix   = 0
local real r31          = 0.
local real r32          = 0.
local real r33          = 0.
local real pitch        = 0.

if pObject > 0 then
set pMatrix = ReadRealMemory( pObject + 0x28 )

if pMatrix > 0 then
set r31   = ReadRealFloat( pMatrix + 0x120 )
set r32   = ReadRealFloat( pMatrix + 0x124 )
set r33   = ReadRealFloat( pMatrix + 0x128 )
set pitch = -Asin( r31 ) // Atan2( -r31, SquareRoot( Pow( r32, 2 ) + Pow( r33, 2 ) ) )

if r31 < 0. and r33 > 0. then
set pitch = pitch
elseif r31 < 0. and r33 < 0. then
set pitch = 3.14159 - pitch
elseif r31 > 0. and r33 < 0. then
set pitch = 3.14159 - pitch
elseif r31 > 0. and r33 > 0. then
set pitch = 6.28319 + pitch
endif
endif
endif

return pitch
endfunction

function GetObjectRollRad takes integer pObject returns real // X | returns Degrees!
local integer pMatrix   = 0
local real r31          = 0.
local real r32          = 0.
local real r33          = 0.
local real pitch        = 0.
local real roll         = 0.

if pObject > 0 then
set pMatrix = ReadRealMemory( pObject + 0x28 )

if pMatrix > 0 then
set r31     = ReadRealFloat( pMatrix + 0x120 )
set r32     = ReadRealFloat( pMatrix + 0x124 )
set r33     = ReadRealFloat( pMatrix + 0x128 )
set pitch   = -Asin( r31 )
set roll    = Atan2( r32 / Cos( pitch ), r33 / Cos( pitch ) )

if roll < 0. then
set roll = 6.28319 + roll
endif
endif
endif

return roll
endfunction

function GetObjectFacingRad takes integer pObject returns real // Z | Yaw | returns Degrees!
endfunction

function SetObjectSpaceRotationRad takes integer pObject, real yaw, real pitch, real roll returns nothing
local integer pMatrix = 0
local real Sx = Sin( roll )
local real Sy = Sin( pitch )
local real Sz = Sin( -yaw )
local real Cx = Cos( roll )
local real Cy = Cos( pitch )
local real Cz = Cos( -yaw )

if pObject > 0 then
set pMatrix = ReadRealMemory( pObject + 0x28 )

if pMatrix > 0 then
call WriteRealFloat( pMatrix + 0x108, Cy * Cz )
call WriteRealFloat( pMatrix + 0x10C, -Cy * Sz )
call WriteRealFloat( pMatrix + 0x110, Sy )
call WriteRealFloat( pMatrix + 0x114, Cz * Sx * Sy + Cx * Sz )
call WriteRealFloat( pMatrix + 0x118, Cx * Cz - Sx * Sy * Sz )
call WriteRealFloat( pMatrix + 0x11C, -Cy * Sx )
call WriteRealFloat( pMatrix + 0x120, -Cx * Cz * Sy + Sx * Sz )
call WriteRealFloat( pMatrix + 0x124, Cz * Sx + Cx * Sy * Sz )
call WriteRealFloat( pMatrix + 0x128, Cx * Cy )
endif
endif
endfunction

function SetObjectYawRad takes integer pObject, real angle returns nothing // Z Yaw | In Degrees!
local integer pMatrix   = 0
local real r31          = 0.
local real r32          = 0.
local real r33          = 0.
local real pitch        = 0.
local real roll            = 0.

if pObject > 0 then
set pMatrix = ReadRealMemory( pObject + 0x28 )

if pMatrix > 0 then
set r31       = ReadRealFloat( pMatrix + 0x120 )
set r32       = ReadRealFloat( pMatrix + 0x124 )
set r33       = ReadRealFloat( pMatrix + 0x128 )
set pitch     = -Asin( r31 ) //Atan2( -r31, SquareRoot( Pow( r32, 2 ) + Pow( r33, 2 ) ) )
set roll     = Atan2( r32 / Cos( pitch ), r33 / Cos( pitch ) )

call SetObjectSpaceRotationRad( pObject, angle, pitch, roll )
endif
endif
endfunction

function SetObjectPitchRad takes integer pObject, real angle returns nothing // Y | In Degrees!
local integer pMatrix   = 0
local real r11          = 0.
local real r21          = 0.
local real r32          = 0.
local real r33          = 0.
local real yaw          = 0.
local real roll            = 0.

if pObject > 0 then
set pMatrix = ReadRealMemory( pObject + 0x28 )

if pMatrix > 0 then
set r11        = ReadRealFloat( pMatrix + 0x108 )
set r21        = ReadRealFloat( pMatrix + 0x114 )
set r32       = ReadRealFloat( pMatrix + 0x124 )
set r33       = ReadRealFloat( pMatrix + 0x128 )
set yaw     = Atan2( r21 / Cos( angle ), r11 / Cos( angle ) )
set roll    = Atan2( r32 / Cos( angle ), r33 / Cos( angle ) )

call SetObjectSpaceRotationRad( pObject, yaw, angle, roll )
endif
endif
endfunction

function SetObjectRollRad takes integer pObject, real angle returns nothing // X | In Degrees!
local integer pMatrix   = 0
local real r11          = 0.
local real r21          = 0.
local real r31          = 0.
local real yaw          = 0.
local real pitch        = 0.

if pObject > 0 then
set pMatrix = ReadRealMemory( pObject + 0x28 )

if pMatrix > 0 then
set r11        = ReadRealFloat( pMatrix + 0x108 )
set r21        = ReadRealFloat( pMatrix + 0x114 )
set r31       = ReadRealFloat( pMatrix + 0x120 )
set pitch     = -Asin( r31 ) // Atan2( -r31, SquareRoot( Pow( r32, 2 ) + Pow( r33, 2 ) ) )
set yaw     = Atan2( r21 / Cos( pitch ), r11 / Cos( pitch ) )

call SetObjectSpaceRotationRad( pObject, yaw, pitch, angle )
endif
endif
endfunction

function SetObjectOrientationRad takes integer pObject, real yaw, real pitch, real roll returns nothing
if pObject > 0 then
call SetObjectSpaceRotationRad( pObject, yaw, pitch, roll )
endif
endfunction
//===================================================================

// Effect Rotation API Degrees
function SetObjectSpaceRotation takes integer pObject, real yaw, real pitch, real roll returns nothing
endfunction

function GetObjectYaw takes integer pObject returns real // Z | Yaw | returns Degrees!
endfunction

function GetObjectFacing takes integer pObject returns real
endfunction

function GetObjectPitch takes integer pObject returns real
endfunction

function GetObjectRoll takes integer pObject returns real
endfunction

function SetObjectYaw takes integer pObject, real angle returns nothing
endfunction

function SetObjectFacing takes integer pObject, real angle returns nothing
endfunction

function SetObjectPitch takes integer pObject, real angle returns nothing
endfunction

function SetObjectRoll takes integer pObject, real angle returns nothing
endfunction

function SetObjectOrientation takes integer pObject, real yaw, real pitch, real roll returns nothing
endfunction``````

#### PurgeandFire

Level 44
Hmm it might be hard for us to help on the specifics since it really depends on what those memory values represent. Does your code at least change the roll/pitch/yaw (even if incorrectly), or does it do nothing at all?

If you're developing for 1.26, then have you looked into non-memory-hack solutions? e.g. using a dummy model with animations to control the pitch, and then attaching your effect to it. Here's an example of what it looks like:

#### maxodors

Level 7
Hmm it might be hard for us to help on the specifics since it really depends on what those memory values represent. Does your code at least change the roll/pitch/yaw (even if incorrectly), or does it do nothing at all?

If you're developing for 1.26, then have you looked into non-memory-hack solutions? e.g. using a dummy model with animations to control the pitch, and then attaching your effect to it. Here's an example of what it looks like:
Yes, I checked other solutions. I want to use effects instead of dummies because they lead to better performance. I build the map for a community with weak pcs and some spells can be very effect heavy. Moreover, I want to use the Relativistic Missle Effect version.

Yes, the code change roll/pitch/yaw (just the math is not correct). It seems like SetObjectSpaceRotationRad works correctly. As far as I understand, r11, r21, r32 and r33 are values from Euler Matrix.

Here is some math on the topic, which is beyond my comprehension: http://www.close-range.com/docs/Computing_Euler_angles_from_a_rotation_matrix.pdf

I can try to get the required info about memory values if someone can help me with math. Just let me know exactly what is necessary.

Last edited:

#### maxodors

Level 7
Hmm it might be hard for us to help on the specifics since it really depends on what those memory values represent. Does your code at least change the roll/pitch/yaw (even if incorrectly), or does it do nothing at all?

If you're developing for 1.26, then have you looked into non-memory-hack solutions? e.g. using a dummy model with animations to control the pitch, and then attaching your effect to it. Here's an example of what it looks like:
names of variables are equal to their name in Euler Matrix

#### maxodors

Level 7
It seems like I found the problem. The only functions that are not working are "Get"

Replies
5
Views
583
Replies
0
Views
337
Replies
9
Views
318
Replies
10
Views
987