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 }