@tomorrowevening/hermes 0.0.9 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/hermes.js +1608 -1382
  2. package/dist/hermes.umd.cjs +16 -16
  3. package/dist/style.css +1 -1
  4. package/package.json +1 -1
  5. package/src/core/RemoteController.ts +7 -3
  6. package/src/core/remote/RemoteThree.ts +24 -11
  7. package/src/core/types.ts +2 -1
  8. package/src/editor/global.ts +3 -1
  9. package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/CameraWindow.tsx +20 -7
  10. package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiView.scss +8 -0
  11. package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiView.tsx +286 -56
  12. package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiViewData.ts +7 -15
  13. package/src/editor/scss/{_sceneHierarchy.scss → _sidePanel.scss} +1 -1
  14. package/src/editor/scss/index.scss +1 -1
  15. package/src/editor/sidePanel/SidePanel.tsx +64 -0
  16. package/src/editor/sidePanel/inspector/Inspector.tsx +114 -0
  17. package/src/editor/{sceneHierarchy → sidePanel}/inspector/SceneInspector.tsx +16 -11
  18. package/src/editor/sidePanel/inspector/utils/InspectAnimation.tsx +51 -0
  19. package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectMaterial.tsx +1 -0
  20. package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectTransform.tsx +35 -46
  21. package/src/editor/{sceneHierarchy → sidePanel}/types.ts +10 -1
  22. package/src/editor/{sceneHierarchy → sidePanel}/utils.ts +11 -2
  23. package/src/editor/utils.ts +60 -4
  24. package/src/index.ts +9 -9
  25. package/types/core/remote/RemoteThree.d.ts +3 -2
  26. package/types/core/types.d.ts +1 -1
  27. package/types/editor/global.d.ts +2 -1
  28. package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/CameraWindow.d.ts +2 -0
  29. package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiView.d.ts +2 -4
  30. package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiViewData.d.ts +4 -4
  31. package/types/editor/sidePanel/SidePanel.d.ts +11 -0
  32. package/types/editor/{sceneHierarchy → sidePanel}/inspector/SceneInspector.d.ts +0 -2
  33. package/types/editor/sidePanel/inspector/utils/InspectAnimation.d.ts +3 -0
  34. package/types/editor/{sceneHierarchy → sidePanel}/types.d.ts +7 -1
  35. package/types/editor/utils.d.ts +7 -1
  36. package/types/index.d.ts +9 -9
  37. package/src/editor/sceneHierarchy/SceneHierarchy.tsx +0 -80
  38. package/src/editor/sceneHierarchy/inspector/Inspector.tsx +0 -97
  39. package/types/editor/sceneHierarchy/SceneHierarchy.d.ts +0 -13
  40. /package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridHelper.ts +0 -0
  41. /package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridMaterial.ts +0 -0
  42. /package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/UVMaterial.ts +0 -0
  43. /package/src/editor/{sceneHierarchy → sidePanel}/Accordion.tsx +0 -0
  44. /package/src/editor/{sceneHierarchy → sidePanel}/ChildObject.tsx +0 -0
  45. /package/src/editor/{sceneHierarchy → sidePanel}/ContainerObject.tsx +0 -0
  46. /package/src/editor/{sceneHierarchy → sidePanel}/ToggleBtn.tsx +0 -0
  47. /package/src/editor/{sceneHierarchy → sidePanel}/inspector/InspectorField.tsx +0 -0
  48. /package/src/editor/{sceneHierarchy → sidePanel}/inspector/InspectorGroup.tsx +0 -0
  49. /package/src/editor/{sceneHierarchy → sidePanel}/inspector/inspector.scss +0 -0
  50. /package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectCamera.tsx +0 -0
  51. /package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectLight.tsx +0 -0
  52. /package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridHelper.d.ts +0 -0
  53. /package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridMaterial.d.ts +0 -0
  54. /package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/UVMaterial.d.ts +0 -0
  55. /package/types/editor/{sceneHierarchy → sidePanel}/Accordion.d.ts +0 -0
  56. /package/types/editor/{sceneHierarchy → sidePanel}/ChildObject.d.ts +0 -0
  57. /package/types/editor/{sceneHierarchy → sidePanel}/ContainerObject.d.ts +0 -0
  58. /package/types/editor/{sceneHierarchy → sidePanel}/ToggleBtn.d.ts +0 -0
  59. /package/types/editor/{sceneHierarchy → sidePanel}/inspector/Inspector.d.ts +0 -0
  60. /package/types/editor/{sceneHierarchy → sidePanel}/inspector/InspectorField.d.ts +0 -0
  61. /package/types/editor/{sceneHierarchy → sidePanel}/inspector/InspectorGroup.d.ts +0 -0
  62. /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectCamera.d.ts +0 -0
  63. /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectLight.d.ts +0 -0
  64. /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectMaterial.d.ts +0 -0
  65. /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectTransform.d.ts +0 -0
  66. /package/types/editor/{sceneHierarchy → sidePanel}/utils.d.ts +0 -0
@@ -1,28 +1,67 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
- import { AxesHelper, Camera, CameraHelper, OrthographicCamera, PerspectiveCamera, Scene, Vector2, WebGLRenderer } from 'three';
2
+ import { AxesHelper, Camera, CameraHelper, Group, OrthographicCamera, PerspectiveCamera, Raycaster, Scene, Vector2, WebGLRenderer } from 'three';
3
3
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
4
4
  import CameraWindow, { Dropdown } from './CameraWindow';
5
5
  import InfiniteGridHelper from './InfiniteGridHelper';
6
- import { cameraOptions, cameras, controls, helpers, ModeOptions, MultiViewMode, normalsMaterial, RenderMode, renderOptions, uvMaterial, wireframeMaterial } from './MultiViewData';
6
+ import { cameras, controls, depthMaterial, helpers, ModeOptions, MultiViewMode, normalsMaterial, RenderMode, renderOptions, uvMaterial, wireframeMaterial } from './MultiViewData';
7
7
  import './MultiView.scss';
8
+ import RemoteThree from '@/core/remote/RemoteThree';
9
+ import { ToolEvents, debugDispatcher } from '../global';
10
+ import { dispose } from '../utils';
11
+ import { mapLinear } from 'three/src/math/MathUtils';
8
12
 
9
- let currentRenderMode: RenderMode = 'Default';
13
+ let currentRenderMode: RenderMode = 'Renderer';
14
+
15
+ // Scene
10
16
 
11
17
  const scene = new Scene();
18
+ scene.name = 'Debug Scene';
19
+
20
+ let currentScene = new Scene();
21
+ scene.add(currentScene);
22
+
23
+ const helpersContainer = new Group();
24
+ helpersContainer.name = 'helpers';
25
+ scene.add(helpersContainer);
26
+
27
+ const grid = new InfiniteGridHelper();
28
+ helpersContainer.add(grid);
29
+
30
+ const axisHelper = new AxesHelper(500);
31
+ axisHelper.name = 'axisHelper';
32
+ helpersContainer.add(axisHelper);
33
+
34
+ const interactionHelper = new AxesHelper(100);
35
+ interactionHelper.name = 'interactionHelper';
36
+ helpersContainer.add(interactionHelper);
37
+ interactionHelper.visible = false;
38
+
39
+ let useRaycaster = false;
40
+
41
+ // Cameras
42
+
12
43
  let tlCam = cameras.get('Debug')!;
13
44
  let trCam = cameras.get('Orthographic')!;
14
45
  let blCam = cameras.get('Front')!;
15
46
  let brCam = cameras.get('Top')!;
16
47
 
17
48
  interface MultiViewProps {
18
- scene: Scene;
19
- renderer: WebGLRenderer;
20
- cameras: Camera[];
49
+ three: RemoteThree;
21
50
  mode?: MultiViewMode;
22
51
  }
52
+
23
53
  export default function MultiView(props: MultiViewProps) {
54
+ // States
24
55
  const [mode, setMode] = useState<MultiViewMode>(props.mode !== undefined ? props.mode : 'Quad');
25
-
56
+ const [renderer, setRenderer] = useState<WebGLRenderer | null>(null);
57
+ const [modeOpen, setModeOpen] = useState(false);
58
+ const [renderModeOpen, setRenderModeOpen] = useState(false);
59
+ const [interactionModeOpen, setInteractionModeOpen] = useState(false);
60
+ const [, setLastUpdate] = useState(Date.now());
61
+
62
+ // References
63
+ const canvasRef = useRef<HTMLCanvasElement>(null);
64
+ const containerRef = useRef<HTMLDivElement>(null);
26
65
  const tlWindow = useRef<HTMLDivElement>(null);
27
66
  const trWindow = useRef<HTMLDivElement>(null);
28
67
  const blWindow = useRef<HTMLDivElement>(null);
@@ -43,6 +82,8 @@ export default function MultiView(props: MultiViewProps) {
43
82
 
44
83
  // New items
45
84
  const control = new OrbitControls(camera, element);
85
+ control.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
86
+ control.dampingFactor = 0.05;
46
87
  switch (camera.name) {
47
88
  case 'Top':
48
89
  case 'Bottom':
@@ -110,24 +151,57 @@ export default function MultiView(props: MultiViewProps) {
110
151
  }
111
152
  };
112
153
 
113
- // Add scene + helpers
154
+ // Renderer
114
155
  useEffect(() => {
115
- scene.name = 'Debug Scene';
116
- scene.add(props.scene);
156
+ const instance = new WebGLRenderer({
157
+ canvas: canvasRef.current!,
158
+ stencil: false
159
+ });
160
+ instance.autoClear = false;
161
+ instance.shadowMap.enabled = true;
162
+ instance.setPixelRatio(devicePixelRatio);
163
+ instance.setClearColor(0x000000);
164
+ setRenderer(instance);
165
+ }, []);
117
166
 
118
- const grid = new InfiniteGridHelper();
119
- scene.add(grid);
167
+ // Event handling
168
+ useEffect(() => {
169
+ const sceneUpdate = () => {
170
+ dispose(currentScene);
171
+ scene.remove(currentScene);
172
+ if (props.three.scene !== undefined) {
173
+ currentScene = props.three.scene;
174
+ scene.add(currentScene);
175
+ }
176
+ };
177
+
178
+ const addCamera = (evt: any) => {
179
+ const data = evt.value;
180
+ const child = props.three.scene?.getObjectByProperty('uuid', data.uuid);
181
+ if (child !== undefined) cameras.set(data.name, child as Camera);
182
+ setLastUpdate(Date.now());
183
+ };
120
184
 
121
- const axisHelper = new AxesHelper(500);
122
- axisHelper.name = 'axisHelper';
123
- scene.add(axisHelper);
185
+ const removeCamera = (evt: any) => {
186
+ cameras.delete(evt.value.name);
187
+ setLastUpdate(Date.now());
188
+ };
189
+
190
+ debugDispatcher.addEventListener(ToolEvents.SET_SCENE, sceneUpdate);
191
+ debugDispatcher.addEventListener(ToolEvents.ADD_CAMERA, addCamera);
192
+ debugDispatcher.addEventListener(ToolEvents.REMOVE_CAMERA, removeCamera);
193
+ return () => {
194
+ debugDispatcher.removeEventListener(ToolEvents.SET_SCENE, sceneUpdate);
195
+ debugDispatcher.removeEventListener(ToolEvents.ADD_CAMERA, addCamera);
196
+ debugDispatcher.removeEventListener(ToolEvents.REMOVE_CAMERA, removeCamera);
197
+ };
124
198
  }, []);
125
199
 
126
200
  // Resize handling + drawing
127
201
  useEffect(() => {
128
- const size = props.renderer.getSize(new Vector2());
129
- let width = size.x;
130
- let height = size.y;
202
+ if (renderer === null) return;
203
+ let width = window.innerWidth;
204
+ let height = window.innerHeight;
131
205
  let bw = Math.floor(width / 2);
132
206
  let bh = Math.floor(height / 2);
133
207
  let raf = -1;
@@ -137,6 +211,7 @@ export default function MultiView(props: MultiViewProps) {
137
211
  height = window.innerHeight;
138
212
  bw = Math.floor(width / 2);
139
213
  bh = Math.floor(height / 2);
214
+ renderer.setSize(width, height);
140
215
 
141
216
  let cw = width;
142
217
  let ch = height;
@@ -171,29 +246,29 @@ export default function MultiView(props: MultiViewProps) {
171
246
  };
172
247
 
173
248
  const drawSingle = () => {
174
- props.renderer.setViewport(0, 0, width, height);
175
- props.renderer.setScissor(0, 0, width, height);
176
- props.renderer.render(scene, tlCam);
249
+ renderer.setViewport(0, 0, width, height);
250
+ renderer.setScissor(0, 0, width, height);
251
+ renderer.render(scene, tlCam);
177
252
  };
178
253
 
179
254
  const drawDouble = () => {
180
255
  if (mode === 'Side by Side') {
181
- props.renderer.setViewport(0, 0, bw, height);
182
- props.renderer.setScissor(0, 0, bw, height);
183
- props.renderer.render(scene, tlCam);
256
+ renderer.setViewport(0, 0, bw, height);
257
+ renderer.setScissor(0, 0, bw, height);
258
+ renderer.render(scene, tlCam);
184
259
 
185
- props.renderer.setViewport(bw, 0, bw, height);
186
- props.renderer.setScissor(bw, 0, bw, height);
187
- props.renderer.render(scene, trCam);
260
+ renderer.setViewport(bw, 0, bw, height);
261
+ renderer.setScissor(bw, 0, bw, height);
262
+ renderer.render(scene, trCam);
188
263
  } else {
189
264
  const y = height - bh;
190
- props.renderer.setViewport(0, y, width, bh);
191
- props.renderer.setScissor(0, y, width, bh);
192
- props.renderer.render(scene, tlCam);
265
+ renderer.setViewport(0, y, width, bh);
266
+ renderer.setScissor(0, y, width, bh);
267
+ renderer.render(scene, tlCam);
193
268
 
194
- props.renderer.setViewport(0, 0, width, bh);
195
- props.renderer.setScissor(0, 0, width, bh);
196
- props.renderer.render(scene, trCam);
269
+ renderer.setViewport(0, 0, width, bh);
270
+ renderer.setScissor(0, 0, width, bh);
271
+ renderer.render(scene, trCam);
197
272
  }
198
273
  };
199
274
 
@@ -204,29 +279,29 @@ export default function MultiView(props: MultiViewProps) {
204
279
 
205
280
  // TL
206
281
  x = 0;
207
- props.renderer.setViewport(x, y, bw, bh);
208
- props.renderer.setScissor(x, y, bw, bh);
209
- props.renderer.render(scene, tlCam);
282
+ renderer.setViewport(x, y, bw, bh);
283
+ renderer.setScissor(x, y, bw, bh);
284
+ renderer.render(scene, tlCam);
210
285
 
211
286
  // TR
212
287
  x = bw;
213
- props.renderer.setViewport(x, y, bw, bh);
214
- props.renderer.setScissor(x, y, bw, bh);
215
- props.renderer.render(scene, trCam);
288
+ renderer.setViewport(x, y, bw, bh);
289
+ renderer.setScissor(x, y, bw, bh);
290
+ renderer.render(scene, trCam);
216
291
 
217
292
  y = 0;
218
293
 
219
294
  // BL
220
295
  x = 0;
221
- props.renderer.setViewport(x, y, bw, bh);
222
- props.renderer.setScissor(x, y, bw, bh);
223
- props.renderer.render(scene, blCam);
296
+ renderer.setViewport(x, y, bw, bh);
297
+ renderer.setScissor(x, y, bw, bh);
298
+ renderer.render(scene, blCam);
224
299
 
225
300
  // BR
226
301
  x = bw;
227
- props.renderer.setViewport(x, y, bw, bh);
228
- props.renderer.setScissor(x, y, bw, bh);
229
- props.renderer.render(scene, brCam);
302
+ renderer.setViewport(x, y, bw, bh);
303
+ renderer.setScissor(x, y, bw, bh);
304
+ renderer.render(scene, brCam);
230
305
  };
231
306
 
232
307
  const onUpdate = () => {
@@ -234,10 +309,9 @@ export default function MultiView(props: MultiViewProps) {
234
309
  controls.forEach((control: OrbitControls) => {
235
310
  control.update();
236
311
  });
237
- props.scene['update']();
238
312
 
239
313
  // Drawing
240
- props.renderer.clear();
314
+ renderer.clear();
241
315
  switch (mode) {
242
316
  case 'Single':
243
317
  drawSingle();
@@ -265,16 +339,136 @@ export default function MultiView(props: MultiViewProps) {
265
339
  cancelAnimationFrame(raf);
266
340
  raf = -1;
267
341
  };
268
- }, [mode]);
342
+ }, [mode, renderer]);
269
343
 
270
- props.cameras.forEach((camera: Camera) => {
271
- cameras.set(camera.name, camera);
272
- cameraOptions.push(camera.name);
344
+ // Raycaster
345
+ useEffect(() => {
346
+ if (renderer !== null) {
347
+ const raycaster = new Raycaster();
348
+ const pointer = new Vector2();
349
+
350
+ const updateCamera = (mouseX: number, mouseY: number, hw: number, hh: number) => {
351
+ switch (mode) {
352
+ case 'Quad':
353
+ if (mouseX < hw) {
354
+ if (mouseY < hh) {
355
+ raycaster.setFromCamera(pointer, tlCam);
356
+ } else {
357
+ raycaster.setFromCamera(pointer, blCam);
358
+ }
359
+ } else {
360
+ if (mouseY < hh) {
361
+ raycaster.setFromCamera(pointer, trCam);
362
+ } else {
363
+ raycaster.setFromCamera(pointer, brCam);
364
+ }
365
+ }
366
+ break;
367
+ case 'Side by Side':
368
+ if (mouseX < hw) {
369
+ raycaster.setFromCamera(pointer, tlCam);
370
+ } else {
371
+ raycaster.setFromCamera(pointer, trCam);
372
+ }
373
+ break;
374
+ case 'Single':
375
+ raycaster.setFromCamera(pointer, tlCam);
376
+ break;
377
+ case 'Stacked':
378
+ if (mouseY < hh) {
379
+ raycaster.setFromCamera(pointer, tlCam);
380
+ } else {
381
+ raycaster.setFromCamera(pointer, trCam);
382
+ }
383
+ break;
384
+ }
385
+ };
386
+
387
+ const onMouseMove = (event: MouseEvent) => {
388
+ if (!useRaycaster) return;
389
+ const size = new Vector2();
390
+ renderer!.getSize(size);
391
+
392
+ const mouseX = Math.min(event.clientX, size.x);
393
+ const mouseY = Math.min(event.clientY, size.y);
394
+ pointer.x = mapLinear(mouseX, 0, size.x, -1, 1);
395
+ pointer.y = mapLinear(mouseY, 0, size.y, 1, -1);
396
+
397
+ const hw = size.x / 2;
398
+ const hh = size.y / 2;
399
+
400
+ const sideBySide = () => {
401
+ if (mouseX < hw) {
402
+ pointer.x = mapLinear(mouseX, 0, hw, -1, 1);
403
+ } else {
404
+ pointer.x = mapLinear(mouseX, hw, size.x, -1, 1);
405
+ }
406
+ };
407
+
408
+ const stacked = () => {
409
+ if (mouseY < hh) {
410
+ pointer.y = mapLinear(mouseY, 0, hh, 1, -1);
411
+ } else {
412
+ pointer.y = mapLinear(mouseY, hh, size.y, 1, -1);
413
+ }
414
+ };
415
+
416
+ // mapLinear
417
+ switch (mode) {
418
+ case 'Quad':
419
+ sideBySide();
420
+ stacked();
421
+ break;
422
+ case 'Side by Side':
423
+ sideBySide();
424
+ break;
425
+ case 'Stacked':
426
+ stacked();
427
+ stacked();
428
+ break;
429
+ }
430
+
431
+ updateCamera(mouseX, mouseY, hw, hh);
432
+ const intersects = raycaster.intersectObjects(currentScene.children);
433
+ if (intersects.length > 0) interactionHelper.position.copy(intersects[0].point);
434
+ };
435
+
436
+ const onClick = (event: MouseEvent) => {
437
+ if (!useRaycaster) return;
438
+
439
+ const size = new Vector2();
440
+ renderer!.getSize(size);
441
+ if (event.clientX >= size.x) return;
442
+
443
+ onMouseMove(event);
444
+
445
+ const intersects = raycaster.intersectObjects(currentScene.children);
446
+ if (intersects.length > 0) {
447
+ props.three.getObject(intersects[0].object.uuid);
448
+ }
449
+ };
450
+
451
+ const element = containerRef.current!;
452
+ element.addEventListener('mousemove', onMouseMove, false);
453
+ element.addEventListener('click', onClick, false);
454
+ return () => {
455
+ element.removeEventListener('mousemove', onMouseMove);
456
+ element.removeEventListener('click', onClick);
457
+ };
458
+ }
459
+ }, [mode, renderer]);
460
+
461
+ // Camera names
462
+ const cameraOptions: string[] = [];
463
+ cameras.forEach((_: Camera, key: string) => {
464
+ cameraOptions.push(key);
273
465
  });
274
466
 
275
467
  return (
276
468
  <div className='multiview'>
277
- <div className={`cameras ${mode === 'Single' || mode === 'Stacked' ? 'single' : ''}`}>
469
+ <canvas ref={canvasRef} />
470
+
471
+ <div className={`cameras ${mode === 'Single' || mode === 'Stacked' ? 'single' : ''}`} ref={containerRef}>
278
472
  {mode === 'Single' && (
279
473
  <>
280
474
  <CameraWindow camera={tlCam} options={cameraOptions} ref={tlWindow} onSelect={(value: string) => {
@@ -364,29 +558,65 @@ export default function MultiView(props: MultiViewProps) {
364
558
  killControls();
365
559
  setMode(value as MultiViewMode);
366
560
  }}
561
+ open={modeOpen}
562
+ onToggle={(value: boolean) => {
563
+ setModeOpen(value);
564
+ if (renderModeOpen) setRenderModeOpen(false);
565
+ if (interactionModeOpen) setInteractionModeOpen(false);
566
+ }}
367
567
  />
568
+
368
569
  {/* Render Mode */}
369
570
  <Dropdown
370
- index={0}
571
+ index={renderOptions.indexOf(currentRenderMode)}
371
572
  options={renderOptions}
372
573
  onSelect={(value: string) => {
373
574
  if (value === currentRenderMode) return;
374
575
  currentRenderMode = value as RenderMode;
375
576
  switch (currentRenderMode) {
376
- case 'Default':
377
- scene.overrideMaterial = null;
577
+ case 'Depth':
578
+ scene.overrideMaterial = depthMaterial;
378
579
  break;
379
580
  case 'Normals':
380
581
  scene.overrideMaterial = normalsMaterial;
381
582
  break;
583
+ default:
584
+ case 'Renderer':
585
+ scene.overrideMaterial = null;
586
+ break;
382
587
  case 'Wireframe':
383
588
  scene.overrideMaterial = wireframeMaterial;
384
589
  break;
385
- case 'UVs':
590
+ case 'UVs':
386
591
  scene.overrideMaterial = uvMaterial;
387
592
  break;
388
593
  }
389
594
  }}
595
+ open={renderModeOpen}
596
+ onToggle={(value: boolean) => {
597
+ if (modeOpen) setModeOpen(false);
598
+ setRenderModeOpen(value);
599
+ if (interactionModeOpen) setInteractionModeOpen(false);
600
+ }}
601
+ />
602
+
603
+ {/* Interaction Mode */}
604
+ <Dropdown
605
+ index={0}
606
+ options={[
607
+ 'Orbit Mode',
608
+ 'Selection Mode',
609
+ ]}
610
+ onSelect={(value: string) => {
611
+ useRaycaster = value === 'Selection Mode';
612
+ interactionHelper.visible = useRaycaster;
613
+ }}
614
+ open={interactionModeOpen}
615
+ onToggle={(value: boolean) => {
616
+ if (modeOpen) setModeOpen(false);
617
+ if (renderModeOpen) setRenderModeOpen(false);
618
+ setInteractionModeOpen(value);
619
+ }}
390
620
  />
391
621
  </div>
392
622
  </div>
@@ -1,4 +1,4 @@
1
- import { Camera, CameraHelper, MeshBasicMaterial, MeshNormalMaterial, OrthographicCamera, PerspectiveCamera, Vector3 } from 'three';
1
+ import { Camera, CameraHelper, MeshBasicMaterial, MeshDepthMaterial, MeshNormalMaterial, OrthographicCamera, PerspectiveCamera, Vector3 } from 'three';
2
2
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
3
3
  import UVMaterial from './UVMaterial';
4
4
 
@@ -15,16 +15,6 @@ export const ModeOptions: MultiViewMode[] = [
15
15
  export const cameras: Map<string, Camera> = new Map();
16
16
  export const controls: Map<string, OrbitControls> = new Map();
17
17
  export const helpers: Map<string, CameraHelper> = new Map();
18
- export const cameraOptions: string[] = [
19
- 'Top',
20
- 'Bottom',
21
- 'Left',
22
- 'Right',
23
- 'Front',
24
- 'Back',
25
- 'Orthographic',
26
- 'Debug',
27
- ];
28
18
 
29
19
  export function createOrtho(name: string, position: Vector3) {
30
20
  const camera = new OrthographicCamera(-100, 100, 100, -100, 50, 3000);
@@ -51,17 +41,19 @@ cameras.set('Debug', debugCamera);
51
41
 
52
42
  // Rendering
53
43
 
54
- export type RenderMode = 'Default' | 'Normals' | 'Wireframe' | 'UVs';
44
+ export type RenderMode = 'Depth' | 'Normals' | 'Renderer' | 'UVs' | 'Wireframe';
55
45
  export const renderOptions: RenderMode[] = [
56
- 'Default',
46
+ 'Renderer',
47
+ 'Depth',
57
48
  'Normals',
58
- 'Wireframe',
59
49
  'UVs',
50
+ 'Wireframe',
60
51
  ];
52
+ export const depthMaterial = new MeshDepthMaterial();
61
53
  export const normalsMaterial = new MeshNormalMaterial();
54
+ export const uvMaterial = new UVMaterial();
62
55
  export const wireframeMaterial = new MeshBasicMaterial({
63
56
  opacity: 0.33,
64
57
  transparent: true,
65
58
  wireframe: true
66
59
  });
67
- export const uvMaterial = new UVMaterial();
@@ -9,7 +9,7 @@ $icon_ui: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rh
9
9
  $icon_utils: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAACXBIWXMAAAsTAAALEwEAmpwYAAADFElEQVRYhe2YT0hVQRSHf7YwsUVoakFtKmhdUfhUeLSrrFVQEES72rip1EoscFlLK2jRpl21tT8QhFkLq13gIotqlaRPQ8SkgvRrcefiOO/eufN8LzPwwMV375w5893fnHPm+aoArWZb968BsmwNsFz7rwHzkgYltVdgnRpJZyU9lTQm6ZukUUl9GQwSkHS1AgUimwduAHUpvlnXLmCYYpsFDmXNT3p4AJhICDgC7C0RbgvwISHWGNASEiPpYdLbxvYJ2FQC4F1rbj/w1nx+ERoj6WE78NsDeSIw+E7gh5kzYJ5dM/dzwFbH/yDQ58ZJStAnkm570rY+sDDaTHEgqd88GzJ/ayWdk7Td3Ock3Zd0OrRINgKjKQq+ApoCFOw0/j8tteqAaSvWd6LtjgtyKkRBSZqRdFLS+4SxnKQBSU0ZCsaHfLXlOy3plqRxc79BUTtrNPe/QhWU9cbHgQ7gTYKSm1Pm5YAvlm+bM15PlOvXWSwcgGdurFJaRpOBsu010Oj4tVhbBtAFVHni3rR8z5QDKKNYEmSsZI6lPbTbmZ8HdgPbgMNE1R3bMFBbLqCABgNl20vgmAN30ZnXRXQqzbPYfmIbAXYkrbccwLTtts1VrjvFbxa4Q3GalA0Yb/fzALgua2zcjHcDp0hRrVKAAo4CCx64XmtsksDzt1KAbitx4a5YY1+BPctZZ7lwzfgLwlZuxQFb8LcSW7k5FlNgRbY4R5ToIXATREp3OM9a/xZgjqUnhG9bZ4D91linNTZpYlUU0IVzlbMBIGrE5z0+hVAlQ3POt63uwnZ+XvL4ThCQk5VUbhLYR1StNmSPM+eCM8erZBacr1rtE8JVw21Dlz0vVsCTk2lwDcBnE2CB4oKwz9YCyVvltqOkLw9xC/pIyj9jaYBHrMC9Hris3pYzPmmQPdZYeymAeWviPaAmAS4oyT1KrjexY8uXAlgNPLImP2BpnwtuExakXWxXHbjHZs2SiqQeGKTYpgKVy9ru2IbMWiVXcQxpfy1/t0y4+Go2MWJ7SMYvFVWw9hNwWbYGWK6tesA/ap/6uHJWeiAAAAAASUVORK5CYII=');
10
10
  $icon_world: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEZklEQVRYhe2YW4iVVRTHf4465oSaUNlUjo7SmCBEPVipTWYXoV7qoejykhRCEVQP9pAFSWVBPdRTMNRLWGRaFr2FSShmEQ1KzQymUhpeMky6ONbcfj3sdZpvvvnO8Zy5lA/+YcP51jpr7bVv/7X2nqByNqPu/w7gTDgX4GgxaYR2DcDlwC3AUmAh0ARMDf1fwGGgE9gFfAb8AJyquSe1ljZFXa6+o/Y4FD3qvmh5neomdYXaUEuftQQ3T31d7Y8O96tdal98P69eos5SXwhZn7pb7cgE2qa2jHWAy9Svo4Nf1VfUG9VPQvauWp/5f726MXSb1WvVF9XjIftWvXWsArxdPRSOt5uWCfV+dUDtVJsL7K5Q98aM3xuyVnVr+Dqi3jHaAJepx8Lhe2pTyJvVn6PzVRXsHw7bw+rckDWqb4b8mHrbSAOcp7aHozZ1Wka3NuQfqHUVfExUt8R/n8rI69XXQt6lLijnoxzNTAEeA64GeoDzgbVBI5OBu+J/FwPrg3aK0A1cGL8fB+YAfUFDF4T+SmAN8ATwZ97BBC3MxdeTuGtqOBSYkGklgu/NyIpgtMnxPRDfpd9kdCuBT/MOimawHlgdwW0DPs918AAwH9gK7MjoyqEHWA6sAPYBGzMD6gWWRHCPhL/TQ4dYfPpOxSFYXKDvVE+YaKZamrpZPWmil7xuoXrQxAiL8vqiXHwTaU99BbTndItJe+Zoga4S2oFjpJR4TU7XBXwZs7oyb1gU4DKgH/iCtP+yaAlH+4E/agjwJCkXTwwfeewgLXdrNQEuAn6neIYaSfvwQA3BlXCAdEAaC3TtpEFclVcUHZIm0sauC2f1Ie8lLZGkmbiI8vSSR3fYDYSPyzJ990YfvQxS0r8oopkTJI76jbTUpRMnMI3Ekd2k0qnaenKAxKUNwN+k7ZH1Wxd9nswHWWvBWo7vxg1FSyzwC/AgsIfBJe4DngNWAW1UziB5dAPPAo8CbwPrGLrELcAGYEY1AR4C5pKW5WhOt5c0iwMxiFpQykBdpGo7i7kkwj+eNypa4g5gOsP5ChKX1ZG4sFbMjyDzgyb6mgl8V02AO0mndAnDZ/h70hZoJg2iWswMm37SKuRxA2kGtw/TFKSelipTXesIUt3uWlNd0R78EXifdEheYnixMDlm5BlqKxZmkChqHcOLhdnAxxQkgErl1jbgPM7CcgtS6nkDeDIcbQZ+IpVgk4A7gUtJBcVOKhesS0n5/QjwEYMF6yzg7gjwLVLuLxhi+X3TrH4TZXmbOj2jezrkZyr5JzlY8q/JyKsu+UdzaToaG/uhCvarw/agOscxvjSVWvbaucPBa+d9plvdXlORm7dbELo+9Z6Qjfm1MzuT2Yv7q9HZlpBtdOjFfar6Yeg2qdep6x2ni3upFT19dDj49PGy6emjMQZg6PaY9lkJ4/L0UWqlx6MNDn8g6o2g98fvPEb0eFSOB8+Eoue32Rm6OR200hn0sY0RPr+NNMD/DGf9C+u5AEeLfwBkrdN1844nCgAAAABJRU5ErkJggg==');
11
11
 
12
- #SceneHierarchy {
12
+ #SidePanel {
13
13
  background-color: #0d0d0d;
14
14
  border: 1px solid #111;
15
15
  max-height: 100%;
@@ -1,6 +1,6 @@
1
1
  @import 'theme';
2
2
  @import 'debug';
3
- @import 'sceneHierarchy';
3
+ @import 'sidePanel';
4
4
 
5
5
  .editor {
6
6
  font-family: Roboto Mono, Source Code Pro, Menlo, Courier, monospace;
@@ -0,0 +1,64 @@
1
+ // Libs
2
+ import { Component, ReactNode } from 'react';
3
+ // Models
4
+ import { debugDispatcher, ToolEvents } from '../global';
5
+ // Components
6
+ import '../scss/_sidePanel.scss';
7
+ import Accordion from './Accordion';
8
+ import ContainerObject from './ContainerObject';
9
+ import Inspector from './inspector/Inspector';
10
+ import { SidePanelState } from './types';
11
+ import RemoteThree from '@/core/remote/RemoteThree';
12
+
13
+ export default class SidePanel extends Component<SidePanelState> {
14
+ private three: RemoteThree;
15
+
16
+ constructor(props: SidePanelState) {
17
+ super(props);
18
+ this.state = {
19
+ scene: props.scene !== undefined ? props.scene : null,
20
+ };
21
+ this.three = props.three;
22
+ debugDispatcher.addEventListener(ToolEvents.SET_SCENE, this.setScene);
23
+ }
24
+
25
+ componentWillUnmount(): void {
26
+ debugDispatcher.removeEventListener(ToolEvents.SET_SCENE, this.setScene);
27
+ }
28
+
29
+ render(): ReactNode {
30
+ const hasScene = this.componentState.scene !== null;
31
+ const HierarchyName = 'Hierarchy - ' + (hasScene ? `${this.componentState.scene?.name}` : 'No Scene');
32
+ return (
33
+ <div id="SidePanel" key="SidePanel">
34
+ {(
35
+ <>
36
+ <Accordion label={HierarchyName} open={true}>
37
+ <>
38
+ {hasScene && (
39
+ <ContainerObject child={this.componentState.scene!} three={this.three} />
40
+ )}
41
+ </>
42
+ </Accordion>
43
+
44
+ <Inspector three={this.three} />
45
+ </>
46
+ )}
47
+ </div>
48
+ );
49
+ }
50
+
51
+ // Private
52
+
53
+ private setScene = (evt: any) => {
54
+ this.setState(() => ({
55
+ scene: evt.value
56
+ }));
57
+ };
58
+
59
+ // Getters / Setters
60
+
61
+ get componentState(): SidePanelState {
62
+ return this.state as SidePanelState;
63
+ }
64
+ }