forked from mrdoob/three.js
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OBJLoader web worker wrapper (mrdoob#9756)
WWOBJLoaderFrontEnd.js: Handles mtl loading via MTLLoader. Materials are passed without textures to WWOBJLoader. Webworker (WWOBJLoader.js) re-creates the MaterialCreator. It can be used with both files and already loaded files (arraybuffer/string) and pass the obj data to the webworker (arraybuffer is useful when OBJ file was for example stored in zip). Realizes the communication and workflow with the webworker. WWOBJLoader.js: Is an extension of OBJLoader and wraps it into a web worker. It overrides the '_buildSingleMesh' method. Sending back the mesh content to WWOBJLoaderFrontEnd.js WWCommons.js: Relative import paths for webworker defined outside. Possibility to share other common static information
- Loading branch information
Kai Salmen
committed
Sep 23, 2016
1 parent
151f57b
commit 4335c25
Showing
3 changed files
with
626 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @author Kai Salmen / www.kaisalmen.de | ||
*/ | ||
|
||
'use strict'; | ||
|
||
if ( THREE === undefined ) { | ||
var THREE = {} | ||
} | ||
|
||
if ( THREE.WebWorker === undefined ) { | ||
|
||
THREE.WebWorker = { | ||
Commons: { | ||
paths: { | ||
threejsPath: '../../../../build/three.min.js', | ||
objLoaderPath: '../OBJLoader.js', | ||
mtlLoaderPath: '../MTLLoader.js' | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
/** | ||
* @author Kai Salmen / www.kaisalmen.de | ||
*/ | ||
|
||
'use strict'; | ||
|
||
importScripts( './WWCommons.js' ); | ||
importScripts( THREE.WebWorker.Commons.paths.threejsPath ); | ||
importScripts( THREE.WebWorker.Commons.paths.objLoaderPath ); | ||
importScripts( THREE.WebWorker.Commons.paths.mtlLoaderPath ); | ||
|
||
THREE.WebWorker.WWOBJLoader = (function () { | ||
|
||
WWOBJLoader.prototype = Object.create( THREE.OBJLoader.prototype, { | ||
constructor: { | ||
configurable: true, | ||
enumerable: true, | ||
value: WWOBJLoader, | ||
writable: true | ||
} | ||
} ); | ||
|
||
function WWOBJLoader() { | ||
THREE.OBJLoader.call( this ); | ||
this.cmdState = 'created'; | ||
this.debug = false; | ||
|
||
this.basePath = ''; | ||
this.objFile = ''; | ||
this.dataAvailable = false; | ||
this.objAsArrayBuffer = null; | ||
|
||
this.setLoadAsArrayBuffer( true ); | ||
this.setWorkInline( true ); | ||
|
||
this.counter = 0; | ||
} | ||
|
||
WWOBJLoader.prototype._buildSingleMesh = function ( object, material ) { | ||
// Fast-Fail: Skip o/g line declarations that did not follow with any faces | ||
if ( object.geometry.vertices.length === 0 ) return null; | ||
|
||
this.counter ++; | ||
|
||
var geometry = object.geometry; | ||
var objectMaterials = object.materials; | ||
|
||
var verticesOut = new Float32Array( geometry.vertices ); | ||
var normalsOut = null; | ||
if ( geometry.normals.length > 0 ) { | ||
|
||
normalsOut = new Float32Array( geometry.normals ); | ||
|
||
} | ||
var uvsOut = new Float32Array( geometry.uvs ); | ||
|
||
|
||
var materialGroups = []; | ||
var materialNames = []; | ||
var multiMaterial = false; | ||
if ( material instanceof THREE.MultiMaterial ) { | ||
|
||
for ( var objectMaterial, group, i = 0, length = objectMaterials.length; i < length; i ++ ) { | ||
|
||
objectMaterial = objectMaterials[ i ]; | ||
group = { | ||
start: objectMaterial.groupStart, | ||
count: objectMaterial.groupCount, | ||
index: i | ||
}; | ||
materialGroups.push( group ); | ||
|
||
} | ||
|
||
var mMaterial; | ||
for ( var key in material.materials ) { | ||
|
||
mMaterial = material.materials[ key ]; | ||
materialNames.push( mMaterial.name ); | ||
|
||
} | ||
multiMaterial = true; | ||
} | ||
|
||
|
||
self.postMessage( { | ||
cmd: 'objData', | ||
meshName: object.name, | ||
multiMaterial: multiMaterial, | ||
materialName: multiMaterial ? JSON.stringify( materialNames ) : material.name, | ||
materialGroups: multiMaterial ? JSON.stringify( materialGroups ) : null, | ||
vertices: verticesOut, | ||
normals: normalsOut, | ||
uvs: uvsOut, | ||
}, [ verticesOut.buffer ], [ normalsOut.buffer ], [ uvsOut.buffer ] ); | ||
|
||
return null; | ||
}; | ||
|
||
|
||
WWOBJLoader.prototype.init = function ( payload ) { | ||
this.cmdState = 'init'; | ||
|
||
this.debug = payload.debug; | ||
this.dataAvailable = payload.dataAvailable; | ||
this.basePath = payload.basePath === null ? '' : payload.basePath; | ||
this.objFile = payload.objFile === null ? '' : payload.objFile; | ||
|
||
// configure OBJLoader | ||
if ( payload.loadAsArrayBuffer !== undefined ) { | ||
|
||
this.setLoadAsArrayBuffer( payload.loadAsArrayBuffer ); | ||
|
||
} | ||
if ( payload.workInline !== undefined ) { | ||
|
||
this.setWorkInline( payload.workInline ); | ||
|
||
} | ||
this.setPath( this.basePath ); | ||
|
||
if ( this.dataAvailable ) { | ||
|
||
// this must be the case, otherwise loading will fail | ||
this.setLoadAsArrayBuffer( true ); | ||
this.objAsArrayBuffer = payload.objAsArrayBuffer; | ||
|
||
} | ||
}; | ||
|
||
WWOBJLoader.prototype.initMaterials = function ( payload ) { | ||
this.cmdState = 'initMaterials'; | ||
|
||
var materialsJSON = JSON.parse( payload.materials ); | ||
var materialCreator = new THREE.MTLLoader.MaterialCreator( payload.baseUrl, payload.options ); | ||
materialCreator.setMaterials( materialsJSON ); | ||
materialCreator.preload(); | ||
|
||
this.setMaterials( materialCreator ); | ||
}; | ||
|
||
WWOBJLoader.prototype.run = function () { | ||
this.cmdState = 'run'; | ||
var scope = this; | ||
|
||
var complete = function () { | ||
console.log( 'OBJ loading complete!' ); | ||
|
||
scope.cmdState = 'complete'; | ||
self.postMessage( { | ||
cmd: scope.cmdState | ||
} ); | ||
|
||
scope.dispose(); | ||
}; | ||
|
||
if ( scope.dataAvailable ) { | ||
|
||
scope.parseArrayBuffer( scope.objAsArrayBuffer ); | ||
complete(); | ||
|
||
} else { | ||
|
||
var onLoad = function () { | ||
complete(); | ||
}; | ||
|
||
var onProgress = function ( xhr ) { | ||
if ( xhr.lengthComputable ) { | ||
var percentComplete = xhr.loaded / xhr.total * 100; | ||
console.log( Math.round( percentComplete, 2 ) + '% downloaded' ); | ||
} | ||
}; | ||
|
||
var onError = function ( xhr ) { | ||
console.error( xhr ); | ||
}; | ||
|
||
scope.load( scope.objFile, onLoad, onProgress, onError ); | ||
|
||
} | ||
}; | ||
|
||
return WWOBJLoader; | ||
})(); | ||
|
||
var implRef = new THREE.WebWorker.WWOBJLoader( this ); | ||
|
||
var runner = function ( event ) { | ||
var payload = event.data; | ||
|
||
console.log( 'Command state before: ' + implRef.cmdState ); | ||
|
||
switch ( payload.cmd ) { | ||
case 'init': | ||
|
||
implRef.init( payload ); | ||
break; | ||
|
||
case 'initMaterials': | ||
|
||
implRef.initMaterials( payload ); | ||
break; | ||
|
||
case 'run': | ||
|
||
implRef.run(); | ||
break; | ||
|
||
default: | ||
|
||
console.error( 'WWOBJLoader: Received unknown command: ' + payload.cmd ); | ||
break; | ||
|
||
} | ||
|
||
console.log( 'Command state after: ' + implRef.cmdState ); | ||
}; | ||
|
||
self.addEventListener( 'message', runner, false ); |
Oops, something went wrong.