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;
|
import net.minecraftforge.client.model.data.ModelData;
|
||||||
|
|
||||||
public class ContraptionVisual<E extends AbstractContraptionEntity> extends AbstractEntityVisual<E> implements DynamicVisual, TickableVisual, LitVisual {
|
public class ContraptionVisual<E extends AbstractContraptionEntity> extends AbstractEntityVisual<E> implements DynamicVisual, TickableVisual, LitVisual {
|
||||||
|
protected static final int LIGHT_PADDING = 1;
|
||||||
|
|
||||||
protected final VisualEmbedding embedding;
|
protected final VisualEmbedding embedding;
|
||||||
private final List<BlockEntityVisual<?>> children = new ArrayList<>();
|
protected final List<BlockEntityVisual<?>> children = new ArrayList<>();
|
||||||
private final List<ActorVisual> actors = new ArrayList<>();
|
protected final List<ActorVisual> actors = new ArrayList<>();
|
||||||
private final PlanMap<DynamicVisual, VisualFrameContext> dynamicVisuals = new PlanMap<>();
|
protected final PlanMap<DynamicVisual, VisualFrameContext> dynamicVisuals = new PlanMap<>();
|
||||||
private final PlanMap<TickableVisual, VisualTickContext> tickableVisuals = new PlanMap<>();
|
protected final PlanMap<TickableVisual, VisualTickContext> tickableVisuals = new PlanMap<>();
|
||||||
private VirtualRenderWorld virtualRenderWorld;
|
protected VirtualRenderWorld virtualRenderWorld;
|
||||||
private Notifier notifier;
|
protected Model model;
|
||||||
private Model model;
|
protected TransformedInstance structure;
|
||||||
private TransformedInstance structure;
|
protected Notifier notifier;
|
||||||
|
protected long minSection, maxSection;
|
||||||
|
protected long minBlock, maxBlock;
|
||||||
|
|
||||||
private final PoseStack contraptionMatrix = new PoseStack();
|
private final PoseStack contraptionMatrix = new PoseStack();
|
||||||
|
|
||||||
|
@ -171,7 +175,16 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
|
||||||
var partialTick = context.partialTick();
|
var partialTick = context.partialTick();
|
||||||
setEmbeddingMatrices(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) {
|
private void setEmbeddingMatrices(float partialTick) {
|
||||||
|
@ -188,42 +201,73 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateLight() {
|
public void updateLight() {
|
||||||
|
embedding.invalidateLight();
|
||||||
// FIXME: Some blocks (e.g. large waterwheels) extend well beyond their actual block
|
// FIXME: Some blocks (e.g. large waterwheels) extend well beyond their actual block
|
||||||
// and might have lighting issues here
|
// and might have lighting issues here
|
||||||
var boundingBox = entity.getBoundingBox();
|
var boundingBox = entity.getBoundingBox();
|
||||||
|
|
||||||
int minX = Mth.floor(boundingBox.minX) - 1;
|
int minX = minLight(boundingBox.minX);
|
||||||
int minY = Mth.floor(boundingBox.minY) - 1;
|
int minY = minLight(boundingBox.minY);
|
||||||
int minZ = Mth.floor(boundingBox.minZ) - 1;
|
int minZ = minLight(boundingBox.minZ);
|
||||||
int sizeX = Mth.ceil(boundingBox.maxX) - minX + 2;
|
int maxX = maxLight(boundingBox.maxX);
|
||||||
int sizeY = Mth.ceil(boundingBox.maxY) - minY + 2;
|
int maxY = maxLight(boundingBox.maxY);
|
||||||
int sizeZ = Mth.ceil(boundingBox.maxZ) - minZ + 2;
|
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
|
@Override
|
||||||
public void collectLightSections(LongConsumer consumer) {
|
public void collectLightSections(LongConsumer consumer) {
|
||||||
var boundingBox = entity.getBoundingBox();
|
var boundingBox = entity.getBoundingBox();
|
||||||
|
|
||||||
int minX = Mth.floor(boundingBox.minX) - 1;
|
var minSectionX = minLightSection(boundingBox.minX);
|
||||||
int minY = Mth.floor(boundingBox.minY) - 1;
|
var minSectionY = minLightSection(boundingBox.minY);
|
||||||
int minZ = Mth.floor(boundingBox.minZ) - 1;
|
var minSectionZ = minLightSection(boundingBox.minZ);
|
||||||
int sizeXChunks = SectionPos.blockToSectionCoord(Mth.ceil(boundingBox.maxX) - minX + 2) + 1;
|
int maxSectionX = maxLightSection(boundingBox.maxX);
|
||||||
int sizeYChunks = SectionPos.blockToSectionCoord(Mth.ceil(boundingBox.maxY) - minY + 2) + 1;
|
int maxSectionY = maxLightSection(boundingBox.maxY);
|
||||||
int sizeZChunks = SectionPos.blockToSectionCoord(Mth.ceil(boundingBox.maxZ) - minZ + 2) + 1;
|
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 x = 0; x <= maxSectionX - minSectionX; x++) {
|
||||||
for (int y = 0; y < sizeYChunks; y++) {
|
for (int y = 0; y <= maxSectionY - minSectionY; y++) {
|
||||||
for (int z = 0; z < sizeZChunks; z++) {
|
for (int z = 0; z <= maxSectionZ - minSectionZ; z++) {
|
||||||
consumer.accept(SectionPos.offset(base, x, y, 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
|
@Override
|
||||||
public void initLightSectionNotifier(Notifier notifier) {
|
public void initLightSectionNotifier(Notifier notifier) {
|
||||||
this.notifier = notifier;
|
this.notifier = notifier;
|
||||||
|
@ -243,4 +287,20 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
|
||||||
structure.delete();
|
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