| @@ -1,15 +1,15 @@ | |||
| { | |||
| "name": "threepipe", | |||
| "version": "0.0.37", | |||
| "version": "0.0.38", | |||
| "lockfileVersion": 3, | |||
| "requires": true, | |||
| "packages": { | |||
| "": { | |||
| "name": "threepipe", | |||
| "version": "0.0.37", | |||
| "version": "0.0.38", | |||
| "license": "Apache-2.0", | |||
| "dependencies": { | |||
| "@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.157.1002/package.tgz", | |||
| "@types/webxr": "^0.5.1", | |||
| "@types/wicg-file-system-access": "^2020.9.5", | |||
| "popmotion": "^11.0.5", | |||
| @@ -35,7 +35,7 @@ | |||
| "rimraf": "^5.0.1", | |||
| "rollup-plugin-glsl": "^1.3.0", | |||
| "rollup-plugin-license": "^3.0.1", | |||
| "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.157.1002/package.tgz", | |||
| "tslib": "^2.5.0", | |||
| "typedoc": "^0.27.5", | |||
| "typescript": "5.7.2", | |||
| @@ -49,7 +49,7 @@ | |||
| "win-node-env": "^0.6.1" | |||
| }, | |||
| "peerDependencies": { | |||
| "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.157.1002/package.tgz" | |||
| }, | |||
| "peerDependenciesMeta": { | |||
| "three": { | |||
| @@ -2209,12 +2209,6 @@ | |||
| "node": ">= 10" | |||
| } | |||
| }, | |||
| "node_modules/@tweenjs/tween.js": { | |||
| "version": "18.6.4", | |||
| "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", | |||
| "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==", | |||
| "license": "MIT" | |||
| }, | |||
| "node_modules/@types/argparse": { | |||
| "version": "1.0.38", | |||
| "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", | |||
| @@ -2333,13 +2327,12 @@ | |||
| "license": "MIT" | |||
| }, | |||
| "node_modules/@types/three": { | |||
| "version": "0.153.1002", | |||
| "resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.153.1002/package.tgz", | |||
| "integrity": "sha512-C0gfzxmzvVR0dwzBtHlgA7HoTUoLeDalMksQCgq+suzqhAfbgLVBjE641NtNiEyp1TQmEOCVfgBBzpq3AboRpg==", | |||
| "version": "0.157.1002", | |||
| "resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.157.1002/package.tgz", | |||
| "integrity": "sha512-Awi3M95BysLnWcQYceEwwU/9IUOd0NeXCo+ldvRWbnHjbyCAwQKb2pSsEuhYcdA6Nk6sbJQMY814Svqy0fYuJg==", | |||
| "dependencies": { | |||
| "@tweenjs/tween.js": "~18.6.4", | |||
| "fflate": "~0.6.9", | |||
| "lil-gui": "~0.17.0" | |||
| "fflate": "~0.6.10", | |||
| "meshoptimizer": "~0.18.1" | |||
| } | |||
| }, | |||
| "node_modules/@types/unist": { | |||
| @@ -6742,12 +6735,6 @@ | |||
| "node": ">= 0.8.0" | |||
| } | |||
| }, | |||
| "node_modules/lil-gui": { | |||
| "version": "0.17.0", | |||
| "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.17.0.tgz", | |||
| "integrity": "sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==", | |||
| "license": "MIT" | |||
| }, | |||
| "node_modules/lilconfig": { | |||
| "version": "2.1.0", | |||
| "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", | |||
| @@ -7265,6 +7252,12 @@ | |||
| "node": ">= 8" | |||
| } | |||
| }, | |||
| "node_modules/meshoptimizer": { | |||
| "version": "0.18.1", | |||
| "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", | |||
| "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==", | |||
| "license": "MIT" | |||
| }, | |||
| "node_modules/methods": { | |||
| "version": "1.1.2", | |||
| "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", | |||
| @@ -9927,9 +9920,9 @@ | |||
| "license": "MIT" | |||
| }, | |||
| "node_modules/three": { | |||
| "version": "0.153.1006", | |||
| "resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.153.1006/package.tgz", | |||
| "integrity": "sha512-vUj+kY9FDleRTLn+T8lbn5m8KQLOCR1nuQx2MyUtBrmYm3I+ttnfRlgjU5p/y2vrzjqnP6bCH5bfwp43YKl6LA==", | |||
| "version": "0.157.1002", | |||
| "resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1002/package.tgz", | |||
| "integrity": "sha512-xnfOnDX1UmcKc992mYitqY0EOcBNDqI7hxPoQJRdFmTCbjpTe6LYhjN0LbTozVM1RmmpUZa3Tw2Ji8h1hh7QuQ==", | |||
| "dev": true, | |||
| "license": "MIT" | |||
| }, | |||
| @@ -1,6 +1,6 @@ | |||
| { | |||
| "name": "threepipe", | |||
| "version": "0.0.38", | |||
| "version": "0.0.39", | |||
| "description": "A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.", | |||
| "main": "dist/index.js", | |||
| "module": "dist/index.mjs", | |||
| @@ -108,7 +108,7 @@ | |||
| "rimraf": "^5.0.1", | |||
| "rollup-plugin-glsl": "^1.3.0", | |||
| "rollup-plugin-license": "^3.0.1", | |||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.155.1001/package.tgz", | |||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1002/package.tgz", | |||
| "tslib": "^2.5.0", | |||
| "typedoc": "^0.27.5", | |||
| "typescript": "5.7.2", | |||
| @@ -119,7 +119,7 @@ | |||
| "vitepress-plugin-nprogress": "^0.0.4" | |||
| }, | |||
| "dependencies": { | |||
| "@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.157.1002/package.tgz", | |||
| "@types/webxr": "^0.5.1", | |||
| "@types/wicg-file-system-access": "^2020.9.5", | |||
| "stats.js": "^0.17.0", | |||
| @@ -128,7 +128,7 @@ | |||
| "popmotion": "^11.0.5" | |||
| }, | |||
| "peerDependencies": { | |||
| "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.157.1002/package.tgz" | |||
| }, | |||
| "peerDependenciesMeta": { | |||
| "three": { | |||
| @@ -139,10 +139,10 @@ | |||
| "dependencies": { | |||
| "uiconfig.js": "^0.1.3", | |||
| "ts-browser-helpers": "^0.16.2", | |||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.155.1007/package.tgz", | |||
| "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.155.1007.tar.gz", | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.153.1002/package.tgz", | |||
| "@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.153.1002.tar.gz", | |||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.157.1002/package.tgz", | |||
| "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.157.1002.tar.gz", | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.157.1002/package.tgz", | |||
| "@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.157.1002.tar.gz", | |||
| "@types/three-pkg": "https://gitpkg.now.sh/repalash/three-ts-types/types/three?modded_three" | |||
| }, | |||
| "local_dependencies": { | |||
| @@ -17,7 +17,7 @@ | |||
| "replace": { | |||
| "dependencies": {}, | |||
| "peerDependencies": { | |||
| "threepipe": "^0.0.30" | |||
| "threepipe": "^0.0.39" | |||
| } | |||
| } | |||
| }, | |||
| @@ -4,7 +4,7 @@ import {GridItemList} from './GridItemList' | |||
| /** | |||
| * A helper plugin to create a a simple list of small grids like for material or object configurator | |||
| */ | |||
| export class GridItemListPlugin extends AViewerPluginSync<''> { | |||
| export class GridItemListPlugin extends AViewerPluginSync { | |||
| enabled = true | |||
| toJSON: any = undefined | |||
| create = GridItemList.Create | |||
| @@ -26,7 +26,7 @@ | |||
| "replace": { | |||
| "dependencies": {}, | |||
| "peerDependencies": { | |||
| "threepipe": "^0.0.20" | |||
| "threepipe": "^0.0.39" | |||
| } | |||
| } | |||
| }, | |||
| @@ -24,7 +24,7 @@ import {Class} from 'ts-browser-helpers' | |||
| * Geometry generator plugin to create updatable parametric objects/geometries. | |||
| * Includes support for several primitive types from three.js | |||
| */ | |||
| export class GeometryGeneratorPlugin extends AViewerPluginSync<''> { | |||
| export class GeometryGeneratorPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'GeometryGeneratorPlugin' | |||
| enabled = true | |||
| toJSON: any = undefined | |||
| @@ -28,7 +28,7 @@ | |||
| "replace": { | |||
| "dependencies": {}, | |||
| "peerDependencies": { | |||
| "threepipe": "^0.0.35" | |||
| "threepipe": "^0.0.39" | |||
| } | |||
| } | |||
| }, | |||
| @@ -34,7 +34,7 @@ export enum EncoderMethod { | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export class GLTFDracoExportPlugin extends AViewerPluginSync<''> { | |||
| export class GLTFDracoExportPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'GLTFDracoExportPlugin' | |||
| enabled = true | |||
| @@ -29,7 +29,7 @@ | |||
| "replace": { | |||
| "dependencies": {}, | |||
| "peerDependencies": { | |||
| "threepipe": "^0.0.30" | |||
| "threepipe": "^0.0.39" | |||
| } | |||
| } | |||
| }, | |||
| @@ -1,4 +1,5 @@ | |||
| import { | |||
| AViewerPluginEventMap, | |||
| AViewerPluginSync, | |||
| FileTransferPlugin, | |||
| pathJoin, | |||
| @@ -13,6 +14,15 @@ import { | |||
| } from 'threepipe' | |||
| import {AwsClient, AwsV4Signer} from 'aws4fetch' | |||
| export interface AWSClientPluginEventMap extends AViewerPluginEventMap { | |||
| fileUpload: { | |||
| name: string | |||
| blob: Blob | |||
| response: Response | |||
| path: string | |||
| } | |||
| } | |||
| /** | |||
| * AWSClientPlugin | |||
| * Provides `fetch` function that performs a fetch request with AWS v4 signing. | |||
| @@ -24,7 +34,7 @@ import {AwsClient, AwsV4Signer} from 'aws4fetch' | |||
| * {@todo Make an example for AWSClient Plugin} | |||
| */ | |||
| @uiFolderContainer('AWS/S3 Client') | |||
| export class AWSClientPlugin extends AViewerPluginSync<'fileUpload'> { | |||
| export class AWSClientPlugin extends AViewerPluginSync<AWSClientPluginEventMap> { | |||
| static readonly PluginType = 'AWSClientPlugin1' | |||
| declare uiConfig: UiObjectConfig | |||
| @@ -11,7 +11,7 @@ import {AssetExporterPlugin, AViewerPluginSync, IObject3D, uiButton, uiFolderCon | |||
| * Note: since the uploaded files are publicly accessible by anyone by default, it is recommended to encrypt the file using the exporter options or use a secure backend. | |||
| */ | |||
| @uiFolderContainer('Share Link') | |||
| export class TransfrSharePlugin extends AViewerPluginSync<''> { | |||
| export class TransfrSharePlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'TransfrSharePlugin' | |||
| toJSON: any = null | |||
| @@ -37,7 +37,7 @@ | |||
| "replace": { | |||
| "dependencies": {}, | |||
| "peerDependencies": { | |||
| "threepipe": "^0.0.30" | |||
| "threepipe": "^0.0.39" | |||
| } | |||
| } | |||
| }, | |||
| @@ -13,7 +13,7 @@ import {BasicSVGRenderer} from './basic/BasicSVGRenderer' | |||
| * SVG rendering of 3d objects using SVGRenderer from three/addons | |||
| */ | |||
| @uiFolderContainer('SVG Renderer') | |||
| export class BasicSVGRendererPlugin extends AViewerPluginSync<''> { | |||
| export class BasicSVGRendererPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'BasicSVGRendererPlugin' | |||
| @uiToggle() | |||
| @@ -20,7 +20,7 @@ import {Vertex} from './three-mesh-halfedge' | |||
| * SVG Rendering from 3d scenes helper plugin using [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer) (GPLV3 Licenced) | |||
| */ | |||
| @uiFolderContainer('SVG Renderer') | |||
| export class ThreeSVGRendererPlugin extends AViewerPluginSync<''> { | |||
| export class ThreeSVGRendererPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'ThreeSVGRendererPlugin' | |||
| @uiToggle() | |||
| @@ -360,9 +360,9 @@ export class ThreeSVGRendererPlugin extends AViewerPluginSync<''> { | |||
| this.renderer.viewmap.options.creaseAngle.max = this.creaseAngle.y | |||
| const passes = this.renderer.drawHandler.passes | |||
| const fillPass = passes.find(p=>p instanceof FillPass) as FillPass | |||
| const visibleContourPass = passes.find(p=>p instanceof VisibleChainPass) as VisibleChainPass | |||
| const hiddenContourPass = passes.find(p=>p instanceof HiddenChainPass) as HiddenChainPass | |||
| const fillPass = passes.find(p=>p instanceof FillPass)! | |||
| const visibleContourPass = passes.find(p=>p instanceof VisibleChainPass)! | |||
| const hiddenContourPass = passes.find(p=>p instanceof HiddenChainPass)! | |||
| if (fillPass) { | |||
| fillPass.enabled = this.drawPolygons && (this.drawPolygonFills || this.drawPolygonStrokes || this.drawImageFills) | |||
| fillPass.drawFills = this.drawPolygonFills | |||
| @@ -30,8 +30,8 @@ | |||
| "replace": { | |||
| "dependencies": {}, | |||
| "peerDependencies": { | |||
| "threepipe": "^0.0.18", | |||
| "@threepipe/plugin-tweakpane": "^0.2.0" | |||
| "threepipe": "^0.0.39", | |||
| "@threepipe/plugin-tweakpane": "^0.5.3" | |||
| } | |||
| } | |||
| }, | |||
| @@ -3,7 +3,7 @@ import Tree from 'treejs' | |||
| import {AViewerPluginSync, IObject3D, Object3D, ThreeViewer} from 'threepipe' | |||
| import {UiObjectConfig} from 'uiconfig.js' | |||
| export class HierarchyUiPlugin extends AViewerPluginSync<''> { | |||
| export class HierarchyUiPlugin extends AViewerPluginSync { | |||
| enabled = true | |||
| public static readonly PluginType = 'HierarchyUiPlugin' | |||
| @@ -39,7 +39,7 @@ export class HierarchyUiPlugin extends AViewerPluginSync<''> { | |||
| } | |||
| reset(e?: any) { | |||
| if (e?.fromHierarchyPlugin) return // for infinite loop | |||
| if (e?.source !== HierarchyUiPlugin.PluginType) return // for infinite loop | |||
| if (!e?.hierarchyChanged) return | |||
| this._needsReset = true | |||
| } | |||
| @@ -76,7 +76,7 @@ export class HierarchyUiPlugin extends AViewerPluginSync<''> { | |||
| onItemLabelClick: (item: any) => { | |||
| const obj1 = this._viewer?.scene.modelRoot.getObjectByProperty('uuid', item) | |||
| if (!obj1 || !obj.visible) return | |||
| obj1.dispatchEvent({type: 'select', value: obj1, ui: true}) | |||
| obj1.dispatchEvent({type: 'select', value: obj1, object: obj1, ui: true}) | |||
| }, | |||
| }) | |||
| }) | |||
| @@ -136,7 +136,7 @@ export class HierarchyUiPlugin extends AViewerPluginSync<''> { | |||
| if (o.visible) o.traverseAncestors(p=>ancestorSet.add(p)) | |||
| }) | |||
| ancestorSet.forEach(o=> o.visible = true) | |||
| this._viewer?.scene?.setDirty({refreshScene: true, fromHierarchyPlugin: true, updateGround: false}) | |||
| this._viewer?.scene?.setDirty({refreshScene: true, source: HierarchyUiPlugin.PluginType, updateGround: false}) | |||
| }) | |||
| } | |||
| } | |||
| @@ -1,9 +1,19 @@ | |||
| import {BaseEvent, EventDispatcher, WebGLRenderTarget} from 'three' | |||
| import {EventDispatcher, WebGLRenderTarget} from 'three' | |||
| import {IMaterial, IObject3D, ITexture} from '../core' | |||
| import {BlobExt, ExportFileOptions, IAssetExporter, IExporter, IExportParser} from './IExporter' | |||
| import {EXRExporter2, SimpleJSONExporter, SimpleTextExporter} from './export' | |||
| import {IRenderTarget} from '../rendering' | |||
| export interface AssetExporterEventMap { | |||
| exporterCreate: {exporter: IExporter, parser: IExportParser} | |||
| exportFile: { | |||
| obj: IObject3D|IMaterial|ITexture|IRenderTarget, | |||
| state: 'processing'|'exporting'|'done'|'error', | |||
| error?: any, | |||
| exportOptions: ExportFileOptions | |||
| } | |||
| } | |||
| /** | |||
| * Asset Exporter | |||
| * | |||
| @@ -11,7 +21,7 @@ import {IRenderTarget} from '../rendering' | |||
| * Used in {@link AssetManager} to export assets. | |||
| * @category Asset Manager | |||
| */ | |||
| export class AssetExporter extends EventDispatcher<BaseEvent, 'exporterCreate' | 'exportFile'> implements IAssetExporter { | |||
| export class AssetExporter extends EventDispatcher<AssetExporterEventMap> implements IAssetExporter { | |||
| readonly exporters: IExporter[] = [ | |||
| {ctor: ()=>new SimpleJSONExporter(), ext: ['json']}, | |||
| {ctor: ()=>new SimpleTextExporter(), ext: ['txt', 'text']}, | |||
| @@ -86,17 +96,17 @@ export class AssetExporter extends EventDispatcher<BaseEvent, 'exporterCreate' | | |||
| else { | |||
| const parser = this._getParser(ext) | |||
| this.dispatchEvent({type: 'exportFile', obj, state:'exporting'}) | |||
| this.dispatchEvent({type: 'exportFile', obj, state:'exporting', exportOptions: options}) | |||
| res = await parser.parseAsync(processed.obj, {exportExt: processed.ext ?? ext, ...options}) as BlobExt | |||
| res.ext = processed.ext | |||
| } | |||
| this.dispatchEvent({type: 'exportFile', obj, state: 'done'}) | |||
| this.dispatchEvent({type: 'exportFile', obj, state: 'done', exportOptions: options}) | |||
| } catch (e) { | |||
| console.error('AssetExporter: Unable to Export file', obj) | |||
| // console.error(e) | |||
| this.dispatchEvent({type: 'exportFile', obj, state: 'error', error: e}) | |||
| this.dispatchEvent({type: 'exportFile', obj, state: 'error', error: e, exportOptions: options}) | |||
| throw e | |||
| return undefined | |||
| } | |||
| @@ -1,7 +1,6 @@ | |||
| import {Event, EventDispatcher, EventListener, FileLoader, LoaderUtils, LoadingManager} from 'three' | |||
| import {EventDispatcher, EventListener, FileLoader, LoaderUtils, LoadingManager} from 'three' | |||
| import { | |||
| IAssetImporter, | |||
| IAssetImporterEventTypes, | |||
| IImportResultUserData, | |||
| ImportAssetOptions, | |||
| ImportFilesOptions, | |||
| @@ -16,14 +15,41 @@ import {SimpleJSONLoader} from './import' | |||
| import {parseFileExtension} from 'ts-browser-helpers' | |||
| import {IObject3D} from '../core' | |||
| export type IAssetImporterEvent = Event&{ | |||
| type: IAssetImporterEventTypes, | |||
| data?: ImportResult, options?: ProcessRawOptions, | |||
| path?: string, progress?: number, state?: string, error?: any | |||
| files?: Map<string, IFile> | |||
| url?: string, loaded?: number, total?: number | |||
| loader?: ILoader, | |||
| // export type IAssetImporterEvent = Event&{ | |||
| // type: IAssetImporterEventTypes, | |||
| // data?: ImportResult, options?: ProcessRawOptions, | |||
| // path?: string, progress?: number, state?: string, error?: any | |||
| // files?: Map<string, IFile> | |||
| // url?: string, loaded?: number, total?: number | |||
| // loader?: ILoader, | |||
| // } | |||
| // export type IAssetImporterEventTypes = 'onLoad' | 'onProgress' | 'onStop' | 'onError' | 'onStart' | 'loaderCreate' | 'importFile' | 'importFiles' | 'processRaw' | 'processRawStart' | |||
| export interface IAssetImporterEventMap { | |||
| loaderCreate: {type: 'loaderCreate', loader: ILoader} | |||
| importFile: {type: 'importFile', path: string, state: 'downloading'|'done'|'error'|'adding', progress?: number, loadedBytes?: number, totalBytes?: number, error?: any} | |||
| importFiles: {type: 'importFiles', files: Map<string, IFile>, state: 'start'|'end'} | |||
| processRaw: {type: 'processRaw', data: any, options: ProcessRawOptions, path?: string} | |||
| processRawStart: {type: 'processRawStart', data: any, options: ProcessRawOptions, path?: string} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onLoad: {type: 'onLoad'} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onProgress: {type: 'onProgress', url: string, loaded: number, total: number} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onError: {type: 'onError', url: string} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onStart: {type: 'onStart', url: string, loaded: number, total: number} | |||
| } | |||
| /** | |||
| * Asset Importer | |||
| * | |||
| @@ -32,7 +58,7 @@ export type IAssetImporterEvent = Event&{ | |||
| * Acts as a wrapper over three.js LoadingManager and adds support for dynamically loading loaders, caching assets, better event dispatching and file tracking. | |||
| * @category Asset Manager | |||
| */ | |||
| export class AssetImporter extends EventDispatcher<IAssetImporterEvent, IAssetImporterEventTypes> implements IAssetImporter { | |||
| export class AssetImporter extends EventDispatcher<IAssetImporterEventMap> implements IAssetImporter { | |||
| private _loadingManager: LoadingManager | |||
| private _logger = console.log | |||
| @@ -557,7 +583,7 @@ export class AssetImporter extends EventDispatcher<IAssetImporterEvent, IAssetIm | |||
| return loader | |||
| } | |||
| addEventListener<T extends IAssetImporterEvent['type'] & IAssetImporterEventTypes>(type: T, listener: EventListener<IAssetImporterEvent, T, this>) { | |||
| addEventListener<T extends keyof IAssetImporterEventMap>(type: T, listener: EventListener<IAssetImporterEventMap[T], T, this>): void { | |||
| super.addEventListener(type, listener) | |||
| if (type === 'loaderCreate') { | |||
| for (const loaderCacheElement of this._loaderCache) { | |||
| @@ -29,7 +29,7 @@ import { | |||
| iMaterialCommons, | |||
| IObject3D, | |||
| iObjectCommons, | |||
| ISceneEvent, | |||
| ISceneEventMap, | |||
| ITexture, | |||
| PerspectiveCamera2, | |||
| PointLight2, | |||
| @@ -79,6 +79,10 @@ export interface AddAssetOptions extends AddObjectOptions{ | |||
| export type ImportAddOptions = ImportAssetOptions & AddAssetOptions | |||
| export type AddRawOptions = ProcessRawOptions & AddAssetOptions | |||
| export interface AssetManagerEventMap{ | |||
| loadAsset: {data: ImportResult} | |||
| processStateUpdate: object | |||
| } | |||
| /** | |||
| * Asset Manager | |||
| @@ -86,7 +90,7 @@ export type AddRawOptions = ProcessRawOptions & AddAssetOptions | |||
| * Utility class to manage import, export, and material management. | |||
| * @category Asset Manager | |||
| */ | |||
| export class AssetManager extends EventDispatcher<BaseEvent&{data?: ImportResult}, 'loadAsset'|'processStateUpdate'> { | |||
| export class AssetManager extends EventDispatcher<AssetManagerEventMap> { | |||
| readonly viewer: ThreeViewer | |||
| readonly importer: AssetImporter | |||
| readonly exporter: AssetExporter | |||
| @@ -216,8 +220,9 @@ export class AssetManager extends EventDispatcher<BaseEvent&{data?: ImportResult | |||
| return (await this.addRaw<T>(res, options))?.[0] | |||
| } | |||
| private _sceneUpdated(event: ISceneEvent) { // todo: check if objects are added some other way. | |||
| if (event.type === 'addSceneObject') { | |||
| private _sceneUpdated<T extends keyof ISceneEventMap>(ev: BaseEvent<T> & ISceneEventMap[T]) { // todo: check if objects are added some other way. | |||
| if (ev.type === 'addSceneObject') { | |||
| const event = ev as ISceneEventMap['addSceneObject'] | |||
| const target = event.object as ImportResult | |||
| switch (target.assetType) { | |||
| case 'material': | |||
| @@ -232,15 +237,17 @@ export class AssetManager extends EventDispatcher<BaseEvent&{data?: ImportResult | |||
| default: | |||
| break | |||
| } | |||
| } else if (event.type === 'materialChanged') { | |||
| } else if (ev.type === 'materialChanged') { | |||
| const event = ev as ISceneEventMap['materialChanged'] | |||
| const target = event.material as IMaterial | IMaterial[] | undefined | |||
| const targets = Array.isArray(target) ? target : target ? [target] : [] | |||
| for (const t of targets) { | |||
| this.materials.registerMaterial(t) | |||
| } | |||
| } else if (event.type === 'beforeDeserialize') { | |||
| } else if (ev.type === 'beforeDeserialize') { | |||
| const event = ev as ISceneEventMap['beforeDeserialize'] | |||
| // object/material/texture to be deserialized | |||
| const data = event.data | |||
| const data = event.data as any | |||
| const meta = event.meta | |||
| if (!data.metadata) { | |||
| console.warn('Invalid data(no metadata)', data) | |||
| @@ -1,4 +1,4 @@ | |||
| import {BaseEvent, EventDispatcher, LoadingManager, Object3D} from 'three' | |||
| import {EventDispatcher, LoadingManager, Object3D} from 'three' | |||
| import {IDisposable} from 'ts-browser-helpers' | |||
| import {IAsset, IFile} from './IAsset' | |||
| import {ILoader} from './IImporter' | |||
| @@ -161,8 +161,34 @@ export interface ImportAssetOptions extends ProcessRawOptions, LoadFileOptions { | |||
| importedFile?: IFile, | |||
| } | |||
| export type IAssetImporterEventTypes = 'onLoad' | 'onProgress' | 'onStop' | 'onError' | 'onStart' | 'loaderCreate' | 'importFile' | 'importFiles' | 'processRaw' | 'processRawStart' | |||
| export interface IAssetImporter extends EventDispatcher<BaseEvent, IAssetImporterEventTypes>, IDisposable { | |||
| // export type IAssetImporterEventTypes = 'onLoad' | 'onProgress' | 'onStop' | 'onError' | 'onStart' | 'loaderCreate' | 'importFile' | 'importFiles' | 'processRaw' | 'processRawStart' | |||
| export interface IAssetImporterEventMap { | |||
| loaderCreate: {type: 'loaderCreate', loader: ILoader} | |||
| importFile: {type: 'importFile', path: string, state: 'downloading'|'done'|'error'|'adding', progress?: number, loadedBytes?: number, totalBytes?: number, error?: any} | |||
| importFiles: {type: 'importFiles', files: Map<string, IFile>, state: 'start'|'end'} | |||
| processRaw: {type: 'processRaw', data: any, options: ProcessRawOptions, path?: string} | |||
| processRawStart: {type: 'processRawStart', data: any, options: ProcessRawOptions, path?: string} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onLoad: {type: 'onLoad'} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onProgress: {type: 'onProgress', url: string, loaded: number, total: number} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onError: {type: 'onError', url: string} | |||
| /** | |||
| * @deprecated use the {@link importFile} event instead | |||
| */ | |||
| onStart: {type: 'onStart', url: string, loaded: number, total: number} | |||
| } | |||
| export interface IAssetImporter<TE extends IAssetImporterEventMap = IAssetImporterEventMap> extends EventDispatcher<TE>, IDisposable { | |||
| readonly loadingManager: LoadingManager | |||
| readonly cachedAssets: IAsset[] | |||
| @@ -1,22 +1,21 @@ | |||
| import {BaseEvent, ColorManagement, EventDispatcher, Material} from 'three' | |||
| import {ColorManagement, Event, EventDispatcher, EventListener, Material, Texture} from 'three' | |||
| import { | |||
| IMaterial, | |||
| iMaterialCommons, | |||
| IMaterialEvent, | |||
| IMaterialParameters, | |||
| IMaterialTemplate, | |||
| ITexture, | |||
| ITextureEvent, | |||
| LegacyPhongMaterial, | |||
| LineMaterial2, | |||
| ObjectShaderMaterial, | |||
| PhysicalMaterial, | |||
| UnlitLineMaterial, | |||
| UnlitMaterial, | |||
| ObjectShaderMaterial, | |||
| } from '../core' | |||
| import {downloadFile} from 'ts-browser-helpers' | |||
| import {MaterialExtension} from '../materials' | |||
| import {generateUUID, isInScene} from '../three' | |||
| import {IMaterialEventMap} from '../core/IMaterial' | |||
| /** | |||
| * Material Manager | |||
| @@ -25,7 +24,7 @@ import {generateUUID, isInScene} from '../three' | |||
| * Used in {@link AssetManager} to manage materials. | |||
| * @category Asset Manager | |||
| */ | |||
| export class MaterialManager<T = ''> extends EventDispatcher<BaseEvent, T> { | |||
| export class MaterialManager<TEventMap extends object = object> extends EventDispatcher<TEventMap> { | |||
| readonly templates: IMaterialTemplate[] = [ | |||
| PhysicalMaterial.MaterialTemplate, | |||
| UnlitMaterial.MaterialTemplate, | |||
| @@ -133,13 +132,13 @@ export class MaterialManager<T = ''> extends EventDispatcher<BaseEvent, T> { | |||
| private _materialMaps = new Map<string, Set<ITexture>>() | |||
| protected _materialUpdate = (e: IMaterialEvent<'materialUpdate'>)=>{ | |||
| protected _materialUpdate: EventListener<IMaterialEventMap['materialUpdate'], 'materialUpdate', IMaterial> = (e)=>{ | |||
| const mat = e.material || e.target | |||
| if (!mat || mat.assetType !== 'material') return | |||
| this._refreshTextureRefs(mat) | |||
| } | |||
| protected _textureUpdate = function(this: IMaterial, e: ITextureEvent<'update'>) { | |||
| protected _textureUpdate = function(this: IMaterial, e: Event<'update', Texture>) { | |||
| if (!this || this.assetType !== 'material') return | |||
| this.dispatchEvent({texture: e.target, bubbleToParent: true, bubbleToObject: true, ...e, type: 'textureUpdate'}) | |||
| } | |||
| @@ -12,7 +12,7 @@ export class EXRExporter2 extends EXRExporter implements IExportParser { | |||
| console.warn('No textureIndex specified for WebGLMultipleRenderTargets') | |||
| const res = target.isWebGLRenderTarget ? | |||
| this.parse(target.renderManager!.webglRenderer, <WebGLRenderTarget>target, options) : | |||
| this.parse(undefined, <DataTexture>obj, options) | |||
| this.parse(<DataTexture>obj, options) | |||
| return new Blob([res], {type: 'image/x-exr'}) | |||
| } | |||
| } | |||
| @@ -35,7 +35,7 @@ class MTLLoader2 extends Loader { | |||
| * @param {Function} [onProgress] - Callback for download progress. | |||
| * @param {Function} [onError] - Callback for download errors. | |||
| * | |||
| * @link setPath setResourcePath | |||
| * {@link setPath} {@link setResourcePath} | |||
| * | |||
| * @note In order for relative texture references to resolve correctly | |||
| * you must call setResourcePath() explicitly prior to load. | |||
| @@ -89,7 +89,7 @@ class MTLLoader2 extends Loader { | |||
| * @param {String} text - Content of MTL file | |||
| * @return {MaterialCreator} | |||
| * | |||
| * @link setPath setResourcePath | |||
| * {@link setPath} {@link setResourcePath} | |||
| * | |||
| * @note In order for relative texture references to resolve correctly | |||
| * you must call setResourcePath() explicitly prior to parse. | |||
| @@ -3,10 +3,9 @@ export {AssetExporter} from './AssetExporter' | |||
| export {AssetManager} from './AssetManager' | |||
| export {Importer} from './Importer' | |||
| export {MaterialManager} from './MaterialManager' | |||
| export type {IAssetImporterEvent} from './AssetImporter' | |||
| export type {AssetManagerOptions, AddRawOptions, ImportAddOptions, AddAssetOptions} from './AssetManager' | |||
| export type {IAsset, IFile, IAssetID, IAssetList} from './IAsset' | |||
| export type {ImportResult, IImportResultUserData, ImportResultObject, IAssetImporter, IAssetImporterEventTypes, ImportAssetOptions, ImportFilesOptions, LoadFileOptions, ProcessRawOptions, RootSceneImportResult, ImportResultExtras} from './IAssetImporter' | |||
| export type {ImportResult, IImportResultUserData, ImportResultObject, IAssetImporter, IAssetImporterEventMap, ImportAssetOptions, ImportFilesOptions, LoadFileOptions, ProcessRawOptions, RootSceneImportResult, ImportResultExtras} from './IAssetImporter' | |||
| export type {IAssetExporter, IExporter, IExportParser, ExportFileOptions, BlobExt} from './IExporter' | |||
| export type {IImporter, ILoader} from './IImporter' | |||
| @@ -1,5 +1,5 @@ | |||
| import {Camera, Vector3} from 'three' | |||
| import {IObject3D, IObject3DEvent, IObject3DEventTypes, IObject3DUserData, IObjectSetDirtyOptions} from './IObject' | |||
| import {IObject3D, IObject3DEventMap, IObject3DUserData, IObjectSetDirtyOptions} from './IObject' | |||
| import {IShaderPropertiesUpdater} from '../materials' | |||
| import {ICameraControls, TControlsCtor} from './camera/ICameraControls' | |||
| import {CameraView, ICameraView} from './camera/CameraView' | |||
| @@ -54,7 +54,7 @@ export interface ICameraUserData extends IObject3DUserData { | |||
| // [key: string]: any // commented for noe | |||
| } | |||
| export interface ICamera<E extends ICameraEvent = ICameraEvent, ET extends ICameraEventTypes = ICameraEventTypes> extends Camera<E, ET>, IObject3D<E, ET>, IShaderPropertiesUpdater { | |||
| export interface ICamera<TE extends ICameraEventMap = ICameraEventMap> extends Camera<TE>, IObject3D<TE>, IShaderPropertiesUpdater { | |||
| assetType: 'camera' | |||
| readonly isCamera: true | |||
| setDirty(options?: ICameraSetDirtyOptions): void; | |||
| @@ -63,8 +63,8 @@ export interface ICamera<E extends ICameraEvent = ICameraEvent, ET extends ICame | |||
| readonly isPerspectiveCamera?: boolean; | |||
| readonly isOrthographicCamera?: boolean; | |||
| activateMain(options?: Partial<ICameraEvent>, _internal?: boolean, _refresh?: boolean): void; | |||
| deactivateMain(options?: Partial<ICameraEvent>, _internal?: boolean, _refresh?: boolean): void; | |||
| activateMain(options?: Omit<ICameraEventMap['activateMain'], 'bubbleToParent'>, _internal?: boolean, _refresh?: boolean): void; | |||
| deactivateMain(options?: Omit<ICameraEventMap['activateMain'], 'bubbleToParent'>, _internal?: boolean, _refresh?: boolean): void; | |||
| /** | |||
| * @deprecated use `this` instead | |||
| @@ -155,7 +155,7 @@ export interface ICamera<E extends ICameraEvent = ICameraEvent, ET extends ICame | |||
| * Dispatches the `setView` event which triggers the main camera to set its view to this camera's view. | |||
| * @param eventOptions | |||
| */ | |||
| setViewToMain(eventOptions: Partial<ICameraEvent>): void | |||
| setViewToMain(eventOptions: Pick<ICameraEventMap['setView'], 'ui'>): void | |||
| // region inherited type fixes | |||
| // re-declaring from IObject3D because: https://github.com/microsoft/TypeScript/issues/16936 | |||
| @@ -176,11 +176,18 @@ export interface ICamera<E extends ICameraEvent = ICameraEvent, ET extends ICame | |||
| } | |||
| export type ICameraEventTypes = IObject3DEventTypes | 'update'// | string | |||
| export type ICameraEvent = Omit<IObject3DEvent, 'type'> & { | |||
| type: ICameraEventTypes | |||
| camera?: ICamera | null | |||
| // change?: string | |||
| } | |||
| // export type ICameraEventTypes = IObject3DEventTypes | 'update'// | string | |||
| // export type ICameraEvent = Omit<IObject3DEvent, 'type'> & { | |||
| // type: ICameraEventTypes | |||
| // camera?: ICamera | null | |||
| // // change?: string | |||
| // } | |||
| export type ICameraSetDirtyOptions = IObjectSetDirtyOptions | |||
| export interface ICameraEventMap extends IObject3DEventMap { | |||
| update: { | |||
| camera: ICamera | |||
| bubbleToParent: false | |||
| // todo | |||
| } & ICameraSetDirtyOptions | |||
| } | |||
| @@ -1,4 +1,10 @@ | |||
| import {BufferGeometry, Event, NormalBufferAttributes, NormalOrGLBufferAttributes, Vector3} from 'three' | |||
| import { | |||
| BufferGeometry, | |||
| BufferGeometryEventMap, | |||
| NormalBufferAttributes, | |||
| NormalOrGLBufferAttributes, | |||
| Vector3, | |||
| } from 'three' | |||
| import {IUiConfigContainer, UiObjectConfig} from 'uiconfig.js' | |||
| import {AnyOptions} from 'ts-browser-helpers' | |||
| import {IObject3D} from './IObject' | |||
| @@ -12,7 +18,7 @@ export interface IGeometryUserData extends IImportResultUserData{ | |||
| disposeOnIdle?: boolean | |||
| // [key: string]: any // commented for noe | |||
| } | |||
| export interface IGeometry<Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes> extends BufferGeometry<Attributes, IGeometryEvent, IGeometryEventTypes>, IUiConfigContainer { | |||
| export interface IGeometry<Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes, TE extends IGeometryEventMap = IGeometryEventMap> extends BufferGeometry<Attributes, TE>, IUiConfigContainer { | |||
| assetType: 'geometry' | |||
| setDirty(options?: IGeometrySetDirtyOptions): void; | |||
| refreshUi(): void; | |||
| @@ -49,13 +55,22 @@ export interface IGeometry<Attributes extends NormalOrGLBufferAttributes = Norma | |||
| _uiConfig?: UiObjectConfig | |||
| } | |||
| export type IGeometryEventTypes = 'dispose' | 'geometryUpdate' // | string | |||
| export type IGeometryEvent<T extends string = IGeometryEventTypes> = Event & { | |||
| type: T | |||
| bubbleToObject?: boolean // bubble event to parent root | |||
| geometry?: IGeometry | |||
| // change?: string | |||
| } | |||
| // export type IGeometryEventTypes = 'dispose' | 'geometryUpdate' // | string | |||
| // export type IGeometryEvent<T extends string = IGeometryEventTypes> = Event & { | |||
| // type: T | |||
| // bubbleToObject?: boolean // bubble event to parent root | |||
| // geometry?: IGeometry | |||
| // // change?: string | |||
| // } | |||
| export type IGeometrySetDirtyOptions = AnyOptions & {bubbleToObject?: boolean} | |||
| export type IGeometryEventMap = BufferGeometryEventMap | |||
| declare module 'three'{ | |||
| export interface BufferGeometryEventMap{ | |||
| geometryUpdate: { | |||
| geometry: IGeometry | |||
| bubbleToObject?: boolean | |||
| } | |||
| } | |||
| } | |||
| @@ -1,4 +1,16 @@ | |||
| import type {Color, Event, IUniform, Material, MaterialParameters, Shader} from 'three' | |||
| import { | |||
| BufferGeometry, | |||
| Camera, | |||
| Color, | |||
| IUniform, | |||
| Material, | |||
| MaterialEventMap, | |||
| MaterialParameters, | |||
| Object3D, | |||
| Scene, | |||
| Shader, | |||
| WebGLRenderer, | |||
| } from 'three' | |||
| import type {IDisposable, IJSONSerializable} from 'ts-browser-helpers' | |||
| import type {MaterialExtension} from '../materials' | |||
| import type {ChangeEvent, IUiConfigContainer} from 'uiconfig.js' | |||
| @@ -9,18 +21,65 @@ import type {ITexture} from './ITexture' | |||
| import type {IImportResultUserData} from '../assetmanager' | |||
| export type IMaterialParameters = MaterialParameters & {customMaterialExtensions?: MaterialExtension[]} | |||
| export type IMaterialEventTypes = 'dispose' | 'materialUpdate' | 'beforeRender' | 'beforeCompile' | 'afterRender' | 'textureUpdate' | 'beforeDeserialize' | |||
| export type IMaterialEvent<T extends string = IMaterialEventTypes> = Event & { | |||
| type: T | |||
| bubbleToObject?: boolean | |||
| bubbleToParent?: boolean | |||
| material?: IMaterial | |||
| texture?: ITexture | |||
| oldTexture?: ITexture | |||
| // export type IMaterialEventTypes = 'dispose' | 'materialUpdate' | 'beforeRender' | 'beforeCompile' | 'afterRender' | 'textureUpdate' | 'beforeDeserialize' | |||
| // export type IMaterialEvent<T extends string = IMaterialEventTypes> = Event & { | |||
| // type: T | |||
| // bubbleToObject?: boolean | |||
| // bubbleToParent?: boolean | |||
| // material?: IMaterial | |||
| // | |||
| // texture?: ITexture | |||
| // oldTexture?: ITexture | |||
| // | |||
| // uiChangeEvent?: ChangeEvent | |||
| // } | |||
| export interface IMaterialEventMap extends MaterialEventMap{ | |||
| beforeCompile: { | |||
| shader: Shader | |||
| renderer: WebGLRenderer | |||
| } | |||
| beforeRender: { | |||
| renderer: WebGLRenderer | |||
| scene: Scene | |||
| camera: Camera | |||
| geometry: BufferGeometry | |||
| object: Object3D | |||
| } | |||
| afterRender: { | |||
| renderer: WebGLRenderer | |||
| scene: Scene | |||
| camera: Camera | |||
| geometry: BufferGeometry | |||
| object: Object3D | |||
| } | |||
| /** | |||
| * For internal use | |||
| */ | |||
| beforeDeserialize: { | |||
| data: unknown | |||
| meta?: SerializationMetaType | |||
| bubbleToObject: boolean | |||
| bubbleToParent: boolean | |||
| } | |||
| } | |||
| uiChangeEvent?: ChangeEvent | |||
| declare module 'three'{ | |||
| export interface MaterialEventMap{ | |||
| materialUpdate: { | |||
| bubbleToObject?: boolean | |||
| bubbleToParent?: boolean | |||
| uiChangeEvent?: ChangeEvent | |||
| } & IMaterialSetDirtyOptions | |||
| textureUpdate: { | |||
| texture: ITexture | |||
| bubbleToObject?: boolean | |||
| bubbleToParent?: boolean | |||
| uiChangeEvent?: ChangeEvent | |||
| } | |||
| } | |||
| } | |||
| export interface IMaterialSetDirtyOptions extends ISetDirtyCommonOptions{ | |||
| /** | |||
| * @default true | |||
| @@ -125,7 +184,7 @@ export interface IMaterialUserData extends IImportResultUserData{ | |||
| postTonemap?: boolean | |||
| } | |||
| export interface IMaterial<E extends IMaterialEvent = IMaterialEvent, ET = IMaterialEventTypes> extends Material<E, ET>, IJSONSerializable, IDisposable, IUiConfigContainer { | |||
| export interface IMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends Material<TE>, IJSONSerializable, IDisposable, IUiConfigContainer { | |||
| constructor: { | |||
| TYPE: string | |||
| TypeSlug: string | |||
| @@ -1,26 +1,118 @@ | |||
| import {IDisposable} from 'ts-browser-helpers' | |||
| import {IMaterial} from './IMaterial' | |||
| import {Event, Object3D, Vector3} from 'three' | |||
| import {IMaterial, IMaterialEventMap} from './IMaterial' | |||
| import {EventListener, Object3D, Object3DEventMap, Vector3} from 'three' | |||
| import {ChangeEvent, IUiConfigContainer, UiObjectConfig} from 'uiconfig.js' | |||
| import {IGeometry, IGeometryEvent} from './IGeometry' | |||
| import {IGeometry, IGeometryEventMap} from './IGeometry' | |||
| import {IImportResultUserData} from '../assetmanager' | |||
| import {GLTF} from 'three/examples/jsm/loaders/GLTFLoader.js' | |||
| export type IObject3DEventTypes = 'dispose' | 'materialUpdate' | 'objectUpdate' | 'textureUpdate' | 'geometryChanged' | | |||
| 'materialChanged' | 'geometryUpdate' | 'added' | 'removed' | 'select' | 'beforeDeserialize' | | |||
| 'setView' | 'activateMain' | 'cameraUpdate' // from camera | |||
| // | string | |||
| export interface IObject3DEvent<T extends string = IObject3DEventTypes> extends Event { | |||
| type: T | |||
| object?: IObject3D // object that triggered the event, target might be parent in case of bubbleToParent | |||
| bubbleToParent?: boolean // bubble event to parent root | |||
| change?: string | |||
| material?: IMaterial|undefined|IMaterial[] // from materialUpdate and materialChanged | |||
| oldMaterial?: IMaterial|undefined|IMaterial[] // from materialChanged | |||
| geometry?: IGeometry|undefined // from geometryUpdate, geometryChanged | |||
| oldGeometry?: IGeometry|undefined // from geometryChanged | |||
| source?: any | |||
| import {ICamera, type ICameraSetDirtyOptions} from './ICamera' | |||
| // export type IObject3DEventTypes = 'dispose' | 'materialUpdate' | 'objectUpdate' | 'textureUpdate' | 'geometryChanged' | | |||
| // 'materialChanged' | 'geometryUpdate' | 'added' | 'removed' | 'select' | 'beforeDeserialize' | | |||
| // 'setView' | 'activateMain' | 'cameraUpdate' // from camera | |||
| // | string | |||
| // export interface IObject3DEvent<T extends string = IObject3DEventTypes> extends Event { | |||
| // type: T | |||
| // object?: IObject3D // object that triggered the event, target might be parent in case of bubbleToParent | |||
| // bubbleToParent?: boolean // bubble event to parent root | |||
| // change?: string // todo - add to new type... | |||
| // material?: IMaterial|undefined|IMaterial[] // from materialUpdate and materialChanged | |||
| // oldMaterial?: IMaterial|undefined|IMaterial[] // from materialChanged | |||
| // geometry?: IGeometry|undefined // from geometryUpdate, geometryChanged | |||
| // oldGeometry?: IGeometry|undefined // from geometryChanged | |||
| // source?: any // todo - add to new type... | |||
| // } | |||
| declare module 'three'{ | |||
| export interface Object3DEventMap{ | |||
| select: { // todo | |||
| ui?: boolean | |||
| focusCamera?: boolean | |||
| bubbleToParent?: boolean | |||
| object: IObject3D | |||
| value?: IObject3D /* | Material*/ // todo is this required? | |||
| source?: string // who is triggering the event. so that recursive events can be prevented | |||
| } | |||
| } | |||
| } | |||
| // [key: keyof Object3DEventMap]: Object3DEventMap[key] & { | |||
| // bubbleToParent?: boolean | |||
| // } | |||
| export interface IObject3DEventMap extends Object3DEventMap{ | |||
| dispose: { | |||
| // object: IObject3D | |||
| // todo | |||
| bubbleToParent: false | |||
| } | |||
| materialUpdate: { | |||
| // object: IObject3D | |||
| material: IMaterial|IMaterial[] | |||
| } | |||
| objectUpdate: { | |||
| object: IObject3D | |||
| change?: string | |||
| args?: any[] | |||
| bubbleToParent: boolean | |||
| } | |||
| textureUpdate: { | |||
| // object: IObject3D | |||
| // todo | |||
| } | |||
| geometryChanged: { | |||
| object: IObject3D | |||
| geometry: IGeometry|null | |||
| oldGeometry: IGeometry|null | |||
| bubbleToParent: boolean | |||
| } | |||
| materialChanged: { | |||
| object: IObject3D | |||
| material: IMaterial|IMaterial[]|null | |||
| oldMaterial: IMaterial|IMaterial[]|null | |||
| bubbleToParent: boolean | |||
| } | |||
| geometryUpdate: { | |||
| object: IObject3D | |||
| geometry: IGeometry | |||
| // oldGeometry: IGeometry | |||
| bubbleToParent: boolean | |||
| } | |||
| added: { | |||
| // object: IObject3D | |||
| // todo | |||
| } | |||
| removed: { | |||
| // object: IObject3D | |||
| // todo | |||
| } | |||
| beforeDeserialize: { // from material | |||
| material: IMaterial | |||
| // todo | |||
| } & IMaterialEventMap['beforeDeserialize'] | |||
| setView: { | |||
| ui?: boolean | |||
| camera: ICamera | |||
| bubbleToParent: boolean | |||
| // object: IObject3D | |||
| // todo | |||
| } | |||
| activateMain: { | |||
| ui?: boolean | |||
| camera?: ICamera | null | |||
| bubbleToParent: boolean | |||
| // object: IObject3D | |||
| // todo | |||
| } | |||
| cameraUpdate: { | |||
| ui?: boolean | |||
| camera?: ICamera | |||
| // object: IObject3D | |||
| bubbleToParent: boolean | |||
| // todo | |||
| } & ICameraSetDirtyOptions | |||
| } | |||
| // Record<keyof IObject3DEventMap0, IObject3DEventMap0[keyof IObject3DEventMap0] & { | |||
| // // bubbleToParent?: boolean | |||
| // }> | |||
| export interface ISetDirtyCommonOptions { | |||
| /** | |||
| @@ -58,7 +150,24 @@ export interface IObjectSetDirtyOptions extends ISetDirtyCommonOptions{ | |||
| */ | |||
| sceneUpdate?: boolean // update scene after setting dirty | |||
| [key: string]: any | |||
| source?: string // who is triggering the event. so that recursive events can be prevented | |||
| // from onChange3 etc. | |||
| key?: string | |||
| /** | |||
| * Set to true if this is the last value in a user input chain. (like when mouse up on slider) | |||
| */ | |||
| last?: boolean | |||
| /** | |||
| * Indicates that this change in from an `undo` operation. | |||
| */ | |||
| undo?: boolean | |||
| // value: any; | |||
| // oldValue: any; | |||
| // [key: string]: any | |||
| } | |||
| export interface IObjectProcessor { // todo, should be viewer | |||
| @@ -156,7 +265,7 @@ export interface IObject3DUserData extends IImportResultUserData { | |||
| [key: string]: any | |||
| } | |||
| export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEventTypes> extends Object3D<E, ET>, IUiConfigContainer, IDisposable { | |||
| export interface IObject3D<TE extends IObject3DEventMap = IObject3DEventMap> extends Object3D<TE>, IUiConfigContainer { | |||
| assetType: 'model' | 'light' | 'camera' | 'widget' | |||
| isLight?: boolean | |||
| isCamera?: boolean | |||
| @@ -248,7 +357,8 @@ export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEvent | |||
| // eslint-disable-next-line @typescript-eslint/naming-convention | |||
| _onGeometryUpdate?: (e: IGeometryEvent<'geometryUpdate'>) => void | |||
| _onGeometryUpdate?: EventListener<IGeometryEventMap['geometryUpdate'], 'geometryUpdate', IGeometry> | |||
| objectProcessor?: IObjectProcessor | |||
| @@ -276,3 +386,4 @@ export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEvent | |||
| // endregion | |||
| } | |||
| @@ -1,15 +1,5 @@ | |||
| import {PartialRecord} from 'ts-browser-helpers' | |||
| import { | |||
| Blending, | |||
| Clock, | |||
| Event, | |||
| ShaderMaterial, | |||
| Texture, | |||
| Vector2, | |||
| Vector4, | |||
| WebGLRenderer, | |||
| WebGLRenderTarget, | |||
| } from 'three' | |||
| import {Blending, Clock, ShaderMaterial, Texture, Vector2, Vector4, WebGLRenderer, WebGLRenderTarget} from 'three' | |||
| import {CreateRenderTargetOptions, IRenderTarget, RenderTargetManager} from '../rendering' | |||
| import {IShaderPropertiesUpdater} from '../materials' | |||
| import {EffectComposer2, IPassID, IPipelinePass} from '../postprocessing' | |||
| @@ -19,24 +9,30 @@ import {BlobExt} from '../assetmanager' | |||
| export type TThreeRendererMode = 'shadowMapRender' | 'backgroundRender' | 'sceneRender' | 'opaqueRender' | 'transparentRender' | 'transmissionRender' | 'mainRenderPass' | 'screenSpaceRendering' | |||
| export type TThreeRendererModeUserData = PartialRecord<TThreeRendererMode, boolean> | |||
| export interface IAnimationLoopEvent extends Event{ | |||
| export interface IAnimationLoopEvent { | |||
| renderer: IWebGLRenderer | |||
| deltaTime: number | |||
| time: number | |||
| xrFrame?: XRFrame | |||
| } | |||
| export interface IRenderManagerUpdateEvent extends Event{ | |||
| change: 'registerPass' | 'unregisterPass' | 'useLegacyLights' | 'passRefresh' | 'size' | 'rebuild' | string | |||
| data: any | |||
| pass: IPipelinePass | |||
| export interface IRenderManagerUpdateEvent { | |||
| change?: 'registerPass' | 'unregisterPass' | 'useLegacyLights' | 'passRefresh' | 'size' | 'rebuild' | string | |||
| data?: any | |||
| pass?: IPipelinePass | |||
| } | |||
| export type IRenderManagerEvent = Partial<IAnimationLoopEvent>&Partial<IRenderManagerUpdateEvent>&Event & { | |||
| [key: string]: any | |||
| export interface IRenderManagerEventMap { | |||
| animationLoop: IAnimationLoopEvent | |||
| update: IRenderManagerUpdateEvent | |||
| resize: object | |||
| contextRestored: object | |||
| contextLost: { | |||
| event: WebGLContextEvent | |||
| } | |||
| } | |||
| export type IRenderManagerEventTypes = 'animationLoop'|'update'|'resize'|'contextLost'|'contextRestored' | |||
| export interface RendererBlitOptions {source?: Texture, viewport?: Vector4, material?: ShaderMaterial, clear?: boolean, respectColorSpace?: boolean, blending?: Blending, transparent?: boolean} | |||
| export interface IRenderManager<E extends IRenderManagerEvent = IRenderManagerEvent, ET extends string = IRenderManagerEventTypes> extends RenderTargetManager<E, ET>, IShaderPropertiesUpdater{ | |||
| export interface IRenderManager<TE extends IRenderManagerEventMap = IRenderManagerEventMap> extends RenderTargetManager<TE>, IShaderPropertiesUpdater{ | |||
| readonly renderer: IWebGLRenderer | |||
| readonly needsRender: boolean | |||
| rebuildPipeline(setDirty?: boolean): void | |||
| @@ -1,9 +1,10 @@ | |||
| import {IObject3D, IObject3DEvent, IObject3DEventTypes, IObject3DUserData, IObjectSetDirtyOptions} from './IObject' | |||
| import {Color, Scene} from 'three' | |||
| import {IObject3D, IObject3DEventMap, IObject3DUserData, IObjectSetDirtyOptions} from './IObject' | |||
| import {Color, Scene, Texture} from 'three' | |||
| import {IShaderPropertiesUpdater} from '../materials' | |||
| import {ICamera} from './ICamera' | |||
| import {Box3B} from '../three' | |||
| import {ITexture} from './ITexture' | |||
| import {IGeometry} from './IGeometry' | |||
| export interface AddObjectOptions { | |||
| /** | |||
| @@ -62,21 +63,90 @@ export interface AddObjectOptions { | |||
| } | |||
| // | string | |||
| export type ISceneEventTypes = IObject3DEventTypes | 'sceneUpdate' | 'addSceneObject' | | |||
| 'mainCameraChange' | 'mainCameraUpdate' | 'environmentChanged' | 'backgroundChanged' | 'renderCameraChange' | | |||
| 'update' | // todo: deprecate, use 'sceneUpdate' instead | |||
| 'textureAdded' | // todo remove | |||
| 'activeCameraChange' | 'activeCameraUpdate' | // todo: deprecate | |||
| 'sceneMaterialUpdate' // todo deprecate: use 'materialUpdate' instead | |||
| // export type ISceneEventTypes = | |||
| // 'update' // todo: deprecate, use 'sceneUpdate' instead | |||
| // | string | |||
| export interface ISceneEvent<T extends string = ISceneEventTypes> extends IObject3DEvent<T> { | |||
| scene?: IScene | null | |||
| // export interface ISceneEvent<T extends string = ISceneEventTypes> extends IObject3DEvent<T> { | |||
| // scene?: IScene | null | |||
| // | |||
| // hierarchyChanged?: boolean // for 'sceneUpdate' event | |||
| // // change?: string | |||
| // } | |||
| export interface ISceneEventMap extends IObject3DEventMap { | |||
| sceneUpdate: { | |||
| hierarchyChanged?: boolean | |||
| refreshScene?: boolean | |||
| object?: IObject3D | |||
| change?: ISceneEventMap['objectUpdate']['change'] | |||
| // args?: any[] | |||
| bubbleToParent?: boolean // objectUpdate, geometryUpdate, geometryChanged | |||
| geometry?: IGeometry|null // geometryUpdate and geometryChanged | |||
| oldGeometry?: IGeometry|null // geometryChanged | |||
| /** | |||
| * @deprecated use {@link refreshScene} instead | |||
| */ | |||
| sceneUpdate?: boolean | |||
| } & ISceneSetDirtyOptions | |||
| addSceneObject: { | |||
| object: IObject3D | |||
| options?: AddObjectOptions | |||
| geometryChanged?: boolean | |||
| updateGround?: boolean | |||
| } | |||
| mainCameraChange: { | |||
| lastCamera: ICamera | |||
| camera: ICamera | |||
| } | |||
| mainCameraUpdate: IObject3DEventMap['cameraUpdate'] | |||
| renderCameraChange: { | |||
| lastCamera: ICamera | undefined | |||
| camera: ICamera | |||
| }, | |||
| // sceneUpdate: { | |||
| // change?: string | |||
| // sceneUpdate?: boolean | |||
| // refreshScene?: boolean | |||
| // hierarchyChanged: boolean | |||
| // geometryChanged: boolean | |||
| // } | |||
| environmentChanged: { | |||
| environment: ITexture|null | |||
| } | |||
| backgroundChanged: { | |||
| background: Texture | Color | 'environment' | null | |||
| backgroundColor: Color | null | |||
| } | |||
| // textureAdded: { | |||
| // texture: ITexture | |||
| // } | |||
| hierarchyChanged?: boolean // for 'sceneUpdate' event | |||
| // change?: string | |||
| /** | |||
| * @deprecated use {@link mainCameraChange} instead | |||
| */ | |||
| activeCameraChange: ISceneEventMap['mainCameraChange'] | |||
| /** | |||
| * @deprecated use {@link mainCameraUpdate} instead | |||
| */ | |||
| activeCameraUpdate: ISceneEventMap['mainCameraUpdate'] | |||
| /** | |||
| * @deprecated use {@link materialUpdate} instead | |||
| */ | |||
| sceneMaterialUpdate: IObject3DEventMap['materialUpdate'] | |||
| /** | |||
| * @deprecated use {@link objectUpdate} or {@link sceneUpdate} instead | |||
| */ | |||
| update: IObject3DEventMap['objectUpdate'] | |||
| } | |||
| export interface ISceneSetDirtyOptions extends IObjectSetDirtyOptions{ | |||
| refreshScene?: boolean // duplicated declaration from parent intentionally | |||
| } | |||
| export type ISceneSetDirtyOptions = IObjectSetDirtyOptions | |||
| export type ISceneUserData = IObject3DUserData | |||
| @@ -93,8 +163,8 @@ export interface IWidget { | |||
| dispose?(): void | |||
| } | |||
| export interface IScene<E extends ISceneEvent = ISceneEvent, ET extends ISceneEventTypes = ISceneEventTypes> | |||
| extends Scene<E, ET>, IObject3D<E, ET>, IShaderPropertiesUpdater { | |||
| export interface IScene<TE extends ISceneEventMap = ISceneEventMap> | |||
| extends Scene<TE>, IObject3D<TE>, IShaderPropertiesUpdater { | |||
| readonly visible: boolean; | |||
| readonly isScene: true; | |||
| /** | |||
| @@ -1,6 +1,5 @@ | |||
| import {IMaterial} from './IMaterial' | |||
| import {Event, Source, Texture} from 'three' | |||
| import {ChangeEvent} from 'uiconfig.js' | |||
| import {Source, Texture, TextureEventMap} from 'three' | |||
| import {IRenderTarget} from '../rendering' | |||
| export interface ITextureUserData{ | |||
| @@ -12,14 +11,17 @@ export interface ITextureUserData{ | |||
| */ | |||
| disposeOnIdle?: boolean | |||
| } | |||
| export type ITextureEventTypes = 'dispose' | 'update' | |||
| export type ITextureEvent<T extends string = ITextureEventTypes> = Event & { | |||
| type: T | |||
| texture?: ITexture | |||
| uiChangeEvent?: ChangeEvent | |||
| } | |||
| export interface ITexture extends Texture { | |||
| // export type ITextureEventTypes = 'dispose' | 'update' | |||
| // export type ITextureEvent<T extends string = ITextureEventTypes> = Event & { | |||
| // type: T | |||
| // texture?: ITexture | |||
| // uiChangeEvent?: ChangeEvent | |||
| // } | |||
| export type ITextureEventMap = TextureEventMap | |||
| export interface ITexture<TE extends ITextureEventMap = ITextureEventMap> extends Texture<TE> { | |||
| assetType?: 'texture' | |||
| userData: ITextureUserData | |||
| readonly isTexture: true | |||
| @@ -1,4 +1,4 @@ | |||
| import {Event, EventDispatcher, Quaternion, Vector3} from 'three' | |||
| import {EventDispatcher, Quaternion, Vector3} from 'three' | |||
| import {onChange, serializable, serialize} from 'ts-browser-helpers' | |||
| import {IUiConfigContainer, uiButton, uiInput, uiNumber, UiObjectConfig, uiPanelContainer, uiVector} from 'uiconfig.js' | |||
| import {ICamera} from '../ICamera' | |||
| @@ -17,9 +17,16 @@ export interface ICameraView extends IUiConfigContainer{ | |||
| delete(camera?: ICamera): void | |||
| } | |||
| export interface CameraViewEventMap { | |||
| setView: {camera?: ICamera, view: ICameraView} | |||
| animateView: {camera?: ICamera, duration?: number, view: ICameraView} | |||
| updateView: {camera?: ICamera, view: ICameraView} | |||
| deleteView: {camera?: ICamera, view: ICameraView} | |||
| } | |||
| @serializable('CameraView') | |||
| @uiPanelContainer('Camera View') | |||
| export class CameraView extends EventDispatcher<Event, 'setView'|'animateView'|'updateView'|'deleteView'> implements ICameraView, IUiConfigContainer { | |||
| export class CameraView extends EventDispatcher<CameraViewEventMap> implements ICameraView, IUiConfigContainer { | |||
| uuid = generateUUID() | |||
| @onChange(CameraView.prototype._nameChanged) | |||
| @serialize() @uiInput() name = 'Camera View' | |||
| @@ -1,7 +1,11 @@ | |||
| import {IUiConfigContainer} from 'uiconfig.js' | |||
| import {Camera, Event, EventDispatcher, Object3D, Vector3} from 'three' | |||
| import {Camera, EventDispatcher, Object3D, Vector3} from 'three' | |||
| export interface ICameraControls<TEvents = 'change'|string> extends IUiConfigContainer<void, 'panel'>, EventDispatcher<Event, TEvents> { | |||
| export interface ICameraControlsEventMap { | |||
| change: object | |||
| } | |||
| export interface ICameraControls<TE extends ICameraControlsEventMap = ICameraControlsEventMap> extends IUiConfigContainer<void, 'panel'>, EventDispatcher<TE> { | |||
| object: Object3D | |||
| enabled: boolean | |||
| @@ -1,7 +1,7 @@ | |||
| import {Camera, Event, IUniform, Object3D, OrthographicCamera, Vector3} from 'three' | |||
| import {Camera, IUniform, Object3D, OrthographicCamera, Vector3} from 'three' | |||
| import {generateUiConfig, uiInput, uiNumber, UiObjectConfig, uiToggle, uiVector} from 'uiconfig.js' | |||
| import {onChange, onChange2, onChange3, serialize} from 'ts-browser-helpers' | |||
| import type {ICamera, ICameraEvent, ICameraUserData, TCameraControlsMode} from '../ICamera' | |||
| import type {ICamera, ICameraEventMap, ICameraUserData, TCameraControlsMode} from '../ICamera' | |||
| import {ICameraSetDirtyOptions} from '../ICamera' | |||
| import type {ICameraControls, TControlsCtor} from './ICameraControls' | |||
| import {OrbitControls3} from '../../three/controls/OrbitControls3' | |||
| @@ -14,7 +14,7 @@ import {CameraView, ICameraView} from './CameraView' | |||
| // todo: extract out common functions with perspective camera into iCameraCommons | |||
| // todo: maybe change domElement to some wrapper/base class of viewer | |||
| export class OrthographicCamera2 extends OrthographicCamera implements ICamera { | |||
| export class OrthographicCamera2<TE extends ICameraEventMap = ICameraEventMap> extends OrthographicCamera<TE&ICameraEventMap> implements ICamera<TE&ICameraEventMap> { | |||
| assetType = 'camera' as const | |||
| get controls(): ICameraControls | undefined { | |||
| return this._controls | |||
| @@ -214,13 +214,17 @@ export class OrthographicCamera2 extends OrthographicCamera implements ICamera { | |||
| // region refreshing | |||
| setDirty(options?: ICameraSetDirtyOptions|Event): void { | |||
| setDirty(options?: ICameraSetDirtyOptions): void { | |||
| if (!this._positionWorld) return // class not initialized | |||
| if (!options?.key || ['zoom', 'left', 'right', 'top', 'bottom', 'aspect', 'frustumSize'].includes(options.key)) { | |||
| // noinspection SuspiciousTypeOfGuard it can be string when called from bindToValue | |||
| const changeKey = typeof options === 'string' ? options : options?.key | |||
| if (!changeKey || ['zoom', 'left', 'right', 'top', 'bottom', 'aspect', 'frustumSize'].includes(changeKey)) { | |||
| this.updateProjectionMatrix() | |||
| } | |||
| if (typeof options === 'string') options = undefined | |||
| this.getWorldPosition(this._positionWorld) | |||
| iCameraCommons.setDirty.call(this, options) | |||
| @@ -416,7 +420,7 @@ export class OrthographicCamera2 extends OrthographicCamera implements ICamera { | |||
| this.copy(camera, undefined, distanceFromTarget, worldSpace) | |||
| } | |||
| setViewToMain(eventOptions: Partial<ICameraEvent>) { | |||
| setViewToMain(eventOptions: Omit<ICameraEventMap['setView'], 'camera'|'bubbleToParent'>) { | |||
| this.dispatchEvent({type: 'setView', ...eventOptions, camera: this, bubbleToParent: true}) | |||
| } | |||
| @@ -538,7 +542,7 @@ export class OrthographicCamera2 extends OrthographicCamera implements ICamera { | |||
| clone: (recursive?: boolean) => this | |||
| add: (...object: IObject3D[]) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ICameraEvent) => void | |||
| // dispatchEvent: (event: ICameraEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,7 +1,7 @@ | |||
| import {Camera, Event, IUniform, Object3D, PerspectiveCamera, Vector3} from 'three' | |||
| import {Camera, IUniform, Object3D, PerspectiveCamera, Vector3} from 'three' | |||
| import {generateUiConfig, uiInput, UiObjectConfig, uiSlider, uiToggle, uiVector} from 'uiconfig.js' | |||
| import {onChange, onChange2, onChange3, serialize} from 'ts-browser-helpers' | |||
| import type {ICamera, ICameraEvent, ICameraUserData, TCameraControlsMode} from '../ICamera' | |||
| import type {ICamera, ICameraEventMap, ICameraUserData, TCameraControlsMode} from '../ICamera' | |||
| import {ICameraSetDirtyOptions} from '../ICamera' | |||
| import type {ICameraControls, TControlsCtor} from './ICameraControls' | |||
| import {OrbitControls3} from '../../three/controls/OrbitControls3' | |||
| @@ -13,7 +13,7 @@ import {makeICameraCommonUiConfig} from '../object/IObjectUi' | |||
| import {CameraView, ICameraView} from './CameraView' | |||
| // todo: maybe change domElement to some wrapper/base class of viewer | |||
| export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera { | |||
| export class PerspectiveCamera2<TE extends ICameraEventMap = ICameraEventMap> extends PerspectiveCamera<TE&ICameraEventMap> implements ICamera<TE&ICameraEventMap> { | |||
| assetType = 'camera' as const | |||
| get controls(): ICameraControls | undefined { | |||
| return this._controls | |||
| @@ -206,10 +206,14 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera { | |||
| // region refreshing | |||
| setDirty(options?: ICameraSetDirtyOptions|Event): void { | |||
| setDirty(options?: ICameraSetDirtyOptions): void { | |||
| if (!this._positionWorld) return // class not initialized | |||
| if (!options?.key || options?.key === 'fov' || options?.key === 'zoom') this.updateProjectionMatrix() | |||
| // noinspection SuspiciousTypeOfGuard it can be string when called from bindToValue | |||
| const changeKey = typeof options === 'string' ? options : options?.key | |||
| if (!changeKey || changeKey === 'fov' || changeKey === 'zoom') this.updateProjectionMatrix() | |||
| if (typeof options === 'string') options = undefined | |||
| this.getWorldPosition(this._positionWorld) | |||
| @@ -423,7 +427,7 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera { | |||
| this.copy(camera, undefined, distanceFromTarget, worldSpace) | |||
| } | |||
| setViewToMain(eventOptions: Partial<ICameraEvent>) { | |||
| setViewToMain(eventOptions: Omit<ICameraEventMap['setView'], 'camera'|'bubbleToParent'>): void { | |||
| this.dispatchEvent({type: 'setView', ...eventOptions, camera: this, bubbleToParent: true}) | |||
| } | |||
| @@ -611,7 +615,7 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera { | |||
| clone: (recursive?: boolean) => this | |||
| add: (...object: IObject3D[]) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ICameraEvent) => void | |||
| // dispatchEvent: (event: ICameraEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,9 +1,9 @@ | |||
| import {BufferGeometry, NormalBufferAttributes, NormalOrGLBufferAttributes} from 'three' | |||
| import type {IGeometry, IGeometryEvent, IGeometryEventTypes} from '../IGeometry' | |||
| import type {IGeometry, IGeometryEventMap} from '../IGeometry' | |||
| import {iGeometryCommons} from './iGeometryCommons' | |||
| import type {IObject3D} from '../IObject' | |||
| export class BufferGeometry2<Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes> extends BufferGeometry<Attributes, IGeometryEvent, IGeometryEventTypes> implements IGeometry<Attributes> { | |||
| export class BufferGeometry2<Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes, TE extends IGeometryEventMap = IGeometryEventMap> extends BufferGeometry<Attributes, TE> implements IGeometry<Attributes, TE> { | |||
| assetType: 'geometry' // dont set the value here since its checked in upgradeGeometry | |||
| center2 = iGeometryCommons.center2 | |||
| setDirty = iGeometryCommons.setDirty | |||
| @@ -1,14 +1,14 @@ | |||
| export {PerspectiveCamera2, PerspectiveCamera0} from './camera/PerspectiveCamera2' | |||
| export {OrthographicCamera2, OrthographicCamera0} from './camera/OrthographicCamera2' | |||
| export {CameraView, type ICameraView} from './camera/CameraView' | |||
| export {CameraView, type ICameraView, type CameraViewEventMap} from './camera/CameraView' | |||
| export {ExtendedShaderMaterial} from './material/ExtendedShaderMaterial' | |||
| export {PhysicalMaterial, type PhysicalMaterialEventTypes, MeshStandardMaterial2} from './material/PhysicalMaterial' | |||
| export {PhysicalMaterial, MeshStandardMaterial2} from './material/PhysicalMaterial' | |||
| export {ShaderMaterial2} from './material/ShaderMaterial2' | |||
| export {ObjectShaderMaterial, type ObjectShaderMaterialEventTypes} from './material/ObjectShaderMaterial' | |||
| export {UnlitMaterial, type UnlitMaterialEventTypes, MeshBasicMaterial2} from './material/UnlitMaterial' | |||
| export {UnlitLineMaterial, type UnlitLineMaterialEventTypes, LineBasicMaterial2} from './material/UnlitLineMaterial' | |||
| export {LineMaterial2, type LineMaterial2EventTypes} from './material/LineMaterial2' | |||
| export {LegacyPhongMaterial, type PhongMaterialEventTypes} from './material/LegacyPhongMaterial' | |||
| export {ObjectShaderMaterial} from './material/ObjectShaderMaterial' | |||
| export {UnlitMaterial, MeshBasicMaterial2} from './material/UnlitMaterial' | |||
| export {UnlitLineMaterial, LineBasicMaterial2} from './material/UnlitLineMaterial' | |||
| export {LineMaterial2} from './material/LineMaterial2' | |||
| export {LegacyPhongMaterial} from './material/LegacyPhongMaterial' | |||
| export {Mesh2} from './object/Mesh2' | |||
| export {BufferGeometry2} from './geometry/BufferGeometry2' | |||
| export {AmbientLight2} from './light/AmbientLight2' | |||
| @@ -25,12 +25,12 @@ export {iMaterialCommons} from './material/iMaterialCommons' | |||
| export {upgradeTexture} from './ITexture' | |||
| export {upgradeWebGLRenderer, setThreeRendererMode} from './IRenderer' | |||
| export {RootScene} from './object/RootScene' | |||
| export type {ICameraControls, TControlsCtor} from './camera/ICameraControls' | |||
| export type {ICamera, ICameraEvent, ICameraEventTypes, ICameraUserData, TCameraControlsMode, ICameraSetDirtyOptions} from './ICamera' | |||
| export type {IGeometry, IGeometryUserData, IGeometryEvent, IGeometryEventTypes, IGeometrySetDirtyOptions} from './IGeometry' | |||
| export type {IMaterial, IMaterialEvent, IMaterialEventTypes, IMaterialParameters, IMaterialUserData, IMaterialSetDirtyOptions, IMaterialTemplate, IMaterialGenerator} from './IMaterial' | |||
| export type {IObject3D, IObject3DEvent, IObjectSetDirtyOptions, IObjectProcessor, IObject3DEventTypes, IObject3DUserData} from './IObject' | |||
| export type {IRenderManager, IRenderManagerOptions, IWebGLRenderer, IRenderManagerEventTypes, IAnimationLoopEvent, TThreeRendererMode, TThreeRendererModeUserData, IRenderManagerUpdateEvent, IRenderManagerEvent, RendererBlitOptions} from './IRenderer' | |||
| export type {IScene, ISceneEvent, ISceneEventTypes, ISceneSetDirtyOptions, AddObjectOptions, ISceneUserData, IWidget} from './IScene' | |||
| export type {ITexture, ITextureUserData, ITextureEvent, ITextureEventTypes} from './ITexture' | |||
| export type {ILight, ILightEvent, ILightEventTypes} from './light/ILight' | |||
| export type {ICameraControls, TControlsCtor, ICameraControlsEventMap} from './camera/ICameraControls' | |||
| export type {ICamera, ICameraEventMap, ICameraUserData, TCameraControlsMode, ICameraSetDirtyOptions} from './ICamera' | |||
| export type {IGeometry, IGeometryUserData, IGeometryEventMap, IGeometrySetDirtyOptions} from './IGeometry' | |||
| export type {IMaterial, IMaterialEventMap, IMaterialParameters, IMaterialUserData, IMaterialSetDirtyOptions, IMaterialTemplate, IMaterialGenerator} from './IMaterial' | |||
| export type {IObject3D, IObject3DEventMap, ISetDirtyCommonOptions, IObjectSetDirtyOptions, IObjectProcessor, IObject3DUserData} from './IObject' | |||
| export type {IRenderManager, IRenderManagerOptions, IWebGLRenderer, IRenderManagerEventMap, IAnimationLoopEvent, TThreeRendererMode, TThreeRendererModeUserData, IRenderManagerUpdateEvent, RendererBlitOptions} from './IRenderer' | |||
| export type {IScene, ISceneEventMap, ISceneSetDirtyOptions, AddObjectOptions, ISceneUserData, IWidget} from './IScene' | |||
| export type {ITexture, ITextureUserData, ITextureEventMap} from './ITexture' | |||
| export type {ILight} from './light/ILight' | |||
| @@ -1,5 +1,5 @@ | |||
| import {AmbientLight, Color, ColorRepresentation} from 'three' | |||
| import {ILight, ILightEvent} from './ILight' | |||
| import {ILight} from './ILight' | |||
| import {iLightCommons} from '../object/iLightCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {uiColor, UiObjectConfig, uiPanelContainer, uiSlider, uiToggle} from 'uiconfig.js' | |||
| @@ -65,7 +65,7 @@ export class AmbientLight2 extends AmbientLight implements ILight<undefined> { | |||
| copy: (source: AmbientLight|IObject3D, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ILightEvent) => void | |||
| // dispatchEvent: (event: ILightEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,5 +1,5 @@ | |||
| import {Color, ColorRepresentation, DirectionalLight, DirectionalLightShadow, Euler, Vector2, Vector3} from 'three' | |||
| import {ILight, ILightEvent, ILightEventTypes} from './ILight' | |||
| import {ILight} from './ILight' | |||
| import {iLightCommons} from '../object/iLightCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {uiColor, uiNumber, UiObjectConfig, uiPanelContainer, uiSlider, uiToggle, uiVector} from 'uiconfig.js' | |||
| @@ -16,10 +16,7 @@ import {bindToValue} from '../../three' | |||
| */ | |||
| // todo: add Light section in the readme detailing these ...2 lights | |||
| @uiPanelContainer('Directional Light') | |||
| export class DirectionalLight2< | |||
| E extends ILightEvent = ILightEvent, | |||
| ET extends ILightEventTypes = ILightEventTypes | |||
| > extends DirectionalLight<E, ET> implements ILight<DirectionalLightShadow> { | |||
| export class DirectionalLight2 extends DirectionalLight implements ILight<DirectionalLightShadow> { | |||
| assetType = 'light' as const | |||
| setDirty = iLightCommons.setDirty | |||
| refreshUi = iLightCommons.refreshUi | |||
| @@ -138,7 +135,7 @@ export class DirectionalLight2< | |||
| copy: (source: DirectionalLight|IObject3D, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ILightEvent) => void | |||
| // dispatchEvent: (event: ILightEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,5 +1,5 @@ | |||
| import {Color, ColorRepresentation, HemisphereLight, Vector3} from 'three' | |||
| import {ILight, ILightEvent} from './ILight' | |||
| import {ILight} from './ILight' | |||
| import {iLightCommons} from '../object/iLightCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {uiColor, UiObjectConfig, uiPanelContainer, uiSlider, uiToggle, uiVector} from 'uiconfig.js' | |||
| @@ -69,7 +69,7 @@ export class HemisphereLight2 extends HemisphereLight implements ILight<undefine | |||
| copy: (source: HemisphereLight|IObject3D, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ILightEvent) => void | |||
| // dispatchEvent: (event: ILightEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,11 +1,10 @@ | |||
| import {Light, LightShadow, Object3D} from 'three' | |||
| import {IObject3D, IObject3DEvent, IObject3DEventTypes, IObject3DUserData} from '../IObject' | |||
| import {IObject3D, IObject3DEventMap, IObject3DUserData} from '../IObject' | |||
| export interface ILight< | |||
| TShadowSupport extends LightShadow | undefined = LightShadow | undefined, | |||
| E extends ILightEvent = ILightEvent, | |||
| ET extends ILightEventTypes = ILightEventTypes | |||
| > extends Light<TShadowSupport, E, ET>, IObject3D<E, ET> { | |||
| TE extends IObject3DEventMap = IObject3DEventMap | |||
| > extends Light<TShadowSupport, TE>, IObject3D<TE> { | |||
| assetType: 'light' | |||
| readonly isLight: true | |||
| @@ -43,9 +42,9 @@ export interface ILight< | |||
| // endregion | |||
| } | |||
| export type ILightEventTypes = IObject3DEventTypes | 'lightUpdate'// | string | |||
| export type ILightEvent = Omit<IObject3DEvent, 'type'> & { | |||
| type: ILightEventTypes | |||
| light?: ILight | null | |||
| // change?: string | |||
| } | |||
| // export type ILightEventTypes = IObject3DEventTypes | 'lightUpdate'// | string | |||
| // export type ILightEvent = Omit<IObject3DEvent, 'type'> & { | |||
| // type: ILightEventTypes | |||
| // light?: ILight | null | |||
| // // change?: string | |||
| // } | |||
| @@ -1,5 +1,5 @@ | |||
| import {Color, ColorRepresentation, PointLight, PointLightShadow, Vector2, Vector3} from 'three' | |||
| import {ILight, ILightEvent} from './ILight' | |||
| import {ILight} from './ILight' | |||
| import {iLightCommons} from '../object/iLightCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {uiColor, uiNumber, UiObjectConfig, uiPanelContainer, uiSlider, uiToggle, uiVector} from 'uiconfig.js' | |||
| @@ -127,7 +127,7 @@ export class PointLight2 extends PointLight implements ILight<PointLightShadow> | |||
| copy: (source: PointLight|IObject3D, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ILightEvent) => void | |||
| // dispatchEvent: (event: ILightEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,5 +1,5 @@ | |||
| import {Color, ColorRepresentation, RectAreaLight} from 'three' | |||
| import {ILight, ILightEvent} from './ILight' | |||
| import {ILight} from './ILight' | |||
| import {iLightCommons} from '../object/iLightCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {uiColor, uiNumber, UiObjectConfig, uiPanelContainer, uiSlider, uiToggle} from 'uiconfig.js' | |||
| @@ -74,7 +74,7 @@ export class RectAreaLight2 extends RectAreaLight implements ILight<undefined> { | |||
| copy: (source: RectAreaLight|IObject3D, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ILightEvent) => void | |||
| // dispatchEvent: (event: ILightEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,5 +1,5 @@ | |||
| import {Color, ColorRepresentation, Euler, SpotLight, SpotLightShadow, Vector2, Vector3} from 'three' | |||
| import {ILight, ILightEvent} from './ILight' | |||
| import {ILight} from './ILight' | |||
| import {iLightCommons} from '../object/iLightCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {uiColor, uiInput, uiNumber, UiObjectConfig, uiPanelContainer, uiSlider, uiToggle, uiVector} from 'uiconfig.js' | |||
| @@ -139,7 +139,7 @@ export class SpotLight2 extends SpotLight implements ILight<SpotLightShadow> { | |||
| copy: (source: SpotLight|IObject3D, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ILightEvent) => void | |||
| // dispatchEvent: (event: ILightEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -1,4 +1,5 @@ | |||
| import { | |||
| BaseEvent, | |||
| Color, | |||
| IUniform, | |||
| Material, | |||
| @@ -12,8 +13,7 @@ import { | |||
| import {UiObjectConfig} from 'uiconfig.js' | |||
| import { | |||
| IMaterial, | |||
| IMaterialEvent, | |||
| IMaterialEventTypes, | |||
| IMaterialEventMap, | |||
| IMaterialGenerator, | |||
| IMaterialParameters, | |||
| IMaterialTemplate, | |||
| @@ -27,9 +27,7 @@ import {IObject3D} from '../IObject' | |||
| import {iMaterialUI} from './IMaterialUi' | |||
| import {makeSamplerUi} from '../../ui/image-ui' | |||
| export type PhongMaterialEventTypes = IMaterialEventTypes | '' | |||
| export class LegacyPhongMaterial extends MeshPhongMaterial<IMaterialEvent, PhongMaterialEventTypes> implements IMaterial<IMaterialEvent, PhongMaterialEventTypes> { | |||
| export class LegacyPhongMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends MeshPhongMaterial<TE> implements IMaterial<TE> { | |||
| declare ['constructor']: typeof LegacyPhongMaterial | |||
| public static readonly TypeSlug = 'phongmat' | |||
| @@ -44,8 +42,7 @@ export class LegacyPhongMaterial extends MeshPhongMaterial<IMaterialEvent, Phong | |||
| readonly setDirty = iMaterialCommons.setDirty | |||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | |||
| clone(): this {return iMaterialCommons.clone(super.clone).call(this)} | |||
| dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| dispatchEvent<T extends Extract<keyof (TE&IMaterialEventMap), string>>(event: BaseEvent<T> & (TE&IMaterialEventMap)[T]): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| generator?: IMaterialGenerator | |||
| envMap: ITexture | null = null | |||
| @@ -135,7 +132,7 @@ export class LegacyPhongMaterial extends MeshPhongMaterial<IMaterialEvent, Phong | |||
| /** | |||
| * Serializes this material to JSON. | |||
| * @param meta - metadata for serialization | |||
| * @param _internal - Calls only super.toJSON, does internal three.js serialization and @serialize tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material | |||
| * @param _internal - Calls only super.toJSON, does internal three.js serialization and `@serialize` tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material | |||
| */ | |||
| toJSON(meta?: SerializationMetaType, _internal = false): any { | |||
| if (_internal) return { | |||
| @@ -1,28 +1,19 @@ | |||
| import {generateUiConfig, uiColor, uiInput, uiNumber, UiObjectConfig, uiToggle, uiVector} from 'uiconfig.js' | |||
| import {Color, IUniform, Material, Shader, Vector2, WebGLRenderer} from 'three' | |||
| import {BaseEvent, Color, IUniform, Material, Shader, Vector2, WebGLRenderer} from 'three' | |||
| import {SerializationMetaType, shaderReplaceString, ThreeSerialization} from '../../utils' | |||
| import { | |||
| IMaterial, | |||
| IMaterialEvent, | |||
| IMaterialEventTypes, | |||
| IMaterialGenerator, | |||
| IMaterialParameters, | |||
| IMaterialTemplate, | |||
| } from '../IMaterial' | |||
| import {IMaterial, IMaterialEventMap, IMaterialGenerator, IMaterialParameters, IMaterialTemplate} from '../IMaterial' | |||
| import {MaterialExtension} from '../../materials' | |||
| import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {iMaterialUI} from './IMaterialUi' | |||
| import {LineMaterial, type LineMaterialParameters} from 'three/examples/jsm/lines/LineMaterial.js' | |||
| export type LineMaterial2EventTypes = IMaterialEventTypes | '' | |||
| /** | |||
| * And extension of three.js LineMaterial that can be assigned to lines, and support threepipe features, uiconfig, and serialization. | |||
| * | |||
| * @category Materials | |||
| */ | |||
| export class LineMaterial2 extends LineMaterial<IMaterialEvent, LineMaterial2EventTypes> implements IMaterial<IMaterialEvent, LineMaterial2EventTypes> { | |||
| export class LineMaterial2<TE extends IMaterialEventMap = IMaterialEventMap> extends LineMaterial<TE> implements IMaterial<TE> { | |||
| declare ['constructor']: typeof LineMaterial2 | |||
| public static readonly TypeSlug = 'lmat' | |||
| public static readonly TYPE = 'LineMaterial2' // not using .type because it is used by three.js | |||
| @@ -34,7 +25,7 @@ export class LineMaterial2 extends LineMaterial<IMaterialEvent, LineMaterial2Eve | |||
| readonly setDirty = iMaterialCommons.setDirty | |||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | |||
| clone(): this {return iMaterialCommons.clone(super.clone).call(this)} | |||
| dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| dispatchEvent<T extends Extract<keyof (TE&IMaterialEventMap), string>>(event: BaseEvent<T> & (TE&IMaterialEventMap)[T]): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| generator?: IMaterialGenerator | |||
| @@ -147,7 +138,7 @@ export class LineMaterial2 extends LineMaterial<IMaterialEvent, LineMaterial2Eve | |||
| /** | |||
| * Serializes this material to JSON. | |||
| * @param meta - metadata for serialization | |||
| * @param _internal - Calls only super.toJSON, does internal three.js serialization and @serialize tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material | |||
| * @param _internal - Calls only super.toJSON, does internal three.js serialization and `@serialize` tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material | |||
| */ | |||
| toJSON(meta?: SerializationMetaType, _internal = false): any { | |||
| if (_internal) return { | |||
| @@ -1,9 +1,8 @@ | |||
| import {IUniform, Material, Shader, ShaderMaterial, ShaderMaterialParameters, WebGLRenderer} from 'three' | |||
| import {BaseEvent, IUniform, Material, Shader, ShaderMaterial, ShaderMaterialParameters, WebGLRenderer} from 'three' | |||
| import {generateUiConfig, UiObjectConfig} from 'uiconfig.js' | |||
| import { | |||
| IMaterial, | |||
| IMaterialEvent, | |||
| IMaterialEventTypes, | |||
| IMaterialEventMap, | |||
| IMaterialGenerator, | |||
| IMaterialParameters, | |||
| IMaterialTemplate, | |||
| @@ -15,14 +14,12 @@ import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {iMaterialUI} from './IMaterialUi' | |||
| export type ObjectShaderMaterialEventTypes = IMaterialEventTypes | '' | |||
| /** | |||
| * And extension of three.js ShaderMaterial that can be assigned to objects, and support threepipe features, uiconfig, and serialization. | |||
| * | |||
| * @category Materials | |||
| */ | |||
| export class ObjectShaderMaterial extends ShaderMaterial<IMaterialEvent, ObjectShaderMaterialEventTypes> implements IMaterial<IMaterialEvent, ObjectShaderMaterialEventTypes> { | |||
| export class ObjectShaderMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends ShaderMaterial<TE> implements IMaterial<TE> { | |||
| declare ['constructor']: typeof ObjectShaderMaterial | |||
| public static readonly TypeSlug = 'shmat' | |||
| @@ -37,7 +34,7 @@ export class ObjectShaderMaterial extends ShaderMaterial<IMaterialEvent, ObjectS | |||
| readonly setDirty = iMaterialCommons.setDirty | |||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | |||
| clone(): this {return iMaterialCommons.clone(super.clone).call(this)} | |||
| dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| dispatchEvent<T extends Extract<keyof (TE&IMaterialEventMap), string>>(event: BaseEvent<T> & (TE&IMaterialEventMap)[T]): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| generator?: IMaterialGenerator | |||
| @@ -1,5 +1,6 @@ | |||
| import {generateUiConfig, UiObjectConfig} from 'uiconfig.js' | |||
| import { | |||
| BaseEvent, | |||
| BufferGeometry, | |||
| Camera, | |||
| Color, | |||
| @@ -17,8 +18,7 @@ import { | |||
| import {SerializationMetaType, shaderReplaceString, ThreeSerialization} from '../../utils' | |||
| import { | |||
| IMaterial, | |||
| IMaterialEvent, | |||
| IMaterialEventTypes, | |||
| IMaterialEventMap, | |||
| IMaterialGenerator, | |||
| IMaterialParameters, | |||
| IMaterialTemplate, | |||
| @@ -30,14 +30,12 @@ import {IObject3D} from '../IObject' | |||
| import {ITexture} from '../ITexture' | |||
| import {iMaterialUI} from './IMaterialUi' | |||
| export type PhysicalMaterialEventTypes = IMaterialEventTypes | '' | |||
| /** | |||
| * And extension of three.js MeshPhysicalMaterial that can be assigned to objects, and support threepipe features, uiconfig, and serialization. | |||
| * | |||
| * @category Materials | |||
| */ | |||
| export class PhysicalMaterial extends MeshPhysicalMaterial<IMaterialEvent, PhysicalMaterialEventTypes> implements IMaterial<IMaterialEvent, PhysicalMaterialEventTypes> { | |||
| export class PhysicalMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends MeshPhysicalMaterial<TE & IMaterialEventMap> implements IMaterial<TE> { | |||
| declare ['constructor']: typeof PhysicalMaterial | |||
| public static readonly TypeSlug = 'pmat' | |||
| public static readonly TYPE = 'PhysicalMaterial' // not using .type because it is used by three.js | |||
| @@ -51,7 +49,7 @@ export class PhysicalMaterial extends MeshPhysicalMaterial<IMaterialEvent, Physi | |||
| readonly setDirty = iMaterialCommons.setDirty | |||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | |||
| clone(): this {return iMaterialCommons.clone(super.clone).call(this)} | |||
| dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| dispatchEvent<T extends Extract<keyof (TE&IMaterialEventMap), string>>(event: BaseEvent<T> & (TE&IMaterialEventMap)[T]): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| generator?: IMaterialGenerator | |||
| @@ -1,4 +1,5 @@ | |||
| import { | |||
| BaseEvent, | |||
| BufferGeometry, | |||
| Camera, | |||
| IUniform, | |||
| @@ -10,11 +11,11 @@ import { | |||
| ShaderMaterialParameters, | |||
| WebGLRenderer, | |||
| } from 'three' | |||
| import {IMaterial, IMaterialEvent, IMaterialEventTypes, IMaterialParameters, IMaterialUserData} from '../IMaterial' | |||
| import {IMaterial, IMaterialEventMap, IMaterialParameters, IMaterialUserData} from '../IMaterial' | |||
| import {MaterialExtension} from '../../materials' | |||
| import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' | |||
| export class ShaderMaterial2<E extends IMaterialEvent = IMaterialEvent, ET = IMaterialEventTypes> extends ShaderMaterial<E, ET> implements IMaterial<E, ET> { | |||
| export class ShaderMaterial2<TE extends IMaterialEventMap = IMaterialEventMap> extends ShaderMaterial<TE> implements IMaterial<TE> { | |||
| declare ['constructor']: typeof ShaderMaterial2 | |||
| static readonly TypeSlug = 'shaderMat' | |||
| @@ -47,7 +48,7 @@ export class ShaderMaterial2<E extends IMaterialEvent = IMaterialEvent, ET = IMa | |||
| readonly setDirty = iMaterialCommons.setDirty | |||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | |||
| clone(): this {return iMaterialCommons.clone(super.clone).call(this)} | |||
| dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| dispatchEvent<T extends Extract<keyof (TE&IMaterialEventMap), string>>(event: BaseEvent<T> & (TE&IMaterialEventMap)[T]): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| readonly isRawShaderMaterial: boolean | |||
| @@ -1,9 +1,17 @@ | |||
| import {Color, IUniform, LineBasicMaterial, LineBasicMaterialParameters, Material, Shader, WebGLRenderer} from 'three' | |||
| import { | |||
| BaseEvent, | |||
| Color, | |||
| IUniform, | |||
| LineBasicMaterial, | |||
| LineBasicMaterialParameters, | |||
| Material, | |||
| Shader, | |||
| WebGLRenderer, | |||
| } from 'three' | |||
| import {UiObjectConfig} from 'uiconfig.js' | |||
| import { | |||
| IMaterial, | |||
| IMaterialEvent, | |||
| IMaterialEventTypes, | |||
| IMaterialEventMap, | |||
| IMaterialGenerator, | |||
| IMaterialParameters, | |||
| IMaterialTemplate, | |||
| @@ -16,14 +24,12 @@ import {IObject3D} from '../IObject' | |||
| import {makeSamplerUi} from '../../ui/image-ui' | |||
| import {iMaterialUI} from './IMaterialUi' | |||
| export type UnlitLineMaterialEventTypes = IMaterialEventTypes | '' | |||
| /** | |||
| * And extension of three.js LineBasicMaterial that can be assigned to lines, and support threepipe features, uiconfig, and serialization. | |||
| * | |||
| * @category Materials | |||
| */ | |||
| export class UnlitLineMaterial extends LineBasicMaterial<IMaterialEvent, UnlitLineMaterialEventTypes> implements IMaterial<IMaterialEvent, UnlitLineMaterialEventTypes> { | |||
| export class UnlitLineMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends LineBasicMaterial<TE> implements IMaterial<TE> { | |||
| declare ['constructor']: typeof UnlitLineMaterial | |||
| public static readonly TypeSlug = 'blmat' | |||
| @@ -38,7 +44,7 @@ export class UnlitLineMaterial extends LineBasicMaterial<IMaterialEvent, UnlitLi | |||
| readonly setDirty = iMaterialCommons.setDirty | |||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | |||
| clone(): this {return iMaterialCommons.clone(super.clone).call(this)} | |||
| dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| dispatchEvent<T extends Extract<keyof (TE&IMaterialEventMap), string>>(event: BaseEvent<T> & (TE&IMaterialEventMap)[T]): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| generator?: IMaterialGenerator | |||
| @@ -116,7 +122,7 @@ export class UnlitLineMaterial extends LineBasicMaterial<IMaterialEvent, UnlitLi | |||
| /** | |||
| * Serializes this material to JSON. | |||
| * @param meta - metadata for serialization | |||
| * @param _internal - Calls only super.toJSON, does internal three.js serialization and @serialize tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material | |||
| * @param _internal - Calls only super.toJSON, does internal three.js serialization and `@serialize` tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material | |||
| */ | |||
| toJSON(meta?: SerializationMetaType, _internal = false): any { | |||
| if (_internal) return { | |||
| @@ -1,4 +1,5 @@ | |||
| import { | |||
| BaseEvent, | |||
| Color, | |||
| IUniform, | |||
| Material, | |||
| @@ -11,8 +12,7 @@ import { | |||
| import {generateUiConfig, UiObjectConfig} from 'uiconfig.js' | |||
| import { | |||
| IMaterial, | |||
| IMaterialEvent, | |||
| IMaterialEventTypes, | |||
| IMaterialEventMap, | |||
| IMaterialGenerator, | |||
| IMaterialParameters, | |||
| IMaterialTemplate, | |||
| @@ -25,14 +25,12 @@ import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' | |||
| import {IObject3D} from '../IObject' | |||
| import {iMaterialUI} from './IMaterialUi' | |||
| export type UnlitMaterialEventTypes = IMaterialEventTypes | '' | |||
| /** | |||
| * And extension of three.js MeshBasicMaterial that can be assigned to objects, and support threepipe features, uiconfig, and serialization. | |||
| * | |||
| * @category Materials | |||
| */ | |||
| export class UnlitMaterial extends MeshBasicMaterial<IMaterialEvent, UnlitMaterialEventTypes> implements IMaterial<IMaterialEvent, UnlitMaterialEventTypes> { | |||
| export class UnlitMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends MeshBasicMaterial<TE> implements IMaterial<TE> { | |||
| declare ['constructor']: typeof UnlitMaterial | |||
| public static readonly TypeSlug = 'bmat' | |||
| @@ -47,7 +45,7 @@ export class UnlitMaterial extends MeshBasicMaterial<IMaterialEvent, UnlitMateri | |||
| readonly setDirty = iMaterialCommons.setDirty | |||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | |||
| clone(): this {return iMaterialCommons.clone(super.clone).call(this)} | |||
| dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| dispatchEvent<T extends Extract<keyof (TE&IMaterialEventMap), string>>(event: BaseEvent<T> & (TE&IMaterialEventMap)[T]): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)} | |||
| generator?: IMaterialGenerator | |||
| @@ -18,7 +18,7 @@ import {copyProps} from 'ts-browser-helpers' | |||
| import {copyMaterialUserData} from '../../utils/serialization' | |||
| import {MaterialExtender, MaterialExtension} from '../../materials' | |||
| import {IScene} from '../IScene' | |||
| import {IMaterial, IMaterialEvent, IMaterialSetDirtyOptions} from '../IMaterial' | |||
| import {IMaterial, IMaterialEventMap, IMaterialSetDirtyOptions} from '../IMaterial' | |||
| import {isInScene} from '../../three/utils' | |||
| /** | |||
| @@ -106,12 +106,12 @@ export const iMaterialCommons = { | |||
| this.setDirty?.() | |||
| return this | |||
| }, | |||
| dispose: (superDispose: Material<any, any>['dispose']): IMaterial['dispose'] => | |||
| dispose: (superDispose: Material['dispose']): IMaterial['dispose'] => | |||
| function(this: IMaterial, force = true): void { | |||
| if (!force && (this.userData.disposeOnIdle === false || isInScene(this))) return | |||
| superDispose.call(this) | |||
| }, | |||
| clone: (superClone: Material<any, any>['clone']): IMaterial['clone'] => | |||
| clone: (superClone: Material['clone']): IMaterial['clone'] => | |||
| function(this: IMaterial): IMaterial { | |||
| if (!this.userData.cloneId) { | |||
| this.userData.cloneId = '0' | |||
| @@ -130,10 +130,10 @@ export const iMaterialCommons = { | |||
| return material | |||
| }, | |||
| dispatchEvent: (superDispatchEvent: Material['dispatchEvent']): IMaterial['dispatchEvent'] => | |||
| function(this: IMaterial, event: IMaterialEvent): void { | |||
| function(this: IMaterial, event): void { | |||
| superDispatchEvent.call(this, event) | |||
| const type = event.type | |||
| if (event.bubbleToObject && ( | |||
| if ((event as IMaterialEventMap['materialUpdate']).bubbleToObject && ( | |||
| type === 'beforeDeserialize' || type === 'materialUpdate' || type === 'textureUpdate' // todo - add more events | |||
| )) { | |||
| this.appliedMeshes.forEach(m => m.dispatchEvent({...event, material: this, type})) | |||
| @@ -1,14 +1,14 @@ | |||
| import {Mesh} from 'three' | |||
| import {IObject3D, IObject3DUserData} from '../IObject' | |||
| import {IObject3D, IObject3DEventMap, IObject3DUserData} from '../IObject' | |||
| import {iObjectCommons} from './iObjectCommons' | |||
| import {IMaterial} from '../IMaterial' | |||
| import {IGeometry} from '../IGeometry' | |||
| import {ILightEvent} from '../light/ILight' | |||
| export class Mesh2< | |||
| TGeometry extends IGeometry = IGeometry, | |||
| TMaterial extends IMaterial | IMaterial[] = IMaterial | IMaterial[] | |||
| > extends Mesh<TGeometry, TMaterial> implements IObject3D { | |||
| TMaterial extends IMaterial | IMaterial[] = IMaterial | IMaterial[], | |||
| TE extends IObject3DEventMap = IObject3DEventMap | |||
| > extends Mesh<TGeometry, TMaterial, TE> implements IObject3D<TE> { | |||
| assetType = 'model' as const | |||
| setDirty = iObjectCommons.setDirty | |||
| refreshUi = iObjectCommons.refreshUi | |||
| @@ -43,7 +43,6 @@ export class Mesh2< | |||
| copy: (source: Mesh2|IObject3D, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ILightEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| dispose: (removeFromParent?: boolean) => void | |||
| @@ -9,24 +9,22 @@ import { | |||
| UVMapping, | |||
| Vector3, | |||
| } from 'three' | |||
| import type {IObject3D, IObjectProcessor} from '../IObject' | |||
| import type {IObject3D, IObject3DEventMap, IObjectProcessor} from '../IObject' | |||
| import {type ICamera} from '../ICamera' | |||
| import {autoGPUInstanceMeshes, bindToValue, Box3B} from '../../three' | |||
| import {AnyOptions, onChange2, onChange3, serialize} from 'ts-browser-helpers' | |||
| import {PerspectiveCamera2} from '../camera/PerspectiveCamera2' | |||
| import {ThreeSerialization} from '../../utils' | |||
| import {ITexture} from '../ITexture' | |||
| import {AddObjectOptions, IScene, ISceneEvent, ISceneEventTypes, ISceneSetDirtyOptions, IWidget} from '../IScene' | |||
| import {AddObjectOptions, IScene, ISceneEventMap, ISceneSetDirtyOptions, IWidget} from '../IScene' | |||
| import {iObjectCommons} from './iObjectCommons' | |||
| import {RootSceneImportResult} from '../../assetmanager' | |||
| import {uiButton, uiColor, uiConfig, uiFolderContainer, uiImage, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js' | |||
| import {IGeometry} from '../IGeometry' | |||
| import {getFittingDistance} from '../../three/utils/camera' | |||
| export type TCamera = ICamera | |||
| @uiFolderContainer('Root Scene') | |||
| export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements IScene<ISceneEvent, ISceneEventTypes> { | |||
| export class RootScene<TE extends ISceneEventMap = ISceneEventMap> extends Scene<TE&ISceneEventMap> implements IScene<TE> { | |||
| readonly isRootScene = true | |||
| assetType = 'model' as const | |||
| @@ -34,7 +32,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| // private _processors = new ObjectProcessorMap<'environment' | 'background'>() | |||
| // private _sceneObjects: ISceneObject[] = [] | |||
| private _mainCamera: TCamera | null = null | |||
| private _mainCamera: ICamera | null = null | |||
| /** | |||
| * The root object where all imported objects are added. | |||
| */ | |||
| @@ -96,17 +94,17 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| /** | |||
| * The default camera in the scene | |||
| */ | |||
| @uiConfig() @serialize() readonly defaultCamera: TCamera | |||
| @uiConfig() @serialize() readonly defaultCamera: ICamera | |||
| // private _environmentLight?: IEnvironmentLight | |||
| // required just because we don't want activeCamera to be null. | |||
| private _dummyCam = new PerspectiveCamera2('') as TCamera | |||
| private _dummyCam = new PerspectiveCamera2('') as ICamera | |||
| get mainCamera(): TCamera { | |||
| get mainCamera(): ICamera { | |||
| return this._mainCamera || this._dummyCam | |||
| } | |||
| set mainCamera(camera: TCamera | undefined) { | |||
| set mainCamera(camera: ICamera | undefined) { | |||
| const cam = this.mainCamera | |||
| if (!camera) camera = this.defaultCamera | |||
| if (cam === camera) return | |||
| @@ -126,11 +124,11 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| this.setDirty() | |||
| } | |||
| private _renderCamera: TCamera | undefined | |||
| private _renderCamera: ICamera | undefined | |||
| get renderCamera() { | |||
| return this._renderCamera ?? this.mainCamera | |||
| } | |||
| set renderCamera(camera: TCamera) { | |||
| set renderCamera(camera: ICamera) { | |||
| const cam = this._renderCamera | |||
| this._renderCamera = camera | |||
| this.dispatchEvent({type: 'renderCameraChange', lastCamera: cam, camera}) | |||
| @@ -141,7 +139,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| * @param camera | |||
| * @param objectProcessor | |||
| */ | |||
| constructor(camera: TCamera, objectProcessor?: IObjectProcessor) { | |||
| constructor(camera: ICamera, objectProcessor?: IObjectProcessor) { | |||
| super() | |||
| this.setDirty = this.setDirty.bind(this) | |||
| @@ -358,14 +356,14 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| if (options?.refreshScene) { | |||
| this.refreshScene(options) | |||
| } else { | |||
| this.dispatchEvent({type: 'update'}) // todo remove | |||
| this.dispatchEvent({type: 'update', bubbleToParent: false, object: this}) // todo remove | |||
| iObjectCommons.setDirty.call(this, {...options, scene: this}) | |||
| } // this sets dirty in the viewer | |||
| return this | |||
| } | |||
| private _mainCameraUpdate = (e: any) => { | |||
| private _mainCameraUpdate: EventListener<IObject3DEventMap['cameraUpdate'], 'cameraUpdate', ICamera> = (e) => { | |||
| this.setDirty({refreshScene: false}) | |||
| this.refreshActiveCameraNearFar() | |||
| if (e.key === 'fov') this.dollyActiveCameraFov() | |||
| @@ -382,7 +380,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| */ | |||
| // readonly boxHelper: Box3Helper | |||
| refreshScene(event?: Partial<ISceneEvent> & ISceneSetDirtyOptions): this { | |||
| refreshScene(event?: Partial<(ISceneEventMap['objectUpdate']|ISceneEventMap['geometryUpdate']|ISceneEventMap['geometryChanged'])> & ISceneSetDirtyOptions & {type?: keyof ISceneEventMap}): this { | |||
| if (event && event.type === 'objectUpdate' && event.object === this) return this // ignore self | |||
| // todo test the isCamera here. this is for animation object plugin | |||
| if (event?.sceneUpdate === false || event?.refreshScene === false || event?.object?.isCamera) return this.setDirty(event) // so that it doesn't trigger frame fade, shadow refresh etc | |||
| @@ -401,7 +399,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| /** | |||
| * Dispose the scene and clear all resources. | |||
| * @warn Not fully implemented yet, just clears the scene. | |||
| * WARNING - Not fully implemented yet, just clears the scene. | |||
| */ | |||
| dispose(clear = true): void { | |||
| this.disposeSceneModels(false, clear) | |||
| @@ -479,7 +477,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| * This is called automatically every time the camera is updated. | |||
| */ | |||
| refreshActiveCameraNearFar(): void { | |||
| const camera = this.mainCamera as TCamera | |||
| const camera = this.mainCamera as ICamera | |||
| if (!camera) return | |||
| if (!this.autoNearFarEnabled || camera.userData.autoNearFar === false) { | |||
| camera.near = camera.userData.minNearPlane ?? 0.5 | |||
| @@ -516,7 +514,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| * This is called automatically every time the camera fov is updated. | |||
| */ | |||
| dollyActiveCameraFov(): void { | |||
| const camera = this.mainCamera as TCamera | |||
| const camera = this.mainCamera as ICamera | |||
| if (!camera) return | |||
| if (!camera.userData.dollyFov) { | |||
| return | |||
| @@ -552,7 +550,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| * Deserialize the scene properties | |||
| * @param json - object from {@link toJSON} | |||
| * @param meta | |||
| * @returns {this<TCamera>} | |||
| * @returns {this<ICamera>} | |||
| */ | |||
| fromJSON(json: any, meta?: any): this { | |||
| const env = json.environment | |||
| @@ -565,7 +563,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| return this | |||
| } | |||
| addEventListener<T extends ISceneEventTypes>(type: T, listener: EventListener<ISceneEvent, T, this>): void { | |||
| addEventListener<T extends keyof ISceneEventMap>(type: T, listener: EventListener<ISceneEventMap[T], T, this>): void { | |||
| if (type === 'activeCameraChange') console.error('activeCameraChange is deprecated. Use mainCameraChange instead.') | |||
| if (type === 'activeCameraUpdate') console.error('activeCameraUpdate is deprecated. Use mainCameraUpdate instead.') | |||
| if (type === 'sceneMaterialUpdate') console.error('sceneMaterialUpdate is deprecated. Use materialUpdate instead.') | |||
| @@ -586,7 +584,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| copy: (source: this, recursive?: boolean, ...args: any[]) => this | |||
| clone: (recursive?: boolean) => this | |||
| remove: (...object: IObject3D[]) => this | |||
| dispatchEvent: (event: ISceneEvent) => void | |||
| // dispatchEvent: (event: ISceneEvent) => void | |||
| declare parent: IObject3D | null | |||
| declare children: IObject3D[] | |||
| @@ -698,7 +696,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| /** | |||
| * @deprecated | |||
| */ | |||
| get activeCamera(): TCamera { | |||
| get activeCamera(): ICamera { | |||
| console.error('activeCamera is deprecated. Use mainCamera instead.') | |||
| return this.mainCamera | |||
| } | |||
| @@ -706,7 +704,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| /** | |||
| * @deprecated | |||
| */ | |||
| set activeCamera(camera: TCamera | undefined) { | |||
| set activeCamera(camera: ICamera | undefined) { | |||
| console.error('activeCamera is deprecated. Use mainCamera instead.') | |||
| this.mainCamera = camera | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| import {iObjectCommons} from './iObjectCommons' | |||
| import {Camera, Vector3} from 'three' | |||
| import type {ICamera, ICameraEvent, ICameraSetDirtyOptions} from '../ICamera' | |||
| import type {ICamera, ICameraEventMap, ICameraSetDirtyOptions} from '../ICamera' | |||
| export const iCameraCommons = { | |||
| setDirty: function(this: ICamera, options?: ICameraSetDirtyOptions): void { | |||
| @@ -14,11 +14,11 @@ export const iCameraCommons = { | |||
| this.lookAt(this.target) | |||
| } | |||
| // } | |||
| this.dispatchEvent({...options, type: 'update'}) // does not bubble | |||
| this.dispatchEvent({...options, type: 'update', bubbleToParent: false, camera: this}) // does not bubble | |||
| this.dispatchEvent({...options, type: 'cameraUpdate', bubbleToParent: true}) // this sets dirty in the viewer | |||
| iObjectCommons.setDirty.call(this, {refreshScene: false, ...options}) | |||
| }, | |||
| activateMain: function(this: ICamera, options: Partial<ICameraEvent> = {}, _internal = false, _refresh = true): void { | |||
| activateMain: function(this: ICamera, options: Omit<ICameraEventMap['activateMain'], 'bubbleToParent'> = {}, _internal = false, _refresh = true): void { | |||
| if (!_internal) { | |||
| if (options.camera === null) return this.deactivateMain(options, _internal, _refresh) | |||
| return this.dispatchEvent({ | |||
| @@ -37,7 +37,7 @@ export const iCameraCommons = { | |||
| this.setDirty({change: 'activateMain', ...options}) | |||
| // console.log({...this._camera.modelObject.position}) | |||
| }, | |||
| deactivateMain: function(this: ICamera, options: Partial<ICameraEvent> = {}, _internal = false, _refresh = true): void { | |||
| deactivateMain: function(this: ICamera, options: Omit<ICameraEventMap['activateMain'], 'bubbleToParent'> = {}, _internal = false, _refresh = true): void { | |||
| if (!_internal) return this.dispatchEvent({ | |||
| type: 'activateMain', ...options, | |||
| camera: null, | |||
| @@ -7,7 +7,7 @@ export const iLightCommons = { | |||
| if (typeof options === 'string') { // just incase called by decorators | |||
| options = {change: options} | |||
| } | |||
| this.dispatchEvent({bubbleToParent: true, ...options, type: 'lightUpdate', light: this, object: this, args}) // this sets sceneUpdate in root scene | |||
| // this.dispatchEvent({bubbleToParent: true, ...options, type: 'lightUpdate', light: this, object: this, args}) // this sets sceneUpdate in root scene | |||
| iObjectCommons.setDirty.call(this, options, ...args) | |||
| }, | |||
| upgradeLight: upgradeLight, | |||
| @@ -1,9 +1,9 @@ | |||
| import {Event, Matrix4, Mesh, Vector3} from 'three' | |||
| import {IMaterial} from '../IMaterial' | |||
| import {objectHasOwn} from 'ts-browser-helpers' | |||
| import {IObject3D, IObject3DEvent, IObjectProcessor, IObjectSetDirtyOptions} from '../IObject' | |||
| import {IObject3D, IObject3DEventMap, IObjectProcessor, IObjectSetDirtyOptions} from '../IObject' | |||
| import {copyObject3DUserData} from '../../utils' | |||
| import {IGeometry, IGeometryEvent} from '../IGeometry' | |||
| import {IGeometry, IGeometryEventMap} from '../IGeometry' | |||
| import {Box3B} from '../../three' | |||
| import {makeIObject3DUiConfig} from './IObjectUi' | |||
| import {iGeometryCommons} from '../geometry/iGeometryCommons' | |||
| @@ -172,7 +172,7 @@ export const iObjectCommons = { | |||
| }) | |||
| } | |||
| }, | |||
| onGeometryUpdate: function(this: IObject3D, e: IGeometryEvent<'geometryUpdate'>): void { | |||
| onGeometryUpdate: function(this: IObject3D, e: IGeometryEventMap['geometryUpdate']&Event<'geometryUpdate'>): void { | |||
| if (!e.bubbleToObject) return | |||
| this.dispatchEvent({bubbleToParent: true, ...e, object: this, geometry: e.geometry}) | |||
| }, | |||
| @@ -230,7 +230,8 @@ export const iObjectCommons = { | |||
| // todo: check by uuid? | |||
| // Remove old material listeners | |||
| const mats = Array.isArray(this.material) ? [...(this.material as IMaterial[])] : [this.material!] | |||
| const oldMats = this.material | |||
| const mats = Array.isArray(oldMats) ? [...oldMats] : [oldMats!] | |||
| for (const mat of mats) { | |||
| if (!mat) continue | |||
| if (mat.appliedMeshes) { | |||
| @@ -255,7 +256,7 @@ export const iObjectCommons = { | |||
| } | |||
| this._currentMaterial = !materials.length ? null : materials.length !== 1 ? materials : materials[0] || null | |||
| this.dispatchEvent({type: 'materialChanged', material, oldMaterial: mats, object: this, bubbleToParent: true}) | |||
| this.dispatchEvent({type: 'materialChanged', material: this._currentMaterial ?? null, oldMaterial: oldMats ?? null, object: this, bubbleToParent: true}) | |||
| this.refreshUi() | |||
| }, | |||
| setMaterials: function(this: IObject3D, materials: IMaterial[]) { | |||
| @@ -315,7 +316,7 @@ export const iObjectCommons = { | |||
| this._onGeometryUpdate && geometry.addEventListener('geometryUpdate', this._onGeometryUpdate) | |||
| geometry.appliedMeshes.add(this) | |||
| } | |||
| this.dispatchEvent({type: 'geometryChanged', geometry, oldGeometry: geom, bubbleToParent: true}) | |||
| this.dispatchEvent({type: 'geometryChanged', geometry: geometry ?? null, oldGeometry: geom, bubbleToParent: true, object: this}) | |||
| this.refreshUi() | |||
| }, | |||
| @@ -324,9 +325,9 @@ export const iObjectCommons = { | |||
| this.uiConfig?.uiRefresh?.(true, 'postFrame', 1) | |||
| }, | |||
| dispatchEvent: (superDispatch: IObject3D['dispatchEvent']) => | |||
| function(this: IObject3D, event: IObject3DEvent): void { | |||
| if (event.bubbleToParent || this.userData?.__autoBubbleToParentEvents?.includes(event.type)) { | |||
| dispatchEvent: (superDispatch: IObject3D['dispatchEvent']): IObject3D['dispatchEvent'] => | |||
| function(this: IObject3D, event): void { | |||
| if ((event as IObject3DEventMap['objectUpdate']).bubbleToParent || this.userData?.__autoBubbleToParentEvents?.includes(event.type)) { | |||
| // console.log('parent dispatch', e, this.parentRoot, this.parent) | |||
| const pRoot = this.parentRoot || this.parent | |||
| if (this.parentRoot !== this) pRoot?.dispatchEvent(event) | |||
| @@ -349,7 +350,7 @@ export const iObjectCommons = { | |||
| return clone | |||
| }, | |||
| copy: (superCopy: IObject3D['copy']): IObject3D['copy'] => | |||
| function(this: IObject3D|ILight, source: IObject3D, ...args): IObject3D { | |||
| function(this: IObject3D, source: IObject3D, ...args): IObject3D { | |||
| const lightTarget = this.isLight ? (this as ILight).target : null | |||
| const userData = source.userData | |||
| @@ -469,7 +470,7 @@ function upgradeObject3D(this: IObject3D, parent?: IObject3D|undefined, objectPr | |||
| if ((this.isMesh || this.isLine) && !this.userData.__meshSetup) { | |||
| this.userData.__meshSetup = true | |||
| this._onGeometryUpdate = (e: IGeometryEvent) => iObjectCommons.eventCallbacks.onGeometryUpdate.call(this, e) | |||
| this._onGeometryUpdate = (e) => iObjectCommons.eventCallbacks.onGeometryUpdate.call(this, e) | |||
| // Material, Geometry prop init | |||
| iObjectCommons.initMaterial.call(this) | |||
| @@ -1,6 +1,6 @@ | |||
| import {Object3D, Vector3} from 'three' | |||
| import {Easing} from 'popmotion' | |||
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {Box3B} from '../../three' | |||
| import {onChange, serialize, timeout} from 'ts-browser-helpers' | |||
| import {generateUiConfig, uiButton, uiDropdown, uiInput, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js' | |||
| @@ -12,13 +12,20 @@ import {getFittingDistance} from '../../three/utils/camera' | |||
| export interface CameraViewPluginOptions{duration?: number, ease?: EasingFunctionType, interpolateMode?: 'spherical'|'linear'} | |||
| export interface CameraViewPluginEventMap extends AViewerPluginEventMap{ | |||
| viewChange: {view: CameraView} | |||
| startViewChange: {view: CameraView} | |||
| viewAdd: {view: CameraView} | |||
| viewDelete: {view: CameraView} | |||
| } | |||
| /** | |||
| * Camera View Plugin | |||
| * | |||
| * Provides API to save, interact and animate and loop between with multiple camera states/views using the {@link PopmotionPlugin}. | |||
| * | |||
| */ | |||
| export class CameraViewPlugin extends AViewerPluginSync<'viewChange'|'startViewChange'|'viewAdd'|'viewDelete'> { | |||
| export class CameraViewPlugin extends AViewerPluginSync<CameraViewPluginEventMap> { | |||
| static readonly PluginType = 'CameraViews' | |||
| enabled = true | |||
| @@ -1,4 +1,4 @@ | |||
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {absMax, now, onChange, onChange2, PointerDragHelper, serialize} from 'ts-browser-helpers' | |||
| import {uiButton, uiDropdown, uiFolderContainer, uiMonitor, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js' | |||
| import {AnimationAction, AnimationClip, AnimationMixer, LoopOnce, LoopRepeat} from 'three' | |||
| @@ -7,6 +7,12 @@ import {IObject3D} from '../../core' | |||
| import {generateUUID} from '../../three' | |||
| import type {FrameFadePlugin} from '../pipeline/FrameFadePlugin' | |||
| export interface GLTFAnimationPluginEventMap extends AViewerPluginEventMap{ | |||
| checkpointBegin: object | |||
| checkpointEnd: object | |||
| animationStep: {delta: number, time: number} | |||
| } | |||
| /** | |||
| * Manages playback of GLTF animations. | |||
| * | |||
| @@ -22,7 +28,7 @@ import type {FrameFadePlugin} from '../pipeline/FrameFadePlugin' | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('GLTF Animations') | |||
| export class GLTFAnimationPlugin extends AViewerPluginSync<'checkpointEnd'|'checkpointBegin'|'animationStep'> { | |||
| export class GLTFAnimationPlugin extends AViewerPluginSync<GLTFAnimationPluginEventMap> { | |||
| enabled = true | |||
| declare uiConfig: UiObjectConfig | |||
| @@ -28,7 +28,7 @@ export interface AnimationResult{ | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export class PopmotionPlugin extends AViewerPluginSync<''> { | |||
| export class PopmotionPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'PopmotionPlugin' | |||
| enabled = true | |||
| @@ -21,7 +21,7 @@ export interface TSavedTransform { | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export class TransformAnimationPlugin extends AViewerPluginSync<''> { | |||
| export class TransformAnimationPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'TransformAnimationPlugin' | |||
| toJSON: any = undefined | |||
| @@ -1,8 +1,8 @@ | |||
| import {createDiv, onChange, serialize} from 'ts-browser-helpers' | |||
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {uiToggle} from 'uiconfig.js' | |||
| export abstract class AAssetManagerProcessStatePlugin<T extends string = ''> extends AViewerPluginSync<T> { | |||
| export abstract class AAssetManagerProcessStatePlugin<TE extends AViewerPluginEventMap = AViewerPluginEventMap> extends AViewerPluginSync<TE> { | |||
| @uiToggle('Enabled') | |||
| @onChange(AAssetManagerProcessStatePlugin.prototype._onEnabledChange) | |||
| @serialize() enabled = true | |||
| @@ -1,7 +1,7 @@ | |||
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {TControlsCtor} from '../../core' | |||
| export abstract class ACameraControlsPlugin extends AViewerPluginSync<''> { | |||
| export abstract class ACameraControlsPlugin extends AViewerPluginSync { | |||
| readonly enabled = true | |||
| toJSON: any = undefined | |||
| protected abstract _controlsCtor: TControlsCtor | |||
| @@ -1,12 +1,12 @@ | |||
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {IGeometry, iGeometryCommons, IMaterial, ISceneEvent, Mesh2, PhysicalMaterial} from '../../core' | |||
| import {BufferAttribute, BufferGeometry, Euler, InterleavedBufferAttribute, PlaneGeometry, Vector3} from 'three' | |||
| import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {IGeometry, iGeometryCommons, IMaterial, IScene, ISceneEventMap, Mesh2, PhysicalMaterial} from '../../core' | |||
| import {BufferAttribute, BufferGeometry, Euler, InterleavedBufferAttribute, PlaneGeometry, Vector3, Event} from 'three' | |||
| import {onChange, onChange2, serialize} from 'ts-browser-helpers' | |||
| import {bindToValue, OrbitControls3} from '../../three' | |||
| import {uiConfig, uiFolderContainer, uiNumber, uiToggle} from 'uiconfig.js' | |||
| @uiFolderContainer('Ground') | |||
| export class BaseGroundPlugin<TEvent extends string = ''> extends AViewerPluginSync<TEvent> { | |||
| export class BaseGroundPlugin<TE extends AViewerPluginEventMap = AViewerPluginEventMap> extends AViewerPluginSync<TE> { | |||
| public static readonly PluginType: string = 'BaseGroundPlugin' | |||
| public static readonly OldPluginType: string = 'Ground' | |||
| @@ -129,7 +129,7 @@ export class BaseGroundPlugin<TEvent extends string = ''> extends AViewerPluginS | |||
| this._material = undefined | |||
| } | |||
| protected _onSceneUpdate(event?: ISceneEvent) { | |||
| protected _onSceneUpdate(event?: ISceneEventMap['addSceneObject' | 'sceneUpdate'] & Event<'addSceneObject' | 'sceneUpdate', IScene>) { | |||
| if (event?.geometryChanged === false) return | |||
| if (event?.updateGround !== false) | |||
| this.refreshTransform() | |||
| @@ -322,3 +322,9 @@ export class BaseGroundPlugin<TEvent extends string = ''> extends AViewerPluginS | |||
| } | |||
| } | |||
| declare module '../../core/IScene' { | |||
| interface ISceneSetDirtyOptions { | |||
| updateGround?: boolean | |||
| } | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| import {IPassID, IPipelinePass} from '../../postprocessing' | |||
| import {AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer' | |||
| import {AViewerPluginEventMap, AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer' | |||
| import {onChange, serialize} from 'ts-browser-helpers' | |||
| import {SerializationMetaType, wrapThisFunction2} from '../../utils' | |||
| import {uiToggle} from 'uiconfig.js' | |||
| @@ -12,7 +12,7 @@ import {ICamera, IRenderManager, IScene} from '../../core' | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export abstract class PipelinePassPlugin<T extends IPipelinePass, TPassId extends IPassID, TEvent extends string, TViewer extends ThreeViewer=ThreeViewer> extends AViewerPluginSync<TEvent, TViewer> { | |||
| export abstract class PipelinePassPlugin<T extends IPipelinePass, TPassId extends IPassID, TEvent extends AViewerPluginEventMap = AViewerPluginEventMap, TViewer extends ThreeViewer=ThreeViewer> extends AViewerPluginSync<TEvent, TViewer> { | |||
| abstract passId: TPassId | |||
| @serialize() | |||
| @@ -17,7 +17,7 @@ import {Color} from 'three' | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export class MaterialConfiguratorBasePlugin extends AViewerPluginSync<''> { | |||
| export class MaterialConfiguratorBasePlugin extends AViewerPluginSync { | |||
| enabled = true | |||
| public static PluginType = 'MaterialConfiguratorPlugin' | |||
| private _picking: PickingPlugin | undefined | |||
| @@ -19,7 +19,7 @@ import {snapObject} from '../../three' | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export class SwitchNodeBasePlugin extends AViewerPluginSync<''> { | |||
| export class SwitchNodeBasePlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'SwitchNodePlugin' | |||
| enabled = true | |||
| @@ -21,7 +21,7 @@ export interface ExportAssetOptions extends ExportFileOptions { | |||
| * Provides options and methods to export the scene, object GLB or Viewer Config. | |||
| * All the functionality is available in the viewer directly, this provides only a ui-config and maintains state of the options. | |||
| */ | |||
| export class AssetExporterPlugin extends AViewerPluginSync<''> { | |||
| export class AssetExporterPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'AssetExporterPlugin' | |||
| enabled = true | |||
| @@ -5,7 +5,7 @@ import {CanvasSnapshot, CanvasSnapshotOptions} from '../../utils/canvas-snapshot | |||
| import {ProgressivePlugin} from '../pipeline/ProgressivePlugin' | |||
| @uiFolderContainer('Canvas Snapshot (Image Export)') | |||
| export class CanvasSnapshotPlugin extends AViewerPluginSync<''> { | |||
| export class CanvasSnapshotPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'CanvasSnapshotPlugin' | |||
| enabled = true | |||
| @@ -1,6 +1,15 @@ | |||
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {downloadBlob} from 'ts-browser-helpers' | |||
| export interface FileTransferPluginEventMap extends AViewerPluginEventMap{ | |||
| transferFile: { | |||
| path: string | |||
| state: 'exporting'|'done'|'error' | |||
| progress?: number | |||
| name?: string | |||
| } | |||
| } | |||
| /** | |||
| * File Transfer Plugin | |||
| * | |||
| @@ -8,7 +17,7 @@ import {downloadBlob} from 'ts-browser-helpers' | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export class FileTransferPlugin extends AViewerPluginSync<'transferFile'> { | |||
| export class FileTransferPlugin extends AViewerPluginSync<FileTransferPluginEventMap> { | |||
| enabled = true | |||
| static readonly PluginType = 'FileTransferPlugin' | |||
| @@ -25,7 +34,7 @@ export class FileTransferPlugin extends AViewerPluginSync<'transferFile'> { | |||
| } | |||
| readonly defaultActions = { | |||
| exportFile: async(blob: Blob, name: string, _onProgress?: (d: {state?: string, progress?: number})=>void)=>{ | |||
| exportFile: async(blob: Blob, name: string, _onProgress?: (d: {state?: 'exporting'|'done'|'error', progress?: number})=>void)=>{ | |||
| downloadBlob(blob, name) | |||
| }, | |||
| } | |||
| @@ -17,7 +17,7 @@ import {gltfExporterMaterialsVariantsExtensionExport} from './helpers/GLTFMateri | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export class GLTFKHRMaterialVariantsPlugin extends AViewerPluginSync<''> { | |||
| export class GLTFKHRMaterialVariantsPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'GLTFKHRMaterialVariantsPlugin' | |||
| enabled = true | |||
| @@ -6,7 +6,7 @@ import {shaderReplaceString} from '../../utils' | |||
| import {uiPanelContainer, uiSlider, uiToggle, uiVector} from 'uiconfig.js' | |||
| @uiPanelContainer('HDRi Ground') | |||
| export class HDRiGroundPlugin extends AViewerPluginSync<'', ThreeViewer> { | |||
| export class HDRiGroundPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'HDRiGroundPlugin' | |||
| @serialize() | |||
| @@ -17,7 +17,7 @@ import {Vector3} from 'three' | |||
| * @category Plugins | |||
| */ | |||
| @uiPanelContainer('Generate Scene Objects') | |||
| export class Object3DGeneratorPlugin extends AViewerPluginSync<''> { | |||
| export class Object3DGeneratorPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'Object3DGeneratorPlugin' | |||
| enabled = true | |||
| toJSON: any = undefined | |||
| @@ -15,7 +15,7 @@ export interface IObject3DHelper<T extends Object3D&IWidget = Object3D&IWidget>{ | |||
| * A helper is automatically created when any supported light or camera is added to the scene. | |||
| * @category Plugins | |||
| */ | |||
| export class Object3DWidgetsPlugin extends AViewerPluginSync<''> { | |||
| export class Object3DWidgetsPlugin extends AViewerPluginSync { | |||
| @onChange(Object3DWidgetsPlugin.prototype.setDirty) | |||
| enabled = true | |||
| public static readonly PluginType = 'Object3DWidgetsPlugin' | |||
| @@ -33,7 +33,7 @@ export interface SimplifyOptions{ | |||
| * This is a base class and cannot be used directly. | |||
| * See {@link MeshOptSimplifyModifierPlugin} the [simplify-modifier-plugin](https://threepipe.org/examples/#simplify-modifier-plugin) example for a sample implementation. | |||
| */ | |||
| export abstract class SimplifyModifierPlugin extends AViewerPluginSync<''> { | |||
| export abstract class SimplifyModifierPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType: string = 'SimplifyModifierPlugin' | |||
| enabled = true | |||
| toJSON: any = undefined | |||
| @@ -10,13 +10,13 @@ export {ProgressivePlugin, ProgressiveBlendPass} from './pipeline/ProgressivePlu | |||
| export {GBufferPlugin, GBufferMaterial, DepthNormalMaterial} from './pipeline/GBufferPlugin' | |||
| export {DepthBufferPlugin} from './pipeline/DepthBufferPlugin' | |||
| export {NormalBufferPlugin} from './pipeline/NormalBufferPlugin' | |||
| export {FrameFadePlugin, FrameFadeBlendPass, type FrameFadePluginEventTypes} from './pipeline/FrameFadePlugin' | |||
| export type {ProgressivePluginEventTypes, ProgressivePluginTarget} from './pipeline/ProgressivePlugin' | |||
| export type {GBufferPluginEventTypes, GBufferPluginPass, GBufferUpdater, GBufferUpdaterContext, GBufferPluginTarget} from './pipeline/GBufferPlugin' | |||
| export type {DepthBufferPluginEventTypes, DepthBufferPluginPass, DepthBufferPluginTarget} from './pipeline/DepthBufferPlugin' | |||
| export type {NormalBufferPluginEventTypes, NormalBufferPluginPass, NormalBufferPluginTarget} from './pipeline/NormalBufferPlugin' | |||
| export {SSAAPlugin, type SSAAPluginEventTypes} from './pipeline/SSAAPlugin' | |||
| export {SSAOPlugin, SSAOPluginPass, type SSAOPluginEventTypes, type SSAOPluginTarget} from './pipeline/SSAOPlugin' | |||
| export {FrameFadePlugin, FrameFadeBlendPass} from './pipeline/FrameFadePlugin' | |||
| export type {ProgressivePluginTarget} from './pipeline/ProgressivePlugin' | |||
| export type {GBufferPluginPass, GBufferUpdater, GBufferUpdaterContext, GBufferPluginTarget} from './pipeline/GBufferPlugin' | |||
| export type {DepthBufferPluginPass, DepthBufferPluginTarget} from './pipeline/DepthBufferPlugin' | |||
| export type {NormalBufferPluginPass, NormalBufferPluginTarget} from './pipeline/NormalBufferPlugin' | |||
| export {SSAAPlugin} from './pipeline/SSAAPlugin' | |||
| export {SSAOPlugin, SSAOPluginPass, type SSAOPluginTarget} from './pipeline/SSAOPlugin' | |||
| // ui | |||
| export {RenderTargetPreviewPlugin, type RenderTargetBlock} from './ui/RenderTargetPreviewPlugin' | |||
| @@ -72,7 +72,7 @@ export {ParallaxMappingPlugin} from './material/ParallaxMappingPlugin' | |||
| export {FragmentClippingExtensionPlugin, FragmentClippingMode, fragmentClippingGLTFExtension} from './material/FragmentClippingExtensionPlugin' | |||
| // rendering | |||
| export {VirtualCamerasPlugin, type VirtualCamera} from './rendering/VirtualCamerasPlugin' | |||
| export {VirtualCamerasPlugin, type VirtualCamera, type VirtualCamerasPluginEventMap} from './rendering/VirtualCamerasPlugin' | |||
| // configurator | |||
| export {MaterialConfiguratorBasePlugin, type MaterialVariations} from './configurator/MaterialConfiguratorBasePlugin' | |||
| @@ -1,4 +1,4 @@ | |||
| import {type ThreeViewer} from '../../viewer/' | |||
| import {AViewerPluginEventMap, type ThreeViewer} from '../../viewer/' | |||
| // noinspection ES6PreferShortImport | |||
| import {AViewerPluginSync} from '../../viewer/AViewerPlugin' | |||
| import {Dropzone} from '../../utils' | |||
| @@ -36,6 +36,15 @@ export interface DropzonePluginOptions { | |||
| addOptions?: AddAssetOptions | |||
| } | |||
| export interface DropzonePluginEventMap extends AViewerPluginEventMap{ | |||
| drop: { | |||
| files: Map<string, File> | |||
| imported?: Map<string, (ImportResult | undefined)[]> | |||
| assets?: (ImportResult | undefined)[] | |||
| nativeEvent: DragEvent | |||
| } | |||
| } | |||
| /** | |||
| * Dropzone Plugin | |||
| * | |||
| @@ -45,7 +54,7 @@ export interface DropzonePluginOptions { | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Dropzone') | |||
| export class DropzonePlugin extends AViewerPluginSync<'drop'> { | |||
| export class DropzonePlugin extends AViewerPluginSync<DropzonePluginEventMap> { | |||
| static readonly PluginType = 'Dropzone' | |||
| declare uiConfig: UiObjectConfig | |||
| @uiToggle() @serialize() enabled = true | |||
| @@ -4,7 +4,7 @@ import {uiFolderContainer, uiToggle} from 'uiconfig.js' | |||
| import {onChange} from 'ts-browser-helpers' | |||
| @uiFolderContainer('Editor View Widget') | |||
| export class EditorViewWidgetPlugin extends AViewerPluginSync<''> { | |||
| export class EditorViewWidgetPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'EditorViewWidgetPlugin' | |||
| @uiToggle() | |||
| @@ -1,5 +1,10 @@ | |||
| import {uiButton, uiFolderContainer} from 'uiconfig.js' | |||
| import {AViewerPluginSync} from '../../viewer' | |||
| import {AViewerPluginEventMap, AViewerPluginSync} from '../../viewer' | |||
| export interface FullScreenPluginEventMap extends AViewerPluginEventMap{ | |||
| enter: object | |||
| exit: object | |||
| } | |||
| /** | |||
| * Full Screen Plugin | |||
| @@ -13,7 +18,7 @@ import {AViewerPluginSync} from '../../viewer' | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Full Screen') | |||
| export class FullScreenPlugin extends AViewerPluginSync<'enter'|'exit'> { | |||
| export class FullScreenPlugin extends AViewerPluginSync<FullScreenPluginEventMap> { | |||
| public static readonly PluginType = 'FullScreenPlugin' | |||
| toJSON: any = undefined | |||
| @@ -14,11 +14,11 @@ import {OrbitControls3} from '../../three' | |||
| * The animation starts after a delay and stops on user interaction. It then restarts after a delay after the user stops interacting | |||
| * | |||
| * The plugin provides several options and functions to configure the automatic behaviour or trigger the animation manually. | |||
| * @todo - create example | |||
| * TODO - create example | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Interaction Prompt') | |||
| export class InteractionPromptPlugin extends AViewerPluginSync<''> { | |||
| export class InteractionPromptPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'InteractionPromptPlugin' | |||
| @serialize() | |||
| @uiToggle() enabled | |||
| @@ -1,13 +1,20 @@ | |||
| import {Object3D} from 'three' | |||
| import {EventListener, Object3D} from 'three' | |||
| import {Class, onChange, serialize} from 'ts-browser-helpers' | |||
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {BoxSelectionWidget, ObjectPicker, SelectionWidget} from '../../three' | |||
| import {IObject3D, IObject3DEvent, ISceneEvent} from '../../core' | |||
| import {IObject3D, IScene, ISceneEventMap} from '../../core' | |||
| import {IUiConfigContainer, UiObjectConfig} from 'uiconfig.js' | |||
| import {FrameFadePlugin} from '../pipeline/FrameFadePlugin' | |||
| import {type UndoManagerPlugin} from './UndoManagerPlugin' | |||
| import {ObjectPickerEventMap} from '../../three/utils/ObjectPicker' | |||
| export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'hoverObjectChanged'|'hitObject'> { | |||
| export interface PickingPluginEventMap extends AViewerPluginEventMap{ | |||
| selectedObjectChanged: {object: IObject3D|null} | |||
| hoverObjectChanged: {object: IObject3D|null} | |||
| hitObject: {intersects: {selectedObject: IObject3D|null}} | |||
| } | |||
| export class PickingPlugin extends AViewerPluginSync<PickingPluginEventMap> { | |||
| @serialize() | |||
| @onChange(PickingPlugin.prototype.setDirty) | |||
| enabled = true | |||
| @@ -179,7 +186,7 @@ export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'ho | |||
| if (!this._picker || !this._viewer) return | |||
| this._picker.camera = this._viewer.scene.mainCamera | |||
| } | |||
| private _onSceneUpdate = (e: ISceneEvent)=>{ | |||
| private _onSceneUpdate: EventListener<ISceneEventMap['sceneUpdate'], 'sceneUpdate', IScene> = (e)=>{ | |||
| if (!e.hierarchyChanged) return | |||
| const s = this.getSelectedObject() | |||
| let inScene = false | |||
| @@ -189,13 +196,13 @@ export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'ho | |||
| if (!inScene) this.setSelectedObject(undefined) | |||
| } | |||
| private _onObjectSelectEvent = (e: IObject3DEvent)=>{ | |||
| private _onObjectSelectEvent: EventListener<ISceneEventMap['select'], 'select', IScene> = (e)=>{ | |||
| 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') | |||
| else this.setSelectedObject(e.object || e.value, this.autoFocus || e.focusCamera) | |||
| } | |||
| private _selectedObjectChanged = (e: any) => { | |||
| private _selectedObjectChanged: EventListener<ObjectPickerEventMap['selectedObjectChanged'], 'selectedObjectChanged', ObjectPicker> = (e: any) => { | |||
| if (!this._viewer) return | |||
| this.dispatchEvent(e) | |||
| @@ -9,7 +9,7 @@ import {Euler, Object3D, Vector3} from 'three' | |||
| import type {UndoManagerPlugin} from './UndoManagerPlugin' | |||
| @uiPanelContainer('Transform Controls') | |||
| export class TransformControlsPlugin extends AViewerPluginSync<''> { | |||
| export class TransformControlsPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'TransformControlsPlugin' | |||
| @uiToggle() | |||
| @@ -57,7 +57,6 @@ export class TransformControlsPlugin extends AViewerPluginSync<''> { | |||
| }, | |||
| } | |||
| private _transformState = { | |||
| obj: null as Object3D|null, | |||
| position: new Vector3(), | |||
| @@ -2,7 +2,7 @@ import {AViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {getUrlQueryParam, JSUndoManager, onChange} from 'ts-browser-helpers' | |||
| // @uiPanelContainer('Undo Manager') | |||
| export class UndoManagerPlugin extends AViewerPluginSync<''> { | |||
| export class UndoManagerPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'UndoManagerPlugin' | |||
| // @uiToggle() | |||
| @@ -16,7 +16,7 @@ import type {GLTFLoaderPlugin, GLTFParser} from 'three/examples/jsm/loaders/GLTF | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Clearcoat Tint (MatExt)') | |||
| export class ClearcoatTintPlugin extends AViewerPluginSync<''> { | |||
| export class ClearcoatTintPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'ClearcoatTintPlugin' | |||
| @uiToggle('Enabled', (that: ClearcoatTintPlugin)=>({onChange: that.setDirty})) | |||
| @@ -21,7 +21,7 @@ import {makeSamplerUi} from '../../ui/image-ui' | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Custom BumpMap (MatExt)') | |||
| export class CustomBumpMapPlugin extends AViewerPluginSync<''> { | |||
| export class CustomBumpMapPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'CustomBumpMapPlugin' | |||
| @uiToggle('Enabled', (that: CustomBumpMapPlugin)=>({onChange: that.setDirty})) | |||
| @@ -20,7 +20,7 @@ import FragmentClippingExtensionPluginPatch from './shaders/FragmentClippingExte | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Fragment Clipping (MatExt)') | |||
| export class FragmentClippingExtensionPlugin extends AViewerPluginSync<''> { | |||
| export class FragmentClippingExtensionPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'FragmentClippingExtensionPlugin1' | |||
| @uiToggle('Enabled', (that: FragmentClippingExtensionPlugin)=>({onChange: that.setDirty})) | |||
| @@ -19,7 +19,7 @@ import NoiseBumpMaterialPluginPatch from './shaders/NoiseBumpMaterialPlugin.patc | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Noise/Sparkle Bump (MatExt)') | |||
| export class NoiseBumpMaterialPlugin extends AViewerPluginSync<''> { | |||
| export class NoiseBumpMaterialPlugin extends AViewerPluginSync { | |||
| static readonly PluginType = 'NoiseBumpMaterialPlugin' | |||
| @uiToggle('Enabled', (that: NoiseBumpMaterialPlugin)=>({onChange: that.setDirty})) | |||
| @@ -14,7 +14,7 @@ import ParallaxMappingPluginReliefShader from './shaders/ParallaxMappingPlugin.r | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Parallax Bump Mapping (MatExt)') | |||
| export class ParallaxMappingPlugin extends AViewerPluginSync<''> { | |||
| export class ParallaxMappingPlugin extends AViewerPluginSync { | |||
| public static PluginType = 'ReliefParallaxMapping' | |||
| @onChange(ParallaxMappingPlugin.prototype._updateExtension) | |||
| @@ -28,7 +28,6 @@ import DepthBufferUnpack from './shaders/DepthBufferPlugin.unpack.glsl' | |||
| import {threeConstMappings} from '../../three' | |||
| import {IMaterial, PhysicalMaterial} from '../../core' | |||
| export type DepthBufferPluginEventTypes = '' | |||
| // type DepthBufferPluginTarget = WebGLMultipleRenderTargets | WebGLRenderTarget | |||
| export type DepthBufferPluginTarget = WebGLRenderTarget | |||
| export type DepthBufferPluginPass = GBufferRenderPass<'depth', DepthBufferPluginTarget|undefined> | |||
| @@ -41,7 +40,7 @@ export type DepthBufferPluginPass = GBufferRenderPass<'depth', DepthBufferPlugin | |||
| */ | |||
| @uiFolderContainer('Depth Buffer Plugin') | |||
| export class DepthBufferPlugin | |||
| extends PipelinePassPlugin<DepthBufferPluginPass, 'depth', DepthBufferPluginEventTypes> { | |||
| extends PipelinePassPlugin<DepthBufferPluginPass, 'depth'> { | |||
| readonly passId = 'depth' | |||
| public static readonly PluginType = 'DepthBufferPlugin' | |||
| @@ -9,8 +9,6 @@ import {now, serialize, timeout, ValOrFunc} from 'ts-browser-helpers' | |||
| import {ProgressivePlugin} from './ProgressivePlugin' | |||
| import {IRenderTarget} from '../../rendering' | |||
| export type FrameFadePluginEventTypes = '' | |||
| /** | |||
| * FrameFade Plugin | |||
| * | |||
| @@ -20,7 +18,7 @@ export type FrameFadePluginEventTypes = '' | |||
| */ | |||
| @uiFolderContainer('FrameFade Plugin') | |||
| export class FrameFadePlugin | |||
| extends PipelinePassPlugin<FrameFadeBlendPass, 'frameFade', FrameFadePluginEventTypes> { | |||
| extends PipelinePassPlugin<FrameFadeBlendPass, 'frameFade'> { | |||
| readonly passId = 'frameFade' | |||
| public static readonly PluginType = 'FrameFadePlugin' | |||
| @@ -230,3 +228,9 @@ export class FrameFadeBlendPass extends AddBlendTexturePass implements IPipeline | |||
| } | |||
| } | |||
| declare module '../../core/IObject'{ | |||
| export interface IObjectSetDirtyOptions{ | |||
| frameFade?: boolean | |||
| } | |||
| } | |||
| @@ -48,7 +48,6 @@ import { | |||
| ShaderMaterial2, | |||
| } from '../../core' | |||
| export type GBufferPluginEventTypes = '' | |||
| export type GBufferPluginTarget = WebGLMultipleRenderTargets | WebGLRenderTarget | |||
| // export type GBufferPluginTarget = WebGLRenderTarget | |||
| export type GBufferPluginPass = GBufferRenderPass<'gbuffer', GBufferPluginTarget|undefined> | |||
| @@ -68,7 +67,7 @@ export interface GBufferUpdater { | |||
| */ | |||
| @uiFolderContainer('G-Buffer Plugin') | |||
| export class GBufferPlugin | |||
| extends PipelinePassPlugin<GBufferPluginPass, 'gbuffer', GBufferPluginEventTypes> { | |||
| extends PipelinePassPlugin<GBufferPluginPass, 'gbuffer'> { | |||
| readonly passId = 'gbuffer' | |||
| public static readonly PluginType = 'GBuffer' | |||
| @@ -373,7 +372,10 @@ export class GBufferMaterial extends ShaderMaterial2 { | |||
| if (!map) return | |||
| this.uniforms[key].value = map | |||
| if (!this.uniforms[key + 'Transform']) console.error('GBufferMaterial: ' + key + 'Transform is not defined in uniform') | |||
| else renderer.materials.refreshTransformUniform(map, this.uniforms[key + 'Transform']) | |||
| else { | |||
| if ((map as Texture).isTexture) | |||
| renderer.materials.refreshTransformUniform((map as Texture), this.uniforms[key + 'Transform']) | |||
| } | |||
| } | |||
| setMap('map') | |||
| @@ -23,7 +23,6 @@ import {PipelinePassPlugin} from '../base/PipelinePassPlugin' | |||
| import type {IMaterial, PhysicalMaterial} from '../../core' | |||
| import {uiFolderContainer, uiImage} from 'uiconfig.js' | |||
| export type NormalBufferPluginEventTypes = '' | |||
| // type NormalBufferPluginTarget = WebGLMultipleRenderTargets | WebGLRenderTarget | |||
| export type NormalBufferPluginTarget = WebGLRenderTarget | |||
| export type NormalBufferPluginPass = GBufferRenderPass<'normal', NormalBufferPluginTarget|undefined> | |||
| @@ -35,7 +34,7 @@ export type NormalBufferPluginPass = GBufferRenderPass<'normal', NormalBufferPlu | |||
| */ | |||
| @uiFolderContainer('Normal Buffer Plugin') | |||
| export class NormalBufferPlugin | |||
| extends PipelinePassPlugin<NormalBufferPluginPass, 'normal', NormalBufferPluginEventTypes> { | |||
| extends PipelinePassPlugin<NormalBufferPluginPass, 'normal'> { | |||
| readonly passId = 'normal' | |||
| public static readonly PluginType = 'NormalBufferPlugin' | |||
| @@ -10,7 +10,6 @@ import {IShaderPropertiesUpdater} from '../../materials' | |||
| import {SerializationMetaType} from '../../utils' | |||
| import {SSAAPlugin} from './SSAAPlugin' | |||
| export type ProgressivePluginEventTypes = '' | |||
| export type ProgressivePluginTarget = WebGLRenderTarget | |||
| /** | |||
| @@ -22,7 +21,7 @@ export type ProgressivePluginTarget = WebGLRenderTarget | |||
| */ | |||
| @uiFolderContainer('Progressive Plugin') | |||
| export class ProgressivePlugin | |||
| extends PipelinePassPlugin<ProgressiveBlendPass, 'progressive', ProgressivePluginEventTypes> implements IShaderPropertiesUpdater { | |||
| extends PipelinePassPlugin<ProgressiveBlendPass, 'progressive'> implements IShaderPropertiesUpdater { | |||
| readonly passId = 'progressive' | |||
| public static readonly PluginType = 'ProgressivePlugin' | |||
| @@ -5,7 +5,6 @@ import {IEvent, onChange, serialize} from 'ts-browser-helpers' | |||
| import {ICamera, ILight} from '../../core' | |||
| import {ProgressivePlugin} from './ProgressivePlugin' | |||
| export type SSAAPluginEventTypes = '' | |||
| export type TCamera = ICamera & (PerspectiveCamera|OrthographicCamera) | |||
| /** | |||
| @@ -17,7 +16,7 @@ export type TCamera = ICamera & (PerspectiveCamera|OrthographicCamera) | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('SSAA Plugin') | |||
| export class SSAAPlugin extends AViewerPluginSync<SSAAPluginEventTypes> { | |||
| export class SSAAPlugin extends AViewerPluginSync { | |||
| public static readonly PluginType = 'SSAAPlugin' | |||
| @serialize() @uiToggle('Enabled') | |||
| @@ -13,7 +13,6 @@ import ssaoPatch from './shaders/SSAOPlugin.patch.glsl' | |||
| import {uiConfigMaterialExtension} from '../../materials/MaterialExtender' | |||
| import {GBufferPlugin, GBufferUpdaterContext} from './GBufferPlugin' | |||
| export type SSAOPluginEventTypes = '' | |||
| export type SSAOPluginTarget = WebGLRenderTarget | |||
| /** | |||
| @@ -25,7 +24,7 @@ export type SSAOPluginTarget = WebGLRenderTarget | |||
| */ | |||
| @uiFolderContainer('SSAO Plugin') | |||
| export class SSAOPlugin | |||
| extends PipelinePassPlugin<SSAOPluginPass, 'ssao', SSAOPluginEventTypes> { | |||
| extends PipelinePassPlugin<SSAOPluginPass, 'ssao'> { | |||
| readonly passId = 'ssao' | |||
| public static readonly PluginType = 'SSAOPlugin' | |||
| @@ -1,4 +1,4 @@ | |||
| import {type AViewerPlugin, AViewerPluginSync} from '../../viewer/AViewerPlugin' | |||
| import {type AViewerPlugin, AViewerPluginEventMap, AViewerPluginSync} from '../../viewer/AViewerPlugin' | |||
| import type {ThreeViewer} from '../../viewer' | |||
| import {MaterialExtension} from '../../materials' | |||
| import {Shader, Vector4, WebGLRenderer} from 'three' | |||
| @@ -15,7 +15,7 @@ import {GBufferPlugin, GBufferUpdater, GBufferUpdaterContext} from '../pipeline/ | |||
| * | |||
| * @category Plugins | |||
| */ | |||
| export abstract class AScreenPassExtensionPlugin<T extends string> extends AViewerPluginSync<T> implements MaterialExtension, GBufferUpdater { | |||
| export abstract class AScreenPassExtensionPlugin<TE extends AViewerPluginEventMap = AViewerPluginEventMap> extends AViewerPluginSync<TE> implements MaterialExtension, GBufferUpdater { | |||
| declare ['constructor']: (typeof AScreenPassExtensionPlugin) & (typeof AViewerPluginSync) & (typeof AViewerPlugin) | |||
| abstract enabled: boolean | |||
| @@ -13,7 +13,7 @@ import {AScreenPassExtensionPlugin} from './AScreenPassExtensionPlugin' | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('ChromaticAberration') | |||
| export class ChromaticAberrationPlugin extends AScreenPassExtensionPlugin<''> { | |||
| export class ChromaticAberrationPlugin extends AScreenPassExtensionPlugin { | |||
| static readonly PluginType = 'ChromaticAberration' | |||
| readonly extraUniforms = { | |||
| @@ -14,7 +14,7 @@ import {AScreenPassExtensionPlugin} from './AScreenPassExtensionPlugin' | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('FilmicGrain') | |||
| export class FilmicGrainPlugin extends AScreenPassExtensionPlugin<''> { | |||
| export class FilmicGrainPlugin extends AScreenPassExtensionPlugin { | |||
| static readonly PluginType = 'FilmicGrain' | |||
| readonly extraUniforms = { | |||
| @@ -36,7 +36,7 @@ export const Uncharted2Tonemapping: ToneMapping = CustomToneMapping | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('Tonemapping') | |||
| export class TonemapPlugin extends AScreenPassExtensionPlugin<''> { | |||
| export class TonemapPlugin extends AScreenPassExtensionPlugin { | |||
| static readonly PluginType = 'Tonemap' | |||
| readonly extraUniforms = { | |||