未验证 提交 ecf862c4 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #20903 from Mcgode/edge-split-keep-normals

EdgeSplitModifier - Keep normals
......@@ -7,6 +7,7 @@ THREE.EdgeSplitModifier = function () {
var positions, normals;
var indexes;
var pointToIndexMap, splitIndexes;
let oldNormals;
function computeNormals() {
......@@ -150,7 +151,7 @@ THREE.EdgeSplitModifier = function () {
}
this.modify = function ( geometry, cutOffAngle ) {
this.modify = function ( geometry, cutOffAngle, tryKeepNormals = true ) {
const wasNotBufferGeometry = geometry.isBufferGeometry === undefined;
if ( ! geometry.isBufferGeometry ) {
......@@ -161,6 +162,7 @@ THREE.EdgeSplitModifier = function () {
let hadNormals = false;
oldNormals = null;
if ( geometry.attributes.normal ) {
hadNormals = true;
......@@ -168,6 +170,9 @@ THREE.EdgeSplitModifier = function () {
if ( wasNotBufferGeometry === false )
geometry = geometry.clone();
if ( tryKeepNormals && geometry.index )
oldNormals = geometry.attributes.normal.array;
geometry.deleteAttribute( 'normal' );
}
......@@ -249,6 +254,27 @@ THREE.EdgeSplitModifier = function () {
geometry.computeVertexNormals();
if ( oldNormals !== null ) {
const changedNormals = new Array( oldNormals.length / 3 ).fill( false );
for ( const splitData of splitIndexes )
changedNormals[ splitData.original ] = true;
for ( let i = 0; i < changedNormals.length; i ++ ) {
if ( changedNormals[ i ] === false ) {
for ( let j = 0; j < 3; j ++ )
geometry.attributes.normal.array[ 3 * i + j ] = oldNormals[ 3 * i + j ];
}
}
}
}
return geometry;
......
......@@ -3,6 +3,20 @@ import { BufferGeometry, Geometry } from '../../../src/Three';
export class EdgeSplitModifier {
constructor();
modify( geometry: Geometry, cutOffPoint: number ): BufferGeometry;
/**
* @param geometry The geometry to modify by splitting edges.
* This geometry can be any of any type: Geometry or BufferGeometry, indexed or
* not...
*
* @param cutOffPoint The cutoff angle in radians. If the angle between two face normals is higher
* than this value, a split will be made.
*
* @param [tryKeepNormals = true] Set to true to keep the normal values for vertices that won't be split.
* To use this feature, you also need to pass an indexed geometry with a 'normal'
* BufferAttribute.
*/
modify( geometry: Geometry, cutOffPoint: number, tryKeepNormals: boolean ): BufferGeometry;
}
......@@ -16,6 +16,8 @@ var EdgeSplitModifier = function () {
var indexes;
var pointToIndexMap, splitIndexes;
let oldNormals;
function computeNormals() {
......@@ -158,7 +160,7 @@ var EdgeSplitModifier = function () {
}
this.modify = function ( geometry, cutOffAngle ) {
this.modify = function ( geometry, cutOffAngle, tryKeepNormals = true ) {
const wasNotBufferGeometry = geometry.isBufferGeometry === undefined;
if ( ! geometry.isBufferGeometry ) {
......@@ -169,6 +171,7 @@ var EdgeSplitModifier = function () {
let hadNormals = false;
oldNormals = null;
if ( geometry.attributes.normal ) {
hadNormals = true;
......@@ -176,6 +179,9 @@ var EdgeSplitModifier = function () {
if ( wasNotBufferGeometry === false )
geometry = geometry.clone();
if ( tryKeepNormals && geometry.index )
oldNormals = geometry.attributes.normal.array;
geometry.deleteAttribute( 'normal' );
}
......@@ -257,6 +263,27 @@ var EdgeSplitModifier = function () {
geometry.computeVertexNormals();
if ( oldNormals !== null ) {
const changedNormals = new Array( oldNormals.length / 3 ).fill( false );
for ( const splitData of splitIndexes )
changedNormals[ splitData.original ] = true;
for ( let i = 0; i < changedNormals.length; i ++ ) {
if ( changedNormals[ i ] === false ) {
for ( let j = 0; j < 3; j ++ )
geometry.attributes.normal.array[ 3 * i + j ] = oldNormals[ 3 * i + j ];
}
}
}
}
return geometry;
......
......@@ -15,6 +15,7 @@
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { OBJLoader } from './jsm/loaders/OBJLoader.js';
import { EdgeSplitModifier } from './jsm/modifiers/EdgeSplitModifier.js';
import { BufferGeometryUtils } from './jsm/utils/BufferGeometryUtils.js';
import { GUI } from './jsm/libs/dat.gui.module.js';
......@@ -27,6 +28,7 @@
edgeSplit: true,
cutOffAngle: 20,
showMap: false,
tryKeepNormals: true,
};
init();
......@@ -68,7 +70,7 @@
const modelGeometry = cerberus.geometry;
modifier = new EdgeSplitModifier();
baseGeometry = modelGeometry;
baseGeometry = BufferGeometryUtils.mergeVertices( modelGeometry );
mesh = new THREE.Mesh( getGeometry(), new THREE.MeshStandardMaterial() );
mesh.material.flatShading = ! params.smoothShading;
......@@ -111,6 +113,7 @@
gui.add( params, 'smoothShading' ).onFinishChange( updateMesh );
gui.add( params, 'edgeSplit' ).onFinishChange( updateMesh );
gui.add( params, 'cutOffAngle' ).min( 0 ).max( 180 ).onFinishChange( updateMesh );
gui.add( params, 'tryKeepNormals' ).onFinishChange( updateMesh );
}
......@@ -132,7 +135,11 @@
if ( params.edgeSplit ) {
geometry = modifier.modify( baseGeometry, params.cutOffAngle * Math.PI / 180 );
geometry = modifier.modify(
baseGeometry,
params.cutOffAngle * Math.PI / 180,
params.tryKeepNormals
);
} else {
......
......@@ -3105,7 +3105,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册