From 6db95fe4e97c9a86e79cb3fcc3f00c9f0f60ecf0 Mon Sep 17 00:00:00 2001 From: Kai Salmen Date: Tue, 25 Aug 2020 23:44:39 +0200 Subject: [PATCH] webgl_loader_taskmanager.html now features mtl loading for female and male obj models Transformed all OBJLoader2 prototype to classes which eases serialization Transformed all other relevant files to classes and fixed broken examples Updated ts definitions --- examples/jsm/loaders/OBJLoader2.d.ts | 71 ++--- examples/jsm/loaders/OBJLoader2.js | 105 ++++--- examples/jsm/loaders/OBJLoader2Parallel.d.ts | 37 ++- examples/jsm/loaders/OBJLoader2Parallel.js | 99 ++++--- .../jsm/loaders/obj2/OBJLoader2Parser.d.ts | 161 ++++++----- examples/jsm/loaders/obj2/OBJLoader2Parser.js | 146 +++++----- .../jsm/loaders/obj2/bridge/MtlObjBridge.js | 17 +- .../loaders/obj2/shared/MaterialHandler.d.ts | 17 ++ .../loaders/obj2/shared/MaterialHandler.js | 60 ++-- .../jsm/loaders/obj2/shared/MeshReceiver.d.ts | 44 +-- .../jsm/loaders/obj2/shared/MeshReceiver.js | 66 ++--- .../loaders/obj2/utils/CodeSerializer.d.ts | 22 -- .../jsm/loaders/obj2/utils/CodeSerializer.js | 264 ------------------ .../jsm/taskmanager/worker/tmOBJLoader2.js | 27 +- examples/webgl_loader_taskmanager.html | 44 ++- 15 files changed, 485 insertions(+), 695 deletions(-) delete mode 100644 examples/jsm/loaders/obj2/utils/CodeSerializer.d.ts delete mode 100644 examples/jsm/loaders/obj2/utils/CodeSerializer.js diff --git a/examples/jsm/loaders/OBJLoader2.d.ts b/examples/jsm/loaders/OBJLoader2.d.ts index f55e3d18c6eaea..8fecb975cf1e8c 100644 --- a/examples/jsm/loaders/OBJLoader2.d.ts +++ b/examples/jsm/loaders/OBJLoader2.d.ts @@ -1,44 +1,31 @@ -import { - Loader, - LoadingManager, - Object3D, -} from '../../../src/Three'; - -import { OBJLoader2Parser } from './obj2/OBJLoader2Parser'; -import { MaterialHandler } from './obj2/shared/MaterialHandler'; -import { MeshReceiver } from './obj2/shared/MeshReceiver'; - export class OBJLoader2 extends Loader { - - constructor( manager?: LoadingManager ); - parser: OBJLoader2Parser; - modelName: string; - path: string; - resourcePath: string; - baseObject3d: Object3D; - materialHandler: MaterialHandler; - meshReceiver: MeshReceiver; - - setLogging( enabled: boolean, debug: boolean ): this; - setMaterialPerSmoothingGroup( materialPerSmoothingGroup: boolean ): this; - setUseOAsMesh( useOAsMesh: boolean ): this; - setUseIndices( useIndices: boolean ): this; - setDisregardNormals( disregardNormals: boolean ): this; - - setModelName( modelName: string ): this; - setPath( path: string ): this; - setResourcePath( path: string ): this; - setBaseObject3d( baseObject3d: Object3D ): this; - addMaterials( materials: object, overrideExisting: boolean ): this; - - setCallbackOnAssetAvailable( onAssetAvailable: Function ): this; - setCallbackOnProgress( onProgress: Function ): this; - setCallbackOnError( onError: Function ): this; - setCallbackOnLoad( onLoad: Function ): this; - setCallbackOnMeshAlter( onMeshAlter: Function ): this; - setCallbackOnLoadMaterials( onLoadMaterials: Function ): this; - - load( url: string, onLoad: ( object3d: Object3D ) => void, onProgress?: ( event: ProgressEvent ) => void, onError?: ( event: ErrorEvent ) => void, onMeshAlter?: ( meshData: object ) => void ): void; - parse( content: ArrayBuffer | string ): Object3D; - + static OBJLOADER2_VERSION: string; + constructor(manager: any); + parser: OBJLoader2Parser; + modelName: string; + baseObject3d: Object3D; + materialHandler: MaterialHandler; + meshReceiver: MeshReceiver; + setLogging(enabled: any, debug: any): OBJLoader2; + setMaterialPerSmoothingGroup(materialPerSmoothingGroup: any): OBJLoader2; + setUseOAsMesh(useOAsMesh: any): OBJLoader2; + setUseIndices(useIndices: any): OBJLoader2; + setDisregardNormals(disregardNormals: any): OBJLoader2; + setModelName(modelName: string): OBJLoader2; + setBaseObject3d(baseObject3d: Object3D): OBJLoader2; + addMaterials(materials: any, overrideExisting: any): OBJLoader2; + setCallbackOnAssetAvailable(onAssetAvailable: any): OBJLoader2; + setCallbackOnProgress(onProgress: any): OBJLoader2; + setCallbackOnError(onError: any): OBJLoader2; + setCallbackOnLoad(onLoad: any): OBJLoader2; + setCallbackOnMeshAlter(onMeshAlter?: Function): OBJLoader2; + setCallbackOnLoadMaterials(onLoadMaterials?: Function): OBJLoader2; + load(url: string, onLoad: Function, onFileLoadProgress?: Function, onError?: Function, onMeshAlter?: Function): void; + parse(content: any | string): Object3D; + _onAssetAvailable(payload: any): void; } +import { Loader } from "../../../build/three.module.js"; +import { OBJLoader2Parser } from "./obj2/OBJLoader2Parser.js"; +import { Object3D } from "../../../build/three.module.js"; +import { MaterialHandler } from "./obj2/shared/MaterialHandler.js"; +import { MeshReceiver } from "./obj2/shared/MeshReceiver.js"; diff --git a/examples/jsm/loaders/OBJLoader2.js b/examples/jsm/loaders/OBJLoader2.js index 2bff0e46f53309..279b5b4145e010 100644 --- a/examples/jsm/loaders/OBJLoader2.js +++ b/examples/jsm/loaders/OBJLoader2.js @@ -19,91 +19,88 @@ import { MaterialHandler } from "./obj2/shared/MaterialHandler.js"; * @param {LoadingManager} [manager] The loadingManager for the loader to use. Default is {@link LoadingManager} * @constructor */ -const OBJLoader2 = function ( manager ) { +class OBJLoader2 extends Loader { - Loader.call( this, manager ); + static OBJLOADER2_VERSION = '4.0.0-dev'; - this.parser = new OBJLoader2Parser(); + constructor ( manager ) { + super( manager ); - this.modelName = ''; - this.baseObject3d = new Object3D(); + this.parser = new OBJLoader2Parser(); - this.materialHandler = new MaterialHandler(); - this.meshReceiver = new MeshReceiver( this.materialHandler ); + this.modelName = ''; + this.baseObject3d = new Object3D(); - // as OBJLoader2 is no longer derived from OBJLoader2Parser, we need to override the default onAssetAvailable callback - let scope = this; - let defaultOnAssetAvailable = function ( payload ) { + this.materialHandler = new MaterialHandler(); + this.meshReceiver = new MeshReceiver( this.materialHandler ); - scope._onAssetAvailable( payload ); - - }; - this.parser.setCallbackOnAssetAvailable( defaultOnAssetAvailable ); - -}; + // as OBJLoader2 is no longer derived from OBJLoader2Parser, we need to override the default onAssetAvailable callback + let scope = this; + let defaultOnAssetAvailable = function ( payload ) { -OBJLoader2.OBJLOADER2_VERSION = '4.0.0-dev'; -console.info( 'Using OBJLoader2 version: ' + OBJLoader2.OBJLOADER2_VERSION ); + scope._onAssetAvailable( payload ); + }; + this.parser.setCallbackOnAssetAvailable( defaultOnAssetAvailable ); -OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { + console.info( 'Using OBJLoader2 version: ' + OBJLoader2.OBJLOADER2_VERSION ); - constructor: OBJLoader2, + } /** * See {@link OBJLoader2Parser.setLogging} * @return {OBJLoader2} */ - setLogging: function ( enabled, debug ) { + setLogging ( enabled, debug ) { this.parser.setLogging( enabled, debug ); return this; - }, + } /** * See {@link OBJLoader2Parser.setMaterialPerSmoothingGroup} * @return {OBJLoader2} */ - setMaterialPerSmoothingGroup: function ( materialPerSmoothingGroup ) { + setMaterialPerSmoothingGroup ( materialPerSmoothingGroup ) { this.parser.setMaterialPerSmoothingGroup( materialPerSmoothingGroup ); return this; - }, + } /** * See {@link OBJLoader2Parser.setUseOAsMesh} * @return {OBJLoader2} */ - setUseOAsMesh: function ( useOAsMesh ) { + setUseOAsMesh ( useOAsMesh ) { this.parser.setUseOAsMesh( useOAsMesh ); return this; - }, + } /** * See {@link OBJLoader2Parser.setUseIndices} * @return {OBJLoader2} */ - setUseIndices: function ( useIndices ) { + setUseIndices ( useIndices ) { this.parser.setUseIndices( useIndices ); return this; - }, + } /** * See {@link OBJLoader2Parser.setDisregardNormals} * @return {OBJLoader2} */ - setDisregardNormals: function ( disregardNormals ) { + setDisregardNormals ( disregardNormals ) { this.parser.setDisregardNormals( disregardNormals ); return this; - }, + } /** * Set the name of the model. @@ -111,12 +108,12 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { * @param {string} modelName * @return {OBJLoader2} */ - setModelName: function ( modelName ) { + setModelName ( modelName ) { this.modelName = modelName ? modelName : this.modelName; return this; - }, + } /** * Set the node where the loaded objects will be attached directly. @@ -124,12 +121,12 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { * @param {Object3D} baseObject3d Object already attached to scenegraph where new meshes will be attached to * @return {OBJLoader2} */ - setBaseObject3d: function ( baseObject3d ) { + setBaseObject3d ( baseObject3d ) { this.baseObject3d = ( baseObject3d === undefined || baseObject3d === null ) ? this.baseObject3d : baseObject3d; return this; - }, + } /** * Add materials as associated array. @@ -138,56 +135,56 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { * @param overrideExisting boolean Override existing material * @return {OBJLoader2} */ - addMaterials: function ( materials, overrideExisting ) { + addMaterials ( materials, overrideExisting ) { this.materialHandler.addMaterials( materials, overrideExisting ); return this; - }, + } /** * See {@link OBJLoader2Parser.setCallbackOnAssetAvailable} * @return {OBJLoader2} */ - setCallbackOnAssetAvailable: function ( onAssetAvailable ) { + setCallbackOnAssetAvailable ( onAssetAvailable ) { this.parser.setCallbackOnAssetAvailable( onAssetAvailable ); return this; - }, + } /** * See {@link OBJLoader2Parser.setCallbackOnProgress} * @return {OBJLoader2} */ - setCallbackOnProgress: function ( onProgress ) { + setCallbackOnProgress ( onProgress ) { this.parser.setCallbackOnProgress( onProgress ); return this; - }, + } /** * See {@link OBJLoader2Parser.setCallbackOnError} * @return {OBJLoader2} */ - setCallbackOnError: function ( onError ) { + setCallbackOnError ( onError ) { this.parser.setCallbackOnError( onError ); return this; - }, + } /** * See {@link OBJLoader2Parser.setCallbackOnLoad} * @return {OBJLoader2} */ - setCallbackOnLoad: function ( onLoad ) { + setCallbackOnLoad ( onLoad ) { this.parser.setCallbackOnLoad( onLoad ); return this; - }, + } /** * Register a function that is called once a single mesh is available and it could be altered by the supplied function. @@ -195,12 +192,12 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { * @param {Function} [onMeshAlter] * @return {OBJLoader2} */ - setCallbackOnMeshAlter: function ( onMeshAlter ) { + setCallbackOnMeshAlter ( onMeshAlter ) { this.meshReceiver._setCallbacks( this.parser.callbacks.onProgress, onMeshAlter ); return this; - }, + } /** * Register a function that is called once all materials have been loaded and they could be altered by the supplied function. @@ -208,12 +205,12 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { * @param {Function} [onLoadMaterials] * @return {OBJLoader2} */ - setCallbackOnLoadMaterials: function ( onLoadMaterials ) { + setCallbackOnLoadMaterials ( onLoadMaterials ) { this.materialHandler._setCallbacks( onLoadMaterials ); return this; - }, + } /** * Use this convenient method to load a file at the given URL. By default the fileLoader uses an ArrayBuffer. @@ -224,7 +221,7 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { * @param {function} [onError] A function to be called if an error occurs during loading. The function receives the error as an argument. * @param {function} [onMeshAlter] Called after every single mesh is made available by the parser */ - load: function ( url, onLoad, onFileLoadProgress, onError, onMeshAlter ) { + load ( url, onLoad, onFileLoadProgress, onError, onMeshAlter ) { let scope = this; if ( onLoad === null || onLoad === undefined || ! ( onLoad instanceof Function ) ) { @@ -300,7 +297,7 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { fileLoader.setResponseType( 'arraybuffer' ); fileLoader.load( filename, fileLoaderOnLoad, onFileLoadProgress, onError ); - }, + } /** * Parses OBJ data synchronously from arraybuffer or string and returns the {@link Object3D}. @@ -308,7 +305,7 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { * @param {arraybuffer|string} content OBJ data as Uint8Array or String * @return {Object3D} */ - parse: function ( content ) { + parse ( content ) { // fast-fail in case of illegal data if ( content === null || content === undefined ) { @@ -350,9 +347,9 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { } return this.baseObject3d; - }, + } - _onAssetAvailable: function ( payload ) { + _onAssetAvailable ( payload ) { if ( payload.cmd !== 'assetAvailable' ) return; @@ -373,6 +370,6 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), { } -} ); +} export { OBJLoader2 }; diff --git a/examples/jsm/loaders/OBJLoader2Parallel.d.ts b/examples/jsm/loaders/OBJLoader2Parallel.d.ts index f2cdac74c33fbd..fed3d1f06a47eb 100644 --- a/examples/jsm/loaders/OBJLoader2Parallel.d.ts +++ b/examples/jsm/loaders/OBJLoader2Parallel.d.ts @@ -1,23 +1,18 @@ -import { - LoadingManager -} from '../../../src/Three'; -import { OBJLoader2 } from './OBJLoader2'; - -import { WorkerExecutionSupport } from './obj2/worker/main/WorkerExecutionSupport'; - export class OBJLoader2Parallel extends OBJLoader2 { - - constructor( manager?: LoadingManager ); - preferJsmWorker: boolean; - executeParallel: boolean; - workerExecutionSupport: WorkerExecutionSupport; - - setJsmWorker( preferJsmWorker: boolean, jsmWorkerUrl: URL ): this; - setExecuteParallel( executeParallel: boolean ): this; - getWorkerExecutionSupport(): object; - buildWorkerCode(): object; - - // @ts-ignore - parse( content: ArrayBuffer ): void; - + static OBJLOADER2_PARALLEL_VERSION: string; + static DEFAULT_JSM_WORKER_PATH: string; + constructor(manager: any); + preferJsmWorker: boolean; + jsmWorkerUrl: URL; + executeParallel: boolean; + taskManager: any; + taskName: string; + setExecuteParallel(executeParallel: boolean): OBJLoader2Parallel; + setTaskManager(taskManager: any, taskName?: any): OBJLoader2Parallel; + setJsmWorker(preferJsmWorker: boolean, jsmWorkerUrl: URL): OBJLoader2Parallel; + setTerminateWorkerOnLoad(terminateWorkerOnLoad: boolean): OBJLoader2Parallel; + terminateWorkerOnLoad: boolean; + private _buildWorkerCode; + _executeWorkerParse(content: any): void; } +import { OBJLoader2 } from "./OBJLoader2.js"; diff --git a/examples/jsm/loaders/OBJLoader2Parallel.js b/examples/jsm/loaders/OBJLoader2Parallel.js index 3133385730e40c..f5b81cbdc7da5c 100644 --- a/examples/jsm/loaders/OBJLoader2Parallel.js +++ b/examples/jsm/loaders/OBJLoader2Parallel.js @@ -10,6 +10,7 @@ import { OBJLoader2 } from "./OBJLoader2.js"; // Imports only related to worker (when standard workers (modules aren't supported) are used) import { OBJLoader2Parser } from "./obj2/OBJLoader2Parser.js"; import { TaskManager } from "../taskmanager/TaskManager.js"; +import { ObjectManipulator } from "../taskmanager/utils/TransferableUtils.js"; import { OBJ2LoaderWorker } from "../taskmanager/worker/tmOBJLoader2.js"; @@ -20,25 +21,25 @@ import { OBJ2LoaderWorker } from "../taskmanager/worker/tmOBJLoader2.js"; * @param [LoadingManager] manager The loadingManager for the loader to use. Default is {@link LoadingManager} * @constructor */ -const OBJLoader2Parallel = function ( manager ) { +class OBJLoader2Parallel extends OBJLoader2 { - OBJLoader2.call( this, manager ); - this.preferJsmWorker = false; - this.jsmWorkerUrl = null; + static OBJLOADER2_PARALLEL_VERSION = '4.0.0-dev'; - this.executeParallel = true; + static DEFAULT_JSM_WORKER_PATH = './jsm/taskmanager/worker/tmOBJLoader2.js'; - this.taskManager = null; - this.taskName = 'tmOBJLoader2'; -}; + constructor( manager ) { + super( manager ); -OBJLoader2Parallel.OBJLOADER2_PARALLEL_VERSION = '4.0.0-dev'; -console.info( 'Using OBJLoader2Parallel version: ' + OBJLoader2Parallel.OBJLOADER2_PARALLEL_VERSION ); -OBJLoader2Parallel.DEFAULT_JSM_WORKER_PATH = './jsm/taskmanager/worker/tmOBJLoader2.js'; + this.preferJsmWorker = false; + this.jsmWorkerUrl = null; -OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototype ), { + this.executeParallel = true; - constructor: OBJLoader2Parallel, + this.taskManager = null; + this.taskName = 'tmOBJLoader2'; + + console.info( 'Using OBJLoader2Parallel version: ' + OBJLoader2Parallel.OBJLOADER2_PARALLEL_VERSION ); + } /** * Execution of parse in parallel via Worker is default, but normal {OBJLoader2} parsing can be enforced via false here. @@ -46,24 +47,26 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp * @param {boolean} executeParallel True or False * @return {OBJLoader2Parallel} */ - setExecuteParallel: function ( executeParallel ) { + setExecuteParallel ( executeParallel ) { this.executeParallel = executeParallel === true; return this; - }, + } /** + * @param taskManager The {@link TaskManager} + * @param [taskName] A specific taskName to allow distinction between legacy and module workers * - * @param [TaskManager] taskManager - * @return {OBJLoader2} + * @return {OBJLoader2Parallel} */ - setTaskManager: function ( taskManager ) { + setTaskManager ( taskManager, taskName ) { this.taskManager = taskManager; + if ( taskName ) this.taskName = taskName; return this; - }, + } /** * Set whether jsm modules in workers should be used. This requires browser support which is currently only experimental. @@ -71,7 +74,7 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp * @param {URL} jsmWorkerUrl Provide complete jsm worker URL otherwise relative path to this module may not be correct * @return {OBJLoader2Parallel} */ - setJsmWorker: function ( preferJsmWorker, jsmWorkerUrl ) { + setJsmWorker ( preferJsmWorker, jsmWorkerUrl ) { this.preferJsmWorker = preferJsmWorker === true; if ( jsmWorkerUrl === undefined || jsmWorkerUrl === null ) { @@ -80,7 +83,7 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp this.jsmWorkerUrl = jsmWorkerUrl; return this; - }, + } /** * Request termination of worker once parser is finished. @@ -88,17 +91,22 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp * @param {boolean} terminateWorkerOnLoad True or false. * @return {OBJLoader2Parallel} */ - setTerminateWorkerOnLoad: function ( terminateWorkerOnLoad ) { + setTerminateWorkerOnLoad ( terminateWorkerOnLoad ) { this.terminateWorkerOnLoad = terminateWorkerOnLoad === true; return this; - }, + } /** * Provide instructions on what is to be contained in the worker. + * + * @param {object} config Configuration object + * @param {ArrayBuffer} [buffer] Optional buffer + * @return {Promise} + * @private */ - _buildWorkerCode: async function () { + async _buildWorkerCode ( config, buffer ) { if ( ! this.taskManager instanceof TaskManager ) { @@ -114,21 +122,32 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp } else { - let obj2ParserDep = 'const OBJLoader2Parser = ' + OBJLoader2Parser.toString() + ';\n\n'; + let obj2ParserDep = OBJLoader2Parser.toString() + ';\n\n'; + let objectManipulator = ObjectManipulator.toString() + ';\n\n'; this.taskManager.registerTaskType( this.taskName, OBJ2LoaderWorker.init, OBJ2LoaderWorker.execute, null, false, - [{ code: obj2ParserDep }] ); + [ { code: obj2ParserDep }, { code: objectManipulator } ] ); + + } + if ( buffer ) { + + config.buffer = buffer; + await this.taskManager.initTaskType( this.taskName, config, { buffer: buffer } ); + + } + else { + + await this.taskManager.initTaskType( this.taskName, config ); } - await this.taskManager.initTaskType( this.taskName, {} ); } - }, + } /** * See {@link OBJLoader2.load} */ - load: function ( content, onLoad, onFileLoadProgress, onError, onMeshAlter ) { + load ( content, onLoad, onFileLoadProgress, onError, onMeshAlter ) { let scope = this; function interceptOnLoad( object3d, message ) { @@ -150,18 +169,24 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp } OBJLoader2.prototype.load.call( this, content, interceptOnLoad, onFileLoadProgress, onError, onMeshAlter ); - }, + } /** * See {@link OBJLoader2.parse} * The callback onLoad needs to be set to be able to receive the content if used in parallel mode. * Fallback is possible via {@link OBJLoader2Parallel#setExecuteParallel}. */ - parse: function ( content ) { + parse ( content ) { if ( this.executeParallel ) { - this._buildWorkerCode() + let config = { + logging: { + enabled: this.parser.logging.enabled, + debug: this.parser.logging.debug + }, + } + this._buildWorkerCode( config ) .then( x => { if ( this.parser.logging.debug ) console.log( 'OBJLoader2Parallel init was performed: ' + x ); @@ -179,9 +204,9 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp } - }, + } - _executeWorkerParse: function ( content ) { + _executeWorkerParse ( content ) { // Create default materials beforehand, but do not override previously set materials (e.g. during init) this.materialHandler.createDefaultMaterials( false ); @@ -196,10 +221,6 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp materialPerSmoothingGroup: this.parser.materialPerSmoothingGroup, useOAsMesh: this.parser.useOAsMesh, materials: this.materialHandler.getMaterialsJSON() - }, - logging: { - enabled: this.parser.logging.enabled, - debug: this.parser.logging.debug } }; this.taskManager.enqueueForExecution( this.taskName, config, data => this._onAssetAvailable( data ), { buffer: content } ) @@ -212,6 +233,6 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp } -} ); +} export { OBJLoader2Parallel }; diff --git a/examples/jsm/loaders/obj2/OBJLoader2Parser.d.ts b/examples/jsm/loaders/obj2/OBJLoader2Parser.d.ts index cc33773140ba21..422844c410d936 100644 --- a/examples/jsm/loaders/obj2/OBJLoader2Parser.d.ts +++ b/examples/jsm/loaders/obj2/OBJLoader2Parser.d.ts @@ -1,74 +1,91 @@ export class OBJLoader2Parser { - - constructor(); - callbacks: { - onProgress: Function; - onAssetAvailable: Function; - onError: Function; - onLoad: Function; - }; - contentRef: Uint8Array; - legacyMode: boolean; - materials: object; - materialPerSmoothingGroup: boolean; - useOAsMesh: boolean; - useIndices: boolean; - disregardNormals: boolean; - - vertices: number[]; - colors: number[]; - normals: number[]; - uvs: number[]; - - rawMesh: { - objectName: string; - groupName: string; - activeMtlName: string; - mtllibName: string; - faceType: number; - subGroups: object[]; - subGroupInUse: object; - smoothingGroup: { - splitMaterials: boolean; - normalized: boolean; - real: boolean; - }; - counts: { - doubleIndicesCount: number; - faceCount: number; - mtlCount: number; - smoothingGroupCount: number; - } - }; - - inputObjectCount: number; - outputObjectCount: number; - globalCounts: { - vertices: number; - faces: number; - doubleIndicesCount: number; - lineByte: number; - currentByte: number; - totalBytes: number; - }; - - logging: { - enabled: boolean; - debug: boolean; - }; - - setMaterialPerSmoothingGroup( materialPerSmoothingGroup: boolean ): this; - setUseOAsMesh( useOAsMesh: boolean ): this; - setUseIndices( useIndices: boolean ): this; - setDisregardNormals( disregardNormals: boolean ): this; - - setCallbackOnAssetAvailable( onAssetAvailable: Function ): this; - setCallbackOnProgress( onProgress: Function ): this; - setCallbackOnError( onError: Function ): this; - setCallbackOnLoad( onLoad: Function ): this; - setLogging( enabled: boolean, debug: boolean ): this; - setMaterials( materials: Object ): void; - execute( arrayBuffer: Uint8Array ): void; - executeLegacy( text: string ): void; - + logging: { + enabled: boolean; + debug: boolean; + }; + usedBefore: boolean; + callbacks: { + onProgress: (text: string) => void; + onError: (errorMessage: string) => void; + onAssetAvailable: (payload: any) => never; + onLoad: (object3d: any, message: any) => void; + }; + _init(): void; + contentRef: string | Uint8Array; + legacyMode: boolean; + materials: any; + materialPerSmoothingGroup: boolean; + useOAsMesh: boolean; + useIndices: boolean; + disregardNormals: boolean; + vertices: any[]; + colors: any[]; + normals: any[]; + uvs: any[]; + objectId: number; + rawMesh: { + objectName: string; + groupName: string; + activeMtlName: string; + mtllibName: string; + faceType: number; + subGroups: any[]; + subGroupInUse: any; + smoothingGroup: { + splitMaterials: boolean; + normalized: number; + real: number; + }; + counts: { + doubleIndicesCount: number; + faceCount: number; + mtlCount: number; + smoothingGroupCount: number; + }; + }; + inputObjectCount: number; + outputObjectCount: number; + globalCounts: { + vertices: number; + faces: number; + doubleIndicesCount: number; + lineByte: number; + currentByte: number; + totalBytes: number; + }; + _resetRawMesh(): void; + setMaterialPerSmoothingGroup(materialPerSmoothingGroup: boolean): OBJLoader2Parser; + setUseOAsMesh(useOAsMesh: boolean): OBJLoader2Parser; + setUseIndices(useIndices: boolean): OBJLoader2Parser; + setDisregardNormals(disregardNormals: boolean): OBJLoader2Parser; + setMaterials(materials: any): void; + setCallbackOnAssetAvailable(onAssetAvailable: any): OBJLoader2Parser; + setCallbackOnProgress(onProgress: Function): OBJLoader2Parser; + setCallbackOnError(onError: Function): OBJLoader2Parser; + setCallbackOnLoad(onLoad: Function): OBJLoader2Parser; + setLogging(enabled: boolean, debug: boolean): OBJLoader2Parser; + isUsedBefore(): boolean; + _configure(): void; + execute(arrayBuffer: Uint8Array): void; + executeLegacy(text: string): void; + _processLine(buffer: any, bufferPointer: any, slashesCount: any, word: any, currentByte: any): void; + _pushSmoothingGroup(smoothingGroup: any): void; + _checkFaceType(faceType: any): void; + _checkSubGroup(): void; + _buildFace(faceIndexV: any, faceIndexU: any, faceIndexN: any): void; + _createRawMeshReport(inputObjectCount: any): string; + _finalizeRawMesh(): { + name: string; + subGroups: any[]; + absoluteVertexCount: number; + absoluteIndexCount: number; + absoluteColorCount: number; + absoluteNormalCount: number; + absoluteUvCount: number; + faceCount: number; + doubleIndicesCount: number; + }; + _processCompletedMesh(): boolean; + _buildMesh(result: any): void; + _finalizeParsing(): void; } diff --git a/examples/jsm/loaders/obj2/OBJLoader2Parser.js b/examples/jsm/loaders/obj2/OBJLoader2Parser.js index ff966140026ca2..68af25b0cbe1c5 100644 --- a/examples/jsm/loaders/obj2/OBJLoader2Parser.js +++ b/examples/jsm/loaders/obj2/OBJLoader2Parser.js @@ -6,63 +6,68 @@ /** * Parse OBJ data either from ArrayBuffer or string */ -const OBJLoader2Parser = function () { +class OBJLoader2Parser { - let scope = this; - this.callbacks = { + constructor() { - /** - * Announce parse progress feedback which is logged to the console. - * @private - * - * @param {string} text Textual description of the event - */ - onProgress: function ( text ) { + this.logging = { + enabled: false, + debug: false + }; + this.usedBefore = false; + this._init(); - let message = text ? text : ''; - if ( scope.logging.enabled && scope.logging.debug ) { + let scope = this; + this.callbacks = { - console.log( message ); + /** + * Announce parse progress feedback which is logged to the console. + * @private + * + * @param {string} text Textual description of the event + */ + onProgress: function ( text ) { - } + let message = text ? text : ''; + if ( scope.logging.enabled && scope.logging.debug ) { - }, + console.log( message ); - /** - * Announce error feedback which is logged as error message. - * @private - * - * @param {String} errorMessage The event containing the error - */ - onError: function ( errorMessage ) { + } - if ( scope.logging.enabled && scope.logging.debug ) { + }, - console.error( errorMessage ); + /** + * Announce error feedback which is logged as error message. + * @private + * + * @param {String} errorMessage The event containing the error + */ + onError: function ( errorMessage ) { - } + if ( scope.logging.enabled && scope.logging.debug ) { - }, - onAssetAvailable: function ( payload ) { + console.error( errorMessage ); - let errorMessage = 'OBJLoader2Parser does not provide implementation for onAssetAvailable. Aborting...'; - scope.callbacks.onError( errorMessage ); - throw errorMessage; + } - }, - onLoad: function ( object3d, message ) { + }, + onAssetAvailable: function ( payload ) { - console.log( "You reached parser default onLoad callback: " + message ); + let errorMessage = 'OBJLoader2Parser does not provide implementation for onAssetAvailable. Aborting...'; + scope.callbacks.onError( errorMessage ); + throw errorMessage; - } - }; + }, + onLoad: function ( object3d, message ) { - this._init = function () { + console.log( "You reached parser default onLoad callback: " + message ); - this.logging = { - enabled: false, - debug: false + } }; + } + + _init () { this.contentRef = null; this.legacyMode = false; @@ -114,9 +119,8 @@ const OBJLoader2Parser = function () { }; } - this._init(); - this._resetRawMesh = function () { + _resetRawMesh () { // faces are stored according combined index of group, material and smoothingGroup (0 or not) this.rawMesh.subGroups = []; @@ -140,7 +144,7 @@ const OBJLoader2Parser = function () { * @param {boolean} materialPerSmoothingGroup=false * @return {OBJLoader2Parser} */ - this.setMaterialPerSmoothingGroup = function ( materialPerSmoothingGroup ) { + setMaterialPerSmoothingGroup ( materialPerSmoothingGroup ) { this.materialPerSmoothingGroup = materialPerSmoothingGroup === true; return this; @@ -153,7 +157,7 @@ const OBJLoader2Parser = function () { * @param {boolean} useOAsMesh=false * @return {OBJLoader2Parser} */ - this.setUseOAsMesh = function ( useOAsMesh ) { + setUseOAsMesh ( useOAsMesh ) { this.useOAsMesh = useOAsMesh === true; return this; @@ -166,7 +170,7 @@ const OBJLoader2Parser = function () { * @param {boolean} useIndices=false * @return {OBJLoader2Parser} */ - this.setUseIndices = function ( useIndices ) { + setUseIndices ( useIndices ) { this.useIndices = useIndices === true; return this; @@ -179,7 +183,7 @@ const OBJLoader2Parser = function () { * @param {boolean} disregardNormals=false * @return {OBJLoader2Parser} */ - this.setDisregardNormals = function ( disregardNormals ) { + setDisregardNormals ( disregardNormals ) { this.disregardNormals = disregardNormals === true; return this; @@ -191,7 +195,7 @@ const OBJLoader2Parser = function () { * * @param {Object} materials Object with named materials */ - this.setMaterials = function ( materials ) { + setMaterials ( materials ) { this.materials = Object.assign( {}, materials ); @@ -203,7 +207,7 @@ const OBJLoader2Parser = function () { * @param onAssetAvailable * @return {OBJLoader2Parser} */ - this.setCallbackOnAssetAvailable = function ( onAssetAvailable ) { + setCallbackOnAssetAvailable ( onAssetAvailable ) { if ( onAssetAvailable !== null && onAssetAvailable !== undefined && onAssetAvailable instanceof Function ) { @@ -220,7 +224,7 @@ const OBJLoader2Parser = function () { * @param {Function} onProgress * @return {OBJLoader2Parser} */ - this.setCallbackOnProgress = function ( onProgress ) { + setCallbackOnProgress ( onProgress ) { if ( onProgress !== null && onProgress !== undefined && onProgress instanceof Function ) { @@ -237,7 +241,7 @@ const OBJLoader2Parser = function () { * @param {Function} onError * @return {OBJLoader2Parser} */ - this.setCallbackOnError = function ( onError ) { + setCallbackOnError ( onError ) { if ( onError !== null && onError !== undefined && onError instanceof Function ) { @@ -254,7 +258,7 @@ const OBJLoader2Parser = function () { * @param {Function} onLoad * @return {OBJLoader2Parser} */ - this.setCallbackOnLoad = function ( onLoad ) { + setCallbackOnLoad ( onLoad ) { if ( onLoad !== null && onLoad !== undefined && onLoad instanceof Function ) { @@ -273,7 +277,7 @@ const OBJLoader2Parser = function () { * * @return {OBJLoader2Parser} */ - this.setLogging = function ( enabled, debug ) { + setLogging ( enabled, debug ) { this.logging.enabled = enabled === true; this.logging.debug = debug === true; @@ -281,8 +285,20 @@ const OBJLoader2Parser = function () { } - this._configure = function () { + /** + * Tell if loader was used before. + * + * @return {boolean} True or false. + */ + isUsedBefore () { + + return this.usedBefore; + + } + + _configure () { + this.usedBefore = true; this._pushSmoothingGroup( 1 ); if ( this.logging.enabled ) { @@ -308,7 +324,7 @@ const OBJLoader2Parser = function () { * * @param {Uint8Array} arrayBuffer OBJ data as Uint8Array */ - this.execute = function ( arrayBuffer ) { + execute ( arrayBuffer ) { if ( this.logging.enabled ) console.time( 'OBJLoader2Parser.execute' ); this._configure(); @@ -371,7 +387,7 @@ const OBJLoader2Parser = function () { * * @param {string} text OBJ data as string */ - this.executeLegacy = function ( text ) { + executeLegacy ( text ) { if ( this.logging.enabled ) console.time( 'OBJLoader2Parser.executeLegacy' ); this._configure(); @@ -424,7 +440,7 @@ const OBJLoader2Parser = function () { } - this._processLine = function ( buffer, bufferPointer, slashesCount, word, currentByte ) { + _processLine ( buffer, bufferPointer, slashesCount, word, currentByte ) { this.globalCounts.lineByte = this.globalCounts.currentByte; this.globalCounts.currentByte = currentByte; @@ -600,7 +616,7 @@ const OBJLoader2Parser = function () { } - this._pushSmoothingGroup = function ( smoothingGroup ) { + _pushSmoothingGroup ( smoothingGroup ) { let smoothingGroupInt = parseInt( smoothingGroup ); if ( isNaN( smoothingGroupInt ) ) { @@ -632,7 +648,7 @@ const OBJLoader2Parser = function () { * faceType = 5: "l vertex ..." * faceType = 6: "p vertex ..." */ - this._checkFaceType = function ( faceType ) { + _checkFaceType ( faceType ) { if ( this.rawMesh.faceType !== faceType ) { @@ -644,7 +660,7 @@ const OBJLoader2Parser = function () { } - this._checkSubGroup = function () { + _checkSubGroup () { let index = this.rawMesh.activeMtlName + '|' + this.rawMesh.smoothingGroup.normalized; this.rawMesh.subGroupInUse = this.rawMesh.subGroups[ index ]; @@ -671,7 +687,7 @@ const OBJLoader2Parser = function () { } - this._buildFace = function ( faceIndexV, faceIndexU, faceIndexN ) { + _buildFace ( faceIndexV, faceIndexU, faceIndexN ) { let subGroupInUse = this.rawMesh.subGroupInUse; let scope = this; @@ -748,7 +764,7 @@ const OBJLoader2Parser = function () { } - this._createRawMeshReport = function ( inputObjectCount ) { + _createRawMeshReport ( inputObjectCount ) { return 'Input Object number: ' + inputObjectCount + '\n\tObject name: ' + this.rawMesh.objectName + @@ -766,7 +782,7 @@ const OBJLoader2Parser = function () { /** * Clear any empty subGroup and calculate absolute vertex, normal and uv counts */ - this._finalizeRawMesh = function () { + _finalizeRawMesh () { let meshOutputGroupTemp = []; let meshOutputGroup; @@ -827,7 +843,7 @@ const OBJLoader2Parser = function () { } - this._processCompletedMesh = function () { + _processCompletedMesh () { let result = this._finalizeRawMesh(); let haveMesh = result !== null; @@ -859,7 +875,7 @@ const OBJLoader2Parser = function () { * * @param result */ - this._buildMesh = function ( result ) { + _buildMesh ( result ) { let meshOutputGroups = result.subGroups; @@ -1081,7 +1097,7 @@ const OBJLoader2Parser = function () { } - this._finalizeParsing = function () { + _finalizeParsing () { if ( this.logging.enabled ) console.info( 'Global output object count: ' + this.outputObjectCount ); if ( this._processCompletedMesh() && this.logging.enabled ) { @@ -1101,6 +1117,6 @@ const OBJLoader2Parser = function () { } ); } -}; +} export { OBJLoader2Parser }; diff --git a/examples/jsm/loaders/obj2/bridge/MtlObjBridge.js b/examples/jsm/loaders/obj2/bridge/MtlObjBridge.js index 45512c7c30deb6..eb70d58ec3cfe2 100644 --- a/examples/jsm/loaders/obj2/bridge/MtlObjBridge.js +++ b/examples/jsm/loaders/obj2/bridge/MtlObjBridge.js @@ -1,46 +1,45 @@ /** + * @author Kai Salmen / https://kaisalmen.de * Development repository: https://github.com/kaisalmen/WWOBJLoader */ import { MTLLoader } from "../../../../jsm/loaders/MTLLoader.js"; -const MtlObjBridge = { +class MtlObjBridge { /** * * @param processResult * @param assetLoader */ - link: function ( processResult, assetLoader ) { + static link ( processResult, assetLoader ) { if ( typeof assetLoader.addMaterials === 'function' ) { - assetLoader.addMaterials( this.addMaterialsFromMtlLoader( processResult ), true ); + assetLoader.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( processResult ), true ); } - }, + } /** * Returns the array instance of {@link MTLLoader.MaterialCreator}. * - * @param Instance of {@link MTLLoader.MaterialCreator} + * @param materialCreator instance of {@link MTLLoader.MaterialCreator} */ - addMaterialsFromMtlLoader: function ( materialCreator ) { + static addMaterialsFromMtlLoader( materialCreator ) { let newMaterials = {}; - if ( materialCreator instanceof MTLLoader.MaterialCreator ) { materialCreator.preload(); newMaterials = materialCreator.materials; } - return newMaterials; } -}; +} export { MtlObjBridge }; diff --git a/examples/jsm/loaders/obj2/shared/MaterialHandler.d.ts b/examples/jsm/loaders/obj2/shared/MaterialHandler.d.ts index ded53965ee33b8..96ef5e3f12509b 100644 --- a/examples/jsm/loaders/obj2/shared/MaterialHandler.d.ts +++ b/examples/jsm/loaders/obj2/shared/MaterialHandler.d.ts @@ -1,2 +1,19 @@ export class MaterialHandler { + logging: { + enabled: boolean; + debug: boolean; + }; + callbacks: { + onLoadMaterials: any; + }; + materials: {}; + setLogging(enabled: boolean, debug: boolean): void; + _setCallbacks(onLoadMaterials: any): void; + createDefaultMaterials(overrideExisting: any): void; + addPayloadMaterials(materialPayload: any): any; + addMaterials(materials: any, overrideExisting: any, newMaterials: any): any; + getMaterials(): any; + getMaterial(materialName: string): any; + getMaterialsJSON(): any; + clearMaterials(): void; } diff --git a/examples/jsm/loaders/obj2/shared/MaterialHandler.js b/examples/jsm/loaders/obj2/shared/MaterialHandler.js index 9e3e4aeafd7dd6..e59e3486048938 100644 --- a/examples/jsm/loaders/obj2/shared/MaterialHandler.js +++ b/examples/jsm/loaders/obj2/shared/MaterialHandler.js @@ -12,23 +12,21 @@ import { } from "../../../../../build/three.module.js"; -const MaterialHandler = function () { +class MaterialHandler { - this.logging = { - enabled: false, - debug: false - }; + constructor() { - this.callbacks = { - onLoadMaterials: null - }; - this.materials = {}; + this.logging = { + enabled: false, + debug: false + }; -}; - -MaterialHandler.prototype = { + this.callbacks = { + onLoadMaterials: null + }; + this.materials = {}; - constructor: MaterialHandler, + } /** * Enable or disable logging in general (except warn and error), plus enable or disable debug logging. @@ -36,14 +34,14 @@ MaterialHandler.prototype = { * @param {boolean} enabled True or false. * @param {boolean} debug True or false. */ - setLogging: function ( enabled, debug ) { + setLogging ( enabled, debug ) { this.logging.enabled = enabled === true; this.logging.debug = debug === true; - }, + } - _setCallbacks: function ( onLoadMaterials ) { + _setCallbacks ( onLoadMaterials ) { if ( onLoadMaterials !== undefined && onLoadMaterials !== null && onLoadMaterials instanceof Function ) { @@ -51,14 +49,14 @@ MaterialHandler.prototype = { } - }, + } /** * Creates default materials and adds them to the materials object. * * @param overrideExisting boolean Override existing material */ - createDefaultMaterials: function ( overrideExisting ) { + createDefaultMaterials ( overrideExisting ) { let defaultMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } ); defaultMaterial.name = 'defaultMaterial'; @@ -81,7 +79,7 @@ MaterialHandler.prototype = { this.addMaterials( runtimeMaterials, overrideExisting ); - }, + } /** * Updates the materials with contained material objects (sync) or from alteration instructions (async). @@ -89,7 +87,7 @@ MaterialHandler.prototype = { * @param {Object} materialPayload Material update instructions * @returns {Object} Map of {@link Material} */ - addPayloadMaterials: function ( materialPayload ) { + addPayloadMaterials ( materialPayload ) { let material, materialName; let materialCloneInstructions = materialPayload.materials.materialCloneInstructions; @@ -153,7 +151,7 @@ MaterialHandler.prototype = { return newMaterials; - }, + } /** * Set materials loaded by any supplier of an Array of {@link Material}. @@ -162,7 +160,7 @@ MaterialHandler.prototype = { * @param overrideExisting boolean Override existing material * @param newMaterials [Object] with named {@link Material} */ - addMaterials: function ( materials, overrideExisting, newMaterials ) { + addMaterials ( materials, overrideExisting, newMaterials ) { if ( newMaterials === undefined || newMaterials === null ) { @@ -207,36 +205,36 @@ MaterialHandler.prototype = { } return newMaterials; - }, + } /** * Returns the mapping object of material name and corresponding material. * * @returns {Object} Map of {@link Material} */ - getMaterials: function () { + getMaterials () { return this.materials; - }, + } /** * * @param {String} materialName * @returns {Material} */ - getMaterial: function ( materialName ) { + getMaterial ( materialName ) { return this.materials[ materialName ]; - }, + } /** * Returns the mapping object of material name and corresponding jsonified material. * * @returns {Object} Map of Materials in JSON representation */ - getMaterialsJSON: function () { + getMaterialsJSON () { let materialsJSON = {}; let material; @@ -249,17 +247,17 @@ MaterialHandler.prototype = { return materialsJSON; - }, + } /** * Removes all materials */ - clearMaterials: function () { + clearMaterials () { this.materials = {}; } -}; +} export { MaterialHandler }; diff --git a/examples/jsm/loaders/obj2/shared/MeshReceiver.d.ts b/examples/jsm/loaders/obj2/shared/MeshReceiver.d.ts index 34ffb4f3dae8fa..8357e46e256fb4 100644 --- a/examples/jsm/loaders/obj2/shared/MeshReceiver.d.ts +++ b/examples/jsm/loaders/obj2/shared/MeshReceiver.d.ts @@ -1,23 +1,25 @@ -import { - Mesh -} from '../../../../../src/Three'; - -import { MaterialHandler } from './MaterialHandler'; - export class MeshReceiver { - - constructor( materialHandler: MaterialHandler ); - logging: { - enabled: boolean; - debug: boolean; - }; - callbacks: { - onParseProgress: Function; - onMeshAlter: Function; - }; - materialHandler: MaterialHandler; - - buildMeshes( meshPayload: object ): Mesh[]; - setLogging( enabled: boolean, debug: boolean ): void; - + constructor(materialHandler: any); + logging: { + enabled: boolean; + debug: boolean; + }; + callbacks: { + onProgress: any; + onMeshAlter: any; + }; + materialHandler: any; + setLogging(enabled: boolean, debug: boolean): void; + private _setCallbacks; + buildMeshes(meshPayload: any): Mesh[]; } +export class LoadedMeshUserOverride { + constructor(disregardMesh: any, alteredMesh: any); + disregardMesh: boolean; + alteredMesh: boolean; + meshes: any[]; + addMesh(mesh: Mesh): void; + isDisregardMesh(): boolean; + providesAlteredMeshes(): boolean; +} +import { Mesh } from "../../../../../build/three.module.js"; diff --git a/examples/jsm/loaders/obj2/shared/MeshReceiver.js b/examples/jsm/loaders/obj2/shared/MeshReceiver.js index 678ec6ce8c3da0..ae218655947f5f 100644 --- a/examples/jsm/loaders/obj2/shared/MeshReceiver.js +++ b/examples/jsm/loaders/obj2/shared/MeshReceiver.js @@ -1,4 +1,5 @@ /** + * @author Kai Salmen / https://kaisalmen.de * Development repository: https://github.com/kaisalmen/WWOBJLoader */ @@ -16,24 +17,22 @@ import { * @param {MaterialHandler} materialHandler * @constructor */ -const MeshReceiver = function ( materialHandler ) { +class MeshReceiver { - this.logging = { - enabled: false, - debug: false - }; + constructor( materialHandler ) { - this.callbacks = { - onProgress: null, - onMeshAlter: null - }; - this.materialHandler = materialHandler; + this.logging = { + enabled: false, + debug: false + }; -}; - -MeshReceiver.prototype = { + this.callbacks = { + onProgress: null, + onMeshAlter: null + }; + this.materialHandler = materialHandler; - constructor: MeshReceiver, + } /** * Enable or disable logging in general (except warn and error), plus enable or disable debug logging. @@ -41,12 +40,12 @@ MeshReceiver.prototype = { * @param {boolean} enabled True or false. * @param {boolean} debug True or false. */ - setLogging: function ( enabled, debug ) { + setLogging ( enabled, debug ) { this.logging.enabled = enabled === true; this.logging.debug = debug === true; - }, + } /** * @@ -54,7 +53,7 @@ MeshReceiver.prototype = { * @param {Function} onMeshAlter * @private */ - _setCallbacks: function ( onProgress, onMeshAlter ) { + _setCallbacks ( onProgress, onMeshAlter ) { if ( onProgress !== null && onProgress !== undefined && onProgress instanceof Function ) { @@ -67,7 +66,7 @@ MeshReceiver.prototype = { } - }, + } /** * Builds one or multiple meshes from the data described in the payload (buffers, params, material info). @@ -75,7 +74,7 @@ MeshReceiver.prototype = { * @param {Object} meshPayload Raw mesh description (buffers, params, materials) used to build one to many meshes. * @returns {Mesh[]} mesh Array of {@link Mesh} */ - buildMeshes: function ( meshPayload ) { + buildMeshes ( meshPayload ) { let buffers = meshPayload.buffers; let bufferGeometry = new BufferGeometry(); @@ -253,7 +252,7 @@ MeshReceiver.prototype = { } -}; +} /** * Object to return by callback onMeshAlter. Used to disregard a certain mesh or to return one to many meshes. @@ -262,53 +261,50 @@ MeshReceiver.prototype = { * @param {boolean} disregardMesh=false Tell implementation to completely disregard this mesh * @param {boolean} disregardMesh=false Tell implementation that mesh(es) have been altered or added */ -const LoadedMeshUserOverride = function ( disregardMesh, alteredMesh ) { +class LoadedMeshUserOverride { - this.disregardMesh = disregardMesh === true; - this.alteredMesh = alteredMesh === true; - this.meshes = []; + constructor ( disregardMesh, alteredMesh ) { -}; + this.disregardMesh = disregardMesh === true; + this.alteredMesh = alteredMesh === true; + this.meshes = []; - -LoadedMeshUserOverride.prototype = { - - constructor: LoadedMeshUserOverride, + } /** * Add a mesh created within callback. * * @param {Mesh} mesh */ - addMesh: function ( mesh ) { + addMesh ( mesh ) { this.meshes.push( mesh ); this.alteredMesh = true; - }, + } /** * Answers if mesh shall be disregarded completely. * * @returns {boolean} */ - isDisregardMesh: function () { + isDisregardMesh () { return this.disregardMesh; - }, + } /** * Answers if new mesh(es) were created. * * @returns {boolean} */ - providesAlteredMeshes: function () { + providesAlteredMeshes () { return this.alteredMesh; } -}; +} export { MeshReceiver, diff --git a/examples/jsm/loaders/obj2/utils/CodeSerializer.d.ts b/examples/jsm/loaders/obj2/utils/CodeSerializer.d.ts deleted file mode 100644 index a9019d36899431..00000000000000 --- a/examples/jsm/loaders/obj2/utils/CodeSerializer.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -export namespace CodeSerializer { - - export function serializeClass( targetPrototype: object, targetPrototypeInstance: object, basePrototypeName?: string, overrideFunctions?: CodeSerializationInstruction[] ): string; - -} - -export class CodeSerializationInstruction { - - constructor( name: string, fullName: string ); - name: string; - fullName: string; - code: string; - removeCode: boolean; - - getName(): string; - getFullName(): string; - setCode( code: string ): this; - getCode(): string; - setRemoveCode( removeCode: boolean ): this; - isRemoveCode(): boolean; - -} diff --git a/examples/jsm/loaders/obj2/utils/CodeSerializer.js b/examples/jsm/loaders/obj2/utils/CodeSerializer.js deleted file mode 100644 index 2dd29945a2e759..00000000000000 --- a/examples/jsm/loaders/obj2/utils/CodeSerializer.js +++ /dev/null @@ -1,264 +0,0 @@ -/** - * Development repository: https://github.com/kaisalmen/WWOBJLoader - */ - -const CodeSerializer = { - - /** - * Serialize an object with specific prototype definition. - * - * @param {Object} targetPrototype The object that should be serialized - * @param {Object} targetPrototypeInstance An instance of the oriobject that should be serialized - * @param {String} [basePrototypeName] Name of the prototype - * @param {Object} [overrideFunctions} Array of {@Link CodeSerializationInstruction} allows to replace or remove function with provided content - * - * @returns {String} - */ - serializeClass: function ( targetPrototype, targetPrototypeInstance, basePrototypeName, overrideFunctions ) { - - let objectPart, constructorString, i, funcInstructions, funcTemp; - let fullObjectName = targetPrototypeInstance.constructor.name; - let prototypeFunctions = []; - let objectProperties = []; - let objectFunctions = []; - let isExtended = ( basePrototypeName !== null && basePrototypeName !== undefined ); - - if ( ! Array.isArray( overrideFunctions ) ) overrideFunctions = []; - - for ( let name in targetPrototype.prototype ) { - - objectPart = targetPrototype.prototype[ name ]; - funcInstructions = new CodeSerializationInstruction( name, fullObjectName + '.prototype.' + name ); - funcInstructions.setCode( objectPart.toString() ); - - if ( name === 'constructor' ) { - - if ( ! funcInstructions.isRemoveCode() ) { - - constructorString = fullObjectName + ' = ' + funcInstructions.getCode() + ';\n\n'; - - } - - } else if ( typeof objectPart === 'function' ) { - - funcTemp = overrideFunctions[ name ]; - - if ( funcTemp instanceof CodeSerializationInstruction && funcTemp.getName() === funcInstructions.getName() ) { - - funcInstructions = funcTemp; - - } - - if ( ! funcInstructions.isRemoveCode() ) { - - if ( isExtended ) { - - prototypeFunctions.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n\n' ); - - } else { - - prototypeFunctions.push( '\t' + funcInstructions.getName() + ': ' + funcInstructions.getCode() + ',\n\n' ); - - } - - } - - } - - } - - for ( let name in targetPrototype ) { - - objectPart = targetPrototype[ name ]; - funcInstructions = new CodeSerializationInstruction( name, fullObjectName + '.' + name ); - - if ( typeof objectPart === 'function' ) { - - funcTemp = overrideFunctions[ name ]; - if ( funcTemp instanceof CodeSerializationInstruction && funcTemp.getName() === funcInstructions.getName() ) { - - funcInstructions = funcTemp; - - } else { - - funcInstructions.setCode( objectPart.toString() ); - - } - - if ( ! funcInstructions.isRemoveCode() ) { - - objectFunctions.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n\n' ); - - } - - } else { - - if ( typeof ( objectPart ) === 'string' || objectPart instanceof String ) { - - funcInstructions.setCode( '\"' + objectPart.toString() + '\"' ); - - } else if ( typeof objectPart === 'object' ) { - - console.log( 'Omitting object "' + funcInstructions.getName() + '" and replace it with empty object.' ); - funcInstructions.setCode( "{}" ); - - } else { - - funcInstructions.setCode( objectPart ); - - } - - if ( ! funcInstructions.isRemoveCode() ) { - - objectProperties.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n' ); - - } - - } - - } - - let objectString = constructorString + '\n\n'; - - if ( isExtended ) { - - objectString += fullObjectName + '.prototype = Object.create( ' + basePrototypeName + '.prototype );\n'; - - } - - objectString += fullObjectName + '.prototype.constructor = ' + fullObjectName + ';\n'; - objectString += '\n\n'; - - for ( i = 0; i < objectProperties.length; i ++ ) { - - objectString += objectProperties[ i ]; - - } - - objectString += '\n\n'; - - for ( i = 0; i < objectFunctions.length; i ++ ) { - - objectString += objectFunctions[ i ]; - - } - - objectString += '\n\n'; - - if ( isExtended ) { - - for ( i = 0; i < prototypeFunctions.length; i ++ ) { - - objectString += prototypeFunctions[ i ]; - - } - - } else { - - objectString += fullObjectName + '.prototype = {\n\n'; - for ( i = 0; i < prototypeFunctions.length; i ++ ) { - - objectString += prototypeFunctions[ i ]; - - } - - objectString += '\n};'; - - } - - objectString += '\n\n'; - - return objectString; - - }, -}; - -/** - * Allows to define instructions to override or remove - * @param {String} name Usually the name of a function - * @param {String} fullName The name plus full object description - * @constructor - */ -const CodeSerializationInstruction = function ( name, fullName ) { - - this.name = name; - this.fullName = fullName; - this.code = null; - this.removeCode = false; - -}; - -CodeSerializationInstruction.prototype = { - - constructor: CodeSerializationInstruction, - - /** - * Returns the name of the function - * @return {String} - */ - getName: function () { - - return this.name; - - }, - - /** - * Returns the full name of the function - * @return {String} - */ - getFullName: function () { - - return this.fullName; - - }, - - /** - * Set the string containing the serialized function - * @param {String} code - * @return {CodeSerializationInstruction} - */ - setCode: function ( code ) { - - this.code = code; - return this; - - }, - - /** - * Returns the serialized function code - * @return {String} - */ - getCode: function () { - - return this.code; - - }, - - /** - * Set if function should be removed - * @param {boolean} removeCode - * @return {CodeSerializationInstruction} - */ - setRemoveCode: function ( removeCode ) { - - this.removeCode = removeCode; - return this; - - }, - - /** - * If function should be completely removed - * @return {boolean} - */ - isRemoveCode: function () { - - return this.removeCode; - - } - -}; - -export { - CodeSerializer, - CodeSerializationInstruction -}; diff --git a/examples/jsm/taskmanager/worker/tmOBJLoader2.js b/examples/jsm/taskmanager/worker/tmOBJLoader2.js index 643d2d5404f16a..142b3173733e55 100644 --- a/examples/jsm/taskmanager/worker/tmOBJLoader2.js +++ b/examples/jsm/taskmanager/worker/tmOBJLoader2.js @@ -3,7 +3,7 @@ */ import { OBJLoader2Parser } from "../../loaders/obj2/OBJLoader2Parser.js"; -//import { ObjectManipulator } from "../../loaders/obj2/utils/TransferableUtils.js"; +import { ObjectManipulator } from "../../taskmanager/utils/TransferableUtils.js"; import { TaskManagerDefaultRouting } from "./tmDefaultComRouting.js"; const OBJ2LoaderWorker = { @@ -14,12 +14,20 @@ const OBJ2LoaderWorker = { objParser: new OBJLoader2Parser(), buffer: null } + if ( config.logging ) { + context.obj2.objParser.setLogging( config.logging.enabled, config.logging.debug ); + } + context.obj2.objParser.setCallbackOnAssetAvailable( m => { context.postMessage( m ); } ); context.obj2.objParser.setCallbackOnProgress( text => { - console.debug( 'WorkerRunner: progress: ' + text ) + if ( context.obj2.objParser.logging.debug ) console.debug( 'WorkerRunner: progress: ' + text ); } ); + + + + ObjectManipulator.applyProperties( context.obj2.objParser, config.params, false ); if ( config.buffer !== undefined && config.buffer !== null ) context.obj2.buffer = config.buffer; context.postMessage( { @@ -30,17 +38,14 @@ const OBJ2LoaderWorker = { }, execute: function ( context, id, config ) { - /* - let callbacks = { - callbackOnAssetAvailable: ( m => { self.postMessage( m ); } ), - callbackOnProgress: ( text => { console.de bug( 'WorkerRunner: progress: ' + text ) } ) - }; - ObjectManipulator.applyProperties( objParser, payload.config, false ); - ObjectManipulator.applyProperties( objParser, callbacks, false ); - */ - context.obj2.objParser._init(); + if ( context.obj2.objParser.isUsedBefore() ) { + + context.obj2.objParser._init(); + + } + ObjectManipulator.applyProperties( context.obj2.objParser, config.params, false ); if ( config.buffer !== undefined && config.buffer !== null ) context.obj2.buffer = config.buffer; context.obj2.objParser.objectId = config.id; diff --git a/examples/webgl_loader_taskmanager.html b/examples/webgl_loader_taskmanager.html index 659eb8ca3b697c..b53e88394d1a34 100644 --- a/examples/webgl_loader_taskmanager.html +++ b/examples/webgl_loader_taskmanager.html @@ -34,11 +34,14 @@ import { TrackballControls } from "./jsm/controls/TrackballControls.js"; import { TaskManager } from "./jsm/taskmanager/TaskManager.js"; import { MeshReceiver } from "./jsm/loaders/obj2/shared/MeshReceiver.js"; + import { ObjectManipulator } from "./jsm/taskmanager/utils/TransferableUtils.js" import { OBJLoader2Parser } from "./jsm/loaders/obj2/OBJLoader2Parser.js"; import { MaterialHandler } from "./jsm/loaders/obj2/shared/MaterialHandler.js"; import { TransferableUtils } from "./jsm/taskmanager/utils/TransferableUtils.js"; import { FileLoader } from "../src/loaders/FileLoader.js"; import { OBJ2LoaderWorker } from "./jsm/taskmanager/worker/tmOBJLoader2.js"; + import { MTLLoader } from "./jsm/loaders/MTLLoader.js"; + import { MtlObjBridge } from "./jsm/loaders/obj2/bridge/MtlObjBridge.js"; class TaskManagerPrototypeExample { @@ -130,7 +133,9 @@ use: true, fallback: false, module: './jsm/taskmanager/worker/tmOBJLoader2.js', - filename: './models/obj/female02/female02.obj' + filenameMtl: './models/obj/female02/female02.mtl', + filenameObj: './models/obj/female02/female02.obj', + materials: {} } ); this.taskDescriptions.set( 'tmOBJLoader2Legacy', { name: 'tmOBJLoader2Legacy', @@ -138,7 +143,9 @@ fallback: false, funcInit: OBJ2LoaderWorker.init, funcExec: OBJ2LoaderWorker.execute, - filename: './models/obj/male02/male02.obj' + filenameMtl: './models/obj/male02/male02.mtl', + filenameObj: './models/obj/male02/male02.obj', + materials: {} } ); this.tasksToUse = []; @@ -244,7 +251,7 @@ this.tasksToUse.push( taskDescr ); this.taskManager.registerTaskTypeModule( taskDescr.name, taskDescr.module ); - await this.loadFile( taskDescr.filename ) + await this.loadObjMtl( taskDescr ) .then( buffer => { let config = { buffer: buffer } awaiting.push( this.taskManager.initTaskType( taskDescr.name, config, { buffer: buffer } ).catch( e => console.error( e ) ) ); @@ -255,9 +262,11 @@ if ( taskDescr.use ) { this.tasksToUse.push( taskDescr ); - let obj2ParserDep = 'const OBJLoader2Parser = ' + OBJLoader2Parser.toString() + ';\n\n'; - this.taskManager.registerTaskType( taskDescr.name, taskDescr.funcInit, taskDescr.funcExec, null, false, [ { code: obj2ParserDep } ] ); - await this.loadFile( taskDescr.filename ) + let obj2ParserDep = OBJLoader2Parser.toString() + ';\n\n'; + let objectManipulator = ObjectManipulator.toString() + ';\n\n'; + this.taskManager.registerTaskType( taskDescr.name, taskDescr.funcInit, taskDescr.funcExec, null, false, + [ { code: obj2ParserDep }, { code: objectManipulator } ] ); + await this.loadObjMtl( taskDescr ) .then( buffer => { let config = { buffer: buffer } awaiting.push( this.taskManager.initTaskType( taskDescr.name, config, { buffer: buffer } ).catch( e => console.error( e ) ) ); @@ -276,11 +285,23 @@ } } - async loadFile ( file ) { + async loadObjMtl ( taskDescr ) { let fileLoader = new FileLoader(); fileLoader.setResponseType( 'arraybuffer' ); - return fileLoader.loadAsync( file ) + + let loadMtl = new Promise(resolve => { + + let mtlLoader = new MTLLoader(); + mtlLoader.load( taskDescr.filenameMtl, resolve ); + + } ); + await loadMtl.then( mtlParseResult => { + let newMaterials = MtlObjBridge.addMaterialsFromMtlLoader( mtlParseResult ); + this.materialHandler.addMaterials( newMaterials, true ); + taskDescr.materials = this.materialHandler.getMaterialsJSON() + } ) ; + return await fileLoader.loadAsync( taskDescr.filenameObj ); } @@ -323,7 +344,12 @@ _storeAddTaskPromise( taskNameIndex, globalCount ) { let taskDescr = this.tasksToUse[ taskNameIndex ]; - let promise = this.taskManager.enqueueForExecution( taskDescr.name, { id: globalCount }, + let promise = this.taskManager.enqueueForExecution( taskDescr.name, { + id: globalCount, + params: { + materials: taskDescr.materials + } + }, data => this._processMessage( data ) ) .then( data => this._processMessage( data ) ) .catch( e => console.error( e ) )