Skip to content

Commit

Permalink
Add uv/normal/tangent support to SimplifyModifier (#26875)
Browse files Browse the repository at this point in the history
* Add uv/normal/tangent support to SimplifyModifier

* add support of color attribute in SimplifyModifier
  • Loading branch information
Makio64 committed Oct 2, 2023
1 parent 5206385 commit 3e7aeaf
Showing 1 changed file with 103 additions and 11 deletions.
114 changes: 103 additions & 11 deletions examples/jsm/modifiers/SimplifyModifier.js
@@ -1,7 +1,9 @@
import {
BufferGeometry,
Float32BufferAttribute,
Vector3
Vector2,
Vector3,
Vector4
} from 'three';
import * as BufferGeometryUtils from '../utils/BufferGeometryUtils.js';

Expand All @@ -20,13 +22,17 @@ class SimplifyModifier {
modify( geometry, count ) {

geometry = geometry.clone();

// currently morphAttributes are not supported
delete geometry.morphAttributes.position;
delete geometry.morphAttributes.normal;
const attributes = geometry.attributes;

// this modifier can only process indexed and non-indexed geomtries with a position attribute
// this modifier can only process indexed and non-indexed geomtries with at least a position attribute

for ( const name in attributes ) {

if ( name !== 'position' ) geometry.deleteAttribute( name );
if ( name !== 'position' && name !== 'uv' && name !== 'normal' && name !== 'tangent' && name !== 'color' ) geometry.deleteAttribute( name );

}

Expand All @@ -42,12 +48,44 @@ class SimplifyModifier {
// add vertices

const positionAttribute = geometry.getAttribute( 'position' );
const uvAttribute = geometry.getAttribute( 'uv' );
const normalAttribute = geometry.getAttribute( 'normal' );
const tangentAttribute = geometry.getAttribute( 'tangent' );
const colorAttribute = geometry.getAttribute( 'color' );

let t = null;
let v2 = null;
let nor = null;
let col = null;

for ( let i = 0; i < positionAttribute.count; i ++ ) {

const v = new Vector3().fromBufferAttribute( positionAttribute, i );
if ( uvAttribute ) {

v2 = new Vector2().fromBufferAttribute( uvAttribute, i );

}

if ( normalAttribute ) {

nor = new Vector3().fromBufferAttribute( normalAttribute, i );

}

if ( tangentAttribute ) {

t = new Vector4().fromBufferAttribute( tangentAttribute, i );

}

const vertex = new Vertex( v );
if ( colorAttribute ) {

col = new THREE.Color().fromBufferAttribute( colorAttribute, i );

}

const vertex = new Vertex( v, v2, nor, t, col );
vertices.push( vertex );

}
Expand Down Expand Up @@ -115,17 +153,46 @@ class SimplifyModifier {

const simplifiedGeometry = new BufferGeometry();
const position = [];
const uv = [];
const normal = [];
const tangent = [];
const color = [];

index = [];

//

for ( let i = 0; i < vertices.length; i ++ ) {

const vertex = vertices[ i ].position;
position.push( vertex.x, vertex.y, vertex.z );
const vertex = vertices[ i ];
position.push( vertex.position.x, vertex.position.y, vertex.position.z );
if ( vertex.uv ) {

uv.push( vertex.uv.x, vertex.uv.y );

}

if ( vertex.normal ) {

normal.push( vertex.normal.x, vertex.normal.y, vertex.normal.z );

}

if ( vertex.tangent ) {

tangent.push( vertex.tangent.x, vertex.tangent.y, vertex.tangent.z, vertex.tangent.w );

}

if ( vertex.color ) {

color.push( vertex.color.r, vertex.color.g, vertex.color.b );

}


// cache final index to GREATLY speed up faces reconstruction
vertices[ i ].id = i;
vertex.id = i;

}

Expand All @@ -138,9 +205,12 @@ class SimplifyModifier {

}

//

simplifiedGeometry.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) );
if ( uv.length > 0 ) simplifiedGeometry.setAttribute( 'uv', new Float32BufferAttribute( uv, 2 ) );
if ( normal.length > 0 ) simplifiedGeometry.setAttribute( 'normal', new Float32BufferAttribute( normal, 3 ) );
if ( tangent.length > 0 ) simplifiedGeometry.setAttribute( 'tangent', new Float32BufferAttribute( tangent, 4 ) );
if ( color.length > 0 ) simplifiedGeometry.setAttribute( 'color', new Float32BufferAttribute( color, 3 ) );

simplifiedGeometry.setIndex( index );

return simplifiedGeometry;
Expand Down Expand Up @@ -318,7 +388,7 @@ function removeFace( f, faces ) {

}

function collapse( vertices, faces, u, v ) { // u and v are pointers to vertices of an edge
function collapse( vertices, faces, u, v ) {

// Collapse the edge uv by moving vertex u onto v

Expand All @@ -330,6 +400,24 @@ function collapse( vertices, faces, u, v ) { // u and v are pointers to vertices

}

if ( v.uv ) {

u.uv.copy( v.uv );

}

if ( v.normal ) {

v.normal.add( u.normal ).normalize();

}

if ( v.tangent ) {

v.tangent.add( u.tangent ).normalize();

}

const tmpVertices = [];

for ( let i = 0; i < u.neighbors.length; i ++ ) {
Expand Down Expand Up @@ -480,9 +568,13 @@ class Triangle {

class Vertex {

constructor( v ) {
constructor( v, uv, normal, tangent, color ) {

this.position = v;
this.uv = uv;
this.normal = normal;
this.tangent = tangent;
this.color = color;

this.id = - 1; // external use position in vertices list (for e.g. face generation)

Expand Down

0 comments on commit 3e7aeaf

Please sign in to comment.