11/**
22 * @author mrdoob / http://mrdoob.com/
33 * @author yomboprime / https://github.com/yomboprime/
4- *
5- *
4+ *
5+ *
66 */
77
88THREE . LDrawLoader = ( function ( ) {
99
1010 function LineParser ( line , lineNumber ) {
11-
11+
1212 this . line = line ;
1313 this . lineLength = line . length ;
1414 this . currentCharIndex = 0 ;
1515 this . currentChar = ' ' ;
1616 this . lineNumber = lineNumber ;
17-
17+
1818 }
1919
2020 LineParser . prototype = {
@@ -26,7 +26,7 @@ THREE.LDrawLoader = ( function () {
2626 while ( this . currentCharIndex < this . lineLength ) {
2727
2828 this . currentChar = this . line . charAt ( this . currentCharIndex ) ;
29-
29+
3030 if ( this . currentChar !== ' ' && this . currentChar !== '\t' ) {
3131
3232 return ;
@@ -59,7 +59,7 @@ THREE.LDrawLoader = ( function () {
5959 }
6060
6161 var pos1 = this . currentCharIndex ;
62-
62+
6363 this . seekNonSpace ( ) ;
6464
6565 return this . line . substring ( pos0 , pos1 ) ;
@@ -85,12 +85,12 @@ THREE.LDrawLoader = ( function () {
8585 } ,
8686
8787 getLineNumberString : function ( ) {
88-
88+
8989 return this . lineNumber >= 0 ? " at line " + this . lineNumber : "" ;
9090
9191 }
9292
93-
93+
9494 } ;
9595
9696 function sortByMaterial ( a , b ) {
@@ -216,7 +216,7 @@ THREE.LDrawLoader = ( function () {
216216 // Temporary matrices
217217 this . tempMatrix180 = new THREE . Matrix4 ( ) . makeRotationX ( Math . PI ) ;
218218 this . tempMatrix = new THREE . Matrix4 ( ) ;
219-
219+
220220
221221 }
222222
@@ -281,18 +281,46 @@ THREE.LDrawLoader = ( function () {
281281
282282 if ( parseScope . numSubobjects > 0 ) {
283283
284- loadSubobject ( parseScope . subobjects [ 0 ] ) ;
284+ // Load the first subobject
285+ var subobjectGroup = loadSubobject ( parseScope . subobjects [ 0 ] , true ) ;
286+
287+ // Optimization for loading pack: If subobjects are obtained from cache, keep loading them iteratively rather than recursively
288+ if ( subobjectGroup ) {
289+
290+ while ( subobjectGroup && parseScope . subobjectIndex < parseScope . numSubobjects - 1 ) {
291+
292+ subobjectGroup = loadSubobject ( parseScope . subobjects [ ++ parseScope . subobjectIndex ] , true ) ;
293+
294+ }
295+
296+ if ( subobjectGroup ) {
297+
298+ scope . removeScopeLevel ( ) ;
299+ if ( onProcessed ) {
300+
301+ onProcessed ( objGroup ) ;
302+
303+ }
304+
305+ }
306+ }
285307
286308 }
287309 else {
288310
289311 // No subobjects, finish object
290312 scope . removeScopeLevel ( ) ;
291- onProcessed ( objGroup ) ;
313+ if ( onProcessed ) {
314+
315+ onProcessed ( objGroup ) ;
316+
317+ }
292318
293319 }
294320
295- function loadSubobject ( subobject ) {
321+ return objGroup ;
322+
323+ function loadSubobject ( subobject , sync ) {
296324
297325 parseScope . mainColourCode = subobject . material . userData . code ;
298326 parseScope . mainEdgeColourCode = subobject . material . userData . edgeMaterial . userData . code ;
@@ -301,9 +329,12 @@ THREE.LDrawLoader = ( function () {
301329 // If subobject was cached previously, use the cached one
302330 var cached = scope . subobjectCache [ subobject . originalFileName ] ;
303331 if ( cached ) {
304- processObject ( cached , onSubobjectLoaded ) ;
332+ var subobjectGroup = processObject ( cached , sync ? undefined : onSubobjectLoaded ) ;
333+ if ( sync ) {
334+ addSubobject ( subobject , subobjectGroup ) ;
335+ return subobjectGroup ;
336+ }
305337 return ;
306-
307338 }
308339
309340 // Adjust file name to locate the subobject file path in standard locations (always under directory scope.path)
@@ -314,7 +345,7 @@ THREE.LDrawLoader = ( function () {
314345 switch ( subobject . locationState ) {
315346
316347 case LDrawLoader . FILE_LOCATION_AS_IS :
317- newLocationState = LDrawLoader . FILE_LOCATION_NOT_FOUND ;
348+ newLocationState = subobject . locationState + 1 ;
318349 break ;
319350
320351 case LDrawLoader . FILE_LOCATION_TRY_PARTS :
@@ -351,7 +382,7 @@ THREE.LDrawLoader = ( function () {
351382 subobject . fileName = subobject . fileName . toLowerCase ( ) ;
352383 subobjectURL = subobject . fileName ;
353384 subobject . triedLowerCase = true ;
354- newLocationState = LDrawLoader . FILE_LOCATION_TRY_PARTS ;
385+ newLocationState = LDrawLoader . FILE_LOCATION_AS_IS ;
355386
356387 }
357388 break ;
@@ -375,15 +406,15 @@ THREE.LDrawLoader = ( function () {
375406
376407 // Load next subobject
377408 loadSubobject ( parseScope . subobjects [ parseScope . subobjectIndex ] ) ;
378-
409+
379410 }
380411
381412 return ;
382413
383414 }
384415
385416 subobject . locationState = newLocationState ;
386- scope . fileMap [ subobject . originalFileName ] = subobjectURL ;
417+ subobject . url = subobjectURL ;
387418
388419 // Load the subobject
389420 scope . load ( subobjectURL , onSubobjectLoaded , undefined , onSubobjectError ) ;
@@ -393,7 +424,7 @@ THREE.LDrawLoader = ( function () {
393424 function onSubobjectLoaded ( subobjectGroup ) {
394425
395426 var subobject = parseScope . subobjects [ parseScope . subobjectIndex ] ;
396-
427+
397428 if ( subobjectGroup === null ) {
398429
399430 // Try to reload
@@ -402,11 +433,8 @@ THREE.LDrawLoader = ( function () {
402433
403434 }
404435
405- // Process the subobject just loaded
406- subobjectGroup . name = subobject . fileName ;
407- objGroup . add ( subobjectGroup ) ;
408- subobjectGroup . matrix . copy ( subobject . matrix ) ;
409- subobjectGroup . matrixAutoUpdate = false ;
436+ // Add the subobject just loaded
437+ addSubobject ( subobject , subobjectGroup ) ;
410438
411439 // Proceed to load the next subobject, or finish the parent object
412440
@@ -426,6 +454,17 @@ THREE.LDrawLoader = ( function () {
426454
427455 }
428456
457+ function addSubobject ( subobject , subobjectGroup ) {
458+
459+ subobjectGroup . name = subobject . fileName ;
460+ objGroup . add ( subobjectGroup ) ;
461+ subobjectGroup . matrix . copy ( subobject . matrix ) ;
462+ subobjectGroup . matrixAutoUpdate = false ;
463+
464+ scope . fileMap [ subobject . originalFileName ] = subobject . url ;
465+
466+ }
467+
429468 function onSubobjectError ( err ) {
430469
431470 // Retry download from a different default possible location
@@ -468,13 +507,13 @@ THREE.LDrawLoader = ( function () {
468507 } ,
469508
470509 newParseScopeLevel : function ( materials ) {
471-
510+
472511 // Adds a new scope level, assign materials to it and returns it
473512
474513 var matLib = { } ;
475514
476515 if ( materials ) {
477-
516+
478517 for ( var i = 0 , n = materials . length ; i < n ; i ++ ) {
479518
480519 var material = materials [ i ] ;
@@ -539,7 +578,7 @@ THREE.LDrawLoader = ( function () {
539578
540579 // Given a colour code search its material in the parse scopes stack
541580
542- if ( colourCode . startsWith ( "0x2" ) ) {
581+ if ( colourCode . startsWith ( "0x2" ) ) {
543582
544583 // Special 'direct' material value (RGB colour)
545584
@@ -592,8 +631,8 @@ THREE.LDrawLoader = ( function () {
592631
593632 parseColourMetaDirective : function ( lineParser ) {
594633
595- // Parses a colour definition and returns a THREE.Material or null if error
596-
634+ // Parses a colour definition and returns a THREE.Material or null if error
635+
597636 var code = null ;
598637
599638 // Triangle and line colours
@@ -670,7 +709,7 @@ THREE.LDrawLoader = ( function () {
670709
671710 // Get the edge material for this triangle material
672711 edgeMaterial = edgeMaterial . userData . edgeMaterial ;
673-
712+
674713 }
675714 break ;
676715
@@ -753,7 +792,7 @@ THREE.LDrawLoader = ( function () {
753792 var hsl = specular . getHSL ( { h : 0 , s : 0 , l : 0 } ) ;
754793
755794 if ( finishType === LDrawLoader . FINISH_TYPE_DEFAULT ) {
756-
795+
757796 // Default plastic material with shiny specular
758797 hsl . l = Math . min ( 1 , hsl . l + ( 1 - hsl . l ) * 0.12 ) ;
759798
@@ -995,7 +1034,7 @@ THREE.LDrawLoader = ( function () {
9951034 keywords = [ ] ;
9961035
9971036 }
998-
1037+
9991038 newKeywords . forEach ( function ( keyword ) {
10001039
10011040 keywords . push ( keyword . trim ( ) ) ;
@@ -1015,7 +1054,7 @@ THREE.LDrawLoader = ( function () {
10151054 currentEmbeddedText = '' ;
10161055
10171056 }
1018-
1057+
10191058 break ;
10201059
10211060 default :
@@ -1055,39 +1094,36 @@ THREE.LDrawLoader = ( function () {
10551094 ) ;
10561095
10571096 var fileName = lp . getRemainingString ( ) . trim ( ) . replace ( "\\" , "/" ) ;
1058- var locationState = LDrawLoader . FILE_LOCATION_TRY_PARTS ;
10591097
10601098 if ( scope . fileMap [ fileName ] ) {
10611099
1062- // Found the subobject path in the preloaded file path map, set the path as "AS_IS"
1100+ // Found the subobject path in the preloaded file path map
10631101 fileName = scope . fileMap [ fileName ] ;
1064- locationState = LDrawLoader . FILE_LOCATION_AS_IS ;
10651102
10661103 }
10671104 else {
10681105
1069- // Standardized subfolders
1106+ // Standardized subfolders
10701107 if ( fileName . startsWith ( 's/' ) ) {
10711108
10721109 fileName = 'parts/' + fileName ;
1073- locationState = LDrawLoader . FILE_LOCATION_AS_IS ;
10741110
10751111 }
10761112 else if ( fileName . startsWith ( '48/' ) ) {
10771113
10781114 fileName = 'p/' + fileName ;
1079- locationState = LDrawLoader . FILE_LOCATION_AS_IS ;
10801115
10811116 }
1082-
1117+
10831118 }
10841119
10851120 subobjects . push ( {
10861121 material : material ,
10871122 matrix : matrix ,
10881123 fileName : fileName ,
10891124 originalFileName : fileName ,
1090- locationState : locationState ,
1125+ locationState : LDrawLoader . FILE_LOCATION_AS_IS ,
1126+ url : null ,
10911127 triedLowerCase : false
10921128 } ) ;
10931129
@@ -1119,7 +1155,7 @@ THREE.LDrawLoader = ( function () {
11191155 v1 : new THREE . Vector3 ( parseFloat ( lp . getToken ( ) ) , parseFloat ( lp . getToken ( ) ) , parseFloat ( lp . getToken ( ) ) ) ,
11201156 v2 : new THREE . Vector3 ( parseFloat ( lp . getToken ( ) ) , parseFloat ( lp . getToken ( ) ) , parseFloat ( lp . getToken ( ) ) )
11211157 } ) ;
1122-
1158+
11231159 break ;
11241160
11251161 // Line type 4: Quadrilateral
@@ -1158,15 +1194,15 @@ THREE.LDrawLoader = ( function () {
11581194 default :
11591195 throw 'LDrawLoader: Unknown line type "' + lineType + '"' + lp . getLineNumberString ( ) + '.' ;
11601196 break ;
1161-
1197+
11621198 }
11631199
11641200 }
11651201
11661202 if ( parsingEmbeddedFiles ) {
11671203
11681204 this . subobjectCache [ currentEmbeddedFileName ] = currentEmbeddedText ;
1169-
1205+
11701206 }
11711207
11721208 //
0 commit comments