using System;
using System.Collections.Generic;
using Chernobyl.DesignPatterns.Extension;
using Chernobyl.Mathematics.Vectors;
using Chernobyl.Measures;
namespace Chernobyl.Mathematics.Movement
{
///
/// Used to provide an interface to which objects can become an object that can scale, rotate,
/// and/or translate. Disposing of an must separate it from its parent.
///
public interface ITransform : IDisposable, IExtension, IExtendable
{
///
/// Translates the transform in the X axis by a specified amount.
///
/// The amount to translate in the X.
void TranslateX(float x);
///
/// Translates the transform in the Y axis by a specified amount.
///
/// The amount to translate in the Y.
void TranslateY(float y);
///
/// Translates the transform in the Z axis by a specified amount.
///
/// The amount to translate in the Z.
void TranslateZ(float z);
///
/// Translates the transform in the X and Y axis by a specified amount.
/// This method is useful for transforms that exist in 2D world.
///
/// The amount to translate in the X.
/// The amount to translate in the Y.
void Translate(float x, float y);
///
/// Translates the transform in the X and Y axis by a specified amount.
/// This method is useful for transforms that exist in 2D world.
///
/// The amount to translate in the X and Y axis.
void Translate(Vector2 amount);
///
/// Translates the transform in the X axis, Y axis and Z axis by
/// specified amounts.
///
/// The amount to translate in the X.
/// The amount to translate in the Y.
/// The amount to translate in the Z.
void Translate(float x, float y, float z);
///
/// Translates the transform in the X axis, Y axis and Z axis by
/// specified amounts.
///
/// The amount to translate the transform in each
/// of the three axis where Vector3.X is the X axis translation amount,
/// Vector3.Y is the Y axis translation amount, and Vector3.Z is the
/// Z axis translation amount.
void Translate(Vector3 amount);
///
/// Rotates this transform around a vector by a specified amount.
///
/// The vector to rotate around.
/// The amount to rotate around the vector,
/// in radians.
void Rotate(Vector3 vectorToRotateAround, Radian radian);
///
/// Rotates this transform about the X axis a specified amount.
///
/// The amount to rotate by, in radians.
void Pitch(Radian amount);
///
/// Rotates this transform about the Y axis a specified amount.
///
/// The amount to rotate by, in radians.
void Yaw(Radian amount);
///
/// Rotates this transform about the Z axis a specified amount.
///
/// The amount to rotate by, in radians.
void Roll(Radian amount);
///
/// Scales the transform along the X axis.
///
/// The amount to scale in the X axis.
void ScaleX(float amount);
///
/// Scales the transform in the Y axis.
///
/// The amount to scale in the Y axis.
void ScaleY(float amount);
///
/// Scales the transform in the Z axis.
///
/// The amount to scale in the Z axis.
void ScaleZ(float amount);
///
/// Scales the transform uniformly over the X, Y, and Z axis.
///
/// The amount to scale in all axis.
void Scale(float amount);
///
/// Scales the transform in the X and Y axis. This is useful if the
/// transform exists in a 2D world.
///
/// The amount to scale in the X axis.
/// The amount to scale in the Y axis.
void Scale(float x, float y);
///
/// Scales the transform in the X and Y axis. This is useful if the
/// transform exists in a 2D world.
///
/// The amount to scale in the X and Y axis.
void Scale(Vector2 amount);
///
/// Scales the transform uniformly over the X, Y, and Z axis.
///
/// The amount to scale in the X axis.
/// The amount to scale in the Y axis.
/// The amount to scale in the Z axis.
void Scale(float x, float y, float z);
///
/// Scales the transform uniformly over the X, Y, and Z axis.
///
/// The amount to scale in each axis where
/// Vector3.X is the amount to scale in the X axis, Vector3.Y is the
/// amount to scale in the Y axis, Vector3.Z is the amount to scale in
/// the Z axis.
void Scale(Vector3 amount);
///
/// Sets the internal local transformation to the matrix passed in.
///
/// The matrix to set the internal local
/// transformation to.
void SetTransformation(ref Matrix4 matrix);
///
/// An event that is raised when the transform has been "dirtied" or
/// when the position, orientation, and/or scale of the transform has
/// been changed either due to an ancestor being changed or due to the
/// transform itself being changed. This event will only be raised once
/// when the transform is changed, subsequent changes to the transform
/// or it's ancestors will not cause the event to be raised. If the
/// transform is cleaned (typically done when the
/// is accessed) and then dirtied again, the event will be raised. This
/// event will be fired before children transforms are notified of the
/// change to the transform or it's ancestors (usually through the
/// child's flag).
///
event EventHandler TransformDirtied;
///
/// The parent to this transform. This property will
/// be null if this is the root of the hierarchy.
///
ITransform TransformParent { get; set; }
///
/// The children of this transform who's
/// position, orientation, scale, etc., are
/// effected or offset by this transform.
///
IList TransformChildren { get; }
///
/// This transforms position in the world. This property returns the
/// World position (i.e. the position from ) but
/// sets the Local position (i.e. the position from .
///
Vector3 Position { get; set; }
///
/// The up vector of this transform in the world, which is also the +Y
/// vector or .
///
Vector3 Up { get; }
///
/// The vector that points straight ahead (in the world) for this
/// transform, which is also the -Z vector or negative
/// .
///
Vector3 Forward { get; }
///
/// The vector that points to this transform's right in the world, which
/// is also the +X vector or .
///
Vector3 Right { get; }
///
/// The amount of scale in the world X axis of the transform.
///
float XScale { get; }
///
/// The amount of scale in the world Y axis of the transform.
///
float YScale { get; }
///
/// The amount of scale in the world Z axis of the transform.
///
float ZScale { get; }
///
/// Retrieves this transforms local matrix. The local matrix
/// is the matrix that has been "untouched" by the parents,
/// grandparents, etc., of this transform. In other words,
/// it is not relative to any other transform.
///
Matrix4 LocalMatrix { get; }
///
/// Retrieves this transform's world matrix. The world matrix
/// is the position and orientation relative to the parent of
/// this transform.
///
Matrix4 WorldMatrix { get; }
///
/// True if an update to this transform's world matrix is
/// needed, false if otherwise. A transform will need to be
/// updated if it's local matrix or an ancestors local matrix
/// is updated.
///
bool IsUpdateNeeded { get; set; }
}
///
/// An enum to define the axis of a transform (i.e. the X axis, Y axis,
/// Z axis). This enum is used by some code when it needs to allow the user
/// to specify certain axis for some operation.
///
[Flags]
public enum Axis
{
///
/// None of the axis.
///
None = 0,
///
/// The X axis of a transform.
///
X = 1,
///
/// The Y axis of a transform.
///
Y = 2,
///
/// The Z axis of a transform.
///
Z = 4,
///
/// All axis' of a transform
///
All = X | Y | Z
}
}