提交 90ee258d 编写于 作者: M Mugen87

JSM: Added TS files for OBJLoader2 and fix style issues.

上级 5b4b5a2d
import {
LoadingManager,
Group
} from '../../../src/Three';
import { MaterialHandler } from './obj2/shared/MaterialHandler';
import { MeshReceiver} from './obj2/shared/MeshReceiver';
export class OBJLoader2 {
constructor(manager?: LoadingManager);
manager: LoadingManager;
logging: {
enabled: boolean;
debug: boolean;
};
modelName: string;
instanceNo: number;
path: string;
resourcePath: string;
useIndices: boolean;
disregardNormals: boolean;
materialPerSmoothingGroup: boolean;
useOAsMesh: boolean;
baseObject3d: Group;
callbacks: {
onParseProgress: Function;
genericErrorHandler: Function;
};
materialHandler: MaterialHandler;
meshReceiver: MeshReceiver;
addMaterials(materials: object): void;
load(url: string, onLoad: (group: Group) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void, onMeshAlter?: (meshData: object) => void): void;
parse(content: ArrayBuffer | string): void;
setLogging(enabled: boolean, debug: boolean): this;
setModelName(modelName: string): this;
setPath(path: string): this;
setResourcePath(path: string): this;
setBaseObject3d(baseObject3d: Object3D): this;
setUseIndices(useIndices: boolean): this;
setDisregardNormals(disregardNormals: boolean): this;
setMaterialPerSmoothingGroup(materialPerSmoothingGroup: boolean): this;
setUseOAsMesh(useOAsMesh: boolean): this;
setGenericErrorHandler(genericErrorHandler: Function): void;
}
......@@ -20,6 +20,7 @@ import { MaterialHandler } from "./obj2/shared/MaterialHandler.js";
* @param {DefaultLoadingManager} [manager] The loadingManager for the loader to use. Default is {@link DefaultLoadingManager}
*/
const OBJLoader2 = function ( manager ) {
this.manager = ( manager !== undefined && manager !== null ) ? manager : DefaultLoadingManager;
this.logging = {
enabled: true,
......@@ -43,6 +44,7 @@ const OBJLoader2 = function ( manager ) {
this.materialHandler = new MaterialHandler();
this.meshReceiver = new MeshReceiver( this.materialHandler );
};
OBJLoader2.OBJLOADER2_VERSION = '3.0.0-beta2';
console.info( 'Using OBJLoader2 version: ' + OBJLoader2.OBJLOADER2_VERSION );
......@@ -58,9 +60,11 @@ OBJLoader2.prototype = {
* @param {boolean} debug True or false.
*/
setLogging: function ( enabled, debug ) {
this.logging.enabled = enabled === true;
this.logging.debug = debug === true;
return this;
},
/**
......@@ -69,8 +73,10 @@ OBJLoader2.prototype = {
* @param {string} modelName
*/
setModelName: function ( modelName ) {
this.modelName = modelName ? modelName : this.modelName;
return this;
},
/**
......@@ -79,8 +85,10 @@ OBJLoader2.prototype = {
* @param {string} path URL
*/
setPath: function ( path ) {
this.path = path ? path : this.path;
return this;
},
......@@ -89,7 +97,9 @@ OBJLoader2.prototype = {
* @param {string} resourcePath
*/
setResourcePath: function ( resourcePath ) {
this.resourcePath = resourcePath ? resourcePath : this.resourcePath;
},
/**
......@@ -98,8 +108,10 @@ OBJLoader2.prototype = {
* @param {Object3D} baseObject3d Object already attached to scenegraph where new meshes will be attached to
*/
setBaseObject3d: function ( baseObject3d ) {
this.baseObject3d = ( baseObject3d === undefined || baseObject3d === null ) ? this.baseObject3d : baseObject3d;
return this;
},
/**
......@@ -108,7 +120,9 @@ OBJLoader2.prototype = {
* @param materials Object with named {@link Material}
*/
addMaterials: function ( materials ) {
this.materialHandler.addMaterials( materials );
},
/**
......@@ -117,8 +131,10 @@ OBJLoader2.prototype = {
* @param {boolean} useIndices=false
*/
setUseIndices: function ( useIndices ) {
this.useIndices = useIndices === true;
return this;
},
/**
......@@ -127,8 +143,10 @@ OBJLoader2.prototype = {
* @param {boolean} disregardNormals=false
*/
setDisregardNormals: function ( disregardNormals ) {
this.disregardNormals = disregardNormals === true;
return this;
},
/**
......@@ -137,8 +155,10 @@ OBJLoader2.prototype = {
* @param {boolean} materialPerSmoothingGroup=false
*/
setMaterialPerSmoothingGroup: function ( materialPerSmoothingGroup ) {
this.materialPerSmoothingGroup = materialPerSmoothingGroup === true;
return this;
},
/**
......@@ -147,8 +167,10 @@ OBJLoader2.prototype = {
* @param {boolean} useOAsMesh=false
*/
setUseOAsMesh: function ( useOAsMesh ) {
this.useOAsMesh = useOAsMesh === true;
return this;
},
/**
......@@ -156,11 +178,13 @@ OBJLoader2.prototype = {
* @param {Function} genericErrorHandler
*/
setGenericErrorHandler: function ( genericErrorHandler ) {
if ( genericErrorHandler !== undefined && genericErrorHandler !== null ) {
this.callbacks.genericErrorHandler = genericErrorHandler;
}
},
/**
......@@ -173,6 +197,7 @@ OBJLoader2.prototype = {
* @private
*/
_setCallbacks: function ( onParseProgress, onMeshAlter, onLoadMaterials ) {
if ( onParseProgress !== undefined && onParseProgress !== null ) {
this.callbacks.onParseProgress = onParseProgress;
......@@ -180,6 +205,7 @@ OBJLoader2.prototype = {
}
this.meshReceiver._setCallbacks( onParseProgress, onMeshAlter );
this.materialHandler._setCallbacks( onLoadMaterials );
},
/**
......@@ -191,6 +217,7 @@ OBJLoader2.prototype = {
* @param {number} numericalValue Numerical value describing the progress
*/
_onProgress: function ( type, text, numericalValue ) {
let message = text ? text : '';
let event = {
detail: {
......@@ -211,6 +238,7 @@ OBJLoader2.prototype = {
console.log( message );
}
},
/**
......@@ -220,6 +248,7 @@ OBJLoader2.prototype = {
* @param {String} errorMessage The event containing the error
*/
_onError: function ( errorMessage ) {
if ( this.callbacks.genericErrorHandler ) {
this.callbacks.genericErrorHandler( errorMessage );
......@@ -243,6 +272,7 @@ OBJLoader2.prototype = {
* @param {function} [onMeshAlter] Called after worker successfully delivered a single mesh
*/
load: function ( url, onLoad, onFileLoadProgress, onError, onMeshAlter ) {
let scope = this;
if ( onError === null || onError === undefined ) {
......@@ -279,27 +309,32 @@ OBJLoader2.prototype = {
let numericalValueRef = 0;
let numericalValue = 0;
onFileLoadProgress = function ( event ) {
if ( ! event.lengthComputable ) return;
numericalValue = event.loaded / event.total;
if ( numericalValue > numericalValueRef ) {
numericalValueRef = numericalValue;
let output = 'Download of "' + url + '": ' + (numericalValue * 100).toFixed( 2 ) + '%';
let output = 'Download of "' + url + '": ' + ( numericalValue * 100 ).toFixed( 2 ) + '%';
scope._onProgress( 'progressLoad', output, numericalValue );
}
};
}
this._setCallbacks( null, onMeshAlter, null );
let fileLoaderOnLoad = function ( content ) {
onLoad( scope.parse( content ) );
};
let fileLoader = new FileLoader( this.manager );
fileLoader.setPath( this.path || this.resourcePath );
fileLoader.setResponseType( 'arraybuffer' );
fileLoader.load( filename, fileLoaderOnLoad, onFileLoadProgress, onError );
},
/**
......@@ -308,6 +343,7 @@ OBJLoader2.prototype = {
* @param {arraybuffer|string} content OBJ data as Uint8Array or String
*/
parse: function ( content ) {
// fast-fail in case of illegal data
if ( content === null || content === undefined ) {
......@@ -330,13 +366,19 @@ OBJLoader2.prototype = {
let scope = this;
let scopedOnAssetAvailable = function ( payload ) {
scope._onAssetAvailable( payload );
};
let onProgressScoped = function ( text, numericalValue ) {
scope._onProgress( 'progressParse', text, numericalValue );
};
let onErrorScoped = function ( message ) {
scope._onError( message );
};
parser.setCallbackOnAssetAvailable( scopedOnAssetAvailable );
parser.setCallbackOnProgress( onProgressScoped );
......@@ -346,7 +388,7 @@ OBJLoader2.prototype = {
if ( this.logging.enabled ) console.info( 'Parsing arrayBuffer...' );
parser.parse( content );
} else if ( typeof( content ) === 'string' || content instanceof String ) {
} else if ( typeof ( content ) === 'string' || content instanceof String ) {
if ( this.logging.enabled ) console.info( 'Parsing text...' );
parser.parseText( content );
......@@ -362,6 +404,7 @@ OBJLoader2.prototype = {
}
return this.baseObject3d;
},
_onAssetAvailable: function ( payload ) {
......@@ -372,7 +415,9 @@ OBJLoader2.prototype = {
let meshes = this.meshReceiver.buildMeshes( payload );
for ( let mesh of meshes ) {
this.baseObject3d.add( mesh );
}
} else if ( payload.type === 'material' ) {
......@@ -380,6 +425,7 @@ OBJLoader2.prototype = {
this.materialHandler.addPayloadMaterials( payload );
}
}
};
......
import {
LoadingManager
} from '../../../src/Three';
import { OBJLoader2 } from './OBJLoader2.js';
export class OBJLoader2Parallel extends OBJLoader2 {
constructor(manager?: LoadingManager);
preferJsmWorker: boolean;
executeParallel: boolean;
workerExecutionSupport: object;
setPreferJsmWorker(preferJsmWorker: boolean): this;
setCallbackOnParseComplete(onParseComplete: Function): this;
setExecuteParallel(executeParallel: boolean): this;
getWorkerExecutionSupport(): object;
buildWorkerCode(): object;
}
......@@ -27,12 +27,14 @@ import {
* @constructor
*/
const OBJLoader2Parallel = function ( manager ) {
OBJLoader2.call( this, manager );
this.preferJsmWorker = false;
this.callbacks.onParseComplete = null;
this.executeParallel = true;
this.workerExecutionSupport = new WorkerExecutionSupport();
};
OBJLoader2Parallel.prototype = Object.create( OBJLoader2.prototype );
OBJLoader2Parallel.prototype.constructor = OBJLoader2Parallel;
......@@ -42,8 +44,10 @@ console.info( 'Using OBJLoader2Parallel version: ' + OBJLoader2.OBJLOADER2_PARAL
OBJLoader2Parallel.prototype.setPreferJsmWorker = function ( preferJsmWorker ) {
this.preferJsmWorker = preferJsmWorker === true;
return this;
};
/**
......@@ -53,10 +57,14 @@ OBJLoader2Parallel.prototype.setPreferJsmWorker = function ( preferJsmWorker ) {
* @return {OBJLoader2Parallel}
*/
OBJLoader2Parallel.prototype.setCallbackOnParseComplete = function ( onParseComplete ) {
if ( onParseComplete !== undefined && onParseComplete !== null ) {
this.callbacks.onParseComplete = onParseComplete;
}
return this;
};
/**
......@@ -66,8 +74,10 @@ OBJLoader2Parallel.prototype.setCallbackOnParseComplete = function ( onParseComp
* @return {OBJLoader2Parallel}
*/
OBJLoader2Parallel.prototype.setExecuteParallel = function ( executeParallel ) {
this.executeParallel = executeParallel === true;
return this;
};
/**
......@@ -76,7 +86,9 @@ OBJLoader2Parallel.prototype.setExecuteParallel = function ( executeParallel ) {
* @return {WorkerExecutionSupport|WorkerExecutionSupport}
*/
OBJLoader2Parallel.prototype.getWorkerExecutionSupport = function () {
return this.workerExecutionSupport;
};
/**
......@@ -85,6 +97,7 @@ OBJLoader2Parallel.prototype.getWorkerExecutionSupport = function () {
* @return {CodeBuilderInstructions}
*/
OBJLoader2Parallel.prototype.buildWorkerCode = function () {
let codeBuilderInstructions = new CodeBuilderInstructions( true, true, this.preferJsmWorker );
if ( codeBuilderInstructions.isSupportsJsmWorker() ) {
......@@ -104,19 +117,23 @@ OBJLoader2Parallel.prototype.buildWorkerCode = function () {
codeBuilderInstructions.addCodeFragment( codeWorkerRunner );
// allows to include full libraries as importScripts
// codeBuilderInstructions.addLibraryImport( '../../node_modules/three/build/three.js' );
// codeBuilderInstructions.addLibraryImport( '../../node_modules/three/build/three.js' );
codeBuilderInstructions.addStartCode( 'new WorkerRunner( new DefaultWorkerPayloadHandler( new OBJLoader2Parser() ) );' );
}
return codeBuilderInstructions;
};
/**
* @private
*/
OBJLoader2Parallel.prototype._configure = function () {
if ( this.callbacks.onParseComplete === null ) {
throw "No callbackOnLoad was provided! Aborting!";
}
// check if worker is already available and if so, then fast-fail
if ( this.workerExecutionSupport.isWorkerLoaded( this.preferJsmWorker ) ) return;
......@@ -125,10 +142,13 @@ OBJLoader2Parallel.prototype._configure = function () {
let scope = this;
let scopedOnAssetAvailable = function ( payload ) {
scope._onAssetAvailable( payload );
};
this.workerExecutionSupport.updateCallbacks( scopedOnAssetAvailable, this.callbacks.onParseComplete );
};
/**
......@@ -141,10 +161,12 @@ OBJLoader2Parallel.prototype._configure = function () {
* @param {function} [onError] A function to be called if an error occurs during loading. The function receives the error as an argument.
* @param {function} [onMeshAlter] Called after worker successfully delivered a single mesh
*/
OBJLoader2Parallel.prototype.load = function( content, onLoad, onFileLoadProgress, onError, onMeshAlter ) {
OBJLoader2Parallel.prototype.load = function ( content, onLoad, onFileLoadProgress, onError, onMeshAlter ) {
this.setCallbackOnParseComplete( onLoad );
OBJLoader2.prototype.load.call( this, content, function () {}, onFileLoadProgress, onError, onMeshAlter );
};
/**
......@@ -152,7 +174,8 @@ OBJLoader2Parallel.prototype.load = function( content, onLoad, onFileLoadProgres
*
* @param {arraybuffer} content OBJ data as Uint8Array or String
*/
OBJLoader2Parallel.prototype.parse = function( content ) {
OBJLoader2Parallel.prototype.parse = function ( content ) {
if ( this.executeParallel ) {
this._configure();
......@@ -183,6 +206,7 @@ OBJLoader2Parallel.prototype.parse = function( content ) {
this.callbacks.onParseComplete( OBJLoader2.prototype.parse.call( this, content ) );
}
};
export { OBJLoader2Parallel }
export { OBJLoader2Parallel };
export namespace MtlObjBridge {
export function link(processResult: object, assetLoader: object): void;
export function addMaterialsFromMtlLoader(materialCreator: object): void;
}
......@@ -13,12 +13,14 @@ const MtlObjBridge = {
* @param processResult
* @param assetLoader
*/
link: function( processResult, assetLoader ) {
link: function ( processResult, assetLoader ) {
if ( typeof assetLoader.addMaterials === 'function' ) {
assetLoader.addMaterials( this.addMaterialsFromMtlLoader( processResult ) );
}
},
/**
......@@ -27,6 +29,7 @@ const MtlObjBridge = {
* @param Instance of {@link MTLLoader.MaterialCreator}
*/
addMaterialsFromMtlLoader: function ( materialCreator ) {
let newMaterials = {};
if ( materialCreator instanceof MTLLoader.MaterialCreator ) {
......@@ -35,7 +38,8 @@ const MtlObjBridge = {
}
return newMaterials;
}
};
export { MtlObjBridge }
export { MtlObjBridge };
import {
Material
} from '../../../../../src/Three';
export class MaterialHandler {
constructor();
logging: {
enabled: boolean;
debug: boolean;
};
callbacks: {
onLoadMaterials: Function;
};
materials: object;
addMaterials(materials: object, newMaterials: object): object;
addPayloadMaterials(materialPayload: object): object;
setLogging(enabled: boolean, debug: boolean): void;
getMaterials(): object;
getMaterial(materialName: string): Material;
getMaterialsJSON(): object;
}
......@@ -13,6 +13,7 @@ import {
const MaterialHandler = function () {
this.logging = {
enabled: true,
debug: false
......@@ -23,6 +24,7 @@ const MaterialHandler = function () {
};
this.materials = {};
this._createDefaultMaterials();
};
MaterialHandler.prototype = {
......@@ -36,19 +38,24 @@ MaterialHandler.prototype = {
* @param {boolean} debug True or false.
*/
setLogging: function ( enabled, debug ) {
this.logging.enabled = enabled === true;
this.logging.debug = debug === true;
},
_setCallbacks: function ( onLoadMaterials ) {
if ( onLoadMaterials !== undefined && onLoadMaterials !== null ) {
this.callbacks.onLoadMaterials = onLoadMaterials;
}
},
_createDefaultMaterials: function () {
let defaultMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } );
defaultMaterial.name = 'defaultMaterial';
......@@ -69,6 +76,7 @@ MaterialHandler.prototype = {
runtimeMaterials[ defaultPointMaterial.name ] = defaultPointMaterial;
this.addMaterials( runtimeMaterials );
},
/**
......@@ -78,6 +86,7 @@ MaterialHandler.prototype = {
* @returns {Object} Map of {@link Material}
*/
addPayloadMaterials: function ( materialPayload ) {
let material, materialName;
let materialCloneInstructions = materialPayload.materials.materialCloneInstructions;
let newMaterials = {};
......@@ -85,9 +94,10 @@ MaterialHandler.prototype = {
if ( materialCloneInstructions !== undefined && materialCloneInstructions !== null ) {
let materialNameOrg = materialCloneInstructions.materialNameOrg;
materialNameOrg = (materialNameOrg !== undefined && materialNameOrg !== null) ? materialNameOrg : "";
materialNameOrg = ( materialNameOrg !== undefined && materialNameOrg !== null ) ? materialNameOrg : "";
let materialOrg = this.materials[ materialNameOrg ];
if ( materialOrg ) {
material = materialOrg.clone();
materialName = materialCloneInstructions.materialName;
......@@ -111,6 +121,7 @@ MaterialHandler.prototype = {
console.info( 'Requested material "' + materialNameOrg + '" is not available!' );
}
}
let materials = materialPayload.materials.serializedMaterials;
......@@ -137,6 +148,7 @@ MaterialHandler.prototype = {
newMaterials = this.addMaterials( materials, newMaterials );
return newMaterials;
},
/**
......@@ -146,6 +158,7 @@ MaterialHandler.prototype = {
* @param newMaterials [Object] with named {@link Material}
*/
addMaterials: function ( materials, newMaterials ) {
if ( newMaterials === undefined || newMaterials === null ) {
newMaterials = {};
......@@ -165,6 +178,7 @@ MaterialHandler.prototype = {
}
return newMaterials;
},
/**
......@@ -173,7 +187,9 @@ MaterialHandler.prototype = {
* @returns {Object} Map of {@link Material}
*/
getMaterials: function () {
return this.materials;
},
/**
......@@ -182,7 +198,9 @@ MaterialHandler.prototype = {
* @returns {Material}
*/
getMaterial: function ( materialName ) {
return this.materials[ materialName ];
},
/**
......@@ -191,17 +209,20 @@ MaterialHandler.prototype = {
* @returns {Object} Map of Materials in JSON representation
*/
getMaterialsJSON: function () {
let materialsJSON = {};
let material;
for ( let materialName in this.materials ) {
material = this.materials[ materialName ];
materialsJSON[ materialName ] = material.toJSON();
}
return materialsJSON;
}
};
export { MaterialHandler }
export { MaterialHandler };
import {
Mesh
} from '../../../../../src/Three';
import { MaterialHandler } from './MaterialHandler'
export class MeshReceiver {
constructor(materialHandler: MaterialHandler);
logging: {
enabled: boolean;
debug: boolean;
};
callbacks: {
onParseProgress: Function;
onMeshAlter: Function;
};
materialHandler: MaterialHandler;
buildMeshes(meshPayload: object): Mesh[];
setLogging(enabled: boolean, debug: boolean): void;
}
......@@ -17,7 +17,8 @@ import {
* @param {MaterialHandler} materialHandler
* @constructor
*/
const MeshReceiver = function( materialHandler ) {
const MeshReceiver = function ( materialHandler ) {
this.logging = {
enabled: true,
debug: false
......@@ -28,6 +29,7 @@ const MeshReceiver = function( materialHandler ) {
onMeshAlter: null
};
this.materialHandler = materialHandler;
};
MeshReceiver.prototype = {
......@@ -41,8 +43,10 @@ MeshReceiver.prototype = {
* @param {boolean} debug True or false.
*/
setLogging: function ( enabled, debug ) {
this.logging.enabled = enabled === true;
this.logging.debug = debug === true;
},
/**
......@@ -52,6 +56,7 @@ MeshReceiver.prototype = {
* @private
*/
_setCallbacks: function ( onParseProgress, onMeshAlter ) {
if ( onParseProgress !== undefined && onParseProgress !== null ) {
this.callbacks.onParseProgress = onParseProgress;
......@@ -62,6 +67,7 @@ MeshReceiver.prototype = {
this.callbacks.onMeshAlter = onMeshAlter;
}
},
/**
......@@ -71,6 +77,7 @@ MeshReceiver.prototype = {
* @returns {Mesh[]} mesh Array of {@link Mesh}
*/
buildMeshes: function ( meshPayload ) {
let meshName = meshPayload.params.meshName;
let bufferGeometry = new BufferGeometry();
......@@ -80,7 +87,7 @@ MeshReceiver.prototype = {
bufferGeometry.setIndex( new BufferAttribute( new Uint32Array( meshPayload.buffers.indices ), 1 ) );
}
let haveVertexColors = meshPayload.buffers.colors !== null;
let haveVertexColors = meshPayload.buffers.colors !== null;
if ( haveVertexColors ) {
bufferGeometry.addAttribute( 'color', new BufferAttribute( new Float32Array( meshPayload.buffers.colors ), 3 ) );
......@@ -95,7 +102,7 @@ MeshReceiver.prototype = {
bufferGeometry.computeVertexNormals();
}
if ( meshPayload.buffers.uvs !== null ) {
if ( meshPayload.buffers.uvs !== null ) {
bufferGeometry.addAttribute( 'uv', new BufferAttribute( new Float32Array( meshPayload.buffers.uvs ), 2 ) );
......@@ -155,6 +162,7 @@ MeshReceiver.prototype = {
}
}
);
}
// here LoadedMeshUserOverride is required to be provided by the callback used to alter the results
......@@ -208,12 +216,12 @@ MeshReceiver.prototype = {
}
progressMessage += ': Adding mesh(es) (' + meshNames.length + ': ' + meshNames + ') from input mesh: ' + meshName;
progressMessage += ' (' + ( meshPayload.progress.numericalValue * 100).toFixed( 2 ) + '%)';
progressMessage += ' (' + ( meshPayload.progress.numericalValue * 100 ).toFixed( 2 ) + '%)';
} else {
progressMessage += ': Not adding mesh: ' + meshName;
progressMessage += ' (' + ( meshPayload.progress.numericalValue * 100).toFixed( 2 ) + '%)';
progressMessage += ' (' + ( meshPayload.progress.numericalValue * 100 ).toFixed( 2 ) + '%)';
}
let callbackOnParseProgress = this.callbacks.onParseProgress;
......@@ -224,6 +232,7 @@ MeshReceiver.prototype = {
}
return meshes;
}
};
......@@ -235,10 +244,12 @@ MeshReceiver.prototype = {
* @param {boolean} disregardMesh=false Tell implementation to completely disregard this mesh
* @param {boolean} disregardMesh=false Tell implementation that mesh(es) have been altered or added
*/
const LoadedMeshUserOverride = function( disregardMesh, alteredMesh ) {
const LoadedMeshUserOverride = function ( disregardMesh, alteredMesh ) {
this.disregardMesh = disregardMesh === true;
this.alteredMesh = alteredMesh === true;
this.meshes = [];
};
......@@ -252,8 +263,10 @@ LoadedMeshUserOverride.prototype = {
* @param {Mesh} mesh
*/
addMesh: function ( mesh ) {
this.meshes.push( mesh );
this.alteredMesh = true;
},
/**
......@@ -262,7 +275,9 @@ LoadedMeshUserOverride.prototype = {
* @returns {boolean}
*/
isDisregardMesh: function () {
return this.disregardMesh;
},
/**
......@@ -271,7 +286,9 @@ LoadedMeshUserOverride.prototype = {
* @returns {boolean}
*/
providesAlteredMeshes: function () {
return this.alteredMesh;
}
};
......
export namespace CodeSerializer {
export function serializeObject(fullName: string, object: object): string;
export function serializeClass(fullName: string, object: object, constructorName?: string, basePrototypeName?: string, ignoreFunctions?: string[], includeFunctions?: string[], overrideFunctions?: string[]): string;
}
......@@ -12,12 +12,13 @@ const CodeSerializer = {
* @returns {string}
*/
serializeObject: function ( fullName, object ) {
let objectString = fullName + ' = {\n\n';
let part;
for ( let name in object ) {
part = object[ name ];
if ( typeof( part ) === 'string' || part instanceof String ) {
if ( typeof ( part ) === 'string' || part instanceof String ) {
part = part.replace( '\n', '\\n' );
part = part.replace( '\r', '\\r' );
......@@ -42,6 +43,7 @@ const CodeSerializer = {
objectString += '}\n\n';
return objectString;
},
/**
......@@ -53,6 +55,7 @@ const CodeSerializer = {
* @returns {string}
*/
serializeClass: function ( fullName, object, constructorName, basePrototypeName, ignoreFunctions, includeFunctions, overrideFunctions ) {
let valueString, objectPart, constructorString, i, funcOverride;
let prototypeFunctions = [];
let objectProperties = [];
......@@ -90,6 +93,7 @@ const CodeSerializer = {
prototypeFunctions.push( '\t' + name + ': ' + valueString + ',\n\n' );
}
}
}
......@@ -119,7 +123,7 @@ const CodeSerializer = {
} else {
if ( typeof( objectPart ) === 'string' || objectPart instanceof String) {
if ( typeof ( objectPart ) === 'string' || objectPart instanceof String ) {
valueString = '\"' + objectPart.toString() + '\"';
......@@ -172,7 +176,8 @@ const CodeSerializer = {
objectString += '\n\n';
return objectString;
},
};
export { CodeSerializer }
export { CodeSerializer };
export namespace ObjectManipulator {
export function applyProperties(objToAlter: object, params: object, forceCreation: boolean): void;
}
......@@ -12,11 +12,13 @@ const ObjectManipulator = {
* @param {Object} params The parameter object
*/
applyProperties: function ( objToAlter, params, forceCreation ) {
// fast-fail
if ( objToAlter === undefined || objToAlter === null || params === undefined || params === null ) return;
var property, funcName, values;
for ( property in params ) {
funcName = 'set' + property.substring( 0, 1 ).toLocaleUpperCase() + property.substring( 1 );
values = params[ property ];
......@@ -29,8 +31,10 @@ const ObjectManipulator = {
objToAlter[ property ] = values;
}
}
}
};
export { ObjectManipulator }
export { ObjectManipulator };
......@@ -11,6 +11,7 @@
* @constructor
*/
const CodeBuilderInstructions = function ( supportsStandardWorker, supportsJsmWorker, preferJsmWorker ) {
this.supportsStandardWorker = supportsStandardWorker;
this.supportsJsmWorker = supportsJsmWorker;
this.preferJsmWorker = preferJsmWorker;
......@@ -20,6 +21,7 @@ const CodeBuilderInstructions = function ( supportsStandardWorker, supportsJsmWo
this.jsmWorkerFile = null;
this.defaultGeometryType = 0;
};
CodeBuilderInstructions.prototype = {
......@@ -27,15 +29,21 @@ CodeBuilderInstructions.prototype = {
constructor: CodeBuilderInstructions,
isSupportsStandardWorker: function () {
return this.supportsStandardWorker;
},
isSupportsJsmWorker: function () {
return this.supportsJsmWorker;
},
isPreferJsmWorker: function () {
return this.preferJsmWorker;
},
/**
......@@ -44,9 +52,13 @@ CodeBuilderInstructions.prototype = {
* @param {String} jsmWorkerFile
*/
setJsmWorkerFile: function ( jsmWorkerFile ) {
if ( jsmWorkerFile !== undefined && jsmWorkerFile !== null ) {
this.jsmWorkerFile = jsmWorkerFile;
}
},
/**
......@@ -54,7 +66,9 @@ CodeBuilderInstructions.prototype = {
* @param {String} startCode
*/
addStartCode: function ( startCode ) {
this.startCode = startCode;
},
/**
......@@ -62,7 +76,9 @@ CodeBuilderInstructions.prototype = {
* @param {String} code
*/
addCodeFragment: function ( code ) {
this.codeFragments.push( code );
},
/**
......@@ -70,21 +86,29 @@ CodeBuilderInstructions.prototype = {
* @param {String} libraryPath
*/
addLibraryImport: function ( libraryPath ) {
let libraryUrl = new URL( libraryPath, window.location.href ).href;
let code = 'importScripts( "' + libraryUrl + '" );';
this.importStatements.push( code );
},
getImportStatements: function () {
return this.importStatements;
},
getCodeFragments: function () {
return this.codeFragments;
},
getStartCode: function () {
return this.startCode;
}
};
......@@ -94,12 +118,14 @@ CodeBuilderInstructions.prototype = {
* @class
*/
const WorkerExecutionSupport = function () {
// check worker support first
if ( window.Worker === undefined ) throw "This browser does not support web workers!";
if ( window.Blob === undefined ) throw "This browser does not support Blob!";
if ( typeof window.URL.createObjectURL !== 'function' ) throw "This browser does not support Object creation from URL!";
this._reset();
};
WorkerExecutionSupport.WORKER_SUPPORT_VERSION = '3.0.0-beta2';
console.info( 'Using WorkerSupport version: ' + WorkerExecutionSupport.WORKER_SUPPORT_VERSION );
......@@ -110,14 +136,17 @@ WorkerExecutionSupport.prototype = {
constructor: WorkerExecutionSupport,
_reset: function () {
this.logging = {
enabled: true,
debug: false
};
let scope = this;
let scopeTerminate = function ( ) {
let scopeTerminate = function ( ) {
scope._terminate();
};
this.worker = {
native: null,
......@@ -138,6 +167,7 @@ WorkerExecutionSupport.prototype = {
terminate: scopeTerminate
}
};
},
/**
......@@ -147,10 +177,12 @@ WorkerExecutionSupport.prototype = {
* @param {boolean} debug True or false.
*/
setLogging: function ( enabled, debug ) {
this.logging.enabled = enabled === true;
this.logging.debug = debug === true;
this.worker.logging = enabled === true;
return this;
},
/**
......@@ -159,8 +191,10 @@ WorkerExecutionSupport.prototype = {
* @param {boolean} forceWorkerDataCopy True or false.
*/
setForceWorkerDataCopy: function ( forceWorkerDataCopy ) {
this.worker.forceWorkerDataCopy = forceWorkerDataCopy === true;
return this;
},
/**
......@@ -169,6 +203,7 @@ WorkerExecutionSupport.prototype = {
* @param {boolean} terminateWorkerOnLoad True or false.
*/
setTerminateWorkerOnLoad: function ( terminateWorkerOnLoad ) {
this.worker.terminateWorkerOnLoad = terminateWorkerOnLoad === true;
if ( this.worker.terminateWorkerOnLoad && this.isWorkerLoaded( this.worker.jsmWorker ) &&
this.worker.queuedMessage === null && this.worker.started ) {
......@@ -182,6 +217,7 @@ WorkerExecutionSupport.prototype = {
}
return this;
},
/**
......@@ -191,6 +227,7 @@ WorkerExecutionSupport.prototype = {
* @param {Function} [onLoad] The function that is called when parsing is complete.
*/
updateCallbacks: function ( onAssetAvailable, onLoad ) {
if ( onAssetAvailable !== undefined && onAssetAvailable !== null ) {
this.worker.callbacks.onAssetAvailable = onAssetAvailable;
......@@ -202,14 +239,17 @@ WorkerExecutionSupport.prototype = {
}
this._verifyCallbacks();
},
_verifyCallbacks: function () {
if ( this.worker.callbacks.onAssetAvailable === undefined || this.worker.callbacks.onAssetAvailable === null ) {
throw 'Unable to run as no "onAssetAvailable" callback is set.';
}
},
/**
......@@ -219,10 +259,13 @@ WorkerExecutionSupport.prototype = {
* @param {CodeBuilderInstructions} codeBuilderInstructions
*/
buildWorker: function ( codeBuilderInstructions ) {
let jsmSuccess = false;
if ( codeBuilderInstructions.isSupportsJsmWorker() && codeBuilderInstructions.isPreferJsmWorker() ) {
jsmSuccess = this._buildWorkerJsm( codeBuilderInstructions );
}
if ( ! jsmSuccess && codeBuilderInstructions.isSupportsStandardWorker() ) {
......@@ -230,6 +273,7 @@ WorkerExecutionSupport.prototype = {
this._buildWorkerStandard( codeBuilderInstructions );
}
},
/**
......@@ -239,6 +283,7 @@ WorkerExecutionSupport.prototype = {
* @private
*/
_buildWorkerJsm: function ( codeBuilderInstructions ) {
let jsmSuccess = true;
let timeLabel = 'buildWorkerJsm';
let workerAvailable = this._buildWorkerCheckPreconditions( true, timeLabel );
......@@ -250,8 +295,7 @@ WorkerExecutionSupport.prototype = {
let worker = new Worker( workerFileUrl, { type: "module" } );
this._configureWorkerCommunication( worker, true, codeBuilderInstructions.defaultGeometryType, timeLabel );
}
catch ( e ) {
} catch ( e ) {
jsmSuccess = false;
// Chrome throws this exception, but Firefox currently does not complain, but can't execute the worker afterwards
......@@ -260,11 +304,13 @@ WorkerExecutionSupport.prototype = {
console.error( "Modules are not supported in workers." );
}
}
}
return jsmSuccess;
},
/**
......@@ -279,17 +325,22 @@ WorkerExecutionSupport.prototype = {
* @private
*/
_buildWorkerStandard: function ( codeBuilderInstructions ) {
let timeLabel = 'buildWorkerStandard';
let workerAvailable = this._buildWorkerCheckPreconditions( false, timeLabel );
if ( ! workerAvailable ) {
let concatenateCode = '';
codeBuilderInstructions.getImportStatements().forEach( function ( element ) {
concatenateCode += element + '\n';
} );
concatenateCode += '\n';
codeBuilderInstructions.getCodeFragments().forEach( function ( element ) {
concatenateCode += element + '\n';
} );
concatenateCode += '\n';
concatenateCode += codeBuilderInstructions.getStartCode();
......@@ -300,15 +351,18 @@ WorkerExecutionSupport.prototype = {
this._configureWorkerCommunication( worker, false, codeBuilderInstructions.defaultGeometryType, timeLabel );
}
},
_buildWorkerCheckPreconditions: function ( requireJsmWorker, timeLabel ) {
let workerAvailable = false;
if ( this.isWorkerLoaded( requireJsmWorker ) ) {
workerAvailable = true;
} else {
if ( this.logging.enabled ) {
console.info( 'WorkerExecutionSupport: Building ' + ( requireJsmWorker ? 'jsm' : 'standard' ) + ' worker code...' );
......@@ -318,20 +372,25 @@ WorkerExecutionSupport.prototype = {
}
return workerAvailable;
},
_configureWorkerCommunication: function ( worker, haveJsmWorker, defaultGeometryType, timeLabel ) {
this.worker.native = worker;
this.worker.jsmWorker = haveJsmWorker;
let scope = this;
let scopedReceiveWorkerMessage = function ( event ) {
scope._receiveWorkerMessage( event );
};
this.worker.native.onmessage = scopedReceiveWorkerMessage;
if ( defaultGeometryType !== undefined && defaultGeometryType !== null ) {
this.worker.workerRunner.defaultGeometryType = defaultGeometryType;
}
if ( this.logging.enabled ) {
......@@ -339,6 +398,7 @@ WorkerExecutionSupport.prototype = {
console.timeEnd( timeLabel );
}
},
/**
......@@ -347,18 +407,22 @@ WorkerExecutionSupport.prototype = {
* @return {boolean|*}
*/
isWorkerLoaded: function ( requireJsmWorker ) {
return this.worker.native !== null &&
( ( requireJsmWorker && this.worker.jsmWorker ) || ( ! requireJsmWorker && ! this.worker.jsmWorker ) );
},
/**
* Executed in worker scope
*/
_receiveWorkerMessage: function ( event ) {
let payload = event.data;
let workerRunnerName = this.worker.workerRunner.name;
switch ( payload.cmd ) {
case 'assetAvailable':
this.worker.callbacks.onAssetAvailable( payload );
break;
......@@ -401,6 +465,7 @@ WorkerExecutionSupport.prototype = {
break;
}
},
/**
......@@ -408,16 +473,19 @@ WorkerExecutionSupport.prototype = {
*
* @param {Object} payload Raw mesh description (buffers, params, materials) used to build one to many meshes.
*/
executeParallel: function( payload, transferables ) {
executeParallel: function ( payload, transferables ) {
payload.cmd = 'parse';
payload.usesMeshDisassembler = this.worker.workerRunner.usesMeshDisassembler;
payload.defaultGeometryType = this.worker.workerRunner.defaultGeometryType;
if ( ! this._verifyWorkerIsAvailable( payload, transferables ) ) return;
this._postMessage();
},
_verifyWorkerIsAvailable: function ( payload, transferables ) {
this._verifyCallbacks();
let ready = true;
if ( this.worker.queuedMessage !== null ) {
......@@ -435,9 +503,11 @@ WorkerExecutionSupport.prototype = {
}
return ready;
},
_postMessage: function () {
if ( this.worker.queuedMessage !== null ) {
if ( this.worker.queuedMessage.payload.data.input instanceof ArrayBuffer ) {
......@@ -466,15 +536,18 @@ WorkerExecutionSupport.prototype = {
}
}
},
_terminate: function () {
this.worker.native.terminate();
this._reset();
}
};
export {
CodeBuilderInstructions,
WorkerExecutionSupport
}
};
......@@ -6,7 +6,8 @@
* Parse OBJ data either from ArrayBuffer or string
* @class
*/
const OBJLoader2Parser = function() {
const OBJLoader2Parser = function () {
this.callbacks = {
onProgress: null,
onAssetAvailable: null,
......@@ -64,6 +65,7 @@ const OBJLoader2Parser = function() {
enabled: true,
debug: false
};
};
OBJLoader2Parser.prototype = {
......@@ -71,6 +73,7 @@ OBJLoader2Parser.prototype = {
constructor: OBJLoader2Parser,
resetRawMesh: function () {
// faces are stored according combined index of group, material and smoothingGroup (0 or not)
this.rawMesh.subGroups = [];
this.rawMesh.subGroupInUse = null;
......@@ -84,66 +87,88 @@ OBJLoader2Parser.prototype = {
this.rawMesh.counts.faceCount = 0;
this.rawMesh.counts.mtlCount = 0;
this.rawMesh.counts.smoothingGroupCount = 0;
},
setMaterialPerSmoothingGroup: function ( materialPerSmoothingGroup ) {
this.materialPerSmoothingGroup = materialPerSmoothingGroup;
},
setUseOAsMesh: function ( useOAsMesh ) {
this.useOAsMesh = useOAsMesh;
},
setUseIndices: function ( useIndices ) {
this.useIndices = useIndices;
},
setDisregardNormals: function ( disregardNormals ) {
this.disregardNormals = disregardNormals;
},
setMaterials: function ( materials ) {
if ( materials === undefined || materials === null ) return;
for ( let materialName in materials ) {
if ( materials.hasOwnProperty( materialName ) ) {
this.materials[ materialName ] = materials[ materialName ];
}
}
},
setCallbackOnAssetAvailable: function ( onAssetAvailable ) {
if ( onAssetAvailable !== null && onAssetAvailable !== undefined ) {
this.callbacks.onAssetAvailable = onAssetAvailable;
}
},
setCallbackOnProgress: function ( onProgress ) {
if ( onProgress !== null && onProgress !== undefined ) {
this.callbacks.onProgress = onProgress;
}
},
setCallbackOnError: function ( onError ) {
if ( onError !== null && onError !== undefined ) {
this.callbacks.onError = onError;
}
},
setLogging: function ( enabled, debug ) {
this.logging.enabled = enabled === true;
this.logging.debug = debug === true;
},
configure: function () {
if ( this.callbacks.onAssetAvailable === null ) {
let errorMessage = 'Unable to run as no callback for building meshes is set.';
......@@ -154,6 +179,7 @@ OBJLoader2Parser.prototype = {
} else {
throw errorMessage;
}
}
......@@ -161,7 +187,7 @@ OBJLoader2Parser.prototype = {
if ( this.logging.enabled ) {
let matKeys = Object.keys( this.materials );
let matNames = (matKeys.length > 0) ? '\n\tmaterialNames:\n\t\t- ' + matKeys.join( '\n\t\t- ' ) : '\n\tmaterialNames: None';
let matNames = ( matKeys.length > 0 ) ? '\n\tmaterialNames:\n\t\t- ' + matKeys.join( '\n\t\t- ' ) : '\n\tmaterialNames: None';
let printedConfig = 'OBJLoader.Parser configuration:'
+ matNames
+ '\n\tmaterialPerSmoothingGroup: ' + this.materialPerSmoothingGroup
......@@ -169,17 +195,24 @@ OBJLoader2Parser.prototype = {
+ '\n\tuseIndices: ' + this.useIndices
+ '\n\tdisregardNormals: ' + this.disregardNormals;
if ( this.callbacks.onProgress !== null ) {
printedConfig += '\n\tcallbacks.onProgress: ' + this.callbacks.onProgress.name;
}
if ( this.callbacks.onAssetAvailable !== null ) {
printedConfig += '\n\tcallbacks.onAssetAvailable: ' + this.callbacks.onAssetAvailable.name;
}
if ( this.callbacks.onError !== null ) {
printedConfig += '\n\tcallbacks.onError: ' + this.callbacks.onError.name;
}
console.info( printedConfig );
}
},
/**
......@@ -188,6 +221,7 @@ OBJLoader2Parser.prototype = {
* @param {Uint8Array} arrayBuffer OBJ data as Uint8Array
*/
parse: function ( arrayBuffer ) {
if ( this.logging.enabled ) console.time( 'OBJLoader.Parser.parse' );
this.configure();
......@@ -201,6 +235,7 @@ OBJLoader2Parser.prototype = {
code = arrayBufferView[ i ];
switch ( code ) {
// space
case 32:
if ( word.length > 0 ) buffer[ bufferPointer ++ ] = word;
......@@ -231,10 +266,13 @@ OBJLoader2Parser.prototype = {
default:
word += String.fromCharCode( code );
break;
}
}
this.finalizeParsing();
if ( this.logging.enabled ) console.timeEnd( 'OBJLoader.Parser.parse' );
},
/**
......@@ -243,6 +281,7 @@ OBJLoader2Parser.prototype = {
* @param {string} text OBJ data as string
*/
parseText: function ( text ) {
if ( this.logging.enabled ) console.time( 'OBJLoader.Parser.parseText' );
this.configure();
this.legacyMode = true;
......@@ -255,6 +294,7 @@ OBJLoader2Parser.prototype = {
char = text[ i ];
switch ( char ) {
case ' ':
if ( word.length > 0 ) buffer[ bufferPointer ++ ] = word;
word = '';
......@@ -281,16 +321,21 @@ OBJLoader2Parser.prototype = {
default:
word += char;
}
}
this.finalizeParsing();
if ( this.logging.enabled ) console.timeEnd( 'OBJLoader.Parser.parseText' );
},
processLine: function ( buffer, bufferPointer, slashesCount ) {
if ( bufferPointer < 1 ) return;
let reconstructString = function ( content, legacyMode, start, stop ) {
let line = '';
if ( stop > start ) {
......@@ -309,11 +354,13 @@ OBJLoader2Parser.prototype = {
}
return line;
};
let bufferLength, length, i, lineDesignation;
lineDesignation = buffer [ 0 ];
lineDesignation = buffer[ 0 ];
switch ( lineDesignation ) {
case 'v':
this.vertices.push( parseFloat( buffer[ 1 ] ) );
this.vertices.push( parseFloat( buffer[ 2 ] ) );
......@@ -354,6 +401,7 @@ OBJLoader2Parser.prototype = {
}
// "f vertex/uv ..."
} else if ( bufferLength === slashesCount * 2 ) {
this.checkFaceType( 1 );
......@@ -366,6 +414,7 @@ OBJLoader2Parser.prototype = {
}
// "f vertex/uv/normal ..."
} else if ( bufferLength * 2 === slashesCount * 3 ) {
this.checkFaceType( 2 );
......@@ -378,6 +427,7 @@ OBJLoader2Parser.prototype = {
}
// "f vertex//normal ..."
} else {
this.checkFaceType( 3 );
......@@ -402,7 +452,7 @@ OBJLoader2Parser.prototype = {
} else {
this.checkFaceType( (lineDesignation === 'l') ? 5 : 6 );
this.checkFaceType( ( lineDesignation === 'l' ) ? 5 : 6 );
for ( i = 1, length = bufferLength + 1; i < length; i ++ ) this.buildFace( buffer[ i ] );
}
......@@ -441,17 +491,22 @@ OBJLoader2Parser.prototype = {
default:
break;
}
},
pushSmoothingGroup: function ( smoothingGroup ) {
let smoothingGroupInt = parseInt( smoothingGroup );
if ( isNaN( smoothingGroupInt ) ) {
smoothingGroupInt = smoothingGroup === "off" ? 0 : 1;
}
let smoothCheck = this.rawMesh.smoothingGroup.normalized;
this.rawMesh.smoothingGroup.normalized = this.rawMesh.smoothingGroup.splitMaterials ? smoothingGroupInt : (smoothingGroupInt === 0) ? 0 : 1;
this.rawMesh.smoothingGroup.normalized = this.rawMesh.smoothingGroup.splitMaterials ? smoothingGroupInt : ( smoothingGroupInt === 0 ) ? 0 : 1;
this.rawMesh.smoothingGroup.real = smoothingGroupInt;
if ( smoothCheck !== smoothingGroupInt ) {
......@@ -460,6 +515,7 @@ OBJLoader2Parser.prototype = {
this.checkSubGroup();
}
},
/**
......@@ -473,6 +529,7 @@ OBJLoader2Parser.prototype = {
* faceType = 6: "p vertex ..."
*/
checkFaceType: function ( faceType ) {
if ( this.rawMesh.faceType !== faceType ) {
this.processCompletedMesh();
......@@ -480,9 +537,11 @@ OBJLoader2Parser.prototype = {
this.checkSubGroup();
}
},
checkSubGroup: function () {
let index = this.rawMesh.activeMtlName + '|' + this.rawMesh.smoothingGroup.normalized;
this.rawMesh.subGroupInUse = this.rawMesh.subGroups[ index ];
......@@ -505,15 +564,17 @@ OBJLoader2Parser.prototype = {
this.rawMesh.subGroups[ index ] = this.rawMesh.subGroupInUse;
}
},
buildFace: function ( faceIndexV, faceIndexU, faceIndexN ) {
let subGroupInUse = this.rawMesh.subGroupInUse;
let scope = this;
let updateSubGroupInUse = function () {
let faceIndexVi = parseInt( faceIndexV );
let indexPointerV = 3 * (faceIndexVi > 0 ? faceIndexVi - 1 : faceIndexVi + scope.vertices.length / 3);
let indexPointerV = 3 * ( faceIndexVi > 0 ? faceIndexVi - 1 : faceIndexVi + scope.vertices.length / 3 );
let indexPointerC = scope.colors.length > 0 ? indexPointerV : null;
let vertices = subGroupInUse.vertices;
......@@ -532,7 +593,7 @@ OBJLoader2Parser.prototype = {
if ( faceIndexU ) {
let faceIndexUi = parseInt( faceIndexU );
let indexPointerU = 2 * (faceIndexUi > 0 ? faceIndexUi - 1 : faceIndexUi + scope.uvs.length / 2);
let indexPointerU = 2 * ( faceIndexUi > 0 ? faceIndexUi - 1 : faceIndexUi + scope.uvs.length / 2 );
let uvs = subGroupInUse.uvs;
uvs.push( scope.uvs[ indexPointerU ++ ] );
uvs.push( scope.uvs[ indexPointerU ] );
......@@ -541,13 +602,14 @@ OBJLoader2Parser.prototype = {
if ( faceIndexN && ! scope.disregardNormals ) {
let faceIndexNi = parseInt( faceIndexN );
let indexPointerN = 3 * (faceIndexNi > 0 ? faceIndexNi - 1 : faceIndexNi + scope.normals.length / 3);
let indexPointerN = 3 * ( faceIndexNi > 0 ? faceIndexNi - 1 : faceIndexNi + scope.normals.length / 3 );
let normals = subGroupInUse.normals;
normals.push( scope.normals[ indexPointerN ++ ] );
normals.push( scope.normals[ indexPointerN ++ ] );
normals.push( scope.normals[ indexPointerN ] );
}
};
if ( this.useIndices ) {
......@@ -560,11 +622,11 @@ OBJLoader2Parser.prototype = {
indicesPointer = this.rawMesh.subGroupInUse.vertices.length / 3;
updateSubGroupInUse();
subGroupInUse.indexMappings[ mappingName ] = indicesPointer;
subGroupInUse.indexMappingsCount++;
subGroupInUse.indexMappingsCount ++;
} else {
this.rawMesh.counts.doubleIndicesCount++;
this.rawMesh.counts.doubleIndicesCount ++;
}
subGroupInUse.indices.push( indicesPointer );
......@@ -575,9 +637,11 @@ OBJLoader2Parser.prototype = {
}
this.rawMesh.counts.faceCount ++;
},
createRawMeshReport: function ( inputObjectCount ) {
return 'Input Object number: ' + inputObjectCount +
'\n\tObject name: ' + this.rawMesh.objectName +
'\n\tGroup name: ' + this.rawMesh.groupName +
......@@ -588,12 +652,14 @@ OBJLoader2Parser.prototype = {
'\n\tSmoothingGroup count: ' + this.rawMesh.counts.smoothingGroupCount +
'\n\tMaterial count: ' + this.rawMesh.counts.mtlCount +
'\n\tReal MeshOutputGroup count: ' + this.rawMesh.subGroups.length;
},
/**
* Clear any empty subGroup and calculate absolute vertex, normal and uv counts
*/
finalizeRawMesh: function () {
let meshOutputGroupTemp = [];
let meshOutputGroup;
let absoluteVertexCount = 0;
......@@ -611,7 +677,7 @@ OBJLoader2Parser.prototype = {
indices = meshOutputGroup.indices;
if ( indices.length > 0 && absoluteIndexMappingsCount > 0 ) {
for ( let i = 0; i < indices.length; i++ ) {
for ( let i = 0; i < indices.length; i ++ ) {
indices[ i ] = indices[ i ] + absoluteIndexMappingsCount;
......@@ -627,6 +693,7 @@ OBJLoader2Parser.prototype = {
absoluteNormalCount += meshOutputGroup.normals.length;
}
}
// do not continue if no result
......@@ -647,9 +714,11 @@ OBJLoader2Parser.prototype = {
}
return result;
},
processCompletedMesh: function () {
let result = this.finalizeRawMesh();
let haveMesh = result !== null;
if ( haveMesh ) {
......@@ -671,13 +740,14 @@ OBJLoader2Parser.prototype = {
if ( this.callbacks.onProgress !== null ) {
this.callbacks.onProgress( 'Completed [o: ' + this.rawMesh.objectName + ' g:' + this.rawMesh.groupName + '' +
'] Total progress: ' + (progressBytesPercent * 100).toFixed( 2 ) + '%', progressBytesPercent );
'] Total progress: ' + ( progressBytesPercent * 100 ).toFixed( 2 ) + '%', progressBytesPercent );
}
this.resetRawMesh();
}
return haveMesh;
},
/**
......@@ -687,22 +757,23 @@ OBJLoader2Parser.prototype = {
* @param result
*/
buildMesh: function ( result ) {
let meshOutputGroups = result.subGroups;
let vertexFA = new Float32Array( result.absoluteVertexCount );
this.globalCounts.vertices += result.absoluteVertexCount / 3;
this.globalCounts.faces += result.faceCount;
this.globalCounts.doubleIndicesCount += result.doubleIndicesCount;
let indexUA = (result.absoluteIndexCount > 0) ? new Uint32Array( result.absoluteIndexCount ) : null;
let colorFA = (result.absoluteColorCount > 0) ? new Float32Array( result.absoluteColorCount ) : null;
let normalFA = (result.absoluteNormalCount > 0) ? new Float32Array( result.absoluteNormalCount ) : null;
let uvFA = (result.absoluteUvCount > 0) ? new Float32Array( result.absoluteUvCount ) : null;
let indexUA = ( result.absoluteIndexCount > 0 ) ? new Uint32Array( result.absoluteIndexCount ) : null;
let colorFA = ( result.absoluteColorCount > 0 ) ? new Float32Array( result.absoluteColorCount ) : null;
let normalFA = ( result.absoluteNormalCount > 0 ) ? new Float32Array( result.absoluteNormalCount ) : null;
let uvFA = ( result.absoluteUvCount > 0 ) ? new Float32Array( result.absoluteUvCount ) : null;
let haveVertexColors = colorFA !== null;
let meshOutputGroup;
let materialNames = [];
let createMultiMaterial = (meshOutputGroups.length > 1);
let createMultiMaterial = ( meshOutputGroups.length > 1 );
let materialIndex = 0;
let materialIndexMapping = [];
let selectedMaterialIndex;
......@@ -727,7 +798,7 @@ OBJLoader2Parser.prototype = {
materialNameOrg = meshOutputGroup.materialName;
if ( this.rawMesh.faceType < 4 ) {
materialName = materialNameOrg + (haveVertexColors ? '_vertexColor' : '') + (meshOutputGroup.smoothingGroup === 0 ? '_flat' : '');
materialName = materialNameOrg + ( haveVertexColors ? '_vertexColor' : '' ) + ( meshOutputGroup.smoothingGroup === 0 ? '_flat' : '' );
} else {
......@@ -883,17 +954,19 @@ OBJLoader2Parser.prototype = {
uvs: uvFA
},
// 0: mesh, 1: line, 2: point
geometryType: this.rawMesh.faceType < 4 ? 0 : (this.rawMesh.faceType === 6) ? 2 : 1
geometryType: this.rawMesh.faceType < 4 ? 0 : ( this.rawMesh.faceType === 6 ) ? 2 : 1
},
[ vertexFA.buffer ],
indexUA !== null ? [ indexUA.buffer ] : null,
indexUA !== null ? [ indexUA.buffer ] : null,
colorFA !== null ? [ colorFA.buffer ] : null,
normalFA !== null ? [ normalFA.buffer ] : null,
uvFA !== null ? [ uvFA.buffer ] : null
);
},
finalizeParsing: function () {
if ( this.logging.enabled ) console.info( 'Global output object count: ' + this.outputObjectCount );
if ( this.processCompletedMesh() && this.logging.enabled ) {
......@@ -904,6 +977,7 @@ OBJLoader2Parser.prototype = {
console.info( parserFinalReport );
}
}
};
......
......@@ -5,11 +5,13 @@
import { ObjectManipulator } from "../../utils/ObjectManipulator.js";
const DefaultWorkerPayloadHandler = function ( parser ) {
this.parser = parser;
this.logging = {
enabled: false,
debug: false
};
};
DefaultWorkerPayloadHandler.prototype = {
......@@ -17,19 +19,26 @@ DefaultWorkerPayloadHandler.prototype = {
constructor: DefaultWorkerPayloadHandler,
handlePayload: function ( payload ) {
if ( payload.logging ) {
this.logging.enabled = payload.logging.enabled === true;
this.logging.debug = payload.logging.debug === true;
}
if ( payload.cmd === 'parse' ) {
let scope = this;
let callbacks = {
callbackOnAssetAvailable: function ( payload ) {
self.postMessage( payload );
},
callbackOnProgress: function ( text ) {
if ( scope.logging.enabled && scope.logging.debug ) console.debug( 'WorkerRunner: progress: ' + text );
}
};
......@@ -44,7 +53,7 @@ DefaultWorkerPayloadHandler.prototype = {
ObjectManipulator.applyProperties( parser, callbacks );
let arraybuffer;
if ( payload.params && payload.params.index !== undefined && payload.params.index !== null) {
if ( payload.params && payload.params.index !== undefined && payload.params.index !== null ) {
arraybuffer = this.resourceDescriptors[ payload.params.index ].content;
......@@ -62,7 +71,7 @@ DefaultWorkerPayloadHandler.prototype = {
} else {
parser[ parseFunctionName ] ( arraybuffer, payload.data.options );
parser[ parseFunctionName ]( arraybuffer, payload.data.options );
}
if ( this.logging.enabled ) console.log( 'WorkerRunner: Run complete!' );
......@@ -87,14 +96,18 @@ DefaultWorkerPayloadHandler.prototype = {
* @constructor
*/
const WorkerRunner = function ( payloadHandler ) {
this.resourceDescriptors = [];
this.payloadHandler = payloadHandler;
let scope = this;
let scopedRunner = function( event ) {
let scopedRunner = function ( event ) {
scope.processMessage( event.data );
};
self.addEventListener( 'message', scopedRunner, false );
};
WorkerRunner.prototype = {
......@@ -107,6 +120,7 @@ WorkerRunner.prototype = {
* @param {Object} payload Raw mesh description (buffers, params, materials) used to build one to many meshes.
*/
processMessage: function ( payload ) {
if ( payload.data.resourceDescriptors && this.resourceDescriptors.length === 0 ) {
for ( let name in payload.data.resourceDescriptors ) {
......@@ -118,6 +132,7 @@ WorkerRunner.prototype = {
}
this.payloadHandler.handlePayload( payload );
}
};
......@@ -125,4 +140,4 @@ WorkerRunner.prototype = {
export {
WorkerRunner,
DefaultWorkerPayloadHandler
}
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册