1 module unecht.core.components._editor;
2 
3 version(UEIncludeEditor):
4 
5 import unecht;
6 
7 import unecht.core.hideFlags;
8 import unecht.core.component;
9 import unecht.core.components.camera;
10 import unecht.core.components.sceneNode;
11 import unecht.core.components.material;
12 import unecht.core.components.misc;
13 import unecht.core.components.renderer;
14 import unecht.core.components.internal.gui;
15 
16 import unecht.core.components.editor.editorGui;
17 import unecht.core.components.editor.ui.menuSystem;
18 import unecht.core.components.editor.menuItems;
19 import unecht.core.components.editor.grid;
20 import unecht.core.components.editor.mouseControls;
21 
22 import unecht.gl.vertexBufferObject;
23 import unecht.gl.vertexArrayObject;
24 
25 import derelict.opengl3.gl3;
26 
27 ///
28 final class UEEditorNodeKeyControls : UEComponent
29 {
30 	mixin(UERegisterObject!());
31 
32 	static UESceneNode target;
33 
34 	override void onUpdate() {
35 		super.onUpdate;
36 
37 		enum speed = 0.5f;
38 
39 		target.position = target.position + (target.up * move.y * speed);
40 		target.position = target.position + (target.right * move.x * speed);
41 		target.position = target.position + (target.forward * move.z * speed);
42 
43 		//target.angles = target.angles + (rotate * speed);
44 	}
45 
46 	//TODO: register this by it self once recursive enable/disable works
47 	///
48 	private void OnKeyEvent(UEEvent _ev)
49 	{
50 		if(_ev.keyEvent.action == UEEvent.KeyEvent.Action.Down)
51 		{
52 			if(_ev.keyEvent.mods.isModShift)
53 			{
54 				if(_ev.keyEvent.key == UEKey.up)
55 					move.y = 1;
56 				else if(_ev.keyEvent.key == UEKey.down)
57 					move.y = -1;
58 			}
59 			else
60 			{
61 				if(_ev.keyEvent.key == UEKey.up)
62 					move.z = 1;
63 				else if(_ev.keyEvent.key == UEKey.down)
64 					move.z = -1;
65 			}
66 
67 			if(_ev.keyEvent.key == UEKey.left)
68 				move.x = -1;
69 			else if(_ev.keyEvent.key == UEKey.right)
70 				move.x = 1;
71 
72 			if(_ev.keyEvent.key == UEKey.w ||
73 				_ev.keyEvent.key == UEKey.s)
74 			{
75 				bool inc = _ev.keyEvent.key == UEKey.w;
76 				rotate.x = (inc?1.0f:-1.0f);
77 			}
78 			if(_ev.keyEvent.key == UEKey.a ||
79 				_ev.keyEvent.key == UEKey.d)
80 			{
81 				bool inc = _ev.keyEvent.key == UEKey.a;
82 				rotate.y = (inc?1.0f:-1.0f);
83 			}
84 			if(_ev.keyEvent.key == UEKey.q ||
85 				_ev.keyEvent.key == UEKey.e)
86 			{
87 				bool inc = _ev.keyEvent.key == UEKey.q;
88 				rotate.z = (inc?1.0f:-1.0f);
89 			}
90 		}
91 		else if(_ev.keyEvent.action == UEEvent.KeyEvent.Action.Up)
92 		{
93 
94 			if(_ev.keyEvent.key == UEKey.up ||
95 				_ev.keyEvent.key == UEKey.down)
96 			{
97 				move.y = 0;
98 				move.z = 0;
99 			}
100 
101 			if(_ev.keyEvent.key == UEKey.left ||
102 				_ev.keyEvent.key == UEKey.right)
103 				move.x = 0;
104 
105 			if(_ev.keyEvent.key == UEKey.w ||
106 				_ev.keyEvent.key == UEKey.s)
107 				rotate.x = 0;
108 			if(_ev.keyEvent.key == UEKey.a ||
109 				_ev.keyEvent.key == UEKey.d)
110 				rotate.y = 0;
111 			if(_ev.keyEvent.key == UEKey.q ||
112 				_ev.keyEvent.key == UEKey.e)
113 				rotate.z = 0;
114 		}
115 	}
116 
117 private:
118 	vec3 move = vec3(0);
119 	vec3 rotate = vec3(0);
120 }
121 
122 ///
123 final class UEEditorComponent : UEComponent {
124 
125 	mixin(UERegisterObject!());
126 
127 	private UEEditorNodeKeyControls keyControls;
128 
129 	override void onCreate()
130 	{
131 		super.onCreate;
132 
133 		registerEvent(UEEventType.key, &OnKeyEvent);
134 
135 		entity.addComponent!UEEditorgridComponent;
136 
137 		keyControls = entity.addComponent!UEEditorNodeKeyControls;
138 	}
139 
140 	///
141 	private void OnKeyEvent(UEEvent _ev)
142 	{
143 		if(_ev.keyEvent.action == UEEvent.KeyEvent.Action.Repeat ||
144 			_ev.keyEvent.action == UEEvent.KeyEvent.Action.Down)
145 		{
146 			if(_ev.keyEvent.key == UEKey.p)
147 			{
148 				import unecht.ue:ue;
149 				ue.scene.playing = !ue.scene.playing;
150 			}
151 
152 			if(EditorRootComponent._currentEntity &&
153 				((_ev.keyEvent.key == UEKey.backspace && _ev.keyEvent.mods.isModSuper) ||
154 				_ev.keyEvent.key == UEKey.del))
155 			{
156 				UEEditorMenus.removeCurrentEntity();
157 			}
158 
159 			if(_ev.keyEvent.key == UEKey.z && _ev.keyEvent.mods.isModSuper)
160 			{
161 				UEEditorMenus.undo();
162 			}
163 		}
164 
165 		keyControls.OnKeyEvent(_ev);
166 	}
167 }
168 
169 ///
170 final class EditorRootComponent : UEComponent {
171 
172 	mixin(UERegisterObject!());
173 
174 	private UEEntity editorComponent;
175 
176 	private static UEEntity gismo;
177 	private static UEMaterial editorMaterial;
178 
179 	private static bool _editorVisible;
180 	private static UECamera _editorCam;
181 	private static UEEntity _currentEntity;
182 	private static UEEditorGUI _editorGUI;
183 
184 	///
185 	static @property UECamera camera() { return _editorCam; }
186 	///
187 	static @property UEEntity currentEntity() { return _currentEntity; }
188 	///
189 	static @property bool visible() { return _editorVisible; }
190 
191 	///
192 	override void onCreate() {
193 		super.onCreate;
194 
195 		sceneNode.hideFlags.set(HideFlags.hideInHirarchie);
196 		sceneNode.hideFlags.set(HideFlags.dontSaveInScene);
197 
198 		registerEvent(UEEventType.key, &OnKeyEvent);
199 		registerEvent(UEEventType.updateEditMode, &onEditorUpdate);
200 
201 		_editorGUI = entity.addComponent!UEEditorGUI;
202 
203 		entity.addComponent!UEEditorMenus;
204 		entity.addComponent!UEEditorMouseControls;
205 
206 		_editorCam = entity.addComponent!UECamera;
207 		_editorCam.clearColor = vec4(0.1,0.1,0.1,1.0);
208 		_editorCam.sceneNode.position = vec3(0,5,-20);
209 
210 		editorComponent = UEEntity.create("subeditor");
211 		editorComponent.sceneNode.parent = this.sceneNode;
212 		editorComponent.addComponent!UEEditorComponent;
213 		editorComponent.sceneNode.enabled = false;
214 
215 		import unecht.core.components.editor.gismo;
216 		//TODO: support recursive disabling and move it under the editor subcomponent (#41)
217 		gismo = UEEntity.create("editor gismo");
218 		gismo.sceneNode.parent = this.sceneNode;
219 		gismo.addComponent!UEEditorGismo;
220 		gismo.sceneNode.enabled = false;
221 
222 		editorMaterial = this.entity.addComponent!UEMaterial;
223 		editorMaterial.setProgram(UEMaterial.vs_flat,UEMaterial.fs_flat, "color");
224 		editorMaterial.depthTest = false;
225 		editorMaterial.polygonFill = false;
226 		editorMaterial.cullMode = UEMaterial.CullMode.cullBack;
227 
228 		selectEntity(null);
229 
230 		toggleEditor();
231 	}
232 
233 	///
234 	override void onUpdate() {
235 		super.onUpdate;
236 
237 		if(_currentEntity && _currentEntity.destroyed)
238 			_currentEntity = null;
239 
240 		if(_currentEntity)
241 		{
242 			gismo.sceneNode.enabled = true;
243 			gismo.sceneNode.position = _currentEntity.sceneNode.position;
244 			gismo.sceneNode.rotation = _currentEntity.sceneNode.rotation;
245 		}
246 		else
247 			gismo.sceneNode.enabled = false;
248 	}
249 
250 	///
251 	private void onEditorUpdate(UEEvent ev)
252 	{
253 		onUpdate();
254 	}
255 
256 	///
257 	private void OnKeyEvent(UEEvent _ev)
258 	{
259 		if(_ev.keyEvent.action == UEEvent.KeyEvent.Action.Down &&
260 			_ev.keyEvent.key == UEKey.f1)
261 		{
262 			toggleEditor();
263 		}
264 	}
265 
266 	///
267 	package static void lookAtNode(UESceneNode node)
268 	{
269 		auto camNode = _editorCam.sceneNode;
270 
271 		camNode.position = node.position + (camNode.forward*-10.0f);
272 	}
273 
274 	///
275 	private void toggleEditor()
276 	{
277 		_editorVisible = !_editorVisible;
278 		editorComponent.sceneNode.enabled = _editorVisible;
279 	}
280 
281 	///
282 	//TODO: #127
283 	static void renderEditor()
284 	{
285 		if(_editorVisible)
286 		{
287 			// render regular but from editor camera pov
288 			_editorCam.render();
289 
290 			{
291 				// render gismo
292 				_editorCam.visibleLayers = 1<<UELayer.editor;
293 				_editorCam.clearBitColor=false;
294 				_editorCam.clearBitDepth=false;
295 				_editorCam.render();
296 				_editorCam.clearBitDepth=true;
297 				_editorCam.clearBitColor=true;
298 				_editorCam.visibleLayers = UECameraDefaultLayers;
299 			}
300 
301 			{
302 				// render wireframes
303 				UERenderer.editorMaterial = editorMaterial;
304 				scope(exit)UERenderer.editorMaterial = null;
305 				_editorCam.clearBitColor=false;
306 				scope(exit)_editorCam.clearBitColor=true;
307 				_editorCam.clearBitDepth=false;
308 				scope(exit)_editorCam.clearBitDepth=true;
309 
310 				_editorCam.render();
311 			}
312 		}
313 
314 		_editorGUI.render();
315 	}
316 
317 	///
318 	public static void selectEntity(UEEntity _entity)
319 	{
320 		if(_entity)
321 		{
322 			UEEditorNodeKeyControls.target = _entity.sceneNode;
323 			_currentEntity = _entity;
324 		}
325 		else
326 		{
327 			_currentEntity = null;
328 			UEEditorNodeKeyControls.target = _editorCam.sceneNode;
329 		}
330 	}
331 }