| { | { | ||||
| "name": "threepipe", | "name": "threepipe", | ||||
| "version": "0.0.48", | |||||
| "version": "0.0.49", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "threepipe", | "name": "threepipe", | ||||
| "version": "0.0.48", | |||||
| "version": "0.0.49", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.158.1004/package.tgz", | "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.158.1004/package.tgz", |
| { | { | ||||
| "name": "threepipe", | "name": "threepipe", | ||||
| "version": "0.0.48", | |||||
| "version": "0.0.49", | |||||
| "description": "A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.", | "description": "A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.", | ||||
| "main": "dist/index.js", | "main": "dist/index.js", | ||||
| "module": "dist/index.mjs", | "module": "dist/index.mjs", |
| return this.pivotToBoundsCenter?.(true) // return value is the undo function | return this.pivotToBoundsCenter?.(true) // return value is the undo function | ||||
| }, | }, | ||||
| }, | }, | ||||
| { | |||||
| type: 'button', | |||||
| label: 'Delete Object', | |||||
| tags: ['context-menu'], | |||||
| value: async()=>{ | |||||
| const res = await ThreeViewer.Dialog.confirm('Delete Object: Are you sure you want to delete this object?') | |||||
| if (!res) return | |||||
| const parent = this.parent | |||||
| this.dispose(true) | |||||
| return ()=>{ // undo | |||||
| if (parent) parent.add(this) | |||||
| } | |||||
| }, | |||||
| }, | |||||
| { | { | ||||
| type: 'folder', | type: 'folder', | ||||
| label: 'Rotate model', | label: 'Rotate model', |
| return this._picker?.selectedObject as T || undefined | return this._picker?.selectedObject as T || undefined | ||||
| } | } | ||||
| setSelectedObject(object: IObject3D|undefined, focusCamera = false) { // todo: listen to object disposed | |||||
| setSelectedObject(object: IObject3D|undefined, focusCamera = false, trackUndo = true) { // todo: listen to object disposed | |||||
| const disabled = this.isDisabled() | const disabled = this.isDisabled() | ||||
| if (disabled && !object) return | if (disabled && !object) return | ||||
| if (!this._picker) return | if (!this._picker) return | ||||
| const t = this.autoFocus | const t = this.autoFocus | ||||
| this.autoFocus = false | this.autoFocus = false | ||||
| this._picker.selectedObject = object || null | |||||
| this._picker.setSelected(object || null, trackUndo) | |||||
| this.autoFocus = t | this.autoFocus = t | ||||
| if (!disabled && object && (t || focusCamera)) this.focusObject(object) | if (!disabled && object && (t || focusCamera)) this.focusObject(object) | ||||
| } | } | ||||
| s?.traverseAncestors((o) => { | s?.traverseAncestors((o) => { | ||||
| if (o === this._viewer?.scene) inScene = true | if (o === this._viewer?.scene) inScene = true | ||||
| }) | }) | ||||
| if (!inScene) this.setSelectedObject(undefined) | |||||
| if (!inScene) this.setSelectedObject(undefined, false, false) | |||||
| } | } | ||||
| protected _viewerListeners = { | protected _viewerListeners = { | ||||
| private _onObjectSelectEvent: EventListener2<'select', ISceneEventMap, IScene> = (e)=>{ | private _onObjectSelectEvent: EventListener2<'select', ISceneEventMap, IScene> = (e)=>{ | ||||
| if (e.source === PickingPlugin.PluginType) return | if (e.source === PickingPlugin.PluginType) return | ||||
| if (e.object === undefined && e.value === undefined) console.error('e.object or e.value must be set for picking, can be null to unselect') | if (e.object === undefined && e.value === undefined) console.error('e.object or e.value must be set for picking, can be null to unselect') | ||||
| else this.setSelectedObject(e.object || e.value, this.autoFocus || e.focusCamera) | |||||
| else this.setSelectedObject(e.object || e.value, this.autoFocus || e.focusCamera, true) | |||||
| } | } | ||||
| private _selectedObjectChanged: EventListener2<'selectedObjectChanged', ObjectPickerEventMap, ObjectPicker> = (e: any) => { | private _selectedObjectChanged: EventListener2<'selectedObjectChanged', ObjectPickerEventMap, ObjectPicker> = (e: any) => { |
| } | } | ||||
| set selectedObject(object) { | set selectedObject(object) { | ||||
| this._setSelected(object) | |||||
| this.setSelected(object) | |||||
| } | } | ||||
| private _setSelected(object: IObject3D|null, record = true) { | |||||
| setSelected(object: IObject3D|null, record = true) { | |||||
| if (!this._selected.length && !object || this._selected.length === 1 && this._selected[0] === object) return | if (!this._selected.length && !object || this._selected.length === 1 && this._selected[0] === object) return | ||||
| const current = [...this._selected] | const current = [...this._selected] | ||||
| this._selected = object ? Array.isArray(object) ? [...object] : [object] : [] | this._selected = object ? Array.isArray(object) ? [...object] : [object] : [] | ||||
| this.dispatchEvent({type: 'selectedObjectChanged', object: this.selectedObject}) | this.dispatchEvent({type: 'selectedObjectChanged', object: this.selectedObject}) | ||||
| record && this.undoManager?.record({ | record && this.undoManager?.record({ | ||||
| undo: () => this._setSelected(current.length ? current[0] : null, false), | |||||
| redo: () => this._setSelected(object, false), | |||||
| undo: () => this.setSelected(current.length ? current[0] : null, false), | |||||
| redo: () => this.setSelected(object, false), | |||||
| }) | }) | ||||
| } | } | ||||
| export const VERSION = '0.0.48' | |||||
| export const VERSION = '0.0.49' |