| if (!viewer) return | if (!viewer) return | ||||
| const importers: Importer[] = [ | const importers: Importer[] = [ | ||||
| new Importer(TextureLoader, ['webp', 'png', 'jpeg', 'jpg', 'svg', 'ico', 'data:image'], [ | |||||
| 'image/webp', 'image/png', 'image/jpeg', 'image/svg+xml', 'image/gif', 'image/bmp', 'image/tiff', 'image/x-icon', | |||||
| new Importer(TextureLoader, ['webp', 'png', 'jpeg', 'jpg', 'svg', 'ico', 'data:image', 'avif'], [ | |||||
| 'image/webp', 'image/png', 'image/jpeg', 'image/svg+xml', 'image/gif', 'image/bmp', 'image/tiff', 'image/x-icon', 'image/avif', | |||||
| ], false), // todo: use ImageBitmapLoader if supported (better performance) | ], false), // todo: use ImageBitmapLoader if supported (better performance) | ||||
| new Importer<JSONMaterialLoader>(JSONMaterialLoader, | new Importer<JSONMaterialLoader>(JSONMaterialLoader, |
| import {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader.js' | import {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader.js' | ||||
| import {BufferGeometry, Color, LoadingManager, Mesh, MeshStandardMaterial} from 'three' | |||||
| import {BufferGeometry, Color, LoadingManager, Mesh} from 'three' | |||||
| import {AnyOptions} from 'ts-browser-helpers' | import {AnyOptions} from 'ts-browser-helpers' | ||||
| import {ILoader} from '../IImporter' | import {ILoader} from '../IImporter' | ||||
| import {PhysicalMaterial} from '../../core' | |||||
| export class DRACOLoader2 extends DRACOLoader implements ILoader<BufferGeometry, Mesh|undefined> { | export class DRACOLoader2 extends DRACOLoader implements ILoader<BufferGeometry, Mesh|undefined> { | ||||
| public encoderPending: Promise<any>|null = null | public encoderPending: Promise<any>|null = null | ||||
| transform(res: BufferGeometry, _: AnyOptions): Mesh|undefined { | transform(res: BufferGeometry, _: AnyOptions): Mesh|undefined { | ||||
| if (!res.attributes?.normal) res.computeVertexNormals() | if (!res.attributes?.normal) res.computeVertexNormals() | ||||
| // todo set mesh name from options/path | // todo set mesh name from options/path | ||||
| return res ? new Mesh(res, new MeshStandardMaterial({color: new Color(1, 1, 1)})) : undefined | |||||
| return res ? new Mesh(res, new PhysicalMaterial({color: new Color(1, 1, 1)})) : undefined | |||||
| } | } | ||||
| preload(decoder = true, encoder = false): DRACOLoader { | preload(decoder = true, encoder = false): DRACOLoader { |
| toJSON(meta?: SerializationMetaType, _internal?: boolean): any; | toJSON(meta?: SerializationMetaType, _internal?: boolean): any; | ||||
| fromJSON(json: any, meta?: SerializationMetaType, _internal?: boolean): this | null; | fromJSON(json: any, meta?: SerializationMetaType, _internal?: boolean): this | null; | ||||
| extraUniformsToUpload?: Record<string, IUniform> | |||||
| materialExtensions?: MaterialExtension[] | |||||
| registerMaterialExtensions?: (customMaterialExtensions: MaterialExtension[]) => void; | |||||
| unregisterMaterialExtensions?: (customMaterialExtensions: MaterialExtension[]) => void; | |||||
| extraUniformsToUpload: Record<string, IUniform> | |||||
| materialExtensions: MaterialExtension[] | |||||
| registerMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void; | |||||
| unregisterMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void; | |||||
| /** | /** | ||||
| * Managed internally, do not change manually | * Managed internally, do not change manually |
| import {IMaterial} from './IMaterial' | import {IMaterial} from './IMaterial' | ||||
| import {Event, Texture} from 'three' | |||||
| import {Event, Source, Texture} from 'three' | |||||
| import {ChangeEvent} from 'uiconfig.js' | import {ChangeEvent} from 'uiconfig.js' | ||||
| import {IRenderTarget} from '../rendering' | import {IRenderTarget} from '../rendering' | ||||
| setDirty?(): void | setDirty?(): void | ||||
| source: Source & { | |||||
| _sourceImgBuffer?: ArrayBuffer // see KTX2LoadPlugin and serializeTextureInExtras | |||||
| } | |||||
| _target?: IRenderTarget // for internal use only. refers to the render target that this texture is attached to | _target?: IRenderTarget // for internal use only. refers to the render target that this texture is attached to | ||||
| } | } | ||||
| IMaterialTemplate, | IMaterialTemplate, | ||||
| } from '../IMaterial' | } from '../IMaterial' | ||||
| import {SerializationMetaType, ThreeSerialization} from '../../utils/serialization' | import {SerializationMetaType, ThreeSerialization} from '../../utils/serialization' | ||||
| import {MaterialExtender, MaterialExtension} from '../../materials' | |||||
| import {MaterialExtension} from '../../materials' | |||||
| import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' | import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' | ||||
| import {IObject3D} from '../IObject' | import {IObject3D} from '../IObject' | ||||
| import {ITexture} from '../ITexture' | import {ITexture} from '../ITexture' | ||||
| public readonly isPhysicalMaterial = true | public readonly isPhysicalMaterial = true | ||||
| public materialExtensions: MaterialExtension[] = [] | |||||
| readonly appliedMeshes: Set<IObject3D> = new Set() | readonly appliedMeshes: Set<IObject3D> = new Set() | ||||
| readonly setDirty = iMaterialCommons.setDirty | readonly setDirty = iMaterialCommons.setDirty | ||||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | ||||
| // region Material Extension | // region Material Extension | ||||
| materialExtensions: MaterialExtension[] = [] | |||||
| extraUniformsToUpload: Record<string, IUniform> = {} | extraUniformsToUpload: Record<string, IUniform> = {} | ||||
| registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions | registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions | ||||
| unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions | unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions | ||||
| customProgramCacheKey(): string { | customProgramCacheKey(): string { | ||||
| return super.customProgramCacheKey() + MaterialExtender.CacheKeyForExtensions(this, this.materialExtensions) + this.userData.inverseAlphaMap | |||||
| return super.customProgramCacheKey() + iMaterialCommons.customProgramCacheKey.call(this) | |||||
| } | } | ||||
| onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines | onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines | ||||
| } | } | ||||
| } | } | ||||
| onAfterRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, object: Object3D): void { | |||||
| super.onAfterRender(renderer, scene, camera, geometry, object) | |||||
| iMaterialCommons.onAfterRender.call(this, renderer, scene, camera, geometry, object) | |||||
| } | |||||
| onAfterRender = iMaterialCommons.onAfterRenderOverride(super.onAfterRender) | |||||
| // endregion | // endregion | ||||
| WebGLRenderer, | WebGLRenderer, | ||||
| } from 'three' | } from 'three' | ||||
| import {IMaterial, IMaterialEvent, IMaterialEventTypes, IMaterialParameters} from '../IMaterial' | import {IMaterial, IMaterialEvent, IMaterialEventTypes, IMaterialParameters} from '../IMaterial' | ||||
| import {MaterialExtender, MaterialExtension} from '../../materials' | |||||
| import {MaterialExtension} from '../../materials' | |||||
| import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' | 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<E extends IMaterialEvent = IMaterialEvent, ET = IMaterialEventTypes> extends ShaderMaterial<E, ET> implements IMaterial<E, ET> { | ||||
| assetType = 'material' as const | assetType = 'material' as const | ||||
| public readonly isAShaderMaterial = true | public readonly isAShaderMaterial = true | ||||
| public materialExtensions: MaterialExtension[] = [] | |||||
| readonly appliedMeshes: Set<any> = new Set() | readonly appliedMeshes: Set<any> = new Set() | ||||
| readonly setDirty = iMaterialCommons.setDirty | readonly setDirty = iMaterialCommons.setDirty | ||||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | ||||
| // region Material Extension | // region Material Extension | ||||
| materialExtensions: MaterialExtension[] = [] | |||||
| extraUniformsToUpload: Record<string, IUniform> = {} | extraUniformsToUpload: Record<string, IUniform> = {} | ||||
| registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions | registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions | ||||
| unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions | unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions | ||||
| customProgramCacheKey(): string { | customProgramCacheKey(): string { | ||||
| return super.customProgramCacheKey() + MaterialExtender.CacheKeyForExtensions(this, this.materialExtensions) + this.userData.inverseAlphaMap | |||||
| return super.customProgramCacheKey() + iMaterialCommons.customProgramCacheKey.call(this) | |||||
| } | } | ||||
| onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines | onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines |
| import { | import { | ||||
| BufferGeometry, | |||||
| Camera, | |||||
| Color, | Color, | ||||
| IUniform, | IUniform, | ||||
| Material, | Material, | ||||
| MeshBasicMaterial, | MeshBasicMaterial, | ||||
| MeshBasicMaterialParameters, | MeshBasicMaterialParameters, | ||||
| MultiplyOperation, | MultiplyOperation, | ||||
| Object3D, | |||||
| Scene, | |||||
| Shader, | Shader, | ||||
| WebGLRenderer, | WebGLRenderer, | ||||
| } from 'three' | } from 'three' | ||||
| IMaterialParameters, | IMaterialParameters, | ||||
| IMaterialTemplate, | IMaterialTemplate, | ||||
| } from '../IMaterial' | } from '../IMaterial' | ||||
| import {MaterialExtender, MaterialExtension} from '../../materials' | |||||
| import {MaterialExtension} from '../../materials' | |||||
| import {shaderReplaceString} from '../../utils/shader-helpers' | import {shaderReplaceString} from '../../utils/shader-helpers' | ||||
| import {SerializationMetaType, ThreeSerialization} from '../../utils/serialization' | import {SerializationMetaType, ThreeSerialization} from '../../utils/serialization' | ||||
| import {ITexture} from '../ITexture' | import {ITexture} from '../ITexture' | ||||
| public readonly isUnlitMaterial = true | public readonly isUnlitMaterial = true | ||||
| public materialExtensions: MaterialExtension[] = [] | |||||
| readonly appliedMeshes: Set<IObject3D> = new Set() | readonly appliedMeshes: Set<IObject3D> = new Set() | ||||
| readonly setDirty = iMaterialCommons.setDirty | readonly setDirty = iMaterialCommons.setDirty | ||||
| dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)} | ||||
| iMaterialCommons.upgradeMaterial.call(this) | iMaterialCommons.upgradeMaterial.call(this) | ||||
| } | } | ||||
| // region Material Extension | // region Material Extension | ||||
| materialExtensions: MaterialExtension[] = [] | |||||
| extraUniformsToUpload: Record<string, IUniform> = {} | extraUniformsToUpload: Record<string, IUniform> = {} | ||||
| registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions | registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions | ||||
| unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions | unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions | ||||
| customProgramCacheKey(): string { | customProgramCacheKey(): string { | ||||
| return super.customProgramCacheKey() + MaterialExtender.CacheKeyForExtensions(this, this.materialExtensions) + this.userData.inverseAlphaMap | |||||
| return super.customProgramCacheKey() + iMaterialCommons.customProgramCacheKey.call(this) | |||||
| } | } | ||||
| onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines | onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines | ||||
| super.onBeforeCompile(shader, renderer) | super.onBeforeCompile(shader, renderer) | ||||
| } | } | ||||
| onBeforeRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, object: Object3D): void { | |||||
| super.onBeforeRender(renderer, scene, camera, geometry, object) | |||||
| iMaterialCommons.onBeforeRender.call(this, renderer, scene, camera, geometry, object) | |||||
| // const t = this.userData.inverseAlphaMap ? 1 : 0 // todo | |||||
| // if (t !== this.defines.INVERSE_ALPHAMAP) { | |||||
| // this.defines.INVERSE_ALPHAMAP = t | |||||
| // this.needsUpdate = true | |||||
| // } | |||||
| } | |||||
| onAfterRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, object: Object3D): void { | |||||
| super.onAfterRender(renderer, scene, camera, geometry, object) | |||||
| iMaterialCommons.onAfterRender.call(this, renderer, scene, camera, geometry, object) | |||||
| } | |||||
| // onBeforeRender(...args: Parameters<IMaterial['onBeforeRender']>): void { | |||||
| // super.onBeforeRender(...args) | |||||
| // iMaterialCommons.onBeforeRender.call(this, ...args) | |||||
| // | |||||
| // // const t = this.userData.inverseAlphaMap ? 1 : 0 // todo | |||||
| // // if (t !== this.defines.INVERSE_ALPHAMAP) { | |||||
| // // this.defines.INVERSE_ALPHAMAP = t | |||||
| // // this.needsUpdate = true | |||||
| // // } | |||||
| // } | |||||
| onBeforeRender = iMaterialCommons.onBeforeRenderOverride(super.onBeforeRender) | |||||
| onAfterRender = iMaterialCommons.onAfterRenderOverride(super.onAfterRender) | |||||
| // endregion | // endregion | ||||
| } | } | ||||
| }, | }, | ||||
| customProgramCacheKey: function(this: IMaterial): string { | |||||
| return MaterialExtender.CacheKeyForExtensions(this, this.materialExtensions) + this.userData.inverseAlphaMap | |||||
| }, | |||||
| registerMaterialExtensions: function(this: IMaterial, customMaterialExtensions: MaterialExtension[]): void { | registerMaterialExtensions: function(this: IMaterial, customMaterialExtensions: MaterialExtension[]): void { | ||||
| MaterialExtender.RegisterExtensions(this, customMaterialExtensions) | MaterialExtender.RegisterExtensions(this, customMaterialExtensions) | ||||
| }, | }, | ||||
| MaterialExtender.UnregisterExtensions(this, customMaterialExtensions) | MaterialExtender.UnregisterExtensions(this, customMaterialExtensions) | ||||
| }, | }, | ||||
| // shader is not Shader but WebglUniforms.getParameters return value type so includes defines | |||||
| onBeforeCompile: function(this: IMaterial, shader: Shader, renderer: WebGLRenderer): void { | onBeforeCompile: function(this: IMaterial, shader: Shader, renderer: WebGLRenderer): void { | ||||
| if (this.materialExtensions) MaterialExtender.ApplyMaterialExtensions(this, shader, this.materialExtensions, renderer) | if (this.materialExtensions) MaterialExtender.ApplyMaterialExtensions(this, shader, this.materialExtensions, renderer) | ||||
| shader.fragmentShader = shader.fragmentShader.replaceAll('#glMarker', '// ') | shader.fragmentShader = shader.fragmentShader.replaceAll('#glMarker', '// ') | ||||
| shader.vertexShader = shader.vertexShader.replaceAll('#glMarker', '// ') | shader.vertexShader = shader.vertexShader.replaceAll('#glMarker', '// ') | ||||
| }, | }, | ||||
| onBeforeRender: function(this: IMaterial, renderer, scene: Scene & Partial<IScene>, camera, geometry, object) { | onBeforeRender: function(this: IMaterial, renderer, scene: Scene & Partial<IScene>, camera, geometry, object) { | ||||
| if (this.envMapIntensity !== undefined && !this.userData.separateEnvMapIntensity && scene.envMapIntensity !== undefined) { | if (this.envMapIntensity !== undefined && !this.userData.separateEnvMapIntensity && scene.envMapIntensity !== undefined) { | ||||
| this.userData.__envIntensity = this.envMapIntensity | this.userData.__envIntensity = this.envMapIntensity | ||||
| this.dispatchEvent({type: 'afterRender', renderer, scene, camera, geometry, object}) | this.dispatchEvent({type: 'afterRender', renderer, scene, camera, geometry, object}) | ||||
| } as IMaterial['onAfterRender'], | } as IMaterial['onAfterRender'], | ||||
| onBeforeCompileOverride: (superOnBeforeCompile: Material['onBeforeCompile']): IMaterial['onBeforeCompile'] => | |||||
| function(this: IMaterial, shader: Shader, renderer: WebGLRenderer): void { | |||||
| iMaterialCommons.onBeforeCompile.call(this, shader, renderer) | |||||
| superOnBeforeCompile.call(this, shader, renderer) | |||||
| }, | |||||
| onBeforeRenderOverride: (superOnBeforeRender: Material['onBeforeRender']): IMaterial['onBeforeRender'] => | |||||
| function(this: IMaterial, ...args: Parameters<Material['onBeforeRender']>): void { | |||||
| superOnBeforeRender.call(this, ...args) | |||||
| iMaterialCommons.onBeforeRender.call(this, ...args) | |||||
| }, | |||||
| onAfterRenderOverride: (superOnAfterRender: Material['onAfterRender']): IMaterial['onAfterRender'] => | |||||
| function(this: IMaterial, ...args: Parameters<Material['onAfterRender']>): void { | |||||
| superOnAfterRender.call(this, ...args) | |||||
| iMaterialCommons.onAfterRender.call(this, ...args) | |||||
| }, | |||||
| customProgramCacheKeyOverride: (superCustomPropertyCacheKey: Material['customProgramCacheKey']): IMaterial['customProgramCacheKey'] => | |||||
| function(this: IMaterial): string { | |||||
| return superCustomPropertyCacheKey.call(this) + iMaterialCommons.customProgramCacheKey.call(this) | |||||
| }, | |||||
| upgradeMaterial: upgradeMaterial, | upgradeMaterial: upgradeMaterial, | ||||
| // todo; | // todo; | ||||
| } as const | } as const | ||||
| if (!this.setDirty) this.setDirty = iMaterialCommons.setDirty | if (!this.setDirty) this.setDirty = iMaterialCommons.setDirty | ||||
| if (!this.appliedMeshes) this.appliedMeshes = new Set() | if (!this.appliedMeshes) this.appliedMeshes = new Set() | ||||
| if (!this.userData) this.userData = {} | if (!this.userData) this.userData = {} | ||||
| this.userData.uuid = this.uuid | |||||
| this.userData.uuid = this.uuid // for serialization | |||||
| // legacy | // legacy | ||||
| if (!this.userData.setDirty) this.userData.setDirty = (e: any) => { | if (!this.userData.setDirty) this.userData.setDirty = (e: any) => { | ||||
| this.clone = iMaterialCommons.clone(this.clone) | this.clone = iMaterialCommons.clone(this.clone) | ||||
| this.dispatchEvent = iMaterialCommons.dispatchEvent(this.dispatchEvent) | this.dispatchEvent = iMaterialCommons.dispatchEvent(this.dispatchEvent) | ||||
| // material extensions | |||||
| if (!this.extraUniformsToUpload) this.extraUniformsToUpload = {} | |||||
| if (!this.materialExtensions) this.materialExtensions = [] | |||||
| if (!this.registerMaterialExtensions) this.registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions | |||||
| if (!this.unregisterMaterialExtensions) this.unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions | |||||
| this.onBeforeCompile = iMaterialCommons.onBeforeCompileOverride(this.onBeforeCompile) | |||||
| this.onBeforeRender = iMaterialCommons.onBeforeRenderOverride(this.onBeforeRender) | |||||
| this.onAfterRender = iMaterialCommons.onAfterRenderOverride(this.onAfterRender) | |||||
| this.customProgramCacheKey = iMaterialCommons.customProgramCacheKeyOverride(this.customProgramCacheKey) | |||||
| // todo: add uiconfig, serialization, other stuff from UnlitMaterial? | // todo: add uiconfig, serialization, other stuff from UnlitMaterial? | ||||
| // dispose uiconfig etc. on dispose | // dispose uiconfig etc. on dispose | ||||
| import {Importer, Rhino3dmLoader2} from '../../assetmanager' | import {Importer, Rhino3dmLoader2} from '../../assetmanager' | ||||
| /** | /** | ||||
| * Adds support for loading Rhino `.3dm` files. | |||||
| * Adds support for loading Rhino `.3dm`, `model/vnd.3dm`, `model/3dm` files and data uris. | |||||
| * @category Plugins | * @category Plugins | ||||
| */ | */ | ||||
| export class Rhino3dmLoadPlugin implements IViewerPluginSync { | export class Rhino3dmLoadPlugin implements IViewerPluginSync { |