| if (i >= 0) this.templates.splice(i, 1) | if (i >= 0) this.templates.splice(i, 1) | ||||
| } | } | ||||
| dispose() { | |||||
| for (const material of this._materials) { | |||||
| dispose(disposeRuntimeMaterials = true) { | |||||
| const mats = this._materials | |||||
| this._materials = [] | |||||
| for (const material of mats) { | |||||
| if (!disposeRuntimeMaterials && material.userData.runtimeMaterial) { | |||||
| this._materials.push(material) | |||||
| continue | |||||
| } | |||||
| material.dispose() | material.dispose() | ||||
| } | } | ||||
| this._materials = [] | |||||
| return | return | ||||
| } | } | ||||
| inverseAlphaMap?: boolean // only for physical material right now | inverseAlphaMap?: boolean // only for physical material right now | ||||
| /** | |||||
| * See {@link MaterialManager.dispose} as {@link BaseGroundPlugin._refreshMaterial} | |||||
| */ | |||||
| runtimeMaterial?: boolean | |||||
| /** | /** | ||||
| * See {@link GBufferPlugin} | * See {@link GBufferPlugin} | ||||
| */ | */ | ||||
| * @default true | * @default true | ||||
| */ | */ | ||||
| tonemapEnabled?: boolean | tonemapEnabled?: boolean | ||||
| [key: string]: any | |||||
| } | } | ||||
| // todo: move these to respective plugins | |||||
| /** | |||||
| * For SSAOPlugin | |||||
| */ | |||||
| ssaoDisabled?: boolean | |||||
| /** | |||||
| * For SSCSPlugin | |||||
| */ | |||||
| sscsDisabled?: boolean | |||||
| /** | |||||
| * For SSRPlugin | |||||
| */ | |||||
| ssreflDisabled?: boolean | |||||
| /** | |||||
| * For SSRPlugin | |||||
| */ | |||||
| ssreflNonPhysical?: boolean | |||||
| [key: string]: any | [key: string]: any | ||||
| */ | */ | ||||
| setDirty?: (options?: IMaterialSetDirtyOptions) => void | setDirty?: (options?: IMaterialSetDirtyOptions) => void | ||||
| /** | /** | ||||
| * @deprecated | |||||
| * @deprecated Use {@link postTonemap.tonemapEnabled} instead. This is kept because used in old files. | |||||
| */ | */ | ||||
| postTonemap?: boolean | postTonemap?: boolean | ||||
| } | } |
| */ | */ | ||||
| userSelectable?: boolean | userSelectable?: boolean | ||||
| /** | |||||
| * For Physics plugins | |||||
| */ | |||||
| physicsMass?: number | |||||
| /** | /** | ||||
| * see {@link GLTFAnimationPlugin} | * see {@link GLTFAnimationPlugin} | ||||
| */ | */ | ||||
| * todo: remove support for this | * todo: remove support for this | ||||
| */ | */ | ||||
| __autoBubbleToParentEvents?: string[] | __autoBubbleToParentEvents?: string[] | ||||
| [key: string]: any | |||||
| } | } | ||||
| export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEventTypes> extends Object3D<E, ET>, IUiConfigContainer, IDisposable { | export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEventTypes> extends Object3D<E, ET>, IUiConfigContainer, IDisposable { |
| // todo: dispose uiconfig on geometry dispose | // todo: dispose uiconfig on geometry dispose | ||||
| // todo: add serialization? | // todo: add serialization? | ||||
| return this | |||||
| } | } |
| import {Mesh} from 'three' | import {Mesh} from 'three' | ||||
| import {IObject3D} from '../IObject' | |||||
| import {IObject3D, IObject3DUserData} from '../IObject' | |||||
| import {iObjectCommons} from './iObjectCommons' | import {iObjectCommons} from './iObjectCommons' | ||||
| import {IMaterial} from '../IMaterial' | import {IMaterial} from '../IMaterial' | ||||
| import {IGeometry} from '../IGeometry' | import {IGeometry} from '../IGeometry' | ||||
| iObjectCommons.upgradeObject3D.call(this) | iObjectCommons.upgradeObject3D.call(this) | ||||
| } | } | ||||
| userData: IObject3DUserData | |||||
| // region inherited type fixes | // region inherited type fixes | ||||
| // re-declaring from IObject3D because: https://github.com/microsoft/TypeScript/issues/16936 | // re-declaring from IObject3D because: https://github.com/microsoft/TypeScript/issues/16936 | ||||
| } | } | ||||
| async onAdded(viewer: ThreeViewer): Promise<void> { | |||||
| onAdded(viewer: ThreeViewer): void { | |||||
| super.onAdded(viewer) | |||||
| viewer.scene.addEventListener('addSceneObject', this._objectAdded) | viewer.scene.addEventListener('addSceneObject', this._objectAdded) | ||||
| viewer.addEventListener('postFrame', this._postFrame) | viewer.addEventListener('postFrame', this._postFrame) | ||||
| window.addEventListener('wheel', this._wheel) | window.addEventListener('wheel', this._wheel) | ||||
| window.addEventListener('scroll', this._scroll) | window.addEventListener('scroll', this._scroll) | ||||
| this._pointerDragHelper.element = viewer.canvas | this._pointerDragHelper.element = viewer.canvas | ||||
| return super.onAdded(viewer) | |||||
| } | } | ||||
| async onRemove(viewer: ThreeViewer): Promise<void> { | |||||
| onRemove(viewer: ThreeViewer): void { | |||||
| while (this.animations.length) this.animations.pop() | while (this.animations.length) this.animations.pop() | ||||
| viewer.scene.removeEventListener('addSceneObject', this._objectAdded) | viewer.scene.removeEventListener('addSceneObject', this._objectAdded) | ||||
| viewer.removeEventListener('postFrame', this._postFrame) | viewer.removeEventListener('postFrame', this._postFrame) |
| this.uniformsNeedUpdate = true | this.uniformsNeedUpdate = true | ||||
| updateMaterialDefines({ | updateMaterialDefines({ | ||||
| ['USE_ALPHAMAP']: this.uniforms.alphaMap.value ? 1 : undefined, | |||||
| // ['USE_ALPHAMAP']: this.uniforms.alphaMap.value ? 1 : undefined, | |||||
| ['ALPHAMAP_UV']: this.uniforms.alphaMap.value ? 'uv' : undefined, // todo use getChannel, see WebGLPrograms.js | ['ALPHAMAP_UV']: this.uniforms.alphaMap.value ? 'uv' : undefined, // todo use getChannel, see WebGLPrograms.js | ||||
| ['USE_DISPLACEMENTMAP']: this.uniforms.displacementMap.value ? 1 : undefined, | ['USE_DISPLACEMENTMAP']: this.uniforms.displacementMap.value ? 1 : undefined, | ||||
| ['DISPLACEMENTMAP_UV']: this.uniforms.displacementMap.value ? 'uv' : undefined, // todo use getChannel, see WebGLPrograms.js | ['DISPLACEMENTMAP_UV']: this.uniforms.displacementMap.value ? 'uv' : undefined, // todo use getChannel, see WebGLPrograms.js |
| * @param postRender - if called after rendering frame. | * @param postRender - if called after rendering frame. | ||||
| */ | */ | ||||
| public isConverged(postRender = false): boolean { | public isConverged(postRender = false): boolean { | ||||
| return (this._viewer?.renderer.frameCount || 0) >= this.maxFrameCount - 1 + (postRender ? 1 : 0) | |||||
| return (this._viewer?.renderManager.frameCount || 0) >= this.maxFrameCount - 1 + (postRender ? 1 : 0) | |||||
| } | } | ||||
| updateShaderProperties(material: {defines: Record<string, string | number | undefined>; uniforms: {[p: string]: IUniform}}): this { | updateShaderProperties(material: {defines: Record<string, string | number | undefined>; uniforms: {[p: string]: IUniform}}): this { |
| import {type AViewerPlugin, AViewerPluginSync} from '../../viewer/AViewerPlugin' | import {type AViewerPlugin, AViewerPluginSync} from '../../viewer/AViewerPlugin' | ||||
| import type {ThreeViewer} from '../../viewer' | |||||
| import type {IViewerEvent, ThreeViewer} from '../../viewer' | |||||
| import {MaterialExtension} from '../../materials' | import {MaterialExtension} from '../../materials' | ||||
| import {Shader, Vector4, WebGLRenderer} from 'three' | import {Shader, Vector4, WebGLRenderer} from 'three' | ||||
| import {IMaterial} from '../../core' | import {IMaterial} from '../../core' | ||||
| onAdded(viewer: ThreeViewer) { | onAdded(viewer: ThreeViewer) { | ||||
| super.onAdded(viewer) | super.onAdded(viewer) | ||||
| viewer.getPlugin(GBufferPlugin)?.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags) | |||||
| const gbuffer = viewer.getPlugin(GBufferPlugin) | |||||
| if (gbuffer) gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this)) | |||||
| else viewer.addEventListener('addPlugin', this._onPluginAdd) | |||||
| viewer.renderManager.screenPass.material.registerMaterialExtensions([this]) | viewer.renderManager.screenPass.material.registerMaterialExtensions([this]) | ||||
| } | } | ||||
| private _onPluginAdd = (e: IViewerEvent)=>{ | |||||
| if (e.plugin?.constructor?.PluginType !== 'GBuffer') return | |||||
| const gbuffer = e.plugin as GBufferPlugin | |||||
| gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this)) | |||||
| this._viewer?.removeEventListener('addPlugin', this._onPluginAdd) | |||||
| } | |||||
| onRemove(viewer: ThreeViewer) { | onRemove(viewer: ThreeViewer) { | ||||
| viewer.removeEventListener('addPlugin', this._onPluginAdd) | |||||
| viewer.getPlugin(GBufferPlugin)?.unregisterGBufferUpdater(this.constructor.PluginType) | viewer.getPlugin(GBufferPlugin)?.unregisterGBufferUpdater(this.constructor.PluginType) | ||||
| viewer.renderManager.screenPass.material.unregisterMaterialExtensions([this]) | viewer.renderManager.screenPass.material.unregisterMaterialExtensions([this]) | ||||
| super.onRemove(viewer) | super.onRemove(viewer) |
| bool doTonemap = true; | bool doTonemap = true; | ||||
| #ifdef HAS_GBUFFER | #ifdef HAS_GBUFFER | ||||
| // doTonemap = getToneMapBit(getGBufferFlags(vUv).a) > 0; // todo | |||||
| doTonemap = getToneMapBit(getGBufferFlags(vUv).a) > 0; | |||||
| #if TONEMAP_BACKGROUND < 1 | #if TONEMAP_BACKGROUND < 1 | ||||
| if(isBackground) doTonemap = false; | if(isBackground) doTonemap = false; | ||||
| #endif | #endif |
| } | } | ||||
| this.renderToScreen = false // for super RenderPass.render | this.renderToScreen = false // for super RenderPass.render | ||||
| if (renderer.info && !renderer.info.autoReset) throw 'renderer.info.autoReset must be true' | |||||
| if (renderer.info && !renderer.info.autoReset) | |||||
| throw 'renderer.info.autoReset must be true' // it is required to check if any object is rendered in the scene, also frame count is maintained separately in the render manager, use that. | |||||
| // Opaque | // Opaque | ||||
| { | { |
| preserveDrawingBuffer: true, | preserveDrawingBuffer: true, | ||||
| powerPreference: RenderManager.POWER_PREFERENCE, | powerPreference: RenderManager.POWER_PREFERENCE, | ||||
| }) | }) | ||||
| renderer.info.autoReset = false | |||||
| // renderer.info.autoReset = false // Not supported by ExtendedRenderPass | |||||
| renderer.useLegacyLights = false | renderer.useLegacyLights = false | ||||
| renderer.setAnimationLoop(this._animationLoop) | renderer.setAnimationLoop(this._animationLoop) | ||||
| if (renderToScreen) { | if (renderToScreen) { | ||||
| this._frameCount += 1 | this._frameCount += 1 | ||||
| this._totalFrameCount += 1 | this._totalFrameCount += 1 | ||||
| this._renderer.info.reset() | |||||
| } | } | ||||
| this._dirty = false | this._dirty = false | ||||
| } | } |