Skip to content

Commit

Permalink
LDrawLoader: 2 bugs and 7 improvements (mrdoob#24257)
Browse files Browse the repository at this point in the history
* 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()
  • Loading branch information
yomboprime authored and abernier committed Sep 16, 2022
1 parent bbed6fd commit 947092f
Showing 1 changed file with 136 additions and 74 deletions.
210 changes: 136 additions & 74 deletions examples/jsm/loaders/LDrawLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const FINISH_TYPE_METAL = 5;

// State machine to search a subobject path.
// The LDraw standard establishes these various possible subfolders.
const FILE_LOCATION_AS_IS = 0;
const FILE_LOCATION_TRY_PARTS = 1;
const FILE_LOCATION_TRY_P = 2;
const FILE_LOCATION_TRY_MODELS = 3;
const FILE_LOCATION_TRY_PARTS = 0;
const FILE_LOCATION_TRY_P = 1;
const FILE_LOCATION_TRY_MODELS = 2;
const FILE_LOCATION_AS_IS = 3;
const FILE_LOCATION_TRY_RELATIVE = 4;
const FILE_LOCATION_TRY_ABSOLUTE = 5;
const FILE_LOCATION_NOT_FOUND = 6;
Expand Down Expand Up @@ -688,7 +688,9 @@ class LDrawParsedCache {
result.type = original.type;
result.category = original.category;
result.keywords = original.keywords;
result.author = original.author;
result.subobjects = original.subobjects;
result.fileName = original.fileName;
result.totalFaces = original.totalFaces;
result.startingConstructionStep = original.startingConstructionStep;
result.materials = original.materials;
Expand All @@ -700,7 +702,7 @@ class LDrawParsedCache {
async fetchData( fileName ) {

let triedLowerCase = false;
let locationState = FILE_LOCATION_AS_IS;
let locationState = FILE_LOCATION_TRY_PARTS;
while ( locationState !== FILE_LOCATION_NOT_FOUND ) {

let subobjectURL = fileName;
Expand Down Expand Up @@ -743,7 +745,7 @@ class LDrawParsedCache {
fileName = fileName.toLowerCase();
subobjectURL = fileName;
triedLowerCase = true;
locationState = FILE_LOCATION_AS_IS;
locationState = FILE_LOCATION_TRY_PARTS;

}

Expand Down Expand Up @@ -794,6 +796,7 @@ class LDrawParsedCache {
let type = 'Model';
let category = null;
let keywords = null;
let author = null;
let totalFaces = 0;

// split into lines
Expand Down Expand Up @@ -995,6 +998,12 @@ class LDrawParsedCache {

break;

case 'Author:':

author = lp.getToken();

break;

default:
// Other meta directives are not implemented
break;
Expand Down Expand Up @@ -1221,6 +1230,7 @@ class LDrawParsedCache {
type,
category,
keywords,
author,
subobjects,
totalFaces,
startingConstructionStep,
Expand Down Expand Up @@ -1356,6 +1366,9 @@ class LDrawPartsGeometryCache {
const group = new Group();
group.userData.category = info.category;
group.userData.keywords = info.keywords;
group.userData.author = info.author;
group.userData.type = info.type;
group.userData.fileName = info.fileName;
info.group = group;

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

loader.applyMaterialsToMesh( subobjectGroup, subobject.colorCode, info.materials );
subobjectGroup.userData.colorCode = subobject.colorCode;

group.add( subobjectGroup );
continue;
Expand Down Expand Up @@ -1473,6 +1487,7 @@ class LDrawPartsGeometryCache {
if ( subobject ) {

loader.applyMaterialsToMesh( group, subobject.colorCode, info.materials );
group.userData.colorCode = subobject.colorCode;

}

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

// Material assigned to not available colors for meshes and edges
this.missingColorMaterial = new MeshStandardMaterial( { color: 0xFF00FF, roughness: 0.3, metalness: 0 } );
this.missingColorMaterial.name = 'Missing material';
this.missingEdgeColorMaterial = new LineBasicMaterial( { color: 0xFF00FF } );
this.missingEdgeColorMaterial.name = 'Missing material - Edge';
this.missingConditionalEdgeColorMaterial = new LDrawConditionalLineMaterial( { fog: true, color: 0xFF00FF } );
this.missingConditionalEdgeColorMaterial.name = 'Missing material - Conditional Edge';
this.missingColorMaterial.userData.edgeMaterial = this.missingEdgeColorMaterial;
this.missingEdgeColorMaterial.userData.conditionalEdgeMaterial = this.missingConditionalEdgeColorMaterial;

}

setPartsLibraryPath( path ) {
Expand Down Expand Up @@ -1934,6 +1959,7 @@ class LDrawLoader extends Loader {

this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true );
this.computeConstructionSteps( group );
group.userData.fileName = url;
onLoad( group );

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

this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true );
this.computeConstructionSteps( group );
group.userData.fileName = '';
onLoad( group );

} );
Expand Down Expand Up @@ -2080,8 +2108,11 @@ class LDrawLoader extends Loader {
material = loader.getMaterial( colorCode );
if ( material === null ) {

// otherwise throw an error if this is final opportunity to set the material
throw new Error( `LDrawLoader: Material properties for code ${ colorCode } not available.` );
// otherwise throw a warning if this is final opportunity to set the material
console.warn( `LDrawLoader: Material properties for code ${ colorCode } not available.` );

// And return the 'missing color' material
material = loader.missingColorMaterial;

}

Expand Down Expand Up @@ -2118,8 +2149,8 @@ class LDrawLoader extends Loader {

getMainEdgeMaterial() {

const mainMat = this.getMainMaterial();
return mainMat && mainMat.userData ? mainMat.userData.edgeMaterial : null;
const mat = this.getMaterial( MAIN_EDGE_COLOUR_CODE );
return mat ? mat.userData.edgeMaterial : null;

}

Expand Down Expand Up @@ -2162,113 +2193,113 @@ class LDrawLoader extends Loader {

}

switch ( token.toUpperCase() ) {
if ( ! parseLuminance( token ) ) {

case 'CODE':
switch ( token.toUpperCase() ) {

code = lineParser.getToken();
break;
case 'CODE':

case 'VALUE':
code = lineParser.getToken();
break;

color = lineParser.getToken();
if ( color.startsWith( '0x' ) ) {
case 'VALUE':

color = '#' + color.substring( 2 );
color = lineParser.getToken();
if ( color.startsWith( '0x' ) ) {

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

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

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

break;
}

case 'EDGE':
break;

edgeColor = lineParser.getToken();
if ( edgeColor.startsWith( '0x' ) ) {
case 'EDGE':

edgeColor = '#' + edgeColor.substring( 2 );
edgeColor = lineParser.getToken();
if ( edgeColor.startsWith( '0x' ) ) {

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

// Try to see if edge color is a color code
edgeMaterial = this.getMaterial( edgeColor );
if ( ! edgeMaterial ) {
} else if ( ! edgeColor.startsWith( '#' ) ) {

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

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

// Get the edge material for this triangle material
edgeMaterial = edgeMaterial.userData.edgeMaterial;
}

}
// Get the edge material for this triangle material
edgeMaterial = edgeMaterial.userData.edgeMaterial;

break;
}

case 'ALPHA':
break;

alpha = parseInt( lineParser.getToken() );
case 'ALPHA':

if ( isNaN( alpha ) ) {
alpha = parseInt( lineParser.getToken() );

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

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

alpha = Math.max( 0, Math.min( 1, alpha / 255 ) );
}

if ( alpha < 1 ) {
alpha = Math.max( 0, Math.min( 1, alpha / 255 ) );

isTransparent = true;
if ( alpha < 1 ) {

}
isTransparent = true;

break;
}

case 'LUMINANCE':
break;

luminance = parseInt( lineParser.getToken() );
case 'LUMINANCE':

if ( isNaN( luminance ) ) {
if ( ! parseLuminance( lineParser.getToken() ) ) {

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

}
}

luminance = Math.max( 0, Math.min( 1, luminance / 255 ) );
break;

break;
case 'CHROME':
finishType = FINISH_TYPE_CHROME;
break;

case 'CHROME':
finishType = FINISH_TYPE_CHROME;
break;
case 'PEARLESCENT':
finishType = FINISH_TYPE_PEARLESCENT;
break;

case 'PEARLESCENT':
finishType = FINISH_TYPE_PEARLESCENT;
break;
case 'RUBBER':
finishType = FINISH_TYPE_RUBBER;
break;

case 'RUBBER':
finishType = FINISH_TYPE_RUBBER;
break;
case 'MATTE_METALLIC':
finishType = FINISH_TYPE_MATTE_METALLIC;
break;

case 'MATTE_METALLIC':
finishType = FINISH_TYPE_MATTE_METALLIC;
break;
case 'METAL':
finishType = FINISH_TYPE_METAL;
break;

case 'METAL':
finishType = FINISH_TYPE_METAL;
break;
case 'MATERIAL':
// Not implemented
lineParser.setToEnd();
break;

case 'MATERIAL':
// Not implemented
lineParser.setToEnd();
break;
default:
throw new Error( 'LDrawLoader: Unknown token "' + token + '" while parsing material' + lineParser.getLineNumberString() + '.' );

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

}

Expand Down Expand Up @@ -2358,6 +2389,8 @@ class LDrawLoader extends Loader {

} );
edgeMaterial.userData.conditionalEdgeMaterial.color.convertSRGBToLinear();
edgeMaterial.userData.conditionalEdgeMaterial.userData.code = code;
edgeMaterial.userData.conditionalEdgeMaterial.name = name + ' - Conditional Edge';

}

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

return material;

function parseLuminance( token ) {

// Returns success

let lum;

if ( token.startsWith( 'LUMINANCE' ) ) {

lum = parseInt( token.substring( 9 ) );

}
else {

lum = parseInt( token );

}

if ( isNaN( lum ) ) {

return false;

}

luminance = Math.max( 0, Math.min( 1, lum / 255 ) );

return true;

}

}

computeConstructionSteps( model ) {
Expand Down

0 comments on commit 947092f

Please sign in to comment.