1 /*
2     Copyright © 2020, Luna Nielsen
3     Distributed under the 2-Clause BSD License, see LICENSE file.
4     
5     Authors: Luna Nielsen
6 */
7 module engine.math.transform;
8 import gl3n.linalg;
9 
10 /**
11     A 3D transform
12 */
13 class Transform {
14 private:
15     Transform parent;
16 
17     // Generated matrix
18     mat4 g_matrix() {
19         return mat4.translation(position) * rotation.to_matrix!(4, 4) * mat4.scaling(scale.x, scale.y, scale.z);
20     }
21 
22     // Generated matrix
23     mat4 g_matrix_ns() {
24         return mat4.translation(position) * rotation.to_matrix!(4, 4);
25     }
26 
27 public:
28 
29     /**
30         Create a new 3D transform
31     */
32     this(Transform parent = null) {
33         this(vec3(0, 0, 0), vec3(1, 1, 1), quat.identity, parent);
34     }
35 
36     /**
37         Create a new 3D transform
38     */
39     this(vec3 position, Transform parent = null) {
40         this(position, vec3(1, 1, 1), quat.identity, parent);
41     }
42 
43     /**
44         Create a new 3D transform
45     */
46     this(vec3 position, vec3 scale, Transform parent = null) {
47         this(position, scale, quat.identity, parent);
48     }
49 
50     /**
51         Create a new 3D transform
52     */
53     this(vec3 position, vec3 scale, quat rotation, Transform parent = null) {
54         this.parent = parent;
55         this.position = position;
56         this.scale = scale;
57         this.rotation = rotation;
58     }
59 
60     /**
61         Position of transform
62     */
63     vec3 position;
64 
65     /**
66         Origin of transform
67     */
68     vec3 origin;
69 
70     /**
71         Scale of transform
72     */
73     vec3 scale;
74 
75     /**
76         Rotation of transform
77     */
78     quat rotation;
79 
80     /**
81         Changes the transform's parent
82     */
83     void changeParent(Transform parent) {
84         this.parent = parent;
85     }
86 
87     /**
88         Gets the calculated matrix for this transform
89     */
90     mat4 matrix() {
91         if (parent is null) return g_matrix;
92         return g_matrix*parent.matrix;
93     }
94 
95     /**
96         Gets the calculated matrix for this transform without any scaling applied
97     */
98     mat4 matrixUnscaled() {
99         if (parent is null) return g_matrix_ns;
100         return g_matrix_ns*parent.matrixUnscaled;
101     }
102 }
103 
104 /**
105     A 2D transform
106 */
107 class Transform2D {
108 private:
109     Transform2D parent;
110 
111     // Generated matrix
112     mat4 g_matrix() {
113         return 
114             mat4.zrotation(rotation) * 
115             mat4.scaling(scale.x, scale.y, 1) * 
116             mat4.translation(position.x, position.y, 0) * 
117             mat4.translation(origin.x, origin.y, 0);
118     }
119 
120 public:
121 
122     /**
123         Create a new 2D transform
124     */
125     this(Transform2D parent = null) {
126         this(vec2(0, 0), vec2(0, 0), vec2(1, 1), 0, parent);
127     }
128 
129     /**
130         Create a new 2D transform
131     */
132     this(vec2 position, vec2 origin = vec2(0, 0), vec2 scale = vec2(1, 1), float rotation = 0, Transform2D parent = null) {
133         this.position = position;
134         this.origin = origin;
135         this.scale = scale;
136         this.rotation = rotation;
137         this.parent = parent;
138     }
139 
140     /**
141         Position of transform
142     */
143     vec2 position;
144     
145     /**
146         Position of the transform origin
147     */
148     vec2 origin;
149 
150     /**
151         Scale of transform
152     */
153     vec2 scale;
154 
155     /**
156         Rotation of transform
157     */
158     float rotation;
159 
160     /**
161         Changes the transform's parent
162     */
163     void changeParent(Transform2D parent) {
164         this.parent = parent;
165     }
166 
167     /**
168         Gets the calculated matrix for this transform
169     */
170     mat4 matrix() {
171         if (parent is null) return g_matrix;
172         return g_matrix*parent.matrix;
173     }
174 }