@@ -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
0 commit comments