@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.
- package/dist/hermes.js +1608 -1382
- package/dist/hermes.umd.cjs +16 -16
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/core/RemoteController.ts +7 -3
- package/src/core/remote/RemoteThree.ts +24 -11
- package/src/core/types.ts +2 -1
- package/src/editor/global.ts +3 -1
- package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/CameraWindow.tsx +20 -7
- package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiView.scss +8 -0
- package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiView.tsx +286 -56
- package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiViewData.ts +7 -15
- package/src/editor/scss/{_sceneHierarchy.scss → _sidePanel.scss} +1 -1
- package/src/editor/scss/index.scss +1 -1
- package/src/editor/sidePanel/SidePanel.tsx +64 -0
- package/src/editor/sidePanel/inspector/Inspector.tsx +114 -0
- package/src/editor/{sceneHierarchy → sidePanel}/inspector/SceneInspector.tsx +16 -11
- package/src/editor/sidePanel/inspector/utils/InspectAnimation.tsx +51 -0
- package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectMaterial.tsx +1 -0
- package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectTransform.tsx +35 -46
- package/src/editor/{sceneHierarchy → sidePanel}/types.ts +10 -1
- package/src/editor/{sceneHierarchy → sidePanel}/utils.ts +11 -2
- package/src/editor/utils.ts +60 -4
- package/src/index.ts +9 -9
- package/types/core/remote/RemoteThree.d.ts +3 -2
- package/types/core/types.d.ts +1 -1
- package/types/editor/global.d.ts +2 -1
- package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/CameraWindow.d.ts +2 -0
- package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiView.d.ts +2 -4
- package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/MultiViewData.d.ts +4 -4
- package/types/editor/sidePanel/SidePanel.d.ts +11 -0
- package/types/editor/{sceneHierarchy → sidePanel}/inspector/SceneInspector.d.ts +0 -2
- package/types/editor/sidePanel/inspector/utils/InspectAnimation.d.ts +3 -0
- package/types/editor/{sceneHierarchy → sidePanel}/types.d.ts +7 -1
- package/types/editor/utils.d.ts +7 -1
- package/types/index.d.ts +9 -9
- package/src/editor/sceneHierarchy/SceneHierarchy.tsx +0 -80
- package/src/editor/sceneHierarchy/inspector/Inspector.tsx +0 -97
- package/types/editor/sceneHierarchy/SceneHierarchy.d.ts +0 -13
- /package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridHelper.ts +0 -0
- /package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridMaterial.ts +0 -0
- /package/src/editor/{sceneHierarchy/inspector/MultiView → multiView}/UVMaterial.ts +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/Accordion.tsx +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/ChildObject.tsx +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/ContainerObject.tsx +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/ToggleBtn.tsx +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/inspector/InspectorField.tsx +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/inspector/InspectorGroup.tsx +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/inspector/inspector.scss +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectCamera.tsx +0 -0
- /package/src/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectLight.tsx +0 -0
- /package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridHelper.d.ts +0 -0
- /package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/InfiniteGridMaterial.d.ts +0 -0
- /package/types/editor/{sceneHierarchy/inspector/MultiView → multiView}/UVMaterial.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/Accordion.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/ChildObject.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/ContainerObject.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/ToggleBtn.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/inspector/Inspector.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/inspector/InspectorField.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/inspector/InspectorGroup.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectCamera.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectLight.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectMaterial.d.ts +0 -0
- /package/types/editor/{sceneHierarchy → sidePanel}/inspector/utils/InspectTransform.d.ts +0 -0
- /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 {
|
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 = '
|
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
|
-
|
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
|
-
//
|
154
|
+
// Renderer
|
114
155
|
useEffect(() => {
|
115
|
-
|
116
|
-
|
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
|
-
|
119
|
-
|
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
|
122
|
-
|
123
|
-
|
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
|
-
|
129
|
-
let width =
|
130
|
-
let height =
|
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
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
182
|
-
|
183
|
-
|
256
|
+
renderer.setViewport(0, 0, bw, height);
|
257
|
+
renderer.setScissor(0, 0, bw, height);
|
258
|
+
renderer.render(scene, tlCam);
|
184
259
|
|
185
|
-
|
186
|
-
|
187
|
-
|
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
|
-
|
191
|
-
|
192
|
-
|
265
|
+
renderer.setViewport(0, y, width, bh);
|
266
|
+
renderer.setScissor(0, y, width, bh);
|
267
|
+
renderer.render(scene, tlCam);
|
193
268
|
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
-
|
208
|
-
|
209
|
-
|
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
|
-
|
214
|
-
|
215
|
-
|
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
|
-
|
222
|
-
|
223
|
-
|
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
|
-
|
228
|
-
|
229
|
-
|
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
|
-
|
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
|
-
|
271
|
-
|
272
|
-
|
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
|
-
<
|
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={
|
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 '
|
377
|
-
scene.overrideMaterial =
|
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
|
-
|
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 = '
|
44
|
+
export type RenderMode = 'Depth' | 'Normals' | 'Renderer' | 'UVs' | 'Wireframe';
|
55
45
|
export const renderOptions: RenderMode[] = [
|
56
|
-
'
|
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
|
-
#
|
12
|
+
#SidePanel {
|
13
13
|
background-color: #0d0d0d;
|
14
14
|
border: 1px solid #111;
|
15
15
|
max-height: 100%;
|
@@ -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
|
+
}
|