|
@@ -271,18 +271,6 @@ THREE.LDrawLoader = ( function () {
|
|
|
|
|
|
}, onProgress, onError );
|
|
}, onProgress, onError );
|
|
|
|
|
|
- function subobjectLoad( url, onLoad, onProgress, onError, subobject ) {
|
|
|
|
-
|
|
|
|
- var fileLoader = new THREE.FileLoader( scope.manager );
|
|
|
|
- fileLoader.setPath( scope.path );
|
|
|
|
- fileLoader.load( url, function ( text ) {
|
|
|
|
-
|
|
|
|
- processObject( text, onLoad, subobject );
|
|
|
|
-
|
|
|
|
- }, onProgress, onError );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
function processObject( text, onProcessed, subobject ) {
|
|
function processObject( text, onProcessed, subobject ) {
|
|
|
|
|
|
var parseScope = scope.newParseScopeLevel();
|
|
var parseScope = scope.newParseScopeLevel();
|
|
@@ -292,6 +280,12 @@ THREE.LDrawLoader = ( function () {
|
|
|
|
|
|
// Add to cache
|
|
// Add to cache
|
|
var currentFileName = parentParseScope.currentFileName;
|
|
var currentFileName = parentParseScope.currentFileName;
|
|
|
|
+ if ( currentFileName !== null ) {
|
|
|
|
+
|
|
|
|
+ currentFileName = parentParseScope.currentFileName.toLowerCase();
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
if ( scope.subobjectCache[ currentFileName ] === undefined ) {
|
|
if ( scope.subobjectCache[ currentFileName ] === undefined ) {
|
|
|
|
|
|
scope.subobjectCache[ currentFileName ] = text;
|
|
scope.subobjectCache[ currentFileName ] = text;
|
|
@@ -308,37 +302,39 @@ THREE.LDrawLoader = ( function () {
|
|
parseScope.numSubobjects = parseScope.subobjects.length;
|
|
parseScope.numSubobjects = parseScope.subobjects.length;
|
|
parseScope.subobjectIndex = 0;
|
|
parseScope.subobjectIndex = 0;
|
|
|
|
|
|
- if ( parseScope.numSubobjects > 0 ) {
|
|
|
|
|
|
+ var finishedCount = 0;
|
|
|
|
+ onSubobjectFinish();
|
|
|
|
|
|
- // Load the first subobject
|
|
|
|
- var subobjectGroup = loadSubobject( parseScope.subobjects[ 0 ], true );
|
|
|
|
|
|
+ return objGroup;
|
|
|
|
|
|
- // Optimization for loading pack: If subobjects are obtained from cache, keep loading them iteratively rather than recursively
|
|
|
|
- if ( subobjectGroup ) {
|
|
|
|
|
|
+ function onSubobjectFinish() {
|
|
|
|
|
|
- while ( subobjectGroup && parseScope.subobjectIndex < parseScope.numSubobjects - 1 ) {
|
|
|
|
|
|
+ finishedCount ++;
|
|
|
|
|
|
- subobjectGroup = loadSubobject( parseScope.subobjects[ ++ parseScope.subobjectIndex ], true );
|
|
|
|
|
|
+ if ( finishedCount === parseScope.subobjects.length + 1 ) {
|
|
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( subobjectGroup ) {
|
|
|
|
|
|
+ finalizeObject();
|
|
|
|
|
|
- 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 );
|
|
|
|
|
|
- } else {
|
|
|
|
|
|
+ } );
|
|
|
|
+ parseScope.subobjectIndex ++;
|
|
|
|
|
|
- // No subobjects, finish object
|
|
|
|
- finalizeObject();
|
|
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- return objGroup;
|
|
|
|
-
|
|
|
|
function finalizeObject() {
|
|
function finalizeObject() {
|
|
|
|
|
|
if ( ! scope.separateObjects && ! parentParseScope.isFromParse ) {
|
|
if ( ! scope.separateObjects && ! parentParseScope.isFromParse ) {
|
|
@@ -368,7 +364,7 @@ THREE.LDrawLoader = ( function () {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- function loadSubobject( subobject, sync ) {
|
|
|
|
|
|
+ function loadSubobject( subobject ) {
|
|
|
|
|
|
parseScope.mainColourCode = subobject.material.userData.code;
|
|
parseScope.mainColourCode = subobject.material.userData.code;
|
|
parseScope.mainEdgeColourCode = subobject.material.userData.edgeMaterial.userData.code;
|
|
parseScope.mainEdgeColourCode = subobject.material.userData.edgeMaterial.userData.code;
|
|
@@ -382,16 +378,15 @@ THREE.LDrawLoader = ( function () {
|
|
}
|
|
}
|
|
|
|
|
|
// If subobject was cached previously, use the cached one
|
|
// If subobject was cached previously, use the cached one
|
|
- var cached = scope.subobjectCache[ subobject.originalFileName ];
|
|
|
|
|
|
+ var cached = scope.subobjectCache[ subobject.originalFileName.toLowerCase() ];
|
|
if ( cached ) {
|
|
if ( cached ) {
|
|
|
|
|
|
- var subobjectGroup = processObject( cached, sync ? undefined : onSubobjectLoaded, subobject );
|
|
|
|
- if ( sync ) {
|
|
|
|
|
|
+ processObject( cached, function ( subobjectGroup ) {
|
|
|
|
|
|
- addSubobject( subobject, subobjectGroup );
|
|
|
|
- return subobjectGroup;
|
|
|
|
|
|
+ onSubobjectLoaded( subobjectGroup, subobject );
|
|
|
|
+ onSubobjectFinish();
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }, subobject );
|
|
|
|
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -451,22 +446,6 @@ THREE.LDrawLoader = ( function () {
|
|
// All location possibilities have been tried, give up loading this object
|
|
// All location possibilities have been tried, give up loading this object
|
|
console.warn( 'LDrawLoader: Subobject "' + subobject.originalFileName + '" could not be found.' );
|
|
console.warn( 'LDrawLoader: Subobject "' + subobject.originalFileName + '" could not be found.' );
|
|
|
|
|
|
- // Try to read the next subobject
|
|
|
|
- parseScope.subobjectIndex ++;
|
|
|
|
-
|
|
|
|
- if ( parseScope.subobjectIndex >= parseScope.numSubobjects ) {
|
|
|
|
-
|
|
|
|
- // All subojects have been loaded. Finish parent object
|
|
|
|
- scope.removeScopeLevel();
|
|
|
|
- onProcessed( objGroup );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- // Load next subobject
|
|
|
|
- loadSubobject( parseScope.subobjects[ parseScope.subobjectIndex ] );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return;
|
|
return;
|
|
|
|
|
|
}
|
|
}
|
|
@@ -481,15 +460,22 @@ THREE.LDrawLoader = ( function () {
|
|
fileLoader.setPath( scope.path );
|
|
fileLoader.setPath( scope.path );
|
|
fileLoader.load( subobjectURL, function ( text ) {
|
|
fileLoader.load( subobjectURL, function ( text ) {
|
|
|
|
|
|
- processObject( text, onSubobjectLoaded, subobject );
|
|
|
|
|
|
+ processObject( text, function ( subobjectGroup ) {
|
|
|
|
|
|
- }, undefined, onSubobjectError );
|
|
|
|
|
|
+ onSubobjectLoaded( subobjectGroup, subobject );
|
|
|
|
+ onSubobjectFinish();
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }, subobject );
|
|
|
|
+
|
|
|
|
+ }, undefined, function ( err ) {
|
|
|
|
+
|
|
|
|
+ onSubobjectError( err, subobject );
|
|
|
|
+
|
|
|
|
+ }, subobject );
|
|
|
|
|
|
- function onSubobjectLoaded( subobjectGroup ) {
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- var subobject = parseScope.subobjects[ parseScope.subobjectIndex ];
|
|
|
|
|
|
+ function onSubobjectLoaded( subobjectGroup, subobject ) {
|
|
|
|
|
|
if ( subobjectGroup === null ) {
|
|
if ( subobjectGroup === null ) {
|
|
|
|
|
|
@@ -502,20 +488,6 @@ THREE.LDrawLoader = ( function () {
|
|
// Add the subobject just loaded
|
|
// Add the subobject just loaded
|
|
addSubobject( subobject, subobjectGroup );
|
|
addSubobject( subobject, subobjectGroup );
|
|
|
|
|
|
- // Proceed to load the next subobject, or finish the parent object
|
|
|
|
-
|
|
|
|
- parseScope.subobjectIndex ++;
|
|
|
|
-
|
|
|
|
- if ( parseScope.subobjectIndex < parseScope.numSubobjects ) {
|
|
|
|
-
|
|
|
|
- loadSubobject( parseScope.subobjects[ parseScope.subobjectIndex ] );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- finalizeObject();
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
function addSubobject( subobject, subobjectGroup ) {
|
|
function addSubobject( subobject, subobjectGroup ) {
|
|
@@ -533,10 +505,10 @@ THREE.LDrawLoader = ( function () {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- function onSubobjectError( err ) {
|
|
|
|
|
|
+ function onSubobjectError( err, subobject ) {
|
|
|
|
|
|
// Retry download from a different default possible location
|
|
// Retry download from a different default possible location
|
|
- loadSubobject( parseScope.subobjects[ parseScope.subobjectIndex ] );
|
|
|
|
|
|
+ loadSubobject( subobject );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1071,7 +1043,7 @@ THREE.LDrawLoader = ( function () {
|
|
if ( line.startsWith( '0 FILE ' ) ) {
|
|
if ( line.startsWith( '0 FILE ' ) ) {
|
|
|
|
|
|
// Save previous embedded file in the cache
|
|
// Save previous embedded file in the cache
|
|
- this.subobjectCache[ currentEmbeddedFileName ] = currentEmbeddedText;
|
|
|
|
|
|
+ this.subobjectCache[ currentEmbeddedFileName.toLowerCase() ] = currentEmbeddedText;
|
|
|
|
|
|
// New embedded text file
|
|
// New embedded text file
|
|
currentEmbeddedFileName = line.substring( 7 );
|
|
currentEmbeddedFileName = line.substring( 7 );
|
|
@@ -1436,7 +1408,7 @@ THREE.LDrawLoader = ( function () {
|
|
|
|
|
|
if ( parsingEmbeddedFiles ) {
|
|
if ( parsingEmbeddedFiles ) {
|
|
|
|
|
|
- this.subobjectCache[ currentEmbeddedFileName ] = currentEmbeddedText;
|
|
|
|
|
|
+ this.subobjectCache[ currentEmbeddedFileName.toLowerCase() ] = currentEmbeddedText;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|