1
1
package dev .engine_room .flywheel .backend .engine ;
2
2
3
3
import java .util .BitSet ;
4
+ import java .util .Objects ;
4
5
5
6
import org .jetbrains .annotations .Nullable ;
6
7
import org .lwjgl .system .MemoryUtil ;
34
35
import net .minecraft .world .level .LevelAccessor ;
35
36
import net .minecraft .world .level .LightLayer ;
36
37
import net .minecraft .world .level .chunk .DataLayer ;
38
+ import net .minecraft .world .level .lighting .LayerLightEventListener ;
37
39
38
40
/**
39
41
* A managed arena of light sections for uploading to the GPU.
@@ -57,8 +59,8 @@ public class LightStorage implements Effect {
57
59
private static final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64 ;
58
60
private static final int INVALID_SECTION = -1 ;
59
61
60
- private static final ConstantDataLayer EMPTY_BLOCK_DATA = new ConstantDataLayer (0 );
61
- private static final ConstantDataLayer EMPTY_SKY_DATA = new ConstantDataLayer (15 );
62
+ private static final ConstantDataLayer ALWAYS_0 = new ConstantDataLayer (0 );
63
+ private static final ConstantDataLayer ALWAYS_15 = new ConstantDataLayer (15 );
62
64
63
65
private final LevelAccessor level ;
64
66
private final LightLut lut ;
@@ -268,29 +270,51 @@ private void collectSolidData(long ptr, long section) {
268
270
}
269
271
270
272
private DataLayer getSkyData (long section ) {
271
- var sky = level .getLightEngine ()
273
+ var layerListener = level .getLightEngine ()
272
274
.getLayerListener (LightLayer .SKY );
273
- var skyStorage = (SkyLightSectionStorageExtension ) ((LightEngineAccessor <?, ?>) sky ).flywheel$storage ();
274
275
275
- var out = skyStorage .flywheel$skyDataLayer (section );
276
+ if (layerListener == LayerLightEventListener .DummyLightLayerEventListener .INSTANCE ) {
277
+ // The dummy listener always returns 0.
278
+ // In vanilla this happens in the nether and end,
279
+ // and the light texture is simply updated
280
+ // to be invariant on sky light.
281
+ return ALWAYS_0 ;
282
+ }
283
+
284
+ if (layerListener instanceof LightEngineAccessor <?, ?> accessor ) {
285
+ // Sky storage has a fancy way to get the sky light at a given block position, but the logic is not
286
+ // implemented in vanilla for fetching data layers directly. We need to re-implement it here. The simplest
287
+ // way to do it was to expose the same logic via an extension method. Re-implementing it external to the
288
+ // SkyLightSectionStorage class would require many more accessors.
289
+ if (accessor .flywheel$storage () instanceof SkyLightSectionStorageExtension skyStorage ) {
290
+ var out = skyStorage .flywheel$skyDataLayer (section );
276
291
277
- if (out == null ) {
278
- return EMPTY_SKY_DATA ;
292
+ // Null section here means there are no blocks above us to darken this section.
293
+ return Objects .requireNonNullElse (out , ALWAYS_15 );
294
+ }
279
295
}
280
296
281
- return out ;
297
+ // FIXME: We're likely in some exotic dimension that needs special handling.
298
+ return ALWAYS_0 ;
282
299
}
283
300
284
301
private DataLayer getBlockData (long section ) {
285
- var out = ((LightEngineAccessor <?, ?>) level .getLightEngine ()
286
- .getLayerListener (LightLayer .BLOCK )).flywheel$storage ()
287
- .getDataLayerData (section );
302
+ var layerListener = level .getLightEngine ()
303
+ .getLayerListener (LightLayer .BLOCK );
288
304
289
- if (out == null ) {
290
- return EMPTY_BLOCK_DATA ;
305
+ if (layerListener == LayerLightEventListener . DummyLightLayerEventListener . INSTANCE ) {
306
+ return ALWAYS_0 ;
291
307
}
292
308
293
- return out ;
309
+ if (layerListener instanceof LightEngineAccessor <?, ?> accessor ) {
310
+ var out = accessor .flywheel$storage ()
311
+ .getDataLayerData (section );
312
+
313
+ return Objects .requireNonNullElse (out , ALWAYS_0 );
314
+ }
315
+
316
+ // FIXME: We're likely in some exotic dimension that needs special handling.
317
+ return ALWAYS_0 ;
294
318
}
295
319
296
320
private void collectXStrip (long ptr , long section , SectionEdge y , SectionEdge z ) {
0 commit comments