Skip to content

Commit ddf8c98

Browse files
committed
MarchingCubes: Migrate to Mesh.
1 parent e57b777 commit ddf8c98

File tree

2 files changed

+46
-152
lines changed

2 files changed

+46
-152
lines changed

examples/jsm/objects/MarchingCubes.js

Lines changed: 45 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@ import {
22
BufferAttribute,
33
BufferGeometry,
44
Color,
5-
ImmediateRenderObject,
6-
NoColors
5+
DynamicDrawUsage,
6+
Mesh
77
} from '../../../build/three.module.js';
88

99
/**
1010
* Port of http://webglsamples.org/blob/blob.html
1111
*/
1212

13-
class MarchingCubes extends ImmediateRenderObject {
13+
class MarchingCubes extends Mesh {
1414

15-
constructor( resolution, material, enableUvs, enableColors ) {
15+
constructor( resolution, material, enableUvs = false, enableColors = false, maxPolyCount = 10000 ) {
1616

17-
super( material );
17+
const geometry = new BufferGeometry();
18+
19+
super( geometry, material );
1820

1921
const scope = this;
2022

@@ -24,8 +26,8 @@ class MarchingCubes extends ImmediateRenderObject {
2426
const nlist = new Float32Array( 12 * 3 );
2527
const clist = new Float32Array( 12 * 3 );
2628

27-
this.enableUvs = enableUvs !== undefined ? enableUvs : false;
28-
this.enableColors = enableColors !== undefined ? enableColors : false;
29+
this.enableUvs = enableUvs;
30+
this.enableColors = enableColors;
2931

3032
// functions have to be object properties
3133
// prototype functions kill performance
@@ -56,28 +58,37 @@ class MarchingCubes extends ImmediateRenderObject {
5658
this.normal_cache = new Float32Array( this.size3 * 3 );
5759
this.palette = new Float32Array( this.size3 * 3 );
5860

59-
// immediate render mode simulator
61+
//
6062

61-
this.maxCount = 4096; // TODO: find the fastest size for this buffer
6263
this.count = 0;
6364

64-
this.hasPositions = false;
65-
this.hasNormals = false;
66-
this.hasColors = false;
67-
this.hasUvs = false;
65+
const maxVertexCount = maxPolyCount * 3;
66+
67+
this.positionArray = new Float32Array( maxVertexCount * 3 );
68+
const positionAttribute = new BufferAttribute( this.positionArray, 3 );
69+
positionAttribute.setUsage( DynamicDrawUsage );
70+
geometry.setAttribute( 'position', positionAttribute );
6871

69-
this.positionArray = new Float32Array( this.maxCount * 3 );
70-
this.normalArray = new Float32Array( this.maxCount * 3 );
72+
this.normalArray = new Float32Array( maxVertexCount * 3 );
73+
const normalAttribute = new BufferAttribute( this.normalArray, 3 );
74+
normalAttribute.setUsage( DynamicDrawUsage );
75+
geometry.setAttribute( 'normal', normalAttribute );
7176

7277
if ( this.enableUvs ) {
7378

74-
this.uvArray = new Float32Array( this.maxCount * 2 );
79+
this.uvArray = new Float32Array( maxVertexCount * 2 );
80+
const uvAttribute = new BufferAttribute( this.uvArray, 2 );
81+
uvAttribute.setUsage( DynamicDrawUsage );
82+
geometry.setAttribute( 'uv', uvAttribute );
7583

7684
}
7785

7886
if ( this.enableColors ) {
7987

80-
this.colorArray = new Float32Array( this.maxCount * 3 );
88+
this.colorArray = new Float32Array( maxVertexCount * 3 );
89+
const colorAttribute = new BufferAttribute( this.colorArray, 3 );
90+
colorAttribute.setUsage( DynamicDrawUsage );
91+
geometry.setAttribute( 'color', colorAttribute );
8192

8293
}
8394

@@ -173,7 +184,7 @@ class MarchingCubes extends ImmediateRenderObject {
173184
// Returns total number of triangles. Fills triangles.
174185
// (this is where most of time is spent - it's inner work of O(n3) loop )
175186

176-
function polygonize( fx, fy, fz, q, isol, renderCallback ) {
187+
function polygonize( fx, fy, fz, q, isol ) {
177188

178189
// cache indices
179190
const q1 = q + 1,
@@ -369,8 +380,7 @@ class MarchingCubes extends ImmediateRenderObject {
369380
clist,
370381
3 * triTable[ o1 ],
371382
3 * triTable[ o2 ],
372-
3 * triTable[ o3 ],
373-
renderCallback
383+
3 * triTable[ o3 ]
374384
);
375385

376386
i += 3;
@@ -382,11 +392,7 @@ class MarchingCubes extends ImmediateRenderObject {
382392

383393
}
384394

385-
/////////////////////////////////////
386-
// Immediate render mode simulator
387-
/////////////////////////////////////
388-
389-
function posnormtriv( pos, norm, colors, o1, o2, o3, renderCallback ) {
395+
function posnormtriv( pos, norm, colors, o1, o2, o3 ) {
390396

391397
const c = scope.count * 3;
392398

@@ -477,69 +483,8 @@ class MarchingCubes extends ImmediateRenderObject {
477483

478484
scope.count += 3;
479485

480-
if ( scope.count >= scope.maxCount - 3 ) {
481-
482-
scope.hasPositions = true;
483-
scope.hasNormals = true;
484-
485-
if ( scope.enableUvs ) {
486-
487-
scope.hasUvs = true;
488-
489-
}
490-
491-
if ( scope.enableColors ) {
492-
493-
scope.hasColors = true;
494-
495-
}
496-
497-
renderCallback( scope );
498-
499-
}
500-
501486
}
502487

503-
this.begin = function () {
504-
505-
this.count = 0;
506-
507-
this.hasPositions = false;
508-
this.hasNormals = false;
509-
this.hasUvs = false;
510-
this.hasColors = false;
511-
512-
};
513-
514-
this.end = function ( renderCallback ) {
515-
516-
if ( this.count === 0 ) return;
517-
518-
for ( let i = this.count * 3; i < this.positionArray.length; i ++ ) {
519-
520-
this.positionArray[ i ] = 0.0;
521-
522-
}
523-
524-
this.hasPositions = true;
525-
this.hasNormals = true;
526-
527-
if ( this.enableUvs && this.material.map ) {
528-
529-
this.hasUvs = true;
530-
531-
}
532-
533-
if ( this.enableColors && this.material.vertexColors !== NoColors ) {
534-
535-
this.hasColors = true;
536-
537-
}
538-
539-
renderCallback( this );
540-
541-
};
542-
543488
/////////////////////////////////////
544489
// Metaballs
545490
/////////////////////////////////////
@@ -867,9 +812,9 @@ class MarchingCubes extends ImmediateRenderObject {
867812

868813
};
869814

870-
this.render = function ( renderCallback ) {
815+
this.onBeforeRender = function () {
871816

872-
this.begin();
817+
this.count = 0;
873818

874819
// Triangulate. Yeah, this is slow.
875820

@@ -890,84 +835,33 @@ class MarchingCubes extends ImmediateRenderObject {
890835
const fx = ( x - this.halfsize ) / this.halfsize; //+ 1
891836
const q = y_offset + x;
892837

893-
polygonize( fx, fy, fz, q, this.isolation, renderCallback );
838+
polygonize( fx, fy, fz, q, this.isolation );
894839

895840
}
896841

897842
}
898843

899844
}
900845

901-
this.end( renderCallback );
846+
// reset unneeded data
902847

903-
};
848+
for ( let i = this.count * 3; i < this.positionArray.length; i ++ ) {
904849

905-
this.generateGeometry = function () {
850+
this.positionArray[ i ] = 0.0;
906851

907-
console.warn(
908-
'THREE.MarchingCubes: generateGeometry() now returns BufferGeometry'
909-
);
910-
return this.generateBufferGeometry();
852+
}
911853

912-
};
854+
// update geometry data
913855

914-
function concatenate( a, b, length ) {
856+
geometry.getAttribute( 'position' ).needsUpdate = true;
857+
geometry.getAttribute( 'normal' ).needsUpdate = true;
915858

916-
const result = new Float32Array( a.length + length );
917-
result.set( a, 0 );
918-
result.set( b.slice( 0, length ), a.length );
919-
return result;
859+
if ( this.enableUvs ) geometry.getAttribute( 'uv' ).needsUpdate = true;
860+
if ( this.enableColors ) geometry.getAttribute( 'color' ).needsUpdate = true;
920861

921-
}
862+
// safety check
922863

923-
this.generateBufferGeometry = function () {
924-
925-
const geo = new BufferGeometry();
926-
let posArray = new Float32Array();
927-
let normArray = new Float32Array();
928-
let colorArray = new Float32Array();
929-
let uvArray = new Float32Array();
930-
const scope = this;
931-
932-
const geo_callback = function ( object ) {
933-
934-
if ( scope.hasPositions )
935-
posArray = concatenate(
936-
posArray,
937-
object.positionArray,
938-
object.count * 3
939-
);
940-
if ( scope.hasNormals )
941-
normArray = concatenate(
942-
normArray,
943-
object.normalArray,
944-
object.count * 3
945-
);
946-
if ( scope.hasColors )
947-
colorArray = concatenate(
948-
colorArray,
949-
object.colorArray,
950-
object.count * 3
951-
);
952-
if ( scope.hasUvs )
953-
uvArray = concatenate( uvArray, object.uvArray, object.count * 2 );
954-
955-
object.count = 0;
956-
957-
};
958-
959-
this.render( geo_callback );
960-
961-
if ( this.hasPositions )
962-
geo.setAttribute( 'position', new BufferAttribute( posArray, 3 ) );
963-
if ( this.hasNormals )
964-
geo.setAttribute( 'normal', new BufferAttribute( normArray, 3 ) );
965-
if ( this.hasColors )
966-
geo.setAttribute( 'color', new BufferAttribute( colorArray, 3 ) );
967-
if ( this.hasUvs )
968-
geo.setAttribute( 'uv', new BufferAttribute( uvArray, 2 ) );
969-
970-
return geo;
864+
if ( this.count / 3 > maxPolyCount ) console.warn( 'THREE.MarchingCubes: Geometry buffers too small for rendering. Please create an instance with a higher poly count.' );
971865

972866
};
973867

examples/webxr_vr_sculpt.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@
157157
transparent: true
158158
} );
159159

160-
blob = new MarchingCubes( 64, material );
160+
blob = new MarchingCubes( 64, material, false, false, 500000 );
161161
blob.position.y = 1;
162162
scene.add( blob );
163163

0 commit comments

Comments
 (0)