Skip to content

Commit 5c6990e

Browse files
authored
LDrawLoader: 2 bugs and 7 improvements (#24257)
* LDrawLoader: 2 bugs and 7 improvements * Fix typo * Don't clone missing pink material. LUMINANCE token single quotes * Small variable optimization * Make missing material generic * Make missing material generic, fix * Add missing line which sets userData.fileName * Fix returned edge material in getMainEdgeMaterial() * Just added a small check to getMainEdgeMaterial()
1 parent 8632512 commit 5c6990e

File tree

1 file changed

+136
-74
lines changed

1 file changed

+136
-74
lines changed

examples/jsm/loaders/LDrawLoader.js

+136-74
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ const FINISH_TYPE_METAL = 5;
2828

2929
// State machine to search a subobject path.
3030
// The LDraw standard establishes these various possible subfolders.
31-
const FILE_LOCATION_AS_IS = 0;
32-
const FILE_LOCATION_TRY_PARTS = 1;
33-
const FILE_LOCATION_TRY_P = 2;
34-
const FILE_LOCATION_TRY_MODELS = 3;
31+
const FILE_LOCATION_TRY_PARTS = 0;
32+
const FILE_LOCATION_TRY_P = 1;
33+
const FILE_LOCATION_TRY_MODELS = 2;
34+
const FILE_LOCATION_AS_IS = 3;
3535
const FILE_LOCATION_TRY_RELATIVE = 4;
3636
const FILE_LOCATION_TRY_ABSOLUTE = 5;
3737
const FILE_LOCATION_NOT_FOUND = 6;
@@ -688,7 +688,9 @@ class LDrawParsedCache {
688688
result.type = original.type;
689689
result.category = original.category;
690690
result.keywords = original.keywords;
691+
result.author = original.author;
691692
result.subobjects = original.subobjects;
693+
result.fileName = original.fileName;
692694
result.totalFaces = original.totalFaces;
693695
result.startingConstructionStep = original.startingConstructionStep;
694696
result.materials = original.materials;
@@ -700,7 +702,7 @@ class LDrawParsedCache {
700702
async fetchData( fileName ) {
701703

702704
let triedLowerCase = false;
703-
let locationState = FILE_LOCATION_AS_IS;
705+
let locationState = FILE_LOCATION_TRY_PARTS;
704706
while ( locationState !== FILE_LOCATION_NOT_FOUND ) {
705707

706708
let subobjectURL = fileName;
@@ -743,7 +745,7 @@ class LDrawParsedCache {
743745
fileName = fileName.toLowerCase();
744746
subobjectURL = fileName;
745747
triedLowerCase = true;
746-
locationState = FILE_LOCATION_AS_IS;
748+
locationState = FILE_LOCATION_TRY_PARTS;
747749

748750
}
749751

@@ -794,6 +796,7 @@ class LDrawParsedCache {
794796
let type = 'Model';
795797
let category = null;
796798
let keywords = null;
799+
let author = null;
797800
let totalFaces = 0;
798801

799802
// split into lines
@@ -995,6 +998,12 @@ class LDrawParsedCache {
995998

996999
break;
9971000

1001+
case 'Author:':
1002+
1003+
author = lp.getToken();
1004+
1005+
break;
1006+
9981007
default:
9991008
// Other meta directives are not implemented
10001009
break;
@@ -1221,6 +1230,7 @@ class LDrawParsedCache {
12211230
type,
12221231
category,
12231232
keywords,
1233+
author,
12241234
subobjects,
12251235
totalFaces,
12261236
startingConstructionStep,
@@ -1356,6 +1366,9 @@ class LDrawPartsGeometryCache {
13561366
const group = new Group();
13571367
group.userData.category = info.category;
13581368
group.userData.keywords = info.keywords;
1369+
group.userData.author = info.author;
1370+
group.userData.type = info.type;
1371+
group.userData.fileName = info.fileName;
13591372
info.group = group;
13601373

13611374
const subobjectInfos = await Promise.all( promises );
@@ -1380,6 +1393,7 @@ class LDrawPartsGeometryCache {
13801393
subobjectGroup.name = subobject.fileName;
13811394

13821395
loader.applyMaterialsToMesh( subobjectGroup, subobject.colorCode, info.materials );
1396+
subobjectGroup.userData.colorCode = subobject.colorCode;
13831397

13841398
group.add( subobjectGroup );
13851399
continue;
@@ -1473,6 +1487,7 @@ class LDrawPartsGeometryCache {
14731487
if ( subobject ) {
14741488

14751489
loader.applyMaterialsToMesh( group, subobject.colorCode, info.materials );
1490+
group.userData.colorCode = subobject.colorCode;
14761491

14771492
}
14781493

@@ -1883,6 +1898,16 @@ class LDrawLoader extends Loader {
18831898
// The path to load parts from the LDraw parts library from.
18841899
this.partsLibraryPath = '';
18851900

1901+
// Material assigned to not available colors for meshes and edges
1902+
this.missingColorMaterial = new MeshStandardMaterial( { color: 0xFF00FF, roughness: 0.3, metalness: 0 } );
1903+
this.missingColorMaterial.name = 'Missing material';
1904+
this.missingEdgeColorMaterial = new LineBasicMaterial( { color: 0xFF00FF } );
1905+
this.missingEdgeColorMaterial.name = 'Missing material - Edge';
1906+
this.missingConditionalEdgeColorMaterial = new LDrawConditionalLineMaterial( { fog: true, color: 0xFF00FF } );
1907+
this.missingConditionalEdgeColorMaterial.name = 'Missing material - Conditional Edge';
1908+
this.missingColorMaterial.userData.edgeMaterial = this.missingEdgeColorMaterial;
1909+
this.missingEdgeColorMaterial.userData.conditionalEdgeMaterial = this.missingConditionalEdgeColorMaterial;
1910+
18861911
}
18871912

18881913
setPartsLibraryPath( path ) {
@@ -1934,6 +1959,7 @@ class LDrawLoader extends Loader {
19341959

19351960
this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true );
19361961
this.computeConstructionSteps( group );
1962+
group.userData.fileName = url;
19371963
onLoad( group );
19381964

19391965
} )
@@ -1949,7 +1975,9 @@ class LDrawLoader extends Loader {
19491975
.parseModel( text, this.materialLibrary )
19501976
.then( group => {
19511977

1978+
this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true );
19521979
this.computeConstructionSteps( group );
1980+
group.userData.fileName = '';
19531981
onLoad( group );
19541982

19551983
} );
@@ -2080,8 +2108,11 @@ class LDrawLoader extends Loader {
20802108
material = loader.getMaterial( colorCode );
20812109
if ( material === null ) {
20822110

2083-
// otherwise throw an error if this is final opportunity to set the material
2084-
throw new Error( `LDrawLoader: Material properties for code ${ colorCode } not available.` );
2111+
// otherwise throw a warning if this is final opportunity to set the material
2112+
console.warn( `LDrawLoader: Material properties for code ${ colorCode } not available.` );
2113+
2114+
// And return the 'missing color' material
2115+
material = loader.missingColorMaterial;
20852116

20862117
}
20872118

@@ -2118,8 +2149,8 @@ class LDrawLoader extends Loader {
21182149

21192150
getMainEdgeMaterial() {
21202151

2121-
const mainMat = this.getMainMaterial();
2122-
return mainMat && mainMat.userData ? mainMat.userData.edgeMaterial : null;
2152+
const mat = this.getMaterial( MAIN_EDGE_COLOUR_CODE );
2153+
return mat ? mat.userData.edgeMaterial : null;
21232154

21242155
}
21252156

@@ -2162,113 +2193,113 @@ class LDrawLoader extends Loader {
21622193

21632194
}
21642195

2165-
switch ( token.toUpperCase() ) {
2196+
if ( ! parseLuminance( token ) ) {
21662197

2167-
case 'CODE':
2198+
switch ( token.toUpperCase() ) {
21682199

2169-
code = lineParser.getToken();
2170-
break;
2200+
case 'CODE':
21712201

2172-
case 'VALUE':
2202+
code = lineParser.getToken();
2203+
break;
21732204

2174-
color = lineParser.getToken();
2175-
if ( color.startsWith( '0x' ) ) {
2205+
case 'VALUE':
21762206

2177-
color = '#' + color.substring( 2 );
2207+
color = lineParser.getToken();
2208+
if ( color.startsWith( '0x' ) ) {
21782209

2179-
} else if ( ! color.startsWith( '#' ) ) {
2210+
color = '#' + color.substring( 2 );
21802211

2181-
throw new Error( 'LDrawLoader: Invalid color while parsing material' + lineParser.getLineNumberString() + '.' );
2212+
} else if ( ! color.startsWith( '#' ) ) {
21822213

2183-
}
2214+
throw new Error( 'LDrawLoader: Invalid color while parsing material' + lineParser.getLineNumberString() + '.' );
21842215

2185-
break;
2216+
}
21862217

2187-
case 'EDGE':
2218+
break;
21882219

2189-
edgeColor = lineParser.getToken();
2190-
if ( edgeColor.startsWith( '0x' ) ) {
2220+
case 'EDGE':
21912221

2192-
edgeColor = '#' + edgeColor.substring( 2 );
2222+
edgeColor = lineParser.getToken();
2223+
if ( edgeColor.startsWith( '0x' ) ) {
21932224

2194-
} else if ( ! edgeColor.startsWith( '#' ) ) {
2225+
edgeColor = '#' + edgeColor.substring( 2 );
21952226

2196-
// Try to see if edge color is a color code
2197-
edgeMaterial = this.getMaterial( edgeColor );
2198-
if ( ! edgeMaterial ) {
2227+
} else if ( ! edgeColor.startsWith( '#' ) ) {
21992228

2200-
throw new Error( 'LDrawLoader: Invalid edge color while parsing material' + lineParser.getLineNumberString() + '.' );
2229+
// Try to see if edge color is a color code
2230+
edgeMaterial = this.getMaterial( edgeColor );
2231+
if ( ! edgeMaterial ) {
22012232

2202-
}
2233+
throw new Error( 'LDrawLoader: Invalid edge color while parsing material' + lineParser.getLineNumberString() + '.' );
22032234

2204-
// Get the edge material for this triangle material
2205-
edgeMaterial = edgeMaterial.userData.edgeMaterial;
2235+
}
22062236

2207-
}
2237+
// Get the edge material for this triangle material
2238+
edgeMaterial = edgeMaterial.userData.edgeMaterial;
22082239

2209-
break;
2240+
}
22102241

2211-
case 'ALPHA':
2242+
break;
22122243

2213-
alpha = parseInt( lineParser.getToken() );
2244+
case 'ALPHA':
22142245

2215-
if ( isNaN( alpha ) ) {
2246+
alpha = parseInt( lineParser.getToken() );
22162247

2217-
throw new Error( 'LDrawLoader: Invalid alpha value in material definition' + lineParser.getLineNumberString() + '.' );
2248+
if ( isNaN( alpha ) ) {
22182249

2219-
}
2250+
throw new Error( 'LDrawLoader: Invalid alpha value in material definition' + lineParser.getLineNumberString() + '.' );
22202251

2221-
alpha = Math.max( 0, Math.min( 1, alpha / 255 ) );
2252+
}
22222253

2223-
if ( alpha < 1 ) {
2254+
alpha = Math.max( 0, Math.min( 1, alpha / 255 ) );
22242255

2225-
isTransparent = true;
2256+
if ( alpha < 1 ) {
22262257

2227-
}
2258+
isTransparent = true;
22282259

2229-
break;
2260+
}
22302261

2231-
case 'LUMINANCE':
2262+
break;
22322263

2233-
luminance = parseInt( lineParser.getToken() );
2264+
case 'LUMINANCE':
22342265

2235-
if ( isNaN( luminance ) ) {
2266+
if ( ! parseLuminance( lineParser.getToken() ) ) {
22362267

2237-
throw new Error( 'LDrawLoader: Invalid luminance value in material definition' + LineParser.getLineNumberString() + '.' );
2268+
throw new Error( 'LDrawLoader: Invalid luminance value in material definition' + LineParser.getLineNumberString() + '.' );
22382269

2239-
}
2270+
}
22402271

2241-
luminance = Math.max( 0, Math.min( 1, luminance / 255 ) );
2272+
break;
22422273

2243-
break;
2274+
case 'CHROME':
2275+
finishType = FINISH_TYPE_CHROME;
2276+
break;
22442277

2245-
case 'CHROME':
2246-
finishType = FINISH_TYPE_CHROME;
2247-
break;
2278+
case 'PEARLESCENT':
2279+
finishType = FINISH_TYPE_PEARLESCENT;
2280+
break;
22482281

2249-
case 'PEARLESCENT':
2250-
finishType = FINISH_TYPE_PEARLESCENT;
2251-
break;
2282+
case 'RUBBER':
2283+
finishType = FINISH_TYPE_RUBBER;
2284+
break;
22522285

2253-
case 'RUBBER':
2254-
finishType = FINISH_TYPE_RUBBER;
2255-
break;
2286+
case 'MATTE_METALLIC':
2287+
finishType = FINISH_TYPE_MATTE_METALLIC;
2288+
break;
22562289

2257-
case 'MATTE_METALLIC':
2258-
finishType = FINISH_TYPE_MATTE_METALLIC;
2259-
break;
2290+
case 'METAL':
2291+
finishType = FINISH_TYPE_METAL;
2292+
break;
22602293

2261-
case 'METAL':
2262-
finishType = FINISH_TYPE_METAL;
2263-
break;
2294+
case 'MATERIAL':
2295+
// Not implemented
2296+
lineParser.setToEnd();
2297+
break;
22642298

2265-
case 'MATERIAL':
2266-
// Not implemented
2267-
lineParser.setToEnd();
2268-
break;
2299+
default:
2300+
throw new Error( 'LDrawLoader: Unknown token "' + token + '" while parsing material' + lineParser.getLineNumberString() + '.' );
22692301

2270-
default:
2271-
throw new Error( 'LDrawLoader: Unknown token "' + token + '" while parsing material' + lineParser.getLineNumberString() + '.' );
2302+
}
22722303

22732304
}
22742305

@@ -2358,6 +2389,8 @@ class LDrawLoader extends Loader {
23582389

23592390
} );
23602391
edgeMaterial.userData.conditionalEdgeMaterial.color.convertSRGBToLinear();
2392+
edgeMaterial.userData.conditionalEdgeMaterial.userData.code = code;
2393+
edgeMaterial.userData.conditionalEdgeMaterial.name = name + ' - Conditional Edge';
23612394

23622395
}
23632396

@@ -2370,6 +2403,35 @@ class LDrawLoader extends Loader {
23702403

23712404
return material;
23722405

2406+
function parseLuminance( token ) {
2407+
2408+
// Returns success
2409+
2410+
let lum;
2411+
2412+
if ( token.startsWith( 'LUMINANCE' ) ) {
2413+
2414+
lum = parseInt( token.substring( 9 ) );
2415+
2416+
}
2417+
else {
2418+
2419+
lum = parseInt( token );
2420+
2421+
}
2422+
2423+
if ( isNaN( lum ) ) {
2424+
2425+
return false;
2426+
2427+
}
2428+
2429+
luminance = Math.max( 0, Math.min( 1, lum / 255 ) );
2430+
2431+
return true;
2432+
2433+
}
2434+
23732435
}
23742436

23752437
computeConstructionSteps( model ) {

0 commit comments

Comments
 (0)