The code that gets generated for the blob for the worker ends up mangled. Here is an excerpt
Validator = {
isValid: function (e){return null!==e&&void 0!==e},
verifyInput: function (e,t){return null===e||void 0===e?t:e},
}
ConsolConsoleLoggerLogger = (function () {
function e(e,t){this.enabled=e!==!1,this.debug=t===!0}
ConsoleLogger.prototype.setDebug = function (e){this.debug=e===!0};
ConsoleLogger.prototype.isDebug = function (){return this.isEnabled()&&this.debug};
ConsoleLogger.prototype.setEnabled = function (e){this.enabled=e===!0};
ConsoleLogger.prototype.isEnabled = function (){return this.enabled};
ConsoleLogger.prototype.logDebug = function (e){this.enabled&&this.debug&&console.info(e)};
ConsoleLogger.prototype.logInfo = function (e){this.enabled&&console.info(e)};
ConsoleLogger.prototype.logWarn = function (e){console.warn(e)};
ConsoleLogger.prototype.logError = function (e){console.error(e)};
ConsoleLogger.prototype.logTimeStart = function (e){this.enabled&&console.time(e)};
ConsoleLogger.prototype.logTimeEnd = function (e){this.enabled&&console.timeEnd(e)};
return ConsoleLogger;
})();
/**
- This code was constructed by OBJLoader2 buildCode.
*/
LoadLoaderBaserBase = (function () {
function e(e,o){this.manager=t.verifyInput(e,THREE.DefaultLoadingManager),this.logger=t.verifyInput(o,new n),this.modelName="",this.instanceNo=0,this.path="",this.useIndices=!1,this.disregardNormals=!1,this.loaderRootNode=new THREE.Group,this.builder=new THREE.LoaderSupport.Builder(this.logger),this._createDefaultMaterials(),this.callbacks=new THREE.LoaderSupport.Callbacks}
LoaderBase.prototype._createDefaultMaterials = function (){var e=new THREE.MeshStandardMaterial({color:14479871});e.name="defaultMaterial";var t=new THREE.MeshStandardMaterial({color:14479871});t.name="vertexColorMaterial",t.vertexColors=THREE.VertexColors;var n={};n[e.name]=e,n[t.name]=t,this.builder.updateMaterials({cmd:"materialData",materials:{materialCloneInstructions:null,serializedMaterials:null,runtimeMaterials:n}})};
LoaderBase.prototype._applyPrepData = function (e){t.isValid(e)&&(this.setModelName(e.modelName),this.setStreamMeshesTo(e.streamMeshesTo),this.builder.setMaterials(e.materials),this.setUseIndices(e.useIndices),this.setDisregardNormals(e.disregardNormals),this._setCallbacks(e.getCallbacks()))};
LoaderBase.prototype._setCallbacks = function (e){t.isValid(e.onProgress)&&this.callbacks.setCallbackOnProgress(e.onProgress),t.isValid(e.onMeshAlter)&&this.callbacks.setCallbackOnMeshAlter(e.onMeshAlter),t.isValid(e.onLoad)&&this.callbacks.setCallbackOnLoad(e.onLoad),t.isValid(e.onLoadMaterials)&&this.callbacks.setCallbackOnLoadMaterials(e.onLoadMaterials),this.builder._setCallbacks(this.callbacks)};
LoaderBase.prototype.getLogger = function (){return this.logger};
LoaderBase.prototype.setModelName = function (e){this.modelName=t.verifyInput(e,this.modelName)};
LoaderBase.prototype.setPath = function (e){this.path=t.verifyInput(e,this.path)};
LoaderBase.prototype.setStreamMeshesTo = function (e){this.loaderRootNode=t.verifyInput(e,this.loaderRootNode)};
LoaderBase.prototype.setMaterials = function (e){this.builder.setMaterials(e)};
LoaderBase.prototype.setUseIndices = function (e){this.useIndices=e===!0};
LoaderBase.prototype.setDisregardNormals = function (e){this.disregardNormals=e===!0};
LoaderBase.prototype.onProgress = function (e,n,o){var a=t.isValid(n)?n:"",i={detail:{type:e,modelName:this.modelName,instanceNo:this.instanceNo,text:a,numericalValue:o}};t.isValid(this.callbacks.onProgress)&&this.callbacks.onProgress(i),this.logger.logDebug(a)};
return LoaderBase;
})();
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",
}
ParsParserr = (function () {
function e(e){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=e,this.totalBytes=0,this.reachedFaces=!1}
Parser.prototype.setUseAsync = function (e){this.useAsync=e};
Parser.prototype.setMaterialPerSmoothingGroup = function (e){this.materialPerSmoothingGroup=e};
Parser.prototype.setUseIndices = function (e){this.useIndices=e};
Parser.prototype.setDisregardNormals = function (e){this.disregardNormals=e};
Parser.prototype.setMaterials = function (e){this.materials=o.verifyInput(e,this.materials),this.materials=o.verifyInput(this.materials,{})};
Parser.prototype.setCallbackBuilder = function (e){if(this.callbackBuilder=e,!o.isValid(this.callbackBuilder))throw'Unable to run as no "builder" callback is set.'};
Parser.prototype.setCallbackProgress = function (e){this.callbackProgress=e};
Parser.prototype.configure = function (){if(this.rawMesh=new r(this.materialPerSmoothingGroup,this.useIndices,this.disregardNormals),this.logger.isEnabled()){var e=Object.keys(this.materials),t=e.length>0?"\n\tmaterialNames:\n\t\t- "+e.join("\n\t\t- "):"\n\tmaterialNames: None",n="OBJLoader2.Parser configuration:"+t+"\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(n)}};
Parser.prototype.parse = function (e){this.logger.logTimeStart("OBJLoader2.Parser.parse"),this.configure();var t=new Uint8Array(e),n=t.byteLength;this.totalBytes=n;for(var o,i=new Array(128),r=0,s=new Array(16),l=0,c="",d=0;d<n;d++)switch(o=t[d]){case a.CODE_SPACE:c.length>0&&(i[r++]=c),s[l++]=0,c="";break;case a.CODE_SLASH:c.length>0&&(i[r++]=c),s[l++]=1,c="";break;case a.CODE_LF:c.length>0&&(i[r++]=c),c="",this.processLine(i,r,s,l,d),r=0,l=0;break;case a.CODE_CR:break;default:c+=String.fromCharCode(o)}this.finalize(d),this.logger.logTimeEnd("OBJLoader2.Parser.parse")};
Parser.prototype.parseText = function (e){this.logger.logTimeStart("OBJLoader2.Parser.parseText"),this.configure();var t=e.length;this.totalBytes=t;for(var n,o=new Array(128),i=0,r=new Array(16),s=0,l="",c=0;c<t;c++)switch(n=e[c]){case a.STRING_SPACE:l.length>0&&(o[i++]=l),r[s++]=0,l="";break;case a.STRING_SLASH:l.length>0&&(o[i++]=l),r[s++]=1,l="";break;case a.STRING_LF:l.length>0&&(o[i++]=l),l="",this.processLine(o,i,r,s,c),i=0,s=0;break;case a.STRING_CR:break;default:l+=n}this.finalize(c),this.logger.logTimeEnd("OBJLoader2.Parser.parseText")};
Parser.prototype.processLine = function (e,t,n,o,i){if(!(t<1)){var r=function(e,t){for(var n=0,o=0;o<t;o++)n+=e[o];return n},s=function(e,t,n){var o="";if(2===t)o=e[1];else{for(var a=t-1,i=1;i<a;i++)o+=e[i]+(0===n[i]?" ":"/");o+=e[a]}return o},l=function(e,t){for(var n=0;n<t;n++)e[n]=""};switch(e[0]){case a.LINE_V: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.processCompletedMesh(this.rawMesh.objectName,this.rawMesh.groupName,i,!0),this.reachedFaces=!1}4===t?this.rawMesh.pushVertex(e):this.rawMesh.pushVertexAndVertextColors(e);break;case a.LINE_VT:this.rawMesh.pushUv(e);break;case a.LINE_VN:this.rawMesh.pushNormal(e);break;case a.LINE_F:this.reachedFaces=!0,this.rawMesh.processFaces(e,t,r(n,o));break;case a.LINE_L:this.rawMesh.processLines(e,t,r(n,o));break;case a.LINE_S:this.rawMesh.pushSmoothingGroup(e[1]),l(e,t);break;case a.LINE_G:this.processCompletedMesh(this.rawMesh.objectName,s(e,t,n),i,!1),l(e,t);break;case a.LINE_O:this.processCompletedMesh(s(e,t,n),this.rawMesh.groupName,i,!1),l(e,t);break;case a.LINE_MTLLIB:this.rawMesh.pushMtllib(s(e,t,n)),l(e,t);break;case a.LINE_USEMTL:this.rawMesh.pushUsemtl(s(e,t,n)),l(e,t)}}};
Parser.prototype.createRawMeshReport = function (e,t){var n=e.createReport(t);return"Input Object number: "+t+"\n\tObject name: "+n.objectName+"\n\tGroup name: "+n.groupName+"\n\tMtllib name: "+n.mtllibName+"\n\tVertex count: "+n.vertexCount+"\n\tNormal count: "+n.normalCount+"\n\tUV count: "+n.uvCount+"\n\tSmoothingGroup count: "+n.smoothingGroupCount+"\n\tMaterial count: "+n.mtlCount+"\n\tReal RawMeshSubGroup count: "+n.subGroups};
Parser.prototype.processCompletedMesh = function (e,t,n,a){var i=this.rawMesh.finalize();if(o.isValid(i)){this.inputObjectCount++,this.logger.isDebug()&&this.logger.logDebug(this.createRawMeshReport(this.rawMesh,this.inputObjectCount)),this.buildMesh(i,n);var r=n/this.totalBytes;this.callbackProgress("Completed [o: "+this.rawMesh.objectName+" g:"+this.rawMesh.groupName+"] Total progress: "+(100*r).toFixed(2)+"%",r),this.rawMesh=a?this.rawMesh.newInstanceResetOffsets():this.rawMesh.newInstanceKeepOffsets()}this.rawMesh.objectName!==e&&o.isValid(e)&&this.rawMesh.pushObject(e),this.rawMesh.groupName!==t&&o.isValid(t)&&this.rawMesh.pushGroup(t)};
Parser.prototype.finalize = function (e){this.logger.logInfo("Global output object count: "+this.outputObjectCount);var t=o.isValid(this.rawMesh)?this.rawMesh.finalize():null;if(o.isValid(t)){if(this.inputObjectCount++,this.logger.isDebug()&&this.logger.logDebug(this.createRawMeshReport(this.rawMesh,this.inputObjectCount)),this.buildMesh(t,e),this.logger.isEnabled()){var n="Overall counts: \n\tVertices: "+this.counts.vertices+"\n\tFaces: "+this.counts.faces+"\n\tMultiple definitions: "+this.counts.doubleIndicesCount;this.logger.logInfo(n)}var a=e/this.totalBytes;this.callbackProgress("Completed Parsing: 100.00%",a)}};
Parser.prototype.buildMesh = function (e,t){var n=e.subGroups,a=new Float32Array(e.absoluteVertexCount);this.counts.vertices+=e.absoluteVertexCount/3,this.counts.faces+=e.faceCount,this.counts.doubleIndicesCount+=e.doubleIndicesCount;var i,r,s,l,c,d,u,h=e.absoluteIndexCount>0?new Uint32Array(e.absoluteIndexCount):null,p=e.absoluteColorCount>0?new Float32Array(e.absoluteColorCount):null,m=e.absoluteNormalCount>0?new Float32Array(e.absoluteNormalCount):null,f=e.absoluteUvCount>0?new Float32Array(e.absoluteUvCount):null,g=o.isValid(p),v=[],E=n.length>1,b=0,y=[],w=[],T=0,M=0,R=0,H=0,x=0,k=0,L=0;for(var S in n)if(n.hasOwnProperty(S)){if(i=n[S],u=i.materialName,d=u+(g?"_vertexColor":"")+(0===i.smoothingGroup?"_flat":""),l=this.materials[u],c=this.materials[d],!o.isValid(l)&&!o.isValid(c)){var I=g?"vertexColorMaterial":"defaultMaterial";l=this.materials[I],this.logger.logWarn('object_group "'+i.objectName+"_"+i.groupName+'" was defined with unresolvable material "'+u+'"! Assigning "'+I+'".'),u=I,u===d&&(c=l,d=I)}if(!o.isValid(c)){var P={materialNameOrg:u,materialName:d,materialProperties:{vertexColors:g?2:0,flatShading:0===i.smoothingGroup}},C={cmd:"materialData",materials:{materialCloneInstructions:P}};this.callbackBuilder(C),this.useAsync&&(this.materials[d]=P)}if(E?(r=y[d],r||(r=b,y[d]=b,v.push(d),b++),L=this.useIndices?i.indices.length:i.vertices.length/3,s={start:k,count:L,index:r},w.push(s),k+=L):v.push(d),a.set(i.vertices,T),T+=i.vertices.length,h&&(h.set(i.indices,M),M+=i.indices.length),p&&(p.set(i.colors,R),R+=i.colors.length),m&&(m.set(i.normals,H),H+=i.normals.length),f&&(f.set(i.uvs,x),x+=i.uvs.length),this.logger.isDebug()){var A=o.isValid(r)?"\n\t\tmaterialIndex: "+r:"",B="Output Object no.: "+this.outputObjectCount+"\n\t\tobjectName: "+i.objectName+"\n\t\tgroupName: "+i.groupName+"\n\t\tmaterialName: "+i.materialName+A+"\n\t\tsmoothingGroup: "+i.smoothingGroup+"\n\t\t#vertices: "+i.vertices.length/3+"\n\t\t#indices: "+i.indices.length+"\n\t\t#colors: "+i.colors.length/3+"\n\t\t#uvs: "+i.uvs.length/2+"\n\t\t#normals: "+i.normals.length/3;this.logger.logDebug(B)}}this.outputObjectCount++,this.callbackBuilder({cmd:"meshData",progress:{numericalValue:t/this.totalBytes},params:{meshName:e.name},materials:{multiMaterial:E,materialNames:v,materialGroups:w},buffers:{vertices:a,indices:h,colors:p,normals:m,uvs:f}},[a.buffer],o.isValid(h)?[h.buffer]:null,o.isValid(p)?[p.buffer]:null,o.isValid(m)?[m.buffer]:null,o.isValid(f)?[f.buffer]:null)};
return Parser;
})();
RawMRawMeshsh = (function () {
function e(e,t,n,a){this.globalVertexOffset=1,this.globalUvOffset=1,this.globalNormalOffset=1,this.vertices=[],this.colors=[],this.normals=[],this.uvs=[],this.activeMtlName=o.verifyInput(a,""),this.objectName="",this.groupName="",this.mtllibName="",this.smoothingGroup={splitMaterials:e===!0,normalized:-1,real:-1},this.useIndices=t===!0,this.disregardNormals=n===!0,this.mtlCount=0,this.smoothingGroupCount=0,this.subGroups=[],this.subGroupInUse=null,this.pushSmoothingGroup(1),this.doubleIndicesCount=0,this.faceCount=0}
RawMesh.prototype.newInstanceResetOffsets = function (){var t=new e(this.smoothingGroup.splitMaterials,this.useIndices,this.disregardNormals,this.activeMtlName);return t.globalVertexOffset=this.globalVertexOffset+this.vertices.length/3,t.globalUvOffset=this.globalUvOffset+this.uvs.length/2,t.globalNormalOffset=this.globalNormalOffset+this.normals.length/3,t};
RawMesh.prototype.newInstanceKeepOffsets = function (){var t=new e(this.smoothingGroup.splitMaterials,this.useIndices,this.disregardNormals,this.activeMtlName);return t.pushObject(this.objectName),t.vertices=this.vertices,t.colors=this.colors,t.uvs=this.uvs,t.normals=this.normals,t.globalVertexOffset=this.globalVertexOffset,t.globalUvOffset=this.globalUvOffset,t.globalNormalOffset=this.globalNormalOffset,t};
RawMesh.prototype.pushVertex = function (e){this.vertices.push(parseFloat(e[1])),this.vertices.push(parseFloat(e[2])),this.vertices.push(parseFloat(e[3]))};
RawMesh.prototype.pushVertexAndVertextColors = function (e){this.vertices.push(parseFloat(e[1])),this.vertices.push(parseFloat(e[2])),this.vertices.push(parseFloat(e[3])),this.colors.push(parseFloat(e[4])),this.colors.push(parseFloat(e[5])),this.colors.push(parseFloat(e[6]))};
RawMesh.prototype.pushUv = function (e){this.uvs.push(parseFloat(e[1])),this.uvs.push(parseFloat(e[2]))};
RawMesh.prototype.pushNormal = function (e){this.normals.push(parseFloat(e[1])),this.normals.push(parseFloat(e[2])),this.normals.push(parseFloat(e[3]))};
RawMesh.prototype.pushObject = function (e){this.objectName=o.verifyInput(e,"")};
RawMesh.prototype.pushMtllib = function (e){this.mtllibName=o.verifyInput(e,"")};
RawMesh.prototype.pushGroup = function (e){this.groupName=o.verifyInput(e,"")};
RawMesh.prototype.pushUsemtl = function (e){this.activeMtlName!==e&&o.isValid(e)&&(this.activeMtlName=e,this.mtlCount++,this.verifyIndex())};
RawMesh.prototype.pushSmoothingGroup = function (e){var t=parseInt(e);isNaN(t)&&(t="off"===e?0:1);var n=this.smoothingGroup.normalized;this.smoothingGroup.normalized=this.smoothingGroup.splitMaterials?t:0===t?0:1,this.smoothingGroup.real=t,n!==t&&(this.smoothingGroupCount++,this.verifyIndex())};
RawMesh.prototype.verifyIndex = function (){var e=this.activeMtlName+"|"+this.smoothingGroup.normalized;this.subGroupInUse=this.subGroups[e],o.isValid(this.subGroupInUse)||(this.subGroupInUse=new s(this.objectName,this.groupName,this.activeMtlName,this.smoothingGroup.normalized),this.subGroups[e]=this.subGroupInUse)};
RawMesh.prototype.processFaces = function (e,t,n){var o,a,i=t-1;if(0===n)for(o=2,a=i-1;o<a;o++)this.buildFace(e[1]),this.buildFace(e[o]),this.buildFace(e[o+1]);else if(i===2*n)for(o=3,a=i-2;o<a;o+=2)this.buildFace(e[1],e[2]),this.buildFace(e[o],e[o+1]),this.buildFace(e[o+2],e[o+3]);else if(2*i===3*n)for(o=4,a=i-3;o<a;o+=3)this.buildFace(e[1],e[2],e[3]),this.buildFace(e[o],e[o+1],e[o+2]),this.buildFace(e[o+3],e[o+4],e[o+5]);else for(o=3,a=i-2;o<a;o+=2)this.buildFace(e[1],void 0,e[2]),this.buildFace(e[o],void 0,e[o+1]),this.buildFace(e[o+2],void 0,e[o+3])};
RawMesh.prototype.buildFace = function (e,t,n){var a=this.subGroupInUse;this.disregardNormals&&(n=void 0);var i=this,r=function(){var o=3*(parseInt(e)-i.globalVertexOffset),r=i.colors.length>0?o:null,s=a.vertices;if(s.push(i.vertices[o++]),s.push(i.vertices[o++]),s.push(i.vertices[o]),null!==r){var l=a.colors;l.push(i.colors[r++]),l.push(i.colors[r++]),l.push(i.colors[r])}if(t){var c=2*(parseInt(t)-i.globalUvOffset),d=a.uvs;d.push(i.uvs[c++]),d.push(i.uvs[c])}if(n){var u=3*(parseInt(n)-i.globalNormalOffset),h=a.normals;h.push(i.normals[u++]),h.push(i.normals[u++]),h.push(i.normals[u])}};if(this.useIndices){var s=e+(t?"_"+t:"_n")+(n?"_"+n:"_n"),l=a.indexMappings[s];o.isValid(l)?this.doubleIndicesCount++:(l=a.vertices.length/3,r(),a.indexMappings[s]=l,a.indexMappingsCount++),a.indices.push(l)}else r();this.faceCount++};
RawMesh.prototype.processLines = function (e,t,n){var o,a=1,i=t-1;if(i===2*n)for(o=i-2;a<o;a+=2)this.vertices.push(parseInt(e[a])),this.uvs.push(parseInt(e[a+1]));else for(o=i-1;a<o;a++)this.vertices.push(parseInt(e[a]))};
RawMesh.prototype.finalize = function (){var e,t,n=[],o=0,a=0,i=0,r=0,s=0,l=0;for(var c in this.subGroups)if(e=this.subGroups[c],e.vertices.length>0){if(t=e.indices,t.length>0&&a>0)for(var d in t)t[d]=t[d]+a;n.push(e),o+=e.vertices.length,a+=e.indexMappingsCount,i+=e.indices.length,r+=e.colors.length,l+=e.uvs.length,s+=e.normals.length}var u=null;return n.length>0&&(u={name:""!==this.groupName?this.groupName:this.objectName,subGroups:n,absoluteVertexCount:o,absoluteIndexCount:i,absoluteColorCount:r,absoluteNormalCount:s,absoluteUvCount:l,faceCount:this.faceCount,doubleIndicesCount:this.doubleIndicesCount}),u};
RawMesh.prototype.createReport = function (){var e={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};return e};
return RawMesh;
})();
RawMRawMeshSubGroupshSubGroup = (function () {
function e(e,t,n,o){this.objectName=e,this.groupName=t,this.materialName=n,this.smoothingGroup=o,this._init()}
RawMeshSubGroup.prototype._init = function (){this.vertices=[],this.indexMappingsCount=0,this.indexMappings=[],this.indices=[],this.colors=[],this.uvs=[],this.normals=[]};
return RawMeshSubGroup;
})();
e = (function () {
function e(){var e=this,t=function(t){e.processMessage(t.data)};self.addEventListener("message",t,!1)}
e.prototype.applyProperties = function (e,t){var n,o,a;for(n in t)o="set"+n.substring(0,1).toLocaleUpperCase()+n.substring(1),a=t[n],"function"==typeof e[o]?e[o](a):e.hasOwnProperty(n)&&(e[n]=a)};
e.prototype.processMessage = function (e){var t=new ConsoleLogger;if(Validator.isValid(e.logger)&&(t.setEnabled(e.logger.enabled),t.setDebug(e.logger.debug)),"run"===e.cmd){var n={callbackBuilder:function(e){self.postMessage(e)},callbackProgress:function(e){t.logDebug("WorkerRunner: progress: "+e)}},o=new Parser(t);this.applyProperties(o,e.params),this.applyProperties(o,e.materials),this.applyProperties(o,n),o.workerScope=self,o.parse(e.data.input,e.data.options),t.logInfo("WorkerRunner: Run complete!"),n.callbackBuilder({cmd:"complete",msg:"WorkerRunner completed run."})}else t.logError("WorkerRunner: Received unknown command: "+e.cmd)};
return e;
})();
new e();
This is what the same exfiltration from non minified code looks like
Validator = {
isValid: function ( input ) {
return ( input !== null && input !== undefined );
},
verifyInput: function ( input, defaultValue ) {
return ( input === null || input === undefined ) ? defaultValue : input;
},
}
ConsoleLogger = (function () {
function ConsoleLogger( enabled, debug ) {
this.enabled = enabled !== false;
this.debug = debug === true;
}
ConsoleLogger.prototype.setDebug = function ( debug ) {
this.debug = debug === true;
};
ConsoleLogger.prototype.isDebug = function () {
return this.isEnabled() && this.debug;
};
ConsoleLogger.prototype.setEnabled = function ( enabled ) {
this.enabled = enabled === true;
};
ConsoleLogger.prototype.isEnabled = function () {
return this.enabled;
};
ConsoleLogger.prototype.logDebug = function ( message ) {
if ( this.enabled && this.debug ) console.info( message );
};
ConsoleLogger.prototype.logInfo = function ( message ) {
if ( this.enabled ) console.info( message );
};
ConsoleLogger.prototype.logWarn = function ( message ) {
console.warn( message );
};
ConsoleLogger.prototype.logError = function ( message ) {
console.error( message );
};
ConsoleLogger.prototype.logTimeStart = function ( id ) {
if ( this.enabled ) console.time( id );
};
ConsoleLogger.prototype.logTimeEnd = function ( id ) {
if ( this.enabled ) console.timeEnd( id );
};
return ConsoleLogger;
})();
/**
- This code was constructed by OBJLoader2 buildCode.
*/
LoaderBase = (function () {
function LoaderBase( manager, logger ) {
this.manager = Validator.verifyInput( manager, THREE.DefaultLoadingManager );
this.logger = Validator.verifyInput( logger, new ConsoleLogger() );
this.modelName = '';
this.instanceNo = 0;
this.path = '';
this.useIndices = false;
this.disregardNormals = false;
this.loaderRootNode = new THREE.Group();
this.builder = new THREE.LoaderSupport.Builder( this.logger );
this._createDefaultMaterials();
this.callbacks = new THREE.LoaderSupport.Callbacks();
}
LoaderBase.prototype._createDefaultMaterials = function () {
var defaultMaterial = new THREE.MeshStandardMaterial( { color: 0xDCF1FF } );
defaultMaterial.name = 'defaultMaterial';
var vertexColorMaterial = new THREE.MeshStandardMaterial( { color: 0xDCF1FF } );
vertexColorMaterial.name = 'vertexColorMaterial';
vertexColorMaterial.vertexColors = THREE.VertexColors;
var runtimeMaterials = {};
runtimeMaterials[ defaultMaterial.name ] = defaultMaterial;
runtimeMaterials[ vertexColorMaterial.name ] = vertexColorMaterial;
this.builder.updateMaterials(
{
cmd: 'materialData',
materials: {
materialCloneInstructions: null,
serializedMaterials: null,
runtimeMaterials: runtimeMaterials
}
}
);
};
LoaderBase.prototype._applyPrepData = function ( prepData ) {
if ( Validator.isValid( prepData ) ) {
this.setModelName( prepData.modelName );
this.setStreamMeshesTo( prepData.streamMeshesTo );
this.builder.setMaterials( prepData.materials );
this.setUseIndices( prepData.useIndices );
this.setDisregardNormals( prepData.disregardNormals );
this._setCallbacks( prepData.getCallbacks() );
}
};
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( this.callbacks );
};
LoaderBase.prototype.getLogger = function () {
return this.logger;
};
LoaderBase.prototype.setModelName = function ( modelName ) {
this.modelName = Validator.verifyInput( modelName, this.modelName );
};
LoaderBase.prototype.setPath = function ( path ) {
this.path = Validator.verifyInput( path, this.path );
};
LoaderBase.prototype.setStreamMeshesTo = function ( streamMeshesTo ) {
this.loaderRootNode = Validator.verifyInput( streamMeshesTo, this.loaderRootNode );
};
LoaderBase.prototype.setMaterials = function ( materials ) {
this.builder.setMaterials( materials );
};
LoaderBase.prototype.setUseIndices = function ( useIndices ) {
this.useIndices = useIndices === true;
};
LoaderBase.prototype.setDisregardNormals = function ( disregardNormals ) {
this.disregardNormals = disregardNormals === true;
};
LoaderBase.prototype.onProgress = function ( type, text, numericalValue ) {
var content = Validator.isValid( text ) ? text: '';
var event = {
detail: {
type: type,
modelName: this.modelName,
instanceNo: this.instanceNo,
text: content,
numericalValue: numericalValue
}
};
if ( Validator.isValid( this.callbacks.onProgress ) ) this.callbacks.onProgress( event );
this.logger.logDebug( content );
};
return LoaderBase;
})();
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 = false;
this.materialPerSmoothingGroup = false;
this.useIndices = false;
this.disregardNormals = false;
this.inputObjectCount = 1;
this.outputObjectCount = 1;
this.counts = {
vertices: 0,
faces: 0,
doubleIndicesCount: 0
};
this.logger = logger;
this.totalBytes = 0;
this.reachedFaces = false;
}
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 ) {
this.callbackBuilder = callbackBuilder;
if ( ! 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 () {
this.rawMesh = new RawMesh( this.materialPerSmoothingGroup, this.useIndices, this.disregardNormals );
if ( this.logger.isEnabled() ) {
var matKeys = Object.keys( this.materials );
var matNames = ( matKeys.length > 0 ) ? '\n\tmaterialNames:\n\t\t- ' + matKeys.join( '\n\t\t- ' ) : '\n\tmaterialNames: None';
var 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 );
var length = arrayBufferView.byteLength;
this.totalBytes = length;
var buffer = new Array( 128 );
var bufferPointer = 0;
var slashSpacePattern = new Array( 16 );
var slashSpacePatternPointer = 0;
var code;
var word = '';
var i = 0;
for ( ; i < length; i++ ) {
code = arrayBufferView[ i ];
switch ( code ) {
case Consts.CODE_SPACE:
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
slashSpacePattern[ slashSpacePatternPointer++ ] = 0;
word = '';
break;
case Consts.CODE_SLASH:
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
slashSpacePattern[ slashSpacePatternPointer++ ] = 1;
word = '';
break;
case Consts.CODE_LF:
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
word = '';
this.processLine( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, i );
bufferPointer = 0;
slashSpacePatternPointer = 0;
break;
case Consts.CODE_CR:
break;
default:
word += String.fromCharCode( code );
break;
}
}
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;
var buffer = new Array( 128 );
var bufferPointer = 0;
var slashSpacePattern = new Array( 16 );
var slashSpacePatternPointer = 0;
var char;
var word = '';
var i = 0;
for ( ; i < length; i++ ) {
char = text[ i ];
switch ( char ) {
case Consts.STRING_SPACE:
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
slashSpacePattern[ slashSpacePatternPointer++ ] = 0;
word = '';
break;
case Consts.STRING_SLASH:
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
slashSpacePattern[ slashSpacePatternPointer++ ] = 1;
word = '';
break;
case Consts.STRING_LF:
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
word = '';
this.processLine( buffer, bufferPointer, slashSpacePattern, slashSpacePatternPointer, 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, currentByte ) {
if ( bufferPointer < 1 ) return;
var countSlashes = function ( slashSpacePattern, slashSpacePatternPointer ) {
var slashesCount = 0;
for ( var i = 0; i < slashSpacePatternPointer; i++ ) {
slashesCount += slashSpacePattern[ i ];
}
return slashesCount;
};
var concatStringBuffer = function ( buffer, bufferPointer, slashSpacePattern ) {
var concatBuffer = '';
if ( bufferPointer === 2 ) {
concatBuffer = buffer[ 1 ];
} else {
var bufferLength = bufferPointer - 1;
for ( var i = 1; i < bufferLength; i++ ) {
concatBuffer += buffer[ i ] + ( slashSpacePattern[ i ] === 0 ? ' ' : '/' );
}
concatBuffer += buffer[ bufferLength ];
}
return concatBuffer;
};
var flushStringBuffer = function ( buffer, bufferPointer ) {
for ( var i = 0; i < bufferPointer; i++ ) {
buffer[ i ] = '';
}
};
switch ( buffer[ 0 ] ) {
case Consts.LINE_V:
// object complete instance required if reached faces already (= reached next block of v)
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!';
}
// 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 ) {
this.rawMesh.pushVertex( buffer )
} else {
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:
this.reachedFaces = true;
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.processCompletedMesh( this.rawMesh.objectName, concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), currentByte, false );
flushStringBuffer( buffer, bufferPointer );
break;
case Consts.LINE_O:
this.processCompletedMesh( concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), this.rawMesh.groupName, currentByte, false );
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 );
break;
default:
break;
}
};
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.processCompletedMesh = function ( objectName, groupName, currentByte, beginNewObject ) {
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 [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 ) {
this.logger.logInfo( 'Global output object count: ' + this.outputObjectCount );
var result = Validator.isValid( this.rawMesh ) ? this.rawMesh.finalize() : null;
if ( Validator.isValid( result ) ) {
this.inputObjectCount++;
if ( this.logger.isDebug() ) this.logger.logDebug( this.createRawMeshReport( this.rawMesh, this.inputObjectCount ) );
this.buildMesh( result, currentByte );
if ( 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;
var vertexFA = new Float32Array( result.absoluteVertexCount );
this.counts.vertices += result.absoluteVertexCount / 3;
this.counts.faces += result.faceCount;
this.counts.doubleIndicesCount += result.doubleIndicesCount;
var indexUA = ( result.absoluteIndexCount > 0 ) ? new Uint32Array( result.absoluteIndexCount ) : null;
var colorFA = ( result.absoluteColorCount > 0 ) ? new Float32Array( result.absoluteColorCount ) : null;
var normalFA = ( result.absoluteNormalCount > 0 ) ? new Float32Array( result.absoluteNormalCount ) : null;
var uvFA = ( result.absoluteUvCount > 0 ) ? new Float32Array( result.absoluteUvCount ) : null;
var haveVertexColors = Validator.isValid( colorFA );
var rawObjectDescription;
var materialNames = [];
var createMultiMaterial = ( rawObjectDescriptions.length > 1 );
var materialIndex = 0;
var materialIndexMapping = [];
var selectedMaterialIndex;
var materialGroup;
var materialGroups = [];
var vertexFAOffset = 0;
var indexUAOffset = 0;
var colorFAOffset = 0;
var normalFAOffset = 0;
var uvFAOffset = 0;
var materialGroupOffset = 0;
var materialGroupLength = 0;
var materialOrg, material, materialName, materialNameOrg;
for ( var oodIndex in rawObjectDescriptions ) {
if ( ! rawObjectDescriptions.hasOwnProperty( oodIndex ) ) continue;
rawObjectDescription = rawObjectDescriptions[ oodIndex ];
materialNameOrg = rawObjectDescription.materialName;
materialName = materialNameOrg + ( haveVertexColors ? '_vertexColor' : '' ) + ( rawObjectDescription.smoothingGroup === 0 ? '_flat' : '' );
materialOrg = this.materials[ materialNameOrg ];
material = this.materials[ materialName ];
// both original and derived names do not lead to an existing material => need to use a default material
if ( ! 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;
// if names are identical then there is no need for later manipulation
if ( materialNameOrg === materialName ) {
material = materialOrg;
materialName = defaultMaterialName;
}
}
if ( ! Validator.isValid( material ) ) {
var materialCloneInstructions = {
materialNameOrg: materialNameOrg,
materialName: materialName,
materialProperties: {
vertexColors: haveVertexColors ? 2 : 0,
flatShading: rawObjectDescription.smoothingGroup === 0
}
};
var payload = {
cmd: 'materialData',
materials: {
materialCloneInstructions: materialCloneInstructions
}
};
this.callbackBuilder( payload );
// fake entry for async; sync Parser always works on material references (Builder update directly visible here)
if ( this.useAsync ) this.materials[ materialName ] = materialCloneInstructions;
}
if ( createMultiMaterial ) {
// re-use material if already used before. Reduces materials array size and eliminates duplicates
selectedMaterialIndex = materialIndexMapping[ materialName ];
if ( ! 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;
} else {
materialNames.push( materialName );
}
vertexFA.set( rawObjectDescription.vertices, vertexFAOffset );
vertexFAOffset += rawObjectDescription.vertices.length;
if ( indexUA ) {
indexUA.set( rawObjectDescription.indices, indexUAOffset );
indexUAOffset += rawObjectDescription.indices.length;
}
if ( colorFA ) {
colorFA.set( rawObjectDescription.colors, colorFAOffset );
colorFAOffset += rawObjectDescription.colors.length;
}
if ( normalFA ) {
normalFA.set( rawObjectDescription.normals, normalFAOffset );
normalFAOffset += rawObjectDescription.normals.length;
}
if ( uvFA ) {
uvFA.set( rawObjectDescription.uvs, uvFAOffset );
uvFAOffset += rawObjectDescription.uvs.length;
}
if ( this.logger.isDebug() ) {
var materialIndexLine = Validator.isValid( selectedMaterialIndex ) ? '\n\t\tmaterialIndex: ' + selectedMaterialIndex : '';
var 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
);
};
return Parser;
})();
RawMesh = (function () {
function RawMesh( materialPerSmoothingGroup, useIndices, disregardNormals, activeMtlName ) {
this.globalVertexOffset = 1;
this.globalUvOffset = 1;
this.globalNormalOffset = 1;
this.vertices = [];
this.colors = [];
this.normals = [];
this.uvs = [];
// faces are stored according combined index of group, material and smoothingGroup (0 or not)
this.activeMtlName = Validator.verifyInput( activeMtlName, '' );
this.objectName = '';
this.groupName = '';
this.mtllibName = '';
this.smoothingGroup = {
splitMaterials: materialPerSmoothingGroup === true,
normalized: -1,
real: -1
};
this.useIndices = useIndices === true;
this.disregardNormals = disregardNormals === true;
this.mtlCount = 0;
this.smoothingGroupCount = 0;
this.subGroups = [];
this.subGroupInUse = null;
// this default index is required as it is possible to define faces without 'g' or 'usemtl'
this.pushSmoothingGroup( 1 );
this.doubleIndicesCount = 0;
this.faceCount = 0;
}
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;
newRawObject.globalUvOffset = this.globalUvOffset + this.uvs.length / 2;
newRawObject.globalNormalOffset = this.globalNormalOffset + this.normals.length / 3;
return newRawObject;
};
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;
newRawObject.colors = this.colors;
newRawObject.uvs = this.uvs;
newRawObject.normals = this.normals;
newRawObject.globalVertexOffset = this.globalVertexOffset;
newRawObject.globalUvOffset = this.globalUvOffset;
newRawObject.globalNormalOffset = this.globalNormalOffset;
return 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 ) {
if ( this.activeMtlName === mtlName || ! Validator.isValid( mtlName ) ) return;
this.activeMtlName = mtlName;
this.mtlCount++;
this.verifyIndex();
};
RawMesh.prototype.pushSmoothingGroup = function ( smoothingGroup ) {
var smoothingGroupInt = parseInt( smoothingGroup );
if ( isNaN( smoothingGroupInt ) ) {
smoothingGroupInt = smoothingGroup === "off" ? 0 : 1;
}
var smoothCheck = this.smoothingGroup.normalized;
this.smoothingGroup.normalized = this.smoothingGroup.splitMaterials ? smoothingGroupInt : ( smoothingGroupInt === 0 ) ? 0 : 1;
this.smoothingGroup.real = smoothingGroupInt;
if ( smoothCheck !== smoothingGroupInt ) {
this.smoothingGroupCount++;
this.verifyIndex();
}
};
RawMesh.prototype.verifyIndex = function () {
var index = this.activeMtlName + '|' + this.smoothingGroup.normalized;
this.subGroupInUse = this.subGroups[ index ];
if ( ! 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 bufferLength = bufferPointer - 1;
var i, length;
// "f vertex ..."
if ( slashesCount === 0 ) {
for ( i = 2, length = bufferLength - 1; i < length; i ++ ) {
this.buildFace( buffer[ 1 ] );
this.buildFace( buffer[ i ] );
this.buildFace( buffer[ i + 1 ] );
}
// "f vertex/uv ..."
} else if ( bufferLength === slashesCount * 2 ) {
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 ] );
}
// "f vertex/uv/normal ..."
} else if ( bufferLength * 2 === slashesCount * 3 ) {
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 ] );
}
// "f vertex//normal ..."
} else {
for ( i = 3, length = bufferLength - 2; i < length; i += 2 ) {
this.buildFace( buffer[ 1 ], undefined, buffer[ 2 ] );
this.buildFace( buffer[ i ], undefined, buffer[ i + 1 ] );
this.buildFace( buffer[ i + 2 ], undefined, buffer[ i + 3 ] );
}
}
};
RawMesh.prototype.buildFace = function ( faceIndexV, faceIndexU, faceIndexN ) {
var sgiu = this.subGroupInUse;
if ( this.disregardNormals ) faceIndexN = undefined;
var scope = this;
var updateRawObjectDescriptionInUse = function () {
var indexPointerV = ( parseInt( faceIndexV ) - scope.globalVertexOffset ) * 3;
var indexPointerC = scope.colors.length > 0 ? indexPointerV : null;
var vertices = sgiu.vertices;
vertices.push( scope.vertices[ indexPointerV++ ] );
vertices.push( scope.vertices[ indexPointerV++ ] );
vertices.push( scope.vertices[ indexPointerV ] );
if ( indexPointerC !== null ) {
var colors = sgiu.colors;
colors.push( scope.colors[ indexPointerC++ ] );
colors.push( scope.colors[ indexPointerC++ ] );
colors.push( scope.colors[ indexPointerC ] );
}
if ( faceIndexU ) {
var indexPointerU = ( parseInt( faceIndexU ) - scope.globalUvOffset ) * 2;
var uvs = sgiu.uvs;
uvs.push( scope.uvs[ indexPointerU++ ] );
uvs.push( scope.uvs[ indexPointerU ] );
}
if ( faceIndexN ) {
var indexPointerN = ( parseInt( faceIndexN ) - scope.globalNormalOffset ) * 3;
var 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' );
var indicesPointer = sgiu.indexMappings[ mappingName ];
if ( Validator.isValid( indicesPointer ) ) {
this.doubleIndicesCount++;
} else {
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 i = 1;
var length;
var bufferLength = bufferPointer - 1;
if ( bufferLength === slashCount * 2 ) {
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 rawObjectDescriptionsTemp = [];
var rawObjectDescription;
var absoluteVertexCount = 0;
var absoluteIndexMappingsCount = 0;
var absoluteIndexCount = 0;
var absoluteColorCount = 0;
var absoluteNormalCount = 0;
var absoluteUvCount = 0;
var indices;
for ( var name in this.subGroups ) {
rawObjectDescription = this.subGroups[ name ];
if ( rawObjectDescription.vertices.length > 0 ) {
indices = rawObjectDescription.indices;
if ( 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;
}
}
// do not continue if no result
var result = null;
if ( 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
};
}
return result;
};
RawMesh.prototype.createReport = function () {
var report = {
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
};
return report;
};
return RawMesh;
})();
RawMeshSubGroup = (function () {
function RawMeshSubGroup( objectName, groupName, materialName, smoothingGroup ) {
this.objectName = objectName;
this.groupName = groupName;
this.materialName = materialName;
this.smoothingGroup = smoothingGroup;
this._init();
}
RawMeshSubGroup.prototype._init = function () {
this.vertices = [];
this.indexMappingsCount = 0;
this.indexMappings = [];
this.indices = [];
this.colors = [];
this.uvs = [];
this.normals = [];
};
return RawMeshSubGroup;
})();
WorkerRunnerRefImpl = (function () {
function WorkerRunnerRefImpl() {
var scope = this;
var scopedRunner = function( event ) {
scope.processMessage( event.data );
};
self.addEventListener( 'message', scopedRunner, false );
}
WorkerRunnerRefImpl.prototype.applyProperties = function ( parser, params ) {
var property, funcName, values;
for ( property in params ) {
funcName = 'set' + property.substring( 0, 1 ).toLocaleUpperCase() + property.substring( 1 );
values = params[ property ];
if ( typeof parser[ funcName ] === 'function' ) {
parser[ funcName ]( values );
} else if ( parser.hasOwnProperty( property ) ) {
parser[ property ] = values;
}
}
};
WorkerRunnerRefImpl.prototype.processMessage = function ( payload ) {
var logger = new ConsoleLogger();
if ( Validator.isValid( payload.logger ) ) {
logger.setEnabled( payload.logger.enabled );
logger.setDebug( payload.logger.debug );
}
if ( payload.cmd === 'run' ) {
var callbacks = {
callbackBuilder: function ( payload ) {
self.postMessage( payload );
},
callbackProgress: function ( text ) {
logger.logDebug( 'WorkerRunner: progress: ' + text );
}
};
// Parser is expected to be named as such
var parser = new Parser( logger );
this.applyProperties( parser, payload.params );
this.applyProperties( parser, payload.materials );
this.applyProperties( parser, callbacks );
parser.workerScope = self;
parser.parse( payload.data.input, payload.data.options );
logger.logInfo( 'WorkerRunner: Run complete!' );
callbacks.callbackBuilder( {
cmd: 'complete',
msg: 'WorkerRunner completed run.'
} );
} else {
logger.logError( 'WorkerRunner: Received unknown command: ' + payload.cmd );
}
};
return WorkerRunnerRefImpl;
})();
new WorkerRunnerRefImpl();
I'm going to be completely honest, I would never have expected this to work. After all there is some metaprogramming going on in there!
But upon closer inspection, the logic appears to all be proper, some of the variables got renamed to minified variable names, but the right ones seem to be called.
The ONLY strange stuff is that many of the toplevel names are mangled as though something went wrong with concurrent serialization somehow. `RawMRawMeshSubGroupshSubGroup` instead of `RawMeshSubGroup`, note the `e` got replaced with an entire instance of itself. Holy shit. I think that's the key to this. Something is causing the name to be injected into itself in place of its first `e` letter.
OK so anyway. Somehow this all seems to ALMOST work under uglify so maybe with some slight robustification i can build a minified three.js that uses objloader2.
Meanwhile, the good news is that i'm quite satisfied to be simply deploying unminified three.js to production.
</details>