1 module d2d.core.transformable;
2 
3 import d2d;
4 
5 /// Base class for Drawables containing code for rotation, scaling and translation around an origin.
6 class Transformable
7 {
8 private:
9 	mat4 _transform = mat4.identity;
10 	vec2 _origin = vec2(0);
11 	vec2 _position = vec2(0);
12 	vec2 _scale = vec2(1);
13 	float _rotation = 0;
14 	bool _needsChange = true;
15 public:
16  @nogc:
17 	/// Rotates this around origin with the specified amount relatively.
18 	void rotate(float amount)
19 	{
20 		_rotation += amount;
21 		_needsChange = true;
22 	}
23 
24 	/// Scales this around origin with the specified amount relatively.
25 	void scale(vec2 amount)
26 	{
27 		_scale += amount;
28 		_needsChange = true;
29 	}
30 
31 	/// Moves this with the specified amount relatively.
32 	void move(vec2 amount)
33 	{
34 		_position += amount;
35 		_needsChange = true;
36 	}
37 
38  @property:
39 	/// Calculates the transformation matrix when needed and returns it.
40 	mat4 transform()
41 	{
42 		if (_needsChange)
43 		{
44 			_transform = mat4.scaling(_scale.x, _scale.y, 1) * mat4.translation(_position.x, _position.y, 0)
45 			             * mat4.zrotation(_rotation) * mat4.translation(-_origin.x, -_origin.y, 0);
46 
47 			assert(_transform.isFinite);
48 		}
49 
50 		return _transform;
51 	}
52 
53 	/// Sets the position of this transform.
54 	void position(vec2 position)
55 	{
56 		_position = position;
57 		_needsChange = true;
58 	}
59 
60 	/// Gets the position of this transform.
61 	vec2 position()
62 	{
63 		return _position;
64 	}
65 
66 	/// Sets the origin position of this transform.
67 	void origin(vec2 origin)
68 	{
69 		_origin = origin;
70 		_needsChange = true;
71 	}
72 
73 	/// Gets the origin position of this transform.
74 	vec2 origin()
75 	{
76 		return _origin;
77 	}
78 
79 	/// Sets the scaling of this transform.
80 	void scaling(vec2 scale)
81 	{
82 		_scale = scale;
83 		_needsChange = true;
84 	}
85 
86 	/// Gets the scaling of this transform.
87 	vec2 scaling()
88 	{
89 		return _scale;
90 	}
91 
92 	/// Sets the rotation of this transform.
93 	void rotation(float rotation)
94 	{
95 		_rotation = rotation;
96 		_needsChange = true;
97 	}
98 
99 	/// Gets the rotation of this transform.
100 	float rotation()
101 	{
102 		return _rotation;
103 	}
104 }