Jump to content
  • Advertisement


This topic is now archived and is closed to further replies.


Turn in global space

This topic is 5378 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

OK, thanks to the help from you two I've managed to simplify it a lot.

I've scrapped the local quaternion and 6 floats, and I'm now using only the matrix. I don't really need to know the global Euler angles, and I can easily get the global position of any entity from its matrix (M41, M42, M43).

I think I've got the following working:


I also have Turn() working, but only with global angles. Turning in local space is trickier. It should work the same as Translate(), but that uses something I can't do with angles.

Also I've left scale alone for now to keep things simple I've also not done the code to update the children when a parent is altered but that shouldn't be too hard.

Here's the source for the local co-ordinates Translate() method (x/y/z describe the translation vector):

// Turn global position into local space

this.Parent.PointToLocal(this.Transform.M41, this.Transform.M42, this.Transform.M43);

// Add translation to it

x = this.Parent.PointX - x;
y = this.Parent.PointY - y;
z = this.Parent.PointZ - z;

// Set new position

Matrix M = this.Parent.Transform;
M = Matrix.Translation(x, y, z) * M;
this.Position(M.M41, M.M42, M.M43, true);

PointToLocal() simply runs a point through the matrix like this:

public void PointToLocal(float x, float y, float z)
Matrix M = this.Transform;
PointX = (M.M11 * x) + (M.M21 * y) + (M.M31 * z) + M.M41;
PointY = (M.M12 * x) + (M.M22 * y) + (M.M32 * z) + M.M42;
PointZ = (M.M13 * x) + (M.M23 * y) + (M.M33 * z) + M.M43;

So - can anyone tell me if it's possible to write a QuaternionToLocal() method to run a rotation through the matrix in the same way as a point? That would enable me to finish my Turn() method.

Thanks for all the help so far!

EDIT: Tidied code.

EDIT AGAIN: I got Turn() working in local space by simply reversing the order of the matrix multiplication! However, my global Turn() doesn't seem to work quite right still.

[edited by - Rottbott on May 28, 2004 5:28:48 PM]

Share this post

Link to post
Share on other sites
Let's see:

M is your entity's matrix now.
GlobalRot is your global rotation matrix
So after rotating you would get the following matrix:

GlobalRot * M

This should be equal to another expression, in which you apply an unknown local rotation matrix:



GlobalRot * M == M * LocalRot is true, from this

LocalRot = M^(-1) * GlobalRot * M

This will be the local rotation matrix, I think.

Try it, hope it's a good idea.

[edited by - szinkopa on May 28, 2004 5:48:19 PM]

Share this post

Link to post
Share on other sites

Lets say,
M = TR, where R is the linear component (that means rotations/
scaling and sheering. T is translational component. When you
look at matrix elements of M you see that:

M = M11 M12 M13 Tx
M21 M22 M23 Ty
M31 M32 M33 Tz
0 0 0 1

If you need to do an absolute transform at any level, just
separate the two components of the matrix and rewrite it.
So, if you want it to translate to someplace else, just
change Tx,Ty,Tz...if you want to rotate in a different
way, just replace the top 3x3 with a new rotation matrix.
If you have to do a "turn" or "move" instead, then just
left multiply the change in transformation to existing matrix.

Now, inverse matrices will allow you to untransfrom things from global
down to local without worrying about what an angle was. Just
multiply the inverse matrices of the higher levels on the left
and they will bring it back down to a lower level.

Well, one more things, you probably want to store your coordinates in their untransformed states. This means
that Local takes them to the locally transformed coordinate
system and global * local takes them to the global coordinate
system. This removes the need to always have to transform
things back from global before doing local transformations.

Also, only transform coordinates on demand. Meaning, store
the matrices, modify them as much as you want, and then compute
for a concatenated transformation of points or a set of points
when you need it. This will take more advantage of the matrices than if you transformed each time your matrix changed.

As for transforming quaternion through a matrix, its done by converting the quaternion to a matrix and then multiply
it through. There's a formula for that somewhere. It would
help in writing a turn method that uses a quaternion. But, be
sure to multiply it to the left.

hope this helps,


EDIT: typo

[edited by - SporadicFire on May 28, 2004 9:42:06 PM]

Share this post

Link to post
Share on other sites
That makes sense. How do I do M^(-1)? Is it just M.Invert()?

I've taken your advice and included the local transformation components again.

However I'm still having trouble with Turn(). I want to turn on the global axes... but how do I work out the new *local* quaternion which will result in a given global rotation? To do that with translation is easy - I use my PointToLocal() method - but I can't seem to get a working RotationToLocal() method, even with szinkopa's equation above.

EDIT: A global Turn() now semi-works. However, if I turn an entity slowly to the right, it works up until about 270', and then goes crazy. Weird.

[edited by - Rottbott on May 29, 2004 1:26:54 PM]

Share this post

Link to post
Share on other sites
yes, M^(-1) is its invert.

Ah, i think i see what you mean now...
but correct me if i am wrong

T = G * L is the total transformation G is global, L is local.
Now, to achieve a rotation in the total transform:

RT = R*G*L

but, you want this represented locally,

RT = G*S*L

R*G*L = G*S*L
inverse(G)*R*G*L*inverse(L) = S
S = inverse(G)*R*G

and S is the transformation that you have to apply at local level
to get RT = R*G*L to be the new total transformation.

Ofcourse, this will work for any general transform, not just


Share this post

Link to post
Share on other sites

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!