#region File Description
//-----------------------------------------------------------------------------
// A class containing all the basic transformations a renderable object can have.
// This include: Translation, Rotation, and Scale.
//
// Author: Ronen Ness.
// Since: 2017.
//-----------------------------------------------------------------------------
#endregion
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace MonoGameSceneGraph
{
///
/// Different way to build matrix from transformations.
///
public enum TransformOrder
{
///
/// Apply position, then rotation, then scale.
///
PositionRotationScale,
///
/// Apply position, then scale, then rotation.
///
PositionScaleRotation,
///
/// Apply scale, then position, then rotation.
///
ScalePositionRotation,
///
/// Apply scale, then rotation, then position.
///
ScaleRotationPosition,
///
/// Apply rotation, then scale, then position.
///
RotationScalePosition,
///
/// Apply rotation, then position, then scale.
///
RotationPositionScale,
}
///
/// Different ways to apply rotation (order in which we rotate the different axis).
///
public enum RotationOrder
{
///
/// Rotate by axis order X, Y, Z.
///
RotateXYZ,
///
/// Rotate by axis order X, Z, Y.
///
RotateXZY,
///
/// Rotate by axis order Y, X, Z.
///
RotateYXZ,
///
/// Rotate by axis order Y, Z, X.
///
RotateYZX,
///
/// Rotate by axis order Z, X, Y.
///
RotateZXY,
///
/// Rotate by axis order Z, Y, X.
///
RotateZYX,
}
///
/// Contain all the possible node transformations.
///
public class Transformations
{
///
/// Node position / translation.
///
public Vector3 Position;
///
/// Node rotation.
///
public Vector3 Rotation;
///
/// Node scale.
///
public Vector3 Scale;
///
/// Create new default transformations.
///
public Transformations()
{
Position = Vector3.Zero;
Rotation = Vector3.Zero;
Scale = Vector3.One;
}
///
/// Clone transformations.
///
public Transformations(Transformations other)
{
Position = other.Position;
Rotation = other.Rotation;
Scale = other.Scale;
}
///
/// Build and return just the rotation matrix for this treansformations.
///
/// In which order to apply rotation (axis order) when applying rotation.
///
public Matrix BuildRotationMatrix(RotationOrder rotationOrder = RotationOrder.RotateYXZ)
{
switch (rotationOrder)
{
case RotationOrder.RotateXYZ:
return Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z);
case RotationOrder.RotateXZY:
return Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationY(Rotation.Y);
case RotationOrder.RotateYXZ:
return Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z);
case RotationOrder.RotateYZX:
return Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationX(Rotation.X);
case RotationOrder.RotateZXY:
return Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y);
case RotationOrder.RotateZYX:
return Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationX(Rotation.X);
default:
throw new System.Exception("Unknown rotation order!");
}
}
///
/// Build and return a matrix from current transformations.
///
/// In which order to apply transformations to produce final matrix.
/// In which order to apply rotation (axis order) when applying rotation.
/// Matrix with all transformations applied.
public Matrix BuildMatrix(TransformOrder transformOrder = TransformOrder.ScaleRotationPosition,
RotationOrder rotationOrder = RotationOrder.RotateYXZ)
{
// create the matrix parts
Matrix pos = Matrix.CreateTranslation(Position);
Matrix rot = BuildRotationMatrix(rotationOrder);
Matrix scale = Matrix.CreateScale(Scale);
// build and return matrix based on order
switch (transformOrder)
{
case TransformOrder.PositionRotationScale:
return pos * rot * scale;
case TransformOrder.PositionScaleRotation:
return pos * scale * rot;
case TransformOrder.ScalePositionRotation:
return scale * pos * rot;
case TransformOrder.ScaleRotationPosition:
return scale * rot * pos;
case TransformOrder.RotationScalePosition:
return rot * scale * pos;
case TransformOrder.RotationPositionScale:
return rot * pos * scale;
default:
throw new System.Exception("Unknown build matrix order!");
}
}
}
}