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

Discussion in 'Starcraft 2 (SC2) Editor Help' started by rover2341, Sep 22, 2010.

1. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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?

2. ### eXirrahNew Member

Ratings:
+51 / 0 / -0
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

• Like x 1
3. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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.

4. ### eXirrahNew Member

Ratings:
+51 / 0 / -0
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.

5. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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.

File size:
8 KB
Views:
95
6. ### ArklessNew Member

Ratings:
+31 / 0 / -0
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?

7. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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));
}```

8. ### ArklessNew Member

Ratings:
+31 / 0 / -0
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.

9. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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.

10. ### ArklessNew Member

Ratings:
+31 / 0 / -0
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.

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).

Gimme a few hours I will test it myself, I know how it should work, just not how it works exactly.

11. ### eXirrahNew Member

Ratings:
+51 / 0 / -0
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.

12. ### ArklessNew Member

Ratings:
+31 / 0 / -0
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).

#### Attached Files:

• ###### poke.rar
File size:
7.6 KB
Views:
112
• Like x 1
13. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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

14. ### eXirrahNew Member

Ratings:
+51 / 0 / -0
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.

15. ### ArklessNew Member

Ratings:
+31 / 0 / -0
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

16. ### eXirrahNew Member

Ratings:
+51 / 0 / -0
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

17. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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.

18. ### ArklessNew Member

Ratings:
+31 / 0 / -0
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)

19. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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.

20. ### rover2341Is riding a roller coaster...Wee!

Ratings:
+114 / 0 / -0
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...