diff --git a/package-lock.json b/package-lock.json index ebadf24ea..0601bf9f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "web-vitals": "^2.1.2" }, "devDependencies": { - "@types/react": "^17.0.36", + "@types/react": "^17.0.37", "@types/react-async-script": "^1.2.1", "@types/three": "^0.134.0", "cross-env": "^7.0.3", @@ -4193,9 +4193,9 @@ "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" }, "node_modules/@types/react": { - "version": "17.0.36", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.36.tgz", - "integrity": "sha512-CUFUp01OdfbpN/76v4koqgcpcRGT3sYOq3U3N6q0ZVGcyeP40NUdVU+EWe3hs34RNaTefiYyBzOpxBBidCc5zw==", + "version": "17.0.37", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.37.tgz", + "integrity": "sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -26522,9 +26522,9 @@ "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" }, "@types/react": { - "version": "17.0.36", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.36.tgz", - "integrity": "sha512-CUFUp01OdfbpN/76v4koqgcpcRGT3sYOq3U3N6q0ZVGcyeP40NUdVU+EWe3hs34RNaTefiYyBzOpxBBidCc5zw==", + "version": "17.0.37", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.37.tgz", + "integrity": "sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", diff --git a/package.json b/package.json index ef104b456..07e212a29 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ ] }, "devDependencies": { - "@types/react": "^17.0.36", + "@types/react": "^17.0.37", "@types/react-async-script": "^1.2.1", "@types/three": "^0.134.0", "cross-env": "^7.0.3", diff --git a/src/ThreeEditor/css/main.css b/src/ThreeEditor/css/main.css index cb27f420b..29b5d8a0a 100644 --- a/src/ThreeEditor/css/main.css +++ b/src/ThreeEditor/css/main.css @@ -328,7 +328,7 @@ select:hover { #resizer { position: absolute; top: 32px; - right: 345px; + right: 370px; width: 5px; bottom: 0px; /* background-color: rgba(255,0,0,0.5); */ @@ -339,7 +339,7 @@ select:hover { position: absolute; top: 32px; left: 0; - right: 360px; + right: 375px; bottom: 0; } @@ -444,7 +444,7 @@ select:hover { right: 0; top: 32px; bottom: 0; - width: 360px; + width: 375px; background: #eee; overflow: auto; } @@ -759,4 +759,4 @@ select:hover { .display-none { display: none !important; -} \ No newline at end of file +} diff --git a/src/ThreeEditor/js/Editor.Context.ts b/src/ThreeEditor/js/Editor.Context.ts index 67250736b..d3d26617f 100644 --- a/src/ThreeEditor/js/Editor.Context.ts +++ b/src/ThreeEditor/js/Editor.Context.ts @@ -1,5 +1,4 @@ import * as THREE from 'three'; -import { Scene } from 'three'; import { BasicMesh, isBasicMesh } from '../util/BasicMeshes'; import { Beam, isBeam } from '../util/Beam'; import * as CSG from '../util/CSG/CSG'; @@ -101,7 +100,7 @@ export class ContextManager { this.editor.signals.contextChanged.dispatch(this._context); } } else { - this._selected = [null, isDetectGeometry(this._selected[1]) ? null : this._selected[1]]; + this._selected = [null, null]; } } diff --git a/src/ThreeEditor/js/menubar/Menubar.Add.js b/src/ThreeEditor/js/menubar/Menubar.Add.js index dc11a141f..1f6a9abc5 100644 --- a/src/ThreeEditor/js/menubar/Menubar.Add.js +++ b/src/ThreeEditor/js/menubar/Menubar.Add.js @@ -1,6 +1,5 @@ -import * as THREE from 'three'; import { BoxMesh, CylinderMesh, SphereMesh } from '../../util/BasicMeshes'; -import { AddObjectCommand, AddZoneCommand, AddDetectGeometryCommand } from '../commands/Commands'; +import { AddDetectGeometryCommand, AddObjectCommand, AddZoneCommand } from '../commands/Commands'; import { UIHorizontalRule, UIPanel } from '../libs/ui.js'; import { createOption } from './Menubar.js'; diff --git a/src/ThreeEditor/js/sidebar/Sidebar.AddPanel.js b/src/ThreeEditor/js/sidebar/Sidebar.AddPanel.js new file mode 100644 index 000000000..6c19f7703 --- /dev/null +++ b/src/ThreeEditor/js/sidebar/Sidebar.AddPanel.js @@ -0,0 +1,67 @@ +import { UIPanel, UIText, UIRow, UIButton } from '../libs/ui.js'; +import { BoxMesh, CylinderMesh, SphereMesh } from '../../util/BasicMeshes'; +import { + AddDetectGeometryCommand, + AddFilterCommand, + AddObjectCommand, + AddZoneCommand +} from '../commands/Commands'; + +function SidebarAddPanel(parent, title, names, commands) { + const container = new UIPanel(); + + // Header + const headerRow = new UIRow(); + headerRow.add(new UIText(title.toUpperCase())); + container.add(headerRow); + + // Buttons + + const btnRow = new UIRow(); + + names.forEach((name, index) => { + const button = new UIButton(name); + button.onClick(commands[index]); + btnRow.add(button); + }); + + container.add(btnRow); + parent.add(container); + + return container; +} + +export function DetectAddPanel(editor, container) { + return SidebarAddPanel( + container, + 'Add Detect', + ['Geometry', 'Filter', 'Quantity'], + [ + () => editor.execute(new AddDetectGeometryCommand(editor)), + () => editor.execute(new AddFilterCommand(editor)), + () => alert('Not implemented') + ] + ); +} + +export function FigureAddPanel(editor, container) { + return SidebarAddPanel( + container, + 'Add Figure', + ['Box', 'Cylinder', 'Sphere'], + [ + () => editor.execute(new AddObjectCommand(editor, new BoxMesh())), + () => editor.execute(new AddObjectCommand(editor, new CylinderMesh())), + () => editor.execute(new AddObjectCommand(editor, new SphereMesh())) + ] + ); +} + +export function ZoneAddPanel(editor, container) { + return SidebarAddPanel( + container, + 'Add Zone', + ['Constructive solid Zone'], + [() => editor.execute(new AddZoneCommand(editor))] + ); +} diff --git a/src/ThreeEditor/js/sidebar/Sidebar.Filters.js b/src/ThreeEditor/js/sidebar/Sidebar.Filters.js index 4559d19f5..5844d238f 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.Filters.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.Filters.js @@ -1,34 +1,22 @@ import { AddFilterCommand } from '../commands/Commands'; import { UIButton, UIPanel, UIRow } from '../libs/ui'; import { OutlinerManager } from './Sidebar.OutlinerManager'; +import { DetectAddPanel } from './Sidebar.AddPanel'; export class SidebarFilters extends UIPanel { editor; signals; detectManager; + detectAddPanel; outlinerManager; - createButton() { - const panel = new UIPanel(); - const row = new UIRow(); - const add_button = new UIButton("Add Detect Filter"); - - add_button.onClick(() => { - this.editor.execute(new AddFilterCommand(this.editor)); - }); - - row.add(add_button); - panel.add(row); - this.add(panel); - } - refreshOptions() { const sources = [ this.editor.detectManager.detectContainer, this.editor.detectManager.filterContainer ]; this.outlinerManager.setOptionsFromSources(sources); - }; + } constructor(editor) { super(); @@ -39,16 +27,12 @@ export class SidebarFilters extends UIPanel { this.outlinerManager = new OutlinerManager(editor, this); this.outlinerManager.id = 'filter-outliner'; - this.signals.editorCleared.add(this.refreshOptions.bind(this)); + this.detectAddPanel = DetectAddPanel(editor, this); + this.signals.editorCleared.add(this.refreshOptions.bind(this)); this.signals.sceneGraphChanged.add(this.refreshOptions.bind(this)); - this.signals.objectChanged.add(this.refreshOptions.bind(this)); - this.signals.detectFilterAdded.add(this.refreshOptions.bind(this)); - this.signals.detectFilterRemoved.add(this.refreshOptions.bind(this)); - - this.createButton(); } } diff --git a/src/ThreeEditor/js/sidebar/Sidebar.Geometry.js b/src/ThreeEditor/js/sidebar/Sidebar.Geometry.js index 97480c9f7..97eafc7be 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.Geometry.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.Geometry.js @@ -120,12 +120,13 @@ function SidebarGeometry(editor) { container.setDisplay('none'); } } - - signals.objectSelected.add(() => { + const handleSelected = () => { currentGeometryType = null; vertexNormalsButton.setDisplay('block'); build(); - }); + }; + signals.objectSelected.add(handleSelected); + signals.dataObjectSelected.add(handleSelected); signals.geometryChanged.add(build); diff --git a/src/ThreeEditor/js/sidebar/Sidebar.Material.js b/src/ThreeEditor/js/sidebar/Sidebar.Material.js index 76b7b8ccd..3c25d47ca 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.Material.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.Material.js @@ -603,7 +603,7 @@ function SidebarMaterial(editor) { // events - signals.objectSelected.add(object => { + const handleSelected = object => { let hasMaterial = false; if (object && object.material) { @@ -622,7 +622,10 @@ function SidebarMaterial(editor) { currentObject = null; container.setDisplay('none'); } - }); + }; + + signals.objectSelected.add(handleSelected); + signals.dataObjectSelected.add(handleSelected); signals.materialChanged.add(refreshUI); diff --git a/src/ThreeEditor/js/sidebar/Sidebar.Object.js b/src/ThreeEditor/js/sidebar/Sidebar.Object.js index cacd06e35..da9b98fc3 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.Object.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.Object.js @@ -778,18 +778,30 @@ function SidebarObject(editor) { } // events - - signals.objectSelected.add(object => { + const handleSelected = object => { const showObjectInfo = () => { container.setDisplay('block'); updateRows(object); updateUI(object); }; + const objectNotApplicable = object => { + return ( + object.isZoneContainer || + object.isDetectContainer || + object.isFilterContainer || + object.isScene || + object.isFilter || + object.isQuantity || + object.isQuantityContainer + ); + }; const hideObjectInfo = () => container.setDisplay('none'); - (object && !object.isZoneContainer && !object.isScene ? showObjectInfo : hideObjectInfo)(); - }); + (object && !objectNotApplicable(object) ? showObjectInfo : hideObjectInfo)(); + }; + signals.objectSelected.add(handleSelected); + signals.dataObjectSelected.add(handleSelected); signals.objectChanged.add(updateUI); diff --git a/src/ThreeEditor/js/sidebar/Sidebar.OutlinerManager.js b/src/ThreeEditor/js/sidebar/Sidebar.OutlinerManager.js index b58e583cd..544299e73 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.OutlinerManager.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.OutlinerManager.js @@ -31,11 +31,11 @@ const getObjectType = object => { case 'SphereMesh': return 'Figure'; case 'Points': - case 'Detect': return 'Detect'; case 'Filter': return 'Filter'; default: + console.warn(`could not parse object of type ${object.type}`, typeof object, object); return 'Unknown'; } }; diff --git a/src/ThreeEditor/js/sidebar/Sidebar.Properties.js b/src/ThreeEditor/js/sidebar/Sidebar.Properties.js index ac797dab3..9fa6a0bc0 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.Properties.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.Properties.js @@ -5,7 +5,7 @@ import { SidebarGeometry } from './Sidebar.Geometry.js'; import { SidebarMaterial } from './Sidebar.Material.js'; import { SidebarZoneMaterial } from './Sidebar.Material.ZoneMaterial.js'; -function SidebarProperties(editor) { +function SidebarProperties(editor, id = 'properties') { const { strings, signals } = editor; const container = new UITabbedPanel(); @@ -19,7 +19,7 @@ function SidebarProperties(editor) { return new UIPanel(); } - container.setId('properties'); + container.setId(id); container.addTab( 'object', @@ -31,16 +31,20 @@ function SidebarProperties(editor) { strings.getKey('sidebar/properties/geometry'), new SidebarGeometry(editor) ); - container.addTab('material', strings.getKey('sidebar/properties/material'), material); + container.addTab( + 'material', + strings.getKey('sidebar/properties/material'), + getPanel(editor.selected) + ); container.select('object'); - //Select Geometry if zone is created - signals.objectAdded.add(object => object?.isZone && container.select('geometry')); - - signals.objectSelected.add(object => { + const handleSelected = object => { container.panels[2].clear(); container.panels[2].add(getPanel(object)); - }); + }; + + signals.objectSelected.add(handleSelected); + signals.dataObjectSelected.add(handleSelected); return container; } diff --git a/src/ThreeEditor/js/sidebar/Sidebar.Scene.js b/src/ThreeEditor/js/sidebar/Sidebar.Scene.js index 86f076267..a36757c1b 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.Scene.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.Scene.js @@ -1,12 +1,9 @@ -import * as THREE from 'three'; -import { UIBreak, UIColor, UIPanel, UIRow, UISelect, UIText } from '../libs/ui.js'; -import { UITexture } from '../libs/ui.three.js'; +import { UIBreak, UIPanel } from '../libs/ui.js'; import { OutlinerManager } from './Sidebar.OutlinerManager'; - - +import { FigureAddPanel, ZoneAddPanel } from './Sidebar.AddPanel'; function SidebarScene(editor) { - const { signals, strings } = editor; + const { signals } = editor; const container = new UIPanel(); container.setBorderTop('0'); @@ -27,141 +24,14 @@ function SidebarScene(editor) { container.add(new UIBreak()); - // background - - const backgroundRow = new UIRow(); - - const backgroundType = new UISelect() - .setOptions({ - None: '', - Color: 'Color', - Texture: 'Texture', - Equirectangular: 'Equirect' - }) - .setWidth('160px'); - backgroundType.onChange(() => { - onBackgroundChanged(); - refreshBackgroundUI(); - }); - - backgroundRow.add(new UIText(strings.getKey('sidebar/scene/background')).setWidth('90px')); - backgroundRow.add(backgroundType); - - const backgroundColor = new UIColor() - .setValue('#000000') - .setMarginLeft('8px') - .onInput(onBackgroundChanged); - backgroundRow.add(backgroundColor); - - const backgroundTexture = new UITexture().setMarginLeft('8px').onChange(onBackgroundChanged); - backgroundTexture.setDisplay('none'); - backgroundRow.add(backgroundTexture); - - const backgroundEquirectangularTexture = new UITexture() - .setMarginLeft('8px') - .onChange(onBackgroundChanged); - backgroundEquirectangularTexture.setDisplay('none'); - backgroundRow.add(backgroundEquirectangularTexture); - - container.add(backgroundRow); - - function onBackgroundChanged() { - signals.sceneBackgroundChanged.dispatch( - backgroundType.getValue(), - backgroundColor.getHexValue(), - backgroundTexture.getValue(), - backgroundEquirectangularTexture.getValue() - ); - } - - function refreshBackgroundUI() { - const type = backgroundType.getValue(); - - backgroundType.setWidth(type === 'None' ? '160px' : '110px'); - backgroundColor.setDisplay(type === 'Color' ? '' : 'none'); - backgroundTexture.setDisplay(type === 'Texture' ? '' : 'none'); - backgroundEquirectangularTexture.setDisplay(type === 'Equirectangular' ? '' : 'none'); - } - - // environment - - const environmentRow = new UIRow(); - - const environmentType = new UISelect() - .setOptions({ - None: '', - Equirectangular: 'Equirect', - ModelViewer: 'ModelViewer' - }) - .setWidth('160px'); - environmentType.setValue('None'); - environmentType.onChange(() => { - onEnvironmentChanged(); - refreshEnvironmentUI(); - }); - - environmentRow.add(new UIText(strings.getKey('sidebar/scene/environment')).setWidth('90px')); - environmentRow.add(environmentType); - - const environmentEquirectangularTexture = new UITexture() - .setMarginLeft('8px') - .onChange(onEnvironmentChanged); - environmentEquirectangularTexture.setDisplay('none'); - environmentRow.add(environmentEquirectangularTexture); - - container.add(environmentRow); - - function onEnvironmentChanged() { - signals.sceneEnvironmentChanged.dispatch( - environmentType.getValue(), - environmentEquirectangularTexture.getValue() - ); - } - - function refreshEnvironmentUI() { - const type = environmentType.getValue(); + const figureAddPanel = FigureAddPanel(editor, container); - environmentType.setWidth(type !== 'Equirectangular' ? '160px' : '110px'); - environmentEquirectangularTexture.setDisplay(type === 'Equirectangular' ? '' : 'none'); - } + const sceneAddPanel = ZoneAddPanel(editor, container); // function refreshUI() { - const { camera, scene } = editor; - const { detectContainer } = editor.detectManager; - const { zoneContainer, worldZone } = editor.zoneManager; - refreshOptions(); - - if (scene.background) { - if (scene.background.isColor) { - backgroundType.setValue('Color'); - backgroundColor.setHexValue(scene.background.getHex()); - } else if (scene.background.isTexture) { - if (scene.background.mapping === THREE.EquirectangularReflectionMapping) { - backgroundType.setValue('Equirectangular'); - backgroundEquirectangularTexture.setValue(scene.background); - } else { - backgroundType.setValue('Texture'); - backgroundTexture.setValue(scene.background); - } - } - } else { - backgroundType.setValue('None'); - } - - if (scene.environment) { - if (scene.environment.mapping === THREE.EquirectangularReflectionMapping) { - environmentType.setValue('Equirectangular'); - environmentEquirectangularTexture.setValue(scene.environment); - } - } else { - environmentType.setValue('None'); - } - - refreshBackgroundUI(); - refreshEnvironmentUI(); } refreshUI(); @@ -174,9 +44,7 @@ function SidebarScene(editor) { signals.objectChanged.add(refreshUI); - return container; } export { SidebarScene }; - diff --git a/src/ThreeEditor/js/sidebar/Sidebar.Settings.js b/src/ThreeEditor/js/sidebar/Sidebar.Settings.js index 006610de7..82c12c77b 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.Settings.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.Settings.js @@ -1,12 +1,12 @@ -import { UIPanel, UIRow, UISelect, UISpan, UIText } from '../libs/ui.js'; - -import { SidebarSettingsViewport } from './Sidebar.Settings.Viewport.js'; -import { SidebarSettingsShortcuts } from './Sidebar.Settings.Shortcuts.js'; +import * as THREE from 'three'; +import { UIColor, UIPanel, UIRow, UISelect, UISpan, UIText } from '../libs/ui.js'; +import { UITexture } from '../libs/ui.three.js'; import { SidebarSettingsHistory } from './Sidebar.Settings.History.js'; +import { SidebarSettingsShortcuts } from './Sidebar.Settings.Shortcuts.js'; +import { SidebarSettingsViewport } from './Sidebar.Settings.Viewport.js'; function SidebarSettings(editor) { - const config = editor.config; - const strings = editor.strings; + const { signals, strings, config, scene } = editor; const container = new UISpan(); @@ -15,6 +15,103 @@ function SidebarSettings(editor) { settings.setPaddingTop('20px'); container.add(settings); + // background + + const backgroundRow = new UIRow(); + + const backgroundType = new UISelect() + .setOptions({ + None: '', + Color: 'Color', + Texture: 'Texture', + Equirectangular: 'Equirect' + }) + .setWidth('160px'); + backgroundType.onChange(() => { + onBackgroundChanged(); + refreshBackgroundUI(); + }); + + backgroundRow.add(new UIText(strings.getKey('sidebar/scene/background')).setWidth('90px')); + backgroundRow.add(backgroundType); + + const backgroundColor = new UIColor() + .setValue('#000000') + .setMarginLeft('8px') + .onInput(onBackgroundChanged); + backgroundRow.add(backgroundColor); + + const backgroundTexture = new UITexture().setMarginLeft('8px').onChange(onBackgroundChanged); + backgroundTexture.setDisplay('none'); + backgroundRow.add(backgroundTexture); + + const backgroundEquirectangularTexture = new UITexture() + .setMarginLeft('8px') + .onChange(onBackgroundChanged); + backgroundEquirectangularTexture.setDisplay('none'); + backgroundRow.add(backgroundEquirectangularTexture); + + settings.add(backgroundRow); + + function onBackgroundChanged() { + signals.sceneBackgroundChanged.dispatch( + backgroundType.getValue(), + backgroundColor.getHexValue(), + backgroundTexture.getValue(), + backgroundEquirectangularTexture.getValue() + ); + } + + function refreshBackgroundUI() { + const type = backgroundType.getValue(); + + backgroundType.setWidth(type === 'None' ? '160px' : '110px'); + backgroundColor.setDisplay(type === 'Color' ? '' : 'none'); + backgroundTexture.setDisplay(type === 'Texture' ? '' : 'none'); + backgroundEquirectangularTexture.setDisplay(type === 'Equirectangular' ? '' : 'none'); + } + + // environment + + const environmentRow = new UIRow(); + + const environmentType = new UISelect() + .setOptions({ + None: '', + Equirectangular: 'Equirect', + ModelViewer: 'ModelViewer' + }) + .setWidth('160px'); + environmentType.setValue('None'); + environmentType.onChange(() => { + onEnvironmentChanged(); + refreshEnvironmentUI(); + }); + + environmentRow.add(new UIText(strings.getKey('sidebar/scene/environment')).setWidth('90px')); + environmentRow.add(environmentType); + + const environmentEquirectangularTexture = new UITexture() + .setMarginLeft('8px') + .onChange(onEnvironmentChanged); + environmentEquirectangularTexture.setDisplay('none'); + environmentRow.add(environmentEquirectangularTexture); + + settings.add(environmentRow); + + function onEnvironmentChanged() { + signals.sceneEnvironmentChanged.dispatch( + environmentType.getValue(), + environmentEquirectangularTexture.getValue() + ); + } + + function refreshEnvironmentUI() { + const type = environmentType.getValue(); + + environmentType.setWidth(type !== 'Equirectangular' ? '160px' : '110px'); + environmentEquirectangularTexture.setDisplay(type === 'Equirectangular' ? '' : 'none'); + } // language const options = { @@ -48,6 +145,49 @@ function SidebarSettings(editor) { container.add(new SidebarSettingsShortcuts(editor)); container.add(new SidebarSettingsHistory(editor)); + // + + function refreshUI() { + if (scene.background) { + if (scene.background.isColor) { + backgroundType.setValue('Color'); + backgroundColor.setHexValue(scene.background.getHex()); + } else if (scene.background.isTexture) { + if (scene.background.mapping === THREE.EquirectangularReflectionMapping) { + backgroundType.setValue('Equirectangular'); + backgroundEquirectangularTexture.setValue(scene.background); + } else { + backgroundType.setValue('Texture'); + backgroundTexture.setValue(scene.background); + } + } + } else { + backgroundType.setValue('None'); + } + + if (scene.environment) { + if (scene.environment.mapping === THREE.EquirectangularReflectionMapping) { + environmentType.setValue('Equirectangular'); + environmentEquirectangularTexture.setValue(scene.environment); + } + } else { + environmentType.setValue('None'); + } + + refreshBackgroundUI(); + refreshEnvironmentUI(); + } + + refreshUI(); + + // events + + signals.editorCleared.add(refreshUI); + + signals.sceneGraphChanged.add(refreshUI); + + signals.objectChanged.add(refreshUI); + return container; } diff --git a/src/ThreeEditor/js/sidebar/Sidebar.js b/src/ThreeEditor/js/sidebar/Sidebar.js index 6a74f4c54..14d9f7bb1 100644 --- a/src/ThreeEditor/js/sidebar/Sidebar.js +++ b/src/ThreeEditor/js/sidebar/Sidebar.js @@ -11,15 +11,16 @@ function Sidebar(editor) { const container = new UITabbedPanel(); container.setId('sidebar'); + const filters = new SidebarFilters(editor).setBorderTop('0').setPaddingTop('20px'); const scene = new UISpan().add(new SidebarScene(editor), new SidebarProperties(editor)); const project = new SidebarProject(editor); const settings = new SidebarSettings(editor); - const filters = new SidebarFilters(editor).setBorderTop('0').setPaddingTop('20px'); + const output = new UISpan().add(filters, new SidebarProperties(editor)); let ignoreContextChangedSignal = false; container.addTab('scene', strings.getKey('sidebar/scene'), scene); - container.addTab('output', 'OUTPUT', filters); + container.addTab('output', 'OUTPUT', output); container.addTab('parameters', 'PARAMETERS', project); container.addTab('settings', strings.getKey('sidebar/settings'), settings); @@ -30,10 +31,10 @@ function Sidebar(editor) { ignoreContextChangedSignal = true; editor.contextManager.currentContext = id; ignoreContextChangedSignal = false; - } + }; container.select('scene'); - signals.contextChanged.add((id) => { + signals.contextChanged.add(id => { ignoreContextChangedSignal || container._select(id); }); diff --git a/src/ThreeEditor/util/BasicMeshes.ts b/src/ThreeEditor/util/BasicMeshes.ts index d522b872a..6c2e4d5ef 100644 --- a/src/ThreeEditor/util/BasicMeshes.ts +++ b/src/ThreeEditor/util/BasicMeshes.ts @@ -1,7 +1,6 @@ import * as THREE from 'three'; import { Editor } from '../js/Editor'; import { SimulationMesh } from './SimulationBase/SimulationMesh'; -import { ISimulationObject } from './SimulationBase/SimulationObject'; const defaultMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, diff --git a/src/ThreeEditor/util/Beam.ts b/src/ThreeEditor/util/Beam.ts index 48e9dc6a3..affd099df 100644 --- a/src/ThreeEditor/util/Beam.ts +++ b/src/ThreeEditor/util/Beam.ts @@ -1,12 +1,11 @@ import * as THREE from 'three'; import { Euler, Vector3 } from 'three'; -import { debounce } from 'throttle-debounce'; -import { Editor } from '../js/Editor'; // Import of 'lines' from examples subfolder follows the official guidelines of threejs.editor (see https://threejs.org/docs/#manual/en/introduction/Installation) import { Line2 } from 'three/examples/jsm/lines/Line2.js'; -import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'; import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'; -import { ISimulationObject } from './SimulationBase/SimulationObject'; +import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'; +import { debounce } from 'throttle-debounce'; +import { Editor } from '../js/Editor'; import { SimulationMesh } from './SimulationBase/SimulationMesh'; export interface BeamJSON { diff --git a/src/ThreeEditor/util/Detect/DetectFilter.ts b/src/ThreeEditor/util/Detect/DetectFilter.ts index 0063ac09f..e7feefcb5 100644 --- a/src/ThreeEditor/util/Detect/DetectFilter.ts +++ b/src/ThreeEditor/util/Detect/DetectFilter.ts @@ -1,4 +1,3 @@ -import { MathUtils } from 'three'; import { Editor } from '../../js/Editor'; import { SimulationData } from '../SimulationBase/SimulationMesh'; import { diff --git a/src/ThreeEditor/util/Detect/DetectGeometry.ts b/src/ThreeEditor/util/Detect/DetectGeometry.ts index 39305be36..b908ba586 100644 --- a/src/ThreeEditor/util/Detect/DetectGeometry.ts +++ b/src/ThreeEditor/util/Detect/DetectGeometry.ts @@ -2,8 +2,7 @@ import { Signal } from 'signals'; import * as THREE from 'three'; import { Editor } from '../../js/Editor'; import * as CSG from '../CSG/CSG'; -import { SimulationMesh, SimulationPoints } from '../SimulationBase/SimulationMesh'; -import { ISimulationObject } from '../SimulationBase/SimulationObject'; +import { SimulationPoints } from '../SimulationBase/SimulationMesh'; import { DetectManager } from './DetectManager'; import * as DETECT from './DetectTypes'; @@ -91,9 +90,6 @@ export class DetectGeometry extends SimulationPoints { get: (target: DetectGeometry, p: keyof DetectGeometry) => { let result: unknown; switch (p) { - case 'type': - result = `${target.detectType}Section`; - break; case 'position': result = this.positionProxy; break; @@ -179,7 +175,9 @@ export class DetectGeometry extends SimulationPoints { this.positionProxy = new Proxy(this.position, { get: (target: THREE.Vector3, p: keyof THREE.Vector3) => { const scope = this; - const parent: DetectManager = this.parent!.parent as DetectManager; + const parent: DetectManager | undefined = this.parent?.parent as + | DetectManager + | undefined; switch (p) { case 'copy': return function (v: THREE.Vector3) { @@ -187,11 +185,13 @@ export class DetectGeometry extends SimulationPoints { return scope.positionProxy; }; case 'add': - return function (v: THREE.Vector3) { - const nV = target[p].apply(target, [v]); - parent.detectHelper.position.copy(nV); - return nV; - }; + if (parent) + return function (v: THREE.Vector3) { + const nV = target[p].apply(target, [v]); + parent.detectHelper.position.copy(nV); + return nV; + }; + return Reflect.get(target, p); default: return Reflect.get(target, p); } diff --git a/src/ThreeEditor/util/Detect/DetectManager.ts b/src/ThreeEditor/util/Detect/DetectManager.ts index 05fcd4dbc..46f9fad4d 100644 --- a/src/ThreeEditor/util/Detect/DetectManager.ts +++ b/src/ThreeEditor/util/Detect/DetectManager.ts @@ -28,7 +28,7 @@ export class DetectContainer extends SimulationSceneGroup { } reset() { - this.name = 'Geometries'; + this.name = 'Detects'; this.clear(); } } @@ -49,6 +49,7 @@ export class FilterContainer extends SimulationDataGroup { reset() { this.name = 'Filters'; this.clear(); + console.log(this); } } @@ -195,18 +196,11 @@ export class DetectManager extends THREE.Scene implements ISimulationObject { this.environment = null; this.detectContainer.reset(); - this.clear(); + this.filterContainer.reset(); this.detectHelper.geometry.dispose(); } - clear(): this { - this.filters.forEach(filter => { - this.removeFilter(filter); - }); - return this; - } - clone(recursive: boolean) { return new DetectManager(this.editor).copy(this, recursive) as this; } diff --git a/src/ThreeEditor/util/Detect/DetectOutput.ts b/src/ThreeEditor/util/Detect/DetectOutput.ts index e904d701c..f4c9d7dde 100644 --- a/src/ThreeEditor/util/Detect/DetectOutput.ts +++ b/src/ThreeEditor/util/Detect/DetectOutput.ts @@ -1,3 +1,9 @@ -export class DetectOutput {} +import { SimulationData } from '../SimulationBase/SimulationMesh'; + +export class DetectOutput extends SimulationData { + toJSON(): unknown { + throw new Error('Method not implemented.'); + } +} export const isDetectOutput = (x: any): x is DetectOutput => x instanceof DetectOutput; diff --git a/src/ThreeEditor/util/WorldZone.ts b/src/ThreeEditor/util/WorldZone.ts index c1a8be935..f0835b029 100644 --- a/src/ThreeEditor/util/WorldZone.ts +++ b/src/ThreeEditor/util/WorldZone.ts @@ -234,6 +234,8 @@ export class WorldZone extends SimulationObject3D { reset({ color = 0xff0000, name = 'World Zone' } = {}): void { this._material.color.set(color); this.name = name; + this.simulationMaterial = + this.editor.materialsManager.materials['AIR, DRY (NEAR SEA LEVEL)']; this.geometryType = 'box'; this.updateBox(box => box.setFromCenterAndSize(new Vector3(), new Vector3())); }