# How can you change a units "PITCH" After The Units Created?

#### rover2341

##### Is riding a roller coaster...Wee!
What?
I would like function that will change the units pitch.

Why
Will Make Roller Coaster Map alot easier to make and maintain.

Note: I am not looking how to change a doodads pitch in the editor.
This is something that can be run in the game.

Desired Function
-----------------------------
- ChangeUnitAngles(Unit, Yaw, Pitch)
-
- The function takes the a unit and the desired pitch and yaw.
- It then changes the pitch and yaw of the unit.
-----------------------------

This Is what I mean When i say "Pitch" And "Yaw":

Any Ideas?

#### eXirrah

##### New Member
Check if this function helps:

Code:
``````Send Actor Message To Unit
Message: Set Rotation
Forward X: 0
Forward Y: -1.0
Forward Z: 0
Up X: 0
Up Y: 0
Up Z: 1.0
Unit: No Unit``````
I haven't tested it

#### rover2341

##### Is riding a roller coaster...Wee!
I Found something like that but wont let me change teh pitch past 70 degrees.

Ill Mess around with that thanks.

I am getting alot closer.

#### eXirrah

##### New Member
Check out this article : The Mathematics of the 3D Rotation Matrix

It describes the 3D rotation matrix and the forward and up rotation vectors.
The Set Rotation function uses these vectors. I think if you learn what
they do you will find a way to rotate the unit's model.

I haven't read all of it, but these lines caught my eye:

.....The answer is no. RYrot is performing a rotation around the Up vector. It just happens to be the Y axis when everything is at the default position (at the origin, staring down the Z axis). Once you have applied a transformation, all further rotations are relative to the new coordinate system. If you want to look up, apply a rotation around Right, or multiply by RXrot. If you want the screen in front of you to spin about a point in the center, rotate around Out, or multiply the transform by RZrot. These rotations correspond to Roll, Pitch, and Yaw which you have heard about. Roll is rotation about Out, Pitch is rotation about Right, and Yaw is rotation about Up. You can apply these to any transform matrix, and get a new transform matrix. And from that you will be able to extract a rotation matrix which is guaranteed to be a rotation matrix because the set of special orthogonal matrices is closed under multiplication. Okay, that's the last time I'll mention it. ..... [Diana Gruber - The Mathematics of the 3D Rotation Matrix]

Where Up is UP, Out is Forward and Right ...I guess this is what you need to do .... figure out how to change Right vector in SC2. I believe it
can be expressed as a combination of Up and Forward Vectors.

#### rover2341

##### Is riding a roller coaster...Wee!
K am trying to understand But that stuff is beyond me I think.

I am currently using
ForwardX = 0 <Integer>
ForwardY = 0 <Integer>
UpX = 0 <Integer>
UpY = 0 <Integer>

Heres what I got so far and heres a link of what its based off of.
Right now It works up to 70 Degrees. Not sure whats stoping it from a full rotation. It could be the math but that stuff is beyound me, I am using the math from what I found.
What its based off of is here.
Mine Is Posted at the bot of this.

#### Attachments

• 8 KB Views: 112

#### Arkless

##### New Member
I don't know how to do it right (and I am too lazy to think about it) but I think the problem is the following:
lv_forwardX = Cos(lp_yaw);
lv_forwardY = Sin(lp_yaw);
lv_forwardZ = Sin(lp_pitch);

remember:
lv_forwardX*lv_forwardX + lv_forwardY*lv_forwardY + lv_forwardZ*lv_forwardZ = 1
(for directions we use a vector of the length 1)

Or am I thinking about something else here?

#### rover2341

##### Is riding a roller coaster...Wee!
Here Is my current function. Do you see anything wrong with it?

Code:
``````void ChangeOrientation (unit lp_actor, fixed lp_yaw, fixed lp_pitch)
{
TriggerDebugOutput(1, StringToText("Change Orientation Of Unit."), true);
TriggerDebugOutput(1, StringToText("Yaw = " + lp_yaw + " Pitch = " + lp_pitch), true);

//Pre-Set Orientation
fixed lp_roll = 0;

// Variable Declarations
fixed lv_forwardX;
fixed lv_forwardY;
fixed lv_forwardZ;
fixed lv_upX;
fixed lv_upY;
fixed lv_upZ;

// Variable Initialization
lv_forwardX = Cos(lp_yaw);
lv_forwardY = Sin(lp_yaw);
lv_forwardZ = Sin(lp_pitch);
lv_upX = Cos(lp_roll);
lv_upY = Sin(lp_roll);
lv_upZ = Cos(lp_pitch);

// Implementation
libNtve_gf_SendActorMessageToUnit(lp_actor, libNtve_gf_SetRotation(lv_forwardX, lv_forwardY, lv_forwardZ, lv_upX, lv_upY, lv_upZ));
}``````

#### Arkless

##### New Member
Those are all norm vectors and should have a length of exactly 1, if you use it the way you do, the size of the vector changes. I think sc2 changes it to 1 so thats not the problem but I thing you got at it the wrong way.

This should make it look directly up:
lv_forwardX = 0
lv_forwardY = 0
lv_forwardZ = 1

This would make it look down:
lv_forwardX = 0
lv_forwardY = 0
lv_forwardZ = -1

Z = the height
Y = front/back
X = left/right
(x and y might be changed, i never did this with sc2)

Imagine the unit standing at the point 0/0/0 and looking at the coordinate x/y/z. Always at an exact distance of 1 (to make angle changes a lot easier).

So if we want to change the pitch of the unit, then we would only look at the y/z plane (x would make it look to the sides):
x = 0
y = cos(pitch)
z = sin(pitch)

But wait, we forgot something, the vector has to be exactly 1. How do we do that? Easy, just divide by the length we created:
x = 0
y = cos(pitch)/(cos(pitch)*cos(pitch)+sin(pitch)*sin(pitch))
z = sin(pitch)/(cos(pitch)*cos(pitch)+sin(pitch)*sin(pitch))

Well, I wrote more than I actually wanted ^^ I hope that helps (I am not 100% sure this is the right thing, we did this in school about 1 year ago). This should help you figgure out the rest but if you still need help just ask.

#### rover2341

##### Is riding a roller coaster...Wee!
I have a Model thats A box.

This should make it look directly up:
lv_forwardX = 0
lv_forwardY = 0
lv_forwardZ = 1

This makes the model (In this case a box) Look Side Ways (North)

This would make it look down:

lv_forwardX = 0
lv_forwardY = 0
lv_forwardZ = -1

This makes the model (In this case a box) Look The Other Side Ways (South)

This would make it look down:
lv_forwardX = 0
lv_forwardY = 0
lv_forwardZ = 0

This makes the model (In this case a box) Look Straight up.
No Idea how to make it look straight down.

What Else I tried
Code:
``````    lv_forwardX = 0
lv_forwardY = Cos(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch));
lv_forwardZ = Sin(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch));
lv_upX = Cos(lp_roll);
lv_upY = Sin(lp_roll);
lv_upZ = Cos(pitch);``````
I have it on a loop running the function the way you said to try it, going for degree (1 To 360) and then starts over at -360. +1 per .1 sec.
So Basically it will only rotate half way and then flip over to the start again.

Thoughts
Maybe its not the math and more of somthing to do with warcrafts models.
Ill try studying waht you said a bit more instead of just copy and paste into my code.

#### Arkless

##### New Member
I have to say again that I don't know how exactly it works in sc2, I only know how you use vectors and vector products in general.

What Else I tried
Code:
``````    lv_forwardX = 0
lv_forwardY = Cos(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch));
lv_forwardZ = Sin(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch));
lv_upX = Cos(lp_roll);
lv_upY = Sin(lp_roll);
lv_upZ = Cos(pitch);``````
Well, try using some fixed value for the up vector. To make it exact, it would have to be something like the following:
lv_upX = 0;
lv_upY = (-Sin(pitch))/((-Sin(pitch))*(-Sin(pitch))+Cos(pitch)*Cos(pitch));
lv_upZ = Cos(pitch)/((-Sin(pitch))*(-Sin(pitch))+Cos(pitch)*Cos(pitch));
But I'm pretty sure I fucked this up (it's kinda late here in germany and I didn't take my time to think about it).

I have it on a loop running the function the way you said to try it, going for degree (1 To 360) and then starts over at -360. +1 per .1 sec.
So Basically it will only rotate half way and then flip over to the start again.
Thoughts
Maybe its not the math and more of somthing to do with warcrafts models.
Ill try studying waht you said a bit more instead of just copy and paste into my code.
Gimme a few hours I will test it myself, I know how it should work, just not how it works exactly.

#### eXirrah

##### New Member
It is the math ... I'm not sure if I can explain it in english but I'll try.
cos and sin functions are periodic and for different angles they
happen to returns the same value.

for example sin(0) = sin(180) = 0, sin(30) = sin(150) = 1/2... so on

so when the rotation goes over 90 degrees sin(x) returns the same values
as sin(180-x) and when the game calculates the rotation it gets the
smaller angle (180-x < 90) and not the bigger one (x > 90)

example:
the game starts rotating the unit from 0 degrees and sin(0) = 0.
when the loop gets to 180 degrees the game calculates sin(180) = 0 which
is the same as sin(0) and decides that the unit is a 0 degrees and the
model jumps from 180 to 0 degrees rotation in that direction.

Same goes for 30 and 150 degrees... when the game gets to 150 degrees
it thinks that it must rotate the unit at 30 degrees .... so on....

It's similar for cos function.

I had the same problem with sin and cos a while ago and I didn't find a
way to fix that.

I hope someone understood what I meant and explain it better.

#### Arkless

##### New Member
It is the math ... I'm not sure if I can explain it in english but I'll try.
cos and sin functions are periodic and for different angles they
happen to returns the same value.

for example sin(0) = sin(180) = 0, sin(30) = sin(150) = 1/2... so on

so when the rotation goes over 90 degrees sin(x) returns the same values
as sin(180-x) and when the game calculates the rotation it gets the
smaller angle (180-x < 90) and not the bigger one (x > 90)

example:
the game starts rotating the unit from 0 degrees and sin(0) = 0.
when the loop gets to 180 degrees the game calculates sin(180) = 0 which
is the same as sin(0) and decides that the unit is a 0 degrees and the
model jumps from 180 to 0 degrees rotation in that direction.

Same goes for 30 and 150 degrees... when the game gets to 150 degrees
it thinks that it must rotate the unit at 30 degrees .... so on....

It's similar for cos function.

I had the same problem with sin and cos a while ago and I didn't find a
way to fix that.

I hope someone understood what I meant and explain it better.
The combination of Sin and Cos create unique pairs everywhere.

Well, it worked exactly as I thought (except that x and y are changed). I also have to add, that (ass I thought) my Up vector computing is wrong.

If you want to test it use an air unit, ground units seem to start rotating from the beginning when they would go underground (with their model).

#### Attachments

• 7.6 KB Views: 129

#### rover2341

##### Is riding a roller coaster...Wee!
That works for the pitch, But If i try to add something to do the yaw, it doesn't do the full rotation, and it starts to freak out.

The Yaw Is Broke now, How to Fix?

The Pitch Works Great now. Yet I cant seem to add yaw and have it continue to do a full rotation.
Thanks Alot
Arkless
eXirrah

#### eXirrah

##### New Member
Well I'll try to understand what Arkless have done and create an
yaw + pitch function.

I don't get his calculation though...

Cos(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch)) = Cos(pitch)
Sin(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch)) = Sin(pitch)

cos^2(x)+sin^2(x) = 1

I'm not sure how he got the Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch)
part but if it was some sort of formula maybe he can use it to combine
pitch and yaw angles so that the vectors are of length |L|=1.

#### Arkless

##### New Member
Well I'll try to understand what Arkless have done and create an
yaw + pitch function.

I don't get his calculation though...

Cos(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch)) = Cos(pitch)
Sin(pitch)/(Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch)) = Sin(pitch)

cos^2(x)+sin^2(x) = 1

I'm not sure how he got the Cos(pitch)*Cos(pitch)+Sin(pitch)*Sin(pitch)
part but if it was some sort of formula maybe he can use it to combine
pitch and yaw angles so that the vectors are of length |L|=1.
It sure is just Cos/Sin, but you have to divide by the vector length wich comes in handy when you combine multiple vectors. This is NOT the full pich\yaw\roll function so I thought I should add it (will be needed soon anyways).
The length of a vector is Sqrt(n1^2*n2^2*n3^2.....) (yes, I forgot to add the sqrt ).
Well, I will start thinking about adding yaw and roll rotation to it (gotta go eat lunch first thought ).

edit: didn't have time till now, but I will try something soon

#### eXirrah

##### New Member
Well I managed to combine pitch + yaw, but it doesn't work as it should.

I was working on your test map. I'm afraid I'm out of ideas how to fix
this so I'll upload it and leave it to you for now.

The map

#### rover2341

##### Is riding a roller coaster...Wee!
Cool. I am messing with it too, for my purposes the yaw is the other other important one, roll is cool but not needed for my purposes.

#### Arkless

##### New Member
Unfortunately I couldn't get the up-vector to work at all. No matter what I put in, it's always been ignored (maybe I did something wrong, but my guess is that blizzard failed).

I also found out, that using actors in the trigger editor is totally unsopported, the GUI functions aren't even working properly. For example, the "SetBearings" (I tried that to test if only the SetRotation message bugged) GUI function adds ' ' into the brackets ({}) wich even gives you an error message ingame.

As long as I am unable to use the up-vector I am unable to rotate the model in the model x/y plane (the one influenced by the pitch angle), just in the world x/y plane:

out_x = Cos(rotation)*Cos(pitch)
out_y = Sin(rotation)*Cos(pitch)
out_z = Sin(pitch)

How to get this (I have to warn you, it's a mess, feel free to ask if you don't understand something):

Pitch uses a vertical rotation where the angle in the x/y plane doesn't matter. So we got a z/(x/y) plane (or rather an endless amount). At first we do not care wich plane we want to use, we just want the sublength of our vecor in z and (x/y).
Therefore we use Sin/Cos (it's a pic I googled, don't look at the description of the axes, it should be z/(x/y)):

Sin gives us the height (z) and Cos gives us the distance in the (x/y) plane.

We just got our first value, z = Sin(pitch).

We know the length of our vector in the x/y plane as well. It's Cos(pitch). Now we have to find the right angle, we look at our picture again. AH! Sin = y and Cos = x. Easy going, we just got our other values:
x = Cos(rotation)*distance
y = Sin(rotation)*distance

Oh wait, we already have our distance:
x = Cos(rotation)*Cos(pitch)
y = Sin(rotation)*Cos(pitch)

#### rover2341

##### Is riding a roller coaster...Wee!
Got it, So basically there it should be working but it aint.

We can achieve rotation on the x/y and on the z. But together It wont work.

If you have a X/Y Grid

X = Cos(rotation)
Y = Sin(rotation)

If you have a Z/(X/Y) Grid

Z = Sin(pitch)
XY = Cos(pitch)

To Combine the Grids
(As you said and makes sense to me, but I dont know enough math to be sure)

X = Cos(rotation) * What XY ='s so Cos(pitch)
Y = Sin(rotation) * What XY ='s so Cos(pitch)
Z = Cos(pitch)

X = Cos(rotation) * Cos(pitch)
y = Sin(rotation) * Cos(pitch)
z = sin(pitch)

OR

X = Cos(rotation) * Sin(pitch)
y = Sin(rotation) * Sin(pitch)
z = Cos(pitch)

I have no Idea if thats how you are suppose to combine them though but what you said makes sense.

#### rover2341

##### Is riding a roller coaster...Wee!
X = Cos(rotation) * Cos(pitch)
y = Sin(rotation) * Cos(pitch)
z = sin(pitch)

OR

X = Cos(rotation) * Sin(pitch)
y = Sin(rotation) * Sin(pitch)
z = Cos(pitch)
I Belive this might BE IT! The bottom one.

Starcraft 2 Has its Z/(x/y) Backwards from what we thought.

Can you check If this is right?! I think it is!

EDIT

Only Issue Is unit seems to flip instantly(180 Degree Roll) If it gets upside down, But For my uses It may still be Fine...

General chit-chat
Help Users
• No one is chatting at the moment.
• Ghan:
Test!
• tom_mai78101:
I must be in a test server.
• tom_mai78101:
Nice, Twitter tweets embedding now works
• Wizard:
Yup.
• Ghan:
Excellent.
• Ghan:
@tom_mai78101 Hello there.
• Ghan:
Tagging works in the chat too.
• tom_mai78101:
@Ghan Missed it.
• Wizard:
Still fixing things here and there. Added widgets to the portal, will make it match the ones here on the forum index tomorrow.
• Ghan:
The venerable World Editor Tutorials site has been converted to HTTPS at last.
• jonas:
cool
• jonas:
and I can even edit my messages, nice
• seph ir oth:
GENERAL CHIT CHAT, YOU ARE A BOLD ONE
• Ghan:
Hello there
• The Helper:
this new chatbox is great and the forum software update is great too
+1
• The Helper:
upgrade has fixed forum registration spam problem
• tom_mai78101:
Something tells me we might be able to customize the chatbox a bit, considering that there's a gap under every message.
• Wizard:
Going to deploy a fix soon, just had to take some time for myself this weekend.
• Varine:
Unbelievable. Time for yourself? How dare you!
• Wizard:
xD
• tom_mai78101:
Hm, it is now harder to type anything on an Android phone. Pressing Backspace or Enter keys will dismiss the Android keyboard for some reasons.
• tom_mai78101:
Just noticed there's a delay of at least 2 minutes before each post. Guess I can't post Headline News quickly as I used to.
• tom_mai78101:
As far as I can tell, there are definitely things I need to get accustomed to first.
• Varine:
FCC is cracking down recently

### Members online

No members online now.