# Rotation

Mario Kart Wii, as with all other 3D games, needs a rotation representation to express model orientations, rotate points and transform between coordinate frames among other things. The various coordinate frame conventions and rotation representations are discussed here.

## Standard coordinate system

When racing, the various models'/poses' coordinate system is defined as follows

- Z axis: Backwards, e.g. opposite to the direction of acceleration
- Y axis: Upwards, opposite to the direction of gravity
- X axis: Rightwards, such that X, Y, Z forms a right-handed orthonormal coordinate system.

This is in contrast to many vehicle and aircraft conventions where X is forwards and Z is up, but is closer to the common camera coordinate system convention (where Z is depth).

## Rotation representions

There are a couple of useful ways to represent a rotation/orientation, each with its own advantages and disadvantages.

- Euler angles
^{[1]}: An intuitive and most concise representation as it only uses 3 values. Useful for expressing rotations in files, but not for arithmetic and operations on rotations. - Unit quaternion
^{[2]}: A brief representation (4 values) which is also useful for some arithmetic operations, such as rotation composition. - Rotation matrix
^{[3]}: A 3x3 matrix (9 values) representation. Although large in size, most rotation operations are expressed elegantly and efficiently in terms of rotation matrices.

## Euler angle convention

In Mario Kart Wii file formats, all rotations are defined as a vector of 3 floats using Euler angles. 3D rotation vectors are found in the KMP sections AREA, CAME, CNPT, GOBJ, JGPT, KTPT, MSPT and in the MDL0 section bones.

Euler angles (more precisely Tait-Bryan angles) have multiple conventions based on the order of rotations and the coordinate frame they are expressed. Mario Kart Wii uses the x-y-z extrinsic rotation convention or equivalently the z-y'-x" intrinsic rotation convention (also known as yaw-pitch-roll). This is by far the most commonly used convention in general.

To find the orientation of a model expressed in Euler angles (x,y,z), starting with the child and parent coordinate frames coinciding:

- rotate the child frame around the parent frame's X axis by x
- rotate the child frame around the parent frame's Y axis by y
- rotate the child frame around the parent frame's Z axis by z

All rotations are performed using the right-hand rule

## General transformations

Transformation of objects/coordinates in video games including Mario Kart Wii, are composed of 3 basic transformations:

- Translation
- Rotation
- Scaling

In file formats, these are expressed as 9 floats (3 for translation, 3 for rotation and 3 for scaling). Internally, they are more useful as a 3x4 transformation matrix. The order in which the transformations take place is:

- Scaling
- Translation
- Rotation

### Coding Example

In this coding example we have a position vector **pos**, which should be scaled by **scale**, rotated by **rotate** and moved by **translate**:

// scale the position vector by multiplying pos.x *= scale.x pos.y *= scale.y pos.z *= scale.z // rotate the position vector Mat34 rotationMatrix = createRotationMatrixFromEulerAngles(rotate); pos = rotationMatrix * pos; // operator* implementing matrix multiplication // translate the position vector by adding pos.x += translate.x pos.y += translate.y pos.z += translate.z // Or, using a trasformation matrix T pos = T*pos; // operator* implementing matrix multiplication

## Degrees and Radians

In Mario Kart Wii, all rotation values are stored as single float (32 bit) in **degrees** (360° for a full circle). Programming languages normally use **radians** (2π for a full circle).

Before calling the library functions sin(), cos() or tan(), the degree values must be transformed into radians. The radian results of the library functions asin(), acos(), atan() and atan2() must be converted into degrees:

radians = degrees * (π/180.0) degrees = radians * (180.0/π)

Most desk calculators allow to switch between degree and radian calculations. You can test the active mode by entering 'acos(0)'. It either returns *1.5708* (π/2, radian mode) or 90° (degree mode).

## Links

- Wiiki

- Conversions

- Conversion between Euler angles and quaternions
- Conversion between Euler angles and rotation matrix
- Conversion between quaternion and rotation matrix

- References