Viewport Rotation property

Is there a way to set a TCastleRootTransform’s rotation property for X, Y, and Z properly? I’ve tried the Rotation property by:

Rotation := Vector4(1.0, 1.0, 0.0, FRotXAmount);
Rotation := Vector4(0.0, 1.0, 0.0, FRotYAmount);
Rotation := Vector4(0.0, 0.0, 1.0, FRotZAmount);

But this only sets the Z rotation (as is probably to be expected). I can not find a property or function that can set the rotation over more than one (for instance the X and Y Axis).


The TCastleTransform.Rotation specifies a rotation around an arbitrary axis in 3D, with specified angle – Castle Game Engine: CastleTransform: Class TCastleTransform .

Any combination of rotations can be always “combined” into one rotation in 3D around an arbitrary axis. To do this, you can use quaternions, from Castle Game Engine: CastleQuaternions unit. Multiplying 2 quaternions effectively means “combine these 2 rotations”. So like this:

  Q1, Q2, Q3, QFinal: TQuaternion;
  Q1 := QuatFromAxisAngle(Vector3(1.0, 1.0, 0.0), FRotXAmount);
  Q2 := QuatFromAxisAngle(Vector3(0.0, 1.0, 0.0), FRotYAmount);
  Q3 := QuatFromAxisAngle(Vector3(0.0, 0.0, 1.0), FRotZAmount);
  QFinal := Q3 * Q2 * Q1;
  MyTransform.Rotation := QFinal.ToAxisAngle;

I used QuatFromAxisAngle to convert axis+angle → quaternion, I used TQuaternion.ToAxisAngle method to convert quaternion->axis+angle.

The multiplication “Q3 * Q2 * Q1” does the main job, see the docs of “*” operator on Castle Game Engine: CastleQuaternions: Record TQuaternion :

Multiply two quaternions.

Geometric interpretation: If these are unit quaternions representing rotations, multiplying them calculates one rotation that has the same effect as rotating by Q2 and then by Q1.

P.S. Note that your first line is Vector4(1.0, 1.0, 0.0, FRotXAmount) which has X = Y = 1.

It’s a valid 3D axis… but you possibly wanted to write Vector4(1.0, 0.0, 0.0, FRotXAmount) instead (with only X = 1, and Y = Z = 0).