1 module polyplex.math.linear.transform; 2 import polyplex.math; 3 4 public class Transform { 5 public Transform Parent; 6 public Vector3 LocalScale; 7 public Quaternion LocalRotation; 8 public Vector3 LocalPosition; 9 10 public Transform LocalTransform() { 11 return new Transform(LocalScale, LocalRotation, LocalPosition); 12 } 13 14 this(Transform parent) { 15 this.Parent = parent; 16 LocalScale = Vector3.One; 17 LocalRotation = Quaternion.Identity; 18 LocalPosition = Vector3.Zero; 19 } 20 21 this(Vector3 scale, Quaternion rotation, Vector3 position) { 22 this(null); 23 LocalScale = scale; 24 LocalRotation = rotation; 25 LocalPosition = position; 26 } 27 28 this() { 29 this(null); 30 } 31 32 private Matrix4x4 lscale() { 33 return Matrix4x4.Scaling(LocalScale); 34 } 35 36 private Matrix4x4 lrot() { 37 return Matrix4x4.FromQuaternion(LocalRotation); 38 } 39 40 private Matrix4x4 ltrans() { 41 return Matrix4x4.Translation(LocalPosition); 42 } 43 44 public Matrix4x4 TRS() { 45 if (Parent is null) 46 return (ltrans * lrot * lscale); 47 return Parent.TRS*(ltrans * lrot * lscale); 48 } 49 50 public Vector3 Scale() { 51 if (Parent is null) return LocalScale; 52 return (TRS).ToScaling(); 53 } 54 55 public Quaternion Rotation() { 56 if (Parent is null) return LocalRotation; 57 return Rotation.FromMatrix(TRS); 58 } 59 60 public Vector3 Position() { 61 if (Parent is null) return LocalPosition; 62 return TRS.ToTranslation(); 63 } 64 65 public Vector3 Up() { 66 return Rotation.UpDirection; 67 } 68 69 public Vector3 Down() { 70 Vector3 up = Up; 71 return Vector3(-up.X, -up.Y, -up.Z); 72 } 73 74 public Vector3 Forward() { 75 return Rotation.ForwardDirection; 76 } 77 78 public Vector3 Back() { 79 Vector3 forward = Forward; 80 return Vector3(-forward.X, -forward.Y, -forward.Z); 81 } 82 83 public Vector3 Left() { 84 return Rotation.LeftDirection; 85 } 86 87 public Vector3 Right() { 88 Vector3 left = Left; 89 return Vector3(-left.X, -left.Y, -left.Z); 90 } 91 } 92 93 public class Transform2D { 94 public Transform2D Parent; 95 public Vector2 LocalScale; 96 public float LocalRotation; 97 public Vector2 LocalPosition; 98 99 public Transform2D LocalTransform() { 100 return new Transform2D(LocalScale, LocalRotation, LocalPosition); 101 } 102 103 this(Transform2D parent) { 104 this.Parent = parent; 105 LocalScale = Vector2.One; 106 LocalRotation = 0f; 107 LocalPosition = Vector2.Zero; 108 } 109 110 111 this(Vector2 scale, float rotation, Vector2 position) { 112 LocalScale = scale; 113 LocalRotation = rotation; 114 LocalPosition = position; 115 } 116 117 this() { 118 this(null); 119 } 120 121 private Matrix4x4 lscale() { 122 return Matrix4x4.Scaling(Vector3(LocalScale)); 123 } 124 125 private Matrix4x4 lrot() { 126 return Matrix4x4.RotationZ(this.LocalRotation); 127 } 128 129 private Matrix4x4 ltrans() { 130 return Matrix4x4.Translation(Vector3(LocalPosition)); 131 } 132 133 public Matrix4x4 TRS() { 134 if (Parent is null) 135 return (ltrans * lrot * lscale); 136 return Parent.TRS*(ltrans * lrot * lscale); 137 } 138 139 public Matrix4x4 MatrixScale() { 140 return lscale; 141 } 142 143 public Matrix4x4 MatrixRotation() { 144 return lrot; 145 } 146 147 public Matrix4x4 MatrixPosition() { 148 return ltrans; 149 } 150 151 public Vector2 Scale() { 152 if (Parent is null) return LocalScale; 153 return Vector2(TRS.ToScaling()); 154 } 155 156 public float Rotation() { 157 if (Parent is null) return LocalRotation; 158 return Parent.Rotation+LocalRotation; 159 } 160 161 public Vector2 Position() { 162 if (Parent is null) return LocalPosition; 163 return Vector2(TRS.ToTranslation()); 164 } 165 166 public void Rotate(float amount) { 167 LocalRotation = amount; 168 } 169 170 public Vector2 Up() { 171 return Vector2( 172 Vector2.Up.X * Mathf.Cos(Rotation) - Vector2.Up.Y * Mathf.Sin(Rotation), 173 Vector2.Up.X * Mathf.Sin(Rotation) + Vector2.Up.Y * Mathf.Cos(Rotation) 174 ); 175 } 176 177 public Vector2 Down() { 178 Vector2 up = Up; 179 return Vector2(-up.X, -up.Y); 180 } 181 182 public Vector2 Left() { 183 return Vector2( 184 Vector2.Left.X * Mathf.Cos(Rotation) - Vector2.Left.Y * Mathf.Sin(Rotation), 185 Vector2.Left.X * Mathf.Sin(Rotation) + Vector2.Left.Y * Mathf.Cos(Rotation) 186 ); 187 } 188 189 public Vector2 Right() { 190 Vector2 left = Left; 191 return Vector2(-left.X, -left.Y); 192 } 193 }