| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.153.1006/package.tgz", | "three": "https://github.com/repalash/three.js-modded/releases/download/v0.153.1006/package.tgz", | ||||
| "tslib": "^2.5.0", | "tslib": "^2.5.0", | ||||
| "typedoc": "^0.27.5", | "typedoc": "^0.27.5", | ||||
| "typescript": "^5.7.2", | |||||
| "typescript": "5.7.2", | |||||
| "typescript-plugin-css-modules": "^5.0.1", | "typescript-plugin-css-modules": "^5.0.1", | ||||
| "vite": "^6.0.5", | "vite": "^6.0.5", | ||||
| "vite-plugin-dts": "^4.4.0", | "vite-plugin-dts": "^4.4.0", | ||||
| "@types/webxr": "^0.5.1", | "@types/webxr": "^0.5.1", | ||||
| "@types/wicg-file-system-access": "^2020.9.5", | "@types/wicg-file-system-access": "^2020.9.5", | ||||
| "stats.js": "^0.17.0", | "stats.js": "^0.17.0", | ||||
| "ts-browser-helpers": "^0.15.0", | |||||
| "uiconfig.js": "^0.0.12" | |||||
| "ts-browser-helpers": "^0.16.0", | |||||
| "uiconfig.js": "^0.1.1" | |||||
| }, | }, | ||||
| "//": { | "//": { | ||||
| "dependencies": { | "dependencies": { | ||||
| "uiconfig.js": "^0.0.12", | |||||
| "ts-browser-helpers": "^0.14.2", | |||||
| "uiconfig.js": "^0.1.1", | |||||
| "ts-browser-helpers": "^0.16.0", | |||||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.153.1006/package.tgz", | "three": "https://github.com/repalash/three.js-modded/releases/download/v0.153.1006/package.tgz", | ||||
| "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.153.1006.tar.gz", | "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.153.1006.tar.gz", | ||||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.153.1002/package.tgz", | "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.153.1002/package.tgz", |
| { | { | ||||
| "name": "@threepipe/plugin-tweakpane-editor", | "name": "@threepipe/plugin-tweakpane-editor", | ||||
| "version": "0.3.0", | |||||
| "version": "0.3.2", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-tweakpane-editor", | "name": "@threepipe/plugin-tweakpane-editor", | ||||
| "version": "0.3.0", | |||||
| "version": "0.3.2", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "@threepipe/plugin-tweakpane": "file:./../tweakpane/src/", | "@threepipe/plugin-tweakpane": "file:./../tweakpane/src/", |
| { | { | ||||
| "name": "@threepipe/plugin-tweakpane-editor", | "name": "@threepipe/plugin-tweakpane-editor", | ||||
| "description": "Tweakpane Editor Plugin for ThreePipe", | "description": "Tweakpane Editor Plugin for ThreePipe", | ||||
| "version": "0.3.1", | |||||
| "version": "0.3.2", | |||||
| "devDependencies": { | "devDependencies": { | ||||
| "tippy.js": "^6.3.7", | "tippy.js": "^6.3.7", | ||||
| "treejs": "git://github.com/repalash/treejs.git#d303016bb74e75725d13e97291ac1d4727985918" | "treejs": "git://github.com/repalash/treejs.git#d303016bb74e75725d13e97291ac1d4727985918" | ||||
| }, | }, | ||||
| "exports": { | "exports": { | ||||
| ".": { | ".": { | ||||
| "types": "./dist/index.d.ts", | |||||
| "import": "./dist/index.mjs", | "import": "./dist/index.mjs", | ||||
| "require": "./dist/index.js" | "require": "./dist/index.js" | ||||
| }, | }, |
| cursor: pointer; | cursor: pointer; | ||||
| box-shadow: 0 2px 4px var(--tp-base-shadow-color); | box-shadow: 0 2px 4px var(--tp-base-shadow-color); | ||||
| transition: all 0.25s; | transition: all 0.25s; | ||||
| box-sizing: content-box !important; | |||||
| } | } | ||||
| .round-button:hover{ | .round-button:hover{ | ||||
| color: white; | color: white; | ||||
| width: auto; | width: auto; | ||||
| height: 1.2rem; | height: 1.2rem; | ||||
| aspect-ratio: 1; | aspect-ratio: 1; | ||||
| box-sizing: content-box !important; | |||||
| } | } | ||||
| .mode-buttons-container{ | .mode-buttons-container{ |
| { | { | ||||
| "name": "@threepipe/plugin-tweakpane", | "name": "@threepipe/plugin-tweakpane", | ||||
| "version": "0.4.1", | |||||
| "version": "0.5.0", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-tweakpane", | "name": "@threepipe/plugin-tweakpane", | ||||
| "version": "0.4.1", | |||||
| "version": "0.5.0", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" | ||||
| }, | }, | ||||
| "devDependencies": { | "devDependencies": { | ||||
| "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | ||||
| "uiconfig-tweakpane": "^0.0.8" | |||||
| "uiconfig-tweakpane": "^0.0.10" | |||||
| } | } | ||||
| }, | }, | ||||
| "../../src": {}, | |||||
| "node_modules/@tweakpane/core": { | |||||
| "version": "1.1.8", | |||||
| "resolved": "https://registry.npmjs.org/@tweakpane/core/-/core-1.1.8.tgz", | |||||
| "integrity": "sha512-psvBf6Cbm3YSZOTmDFWkcGzHYMnw7gVZM3jw+TfbzErIC+sMXPQb85h4ayW04w2u7AGg8jD0gHXSCg5wd+rafg==", | |||||
| "dev": true | |||||
| "../../../uiconfig-react/packages/uiconfig-tweakpane": { | |||||
| "version": "0.0.0", | |||||
| "extraneous": true, | |||||
| "devDependencies": { | |||||
| "typescript": "~5.6.2", | |||||
| "vite": "^6.0.3" | |||||
| } | |||||
| }, | }, | ||||
| "../../src": {}, | |||||
| "node_modules/@tweenjs/tween.js": { | "node_modules/@tweenjs/tween.js": { | ||||
| "version": "18.6.4", | "version": "18.6.4", | ||||
| "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", | "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", | ||||
| "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==", | "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==", | ||||
| "dev": true | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| }, | }, | ||||
| "node_modules/@types/stats.js": { | "node_modules/@types/stats.js": { | ||||
| "version": "0.17.3", | "version": "0.17.3", | ||||
| "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", | "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", | ||||
| "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", | "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", | ||||
| "dev": true | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| }, | }, | ||||
| "node_modules/@types/three": { | "node_modules/@types/three": { | ||||
| "version": "0.152.1", | "version": "0.152.1", | ||||
| "resolved": "https://registry.npmjs.org/@types/three/-/three-0.152.1.tgz", | "resolved": "https://registry.npmjs.org/@types/three/-/three-0.152.1.tgz", | ||||
| "integrity": "sha512-PMOCQnx9JRmq+2OUGTPoY9h1hTWD2L7/nmuW/SyNq1Vbq3Lwt3MNdl3wYSa4DvLTGv62NmIXD9jYdAOwohwJyw==", | "integrity": "sha512-PMOCQnx9JRmq+2OUGTPoY9h1hTWD2L7/nmuW/SyNq1Vbq3Lwt3MNdl3wYSa4DvLTGv62NmIXD9jYdAOwohwJyw==", | ||||
| "dev": true, | "dev": true, | ||||
| "license": "MIT", | |||||
| "dependencies": { | "dependencies": { | ||||
| "@tweenjs/tween.js": "~18.6.4", | "@tweenjs/tween.js": "~18.6.4", | ||||
| "@types/stats.js": "*", | "@types/stats.js": "*", | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/@types/webxr": { | "node_modules/@types/webxr": { | ||||
| "version": "0.5.12", | |||||
| "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.12.tgz", | |||||
| "integrity": "sha512-+6LV7bN17XUWy4wIMILsGQX6ucawf64lYLG9jaGKSvOnKaJzWjcKXAkO0dZaC8MfoEqYQC7gl1GQnfITjBcazw==", | |||||
| "dev": true | |||||
| "version": "0.5.20", | |||||
| "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.20.tgz", | |||||
| "integrity": "sha512-JGpU6qiIJQKUuVSKx1GtQnHJGxRjtfGIhzO2ilq43VZZS//f1h1Sgexbdk+Lq+7569a6EYhOWrUpIruR/1Enmg==", | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| }, | }, | ||||
| "node_modules/fflate": { | "node_modules/fflate": { | ||||
| "version": "0.6.10", | "version": "0.6.10", | ||||
| "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", | "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", | ||||
| "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", | "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", | ||||
| "dev": true | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| }, | }, | ||||
| "node_modules/lil-gui": { | "node_modules/lil-gui": { | ||||
| "version": "0.17.0", | "version": "0.17.0", | ||||
| "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.17.0.tgz", | "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.17.0.tgz", | ||||
| "integrity": "sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==", | "integrity": "sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==", | ||||
| "dev": true | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| }, | }, | ||||
| "node_modules/threepipe": { | "node_modules/threepipe": { | ||||
| "resolved": "../../src", | "resolved": "../../src", | ||||
| "@tweakpane/core": "1.1.8" | "@tweakpane/core": "1.1.8" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/tweakpane-image-plugin/node_modules/@tweakpane/core": { | |||||
| "version": "1.1.8", | |||||
| "resolved": "https://registry.npmjs.org/@tweakpane/core/-/core-1.1.8.tgz", | |||||
| "integrity": "sha512-psvBf6Cbm3YSZOTmDFWkcGzHYMnw7gVZM3jw+TfbzErIC+sMXPQb85h4ayW04w2u7AGg8jD0gHXSCg5wd+rafg==", | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| }, | |||||
| "node_modules/uiconfig-tweakpane": { | "node_modules/uiconfig-tweakpane": { | ||||
| "version": "0.0.8", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig-tweakpane/-/uiconfig-tweakpane-0.0.8.tgz", | |||||
| "integrity": "sha512-BZE/+6pW7qlywu4nhMjvzJ47IUORWn8rJsPpmcGqJgAz8G6MZjMXEW3Ey8EL41cVsDf5QSb0E/eTK8OWwuRfbA==", | |||||
| "version": "0.0.10", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig-tweakpane/-/uiconfig-tweakpane-0.0.10.tgz", | |||||
| "integrity": "sha512-VF67oUg7M9EXKR3IO+TXS6jP28qfT1ci/C4Inu8CjruJk8qBfUjuxKBU5kLXH97rE5dM0xLvLg/rYxRlpJ8mog==", | |||||
| "dev": true, | "dev": true, | ||||
| "license": "MIT", | |||||
| "dependencies": { | "dependencies": { | ||||
| "@types/three": "^0.152.1", | "@types/three": "^0.152.1", | ||||
| "uiconfig.js": "^0.0.8" | |||||
| "uiconfig.js": "^0.1.1" | |||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/uiconfig.js": { | "node_modules/uiconfig.js": { | ||||
| "version": "0.0.8", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig.js/-/uiconfig.js-0.0.8.tgz", | |||||
| "integrity": "sha512-0H1OO4CNHP5O0LBy82YWWFCzDK+Yf/GtXnR3i968FkMkf0+3/JsW7MC8ea2CcPtsi8ni4TA1FrMOC+KrYmMnCQ==", | |||||
| "dev": true | |||||
| "version": "0.1.1", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig.js/-/uiconfig.js-0.1.1.tgz", | |||||
| "integrity": "sha512-JzJyAgtFOfWVg964mmKKByULnhg4d5QpfsvXzj0T/Mncs1pK3/FACM+pAteLmT1xDeVDwwIU5s86UzlTiYwR/A==", | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| { | { | ||||
| "name": "@threepipe/plugin-tweakpane", | "name": "@threepipe/plugin-tweakpane", | ||||
| "description": "Tweakpane UI Plugin for ThreePipe", | "description": "Tweakpane UI Plugin for ThreePipe", | ||||
| "version": "0.4.2", | |||||
| "version": "0.5.0", | |||||
| "devDependencies": { | "devDependencies": { | ||||
| "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | ||||
| "uiconfig-tweakpane": "^0.0.8" | |||||
| "uiconfig-tweakpane": "^0.0.10" | |||||
| }, | }, | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" | ||||
| }, | }, | ||||
| "exports": { | "exports": { | ||||
| ".": { | ".": { | ||||
| "types": "./dist/index.d.ts", | |||||
| "import": "./dist/index.mjs", | "import": "./dist/index.mjs", | ||||
| "require": "./dist/index.js" | "require": "./dist/index.js" | ||||
| }, | }, | ||||
| ], | ], | ||||
| "replace": { | "replace": { | ||||
| "dependencies": { | "dependencies": { | ||||
| "uiconfig-tweakpane": "^0.0.8" | |||||
| "uiconfig-tweakpane": "^0.0.10" | |||||
| }, | }, | ||||
| "peerDependencies": { | "peerDependencies": { | ||||
| "threepipe": "^0.0.21" | |||||
| "threepipe": "^0.0.34" | |||||
| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| "//": { | "//": { | ||||
| "dependencies": { | "dependencies": { | ||||
| "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | ||||
| "uiconfig-tweakpane": "^0.0.8" | |||||
| "uiconfig-tweakpane": "^0.0.10" | |||||
| }, | }, | ||||
| "local_dependencies": { | "local_dependencies": { | ||||
| "tweakpane-image-plugin": "file:./../tweakpane-image-plugin", | "tweakpane-image-plugin": "file:./../tweakpane-image-plugin", |
| uploadFile, | uploadFile, | ||||
| Vector2, | Vector2, | ||||
| Vector3, | Vector3, | ||||
| Vector4, | |||||
| Vector4, UndoManagerPlugin, | |||||
| } from 'threepipe' | } from 'threepipe' | ||||
| import styles from './tpTheme.css?inline' | import styles from './tpTheme.css?inline' | ||||
| import {tpImageInputGenerator} from './tpImageInputGenerator' | import {tpImageInputGenerator} from './tpImageInputGenerator' | ||||
| import {JSUndoManager} from 'ts-browser-helpers' | |||||
| @uiFolderContainer('Tweakpane UI') | @uiFolderContainer('Tweakpane UI') | ||||
| export class TweakpaneUiPlugin extends UiConfigRendererTweakpane implements IViewerPluginSync { | export class TweakpaneUiPlugin extends UiConfigRendererTweakpane implements IViewerPluginSync { | ||||
| static readonly PluginType = 'TweakpaneUi' | static readonly PluginType = 'TweakpaneUi' | ||||
| enabled = true | enabled = true | ||||
| static CONTAINER_SLOT = 'uiconfigMainPanelSlot' | |||||
| @onChange(TweakpaneUiPlugin.prototype._colorModeChanged) | @onChange(TweakpaneUiPlugin.prototype._colorModeChanged) | ||||
| @uiDropdown('Color Mode', ['black', 'white', 'blue'].map(label=>({label}))) | @uiDropdown('Color Mode', ['black', 'white', 'blue'].map(label=>({label}))) | ||||
| colorMode: 'black'|'white'|'blue' | colorMode: 'black'|'white'|'blue' | ||||
| constructor(expanded = false, bigTheme = true, container: HTMLElement = document.body, colorMode?: 'black'|'white'|'blue') { | |||||
| super(container, { | |||||
| constructor(expanded = false, bigTheme = true, container?: HTMLElement, colorMode?: 'black'|'white'|'blue') { | |||||
| super(container ?? document.getElementById(TweakpaneUiPlugin.CONTAINER_SLOT) ?? document.getElementById('tweakpaneMainPanelSlot') ?? document.body, { | |||||
| expanded, autoPostFrame: false, | expanded, autoPostFrame: false, | ||||
| }) | |||||
| }, false) | |||||
| this.THREE = {Color, Vector4, Vector3, Vector2} as any | this.THREE = {Color, Vector4, Vector3, Vector2} as any | ||||
| this._root!.registerPlugin(TweakpaneImagePlugin) | |||||
| this._root!.registerPlugin(TweakpaneImagePlugin as any) | |||||
| if (bigTheme) createStyles(styles, container) | if (bigTheme) createStyles(styles, container) | ||||
| this.colorMode = colorMode ?? (localStorage ? localStorage.getItem('tpTheme') as any : 'blue') ?? 'blue' | this.colorMode = colorMode ?? (localStorage ? localStorage.getItem('tpTheme') as any : 'blue') ?? 'blue' | ||||
| } | } | ||||
| protected _viewer?: ThreeViewer | protected _viewer?: ThreeViewer | ||||
| private _lastManager?: JSUndoManager | |||||
| onAdded(viewer: ThreeViewer): void { | onAdded(viewer: ThreeViewer): void { | ||||
| this._viewer = viewer | this._viewer = viewer | ||||
| this.typeGenerators.image = tpImageInputGenerator(this._viewer) | this.typeGenerators.image = tpImageInputGenerator(this._viewer) | ||||
| viewer.addEventListener('postRender', this._postRender) | viewer.addEventListener('postRender', this._postRender) | ||||
| viewer.addEventListener('preFrame', this._preFrame) | viewer.addEventListener('preFrame', this._preFrame) | ||||
| viewer.addEventListener('postFrame', this._postFrame) | viewer.addEventListener('postFrame', this._postFrame) | ||||
| const undo = viewer.getOrAddPluginSync(UndoManagerPlugin) // yes, manual dependency | |||||
| if (undo?.undoManager) { | |||||
| this._lastManager?.dispose() | |||||
| this._lastManager = this.undoManager | |||||
| this.undoManager = undo.undoManager | |||||
| if (this._lastManager) Object.assign(this.undoManager.presets, this._lastManager.presets) | |||||
| } | |||||
| } | } | ||||
| onRemove(viewer: ThreeViewer): void { | onRemove(viewer: ThreeViewer): void { | ||||
| this._viewer = undefined | this._viewer = undefined | ||||
| viewer.removeEventListener('preRender', this._preRender) | viewer.removeEventListener('preRender', this._preRender) | ||||
| viewer.removeEventListener('postRender', this._postRender) | viewer.removeEventListener('postRender', this._postRender) | ||||
| viewer.removeEventListener('preFrame', this._preFrame) | viewer.removeEventListener('preFrame', this._preFrame) | ||||
| viewer.removeEventListener('postFrame', this._postFrame) | viewer.removeEventListener('postFrame', this._postFrame) | ||||
| this.undoManager = this._lastManager | |||||
| this._lastManager = undefined | |||||
| this.dispose() | this.dispose() | ||||
| } | } | ||||
| localStorage.setItem('tpTheme', this.colorMode) | localStorage.setItem('tpTheme', this.colorMode) | ||||
| } | } | ||||
| dispose() { | |||||
| this.undoManager?.dispose() | |||||
| this.unmount() | |||||
| } | |||||
| } | } |
| import type {UiObjectConfig} from 'uiconfig.js' | import type {UiObjectConfig} from 'uiconfig.js' | ||||
| import {TweakpaneUiPlugin} from './TweakpaneUiPlugin' | import {TweakpaneUiPlugin} from './TweakpaneUiPlugin' | ||||
| export const makeTextSvg2 = (text: string): string => { | |||||
| return `data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Ctext style='font: 8px "Roboto Mono", "Source Code Pro", Menlo, Courier, monospace; fill: white;' x='9' y='18'%3E${text}%3C/text%3E%3C/svg%3E%0A` | |||||
| } | |||||
| const staticData = { | const staticData = { | ||||
| placeholderVal: 'placeholder', | placeholderVal: 'placeholder', | ||||
| // renderTarImage: makeColorSvg('ffffff'), | |||||
| renderTarImage: makeTextSvg('Render Target'), | renderTarImage: makeTextSvg('Render Target'), | ||||
| renderTarImage2: makeTextSvg2('...'), | |||||
| dataTexImage: makeTextSvg('Data Texture'), | dataTexImage: makeTextSvg('Data Texture'), | ||||
| lutCubeTexImage: makeTextSvg('CUBE Texture'), | lutCubeTexImage: makeTextSvg('CUBE Texture'), | ||||
| compressedTexImage: makeTextSvg('Compressed Texture'), | compressedTexImage: makeTextSvg('Compressed Texture'), | ||||
| tempMap: {} as any, | tempMap: {} as any, | ||||
| } | } | ||||
| function proxyGetValue(cc: any, viewer: ThreeViewer) { | |||||
| function proxyGetValue(cc: any, viewer: ThreeViewer, config: UiObjectConfig) { | |||||
| if (cc?.get) cc = cc.get() | if (cc?.get) cc = cc.get() | ||||
| let ret: any = undefined | let ret: any = undefined | ||||
| if (!cc) return staticData.placeholderVal | if (!cc) return staticData.placeholderVal | ||||
| if (cc.isTexture) { | if (cc.isTexture) { | ||||
| // console.warn('here') | // console.warn('here') | ||||
| // todo: use textureToCanvas for data texture | // todo: use textureToCanvas for data texture | ||||
| if (cc.image && !cc.image.tp_src) { | |||||
| if (cc.image instanceof ImageBitmap || cc.image instanceof HTMLImageElement || cc.image instanceof HTMLVideoElement) { // todo: support playback in video | |||||
| cc.image.tp_src = imageBitmapToBase64(cc.image, 160) | |||||
| } else if (cc.isRenderTargetTexture) { | |||||
| if (cc.image && !cc.image.tp_src && !cc.tp_src) { | |||||
| if (cc.isRenderTargetTexture) { | |||||
| if (cc._target) { | if (cc._target) { | ||||
| // here we are not doing cc.image.tp_src because cc.image can be shared across multiple textures in MRT | |||||
| cc.tp_src = viewer.renderManager.renderTargetToDataUrl(cc._target, undefined, undefined, Array.isArray(cc._target.texture) ? cc._target.texture.indexOf(cc) : undefined) | |||||
| setTimeout(()=>cc.tp_src && delete cc.tp_src, 1000) // clear after 1 second so it refreshes on next render | |||||
| // todo do same change in blueprint | |||||
| // doing in the timeout so it doesnt hang when opening a folder which does deep refresh | |||||
| // if (!config._lastRtRefresh || Date.now() - config._lastRtRefresh > 5000) { // 5000 should be significantly more than 500 + 100 below | |||||
| setTimeout(() => { | |||||
| // here we are not doing cc.image.tp_src because cc.image can be shared across multiple textures in MRT | |||||
| const dataUrl = viewer.renderManager.renderTargetToDataUrl(cc._target, undefined, undefined, Array.isArray(cc._target.texture) ? cc._target.texture.indexOf(cc) : undefined) | |||||
| cc.tp_src = dataUrl | |||||
| setTimeout(()=>cc.tp_src && delete cc.tp_src, 1000) // clear after 1 second so it refreshes on next render | |||||
| config.uiRefresh?.(false, 'postFrame') | |||||
| }, 200) | |||||
| cc.tp_src = staticData.renderTarImage2 | |||||
| // } | |||||
| // config._lastRtRefresh = Date.now() | |||||
| } | } | ||||
| } else if (cc.image instanceof ImageBitmap || cc.image instanceof HTMLImageElement || cc.image instanceof HTMLVideoElement) { // todo: support playback in video | |||||
| cc.image.tp_src = imageBitmapToBase64(cc.image, 160) | |||||
| } else { | } else { | ||||
| cc.image.tp_src = textureToDataUrl(cc, 160, false, 'image/png', 90) // this supports DataTexture also | cc.image.tp_src = textureToDataUrl(cc, 160, false, 'image/png', 90) // this supports DataTexture also | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| config.__proxy.value_ = v1 | config.__proxy.value_ = v1 | ||||
| renderer.methods.setValue(config, v1, {last: true}, false) | |||||
| renderer.methods.setValue(config, v1, {last: true}, false, false) | |||||
| config.uiRefresh?.(false, 'postFrame') | config.uiRefresh?.(false, 'postFrame') | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| export const tpImageInputGenerator = (viewer: ThreeViewer) => (parent: any /* FolderApi */, config: UiObjectConfig, renderer: TweakpaneUiPlugin, params?: any) => { | |||||
| export const tpImageInputGenerator: (viewer: ThreeViewer) => (parent: any, config: UiObjectConfig, renderer: TweakpaneUiPlugin, params?: any) => any = (viewer: ThreeViewer) => (parent: any /* FolderApi */, config: UiObjectConfig, renderer: TweakpaneUiPlugin, params?: any) => { | |||||
| // if (config.value !== undefined) throw 'Not supported yet' | // if (config.value !== undefined) throw 'Not supported yet' | ||||
| if (!config.__proxy) { | if (!config.__proxy) { | ||||
| Object.defineProperty(config.__proxy, 'value', { | Object.defineProperty(config.__proxy, 'value', { | ||||
| get: () => { | get: () => { | ||||
| config.__proxy.value_ = renderer.methods.getValue(config) | |||||
| const ret = proxyGetValue(config.__proxy.value_, viewer) | |||||
| if (typeof ret !== 'string' && !ret.id?.length) ret.id = generateUUID() | |||||
| const id = typeof ret === 'string' ? ret : ret.id ?? ret | |||||
| if (!staticData.textureMap[id]) staticData.textureMap[id] = config.__proxy.value_ | |||||
| return ret | |||||
| try { | |||||
| config.__proxy.value_ = renderer.methods.getRawValue(config) // sending undefined to disable comparison for undo etc | |||||
| const ret = proxyGetValue(config.__proxy.value_, viewer, config) | |||||
| if (typeof ret !== 'string' && !ret.id?.length) ret.id = generateUUID() | |||||
| const id = typeof ret === 'string' ? ret : ret.id ?? ret | |||||
| if (!staticData.textureMap[id]) staticData.textureMap[id] = config.__proxy.value_ | |||||
| return ret | |||||
| } catch (e) { | |||||
| console.error('uiconfig-tweakpane - ImageInput Unknown error', e) | |||||
| return staticData.placeholderVal | |||||
| } | |||||
| }, | }, | ||||
| set: (v: any) => { | set: (v: any) => { | ||||
| if (getOrCall(config.readOnly)) return | if (getOrCall(config.readOnly)) return | ||||
| config.__proxy.value_ = renderer.methods.getValue(config) // current value | |||||
| config.__proxy.value_ = renderer.methods.getRawValue(config) // current value | |||||
| proxySetValue(v, config.__proxy.value_, config, viewer, renderer) | proxySetValue(v, config.__proxy.value_, config, viewer, renderer) | ||||
| }, | }, | ||||
| }) | }) | ||||
| } | } | ||||
| config.__proxy.value_ = renderer.methods.getValue(config) | |||||
| config.__proxy.value_ = renderer.methods.getRawValue(config) | |||||
| params = params ?? {} | params = params ?? {} | ||||
| params.extensions = ['.jpg', '.png', '.svg', '.hdr', | params.extensions = ['.jpg', '.png', '.svg', '.hdr', | ||||
| menu.style.top = 'auto' | menu.style.top = 'auto' | ||||
| menu.style.bottom = rect.height + 8 + 'px' | menu.style.bottom = rect.height + 8 + 'px' | ||||
| } | } | ||||
| config.uiRefresh?.(false, 'postFrame') | |||||
| } | } | ||||
| params.view = 'input-image' | params.view = 'input-image' | ||||
| return renderer.typeGenerators.input(parent, config, renderer, params) | return renderer.typeGenerators.input(parent, config, renderer, params) |
| // rollup.config.js | |||||
| import json from '@rollup/plugin-json'; | |||||
| import resolve from '@rollup/plugin-node-resolve'; | |||||
| import typescript from '@rollup/plugin-typescript'; | |||||
| import packageJson from './package.json' assert {type: 'json'}; | |||||
| import path from 'node:path' | |||||
| import {fileURLToPath} from 'node:url'; | |||||
| import postcss from 'rollup-plugin-postcss' | |||||
| import glsl from "rollup-plugin-glsl" | |||||
| import replace from "@rollup/plugin-replace"; | |||||
| import commonjs from "@rollup/plugin-commonjs"; | |||||
| import license from "rollup-plugin-license"; | |||||
| import terser from "@rollup/plugin-terser"; | |||||
| const __filename = fileURLToPath(import.meta.url); | |||||
| const __dirname = path.dirname(__filename); | |||||
| const {name, version, author} = packageJson | |||||
| const {main, module, browser} = packageJson["clean-package"].replace | |||||
| const isProduction = process.env.NODE_ENV === 'production' | |||||
| const settings = { | |||||
| globals: {}, | |||||
| sourcemap: isProduction | |||||
| } | |||||
| export default { | |||||
| input: './src/index.ts', | |||||
| output: [ | |||||
| // { | |||||
| // file: main, | |||||
| // name: main, | |||||
| // ...settings, | |||||
| // format: 'cjs', | |||||
| // plugins: [ | |||||
| // isProduction && terser() | |||||
| // ] | |||||
| // }, | |||||
| { | |||||
| file: module, | |||||
| ...settings, | |||||
| name: name, | |||||
| // dir: 'dist', // indicate not create a single-file | |||||
| // preserveModules: true, // indicate not create a single-file | |||||
| // preserveModulesRoot: 'src', // optional but useful to create a more plain folder structure | |||||
| format: 'es' | |||||
| }, | |||||
| isProduction ? { | |||||
| file: browser, | |||||
| ...settings, | |||||
| name: name, | |||||
| format: 'umd', | |||||
| plugins: [ | |||||
| isProduction && terser() | |||||
| ] | |||||
| } : null, | |||||
| ], | |||||
| external: [], | |||||
| plugins: [ | |||||
| replace({ | |||||
| 'process.env.NODE_ENV': JSON.stringify( 'production' ), | |||||
| '.css?inline': '.css', | |||||
| preventAssignment: true, | |||||
| }), | |||||
| // replace({ | |||||
| // exclude: 'src/**', | |||||
| // delimiters: ['', ''], | |||||
| // values:{ | |||||
| // 'from \'three\'': 'from \'threepipe\'', | |||||
| // }, | |||||
| // }), | |||||
| glsl({ // todo: minify glsl. | |||||
| include: "src/**/*.glsl" | |||||
| }), | |||||
| postcss({ | |||||
| extensions: ['.css', '.css?inline'], | |||||
| modules: false, | |||||
| autoModules: true, // todo; issues with typescript import css, because inject is false | |||||
| inject: false, | |||||
| minimize: isProduction, | |||||
| // Or with custom options for `postcss-modules` | |||||
| }), | |||||
| json(), | |||||
| resolve({}), | |||||
| typescript({}), | |||||
| commonjs({ | |||||
| include: 'node_modules/**', | |||||
| extensions: ['.js'], | |||||
| ignoreGlobal: false, | |||||
| sourceMap: false | |||||
| }), | |||||
| license({ | |||||
| banner: ` | |||||
| @license | |||||
| ${name} v${version} | |||||
| Copyright 2022<%= moment().format('YYYY') > 2022 ? '-' + moment().format('YYYY') : null %> ${author} | |||||
| ${packageJson.license} License | |||||
| See ./dependencies.txt for bundled third-party dependencies and licenses. | |||||
| `, | |||||
| thirdParty: { | |||||
| output: path.join(__dirname, 'dist', 'dependencies.txt'), | |||||
| includePrivate: true, // Default is false. | |||||
| }, | |||||
| }) | |||||
| ] | |||||
| } |