浏览代码

LDrawLoader: Start removing stored derivative data during initial parse (#23139)

* generate face normals only as needed

* Remove unused variable

* comment update
Garrett Johnson 3 年之前
父节点
当前提交
5655fbea21
共有 1 个文件被更改,包括 56 次插入36 次删除
  1. 56 36
      examples/jsm/loaders/LDrawLoader.js

+ 56 - 36
examples/jsm/loaders/LDrawLoader.js

@@ -167,6 +167,26 @@ class LDrawConditionalLineMaterial extends ShaderMaterial {
 
 }
 
+function generateFaceNormals( faces ) {
+
+	for ( let i = 0, l = faces.length; i < l; i ++ ) {
+
+		const face = faces[ i ];
+		const vertices = face.vertices;
+		const v0 = vertices[ 0 ];
+		const v1 = vertices[ 1 ];
+		const v2 = vertices[ 2 ];
+
+		_tempVec0.subVectors( v1, v0 );
+		_tempVec1.subVectors( v2, v1 );
+		face.faceNormal = new Vector3()
+			.crossVectors( _tempVec0, _tempVec1 )
+			.normalize();
+
+	}
+
+}
+
 function smoothNormals( faces, lineSegments ) {
 
 	function hashVertex( v ) {
@@ -666,8 +686,22 @@ function createObject( elements, elementSize, isConditionalSegments = false, tot
 
 		}
 
+		// create the normals array if this is a set of faces
 		if ( elementSize === 3 ) {
 
+			if ( ! elem.faceNormal ) {
+
+				const v0 = vertices[ 0 ];
+				const v1 = vertices[ 1 ];
+				const v2 = vertices[ 2 ];
+				_tempVec0.subVectors( v1, v0 );
+				_tempVec1.subVectors( v2, v1 );
+				elem.faceNormal = new Vector3()
+					.crossVectors( _tempVec0, _tempVec1 )
+					.normalize();
+
+			}
+
 			let elemNormals = elem.normals;
 			if ( elemNormals.length === 4 ) {
 
@@ -683,6 +717,7 @@ function createObject( elements, elementSize, isConditionalSegments = false, tot
 
 			for ( let j = 0, l = elemNormals.length; j < l; j ++ ) {
 
+				// use face normal if a vertex normal is not provided
 				let n = elem.faceNormal;
 				if ( elemNormals[ j ] ) {
 
@@ -1321,8 +1356,7 @@ class LDrawLoader extends Loader {
 
 		let startingConstructionStep = false;
 
-		const scope = this;
-		function parseColourCode( lineParser, forEdge ) {
+		const parseColourCode = ( lineParser, forEdge ) => {
 
 			// Parses next colour code and returns a THREE.Material
 
@@ -1340,7 +1374,7 @@ class LDrawLoader extends Loader {
 
 			}
 
-			const material = scope.getMaterial( colourCode, currentParseScope );
+			const material = this.getMaterial( colourCode, currentParseScope );
 
 			if ( ! material ) {
 
@@ -1350,13 +1384,13 @@ class LDrawLoader extends Loader {
 
 			return material;
 
-		}
+		};
 
-		function parseVector( lp ) {
+		const parseVector = lp => {
 
 			const v = new Vector3( parseFloat( lp.getToken() ), parseFloat( lp.getToken() ), parseFloat( lp.getToken() ) );
 
-			if ( ! scope.separateObjects ) {
+			if ( ! this.separateObjects ) {
 
 				v.applyMatrix4( currentParseScope.currentMatrix );
 
@@ -1364,7 +1398,7 @@ class LDrawLoader extends Loader {
 
 			return v;
 
-		}
+		};
 
 		// Parse all line commands
 		for ( let lineIndex = 0; lineIndex < numLines; lineIndex ++ ) {
@@ -1413,7 +1447,7 @@ class LDrawLoader extends Loader {
 			let inverted;
 			let ccw;
 			let doubleSided;
-			let v0, v1, v2, v3, c0, c1, faceNormal;
+			let v0, v1, v2, v3, c0, c1;
 
 			switch ( lineType ) {
 
@@ -1437,8 +1471,8 @@ class LDrawLoader extends Loader {
 								// needs to be flipped.
 								if (
 									currentParseScope.matrix.determinant() < 0 && (
-										scope.separateObjects && isPrimitiveType( type ) ||
-											! scope.separateObjects
+										this.separateObjects && isPrimitiveType( type ) ||
+											! this.separateObjects
 									) ) {
 
 									currentParseScope.inverted = ! currentParseScope.inverted;
@@ -1600,10 +1634,10 @@ class LDrawLoader extends Loader {
 
 					let fileName = lp.getRemainingString().trim().replace( /\\/g, '/' );
 
-					if ( scope.fileMap[ fileName ] ) {
+					if ( this.fileMap[ fileName ] ) {
 
 						// Found the subobject path in the preloaded file path map
-						fileName = scope.fileMap[ fileName ];
+						fileName = this.fileMap[ fileName ];
 
 					} else {
 
@@ -1695,16 +1729,10 @@ class LDrawLoader extends Loader {
 
 					}
 
-					_tempVec0.subVectors( v1, v0 );
-					_tempVec1.subVectors( v2, v1 );
-					faceNormal = new Vector3()
-						.crossVectors( _tempVec0, _tempVec1 )
-						.normalize();
-
 					faces.push( {
 						material: material,
 						colourCode: material.userData.code,
-						faceNormal: faceNormal,
+						faceNormal: null,
 						vertices: [ v0, v1, v2 ],
 						normals: [ null, null, null ],
 					} );
@@ -1715,7 +1743,7 @@ class LDrawLoader extends Loader {
 						faces.push( {
 							material: material,
 							colourCode: material.userData.code,
-							faceNormal: faceNormal,
+							faceNormal: null,
 							vertices: [ v2, v1, v0 ],
 							normals: [ null, null, null ],
 						} );
@@ -1750,18 +1778,12 @@ class LDrawLoader extends Loader {
 
 					}
 
-					_tempVec0.subVectors( v1, v0 );
-					_tempVec1.subVectors( v2, v1 );
-					faceNormal = new Vector3()
-						.crossVectors( _tempVec0, _tempVec1 )
-						.normalize();
-
 					// specifically place the triangle diagonal in the v0 and v1 slots so we can
 					// account for the doubling of vertices later when smoothing normals.
 					faces.push( {
 						material: material,
 						colourCode: material.userData.code,
-						faceNormal: faceNormal,
+						faceNormal: null,
 						vertices: [ v0, v1, v2, v3 ],
 						normals: [ null, null, null, null ],
 					} );
@@ -1772,7 +1794,7 @@ class LDrawLoader extends Loader {
 						faces.push( {
 							material: material,
 							colourCode: material.userData.code,
-							faceNormal: faceNormal,
+							faceNormal: null,
 							vertices: [ v3, v2, v1, v0 ],
 							normals: [ null, null, null, null ],
 						} );
@@ -1802,7 +1824,7 @@ class LDrawLoader extends Loader {
 		currentParseScope.subobjectIndex = 0;
 
 		const isRoot = ! parentParseScope.isFromParse;
-		if ( isRoot || scope.separateObjects && ! isPrimitiveType( type ) ) {
+		if ( isRoot || this.separateObjects && ! isPrimitiveType( type ) ) {
 
 			currentParseScope.groupObject = new Group();
 			currentParseScope.groupObject.userData.startingConstructionStep = currentParseScope.startingConstructionStep;
@@ -1860,6 +1882,7 @@ class LDrawLoader extends Loader {
 
 		if ( this.smoothNormals && doSmooth ) {
 
+			generateFaceNormals( subobjectParseScope.faces );
 			smoothNormals( subobjectParseScope.faces, subobjectParseScope.lineSegments );
 
 		}
@@ -1953,14 +1976,10 @@ class LDrawLoader extends Loader {
 					const vertices = tri.vertices;
 					for ( let i = 0, l = vertices.length; i < l; i ++ ) {
 
-						vertices[ i ] = vertices[ i ].clone().applyMatrix4( subobjectParseScope.matrix );
+						vertices[ i ].applyMatrix4( subobjectParseScope.matrix );
 
 					}
 
-					_tempVec0.subVectors( vertices[ 1 ], vertices[ 0 ] );
-					_tempVec1.subVectors( vertices[ 2 ], vertices[ 1 ] );
-					tri.faceNormal.crossVectors( _tempVec0, _tempVec1 ).normalize();
-
 				}
 
 				parentFaces.push( tri );
@@ -2031,9 +2050,10 @@ class LDrawLoader extends Loader {
 
 				return scope.processObject( text, subobject, url, parseScope );
 
-			} ).catch( function () {
+			} ).catch( function ( err ) {
 
-				console.warn( 'LDrawLoader: Subobject "' + subobject.fileName + '" could not be found.' );
+				console.warn( 'LDrawLoader: Subobject "' + subobject.fileName + '" could not be loaded.' );
+				console.warn( err );
 				return null;
 
 			} );