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 }