wwobjloader2
Version:
New OBJLoader utilizing web worker for three.js
1 lines • 30.9 kB
JavaScript
"use strict";void 0===THREE.OBJLoader2&&(THREE.OBJLoader2={}),THREE.OBJLoader2=function(){function OBJLoader2(manager,logger){THREE.LoaderSupport.LoaderBase.call(this,manager,logger),this.logger.logInfo("Using THREE.OBJLoader2 version: "+OBJLOADER2_VERSION),this.materialPerSmoothingGroup=!1,this.fileLoader=Validator.verifyInput(this.fileLoader,new THREE.FileLoader(this.manager)),this.workerSupport=null,this.terminateWorkerOnLoad=!0}var OBJLOADER2_VERSION="2.1.1",LoaderBase=THREE.LoaderSupport.LoaderBase,Validator=THREE.LoaderSupport.Validator;THREE.LoaderSupport.ConsoleLogger;OBJLoader2.prototype=Object.create(THREE.LoaderSupport.LoaderBase.prototype),OBJLoader2.prototype.constructor=OBJLoader2,OBJLoader2.prototype.setMaterialPerSmoothingGroup=function(materialPerSmoothingGroup){this.materialPerSmoothingGroup=!0===materialPerSmoothingGroup},OBJLoader2.prototype.load=function(url,onLoad,onProgress,onError,onMeshAlter,useAsync){var scope=this;if(!Validator.isValid(onProgress)){var numericalValueRef=0,numericalValue=0;onProgress=function(event){if(event.lengthComputable&&(numericalValue=event.loaded/event.total)>numericalValueRef){numericalValueRef=numericalValue;var output='Download of "'+url+'": '+(100*numericalValue).toFixed(2)+"%";scope.onProgress("progressLoad",output,numericalValue)}}}Validator.isValid(onError)||(onError=function(event){var output='Error occurred while downloading "'+url+'"';scope.logger.logError(output+": "+event),scope.onProgress("error",output,-1)}),this.fileLoader.setPath(this.path),this.fileLoader.setResponseType("arraybuffer"),this.fileLoader.load(url,function(content){useAsync?scope.parseAsync(content,onLoad):(scope._setCallbacks(null,onMeshAlter,null),onLoad({detail:{loaderRootNode:scope.parse(content),modelName:scope.modelName,instanceNo:scope.instanceNo}}))},onProgress,onError)},OBJLoader2.prototype.run=function(prepData,workerSupportExternal){this._applyPrepData(prepData);var available=this._checkFiles(prepData.resources);Validator.isValid(workerSupportExternal)?(this.terminateWorkerOnLoad=!1,this.workerSupport=workerSupportExternal,this.logger=workerSupportExternal.logger):this.terminateWorkerOnLoad=!0;var scope=this,onMaterialsLoaded=function(materials){scope.builder.setMaterials(materials),Validator.isValid(available.obj.content)?prepData.useAsync?scope.parseAsync(available.obj.content,scope.callbacks.onLoad):scope.parse(available.obj.content):(scope.setPath(available.obj.path),scope.load(available.obj.name,scope.callbacks.onLoad,null,null,scope.callbacks.onMeshAlter,prepData.useAsync))};this._loadMtl(available.mtl,onMaterialsLoaded,prepData.crossOrigin)},OBJLoader2.prototype._applyPrepData=function(prepData){THREE.LoaderSupport.LoaderBase.prototype._applyPrepData.call(this,prepData),Validator.isValid(prepData)&&this.setMaterialPerSmoothingGroup(prepData.materialPerSmoothingGroup)},OBJLoader2.prototype.parse=function(content){this.logger.logTimeStart("OBJLoader2 parse: "+this.modelName);var parser=new Parser(this.logger);parser.setMaterialPerSmoothingGroup(this.materialPerSmoothingGroup),parser.setUseIndices(this.useIndices),parser.setDisregardNormals(this.disregardNormals),parser.setMaterials(this.builder.getMaterials());var scope=this,onMeshLoaded=function(payload){var mesh,meshes=scope.builder.processPayload(payload);for(var i in meshes)mesh=meshes[i],scope.loaderRootNode.add(mesh)};parser.setCallbackBuilder(onMeshLoaded);var onProgressScoped=function(text,numericalValue){scope.onProgress("progressParse",text,numericalValue)};if(parser.setCallbackProgress(onProgressScoped),content instanceof ArrayBuffer||content instanceof Uint8Array)this.logger.logInfo("Parsing arrayBuffer..."),parser.parse(content);else{if(!("string"==typeof content||content instanceof String))throw"Provided content was neither of type String nor Uint8Array! Aborting...";this.logger.logInfo("Parsing text..."),parser.parseText(content)}return this.logger.logTimeEnd("OBJLoader2 parse: "+this.modelName),this.loaderRootNode},OBJLoader2.prototype.parseAsync=function(content,onLoad){this.logger.logTimeStart("OBJLoader2 parseAsync: "+this.modelName);var scope=this,scopedOnLoad=function(){onLoad({detail:{loaderRootNode:scope.loaderRootNode,modelName:scope.modelName,instanceNo:scope.instanceNo}}),scope.terminateWorkerOnLoad&&scope.workerSupport.terminateWorker(),scope.logger.logTimeEnd("OBJLoader2 parseAsync: "+scope.modelName)},scopedOnMeshLoaded=function(payload){var mesh,meshes=scope.builder.processPayload(payload);for(var i in meshes)mesh=meshes[i],scope.loaderRootNode.add(mesh)};this.workerSupport=Validator.verifyInput(this.workerSupport,new THREE.LoaderSupport.WorkerSupport(this.logger));var buildCode=function(funcBuildObject,funcBuildSingelton){var workerCode="";return workerCode+="/**\n",workerCode+=" * This code was constructed by OBJLoader2 buildCode.\n",workerCode+=" */\n\n",workerCode+=funcBuildSingelton("LoaderBase","LoaderBase",LoaderBase),workerCode+=funcBuildObject("Consts",Consts),workerCode+=funcBuildSingelton("Parser","Parser",Parser),workerCode+=funcBuildSingelton("RawMesh","RawMesh",RawMesh),workerCode+=funcBuildSingelton("RawMeshSubGroup","RawMeshSubGroup",RawMeshSubGroup)};this.workerSupport.validate(buildCode,!1),this.workerSupport.setCallbacks(scopedOnMeshLoaded,scopedOnLoad);var materialNames={},materials=this.builder.getMaterials();for(var materialName in materials)materialNames[materialName]=materialName;this.workerSupport.run({params:{useAsync:!0,materialPerSmoothingGroup:this.materialPerSmoothingGroup,useIndices:this.useIndices,disregardNormals:this.disregardNormals},logger:{debug:this.logger.debug,enabled:this.logger.enabled},materials:{materials:materialNames},data:{input:content,options:null}},[content.buffer])};var Consts={CODE_LF:10,CODE_CR:13,CODE_SPACE:32,CODE_SLASH:47,STRING_LF:"\n",STRING_CR:"\r",STRING_SPACE:" ",STRING_SLASH:"/",LINE_F:"f",LINE_G:"g",LINE_L:"l",LINE_O:"o",LINE_S:"s",LINE_V:"v",LINE_VT:"vt",LINE_VN:"vn",LINE_MTLLIB:"mtllib",LINE_USEMTL:"usemtl"},Parser=function(){function Parser(logger){this.callbackProgress=null,this.callbackBuilder=null,this.materials={},this.rawMesh=null,this.useAsync=!1,this.materialPerSmoothingGroup=!1,this.useIndices=!1,this.disregardNormals=!1,this.inputObjectCount=1,this.outputObjectCount=1,this.counts={vertices:0,faces:0,doubleIndicesCount:0},this.logger=logger,this.totalBytes=0}return Parser.prototype.setUseAsync=function(useAsync){this.useAsync=useAsync},Parser.prototype.setMaterialPerSmoothingGroup=function(materialPerSmoothingGroup){this.materialPerSmoothingGroup=materialPerSmoothingGroup},Parser.prototype.setUseIndices=function(useIndices){this.useIndices=useIndices},Parser.prototype.setDisregardNormals=function(disregardNormals){this.disregardNormals=disregardNormals},Parser.prototype.setMaterials=function(materials){this.materials=Validator.verifyInput(materials,this.materials),this.materials=Validator.verifyInput(this.materials,{})},Parser.prototype.setCallbackBuilder=function(callbackBuilder){if(this.callbackBuilder=callbackBuilder,!Validator.isValid(this.callbackBuilder))throw'Unable to run as no "builder" callback is set.'},Parser.prototype.setCallbackProgress=function(callbackProgress){this.callbackProgress=callbackProgress},Parser.prototype.configure=function(){if(this.rawMesh=new RawMesh(this.materialPerSmoothingGroup,this.useIndices,this.disregardNormals),this.logger.isEnabled()){var matKeys=Object.keys(this.materials),matNames=matKeys.length>0?"\n\tmaterialNames:\n\t\t- "+matKeys.join("\n\t\t- "):"\n\tmaterialNames: None",printedConfig="OBJLoader2.Parser configuration:"+matNames+"\n\tuseAsync: "+this.useAsync+"\n\tmaterialPerSmoothingGroup: "+this.materialPerSmoothingGroup+"\n\tuseIndices: "+this.useIndices+"\n\tdisregardNormals: "+this.disregardNormals+"\n\tcallbackBuilderName: "+this.callbackBuilder.name+"\n\tcallbackProgressName: "+this.callbackProgress.name;this.logger.logInfo(printedConfig)}},Parser.prototype.parse=function(arrayBuffer){this.logger.logTimeStart("OBJLoader2.Parser.parse"),this.configure();var arrayBufferView=new Uint8Array(arrayBuffer),length=arrayBufferView.byteLength;this.totalBytes=length;for(var code,buffer=new Array(128),bufferPointer=0,slashSpacePattern=new Array(16),slashSpacePatternPointer=0,reachedFaces=!1,word="",i=0;i<length;i++)switch(code=arrayBufferView[i]){case Consts.CODE_SPACE:word.length>0&&(buffer[bufferPointer++]=word),slashSpacePattern[slashSpacePatternPointer++]=0,word="";break;case Consts.CODE_SLASH:word.length>0&&(buffer[bufferPointer++]=word),slashSpacePattern[slashSpacePatternPointer++]=1,word="";break;case Consts.CODE_LF:word.length>0&&(buffer[bufferPointer++]=word),word="",reachedFaces=this.processLine(buffer,bufferPointer,slashSpacePattern,slashSpacePatternPointer,reachedFaces,i),bufferPointer=0,slashSpacePatternPointer=0;break;case Consts.CODE_CR:break;default:word+=String.fromCharCode(code)}this.finalize(i),this.logger.logTimeEnd("OBJLoader2.Parser.parse")},Parser.prototype.parseText=function(text){this.logger.logTimeStart("OBJLoader2.Parser.parseText"),this.configure();var length=text.length;this.totalBytes=length;for(var char,buffer=new Array(128),bufferPointer=0,slashSpacePattern=new Array(16),slashSpacePatternPointer=0,reachedFaces=!1,word="",i=0;i<length;i++)switch(char=text[i]){case Consts.STRING_SPACE:word.length>0&&(buffer[bufferPointer++]=word),slashSpacePattern[slashSpacePatternPointer++]=0,word="";break;case Consts.STRING_SLASH:word.length>0&&(buffer[bufferPointer++]=word),slashSpacePattern[slashSpacePatternPointer++]=1,word="";break;case Consts.STRING_LF:word.length>0&&(buffer[bufferPointer++]=word),word="",reachedFaces=this.processLine(buffer,bufferPointer,slashSpacePattern,slashSpacePatternPointer,reachedFaces,i),bufferPointer=0,slashSpacePatternPointer=0;break;case Consts.STRING_CR:break;default:word+=char}this.finalize(i),this.logger.logTimeEnd("OBJLoader2.Parser.parseText")},Parser.prototype.processLine=function(buffer,bufferPointer,slashSpacePattern,slashSpacePatternPointer,reachedFaces,currentByte){if(bufferPointer<1)return reachedFaces;var countSlashes=function(slashSpacePattern,slashSpacePatternPointer){for(var slashesCount=0,i=0;i<slashSpacePatternPointer;i++)slashesCount+=slashSpacePattern[i];return slashesCount},concatStringBuffer=function(buffer,bufferPointer,slashSpacePattern){var concatBuffer="";if(2===bufferPointer)concatBuffer=buffer[1];else{for(var bufferLength=bufferPointer-1,i=1;i<bufferLength;i++)concatBuffer+=buffer[i]+(0===slashSpacePattern[i]?" ":"/");concatBuffer+=buffer[bufferLength]}return concatBuffer},flushStringBuffer=function(buffer,bufferPointer){for(var i=0;i<bufferPointer;i++)buffer[i]=""};switch(buffer[0]){case Consts.LINE_V:if(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=!1}4===bufferPointer?this.rawMesh.pushVertex(buffer):this.rawMesh.pushVertexAndVertextColors(buffer);break;case Consts.LINE_VT:this.rawMesh.pushUv(buffer);break;case Consts.LINE_VN:this.rawMesh.pushNormal(buffer);break;case Consts.LINE_F:reachedFaces=!0,this.rawMesh.processFaces(buffer,bufferPointer,countSlashes(slashSpacePattern,slashSpacePatternPointer));break;case Consts.LINE_L:this.rawMesh.processLines(buffer,bufferPointer,countSlashes(slashSpacePattern,slashSpacePatternPointer));break;case Consts.LINE_S:this.rawMesh.pushSmoothingGroup(buffer[1]),flushStringBuffer(buffer,bufferPointer);break;case Consts.LINE_G:this.processCompletedGroup(concatStringBuffer(buffer,bufferPointer,slashSpacePattern),currentByte),reachedFaces=!1,flushStringBuffer(buffer,bufferPointer);break;case Consts.LINE_O:this.processCompletedObject(concatStringBuffer(buffer,bufferPointer,slashSpacePattern),this.rawMesh.groupName,currentByte),reachedFaces=!1,flushStringBuffer(buffer,bufferPointer);break;case Consts.LINE_MTLLIB:this.rawMesh.pushMtllib(concatStringBuffer(buffer,bufferPointer,slashSpacePattern)),flushStringBuffer(buffer,bufferPointer);break;case Consts.LINE_USEMTL:this.rawMesh.pushUsemtl(concatStringBuffer(buffer,bufferPointer,slashSpacePattern)),flushStringBuffer(buffer,bufferPointer)}return reachedFaces},Parser.prototype.createRawMeshReport=function(rawMesh,inputObjectCount){var report=rawMesh.createReport(inputObjectCount);return"Input Object number: "+inputObjectCount+"\n\tObject name: "+report.objectName+"\n\tGroup name: "+report.groupName+"\n\tMtllib name: "+report.mtllibName+"\n\tVertex count: "+report.vertexCount+"\n\tNormal count: "+report.normalCount+"\n\tUV count: "+report.uvCount+"\n\tSmoothingGroup count: "+report.smoothingGroupCount+"\n\tMaterial count: "+report.mtlCount+"\n\tReal RawMeshSubGroup count: "+report.subGroups},Parser.prototype.processCompletedObject=function(objectName,groupName,currentByte){var result=this.rawMesh.finalize();if(Validator.isValid(result)){this.inputObjectCount++,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: "+(100*progressBytesPercent).toFixed(2)+"%",progressBytesPercent),this.rawMesh=this.rawMesh.newInstanceFromObject(objectName,groupName)}else this.rawMesh.pushObject(objectName)},Parser.prototype.processCompletedGroup=function(groupName,currentByte){var result=this.rawMesh.finalize();if(Validator.isValid(result)){this.inputObjectCount++,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: "+(100*progressBytesPercent).toFixed(2)+"%",progressBytesPercent),this.rawMesh=this.rawMesh.newInstanceFromGroup(groupName)}else this.rawMesh.pushGroup(groupName)},Parser.prototype.finalize=function(currentByte){this.logger.logInfo("Global output object count: "+this.outputObjectCount);var result=Validator.isValid(this.rawMesh)?this.rawMesh.finalize():null;if(Validator.isValid(result)){if(this.inputObjectCount++,this.logger.isDebug()&&this.logger.logDebug(this.createRawMeshReport(this.rawMesh,this.inputObjectCount)),this.buildMesh(result,currentByte),this.logger.isEnabled()){var parserFinalReport="Overall counts: \n\tVertices: "+this.counts.vertices+"\n\tFaces: "+this.counts.faces+"\n\tMultiple definitions: "+this.counts.doubleIndicesCount;this.logger.logInfo(parserFinalReport)}var progressBytesPercent=currentByte/this.totalBytes;this.callbackProgress("Completed Parsing: 100.00%",progressBytesPercent)}},Parser.prototype.buildMesh=function(result,currentByte){var rawObjectDescriptions=result.subGroups,vertexFA=new Float32Array(result.absoluteVertexCount);this.counts.vertices+=result.absoluteVertexCount/3,this.counts.faces+=result.faceCount,this.counts.doubleIndicesCount+=result.doubleIndicesCount;var rawObjectDescription,selectedMaterialIndex,materialGroup,materialOrg,material,materialName,materialNameOrg,indexUA=result.absoluteIndexCount>0?new Uint32Array(result.absoluteIndexCount):null,colorFA=result.absoluteColorCount>0?new Float32Array(result.absoluteColorCount):null,normalFA=result.absoluteNormalCount>0?new Float32Array(result.absoluteNormalCount):null,uvFA=result.absoluteUvCount>0?new Float32Array(result.absoluteUvCount):null,haveVertexColors=Validator.isValid(colorFA),materialNames=[],createMultiMaterial=rawObjectDescriptions.length>1,materialIndex=0,materialIndexMapping=[],materialGroups=[],vertexFAOffset=0,indexUAOffset=0,colorFAOffset=0,normalFAOffset=0,uvFAOffset=0,materialGroupOffset=0,materialGroupLength=0;for(var oodIndex in rawObjectDescriptions)if(rawObjectDescriptions.hasOwnProperty(oodIndex)){if(rawObjectDescription=rawObjectDescriptions[oodIndex],materialNameOrg=rawObjectDescription.materialName,materialName=materialNameOrg+(haveVertexColors?"_vertexColor":"")+(0===rawObjectDescription.smoothingGroup?"_flat":""),materialOrg=this.materials[materialNameOrg],material=this.materials[materialName],!Validator.isValid(materialOrg)&&!Validator.isValid(material)){var defaultMaterialName=haveVertexColors?"vertexColorMaterial":"defaultMaterial";materialOrg=this.materials[defaultMaterialName],this.logger.logWarn('object_group "'+rawObjectDescription.objectName+"_"+rawObjectDescription.groupName+'" was defined with unresolvable material "'+materialNameOrg+'"! Assigning "'+defaultMaterialName+'".'),materialNameOrg=defaultMaterialName,materialNameOrg===materialName&&(material=materialOrg,materialName=defaultMaterialName)}if(!Validator.isValid(material)){var materialCloneInstructions={materialNameOrg:materialNameOrg,materialName:materialName,materialProperties:{vertexColors:haveVertexColors?2:0,flatShading:0===rawObjectDescription.smoothingGroup}},payload={cmd:"materialData",materials:{materialCloneInstructions:materialCloneInstructions}};this.callbackBuilder(payload),this.useAsync&&(this.materials[materialName]=materialCloneInstructions)}if(createMultiMaterial?(selectedMaterialIndex=materialIndexMapping[materialName],selectedMaterialIndex||(selectedMaterialIndex=materialIndex,materialIndexMapping[materialName]=materialIndex,materialNames.push(materialName),materialIndex++),materialGroupLength=this.useIndices?rawObjectDescription.indices.length:rawObjectDescription.vertices.length/3,materialGroup={start:materialGroupOffset,count:materialGroupLength,index:selectedMaterialIndex},materialGroups.push(materialGroup),materialGroupOffset+=materialGroupLength):materialNames.push(materialName),vertexFA.set(rawObjectDescription.vertices,vertexFAOffset),vertexFAOffset+=rawObjectDescription.vertices.length,indexUA&&(indexUA.set(rawObjectDescription.indices,indexUAOffset),indexUAOffset+=rawObjectDescription.indices.length),colorFA&&(colorFA.set(rawObjectDescription.colors,colorFAOffset),colorFAOffset+=rawObjectDescription.colors.length),normalFA&&(normalFA.set(rawObjectDescription.normals,normalFAOffset),normalFAOffset+=rawObjectDescription.normals.length),uvFA&&(uvFA.set(rawObjectDescription.uvs,uvFAOffset),uvFAOffset+=rawObjectDescription.uvs.length),this.logger.isDebug()){var materialIndexLine=Validator.isValid(selectedMaterialIndex)?"\n\t\tmaterialIndex: "+selectedMaterialIndex:"",createdReport="Output Object no.: "+this.outputObjectCount+"\n\t\tobjectName: "+rawObjectDescription.objectName+"\n\t\tgroupName: "+rawObjectDescription.groupName+"\n\t\tmaterialName: "+rawObjectDescription.materialName+materialIndexLine+"\n\t\tsmoothingGroup: "+rawObjectDescription.smoothingGroup+"\n\t\t#vertices: "+rawObjectDescription.vertices.length/3+"\n\t\t#indices: "+rawObjectDescription.indices.length+"\n\t\t#colors: "+rawObjectDescription.colors.length/3+"\n\t\t#uvs: "+rawObjectDescription.uvs.length/2+"\n\t\t#normals: "+rawObjectDescription.normals.length/3;this.logger.logDebug(createdReport)}}this.outputObjectCount++,this.callbackBuilder({cmd:"meshData",progress:{numericalValue:currentByte/this.totalBytes},params:{meshName:result.name},materials:{multiMaterial:createMultiMaterial,materialNames:materialNames,materialGroups:materialGroups},buffers:{vertices:vertexFA,indices:indexUA,colors:colorFA,normals:normalFA,uvs:uvFA}},[vertexFA.buffer],Validator.isValid(indexUA)?[indexUA.buffer]:null,Validator.isValid(colorFA)?[colorFA.buffer]:null,Validator.isValid(normalFA)?[normalFA.buffer]:null,Validator.isValid(uvFA)?[uvFA.buffer]:null)},Parser}(),RawMesh=function(){function RawMesh(materialPerSmoothingGroup,useIndices,disregardNormals,objectName,groupName,activeMtlName){this.globalVertexOffset=1,this.globalUvOffset=1,this.globalNormalOffset=1,this.vertices=[],this.colors=[],this.normals=[],this.uvs=[],this.activeMtlName=Validator.verifyInput(activeMtlName,""),this.objectName=Validator.verifyInput(objectName,""),this.groupName=Validator.verifyInput(groupName,""),this.mtllibName="",this.smoothingGroup={splitMaterials:!0===materialPerSmoothingGroup,normalized:-1,real:-1},this.useIndices=!0===useIndices,this.disregardNormals=!0===disregardNormals,this.mtlCount=0,this.smoothingGroupCount=0,this.subGroups=[],this.subGroupInUse=null,this.pushSmoothingGroup(1),this.doubleIndicesCount=0,this.faceCount=0}return RawMesh.prototype.newInstanceFromObject=function(objectName,groupName){var newRawObject=new RawMesh(this.smoothingGroup.splitMaterials,this.useIndices,this.disregardNormals,objectName,groupName,this.activeMtlName);return newRawObject.globalVertexOffset=this.globalVertexOffset+this.vertices.length/3,newRawObject.globalUvOffset=this.globalUvOffset+this.uvs.length/2,newRawObject.globalNormalOffset=this.globalNormalOffset+this.normals.length/3,newRawObject},RawMesh.prototype.newInstanceFromGroup=function(groupName){var newRawObject=new RawMesh(this.smoothingGroup.splitMaterials,this.useIndices,this.disregardNormals,this.objectName,groupName,this.activeMtlName);return newRawObject.vertices=this.vertices,newRawObject.colors=this.colors,newRawObject.uvs=this.uvs,newRawObject.normals=this.normals,newRawObject.globalVertexOffset=this.globalVertexOffset,newRawObject.globalUvOffset=this.globalUvOffset,newRawObject.globalNormalOffset=this.globalNormalOffset,newRawObject},RawMesh.prototype.pushVertex=function(buffer){this.vertices.push(parseFloat(buffer[1])),this.vertices.push(parseFloat(buffer[2])),this.vertices.push(parseFloat(buffer[3]))},RawMesh.prototype.pushVertexAndVertextColors=function(buffer){this.vertices.push(parseFloat(buffer[1])),this.vertices.push(parseFloat(buffer[2])),this.vertices.push(parseFloat(buffer[3])),this.colors.push(parseFloat(buffer[4])),this.colors.push(parseFloat(buffer[5])),this.colors.push(parseFloat(buffer[6]))},RawMesh.prototype.pushUv=function(buffer){this.uvs.push(parseFloat(buffer[1])),this.uvs.push(parseFloat(buffer[2]))},RawMesh.prototype.pushNormal=function(buffer){this.normals.push(parseFloat(buffer[1])),this.normals.push(parseFloat(buffer[2])),this.normals.push(parseFloat(buffer[3]))},RawMesh.prototype.pushObject=function(objectName){this.objectName=Validator.verifyInput(objectName,"")},RawMesh.prototype.pushMtllib=function(mtllibName){this.mtllibName=Validator.verifyInput(mtllibName,"")},RawMesh.prototype.pushGroup=function(groupName){this.groupName=Validator.verifyInput(groupName,"")},RawMesh.prototype.pushUsemtl=function(mtlName){this.activeMtlName!==mtlName&&Validator.isValid(mtlName)&&(this.activeMtlName=mtlName,this.mtlCount++,this.verifyIndex())},RawMesh.prototype.pushSmoothingGroup=function(smoothingGroup){var smoothingGroupInt=parseInt(smoothingGroup);isNaN(smoothingGroupInt)&&(smoothingGroupInt="off"===smoothingGroup?0:1);var smoothCheck=this.smoothingGroup.normalized;this.smoothingGroup.normalized=this.smoothingGroup.splitMaterials?smoothingGroupInt:0===smoothingGroupInt?0:1,this.smoothingGroup.real=smoothingGroupInt,smoothCheck!==smoothingGroupInt&&(this.smoothingGroupCount++,this.verifyIndex())},RawMesh.prototype.verifyIndex=function(){var index=this.activeMtlName+"|"+this.smoothingGroup.normalized;this.subGroupInUse=this.subGroups[index],Validator.isValid(this.subGroupInUse)||(this.subGroupInUse=new RawMeshSubGroup(this.objectName,this.groupName,this.activeMtlName,this.smoothingGroup.normalized),this.subGroups[index]=this.subGroupInUse)},RawMesh.prototype.processFaces=function(buffer,bufferPointer,slashesCount){var i,length,bufferLength=bufferPointer-1;if(0===slashesCount)for(i=2,length=bufferLength-1;i<length;i++)this.buildFace(buffer[1]),this.buildFace(buffer[i]),this.buildFace(buffer[i+1]);else if(bufferLength===2*slashesCount)for(i=3,length=bufferLength-2;i<length;i+=2)this.buildFace(buffer[1],buffer[2]),this.buildFace(buffer[i],buffer[i+1]),this.buildFace(buffer[i+2],buffer[i+3]);else if(2*bufferLength==3*slashesCount)for(i=4,length=bufferLength-3;i<length;i+=3)this.buildFace(buffer[1],buffer[2],buffer[3]),this.buildFace(buffer[i],buffer[i+1],buffer[i+2]),this.buildFace(buffer[i+3],buffer[i+4],buffer[i+5]);else for(i=3,length=bufferLength-2;i<length;i+=2)this.buildFace(buffer[1],void 0,buffer[2]),this.buildFace(buffer[i],void 0,buffer[i+1]),this.buildFace(buffer[i+2],void 0,buffer[i+3])},RawMesh.prototype.buildFace=function(faceIndexV,faceIndexU,faceIndexN){var sgiu=this.subGroupInUse;this.disregardNormals&&(faceIndexN=void 0);var scope=this,updateRawObjectDescriptionInUse=function(){var indexPointerV=3*(parseInt(faceIndexV)-scope.globalVertexOffset),indexPointerC=scope.colors.length>0?indexPointerV:null,vertices=sgiu.vertices;if(vertices.push(scope.vertices[indexPointerV++]),vertices.push(scope.vertices[indexPointerV++]),vertices.push(scope.vertices[indexPointerV]),null!==indexPointerC){var colors=sgiu.colors;colors.push(scope.colors[indexPointerC++]),colors.push(scope.colors[indexPointerC++]),colors.push(scope.colors[indexPointerC])}if(faceIndexU){var indexPointerU=2*(parseInt(faceIndexU)-scope.globalUvOffset),uvs=sgiu.uvs;uvs.push(scope.uvs[indexPointerU++]),uvs.push(scope.uvs[indexPointerU])}if(faceIndexN){var indexPointerN=3*(parseInt(faceIndexN)-scope.globalNormalOffset),normals=sgiu.normals;normals.push(scope.normals[indexPointerN++]),normals.push(scope.normals[indexPointerN++]),normals.push(scope.normals[indexPointerN])}};if(this.useIndices){var mappingName=faceIndexV+(faceIndexU?"_"+faceIndexU:"_n")+(faceIndexN?"_"+faceIndexN:"_n"),indicesPointer=sgiu.indexMappings[mappingName];Validator.isValid(indicesPointer)?this.doubleIndicesCount++:(indicesPointer=sgiu.vertices.length/3,updateRawObjectDescriptionInUse(),sgiu.indexMappings[mappingName]=indicesPointer,sgiu.indexMappingsCount++),sgiu.indices.push(indicesPointer)}else updateRawObjectDescriptionInUse();this.faceCount++},RawMesh.prototype.processLines=function(buffer,bufferPointer,slashCount){var length,i=1,bufferLength=bufferPointer-1;if(bufferLength===2*slashCount)for(length=bufferLength-2;i<length;i+=2)this.vertices.push(parseInt(buffer[i])),this.uvs.push(parseInt(buffer[i+1]));else for(length=bufferLength-1;i<length;i++)this.vertices.push(parseInt(buffer[i]))},RawMesh.prototype.finalize=function(){var rawObjectDescription,indices,rawObjectDescriptionsTemp=[],absoluteVertexCount=0,absoluteIndexMappingsCount=0,absoluteIndexCount=0,absoluteColorCount=0,absoluteNormalCount=0,absoluteUvCount=0;for(var name in this.subGroups)if(rawObjectDescription=this.subGroups[name],rawObjectDescription.vertices.length>0){if(indices=rawObjectDescription.indices,indices.length>0&&absoluteIndexMappingsCount>0)for(var i in indices)indices[i]=indices[i]+absoluteIndexMappingsCount;rawObjectDescriptionsTemp.push(rawObjectDescription),absoluteVertexCount+=rawObjectDescription.vertices.length,absoluteIndexMappingsCount+=rawObjectDescription.indexMappingsCount,absoluteIndexCount+=rawObjectDescription.indices.length,absoluteColorCount+=rawObjectDescription.colors.length,absoluteUvCount+=rawObjectDescription.uvs.length,absoluteNormalCount+=rawObjectDescription.normals.length}var result=null;return rawObjectDescriptionsTemp.length>0&&(result={name:""!==this.groupName?this.groupName:this.objectName,subGroups:rawObjectDescriptionsTemp,absoluteVertexCount:absoluteVertexCount,absoluteIndexCount:absoluteIndexCount,absoluteColorCount:absoluteColorCount,absoluteNormalCount:absoluteNormalCount,absoluteUvCount:absoluteUvCount,faceCount:this.faceCount,doubleIndicesCount:this.doubleIndicesCount}),result},RawMesh.prototype.createReport=function(){return{objectName:this.objectName,groupName:this.groupName,mtllibName:this.mtllibName,vertexCount:this.vertices.length/3,normalCount:this.normals.length/3,uvCount:this.uvs.length/2,smoothingGroupCount:this.smoothingGroupCount,mtlCount:this.mtlCount,subGroups:this.subGroups.length}},RawMesh}(),RawMeshSubGroup=function(){function RawMeshSubGroup(objectName,groupName,materialName,smoothingGroup){this.objectName=objectName,this.groupName=groupName,this.materialName=materialName,this.smoothingGroup=smoothingGroup,this.vertices=[],this.indexMappingsCount=0,this.indexMappings=[],this.indices=[],this.colors=[],this.uvs=[],this.normals=[]}return RawMeshSubGroup}();return OBJLoader2.prototype._checkFiles=function(resources){var resource,result={mtl:null,obj:null};for(var index in resources)if(resource=resources[index],Validator.isValid(resource.name))if(Validator.isValid(resource.content)){if("OBJ"===resource.extension){if(!(resource.content instanceof Uint8Array))throw"Provided content is not of type arraybuffer! Aborting...";result.obj=resource}else if("MTL"===resource.extension&&Validator.isValid(resource.name)){if(!("string"==typeof resource.content||resource.content instanceof String))throw"Provided content is not of type String! Aborting...";result.mtl=resource}else if("ZIP"!==resource.extension)throw'Unidentified resource "'+resource.name+'": '+resource.url}else{if(!("string"==typeof resource.name||resource.name instanceof String))throw"Provided file is not properly defined! Aborting...";if("OBJ"===resource.extension)result.obj=resource;else if("MTL"===resource.extension)result.mtl=resource;else if("ZIP"!==resource.extension)throw'Unidentified resource "'+resource.name+'": '+resource.url}return result},OBJLoader2.prototype.loadMtl=function(url,name,content,callbackOnLoad,crossOrigin){var resource=new THREE.LoaderSupport.ResourceDescriptor(url,"MTL");resource.setContent(content),this._loadMtl(resource,callbackOnLoad,crossOrigin)},OBJLoader2.prototype._loadMtl=function(resource,callbackOnLoad,crossOrigin){Validator.isValid(resource)&&this.logger.logTimeStart("Loading MTL: "+resource.name);var materials=[],scope=this,processMaterials=function(materialCreator){var materialCreatorMaterials=[];if(Validator.isValid(materialCreator)){materialCreator.preload(),materialCreatorMaterials=materialCreator.materials;for(var materialName in materialCreatorMaterials)materialCreatorMaterials.hasOwnProperty(materialName)&&(materials[materialName]=materialCreatorMaterials[materialName])}Validator.isValid(resource)&&scope.logger.logTimeEnd("Loading MTL: "+resource.name),callbackOnLoad(materials)},mtlLoader=new THREE.MTLLoader;if(crossOrigin=Validator.verifyInput(crossOrigin,"anonymous"),mtlLoader.setCrossOrigin(crossOrigin),Validator.isValid(resource)&&(Validator.isValid(resource.content)||Validator.isValid(resource.url))){if(mtlLoader.setPath(resource.path),Validator.isValid(resource.content))processMaterials(Validator.isValid(resource.content)?mtlLoader.parse(resource.content):null);else if(Validator.isValid(resource.url)){var onError=function(event){var output='Error occurred while downloading "'+resource.url+'"';throw this.logger.logError(output+": "+event),output};mtlLoader.load(resource.name,processMaterials,void 0,onError)}}else processMaterials()},OBJLoader2}();