modify static method
BufferGeometry
modify(
- BufferGeometry bufferGeometry,
- int count
)
Implementation
static BufferGeometry modify(BufferGeometry bufferGeometry, int count) {
BufferGeometry geometry = bufferGeometry.clone();
// currently morphAttributes are not supported
geometry.morphAttributes.remove('position');
geometry.morphAttributes.remove('normal');
final attributes = geometry.attributes;
// this modifier can only process indexed and non-indexed geomtries with at least a position attribute
for ( final name in attributes.keys) {
if ( name != 'position' && name != 'uv' && name != 'normal' && name != 'tangent' && name != 'color' ) geometry.deleteAttributeFromString( name );
}
geometry = BufferGeometryUtils.mergeVertices( geometry );
final List<Vertex> vertices = [];
final List<Triangle> faces = [];
// add vertices
final BufferAttribute positionAttribute = geometry.getAttributeFromString( 'position' );
final BufferAttribute? uvAttribute = geometry.getAttributeFromString( 'uv' );
final BufferAttribute? normalAttribute = geometry.getAttributeFromString( 'normal' );
final BufferAttribute? tangentAttribute = geometry.getAttributeFromString( 'tangent' );
final BufferAttribute? colorAttribute = geometry.getAttributeFromString( 'color' );
Vector4? t;
Vector3? v2;
Vector3? nor;
Color? col;
for (int i = 0; i < positionAttribute.count; i ++ ) {
final v = Vector3.zero().fromBuffer( positionAttribute, i );
if ( uvAttribute != null) {
v2 = Vector3.zero().fromBuffer( uvAttribute, i );
}
if ( normalAttribute != null) {
nor = Vector3.zero().fromBuffer( normalAttribute, i );
}
if ( tangentAttribute != null) {
t = Vector4.zero().fromBuffer( tangentAttribute, i );
}
if ( colorAttribute != null) {
col = Color().fromBuffer( colorAttribute, i );
}
final vertex = Vertex(v, v2, nor, t, col );
vertices.add( vertex );
}
// add faces
BufferAttribute<NativeArray<num>>? index = geometry.getIndex();
if ( index != null ) {
for (int i = 0; i < index.count; i += 3 ) {
final a = index.getX( i )!.toInt();
final b = index.getX( i + 1 )!.toInt();
final c = index.getX( i + 2 )!.toInt();
final triangle = Triangle( vertices[ a ], vertices[ b ], vertices[ c ], a, b, c );
faces.add( triangle );
}
}
else {
for (int i = 0; i < positionAttribute.count; i += 3 ) {
final a = i;
final b = i + 1;
final c = i + 2;
final triangle = Triangle( vertices[ a ], vertices[ b ], vertices[ c ], a, b, c );
faces.add( triangle );
}
}
// compute all edge collapse costs
for (int i = 0, il = vertices.length; i < il; i ++ ) {
_computeEdgeCostAtVertex(vertices[ i ]);
}
Vertex? nextVertex;
int z = count;
while (z-- != -1) {
nextVertex = _minimumCostEdge( vertices );
if (nextVertex == null) {
console.info( 'SimplifyModifier: No next vertex' );
break;
}
_collapse( vertices, faces, nextVertex, nextVertex.collapseNeighbor );
}
final simplifiedGeometry = BufferGeometry();
final List<double> position = [];
final List<double> uv = [];
final List<double> normal = [];
final List<double> tangent = [];
final List<double> color = [];
final List<int> indx = [];
for (int i = 0; i < vertices.length; i ++ ) {
final vertex = vertices[ i ];
position.addAll([ vertex.position.x, vertex.position.y, vertex.position.z ]);
if ( vertex.uv != null) {
uv.addAll([ vertex.uv!.x, vertex.uv!.y ]);
}
if ( vertex.normal != null) {
normal.addAll([ vertex.normal!.x, vertex.normal!.y, vertex.normal!.z ]);
}
if ( vertex.tangent != null) {
tangent.addAll([ vertex.tangent!.x, vertex.tangent!.y, vertex.tangent!.z, vertex.tangent!.w ]);
}
if ( vertex.color != null) {
color.addAll( [vertex.color!.red, vertex.color!.green, vertex.color!.blue] );
}
// cache final index to GREATLY speed up faces refinalruction
vertex.id = i;
}
//
for (int i = 0; i < faces.length; i ++ ) {
final face = faces[ i ];
indx.addAll([ face.v1!.id, face.v2!.id, face.v3!.id ]);
}
simplifiedGeometry.setAttributeFromString( 'position', Float32BufferAttribute.fromList( position, 3 ) );
if ( uv.isNotEmpty) simplifiedGeometry.setAttributeFromString( 'uv', Float32BufferAttribute.fromList( uv, 2 ) );
if ( normal.isNotEmpty ) simplifiedGeometry.setAttributeFromString( 'normal', Float32BufferAttribute.fromList( normal, 3 ) );
if ( tangent.isNotEmpty ) simplifiedGeometry.setAttributeFromString( 'tangent', Float32BufferAttribute.fromList( tangent, 4 ) );
if ( color.isNotEmpty ) simplifiedGeometry.setAttributeFromString( 'color', Float32BufferAttribute.fromList( color, 3 ) );
simplifiedGeometry.setIndex( indx );
return simplifiedGeometry;
}