Przeglądaj źródła

Updated examples builds.

Mr.doob 3 lat temu
rodzic
commit
18c908125c

+ 8 - 23
examples/js/exporters/GLTFExporter.js

@@ -866,7 +866,7 @@
 		/**
    * Process image
    * @param  {Image} image to process
-   * @param  {Integer} format of the image (e.g. THREE.RGBFormat, THREE.RGBAFormat etc)
+   * @param  {Integer} format of the image (THREE.RGBAFormat)
    * @param  {Boolean} flipY before writing out the image
    * @return {Integer}     Index of the processed texture in the "images" array
    */
@@ -909,9 +909,9 @@
 
 				} else {
 
-					if ( format !== THREE.RGBAFormat && format !== THREE.RGBFormat ) {
+					if ( format !== THREE.RGBAFormat ) {
 
-						console.error( 'GLTFExporter: Only RGB and RGBA formats are supported.' );
+						console.error( 'GLTFExporter: Only THREE.RGBAFormat is supported.' );
 
 					}
 
@@ -923,27 +923,12 @@
 
 					const data = new Uint8ClampedArray( image.height * image.width * 4 );
 
-					if ( format === THREE.RGBAFormat ) {
+					for ( let i = 0; i < data.length; i += 4 ) {
 
-						for ( let i = 0; i < data.length; i += 4 ) {
-
-							data[ i + 0 ] = image.data[ i + 0 ];
-							data[ i + 1 ] = image.data[ i + 1 ];
-							data[ i + 2 ] = image.data[ i + 2 ];
-							data[ i + 3 ] = image.data[ i + 3 ];
-
-						}
-
-					} else {
-
-						for ( let i = 0, j = 0; i < data.length; i += 4, j += 3 ) {
-
-							data[ i + 0 ] = image.data[ j + 0 ];
-							data[ i + 1 ] = image.data[ j + 1 ];
-							data[ i + 2 ] = image.data[ j + 2 ];
-							data[ i + 3 ] = 255;
-
-						}
+						data[ i + 0 ] = image.data[ i + 0 ];
+						data[ i + 1 ] = image.data[ i + 1 ];
+						data[ i + 2 ] = image.data[ i + 2 ];
+						data[ i + 3 ] = image.data[ i + 3 ];
 
 					}
 

+ 24 - 15
examples/js/loaders/LDrawLoader.js

@@ -1407,6 +1407,9 @@
 	} //
 
 
+	const MAIN_COLOUR_CODE = '16';
+	const MAIN_EDGE_COLOUR_CODE = '24';
+
 	class LDrawLoader extends THREE.Loader {
 
 		constructor( manager ) {
@@ -1535,15 +1538,13 @@
 				url: null,
 				// Subobjects
 				subobjects: null,
-				numSubobjects: 0,
-				subobjectIndex: 0,
 				inverted: false,
 				category: null,
 				keywords: null,
 				// Current subobject
 				currentFileName: null,
-				mainColorCode: parentScope ? parentScope.mainColorCode : '16',
-				mainEdgeColorCode: parentScope ? parentScope.mainEdgeColorCode : '24',
+				mainColorCode: parentScope ? parentScope.mainColorCode : MAIN_COLOUR_CODE,
+				mainEdgeColorCode: parentScope ? parentScope.mainEdgeColorCode : MAIN_EDGE_COLOUR_CODE,
 				matrix: new THREE.Matrix4(),
 				type: 'Model',
 				groupObject: null,
@@ -1609,6 +1610,18 @@
 
 		}
 
+		getMainMaterial() {
+
+			return this.getMaterial( MAIN_COLOUR_CODE );
+
+		}
+
+		getMainEdgeMaterial() {
+
+			return this.getMaterial( MAIN_EDGE_COLOUR_CODE );
+
+		}
+
 		parseColorMetaDirective( lineParser ) {
 
 			// Parses a color definition and returns a THREE.Material
@@ -1871,13 +1884,13 @@
 			const parseColorCode = ( colorCode, forEdge ) => {
 
 				// Parses next color code and returns a THREE.Material
-				if ( ! forEdge && colorCode === '16' ) {
+				if ( ! forEdge && colorCode === MAIN_COLOUR_CODE ) {
 
 					colorCode = mainColorCode;
 
 				}
 
-				if ( forEdge && colorCode === '24' ) {
+				if ( forEdge && colorCode === MAIN_EDGE_COLOUR_CODE ) {
 
 					colorCode = mainEdgeColorCode;
 
@@ -1954,8 +1967,6 @@
 			currentParseScope.category = info.category;
 			currentParseScope.keywords = info.keywords;
 			currentParseScope.subobjects = info.subobjects;
-			currentParseScope.numSubobjects = info.subobjects.length;
-			currentParseScope.subobjectIndex = 0;
 			currentParseScope.type = info.type;
 			currentParseScope.totalFaces = info.totalFaces;
 			const isRoot = ! parentParseScope.isFromParse;
@@ -2121,8 +2132,7 @@
 
 			const scope = this;
 			const parseScope = this.newParseScopeLevel( null, parentScope );
-			parseScope.url = url;
-			const parentParseScope = parseScope.parentScope; // Set current matrix
+			parseScope.url = url; // Set current matrix
 
 			if ( subobject ) {
 
@@ -2131,13 +2141,12 @@
 				parseScope.startingConstructionStep = subobject.startingConstructionStep;
 				parseScope.fileName = subobject.fileName;
 
-				if ( subobject.colorCode === '16' && parseScope.parentScope ) {
+				if ( subobject.colorCode === MAIN_COLOUR_CODE && parentScope ) {
 
-					const parentScope = parseScope.parentScope;
 					parseScope.mainColorCode = parentScope.mainColorCode;
 					parseScope.mainEdgeColorCode = parentScope.mainEdgeColorCode;
 
-				} else if ( subobject.colorCode !== '16' ) {
+				} else if ( subobject.colorCode !== MAIN_COLOUR_CODE ) {
 
 					parseScope.mainColorCode = subobject.colorCode;
 					parseScope.mainEdgeColorCode = subobject.colorCode;
@@ -2153,7 +2162,7 @@
 
 			for ( let i = 0, l = subobjects.length; i < l; i ++ ) {
 
-				promises.push( loadSubobject( parseScope.subobjects[ i ] ) );
+				promises.push( loadSubobject( subobjects[ i ] ) );
 
 			} // Kick off of the downloads in parallel but process all the subobjects
 			// in order so all the assembly instructions are correct
@@ -2168,7 +2177,7 @@
 			} // If it is root object then finalize this object and compute construction steps
 
 
-			if ( ! parentParseScope.isFromParse ) {
+			if ( ! parentScope.isFromParse ) {
 
 				this.finalizeObject( parseScope );
 				this.computeConstructionSteps( parseScope.groupObject );

+ 1 - 1
examples/js/loaders/SVGLoader.js

@@ -561,7 +561,7 @@
 					for ( let j = 0; j < selectorList.length; j ++ ) {
 
 						// Remove empty rules
-						const definitions = Object.fromEntries( Object.entries( stylesheet.style ).filter( ( [ _, v ] ) => v !== '' ) );
+						const definitions = Object.fromEntries( Object.entries( stylesheet.style ).filter( ( [ , v ] ) => v !== '' ) );
 						stylesheets[ selectorList[ j ] ] = Object.assign( stylesheets[ selectorList[ j ] ] || {}, definitions );
 
 					}

+ 2 - 2
examples/js/objects/Lensflare.js

@@ -15,8 +15,8 @@
 			const positionScreen = new THREE.Vector3();
 			const positionView = new THREE.Vector3(); // textures
 
-			const tempMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBFormat );
-			const occlusionMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBFormat ); // material
+			const tempMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBAFormat );
+			const occlusionMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBAFormat ); // material
 
 			const geometry = Lensflare.Geometry;
 			const material1a = new THREE.RawShaderMaterial( {

+ 173 - 0
examples/js/utils/LDrawUtils.js

@@ -0,0 +1,173 @@
+( function () {
+
+	class LDrawUtils {
+
+		static mergeObject( object ) {
+
+			// Merges geometries in object by materials and returns new object. Use on not indexed geometries.
+			// The object buffers reference the old object ones.
+			// Special treatment is done to the conditional lines generated by LDrawLoader.
+			function extractGroup( geometry, group, elementSize, isConditionalLine ) {
+
+				// Extracts a group from a geometry as a new geometry (with attribute buffers referencing original buffers)
+				const newGeometry = new THREE.BufferGeometry();
+				const originalPositions = geometry.getAttribute( 'position' ).array;
+				const originalNormals = elementSize === 3 ? geometry.getAttribute( 'normal' ).array : null;
+				const numVertsGroup = Math.min( group.count, Math.floor( originalPositions.length / 3 ) - group.start );
+				const vertStart = group.start * 3;
+				const vertEnd = ( group.start + numVertsGroup ) * 3;
+				const positions = originalPositions.subarray( vertStart, vertEnd );
+				const normals = originalNormals !== null ? originalNormals.subarray( vertStart, vertEnd ) : null;
+				newGeometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				if ( normals !== null ) newGeometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+
+				if ( isConditionalLine ) {
+
+					const controlArray0 = geometry.getAttribute( 'control0' ).array.subarray( vertStart, vertEnd );
+					const controlArray1 = geometry.getAttribute( 'control1' ).array.subarray( vertStart, vertEnd );
+					const directionArray = geometry.getAttribute( 'direction' ).array.subarray( vertStart, vertEnd );
+					newGeometry.setAttribute( 'control0', new THREE.BufferAttribute( controlArray0, 3, false ) );
+					newGeometry.setAttribute( 'control1', new THREE.BufferAttribute( controlArray1, 3, false ) );
+					newGeometry.setAttribute( 'direction', new THREE.BufferAttribute( directionArray, 3, false ) );
+
+				}
+
+				return newGeometry;
+
+			}
+
+			function addGeometry( mat, geometry, geometries ) {
+
+				const geoms = geometries[ mat.uuid ];
+
+				if ( ! geoms ) {
+
+					geometries[ mat.uuid ] = {
+						mat: mat,
+						arr: [ geometry ]
+					};
+
+				} else geoms.arr.push( geometry );
+
+			}
+
+			function permuteAttribute( attribute, elemSize ) {
+
+				// Permutes first two vertices of each attribute element
+				if ( ! attribute ) return;
+				const verts = attribute.array;
+				const numVerts = Math.floor( verts.length / 3 );
+				let offset = 0;
+
+				for ( let i = 0; i < numVerts; i ++ ) {
+
+					const x = verts[ offset ];
+					const y = verts[ offset + 1 ];
+					const z = verts[ offset + 2 ];
+					verts[ offset ] = verts[ offset + 3 ];
+					verts[ offset + 1 ] = verts[ offset + 4 ];
+					verts[ offset + 2 ] = verts[ offset + 5 ];
+					verts[ offset + 3 ] = x;
+					verts[ offset + 4 ] = y;
+					verts[ offset + 5 ] = z;
+					offset += elemSize * 3;
+
+				}
+
+			} // Traverse the object hierarchy collecting geometries and transforming them to world space
+
+
+			const meshGeometries = {};
+			const linesGeometries = {};
+			const condLinesGeometries = {};
+			object.updateMatrixWorld( true );
+			const normalMatrix = new THREE.Matrix3();
+			object.traverse( c => {
+
+				if ( c.isMesh | c.isLineSegments ) {
+
+					const elemSize = c.isMesh ? 3 : 2;
+					const matrixIsInverted = c.matrixWorld.determinant() < 0;
+
+					if ( matrixIsInverted ) {
+
+						permuteAttribute( c.geometry.attributes.position, elemSize );
+						permuteAttribute( c.geometry.attributes.normal, elemSize );
+
+					}
+
+					c.geometry.applyMatrix4( c.matrixWorld );
+
+					if ( c.isConditionalLine ) {
+
+						c.geometry.attributes.control0.applyMatrix4( c.matrixWorld );
+						c.geometry.attributes.control1.applyMatrix4( c.matrixWorld );
+						normalMatrix.getNormalMatrix( c.matrixWorld );
+						c.geometry.attributes.direction.applyNormalMatrix( normalMatrix );
+
+					}
+
+					const geometries = c.isMesh ? meshGeometries : c.isConditionalLine ? condLinesGeometries : linesGeometries;
+
+					if ( Array.isArray( c.material ) ) {
+
+						for ( const groupIndex in c.geometry.groups ) {
+
+							const group = c.geometry.groups[ groupIndex ];
+							const mat = c.material[ group.materialIndex ];
+							const newGeometry = extractGroup( c.geometry, group, elemSize, c.isConditionalLine );
+							addGeometry( mat, newGeometry, geometries );
+
+						}
+
+					} else addGeometry( c.material, c.geometry, geometries );
+
+				}
+
+			} ); // Create object with merged geometries
+
+			const mergedObject = new THREE.Group();
+			const meshMaterialsIds = Object.keys( meshGeometries );
+
+			for ( const i in meshMaterialsIds ) {
+
+				const meshGeometry = meshGeometries[ meshMaterialsIds[ i ] ];
+				const mergedGeometry = THREE.mergeBufferGeometries( meshGeometry.arr );
+				mergedObject.add( new THREE.Mesh( mergedGeometry, meshGeometry.mat ) );
+
+			}
+
+			const linesMaterialsIds = Object.keys( linesGeometries );
+
+			for ( const i in linesMaterialsIds ) {
+
+				const lineGeometry = linesGeometries[ linesMaterialsIds[ i ] ];
+				const mergedGeometry = THREE.mergeBufferGeometries( lineGeometry.arr );
+				mergedObject.add( new THREE.LineSegments( mergedGeometry, lineGeometry.mat ) );
+
+			}
+
+			const condLinesMaterialsIds = Object.keys( condLinesGeometries );
+
+			for ( const i in condLinesMaterialsIds ) {
+
+				const condLineGeometry = condLinesGeometries[ condLinesMaterialsIds[ i ] ];
+				const mergedGeometry = THREE.mergeBufferGeometries( condLineGeometry.arr );
+				const condLines = new THREE.LineSegments( mergedGeometry, condLineGeometry.mat );
+				condLines.isConditionalLine = true;
+				mergedObject.add( condLines );
+
+			}
+
+			mergedObject.userData.constructionStep = 0;
+			mergedObject.userData.numConstructionSteps = 1;
+			return mergedObject;
+
+		}
+
+	}
+
+	THREE.LDrawUtils = {};
+	THREE.LDrawUtils.LDrawUtils = LDrawUtils;
+
+} )();