33
33
import net .minecraft .client .renderer .entity .state .EntityRenderState ;
34
34
import net .minecraft .client .resources .model .ModelBakery ;
35
35
import net .minecraft .core .BlockPos ;
36
- import net .minecraft .core .SectionPos ;
37
36
import net .minecraft .server .level .BlockDestructionProgress ;
38
37
import net .minecraft .util .Mth ;
39
38
import net .minecraft .util .profiling .Profiler ;
@@ -191,48 +190,45 @@ public void setupTerrain(Camera camera,
191
190
float fogDistance = RenderSystem .getShaderFog ().end ();
192
191
193
192
if (this .lastCameraPos == null ) {
194
- this .lastCameraPos = new Vector3d ( pos ) ;
193
+ this .lastCameraPos = pos ;
195
194
}
196
195
if (this .lastProjectionMatrix == null ) {
197
196
this .lastProjectionMatrix = new Matrix4f (projectionMatrix );
198
197
}
199
198
boolean cameraLocationChanged = !pos .equals (this .lastCameraPos );
200
199
boolean cameraAngleChanged = pitch != this .lastCameraPitch || yaw != this .lastCameraYaw || fogDistance != this .lastFogDistance ;
201
- boolean cameraProjectionChanged = !projectionMatrix .equals (this .lastProjectionMatrix );
200
+ boolean cameraProjectionChanged = !projectionMatrix .equals (this .lastProjectionMatrix , 0.0001f );
202
201
203
202
this .lastProjectionMatrix = projectionMatrix ;
204
203
205
204
this .lastCameraPitch = pitch ;
206
205
this .lastCameraYaw = yaw ;
207
206
208
207
if (cameraLocationChanged || cameraAngleChanged || cameraProjectionChanged ) {
209
- this .renderSectionManager .markGraphDirty ();
208
+ this .renderSectionManager .notifyChangedCamera ();
210
209
}
211
210
212
211
this .lastFogDistance = fogDistance ;
213
212
214
- this .renderSectionManager .updateCameraState (pos , camera );
213
+ this .renderSectionManager .prepareFrame (pos );
215
214
216
215
if (cameraLocationChanged ) {
217
216
profiler .popPush ("translucent_triggering" );
218
217
219
218
this .renderSectionManager .processGFNIMovement (new CameraMovement (this .lastCameraPos , pos ));
220
- this .lastCameraPos = new Vector3d ( pos ) ;
219
+ this .lastCameraPos = pos ;
221
220
}
222
221
223
222
int maxChunkUpdates = updateChunksImmediately ? this .renderDistance : 1 ;
224
-
225
223
for (int i = 0 ; i < maxChunkUpdates ; i ++) {
226
- if (this .renderSectionManager .needsUpdate ()) {
227
- profiler .popPush ("chunk_render_lists" );
224
+ profiler .popPush ("chunk_render_lists" );
228
225
229
- this .renderSectionManager .update (camera , viewport , fogParameters , spectator );
230
- }
226
+ this .renderSectionManager .updateRenderLists (camera , viewport , fogParameters , spectator , updateChunksImmediately );
231
227
232
228
profiler .popPush ("chunk_update" );
233
229
234
230
this .renderSectionManager .cleanupAndFlip ();
235
- this .renderSectionManager .updateChunks (updateChunksImmediately );
231
+ this .renderSectionManager .updateChunks (viewport , updateChunksImmediately );
236
232
237
233
profiler .popPush ("chunk_upload" );
238
234
@@ -253,6 +249,7 @@ public void setupTerrain(Camera camera,
253
249
}
254
250
255
251
private void processChunkEvents () {
252
+ this .renderSectionManager .beforeSectionUpdates ();
256
253
var tracker = ChunkTrackerHolder .get (this .level );
257
254
tracker .forEachEvent (this .renderSectionManager ::onChunkAdded , this .renderSectionManager ::onChunkRemoved );
258
255
}
@@ -343,9 +340,8 @@ private void renderBlockEntities(PoseStack matrices,
343
340
344
341
while (renderSectionIterator .hasNext ()) {
345
342
var renderSectionId = renderSectionIterator .nextByteAsInt ();
346
- var renderSection = renderRegion .getSection (renderSectionId );
347
343
348
- var blockEntities = renderSection .getCulledBlockEntities ();
344
+ var blockEntities = renderRegion .getCulledBlockEntities (renderSectionId );
349
345
350
346
if (blockEntities == null ) {
351
347
continue ;
@@ -370,7 +366,7 @@ private void renderGlobalBlockEntities(PoseStack matrices,
370
366
LocalPlayer player ,
371
367
LocalBooleanRef isGlowing ) {
372
368
for (var renderSection : this .renderSectionManager .getSectionsWithGlobalEntities ()) {
373
- var blockEntities = renderSection .getGlobalBlockEntities ();
369
+ var blockEntities = renderSection .getRegion (). getGlobalBlockEntities (renderSection . getSectionIndex () );
374
370
375
371
if (blockEntities == null ) {
376
372
continue ;
@@ -444,9 +440,7 @@ public void iterateVisibleBlockEntities(Consumer<BlockEntity> blockEntityConsume
444
440
445
441
while (renderSectionIterator .hasNext ()) {
446
442
var renderSectionId = renderSectionIterator .nextByteAsInt ();
447
- var renderSection = renderRegion .getSection (renderSectionId );
448
-
449
- var blockEntities = renderSection .getCulledBlockEntities ();
443
+ var blockEntities = renderRegion .getCulledBlockEntities (renderSectionId );
450
444
451
445
if (blockEntities == null ) {
452
446
continue ;
@@ -459,7 +453,7 @@ public void iterateVisibleBlockEntities(Consumer<BlockEntity> blockEntityConsume
459
453
}
460
454
461
455
for (var renderSection : this .renderSectionManager .getSectionsWithGlobalEntities ()) {
462
- var blockEntities = renderSection .getGlobalBlockEntities ();
456
+ var blockEntities = renderSection .getRegion (). getGlobalBlockEntities (renderSection . getSectionIndex () );
463
457
464
458
if (blockEntities == null ) {
465
459
continue ;
@@ -472,10 +466,13 @@ public void iterateVisibleBlockEntities(Consumer<BlockEntity> blockEntityConsume
472
466
}
473
467
474
468
// the volume of a section multiplied by the number of sections to be checked at most
475
- private static final double MAX_ENTITY_CHECK_VOLUME = 16 * 16 * 16 * 15 ;
469
+ private static final double MAX_ENTITY_CHECK_VOLUME = 16 * 16 * 16 * 50 ;
476
470
477
471
/**
478
472
* Returns whether the entity intersects with any visible chunks in the graph.
473
+ *
474
+ * Note that this method assumes the entity is within the frustum. It does not perform a frustum check.
475
+ *
479
476
* @return True if the entity is visible, otherwise false
480
477
*/
481
478
public <T extends Entity , S extends EntityRenderState > boolean isEntityVisible (EntityRenderer <T , S > renderer , T entity ) {
@@ -493,7 +490,7 @@ public <T extends Entity, S extends EntityRenderState> boolean isEntityVisible(E
493
490
// bail on very large entities to avoid checking many sections
494
491
double entityVolume = (bb .maxX - bb .minX ) * (bb .maxY - bb .minY ) * (bb .maxZ - bb .minZ );
495
492
if (entityVolume > MAX_ENTITY_CHECK_VOLUME ) {
496
- // TODO: do a frustum check instead, even large entities aren't visible if they're outside the frustum
493
+ // large entities are only frustum tested, their sections are not checked for visibility
497
494
return true ;
498
495
}
499
496
@@ -507,48 +504,28 @@ public boolean isBoxVisible(double x1, double y1, double z1, double x2, double y
507
504
return true ;
508
505
}
509
506
510
- int minX = SectionPos .posToSectionCoord (x1 - 0.5D );
511
- int minY = SectionPos .posToSectionCoord (y1 - 0.5D );
512
- int minZ = SectionPos .posToSectionCoord (z1 - 0.5D );
513
-
514
- int maxX = SectionPos .posToSectionCoord (x2 + 0.5D );
515
- int maxY = SectionPos .posToSectionCoord (y2 + 0.5D );
516
- int maxZ = SectionPos .posToSectionCoord (z2 + 0.5D );
517
-
518
- for (int x = minX ; x <= maxX ; x ++) {
519
- for (int z = minZ ; z <= maxZ ; z ++) {
520
- for (int y = minY ; y <= maxY ; y ++) {
521
- if (this .renderSectionManager .isSectionVisible (x , y , z )) {
522
- return true ;
523
- }
524
- }
525
- }
526
- }
527
-
528
- return false ;
507
+ return this .renderSectionManager .isBoxVisible (x1 , y1 , z1 , x2 , y2 , z2 );
529
508
}
530
509
531
510
public String getChunksDebugString () {
532
- // C: visible/total D: distance
533
- // TODO: add dirty and queued counts
534
- return String .format ("C: %d/%d D: %d" , this .renderSectionManager .getVisibleChunkCount (), this .renderSectionManager .getTotalSections (), this .renderDistance );
511
+ return this .renderSectionManager .getChunksDebugString ();
535
512
}
536
513
537
514
/**
538
515
* Schedules chunk rebuilds for all chunks in the specified block region.
539
516
*/
540
- public void scheduleRebuildForBlockArea (int minX , int minY , int minZ , int maxX , int maxY , int maxZ , boolean important ) {
541
- this .scheduleRebuildForChunks (minX >> 4 , minY >> 4 , minZ >> 4 , maxX >> 4 , maxY >> 4 , maxZ >> 4 , important );
517
+ public void scheduleRebuildForBlockArea (int minX , int minY , int minZ , int maxX , int maxY , int maxZ , boolean playerChanged ) {
518
+ this .scheduleRebuildForChunks (minX >> 4 , minY >> 4 , minZ >> 4 , maxX >> 4 , maxY >> 4 , maxZ >> 4 , playerChanged );
542
519
}
543
520
544
521
/**
545
522
* Schedules chunk rebuilds for all chunks in the specified chunk region.
546
523
*/
547
- public void scheduleRebuildForChunks (int minX , int minY , int minZ , int maxX , int maxY , int maxZ , boolean important ) {
524
+ public void scheduleRebuildForChunks (int minX , int minY , int minZ , int maxX , int maxY , int maxZ , boolean playerChanged ) {
548
525
for (int chunkX = minX ; chunkX <= maxX ; chunkX ++) {
549
526
for (int chunkY = minY ; chunkY <= maxY ; chunkY ++) {
550
527
for (int chunkZ = minZ ; chunkZ <= maxZ ; chunkZ ++) {
551
- this .scheduleRebuildForChunk (chunkX , chunkY , chunkZ , important );
528
+ this .scheduleRebuildForChunk (chunkX , chunkY , chunkZ , playerChanged );
552
529
}
553
530
}
554
531
}
@@ -557,8 +534,8 @@ public void scheduleRebuildForChunks(int minX, int minY, int minZ, int maxX, int
557
534
/**
558
535
* Schedules a chunk rebuild for the render belonging to the given chunk section position.
559
536
*/
560
- public void scheduleRebuildForChunk (int x , int y , int z , boolean important ) {
561
- this .renderSectionManager .scheduleRebuild (x , y , z , important );
537
+ public void scheduleRebuildForChunk (int x , int y , int z , boolean playerChanged ) {
538
+ this .renderSectionManager .scheduleRebuild (x , y , z , playerChanged );
562
539
}
563
540
564
541
public Collection <String > getDebugStrings () {
0 commit comments