|
@@ -593,312 +593,17 @@ THREE.LDrawLoader = ( function () {
|
|
|
fileLoader.setPath( this.path );
|
|
|
fileLoader.load( url, function ( text ) {
|
|
|
|
|
|
- processObject( text, onLoad );
|
|
|
+ scope.processObject( text, onLoad, null, url );
|
|
|
|
|
|
}, onProgress, onError );
|
|
|
|
|
|
- function processObject( text, onProcessed, subobject ) {
|
|
|
-
|
|
|
- var parseScope = scope.newParseScopeLevel();
|
|
|
- parseScope.url = url;
|
|
|
-
|
|
|
- var parentParseScope = scope.getParentParseScope();
|
|
|
-
|
|
|
- // Set current matrix
|
|
|
- if ( subobject ) {
|
|
|
-
|
|
|
- parseScope.currentMatrix.multiplyMatrices( parentParseScope.currentMatrix, subobject.matrix );
|
|
|
- parseScope.matrix.copy( subobject.matrix );
|
|
|
- parseScope.inverted = subobject.inverted;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Add to cache
|
|
|
- var currentFileName = parentParseScope.currentFileName;
|
|
|
- if ( currentFileName !== null ) {
|
|
|
-
|
|
|
- currentFileName = parentParseScope.currentFileName.toLowerCase();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( scope.subobjectCache[ currentFileName ] === undefined ) {
|
|
|
-
|
|
|
- scope.subobjectCache[ currentFileName ] = text;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // Parse the object (returns a THREE.Group)
|
|
|
- scope.parse( text );
|
|
|
- var finishedCount = 0;
|
|
|
- onSubobjectFinish();
|
|
|
-
|
|
|
- function onSubobjectFinish() {
|
|
|
-
|
|
|
- finishedCount ++;
|
|
|
-
|
|
|
- if ( finishedCount === parseScope.subobjects.length + 1 ) {
|
|
|
-
|
|
|
- finalizeObject();
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- // Once the previous subobject has finished we can start processing the next one in the list.
|
|
|
- // The subobject processing shares scope in processing so it's important that they be loaded serially
|
|
|
- // to avoid race conditions.
|
|
|
- // Promise.resolve is used as an approach to asynchronously schedule a task _before_ this frame ends to
|
|
|
- // avoid stack overflow exceptions when loading many subobjects from the cache. RequestAnimationFrame
|
|
|
- // will work but causes the load to happen after the next frame which causes the load to take significantly longer.
|
|
|
- var subobject = parseScope.subobjects[ parseScope.subobjectIndex ];
|
|
|
- Promise.resolve().then( function () {
|
|
|
-
|
|
|
- loadSubobject( subobject );
|
|
|
-
|
|
|
- } );
|
|
|
- parseScope.subobjectIndex ++;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function finalizeObject() {
|
|
|
-
|
|
|
- if ( scope.smoothNormals && parseScope.type === 'Part' ) {
|
|
|
-
|
|
|
- smoothNormals( parseScope.triangles, parseScope.lineSegments );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var isRoot = ! parentParseScope.isFromParse;
|
|
|
- if ( scope.separateObjects && ! isPrimitiveType( parseScope.type ) || isRoot ) {
|
|
|
-
|
|
|
-
|
|
|
- const objGroup = parseScope.groupObject;
|
|
|
- if ( parseScope.triangles.length > 0 ) {
|
|
|
-
|
|
|
- objGroup.add( createObject( parseScope.triangles, 3 ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( parseScope.lineSegments.length > 0 ) {
|
|
|
-
|
|
|
- objGroup.add( createObject( parseScope.lineSegments, 2 ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( parseScope.conditionalSegments.length > 0 ) {
|
|
|
-
|
|
|
- objGroup.add( createObject( parseScope.conditionalSegments, 2, true ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( parentParseScope.groupObject ) {
|
|
|
-
|
|
|
- objGroup.name = parseScope.fileName;
|
|
|
- objGroup.userData.category = parseScope.category;
|
|
|
- objGroup.userData.keywords = parseScope.keywords;
|
|
|
- parseScope.matrix.decompose( objGroup.position, objGroup.quaternion, objGroup.scale );
|
|
|
-
|
|
|
- parentParseScope.groupObject.add( objGroup );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- var separateObjects = scope.separateObjects;
|
|
|
- var parentLineSegments = parentParseScope.lineSegments;
|
|
|
- var parentConditionalSegments = parentParseScope.conditionalSegments;
|
|
|
- var parentTriangles = parentParseScope.triangles;
|
|
|
-
|
|
|
- var lineSegments = parseScope.lineSegments;
|
|
|
- var conditionalSegments = parseScope.conditionalSegments;
|
|
|
- var triangles = parseScope.triangles;
|
|
|
-
|
|
|
- for ( var i = 0, l = lineSegments.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- var ls = lineSegments[ i ];
|
|
|
- if ( separateObjects ) {
|
|
|
-
|
|
|
- ls.v0.applyMatrix4( parseScope.matrix );
|
|
|
- ls.v1.applyMatrix4( parseScope.matrix );
|
|
|
-
|
|
|
- }
|
|
|
- parentLineSegments.push( ls );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- for ( var i = 0, l = conditionalSegments.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- var os = conditionalSegments[ i ];
|
|
|
- if ( separateObjects ) {
|
|
|
-
|
|
|
- os.v0.applyMatrix4( parseScope.matrix );
|
|
|
- os.v1.applyMatrix4( parseScope.matrix );
|
|
|
- os.c0.applyMatrix4( parseScope.matrix );
|
|
|
- os.c1.applyMatrix4( parseScope.matrix );
|
|
|
-
|
|
|
- }
|
|
|
- parentConditionalSegments.push( os );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- for ( var i = 0, l = triangles.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- var tri = triangles[ i ];
|
|
|
- if ( separateObjects ) {
|
|
|
-
|
|
|
- tri.v0 = tri.v0.clone().applyMatrix4( parseScope.matrix );
|
|
|
- tri.v1 = tri.v1.clone().applyMatrix4( parseScope.matrix );
|
|
|
- tri.v2 = tri.v2.clone().applyMatrix4( parseScope.matrix );
|
|
|
-
|
|
|
- tempVec0.subVectors( tri.v1, tri.v0 );
|
|
|
- tempVec1.subVectors( tri.v2, tri.v1 );
|
|
|
- tri.faceNormal.crossVectors( tempVec0, tempVec1 ).normalize();
|
|
|
-
|
|
|
- }
|
|
|
- parentTriangles.push( tri );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- scope.removeScopeLevel();
|
|
|
-
|
|
|
- if ( onProcessed ) {
|
|
|
-
|
|
|
- onProcessed( parseScope.groupObject );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function loadSubobject( subobject ) {
|
|
|
-
|
|
|
- parseScope.mainColourCode = subobject.material.userData.code;
|
|
|
- parseScope.mainEdgeColourCode = subobject.material.userData.edgeMaterial.userData.code;
|
|
|
- parseScope.currentFileName = subobject.originalFileName;
|
|
|
-
|
|
|
-
|
|
|
- // If subobject was cached previously, use the cached one
|
|
|
- var cached = scope.subobjectCache[ subobject.originalFileName.toLowerCase() ];
|
|
|
- if ( cached ) {
|
|
|
-
|
|
|
- processObject( cached, function ( subobjectGroup ) {
|
|
|
-
|
|
|
- onSubobjectLoaded( subobjectGroup, subobject );
|
|
|
- onSubobjectFinish();
|
|
|
-
|
|
|
- }, subobject );
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Adjust file name to locate the subobject file path in standard locations (always under directory scope.path)
|
|
|
- // Update also subobject.locationState for the next try if this load fails.
|
|
|
- var subobjectURL = subobject.fileName;
|
|
|
- var newLocationState = LDrawLoader.FILE_LOCATION_NOT_FOUND;
|
|
|
-
|
|
|
- switch ( subobject.locationState ) {
|
|
|
-
|
|
|
- case LDrawLoader.FILE_LOCATION_AS_IS:
|
|
|
- newLocationState = subobject.locationState + 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case LDrawLoader.FILE_LOCATION_TRY_PARTS:
|
|
|
- subobjectURL = 'parts/' + subobjectURL;
|
|
|
- newLocationState = subobject.locationState + 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case LDrawLoader.FILE_LOCATION_TRY_P:
|
|
|
- subobjectURL = 'p/' + subobjectURL;
|
|
|
- newLocationState = subobject.locationState + 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case LDrawLoader.FILE_LOCATION_TRY_MODELS:
|
|
|
- subobjectURL = 'models/' + subobjectURL;
|
|
|
- newLocationState = subobject.locationState + 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case LDrawLoader.FILE_LOCATION_TRY_RELATIVE:
|
|
|
- subobjectURL = url.substring( 0, url.lastIndexOf( "/" ) + 1 ) + subobjectURL;
|
|
|
- newLocationState = subobject.locationState + 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case LDrawLoader.FILE_LOCATION_TRY_ABSOLUTE:
|
|
|
-
|
|
|
- if ( subobject.triedLowerCase ) {
|
|
|
-
|
|
|
- // Try absolute path
|
|
|
- newLocationState = LDrawLoader.FILE_LOCATION_NOT_FOUND;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- // Next attempt is lower case
|
|
|
- subobject.fileName = subobject.fileName.toLowerCase();
|
|
|
- subobjectURL = subobject.fileName;
|
|
|
- subobject.triedLowerCase = true;
|
|
|
- newLocationState = LDrawLoader.FILE_LOCATION_AS_IS;
|
|
|
-
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case LDrawLoader.FILE_LOCATION_NOT_FOUND:
|
|
|
-
|
|
|
- // All location possibilities have been tried, give up loading this object
|
|
|
- console.warn( 'LDrawLoader: Subobject "' + subobject.originalFileName + '" could not be found.' );
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- subobject.locationState = newLocationState;
|
|
|
- subobject.url = subobjectURL;
|
|
|
-
|
|
|
- // Load the subobject
|
|
|
- // Use another file loader here so we can keep track of the subobject information
|
|
|
- // and use it when processing the next model.
|
|
|
- var fileLoader = new THREE.FileLoader( scope.manager );
|
|
|
- fileLoader.setPath( scope.path );
|
|
|
- fileLoader.load( subobjectURL, function ( text ) {
|
|
|
-
|
|
|
- processObject( text, function ( subobjectGroup ) {
|
|
|
-
|
|
|
- onSubobjectLoaded( subobjectGroup, subobject );
|
|
|
- onSubobjectFinish();
|
|
|
-
|
|
|
- }, subobject );
|
|
|
-
|
|
|
- }, undefined, function ( err ) {
|
|
|
-
|
|
|
- onSubobjectError( err, subobject );
|
|
|
-
|
|
|
- }, subobject );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function onSubobjectLoaded( subobjectGroup, subobject ) {
|
|
|
-
|
|
|
- if ( subobjectGroup === null ) {
|
|
|
-
|
|
|
- // Try to reload
|
|
|
- loadSubobject( subobject );
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- scope.fileMap[ subobject.originalFileName ] = subobject.url;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function onSubobjectError( err, subobject ) {
|
|
|
+ },
|
|
|
|
|
|
- // Retry download from a different default possible location
|
|
|
- loadSubobject( subobject );
|
|
|
+ parse: function ( text, onParsed ) {
|
|
|
|
|
|
- }
|
|
|
+ // Async parse. This function calls onParse with the parsed THREE.Object3D as parameter
|
|
|
|
|
|
- }
|
|
|
+ this.processObject( text, onProcessed, null, "" );
|
|
|
|
|
|
},
|
|
|
|
|
@@ -1329,7 +1034,7 @@ THREE.LDrawLoader = ( function () {
|
|
|
|
|
|
//
|
|
|
|
|
|
- parse: function ( text ) {
|
|
|
+ objectParse: function ( text ) {
|
|
|
|
|
|
//console.time( 'LDrawLoader' );
|
|
|
|
|
@@ -1888,6 +1593,311 @@ THREE.LDrawLoader = ( function () {
|
|
|
currentParseScope.numSubobjects = subobjects.length;
|
|
|
currentParseScope.subobjectIndex = 0;
|
|
|
|
|
|
+ },
|
|
|
+
|
|
|
+ processObject: function ( text, onProcessed, subobject, url ) {
|
|
|
+
|
|
|
+ var scope = this;
|
|
|
+
|
|
|
+ var parseScope = scope.newParseScopeLevel();
|
|
|
+ parseScope.url = url;
|
|
|
+
|
|
|
+ var parentParseScope = scope.getParentParseScope();
|
|
|
+
|
|
|
+ // Set current matrix
|
|
|
+ if ( subobject ) {
|
|
|
+
|
|
|
+ parseScope.currentMatrix.multiplyMatrices( parentParseScope.currentMatrix, subobject.matrix );
|
|
|
+ parseScope.matrix.copy( subobject.matrix );
|
|
|
+ parseScope.inverted = subobject.inverted;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add to cache
|
|
|
+ var currentFileName = parentParseScope.currentFileName;
|
|
|
+ if ( currentFileName !== null ) {
|
|
|
+
|
|
|
+ currentFileName = parentParseScope.currentFileName.toLowerCase();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( scope.subobjectCache[ currentFileName ] === undefined ) {
|
|
|
+
|
|
|
+ scope.subobjectCache[ currentFileName ] = text;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Parse the object (returns a THREE.Group)
|
|
|
+ scope.objectParse( text );
|
|
|
+ var finishedCount = 0;
|
|
|
+ onSubobjectFinish();
|
|
|
+
|
|
|
+ function onSubobjectFinish() {
|
|
|
+
|
|
|
+ finishedCount ++;
|
|
|
+
|
|
|
+ if ( finishedCount === parseScope.subobjects.length + 1 ) {
|
|
|
+
|
|
|
+ finalizeObject();
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // Once the previous subobject has finished we can start processing the next one in the list.
|
|
|
+ // The subobject processing shares scope in processing so it's important that they be loaded serially
|
|
|
+ // to avoid race conditions.
|
|
|
+ // Promise.resolve is used as an approach to asynchronously schedule a task _before_ this frame ends to
|
|
|
+ // avoid stack overflow exceptions when loading many subobjects from the cache. RequestAnimationFrame
|
|
|
+ // will work but causes the load to happen after the next frame which causes the load to take significantly longer.
|
|
|
+ var subobject = parseScope.subobjects[ parseScope.subobjectIndex ];
|
|
|
+ Promise.resolve().then( function () {
|
|
|
+
|
|
|
+ loadSubobject( subobject );
|
|
|
+
|
|
|
+ } );
|
|
|
+ parseScope.subobjectIndex ++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function finalizeObject() {
|
|
|
+
|
|
|
+ if ( scope.smoothNormals && parseScope.type === 'Part' ) {
|
|
|
+
|
|
|
+ smoothNormals( parseScope.triangles, parseScope.lineSegments );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var isRoot = ! parentParseScope.isFromParse;
|
|
|
+ if ( scope.separateObjects && ! isPrimitiveType( parseScope.type ) || isRoot ) {
|
|
|
+
|
|
|
+
|
|
|
+ const objGroup = parseScope.groupObject;
|
|
|
+ if ( parseScope.triangles.length > 0 ) {
|
|
|
+
|
|
|
+ objGroup.add( createObject( parseScope.triangles, 3 ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( parseScope.lineSegments.length > 0 ) {
|
|
|
+
|
|
|
+ objGroup.add( createObject( parseScope.lineSegments, 2 ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( parseScope.conditionalSegments.length > 0 ) {
|
|
|
+
|
|
|
+ objGroup.add( createObject( parseScope.conditionalSegments, 2, true ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( parentParseScope.groupObject ) {
|
|
|
+
|
|
|
+ objGroup.name = parseScope.fileName;
|
|
|
+ objGroup.userData.category = parseScope.category;
|
|
|
+ objGroup.userData.keywords = parseScope.keywords;
|
|
|
+ parseScope.matrix.decompose( objGroup.position, objGroup.quaternion, objGroup.scale );
|
|
|
+
|
|
|
+ parentParseScope.groupObject.add( objGroup );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ var separateObjects = scope.separateObjects;
|
|
|
+ var parentLineSegments = parentParseScope.lineSegments;
|
|
|
+ var parentConditionalSegments = parentParseScope.conditionalSegments;
|
|
|
+ var parentTriangles = parentParseScope.triangles;
|
|
|
+
|
|
|
+ var lineSegments = parseScope.lineSegments;
|
|
|
+ var conditionalSegments = parseScope.conditionalSegments;
|
|
|
+ var triangles = parseScope.triangles;
|
|
|
+
|
|
|
+ for ( var i = 0, l = lineSegments.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var ls = lineSegments[ i ];
|
|
|
+ if ( separateObjects ) {
|
|
|
+
|
|
|
+ ls.v0.applyMatrix4( parseScope.matrix );
|
|
|
+ ls.v1.applyMatrix4( parseScope.matrix );
|
|
|
+
|
|
|
+ }
|
|
|
+ parentLineSegments.push( ls );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( var i = 0, l = conditionalSegments.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var os = conditionalSegments[ i ];
|
|
|
+ if ( separateObjects ) {
|
|
|
+
|
|
|
+ os.v0.applyMatrix4( parseScope.matrix );
|
|
|
+ os.v1.applyMatrix4( parseScope.matrix );
|
|
|
+ os.c0.applyMatrix4( parseScope.matrix );
|
|
|
+ os.c1.applyMatrix4( parseScope.matrix );
|
|
|
+
|
|
|
+ }
|
|
|
+ parentConditionalSegments.push( os );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( var i = 0, l = triangles.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var tri = triangles[ i ];
|
|
|
+ if ( separateObjects ) {
|
|
|
+
|
|
|
+ tri.v0 = tri.v0.clone().applyMatrix4( parseScope.matrix );
|
|
|
+ tri.v1 = tri.v1.clone().applyMatrix4( parseScope.matrix );
|
|
|
+ tri.v2 = tri.v2.clone().applyMatrix4( parseScope.matrix );
|
|
|
+
|
|
|
+ tempVec0.subVectors( tri.v1, tri.v0 );
|
|
|
+ tempVec1.subVectors( tri.v2, tri.v1 );
|
|
|
+ tri.faceNormal.crossVectors( tempVec0, tempVec1 ).normalize();
|
|
|
+
|
|
|
+ }
|
|
|
+ parentTriangles.push( tri );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ scope.removeScopeLevel();
|
|
|
+
|
|
|
+ if ( onProcessed ) {
|
|
|
+
|
|
|
+ onProcessed( parseScope.groupObject );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function loadSubobject( subobject ) {
|
|
|
+
|
|
|
+ parseScope.mainColourCode = subobject.material.userData.code;
|
|
|
+ parseScope.mainEdgeColourCode = subobject.material.userData.edgeMaterial.userData.code;
|
|
|
+ parseScope.currentFileName = subobject.originalFileName;
|
|
|
+
|
|
|
+
|
|
|
+ // If subobject was cached previously, use the cached one
|
|
|
+ var cached = scope.subobjectCache[ subobject.originalFileName.toLowerCase() ];
|
|
|
+ if ( cached ) {
|
|
|
+
|
|
|
+ scope.processObject( cached, function ( subobjectGroup ) {
|
|
|
+
|
|
|
+ onSubobjectLoaded( subobjectGroup, subobject );
|
|
|
+ onSubobjectFinish();
|
|
|
+
|
|
|
+ }, subobject, url );
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // Adjust file name to locate the subobject file path in standard locations (always under directory scope.path)
|
|
|
+ // Update also subobject.locationState for the next try if this load fails.
|
|
|
+ var subobjectURL = subobject.fileName;
|
|
|
+ var newLocationState = LDrawLoader.FILE_LOCATION_NOT_FOUND;
|
|
|
+
|
|
|
+ switch ( subobject.locationState ) {
|
|
|
+
|
|
|
+ case LDrawLoader.FILE_LOCATION_AS_IS:
|
|
|
+ newLocationState = subobject.locationState + 1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LDrawLoader.FILE_LOCATION_TRY_PARTS:
|
|
|
+ subobjectURL = 'parts/' + subobjectURL;
|
|
|
+ newLocationState = subobject.locationState + 1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LDrawLoader.FILE_LOCATION_TRY_P:
|
|
|
+ subobjectURL = 'p/' + subobjectURL;
|
|
|
+ newLocationState = subobject.locationState + 1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LDrawLoader.FILE_LOCATION_TRY_MODELS:
|
|
|
+ subobjectURL = 'models/' + subobjectURL;
|
|
|
+ newLocationState = subobject.locationState + 1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LDrawLoader.FILE_LOCATION_TRY_RELATIVE:
|
|
|
+ subobjectURL = url.substring( 0, url.lastIndexOf( "/" ) + 1 ) + subobjectURL;
|
|
|
+ newLocationState = subobject.locationState + 1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LDrawLoader.FILE_LOCATION_TRY_ABSOLUTE:
|
|
|
+
|
|
|
+ if ( subobject.triedLowerCase ) {
|
|
|
+
|
|
|
+ // Try absolute path
|
|
|
+ newLocationState = LDrawLoader.FILE_LOCATION_NOT_FOUND;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // Next attempt is lower case
|
|
|
+ subobject.fileName = subobject.fileName.toLowerCase();
|
|
|
+ subobjectURL = subobject.fileName;
|
|
|
+ subobject.triedLowerCase = true;
|
|
|
+ newLocationState = LDrawLoader.FILE_LOCATION_AS_IS;
|
|
|
+
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LDrawLoader.FILE_LOCATION_NOT_FOUND:
|
|
|
+
|
|
|
+ // All location possibilities have been tried, give up loading this object
|
|
|
+ console.warn( 'LDrawLoader: Subobject "' + subobject.originalFileName + '" could not be found.' );
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ subobject.locationState = newLocationState;
|
|
|
+ subobject.url = subobjectURL;
|
|
|
+
|
|
|
+ // Load the subobject
|
|
|
+ // Use another file loader here so we can keep track of the subobject information
|
|
|
+ // and use it when processing the next model.
|
|
|
+ var fileLoader = new THREE.FileLoader( scope.manager );
|
|
|
+ fileLoader.setPath( scope.path );
|
|
|
+ fileLoader.load( subobjectURL, function ( text ) {
|
|
|
+
|
|
|
+ scope.processObject( text, function ( subobjectGroup ) {
|
|
|
+
|
|
|
+ onSubobjectLoaded( subobjectGroup, subobject );
|
|
|
+ onSubobjectFinish();
|
|
|
+
|
|
|
+ }, subobject, url );
|
|
|
+
|
|
|
+ }, undefined, function ( err ) {
|
|
|
+
|
|
|
+ onSubobjectError( err, subobject );
|
|
|
+
|
|
|
+ }, subobject );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function onSubobjectLoaded( subobjectGroup, subobject ) {
|
|
|
+
|
|
|
+ if ( subobjectGroup === null ) {
|
|
|
+
|
|
|
+ // Try to reload
|
|
|
+ loadSubobject( subobject );
|
|
|
+ return;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ scope.fileMap[ subobject.originalFileName ] = subobject.url;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function onSubobjectError( err, subobject ) {
|
|
|
+
|
|
|
+ // Retry download from a different default possible location
|
|
|
+ loadSubobject( subobject );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
};
|