| @@ -310,13 +310,13 @@ | |||
| </ul> | |||
| <h2 class="category">Samples</h2> | |||
| <ul> | |||
| <li><a href="html-js-sample/">HTML/JS Sample </a></li> | |||
| <li><a href="react-js-sample/">React/JS Sample </a></li> | |||
| <li><a href="react-jsx-sample/">React/JSX Sample </a></li> | |||
| <li><a href="react-tsx-sample/">React/TSX Sample </a></li> | |||
| <li><a href="vue-html-sample/">Vue/HTML Sample </a></li> | |||
| <li><a href="vue-sfc-sample/">Vue/SFC Sample </a></li> | |||
| <li><a href="svelte-sample/">Svelte Sample </a></li> | |||
| <li><a href="./html-js-sample/">HTML/JS Sample </a></li> | |||
| <li><a href="./react-js-sample/">React/JS Sample </a></li> | |||
| <li><a href="./react-jsx-sample/">React/JSX Sample </a></li> | |||
| <li><a href="./react-tsx-sample/">React/TSX Sample </a></li> | |||
| <li><a href="./vue-html-sample/">Vue/HTML Sample </a></li> | |||
| <li><a href="./vue-sfc-sample/">Vue/SFC Sample </a></li> | |||
| <li><a href="./svelte-sample/">Svelte Sample </a></li> | |||
| </ul> | |||
| <h2 class="category">Lights</h2> | |||
| <ul> | |||
| @@ -16,6 +16,7 @@ export class AssetExporter extends EventDispatcher<BaseEvent, 'exporterCreate' | | |||
| {ctor: ()=>new SimpleJSONExporter(), ext: ['json']}, | |||
| {ctor: ()=>new SimpleTextExporter(), ext: ['txt', 'text']}, | |||
| {ctor: ()=>new EXRExporter2(), ext: ['exr']}, | |||
| // {ctor: ()=>new EXRExporter2(), ext: ['png', 'jpeg', 'webp']}, // todo | |||
| // {ctor: ()=>new GLTFDracoExporter(), ext: ['gltf', 'glb']}, | |||
| ] | |||
| @@ -2,7 +2,7 @@ import {IPassID, IPipelinePass} from '../../postprocessing' | |||
| import {AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer' | |||
| import {onChange, serialize, wrapThisFunction} from 'ts-browser-helpers' | |||
| import {SerializationMetaType} from '../../utils' | |||
| import {uiConfig, uiToggle} from 'uiconfig.js' | |||
| import {uiToggle} from 'uiconfig.js' | |||
| export abstract class PipelinePassPlugin<T extends IPipelinePass, TPassId extends IPassID, TEvent extends string, TViewer extends ThreeViewer=ThreeViewer> extends AViewerPluginSync<TEvent, TViewer> { | |||
| abstract passId: TPassId | |||
| @@ -12,7 +12,7 @@ export abstract class PipelinePassPlugin<T extends IPipelinePass, TPassId extend | |||
| @onChange(PipelinePassPlugin.prototype.setDirty) | |||
| enabled = true | |||
| @uiConfig() | |||
| // @uiConfig() | |||
| @serialize('pass') | |||
| protected _pass?: T | |||
| protected abstract _createPass():T | |||
| @@ -95,11 +95,11 @@ export class FullScreenPlugin extends AViewerPluginSync<'enter'|'exit'> { | |||
| } | |||
| } | |||
| @uiButton('Toggle FullScreen') | |||
| async toggle(elem: HTMLElement): Promise<void> { | |||
| async toggle(element?: HTMLElement): Promise<void> { | |||
| if (this.isFullScreen()) { | |||
| return this.exit() | |||
| } else { | |||
| return this.enter(elem) | |||
| return this.enter(element) | |||
| } | |||
| } | |||
| @@ -51,7 +51,7 @@ export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'ho | |||
| setDirty() { | |||
| if (!this._viewer) return | |||
| if (this.isDisabled()) this.setSelectedObject(undefined) // todo | |||
| if (this.isDisabled()) this.setSelectedObject(undefined) | |||
| this._viewer.setDirty() | |||
| } | |||
| constructor(selection: Class<SelectionWidget>|undefined = BoxSelectionWidget, pickUi = true, autoFocus = false) { | |||
| @@ -74,14 +74,15 @@ export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'ho | |||
| return this._picker?.selectedObject as T || undefined | |||
| } | |||
| setSelectedObject(object: IObject3D|undefined, focusCamera = false) { // todo: listen to object dispose | |||
| if (this.isDisabled()) return | |||
| setSelectedObject(object: IObject3D|undefined, focusCamera = false) { // todo: listen to object disposed | |||
| const disabled = this.isDisabled() | |||
| if (disabled && !object) return | |||
| if (!this._picker) return | |||
| const t = this.autoFocus | |||
| this.autoFocus = false | |||
| this._picker.selectedObject = object || null | |||
| this.autoFocus = t | |||
| if (t || focusCamera) this.focusObject(object) | |||
| if (!disabled && object && (t || focusCamera)) this.focusObject(object) | |||
| } | |||
| onAdded(viewer: ThreeViewer): void { | |||
| @@ -220,7 +221,6 @@ export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'ho | |||
| this.focusObject(selected) | |||
| } | |||
| } | |||
| private _hoverObjectChanged = (e: any) => { | |||
| @@ -15,7 +15,7 @@ import type {GLTFLoaderPlugin, GLTFParser} from 'three/examples/jsm/loaders/GLTF | |||
| * It uses WEBGI_materials_clearcoat_tint glTF extension to save the settings in glTF files. | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('ClearcoatTint Materials') | |||
| @uiFolderContainer('Clearcoat Tint (MatExt)') | |||
| export class ClearcoatTintPlugin extends AViewerPluginSync<''> { | |||
| static readonly PluginType = 'ClearcoatTintPlugin' | |||
| @@ -20,7 +20,7 @@ import {makeSamplerUi} from '../../ui/image-ui' | |||
| * It uses WEBGI_materials_custom_bump_map glTF extension to save the settings in glTF files. | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('CustomBumpMap Materials') | |||
| @uiFolderContainer('Custom BumpMap (MatExt)') | |||
| export class CustomBumpMapPlugin extends AViewerPluginSync<''> { | |||
| static readonly PluginType = 'CustomBumpMapPlugin' | |||
| @@ -19,7 +19,7 @@ import FragmentClippingExtensionPluginPatch from './shaders/FragmentClippingExte | |||
| * It uses WEBGI_materials_fragment_clipping_extension glTF extension to save the settings in glTF files. | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('FragmentClipping Materials') | |||
| @uiFolderContainer('Fragment Clipping (MatExt)') | |||
| export class FragmentClippingExtensionPlugin extends AViewerPluginSync<''> { | |||
| static readonly PluginType = 'FragmentClippingExtensionPlugin1' | |||
| @@ -18,7 +18,7 @@ import NoiseBumpMaterialPluginPatch from './shaders/NoiseBumpMaterialPlugin.patc | |||
| * It uses WEBGI_materials_noise_bump glTF extension to save the settings in glTF files. | |||
| * @category Plugins | |||
| */ | |||
| @uiFolderContainer('NoiseBump Materials') | |||
| @uiFolderContainer('Noise/Sparkle Bump (MatExt)') | |||
| export class NoiseBumpMaterialPlugin extends AViewerPluginSync<''> { | |||
| static readonly PluginType = 'NoiseBumpMaterialPlugin' | |||
| @@ -54,6 +54,17 @@ export class RenderManager extends RenderTargetManager<IRenderManagerEvent, IRen | |||
| private readonly _renderSize = new Vector2(512, 512) // this is updated automatically. | |||
| protected readonly _renderer: IWebGLRenderer<this> | |||
| private _renderScale = 1. | |||
| @uiSlider('Render Scale', [0.1, 8], 0.05) // keep here in code so its at the top in the UI | |||
| get renderScale(): number { | |||
| return this._renderScale | |||
| } | |||
| set renderScale(value: number) { | |||
| if (value !== this._renderScale) { | |||
| this._renderScale = value | |||
| this.setSize(undefined, undefined, true) | |||
| } | |||
| } | |||
| @uiConfig(undefined, {label: 'Passes'}) | |||
| private _passes: IPipelinePass[] = [] | |||
| private _pipeline: IPassID[] = [] | |||
| @@ -336,16 +347,6 @@ export class RenderManager extends RenderTargetManager<IRenderManagerEvent, IRen | |||
| get renderSize(): Vector2 { | |||
| return this._renderSize | |||
| } | |||
| @uiSlider('Render Scale', [0.1, 8], 0.05) | |||
| get renderScale(): number { | |||
| return this._renderScale | |||
| } | |||
| set renderScale(value: number) { | |||
| if (value !== this._renderScale) { | |||
| this._renderScale = value | |||
| this.setSize(undefined, undefined, true) | |||
| } | |||
| } | |||
| get context(): WebGLRenderingContext { | |||
| return this._context | |||
| @@ -107,8 +107,8 @@ export abstract class RenderTargetManager<E extends BaseEvent = BaseEvent, ET ex | |||
| throw 'Not a temp target' | |||
| } | |||
| if (this._releasedTempTargets[key].length > this.maxTempPerKey) { | |||
| this.removeTrackedTarget(target) | |||
| target.dispose() | |||
| this._trackedTempTargets.splice(this._trackedTempTargets.indexOf(target), 1) | |||
| } else this._releasedTempTargets[key].push(target) | |||
| } | |||
| @@ -49,7 +49,7 @@ import { | |||
| RootSceneImportResult, | |||
| } from '../assetmanager' | |||
| import {IViewerPlugin, IViewerPluginSync} from './IViewerPlugin' | |||
| import {uiConfig, uiFolderContainer, UiObjectConfig} from 'uiconfig.js' | |||
| import {uiConfig, UiObjectConfig, uiPanelContainer} from 'uiconfig.js' | |||
| import {IRenderTarget} from '../rendering' | |||
| import type {CameraViewPlugin, ProgressivePlugin} from '../plugins' | |||
| // noinspection ES6PreferShortImport | |||
| @@ -194,7 +194,7 @@ export interface ThreeViewerOptions { | |||
| * The ThreeViewer is the main class in the framework to manage a scene, render and add plugins to it. | |||
| * @category Viewer | |||
| */ | |||
| @uiFolderContainer('Viewer') | |||
| @uiPanelContainer('Viewer') | |||
| export class ThreeViewer extends EventDispatcher<IViewerEvent, IViewerEventTypes> { | |||
| public static readonly VERSION = VERSION | |||
| public static readonly ConfigTypeSlug = 'vjson' | |||