mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-27 20:34:43 +01:00
Light work
- Track the min/max sections contraptions reported themselves in - When the current min/max sections don't match, invoke the notifier - Track the min/max block positions contraptions collected light from - When the current min/max positions don't match, re-collect all light - Invalidate light before collecting
This commit is contained in:
parent
99b886ce15
commit
42b1e19fc8
1 changed files with 87 additions and 27 deletions
|
@ -47,15 +47,19 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
|
|||
import net.minecraftforge.client.model.data.ModelData;
|
||||
|
||||
public class ContraptionVisual<E extends AbstractContraptionEntity> extends AbstractEntityVisual<E> implements DynamicVisual, TickableVisual, LitVisual {
|
||||
protected static final int LIGHT_PADDING = 1;
|
||||
|
||||
protected final VisualEmbedding embedding;
|
||||
private final List<BlockEntityVisual<?>> children = new ArrayList<>();
|
||||
private final List<ActorVisual> actors = new ArrayList<>();
|
||||
private final PlanMap<DynamicVisual, VisualFrameContext> dynamicVisuals = new PlanMap<>();
|
||||
private final PlanMap<TickableVisual, VisualTickContext> tickableVisuals = new PlanMap<>();
|
||||
private VirtualRenderWorld virtualRenderWorld;
|
||||
private Notifier notifier;
|
||||
private Model model;
|
||||
private TransformedInstance structure;
|
||||
protected final List<BlockEntityVisual<?>> children = new ArrayList<>();
|
||||
protected final List<ActorVisual> actors = new ArrayList<>();
|
||||
protected final PlanMap<DynamicVisual, VisualFrameContext> dynamicVisuals = new PlanMap<>();
|
||||
protected final PlanMap<TickableVisual, VisualTickContext> tickableVisuals = new PlanMap<>();
|
||||
protected VirtualRenderWorld virtualRenderWorld;
|
||||
protected Model model;
|
||||
protected TransformedInstance structure;
|
||||
protected Notifier notifier;
|
||||
protected long minSection, maxSection;
|
||||
protected long minBlock, maxBlock;
|
||||
|
||||
private final PoseStack contraptionMatrix = new PoseStack();
|
||||
|
||||
|
@ -171,7 +175,16 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
|
|||
var partialTick = context.partialTick();
|
||||
setEmbeddingMatrices(partialTick);
|
||||
|
||||
// TODO: re-collect light if needed
|
||||
if (hasMovedSections()) {
|
||||
notifier.notifySectionsChanged();
|
||||
}
|
||||
|
||||
if (hasMovedBlocks()) {
|
||||
// TODO: incremental light collection
|
||||
// TODO: optimize light collection for very large contraptions
|
||||
// by only collecting cuboids that contain faces
|
||||
updateLight();
|
||||
}
|
||||
}
|
||||
|
||||
private void setEmbeddingMatrices(float partialTick) {
|
||||
|
@ -188,42 +201,73 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
|
|||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
embedding.invalidateLight();
|
||||
// FIXME: Some blocks (e.g. large waterwheels) extend well beyond their actual block
|
||||
// and might have lighting issues here
|
||||
var boundingBox = entity.getBoundingBox();
|
||||
|
||||
int minX = Mth.floor(boundingBox.minX) - 1;
|
||||
int minY = Mth.floor(boundingBox.minY) - 1;
|
||||
int minZ = Mth.floor(boundingBox.minZ) - 1;
|
||||
int sizeX = Mth.ceil(boundingBox.maxX) - minX + 2;
|
||||
int sizeY = Mth.ceil(boundingBox.maxY) - minY + 2;
|
||||
int sizeZ = Mth.ceil(boundingBox.maxZ) - minZ + 2;
|
||||
int minX = minLight(boundingBox.minX);
|
||||
int minY = minLight(boundingBox.minY);
|
||||
int minZ = minLight(boundingBox.minZ);
|
||||
int maxX = maxLight(boundingBox.maxX);
|
||||
int maxY = maxLight(boundingBox.maxY);
|
||||
int maxZ = maxLight(boundingBox.maxZ);
|
||||
|
||||
embedding.collectLight(level, minX, minY, minZ, sizeX, sizeY, sizeZ);
|
||||
minBlock = BlockPos.asLong(minX, minY, minZ);
|
||||
maxBlock = BlockPos.asLong(maxX, maxY, maxZ);
|
||||
|
||||
embedding.collectLight(level, minX, minY, minZ, maxX - minX, maxY - minY, maxZ - minZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectLightSections(LongConsumer consumer) {
|
||||
var boundingBox = entity.getBoundingBox();
|
||||
|
||||
int minX = Mth.floor(boundingBox.minX) - 1;
|
||||
int minY = Mth.floor(boundingBox.minY) - 1;
|
||||
int minZ = Mth.floor(boundingBox.minZ) - 1;
|
||||
int sizeXChunks = SectionPos.blockToSectionCoord(Mth.ceil(boundingBox.maxX) - minX + 2) + 1;
|
||||
int sizeYChunks = SectionPos.blockToSectionCoord(Mth.ceil(boundingBox.maxY) - minY + 2) + 1;
|
||||
int sizeZChunks = SectionPos.blockToSectionCoord(Mth.ceil(boundingBox.maxZ) - minZ + 2) + 1;
|
||||
var minSectionX = minLightSection(boundingBox.minX);
|
||||
var minSectionY = minLightSection(boundingBox.minY);
|
||||
var minSectionZ = minLightSection(boundingBox.minZ);
|
||||
int maxSectionX = maxLightSection(boundingBox.maxX);
|
||||
int maxSectionY = maxLightSection(boundingBox.maxY);
|
||||
int maxSectionZ = maxLightSection(boundingBox.maxZ);
|
||||
|
||||
var base = SectionPos.asLong(SectionPos.blockToSectionCoord(minX), SectionPos.blockToSectionCoord(minY), SectionPos.blockToSectionCoord(minZ));
|
||||
minSection = SectionPos.asLong(minSectionX, minSectionY, minSectionZ);
|
||||
maxSection = SectionPos.asLong(maxSectionX, maxSectionY, maxSectionZ);
|
||||
|
||||
for (int x = 0; x < sizeXChunks; x++) {
|
||||
for (int y = 0; y < sizeYChunks; y++) {
|
||||
for (int z = 0; z < sizeZChunks; z++) {
|
||||
consumer.accept(SectionPos.offset(base, x, y, z));
|
||||
for (int x = 0; x <= maxSectionX - minSectionX; x++) {
|
||||
for (int y = 0; y <= maxSectionY - minSectionY; y++) {
|
||||
for (int z = 0; z <= maxSectionZ - minSectionZ; z++) {
|
||||
consumer.accept(SectionPos.offset(minSection, x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasMovedBlocks() {
|
||||
var boundingBox = entity.getBoundingBox();
|
||||
|
||||
int minX = minLight(boundingBox.minX);
|
||||
int minY = minLight(boundingBox.minY);
|
||||
int minZ = minLight(boundingBox.minZ);
|
||||
int maxX = maxLight(boundingBox.maxX);
|
||||
int maxY = maxLight(boundingBox.maxY);
|
||||
int maxZ = maxLight(boundingBox.maxZ);
|
||||
|
||||
return minBlock != BlockPos.asLong(minX, minY, minZ) || maxBlock != BlockPos.asLong(maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
protected boolean hasMovedSections() {
|
||||
var boundingBox = entity.getBoundingBox();
|
||||
|
||||
var minSectionX = minLightSection(boundingBox.minX);
|
||||
var minSectionY = minLightSection(boundingBox.minY);
|
||||
var minSectionZ = minLightSection(boundingBox.minZ);
|
||||
int maxSectionX = maxLightSection(boundingBox.maxX);
|
||||
int maxSectionY = maxLightSection(boundingBox.maxY);
|
||||
int maxSectionZ = maxLightSection(boundingBox.maxZ);
|
||||
|
||||
return minSection != SectionPos.asLong(minSectionX, minSectionY, minSectionZ) || maxSection != SectionPos.asLong(maxSectionX, maxSectionY, maxSectionZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initLightSectionNotifier(Notifier notifier) {
|
||||
this.notifier = notifier;
|
||||
|
@ -243,4 +287,20 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
|
|||
structure.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static int minLight(double aabbPos) {
|
||||
return Mth.floor(aabbPos) - LIGHT_PADDING;
|
||||
}
|
||||
|
||||
public static int maxLight(double aabbPos) {
|
||||
return Mth.ceil(aabbPos) + LIGHT_PADDING;
|
||||
}
|
||||
|
||||
public static int minLightSection(double aabbPos) {
|
||||
return SectionPos.blockToSectionCoord(minLight(aabbPos));
|
||||
}
|
||||
|
||||
public static int maxLightSection(double aabbPos) {
|
||||
return SectionPos.blockToSectionCoord(maxLight(aabbPos));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue