11import { ChunkTerrain } from "./ChunkTerrain.js" ;
22import { ChunkMesher } from "./ChunkMesher.js" ;
3+ import vec3 from "vec3" ;
34
45var terrain = null ;
56
@@ -8,8 +9,6 @@ class TerrainManager {
89 this . chunkTerrain = new ChunkTerrain ( {
910 blocksDef : data . blocksDef ,
1011 } ) ;
11- this . chunkNeedsUpdate = { } ;
12- this . loadedMeshes = { } ;
1312 this . chunkMesher = new ChunkMesher ( {
1413 blocksTex : data . blocksTex ,
1514 blocksMapping : data . blocksMapping ,
@@ -24,114 +23,135 @@ class TerrainManager {
2423 [ 0 , 0 , - 1 ] ,
2524 [ 0 , 0 , 1 ] ,
2625 ] ;
26+ this . states = {
27+ needsUpdate : 0 ,
28+ disposed : 1 ,
29+ } ;
30+ this . chunkState = { } ;
31+ this . generatedChunks = { } ;
32+ this . renderRadius = 10 ;
33+ this . playerChunk = [ 0 , 0 , 0 ] ;
34+ this . loop ( ) ;
2735 }
36+
37+ distance ( chunkId ) {
38+ var data = this . chunkTerrain . strToVec ( chunkId ) ;
39+ var chunk = vec3 ( ...data ) ;
40+ var chunkP = vec3 ( ...this . playerChunk ) ;
41+ return chunkP . distanceTo ( chunk ) ;
42+ }
43+
2844 setVoxel ( data ) {
2945 this . chunkTerrain . setVoxel ( ...data ) ;
30- var chunkId = this . chunkTerrain . vec3 (
46+ var chunkId = this . chunkTerrain . vecToStr (
3147 ...terrain . chunkTerrain . computeChunkForVoxel (
3248 data [ 0 ] ,
3349 data [ 1 ] ,
3450 data [ 2 ]
3551 )
3652 ) ;
37- this . chunkNeedsUpdate [ chunkId ] = true ;
53+ this . chunkState [ chunkId ] = this . states . needsUpdate ;
3854 for ( var l = 0 ; l < this . neighbours . length ; l ++ ) {
3955 var nei = this . neighbours [ l ] ;
40- var neiChunkId = this . chunkTerrain . vec3 (
56+ var neiChunkId = this . chunkTerrain . vecToStr (
4157 ...this . chunkTerrain . computeChunkForVoxel (
4258 data [ 0 ] + nei [ 0 ] ,
4359 data [ 1 ] + nei [ 1 ] ,
4460 data [ 2 ] + nei [ 2 ]
4561 )
4662 ) ;
47- this . chunkNeedsUpdate [ neiChunkId ] = true ;
63+ this . chunkState [ neiChunkId ] = this . states . needsUpdate ;
4864 }
4965 }
50- genChunkGeo ( data ) {
51- queueMicrotask ( ( ) => {
52- if (
53- this . chunkTerrain . vec3 ( ...data ) in this . chunkTerrain . chunks ===
54- true
55- ) {
56- var geo = this . chunkMesher . genChunkGeo ( ...data ) ;
57- postMessage ( {
58- type : "cellGeo" ,
59- data : {
60- cell : geo ,
61- info : data ,
62- p : performance . now ( ) ,
63- } ,
64- } ) ;
65- }
66- } ) ;
67- }
66+
6867 setChunk ( data ) {
69- this . chunkNeedsUpdate [
70- terrain . chunkTerrain . vec3 ( data [ 0 ] , data [ 1 ] , data [ 2 ] )
71- ] = true ;
7268 this . chunkTerrain . setChunk ( data [ 0 ] , data [ 1 ] , data [ 2 ] , data [ 3 ] ) ;
69+ var chunkId = terrain . chunkTerrain . vecToStr ( data [ 0 ] , data [ 1 ] , data [ 2 ] ) ;
70+ this . chunkState [ chunkId ] = this . states . needsUpdate ;
7371 for ( var l = 0 ; l < this . neighbours . length ; l ++ ) {
7472 var nei = this . neighbours [ l ] ;
75- var neiCellId = this . chunkTerrain . vec3 (
73+ var neiChunkId = this . chunkTerrain . vecToStr (
7674 data [ 0 ] + nei [ 0 ] ,
7775 data [ 1 ] + nei [ 1 ] ,
7876 data [ 2 ] + nei [ 2 ]
7977 ) ;
80- this . chunkNeedsUpdate [ neiCellId ] = true ;
78+ this . chunkState [ neiChunkId ] = this . states . needsUpdate ;
8179 }
8280 }
83- updateChunksAroundPlayer ( data ) {
84- var chunk = data [ 0 ] ;
85- var radius = data [ 1 ] ;
86- var odw = { } ;
87- var chunkBlackList = { } ;
88- for ( var k in this . loadedMeshes ) {
89- var v = this . loadedMeshes [ k ] ;
90- if ( v === true ) {
91- chunkBlackList [ k ] = true ;
81+
82+ sortQueue ( ) {
83+ this . chunkQueue . sort ( ( a , b ) => {
84+ var chunkA = vec3 ( ...this . chunkTerrain . strToVec ( a ) ) ;
85+ var chunkB = vec3 ( ...this . chunkTerrain . strToVec ( b ) ) ;
86+ var chunkP = vec3 ( ...this . playerChunk ) ;
87+ var roz1 = chunkP . distanceTo ( chunkA ) ;
88+ var roz2 = chunkP . distanceTo ( chunkB ) ;
89+ if ( roz1 < roz2 ) {
90+ return - 1 ;
91+ } else if ( roz1 > roz2 ) {
92+ return 1 ;
93+ } else {
94+ return 0 ;
9295 }
93- }
94- for ( var i = 0 ; i <= radius ; i ++ ) {
95- for ( var x = - i ; x <= i ; x ++ ) {
96- for ( var y = - i ; y <= i ; y ++ ) {
97- for ( var z = - i ; z <= i ; z ++ ) {
98- if ( ! odw [ `${ x } :${ y } :${ z } ` ] ) {
99- odw [ `${ x } :${ y } :${ z } ` ] = true ;
100- var pchunk = [
101- chunk [ 0 ] + x ,
102- chunk [ 1 ] + y ,
103- chunk [ 2 ] + z ,
104- ] ;
105- var chunkId = this . chunkTerrain . vec3 ( ...pchunk ) ;
106- chunkBlackList [ chunkId ] = false ;
107- var gen = false ;
108- if ( this . chunkNeedsUpdate [ chunkId ] ) {
109- delete terrain . chunkNeedsUpdate [ chunkId ] ;
110- this . genChunkGeo ( pchunk ) ;
111- gen = true ;
112- }
113- if ( this . loadedMeshes [ chunkId ] === "disposed" ) {
114- if ( ! gen ) {
115- this . genChunkGeo ( pchunk ) ;
116- }
117- }
118- this . loadedMeshes [ chunkId ] = true ;
119- }
120- }
121- }
96+ } ) ;
97+ }
98+
99+ genNearestChunk ( ) {
100+ var nearestChunkId = "" ;
101+ var nearestDistance = - 1 ;
102+ var isNearest = false ;
103+ for ( var chunkId in this . chunkState ) {
104+ var dist = this . distance ( chunkId ) ;
105+ if (
106+ ( nearestDistance === - 1 || nearestDistance > dist ) &&
107+ dist <= this . renderRadius
108+ ) {
109+ isNearest = true ;
110+ nearestDistance = dist ;
111+ nearestChunkId = chunkId ;
122112 }
123113 }
124- for ( k in chunkBlackList ) {
125- v = chunkBlackList [ k ] ;
126- if ( v === true ) {
127- this . loadedMeshes [ k ] = "disposed" ;
114+ if ( isNearest ) {
115+ var data = this . chunkTerrain . strToVec ( nearestChunkId ) ;
116+ this . generatedChunks [ nearestChunkId ] = true ;
117+ postMessage ( {
118+ type : "cellGeo" ,
119+ data : {
120+ cell : this . chunkMesher . genChunkGeo ( ...data ) ,
121+ info : data ,
122+ p : performance . now ( ) ,
123+ } ,
124+ } ) ;
125+ delete this . chunkState [ nearestChunkId ] ;
126+ }
127+ }
128+
129+ removeChunks ( ) {
130+ for ( var chunkId in this . generatedChunks ) {
131+ var dist = this . distance ( chunkId ) ;
132+ if ( dist > this . renderRadius ) {
133+ delete this . generatedChunks [ chunkId ] ;
134+ this . chunkState [ chunkId ] = this . states . disposed ;
128135 postMessage ( {
129136 type : "removeCell" ,
130- data : k ,
137+ data : chunkId ,
131138 } ) ;
132139 }
133140 }
134141 }
142+
143+ loop ( ) {
144+ this . removeChunks ( ) ;
145+ this . genNearestChunk ( ) ;
146+ requestAnimationFrame ( ( ) => {
147+ this . loop ( ) ;
148+ } ) ;
149+ }
150+
151+ updateChunksAroundPlayer ( data ) {
152+ this . playerChunk = data [ 0 ] ;
153+ this . renderRadius = data [ 1 ] ;
154+ }
135155}
136156
137157addEventListener ( "message" , function ( e ) {
0 commit comments