diff --git a/docs/examples/loaders/LoaderSupport.html b/docs/examples/loaders/LoaderSupport.html index a5d8b8da93d9272827c961c506151f7e6f568573..5479a6bb9c5abb41dd6461c8db4a83a61bb8b732 100644 --- a/docs/examples/loaders/LoaderSupport.html +++ b/docs/examples/loaders/LoaderSupport.html @@ -520,6 +520,14 @@
Register callback function that is called once loading of the complete OBJ file is completed.
+ +

[method:null setCallbackOnLoadMaterials]( [page:Function callbackOnLoadMaterials] )

+
+ [page:Function callbackOnLoadMaterials] - Callback function for described functionality +
+
+ Register callback function that is called when materials have been loaded. +


diff --git a/examples/js/loaders/LoaderSupport.js b/examples/js/loaders/LoaderSupport.js index a1c50f7b21ca9b733662baee538803fe4c7b6c3c..d9effa2a49b5e23828a2673281640de4e809b09f 100644 --- a/examples/js/loaders/LoaderSupport.js +++ b/examples/js/loaders/LoaderSupport.js @@ -163,6 +163,7 @@ THREE.LoaderSupport.Callbacks = (function () { this.onProgress = null; this.onMeshAlter = null; this.onLoad = null; + this.onLoadMaterials = null; } /** @@ -196,6 +197,16 @@ THREE.LoaderSupport.Callbacks = (function () { this.onLoad = Validator.verifyInput( callbackOnLoad, this.onLoad ); }; + /** + * Register callback function that is called when materials have been loaded. + * @memberOf THREE.LoaderSupport.Callbacks + * + * @param {callback} callbackOnLoadMaterials Callback function for described functionality + */ + Callbacks.prototype.setCallbackOnLoadMaterials = function ( callbackOnLoadMaterials ) { + this.onLoadMaterials = Validator.verifyInput( callbackOnLoadMaterials, this.onLoadMaterials ); + }; + return Callbacks; })(); @@ -424,7 +435,7 @@ THREE.LoaderSupport.PrepData = (function () { */ THREE.LoaderSupport.Builder = (function () { - var LOADER_BUILDER_VERSION = '1.1.0'; + var LOADER_BUILDER_VERSION = '1.1.1'; var Validator = THREE.LoaderSupport.Validator; var ConsoleLogger = THREE.LoaderSupport.ConsoleLogger; @@ -448,16 +459,17 @@ THREE.LoaderSupport.Builder = (function () { materials: { materialCloneInstructions: null, serializedMaterials: null, - runtimeMaterials: materials + runtimeMaterials: Validator.isValid( this.callbacks.onLoadMaterials ) ? this.callbacks.onLoadMaterials( materials ) : materials } }; this.updateMaterials( payload ); }; - Builder.prototype._setCallbacks = function ( callbackOnProgress, callbackOnMeshAlter, callbackOnLoad ) { - this.callbacks.setCallbackOnProgress( callbackOnProgress ); - this.callbacks.setCallbackOnMeshAlter( callbackOnMeshAlter ); - this.callbacks.setCallbackOnLoad( callbackOnLoad ); + Builder.prototype._setCallbacks = function ( callbacks ) { + if ( Validator.isValid( callbacks.onProgress ) ) this.callbacks.setCallbackOnProgress( callbacks.onProgress ); + if ( Validator.isValid( callbacks.onMeshAlter ) ) this.callbacks.setCallbackOnMeshAlter( callbacks.onMeshAlter ); + if ( Validator.isValid( callbacks.onLoad ) ) this.callbacks.setCallbackOnLoad( callbacks.onLoad ); + if ( Validator.isValid( callbacks.onLoadMaterials ) ) this.callbacks.setCallbackOnLoadMaterials( callbacks.onLoadMaterials ); }; /** @@ -771,16 +783,17 @@ THREE.LoaderSupport.LoaderBase = (function () { this.setUseIndices( prepData.useIndices ); this.setDisregardNormals( prepData.disregardNormals ); - this._setCallbacks( prepData.getCallbacks().onProgress, prepData.getCallbacks().onMeshAlter, prepData.getCallbacks().onLoad ); + this._setCallbacks( prepData.getCallbacks() ); } }; - LoaderBase.prototype._setCallbacks = function ( callbackOnProgress, callbackOnMeshAlter, callbackOnLoad ) { - this.callbacks.setCallbackOnProgress( callbackOnProgress ); - this.callbacks.setCallbackOnMeshAlter( callbackOnMeshAlter ); - this.callbacks.setCallbackOnLoad( callbackOnLoad ); + LoaderBase.prototype._setCallbacks = function ( callbacks ) { + if ( Validator.isValid( callbacks.onProgress ) ) this.callbacks.setCallbackOnProgress( callbacks.onProgress ); + if ( Validator.isValid( callbacks.onMeshAlter ) ) this.callbacks.setCallbackOnMeshAlter( callbacks.onMeshAlter ); + if ( Validator.isValid( callbacks.onLoad ) ) this.callbacks.setCallbackOnLoad( callbacks.onLoad ); + if ( Validator.isValid( callbacks.onLoadMaterials ) ) this.callbacks.setCallbackOnLoadMaterials( callbacks.onLoadMaterials ); - this.builder._setCallbacks( callbackOnProgress, callbackOnMeshAlter, callbackOnLoad ); + this.builder._setCallbacks( this.callbacks ); }; /** diff --git a/examples/js/loaders/OBJLoader2.js b/examples/js/loaders/OBJLoader2.js index a7f7ff37d52402c6618880b17183a0dad37310b3..322e3e1ca7dd223293dcdd5127b996721e8523a2 100644 --- a/examples/js/loaders/OBJLoader2.js +++ b/examples/js/loaders/OBJLoader2.js @@ -16,10 +16,9 @@ if ( THREE.OBJLoader2 === undefined ) { THREE.OBJLoader2 = {} } */ THREE.OBJLoader2 = (function () { - var OBJLOADER2_VERSION = '2.1.1'; + var OBJLOADER2_VERSION = '2.1.2'; var LoaderBase = THREE.LoaderSupport.LoaderBase; var Validator = THREE.LoaderSupport.Validator; - var ConsoleLogger = THREE.LoaderSupport.ConsoleLogger; OBJLoader2.prototype = Object.create( THREE.LoaderSupport.LoaderBase.prototype ); OBJLoader2.prototype.constructor = OBJLoader2; @@ -92,7 +91,9 @@ THREE.OBJLoader2 = (function () { } else { - scope._setCallbacks( null, onMeshAlter, null ); + var callbacks = new THREE.LoaderSupport.Callbacks(); + callbacks.setCallbackOnMeshAlter( onMeshAlter ); + scope._setCallbacks( callbacks ); onLoad( { detail: { @@ -349,6 +350,7 @@ THREE.OBJLoader2 = (function () { }; this.logger = logger; this.totalBytes = 0; + this.reachedFaces = false; }; Parser.prototype.setUseAsync = function ( useAsync ) { @@ -417,7 +419,6 @@ THREE.OBJLoader2 = (function () { var bufferPointer = 0; var slashSpacePattern = new Array( 16 ); var slashSpacePatternPointer = 0; - var reachedFaces = false; var code; var word = ''; var i = 0; @@ -440,7 +441,7 @@ THREE.OBJLoader2 = (function () { case Consts.CODE_LF: if ( word.length > 0 ) buffer[ bufferPointer++ ] = word; word = ''; - reachedFaces = this.processLine( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, reachedFaces, i ); + this.processLine( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, i ); bufferPointer = 0; slashSpacePatternPointer = 0; break; @@ -473,7 +474,6 @@ THREE.OBJLoader2 = (function () { var bufferPointer = 0; var slashSpacePattern = new Array( 16 ); var slashSpacePatternPointer = 0; - var reachedFaces = false; var char; var word = ''; var i = 0; @@ -496,7 +496,7 @@ THREE.OBJLoader2 = (function () { case Consts.STRING_LF: if ( word.length > 0 ) buffer[ bufferPointer++ ] = word; word = ''; - reachedFaces = this.processLine( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, reachedFaces, i ); + this.processLine( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, i ); bufferPointer = 0; slashSpacePatternPointer = 0; break; @@ -512,8 +512,8 @@ THREE.OBJLoader2 = (function () { this.logger.logTimeEnd( 'OBJLoader2.Parser.parseText' ); }; - Parser.prototype.processLine = function ( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, reachedFaces, currentByte ) { - if ( bufferPointer < 1 ) return reachedFaces; + Parser.prototype.processLine = function ( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, currentByte ) { + if ( bufferPointer < 1 ) return; var countSlashes = function ( slashSpacePattern, slashSpacePatternPointer ) { var slashesCount = 0; @@ -552,15 +552,16 @@ THREE.OBJLoader2 = (function () { switch ( buffer[ 0 ] ) { case Consts.LINE_V: // object complete instance required if reached faces already (= reached next block of v) - if ( reachedFaces ) { + if ( this.reachedFaces ) { if ( this.rawMesh.colors.length > 0 && this.rawMesh.colors.length !== this.rawMesh.vertices.length ) { throw 'Vertex Colors were detected, but vertex count and color count do not match!'; } - this.processCompletedObject( this.rawMesh.objectName, this.rawMesh.groupName, currentByte ); - reachedFaces = false; + // only when new vertices after faces are detected complete new mesh is prepared (reset offsets, etc) + this.processCompletedMesh( this.rawMesh.objectName, this.rawMesh.groupName, currentByte, true ); + this.reachedFaces = false; } if ( bufferPointer === 4 ) { @@ -583,7 +584,7 @@ THREE.OBJLoader2 = (function () { break; case Consts.LINE_F: - reachedFaces = true; + this.reachedFaces = true; this.rawMesh.processFaces( buffer, bufferPointer, countSlashes( slashSpacePattern, slashSpacePatternPointer ) ); break; @@ -597,14 +598,12 @@ THREE.OBJLoader2 = (function () { break; case Consts.LINE_G: - this.processCompletedGroup( concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), currentByte ); - reachedFaces = false; + this.processCompletedMesh( this.rawMesh.objectName, concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), currentByte, false ); flushStringBuffer( buffer, bufferPointer ); break; case Consts.LINE_O: - this.processCompletedObject( concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), this.rawMesh.groupName, currentByte ); - reachedFaces = false; + this.processCompletedMesh( concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), this.rawMesh.groupName, currentByte, false ); flushStringBuffer( buffer, bufferPointer ); break; @@ -621,7 +620,6 @@ THREE.OBJLoader2 = (function () { default: break; } - return reachedFaces; }; Parser.prototype.createRawMeshReport = function ( rawMesh , inputObjectCount ) { @@ -638,7 +636,7 @@ THREE.OBJLoader2 = (function () { '\n\tReal RawMeshSubGroup count: ' + report.subGroups; }; - Parser.prototype.processCompletedObject = function ( objectName, groupName, currentByte ) { + Parser.prototype.processCompletedMesh = function ( objectName, groupName, currentByte, beginNewObject ) { var result = this.rawMesh.finalize(); if ( Validator.isValid( result ) ) { @@ -646,35 +644,13 @@ THREE.OBJLoader2 = (function () { if ( this.logger.isDebug() ) this.logger.logDebug( this.createRawMeshReport( this.rawMesh, this.inputObjectCount ) ); this.buildMesh( result, currentByte ); var progressBytesPercent = currentByte / this.totalBytes; - this.callbackProgress( 'Completed object: ' + objectName + ' Total progress: ' + ( progressBytesPercent * 100 ).toFixed( 2 ) + '%', progressBytesPercent ); - this.rawMesh = this.rawMesh.newInstanceFromObject( objectName, groupName ); - - } else { - - // if a object was set that did not lead to object creation in finalize, then the object name has to be updated - this.rawMesh.pushObject( objectName ); - - } - - }; - - Parser.prototype.processCompletedGroup = function ( groupName, currentByte ) { - var result = this.rawMesh.finalize(); - if ( Validator.isValid( result ) ) { - - this.inputObjectCount++; - if ( this.logger.isDebug() ) this.logger.logDebug( this.createRawMeshReport( this.rawMesh, this.inputObjectCount ) ); - this.buildMesh( result, currentByte ); - var progressBytesPercent = currentByte / this.totalBytes; - this.callbackProgress( 'Completed group: ' + groupName + ' Total progress: ' + ( progressBytesPercent * 100 ).toFixed( 2 ) + '%', progressBytesPercent ); - this.rawMesh = this.rawMesh.newInstanceFromGroup( groupName ); - - } else { - - // if a group was set that did not lead to object creation in finalize, then the group name has to be updated - this.rawMesh.pushGroup( groupName ); + this.callbackProgress( 'Completed [o: ' + this.rawMesh.objectName + ' g:' + this.rawMesh.groupName + '] Total progress: ' + ( progressBytesPercent * 100 ).toFixed( 2 ) + '%', progressBytesPercent ); + this.rawMesh = beginNewObject ? this.rawMesh.newInstanceResetOffsets() : this.rawMesh.newInstanceKeepOffsets(); } + // Always update group an object name in case they have changed and are valid + if ( this.rawMesh.objectName !== objectName && Validator.isValid( objectName ) ) this.rawMesh.pushObject( objectName ); + if ( this.rawMesh.groupName !== groupName && Validator.isValid( groupName ) ) this.rawMesh.pushGroup( groupName ); }; Parser.prototype.finalize = function ( currentByte ) { @@ -907,7 +883,7 @@ THREE.OBJLoader2 = (function () { */ var RawMesh = (function () { - function RawMesh( materialPerSmoothingGroup, useIndices, disregardNormals, objectName, groupName, activeMtlName ) { + function RawMesh( materialPerSmoothingGroup, useIndices, disregardNormals, activeMtlName ) { this.globalVertexOffset = 1; this.globalUvOffset = 1; this.globalNormalOffset = 1; @@ -919,8 +895,8 @@ THREE.OBJLoader2 = (function () { // faces are stored according combined index of group, material and smoothingGroup (0 or not) this.activeMtlName = Validator.verifyInput( activeMtlName, '' ); - this.objectName = Validator.verifyInput( objectName, '' ); - this.groupName = Validator.verifyInput( groupName, '' ); + this.objectName = ''; + this.groupName = ''; this.mtllibName = ''; this.smoothingGroup = { splitMaterials: materialPerSmoothingGroup === true, @@ -942,8 +918,8 @@ THREE.OBJLoader2 = (function () { this.faceCount = 0; } - RawMesh.prototype.newInstanceFromObject = function ( objectName, groupName ) { - var newRawObject = new RawMesh( this.smoothingGroup.splitMaterials, this.useIndices, this.disregardNormals, objectName, groupName, this.activeMtlName ); + RawMesh.prototype.newInstanceResetOffsets = function () { + var newRawObject = new RawMesh( this.smoothingGroup.splitMaterials, this.useIndices, this.disregardNormals, this.activeMtlName ); // move indices forward newRawObject.globalVertexOffset = this.globalVertexOffset + this.vertices.length / 3; @@ -953,8 +929,10 @@ THREE.OBJLoader2 = (function () { return newRawObject; }; - RawMesh.prototype.newInstanceFromGroup = function ( groupName ) { - var newRawObject = new RawMesh( this.smoothingGroup.splitMaterials, this.useIndices, this.disregardNormals, this.objectName, groupName, this.activeMtlName ); + RawMesh.prototype.newInstanceKeepOffsets = function () { + var newRawObject = new RawMesh( this.smoothingGroup.splitMaterials, this.useIndices, this.disregardNormals, this.activeMtlName ); + // keep objectName + newRawObject.pushObject( this.objectName ); // keep current buffers and indices forward newRawObject.vertices = this.vertices; @@ -1282,6 +1260,10 @@ THREE.OBJLoader2 = (function () { this.groupName = groupName; this.materialName = materialName; this.smoothingGroup = smoothingGroup; + this._init(); + } + + RawMeshSubGroup.prototype._init = function () { this.vertices = []; this.indexMappingsCount = 0; this.indexMappings = []; @@ -1289,7 +1271,7 @@ THREE.OBJLoader2 = (function () { this.colors = []; this.uvs = []; this.normals = []; - } + }; return RawMeshSubGroup; })();