1 /**
2  * Copyright:       Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:         $(Gabriel Gheorghe)
4  * License:         $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source:          $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/core/components.d, _components.d)
6  * Documentation:
7  * Coverage:
8  */
9 module liberty.core.components;
10 import liberty.core.scenegraph.node : Node;
11 import liberty.core.model : Model, Mesh;
12 import liberty.graphics.material : Material, Materials;
13 import liberty.math.vector : Vector3F;
14 import liberty.math.matrix : Matrix4F;
15 import liberty.math.functions : radians;
16 ///
17 struct Component;
18 ///
19 struct ComponentField(string access) {
20 	static if (access == "ReadWrite") {
21 		///
22 		string getMethod = "Unspecified";
23 		///
24 		string setMethod = "Unspecified";
25 	} else static if (access == "ReadOnly") {
26 		///
27 		string getMethod = "Unspecified";
28 	} else static if (access == "WriteOnly") {
29 		///
30 		string setMethod = "Unspecified";
31 	} else {
32 		static assert (0, "Unknown access type!");
33 	}
34 }
35 ///
36 immutable ComponentServices = q{};
37 ///
38 @Component
39 struct Renderer(VERTEX) {
40 	///
41 	mixin(ComponentServices);
42 	private {
43 		Node _parent;
44 		Model!VERTEX _model;
45 		/// Mesh reference from _model visible in editor.
46 		@ComponentField!("ReadWrite")("mesh", "mesh")
47 		Mesh _mesh;
48 		/// Material reference from _model visible in editor.
49 		@ComponentField!("ReadWrite")("material", "material")
50 		Material _material;
51 	}
52 	///
53 	this(Node parent, Model!VERTEX model) pure nothrow @safe @nogc {
54 		_parent = parent;
55 		_model = model;
56 		_mesh = _model.mesh;
57 		_material = _model.material;
58 	}
59 	///
60 	void pass(void delegate() @safe drawCallback) @safe {
61 		_material.shader.loadUniform("model", _parent.transform.modelMatrix);
62         _model.mesh.vao.bind();
63         drawCallback();
64         _model.mesh.vao.unbind();
65 	}
66 	///
67 	Model!VERTEX model() pure nothrow @safe @nogc @property {
68 		return _model;
69 	}
70 	///
71 	void mesh(Mesh mesh) pure nothrow @safe @nogc {
72 		_mesh = mesh;
73 		_model.mesh = _mesh;
74 	}
75 	///
76 	void material(Material material) pure nothrow @safe @nogc {
77 		_material = material;
78 		_model.material(_material);
79 	}
80 	///
81 	Mesh mesh() pure nothrow @safe @nogc @property {
82 		return _mesh;
83 	}
84 	///
85 	Material material() pure nothrow @safe @nogc @property {
86 		return _material;
87 	}
88 }
89 ///
90 @Component
91 struct Transform {
92 	private {
93 		Matrix4F _modelMatrix = Matrix4F().identity();
94 		Vector3F _position;
95 		Vector3F _rotation;
96 		Vector3F _scale;
97 		//Vector3F _angles;
98 		Node _parent;
99 	}
100 	///
101 	this(Node parent, Vector3F position = Vector3F.zero, Vector3F rotation = Vector3F.zero, Vector3F scale = Vector3F.one, float angle = 0.0f) pure nothrow @safe @nogc {
102 		_parent = parent;
103 		_position = position;
104 		//_rotation = rotation;
105 		//_scale = scale;
106 		_modelMatrix.translate(position);
107 		//_modelMatrix.rotate(angle, rotation);
108 		_modelMatrix.scale(scale);
109 	}
110 	///
111 	ref Transform translate(float x, float y, float z) pure nothrow @safe @nogc {
112 		_position += Vector3F(x, y, z);
113 		_modelMatrix.translate(Vector3F(x, y, z));
114 		return this;
115 	}
116 	///
117 	ref Transform translate(Vector3F translation) pure nothrow @safe @nogc {
118 		_position += translation;
119 		_modelMatrix.translate(translation);
120 		return this;
121 	}
122 	///
123 	void translateX(float value) pure nothrow @safe @nogc {
124 		_position += Vector3F(value, 0.0f, 0.0f);
125 		_modelMatrix.translate(Vector3F(value, 0.0f, 0.0f));
126 	}
127 	///
128 	void translateY(float value) pure nothrow @safe @nogc {
129 		_position += Vector3F(0.0f, value, 0.0f);
130 		_modelMatrix.translate(Vector3F(0.0f, value, 0.0f));
131 	}
132 	///
133 	void translateZ(float value) pure nothrow @safe @nogc {
134 		_position += Vector3F(0.0f, 0.0f, value);
135 		_modelMatrix.translate(Vector3F(0.0f, 0.0f, value));
136 	}
137 	///
138 	void rotate(float angle, float rotationX, float rotationY, float rotationZ) pure nothrow @safe @nogc {
139 		_modelMatrix.rotate(angle, Vector3F(rotationX, rotationY, rotationZ));
140 	}
141 	///
142 	void rotate(float angle, Vector3F rotation) pure nothrow @safe @nogc {
143 		_modelMatrix.rotate(angle, _rotation);
144 	}
145 	///
146 	void rotatePitch(float angle) pure nothrow @safe @nogc {
147 		_modelMatrix.rotateX(angle.radians);
148 	}
149 	///
150 	void rotateY(float angle) pure nothrow @safe @nogc {
151 		_modelMatrix.rotateY(angle);
152 	}
153 	///
154 	void rotateZ(float angle) pure nothrow @safe @nogc {
155 		_modelMatrix.rotateZ(angle);
156 	}
157 	///
158 	void scale(float x, float y, float z) pure nothrow @safe @nogc {
159 		_modelMatrix.scale(Vector3F(x, y, z));
160 	}
161 	///
162 	void scale(Vector3F scale) pure nothrow @safe @nogc {
163 		_modelMatrix.scale(scale);
164 	}
165 	///
166 	void scaleX(float value) pure nothrow @safe @nogc {
167 		_modelMatrix.scale(Vector3F(value, 0.0f, 0.0f));
168 	}
169 	///
170 	void scaleY(float value) pure nothrow @safe @nogc {
171 		_modelMatrix.scale(Vector3F(0.0f, value, 0.0f));
172 	}
173 	///
174 	void scaleZ(float value) pure nothrow @safe @nogc {
175 		_modelMatrix.scale(Vector3F(0.0f, 0.0f, value));
176 	}
177 	///
178 	ref const(Vector3F) position() pure nothrow const @safe @nogc @property {
179 		return _position;
180 	}
181 		///
182 	ref const(Vector3F) rotation() pure nothrow const @safe @nogc @property {
183 		return _rotation;
184 	}
185 	///
186 	ref const(Vector3F) scale() pure nothrow const @safe @nogc @property {
187 		return _scale;
188 	}
189 	///
190 	ref const(Matrix4F) modelMatrix() pure nothrow const @safe @nogc @property {
191 		return _modelMatrix;
192 	}
193 }