How to rotate an object around world space, not local/object space

Hi all,
I’m trying to figure out how to rotate an object around world space, not local/object space. Meaning no matter how the object is oriented it will always rotate in world space. As I understand it the objects we currently have in the engine are being rotated according to their own axis – but how do I make it always rotate in world space?
Please view this recording as an example.
https://www.dropbox.com/s/xvcyqslvw4nx7ov/WorldSpaceRotation.mov?dl=0

The cube rotation results in that video are exactly the same. However, if you were to translate the object, then the result would be different in object vs global. In object space, the cube would translate along the object axes, and in world space, along the world axes.

See the first half of this video demonstrating in Blender:

(“Global” is your “world” and “local” is your “object” here)

Do you mean “rotate around the world origin” rather than “rotate around world space”?

As described in the chapter on matrices and coordinate spaces, you reverse the order of matrix concatenation.

In the book, the model matrix is composed of translate * rotate, which causes the model to rotate around its own axis. But if you change that to rotate * translate, then the model will rotate around the world’s origin.

1 Like

Hi, I am at 09-scene-graph in met-materials-editions-2.0 and the Node has the following code:

var modelMatrix: float4x4 {
    let translateMatrix = float4x4(translation: position)
    let rotateMatrix = float4x4(quaternion)
    let scaleMatrix = float4x4(scaling: scale)
    return translateMatrix * rotateMatrix * scaleMatrix
  }

Do you mean I should change translateMatrix * rotateMatrix to rotateMatrix * translateMatrix ?

The book relies on that code as is.

However, if you wanted a specific object to have a different type of rotation, you could create a new subclass of Model and override the modelMatrix definition.

Thanks for the reply and tip – I tried it but got the same result as if nothing changed.

The movement of the objects I want is as if they were rolling on the floor like a ball or a tire, forwards and to the sides – but as you can see in the attached example they are spinning around like a disco ball :slight_smile: In this case I just want the rotation working not the position.
Lighting.zip (752.7 KB)

This is a better answer and I’ve deleted the others. I shouldn’t try answering before coffee :slight_smile:

With

train.rotation = [timer*30, timer*30, 0]

you’re changing the rotation of two axes. I think you want to rotate about one axis?

Change your rotation to:

train.rotation.x = timer*30
train.rotation.y = .pi / 5

Rotation takes place around the x axis, on a tilted y axis. With the way we create the rotation matrix, you are applying an angle on the x axis, then applying an angle to the y axis in sequence, not both at the same time. You can apply the rotation in a different order if you want to. That’s the way Euler angles work.

This is the same in Blender:

animateEuler.mov.zip (3.8 MB)

I added 30 to the x and y rotation every 20 frames.

Alternatively, you can use a quaternion.

animateQuaternion.mov.zip (3.1 MB)

I rotated the spaceship manually on its local axis every 20 frames

To try out a quaternion:

Add a new property to Model:

var quaternion = simd_quatf()

In your model matrix, create the rotate matrix:

let rotateMatrix = float4x4(quaternion)

In Renderer’s draw(in:) where you do the rotation, do this instead:

train.quaternion = simd_normalize(simd_quatf(angle: timer * 30, axis: [1, 1, 0]))

That axis is the same as you were trying with your Euler rotation.

animate.mov.zip (2.7 MB)

I’m not quite sure why it doesn’t rotate at constant speed, but rotation math is hard.

You might find this useful: Rotation in Three Dimensions - 3D Math Primer for Graphics and Game Development

Btw, I was poking around the web to see how other people have solved your flying situation, and I found this from somebody who’s better at mathing than I am:

Result here:
http://philcrowther.com/WebGL/Space/Earth/Globe.html

Btw, I was poking around the web to see how other people have solved your flying situation, and I found this from somebody who’s better at mathing than I am:

Result here:
http://philcrowther.com/WebGL/Space/Earth/Globe.html

1 Like

Hi @caroline

Thanks for all the tips and help – I know this is a very difficult topic :wink: and even more difficult to explain.

I’ve been testing a lot of different solutions and came across one on a SceneKit topic on StackOverflow and this is actually the result I want.

Lighting.zip (989.6 KB)
Please see attached project.

So I’m just using a SCNNode as a placeholder to do all the math and the magic is somewhere in there. Now if I could only find a way to reverse-engineer that SCNNode class :wink:

If you look at it for a while you will see that the “ball” is rotating as if it was moving across a surface.

Thank you for being persistent and providing an example of what you are looking for!

I don’t have a background in math, or great intuition in it, so rotations always take me ages to work out. You’d be surprised to learn how much of my life I have spent working out cameras :grimacing:.

Would this be the sort of thing you’re looking for? I’ve included moving the ball to prove translation works as well as rotation.

LightingBall.zip (946.7 KB)

Where you used SceneKit, and quaternionAngleVelocity, I’ve replaced it with a rotation axis and forward vector:

rotationAxis = [axisX, axisY, axisZ]
ball.quaternion *= simd_normalize(simd_quatf(angle: 0.05, axis: rotationAxis))
let upVector = float3(0, 1, 0)
let forwardVector = cross(normalize(rotationAxis), upVector)
ball.position += forwardVector * 0.01
ball.position.y = 0.5

The timer resets ball.quaternion and also sets the rotation axis (a rename of your quaternionAngleVelocity).

Hi @caroline

Thank you for the example and demonstration :slight_smile: 3D is hard – which is why we do it right :wink:
I think we almost got it, but the part where the ball.quaternion is reset cannot be done unfortunately as the ball would be controlled by user input WASD-keys, so the motion has to be applied as a player holds down a key. Apologies for not making this clear.
For example, if the ball is rolling forwards and I press the D-key, so while I’m holding it down the ball would start moving/rotating more and more in that direction :slight_smile:

I made a video to explain the kind of rotation I’m looking for :slight_smile: Dropbox - BallRolling.mov - Simplify your life

I know this can be done with physics but in my case I cannot use physics as the ball might be floating around in air/space :slight_smile:

Unfortunately I won’t be able to give this the concentration it needs for a while (work :unamused: ), but if you get it sorted in the meantime, please do share!

1 Like