Bläddra i källkod

EdgeSplitModifier - Keep other attributes

Max Godefroy (Clyde) 4 år sedan
förälder
incheckning
69b974cbd1

+ 26 - 9
examples/js/modifiers/EdgeSplitModifier.js

@@ -178,7 +178,6 @@ THREE.EdgeSplitModifier = function () {
 		computeNormals();
 		mapPositionsToIndexes();
 
-
 		splitIndexes = [];
 
 		for ( var vertexIndexes of pointToIndexMap ) {
@@ -187,9 +186,15 @@ THREE.EdgeSplitModifier = function () {
 
 		}
 
-		var newPositions = new Float32Array( positions.length + 3 * splitIndexes.length );
-		newPositions.set( positions );
-		var offset = positions.length;
+		const newAttributes = {};
+		for ( const name of Object.keys( geometry.attributes ) ) {
+
+			const oldAttribute = geometry.attributes[ name ];
+			const newArray = new oldAttribute.array.constructor( ( indexes.length + splitIndexes.length ) * oldAttribute.itemSize );
+			newArray.set( oldAttribute.array );
+			newAttributes[ name ] = new THREE.BufferAttribute( newArray, oldAttribute.itemSize, oldAttribute.normalized );
+
+		}
 
 		var newIndexes = new Uint32Array( indexes.length );
 		newIndexes.set( indexes );
@@ -199,22 +204,34 @@ THREE.EdgeSplitModifier = function () {
 			var split = splitIndexes[ i ];
 			var index = indexes[ split.original ];
 
-			newPositions[ offset + 3 * i ] = positions[ 3 * index ];
-			newPositions[ offset + 3 * i + 1 ] = positions[ 3 * index + 1 ];
-			newPositions[ offset + 3 * i + 2 ] = positions[ 3 * index + 2 ];
+			for ( const attribute of Object.values( newAttributes ) ) {
+
+				for ( let j = 0; j < attribute.itemSize; j ++ ) {
+
+					attribute.array[ ( indexes.length + i ) * attribute.itemSize + j ] =
+						attribute.array[ index * attribute.itemSize + j ];
+
+				}
+
+			}
 
 			for ( var j of split.indexes ) {
 
-				newIndexes[ j ] = offset / 3 + i;
+				newIndexes[ j ] = indexes.length + i;
 
 			}
 
 		}
 
 		geometry = new THREE.BufferGeometry();
-		geometry.setAttribute( 'position', new THREE.BufferAttribute( newPositions, 3, true ) );
 		geometry.setIndex( new THREE.BufferAttribute( newIndexes, 1 ) );
 
+		for ( const name of Object.keys( newAttributes ) ) {
+
+			geometry.setAttribute( name, newAttributes[ name ] );
+
+		}
+
 		return geometry;
 
 	};

+ 1 - 1
examples/jsm/modifiers/EdgeSplitModifier.d.ts

@@ -1,4 +1,4 @@
-import { BufferGeometry, Geometry } from "../../../src/Three";
+import { BufferGeometry, Geometry } from '../../../src/Three';
 
 export class EdgeSplitModifier {
 

+ 36 - 12
examples/jsm/modifiers/EdgeSplitModifier.js

@@ -2,8 +2,8 @@ import {
 	BufferAttribute,
 	BufferGeometry,
 	Vector3
-} from "../../../build/three.module.js";
-import { BufferGeometryUtils } from "../utils/BufferGeometryUtils.js";
+} from '../../../build/three.module.js';
+import { BufferGeometryUtils } from '../utils/BufferGeometryUtils.js';
 
 
 var EdgeSplitModifier = function () {
@@ -167,7 +167,14 @@ var EdgeSplitModifier = function () {
 		}
 
 
-		if ( geometry.index == null ) {
+		if ( geometry.attributes.normal ) {
+
+			geometry.deleteAttribute( 'normal' );
+
+		}
+
+
+		if ( ! geometry.index ) {
 
 			if ( BufferGeometryUtils === undefined ) {
 
@@ -185,7 +192,6 @@ var EdgeSplitModifier = function () {
 		computeNormals();
 		mapPositionsToIndexes();
 
-
 		splitIndexes = [];
 
 		for ( var vertexIndexes of pointToIndexMap ) {
@@ -194,9 +200,15 @@ var EdgeSplitModifier = function () {
 
 		}
 
-		var newPositions = new Float32Array( positions.length + 3 * splitIndexes.length );
-		newPositions.set( positions );
-		var offset = positions.length;
+		const newAttributes = {};
+		for ( const name of Object.keys( geometry.attributes ) ) {
+
+			const oldAttribute = geometry.attributes[ name ];
+			const newArray = new oldAttribute.array.constructor( ( indexes.length + splitIndexes.length ) * oldAttribute.itemSize );
+			newArray.set( oldAttribute.array );
+			newAttributes[ name ] = new BufferAttribute( newArray, oldAttribute.itemSize, oldAttribute.normalized );
+
+		}
 
 		var newIndexes = new Uint32Array( indexes.length );
 		newIndexes.set( indexes );
@@ -206,22 +218,34 @@ var EdgeSplitModifier = function () {
 			var split = splitIndexes[ i ];
 			var index = indexes[ split.original ];
 
-			newPositions[ offset + 3 * i ] = positions[ 3 * index ];
-			newPositions[ offset + 3 * i + 1 ] = positions[ 3 * index + 1 ];
-			newPositions[ offset + 3 * i + 2 ] = positions[ 3 * index + 2 ];
+			for ( const attribute of Object.values( newAttributes ) ) {
+
+				for ( let j = 0; j < attribute.itemSize; j ++ ) {
+
+					attribute.array[ ( indexes.length + i ) * attribute.itemSize + j ] =
+						attribute.array[ index * attribute.itemSize + j ];
+
+				}
+
+			}
 
 			for ( var j of split.indexes ) {
 
-				newIndexes[ j ] = offset / 3 + i;
+				newIndexes[ j ] = indexes.length + i;
 
 			}
 
 		}
 
 		geometry = new BufferGeometry();
-		geometry.setAttribute( 'position', new BufferAttribute( newPositions, 3, true ) );
 		geometry.setIndex( new BufferAttribute( newIndexes, 1 ) );
 
+		for ( const name of Object.keys( newAttributes ) ) {
+
+			geometry.setAttribute( name, newAttributes[ name ] );
+
+		}
+
 		return geometry;
 
 	};

+ 51 - 14
examples/webgl_modifier_edgesplit.html

@@ -13,19 +13,21 @@
 			import * as THREE from '../build/three.module.js';
 
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';
-			import { OBJLoader } from "./jsm/loaders/OBJLoader.js";
-			import { BufferGeometryUtils } from "./jsm/utils/BufferGeometryUtils.js";
-			import { EdgeSplitModifier } from "./jsm/modifiers/EdgeSplitModifier.js";
+			import { OBJLoader } from './jsm/loaders/OBJLoader.js';
+			import { BufferGeometryUtils } from './jsm/utils/BufferGeometryUtils.js';
+			import { EdgeSplitModifier } from './jsm/modifiers/EdgeSplitModifier.js';
 
-			import { GUI } from "./jsm/libs/dat.gui.module.js";
+			import { GUI } from './jsm/libs/dat.gui.module.js';
 
 			let renderer, scene, camera;
 			let modifier, mesh, baseGeometry;
+			let map;
 
 			const params = {
 				smoothShading: true,
 				edgeSplit: true,
 				cutOffAngle: 20,
+				showMap: true,
 			};
 
 			init();
@@ -63,10 +65,11 @@
 					'./models/obj/cerberus/Cerberus.obj',
 					function ( group ) {
 
+						const cerberus = group.children[ 0 ];
+
 						// Retrieve Cerberus vertex positions only
-						const modelGeometry = group.children[ 0 ].geometry;
+						const modelGeometry = cerberus.geometry;
 						modelGeometry.deleteAttribute( 'normal' );
-						modelGeometry.deleteAttribute( 'uv' );
 
 						modifier = new EdgeSplitModifier();
 						baseGeometry = modelGeometry;
@@ -78,6 +81,13 @@
 						mesh.translateZ( 1.5 );
 						scene.add( mesh );
 
+						if ( map !== undefined && params.showMap ) {
+
+							mesh.material.map = map;
+							mesh.material.needsUpdate = true;
+
+						}
+
 						render();
 
 					}
@@ -85,12 +95,26 @@
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
+				new THREE.TextureLoader().load( './models/obj/cerberus/Cerberus_A.jpg', function ( texture ) {
+
+					map = texture;
+
+					if ( mesh !== undefined && params.showMap ) {
+
+						mesh.material.map = map;
+						mesh.material.needsUpdate = true;
+
+					}
+
+				} );
 
-				const gui = new GUI( { name: "Edge split modifier parameters" } );
 
-				gui.add( params, "smoothShading" ).onFinishChange( updateMesh );
-				gui.add( params, "edgeSplit" ).onFinishChange( updateMesh );
-				gui.add( params, "cutOffAngle" ).min( 0 ).max( 180 ).onFinishChange( updateMesh );
+				const gui = new GUI( { name: 'Edge split modifier parameters' } );
+
+				gui.add( params, 'showMap' ).onFinishChange( updateMesh );
+				gui.add( params, 'smoothShading' ).onFinishChange( updateMesh );
+				gui.add( params, 'edgeSplit' ).onFinishChange( updateMesh );
+				gui.add( params, 'cutOffAngle' ).min( 0 ).max( 180 ).onFinishChange( updateMesh );
 
 			}
 
@@ -129,12 +153,25 @@
 
 			function updateMesh() {
 
-				mesh.geometry = getGeometry();
+				if ( mesh !== undefined ) {
 
-				mesh.material.flatShading = params.smoothShading === false;
-				mesh.material.needsUpdate = true;
+					mesh.geometry = getGeometry();
 
-				render();
+					let needsUpdate = mesh.material.flatShading === params.smoothShading;
+					mesh.material.flatShading = params.smoothShading === false;
+
+					if ( map !== undefined ) {
+
+						needsUpdate = needsUpdate || mesh.material.map !== ( params.showMap ? map : null );
+						mesh.material.map = params.showMap ? map : null;
+
+					}
+
+					mesh.material.needsUpdate = needsUpdate;
+
+					render();
+
+				}
 
 			}