Game Development Community

Rotating in the world coords, not the object coords

by Drew Parker · in Torque Game Engine · 06/28/2004 (10:45 pm) · 14 replies

Ok, here is where my matrix newbness can be displayed in all its glory (or misery).

I was on the GG IRC tonight (which, by the way, is a totally cool place to hang out and get good tips from people in the community, and have good conversations), and I got a little help on my problem, but I'm still stumped. Turns out I need to buy a book. :) Until I get it though, I'm tossing out this SOS line in hopes someone can walk me through it briefly.

I want to rotate an object by the world's z-axis. Basically, lets says I have a pillar and it falls over. I want to rotate it to point in different directions, and not have it twist about in place around it's own z-axis (which is happenning to me now).

I ripped the code from worldEditor.cc to get my rotate function to work, like this:
void myClass::rotateItem (const EulerF & rot)
{
	MatrixF mat = ((SceneObject*)this)->getTransform();
	
	MatrixF transform(EulerF(0,0,0));
	transform.mul(MatrixF(rot));

	mat.mul(transform);


	((SceneObject*)this)->setTransform(mat);
}

The EulerF rot that gets passed in is basically (0, 0, someZRotation). It works great. But I want it to rotate by the worlds z-axis. I got a lot of good advice about using mObjToWorld, and
multiplying by the world matrix, but I have no clue as to how to do that. I'm sure this is super simple like everyone keeps telling me, but unfortunately I just have no idea how to do it yet.

I've already busted out my old CS OpenGL book and tried to cram my brain with matrix math, but for some reason it hasn't re-clicked yet.

If you have any suggestions, I would really appreciate it a lot!

#1
06/29/2004 (1:00 am)
To move from object space to world space you do something similar to

Point3F cameraPosWorld;
MatrixF objToWorld = playerObj->getRenderTransform();
objToWorld.mulP((0,-3,3), &cameraPosWorld);

Which calculates the world space coordinates of a point -3 units behind, 3 units up from the current player position (used for placing a 3rd person camera in this example).

Hope that helps to get you started
#2
06/29/2004 (6:22 am)
Hi Thomas,

Thanks a lot for the reply. That actually does help, and will certainly be useful when I get to moving an object using different coordinate systems. I actually remember seeing something similiar to that one the forums when I was searching. But I'm not quite sure how to use it for rotation.

For instance, in my above example, where would this kind of code fit? After the final rotation is done,
mat.mul(transform);
do I then grab the renderTransform and do a mulP? By what point would I multiply? Or would I multiply the rotation matrix by the world matrix after
transform.mul(MatrixF(rot));

And how do I do that? transform.mul(objToWorld)?

Sorry I'm so slow at this still! I've tried doing a bunch of different things, but I'm finding just plugging in random matrix multiplication doesn't quite do the trick when I don't understand what I'm doing. :) I think I'll definitely pick up that 3d games math someone recommended so I don't go through this again, and so I have a good practical reference guide. My old college books are turning out to be too theory heavy with not enough practical stuff.

Thanks again for the help.
#3
06/29/2004 (6:45 am)
Am i wrong is saying that in object space it uses right handed co-ordinates with the positive Z axis pointing towards you?

www.gameshots.co.uk/objectspace.jpg
And that in world space is still right handed but rotates Z axis towards you so positive Z is up, positive Y is away from you, and ppositive X is to the right.

www.gameshots.co.uk/worldspace.jpg
#4
06/29/2004 (9:16 am)
Okay, after reading up in my textbooks on matrix math (whew) and re-reading some forums, I may have a slightly better clue. I want to take an object and have it always rotate about the axis (0,0,1) meaning the world z-axis, not it's own z. Also, of course I want the axis to go right through the object, and for it *not* to rotate about the world center, which would cause my object to go into orbit.

Does this sound right?

1. Get your rotation, turn that into a matrix.
2. Get a matrix for transforming from world to object (since I want to rotate about the world's z, but then apply that to the object).
3. Multiply my rotation matrix by the WorldToObject matrix
4. Multiply the result to my object transform.

I came up with this from this thread, which talks about moving camera coordinates from object space to world space, and some textbook stuff.

Well here goes.
#5
06/29/2004 (12:58 pm)
Hi Westy,

Thanks for the reply. Sorry, I wish I knew. I figured that object and world space would have the same axis directions, with z being up on both.
#6
06/30/2004 (9:28 am)
Ok, so my above attempt didn't work. Can anyone help me with this? I'll put you in the credits of my first game! :) I ordered a good practical 3d math/graphics book per some suggestions on the IRC, but until it comes I'm basically stumped.

If someone could help me just a little bit with getting the rotation setup correctly initially, I'm sure I could learn a lot from there. I've learned a lot about Torque over the past couple of months but I haven't had to do anything with more complex rotations until now. The camera position update code-snipit was really insightful, but I can't get that to work for rotations.

Thanks!
#7
06/30/2004 (9:34 am)
Okay...lets see if I can help...

I need some clarification first though:
You have a pillar and you want it to fall over? And currently it is rotating about the center of the pillar, not about the base? Or am I picturing this *completely* wrong?
#8
06/30/2004 (9:43 am)
To make the pillar fall over, you want to rotate around the X- or Y-axis (or combination of both). If you want it spinning as it falls you could throw in a little Z rotation as well.
#9
06/30/2004 (9:44 am)
Matthew, thanks for the reply! You are in the credits. :)

Basically, I have objects that can bounce around via rigidShape and ODE. And now matter how they fall, I always want them to rotate about their center point on the world z-axis when I call my rotation function. So no matter what rotation the object is in, it will always spin like a spinning top, basically. So if a box falls over, I don't want it to turn like it's rolling down a hill, I want it to turn like I'm giving it a new heading.

So for instance, with the pillar. When the pillar is upright, it should spin like a top, on the world's z-axis. But when it falls over, and I call my rotation function again, it's supposed to spin like a clock hand (since it should be turning around a typical up vector), causing the fallen pillar to know point in a different direction. So when it first fell, if the top of it was pointing at a bush, now perhaps the top of it would be pointing towards the rock next to the bush. But instead it rolls around it's own z-axis always pointing at the bush, like a bread roller type of motion, which is not what I want.

Does that make sense? I can upload a picture if that will make things clearer, sorry my explanation isn't so good.
#10
06/30/2004 (9:46 am)
Hi Desmond,

Thanks for the input. Actually, I'm not trying to make the pillar fall over (that happens on it's own from ODE :). That was just an example given to illustrate how my object has changed positions, but is now not rotating about an absolute up vector like I want it to.

Sorry I know this is confusing... :)
#11
06/30/2004 (10:12 am)
Hello,

What it sounds like to me is that you want to rotate the pillar based on the bottom of the pillar and not the center. Is this correct? Like a pole falling over.

You want to do this in the model space (well sort of) and not worldspace. Give me a second and I will explain. If you try to make it fall in world space then depending on were it is and the height its at you may end up with different results.

What I would think you would want to do is say with its model space but translate the object up so that the base is now at the center of the models axis. After that rotate it around the y axis and it will fall around the base of the model. Like a pillar falling. After that translate the newly rotated model back to the way it was (moving down the z axis) and then translate and rotate the object based on the world matrix.

When you translate against the would matrix it will have both the possition and the rotation of the model and it will put it in the proper location. When you think of rotating a model in model space, its not the model that rotates but the axis. So the y axis will always be forward to the model and x will be to the right no matter what the world rotation is.

Ben
#12
06/30/2004 (10:38 am)
Hey Ben,

Thanks for the good info. This whole model space and world space thing I thought I had somewhat of a handle on, but apparently not as much as I need to. If I ever need to animate through rotation a pillar falling, this is definitely a good example.

What I'm actually trying to do however, is not make a pillar fall. That was probably a bad example to give on my part. What I want to do, is always rotate an object, around it's center, based on an arbitrary axis, which is the up/down axis (z-axis). Eventually I will extend this to use different axises, to allow me to do more nity "context sensitive" rotations. Probably my example is not good for what I am trying to explain what I want to do. Let me try a different example.

Let's say I'm trying to build a "real-life" simulator. I want to be able to manipulate individual objects with fine control, to lets say, stack them on eachother or position them uniquely. I'm using a point & click interface to do this. To position objects how you want them, you click on them and drag. But sometimes they don't face the right direction. So you need to be able to move them and rotate them, just like in the mission editor.

So, to further this example, let's say I want to place a long plank across a chasm I want to cross, so the plank will act like a bridge. I find the plank in a shed, and the plank is initially leaning up against the wall, so it's up/down z-axis is pointing along the world's z-axis, or the up vector. I click on it and drag it outside, then I drop it next to the chasm. Since I'm no longer dragging it, the physics engine physcis kick in, and the plank falls over by itself and bounces a bit. The plank is now lying on the floor, parallel to the chasm. But, I want to position it to act like a bridge so I can cross the chasm. So I need to rotate it 90 degrees about a vector pointing upwards (world z) so it's perpendicular to the chasm. So, using my right mouse button (rotate button), I click and drag on it, with the intention being, to turn it 90 degrees in the floor plane (x-y) plane, or in other words, have it rotate about the absolute up vector (0,0,1). It should rotate from it's center point, so the object doesn't change locations, just rotates.

But instead, guess what happens? The plank just rolls on the ground, and it's still parallel to the chasm, so I can't use it as a plank since it's not oriented correctly to bridge the chasm gap! Then I think, "Ah, you are spinning on your *own* z-axis! Must be how your model was setup. So your z-axis is now not parallel to the world's z-axis. But I want your to *always* rotate accoding to an absolute up vector."

So that's where I'm stuck at. I want to click and drag on that plank, and have it rotate about a vector that originates from it's center point, and goes straight up along an absolute up vector, so I can position it correctly to cross the chasm. Instead, it just rolls in place, with it's heading still being parralel to the chasm gap, so I can't use it as a bridge.


I know that took a lot of words, I was trying to make up for my bad description earlier. Does that make sense? Is everyone clear now as to what I want to do?
#13
07/08/2004 (9:05 am)
Ok, I got this working. It took a bit to figure it out, I'll post up some code later on once I organize it so it will benefit others (hopefully).

This is a quick summary of how I got my rotations to be relative to world space instead of object space:

1. Get the WorldToObj transform first (since you want to rotate relative to the world) with myObj.getWorldTransform()
2. Move the object to the center of the world (set the transform position 0,0,0), so that the object will rotate correctly.
3. Do the Euler rotation (this part was already working) by multiplying the WorldToObj transform by the Euler transform.
4. Now the tricky part. You have to convert back to ObjToWorld, because that's what setTransform() uses. To do this, take the inverse of the WorldToObj matrix. I took the affine inverse (since an object space transform is basically the opposite of a world transform).
5. For some reason, the position can get messed up (though I don't think it should, could be I'm doing something wrong). So restore the original position after calling the inverse.
6. Call myObj.setTransform() with the new transform.

I'll post the code later. This was quite the hair puller. Someone on IRC recommended a good math book, which helped straighten out the concepts quickly (without drudging through my old math textbooks), then I had to step trace through the code and watch how the matrices were changing bit by bit to make sure it was working right.

Thanks to everybody who helped me out along the way!
#14
02/16/2009 (8:19 pm)
@Drew

I know this is a long lost thread but hopefully I can get some help. I am looking to rotate objects along the world axis, but I have run into the same problems that you have. All of this that you are talking about in your last post is written in the source code, correct? Could I get some help in the matter?

What I am looking at doing is, imagine looking at a rubik's cube and you need to rotate the cube in all directions to examine it so you can solve it. Hopefully I am reading this right and you have the solution for me, and hopefully you still remember what you did after four and a half years. Any help would be great.