Flying the wheel away

This commit is contained in:
IThundxr 2024-07-18 19:08:25 -04:00 committed by Jozufozu
parent 02dca46855
commit 05c2cbaf73
59 changed files with 948 additions and 334 deletions

View file

@ -104,10 +104,11 @@ repositories {
name = "ModMaven" name = "ModMaven"
url = "https://modmaven.dev" url = "https://modmaven.dev"
}*/ }*/
maven { // Expired SSL cert, prevents building
// location of the maven for Dynamic Trees // maven {
url = 'https://harleyoconnor.com/maven' // // location of the maven for Dynamic Trees
} // url = 'https://harleyoconnor.com/maven'
// }
maven { maven {
// location of the maven for Curios API // location of the maven for Curios API
url = "https://maven.theillusivec4.top/" url = "https://maven.theillusivec4.top/"
@ -145,7 +146,7 @@ dependencies {
jarJar("com.tterrag.registrate:Registrate:${registrate_version}") { jarJar("com.tterrag.registrate:Registrate:${registrate_version}") {
jarJar.ranged(it, '[MC1.19.3-1.1.10,)') jarJar.ranged(it, '[MC1.19.3-1.1.10,)')
} }
jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") { jarJar("dev.engine_room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
jarJar.ranged(it, '[1.0,2.0)') jarJar.ranged(it, '[1.0,2.0)')
} }

View file

@ -23,7 +23,7 @@ use_parchment = true
# dependency versions # dependency versions
registrate_version = MC1.20-1.3.3 registrate_version = MC1.20-1.3.3
flywheel_minecraft_version = 1.20.1 flywheel_minecraft_version = 1.20.1
flywheel_version = 1.0.0-beta-89 flywheel_version = 1.0.0-beta-97
jei_minecraft_version = 1.20.1 jei_minecraft_version = 1.20.1
jei_version = 15.2.0.22 jei_version = 15.2.0.22
curios_minecraft_version = 1.20.1 curios_minecraft_version = 1.20.1

View file

@ -102,9 +102,4 @@ public class HarvesterActorVisual extends ActorVisual {
protected double getRotation() { protected double getRotation() {
return AngleHelper.angleLerp(AnimationTickHolder.getPartialTicks(), previousRotation, rotation); return AngleHelper.angleLerp(AnimationTickHolder.getPartialTicks(), previousRotation, rotation);
} }
@Override
public void init(float partialTick) {
}
} }

View file

@ -32,9 +32,4 @@ public class PSIActorVisual extends ActorVisual {
protected void _delete() { protected void _delete() {
instance.remove(); instance.remove();
} }
@Override
public void init(float partialTick) {
}
} }

View file

@ -14,16 +14,12 @@ public class PSIVisual extends AbstractBlockEntityVisual<PortableStorageInterfac
private final PIInstance instance; private final PIInstance instance;
public PSIVisual(VisualizationContext visualizationContext, PortableStorageInterfaceBlockEntity blockEntity) { public PSIVisual(VisualizationContext visualizationContext, PortableStorageInterfaceBlockEntity blockEntity, float partialTick) {
super(visualizationContext, blockEntity); super(visualizationContext, blockEntity, partialTick);
instance = new PIInstance(visualizationContext.instancerProvider(), blockState, getVisualPosition()); instance = new PIInstance(visualizationContext.instancerProvider(), blockState, getVisualPosition());
}
@Override
public void init(float pt) {
instance.init(isLit()); instance.init(isLit());
super.init(pt);
} }
@Override @Override
@ -37,7 +33,7 @@ public class PSIVisual extends AbstractBlockEntityVisual<PortableStorageInterfac
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, instance.middle, instance.top); relight(pos, instance.middle, instance.top);
} }

View file

@ -27,8 +27,8 @@ public class BearingVisual<B extends KineticBlockEntity & IBearingBlockEntity> e
final Axis rotationAxis; final Axis rotationAxis;
final Quaternionf blockOrientation; final Quaternionf blockOrientation;
public BearingVisual(VisualizationContext context, B blockEntity) { public BearingVisual(VisualizationContext context, B blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
Direction facing = blockState.getValue(BlockStateProperties.FACING); Direction facing = blockState.getValue(BlockStateProperties.FACING);
rotationAxis = Axis.of(Direction.get(Direction.AxisDirection.POSITIVE, axis).step()); rotationAxis = Axis.of(Direction.get(Direction.AxisDirection.POSITIVE, axis).step());
@ -58,8 +58,8 @@ public class BearingVisual<B extends KineticBlockEntity & IBearingBlockEntity> e
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos, topInstance); relight(pos, topInstance);
} }

View file

@ -70,9 +70,4 @@ public class StabilizedBearingVisual extends ActorVisual {
topInstance.delete(); topInstance.delete();
shaft.delete(); shaft.delete();
} }
@Override
public void init(float partialTick) {
}
} }

View file

@ -26,8 +26,8 @@ public class StickerVisual extends AbstractBlockEntityVisual<StickerBlockEntity>
private final TransformedInstance head; private final TransformedInstance head;
public StickerVisual(VisualizationContext context, StickerBlockEntity blockEntity) { public StickerVisual(VisualizationContext context, StickerBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
head = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.STICKER_HEAD)).createInstance(); head = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.STICKER_HEAD)).createInstance();
@ -66,7 +66,7 @@ public class StickerVisual extends AbstractBlockEntityVisual<StickerBlockEntity>
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, head); relight(pos, head);
} }

View file

@ -8,8 +8,8 @@ import com.simibubi.create.content.kinetics.base.ShaftVisual;
// TODO // TODO
public class ElevatorPulleyVisual extends ShaftVisual<ElevatorPulleyBlockEntity> implements SimpleDynamicVisual { public class ElevatorPulleyVisual extends ShaftVisual<ElevatorPulleyBlockEntity> implements SimpleDynamicVisual {
public ElevatorPulleyVisual(VisualizationContext context, ElevatorPulleyBlockEntity blockEntity) { public ElevatorPulleyVisual(VisualizationContext context, ElevatorPulleyBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -31,8 +31,8 @@ public class GantryCarriageVisual extends ShaftVisual<GantryCarriageBlockEntity>
private float lastAngle = Float.NaN; private float lastAngle = Float.NaN;
public GantryCarriageVisual(VisualizationContext context, GantryCarriageBlockEntity blockEntity) { public GantryCarriageVisual(VisualizationContext context, GantryCarriageBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
gantryCogs = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GANTRY_COGS)) gantryCogs = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GANTRY_COGS))
.createInstance(); .createInstance();
@ -98,7 +98,7 @@ public class GantryCarriageVisual extends ShaftVisual<GantryCarriageBlockEntity>
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, gantryCogs, rotatingModel); relight(pos, gantryCogs, rotatingModel);
} }

View file

@ -2,13 +2,14 @@ package com.simibubi.create.content.contraptions.pulley;
import java.util.function.Consumer; import java.util.function.Consumer;
import com.simibubi.create.foundation.utility.flywheel.box.MutableBox;
import com.simibubi.create.foundation.utility.flywheel.light.LightVolume;
import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.box.MutableBox;
import dev.engine_room.flywheel.lib.instance.OrientedInstance; import dev.engine_room.flywheel.lib.instance.OrientedInstance;
import dev.engine_room.flywheel.lib.light.LightVolume;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
@ -34,8 +35,8 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
private final MutableBox volume = new MutableBox(); private final MutableBox volume = new MutableBox();
private final LightVolume light; private final LightVolume light;
public AbstractPulleyVisual(VisualizationContext dispatcher, T blockEntity) { public AbstractPulleyVisual(VisualizationContext dispatcher, T blockEntity, float partialTick) {
super(dispatcher, blockEntity); super(dispatcher, blockEntity, partialTick);
rotatingAbout = Direction.get(Direction.AxisDirection.POSITIVE, axis); rotatingAbout = Direction.get(Direction.AxisDirection.POSITIVE, axis);
rotationAxis = Axis.of(rotatingAbout.step()); rotationAxis = Axis.of(rotatingAbout.step());
@ -109,8 +110,8 @@ public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
light.copyLight(volume); light.copyLight(volume);
relight(pos, coil); relight(pos, coil);
} }

View file

@ -10,8 +10,8 @@ import com.simibubi.create.content.fluids.hosePulley.HosePulleyBlockEntity;
public class HosePulleyVisual extends AbstractPulleyVisual<HosePulleyBlockEntity> { public class HosePulleyVisual extends AbstractPulleyVisual<HosePulleyBlockEntity> {
public HosePulleyVisual(VisualizationContext dispatcher, HosePulleyBlockEntity blockEntity) { public HosePulleyVisual(VisualizationContext dispatcher, HosePulleyBlockEntity blockEntity, float partialTick) {
super(dispatcher, blockEntity); super(dispatcher, blockEntity, partialTick);
} }
protected Instancer<OrientedInstance> getRopeModel() { protected Instancer<OrientedInstance> getRopeModel() {

View file

@ -11,8 +11,8 @@ import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.render.VirtualRenderHelper; import com.simibubi.create.foundation.render.VirtualRenderHelper;
public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> { public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> {
public RopePulleyVisual(VisualizationContext context, PulleyBlockEntity blockEntity) { public RopePulleyVisual(VisualizationContext context, PulleyBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
protected Instancer<OrientedInstance> getRopeModel() { protected Instancer<OrientedInstance> getRopeModel() {

View file

@ -2,7 +2,12 @@ package com.simibubi.create.content.contraptions.render;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.LongConsumer;
import dev.engine_room.flywheel.api.visual.LightUpdatedVisual;
import dev.engine_room.flywheel.api.visual.ShaderLightVisual;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.MutablePair;
@ -10,7 +15,6 @@ import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.api.task.Plan; import dev.engine_room.flywheel.api.task.Plan;
import dev.engine_room.flywheel.api.visual.BlockEntityVisual; import dev.engine_room.flywheel.api.visual.BlockEntityVisual;
import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visual.LitVisual;
import dev.engine_room.flywheel.api.visual.TickableVisual; import dev.engine_room.flywheel.api.visual.TickableVisual;
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
import dev.engine_room.flywheel.api.visualization.VisualEmbedding; import dev.engine_room.flywheel.api.visualization.VisualEmbedding;
@ -44,7 +48,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
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, LightUpdatedVisual, ShaderLightVisual {
protected static final int LIGHT_PADDING = 1; protected static final int LIGHT_PADDING = 1;
protected final VisualEmbedding embedding; protected final VisualEmbedding embedding;
@ -55,18 +59,19 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
protected VirtualRenderWorld virtualRenderWorld; protected VirtualRenderWorld virtualRenderWorld;
protected Model model; protected Model model;
protected TransformedInstance structure; protected TransformedInstance structure;
protected Notifier notifier; protected SectionCollector sectionCollector;
protected long minSection, maxSection; protected long minSection, maxSection;
protected long minBlock, maxBlock; protected long minBlock, maxBlock;
private final PoseStack contraptionMatrix = new PoseStack(); private final PoseStack contraptionMatrix = new PoseStack();
public ContraptionVisual(VisualizationContext ctx, E entity) { public ContraptionVisual(VisualizationContext ctx, E entity, float partialTick) {
super(ctx, entity); super(ctx, entity, partialTick);
embedding = ctx.createEmbedding(); embedding = ctx.createEmbedding();
init(partialTick);
} }
@Override
public void init(float partialTick) { public void init(float partialTick) {
setEmbeddingMatrices(partialTick); setEmbeddingMatrices(partialTick);
@ -97,7 +102,7 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
setupActor(actor, partialTick); setupActor(actor, partialTick);
} }
updateLight(); updateLight(partialTick);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -107,11 +112,9 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
return; return;
} }
Level world = be.getLevel(); Level level = be.getLevel();
be.setLevel(virtualRenderWorld); be.setLevel(virtualRenderWorld);
BlockEntityVisual<? super T> visual = visualizer.createVisual(this.embedding, be); BlockEntityVisual<? super T> visual = visualizer.createVisual(this.embedding, be, partialTicks);
visual.init(partialTicks);
children.add(visual); children.add(visual);
@ -123,7 +126,7 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
tickableVisuals.add(tickable, tickable.planTick()); tickableVisuals.add(tickable, tickable.planTick());
} }
be.setLevel(world); be.setLevel(level);
} }
private void setupActor(MutablePair<StructureTemplate.StructureBlockInfo, MovementContext> actor, float partialTick) { private void setupActor(MutablePair<StructureTemplate.StructureBlockInfo, MovementContext> actor, float partialTick) {
@ -147,8 +150,6 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
return; return;
} }
visual.init(partialTick);
actors.add(visual); actors.add(visual);
} }
@ -174,14 +175,14 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
setEmbeddingMatrices(partialTick); setEmbeddingMatrices(partialTick);
if (hasMovedSections()) { if (hasMovedSections()) {
notifier.notifySectionsChanged(); sectionCollector.sections(collectLightSections());
} }
if (hasMovedBlocks()) { if (hasMovedBlocks()) {
// TODO: incremental light collection // TODO: incremental light collection
// TODO: optimize light collection for very large contraptions // TODO: optimize light collection for very large contraptions
// by only collecting cuboids that contain faces // by only collecting cuboids that contain faces
updateLight(); updateLight(partialTick);
} }
} }
@ -198,27 +199,11 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
embedding.invalidateLight(); super.update(partialTick);
// 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 = 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);
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 LongSet collectLightSections() {
public void collectLightSections(LongConsumer consumer) {
var boundingBox = entity.getBoundingBox(); var boundingBox = entity.getBoundingBox();
var minSectionX = minLightSection(boundingBox.minX); var minSectionX = minLightSection(boundingBox.minX);
@ -231,13 +216,17 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
minSection = SectionPos.asLong(minSectionX, minSectionY, minSectionZ); minSection = SectionPos.asLong(minSectionX, minSectionY, minSectionZ);
maxSection = SectionPos.asLong(maxSectionX, maxSectionY, maxSectionZ); maxSection = SectionPos.asLong(maxSectionX, maxSectionY, maxSectionZ);
LongSet longSet = new LongArraySet();
for (int x = 0; x <= maxSectionX - minSectionX; x++) { for (int x = 0; x <= maxSectionX - minSectionX; x++) {
for (int y = 0; y <= maxSectionY - minSectionY; y++) { for (int y = 0; y <= maxSectionY - minSectionY; y++) {
for (int z = 0; z <= maxSectionZ - minSectionZ; z++) { for (int z = 0; z <= maxSectionZ - minSectionZ; z++) {
consumer.accept(SectionPos.offset(minSection, x, y, z)); longSet.add(SectionPos.offset(minSection, x, y, z));
} }
} }
} }
return longSet;
} }
protected boolean hasMovedBlocks() { protected boolean hasMovedBlocks() {
@ -267,8 +256,8 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
} }
@Override @Override
public void initLightSectionNotifier(Notifier notifier) { public void setSectionCollector(SectionCollector collector) {
this.notifier = notifier; this.sectionCollector = collector;
} }
@Override @Override

View file

@ -7,8 +7,8 @@ import com.simibubi.create.content.kinetics.base.SingleRotatingVisual;
public class BacktankVisual extends SingleRotatingVisual<BacktankBlockEntity> { public class BacktankVisual extends SingleRotatingVisual<BacktankBlockEntity> {
public BacktankVisual(VisualizationContext context, BacktankBlockEntity blockEntity) { public BacktankVisual(VisualizationContext context, BacktankBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -19,25 +19,20 @@ import net.minecraft.core.Direction;
public class ToolBoxVisual extends AbstractBlockEntityVisual<ToolboxBlockEntity> implements SimpleDynamicVisual { public class ToolBoxVisual extends AbstractBlockEntityVisual<ToolboxBlockEntity> implements SimpleDynamicVisual {
private final Direction facing; private final Direction facing;
private TransformedInstance lid; private final TransformedInstance lid;
private TransformedInstance[] drawers; private final TransformedInstance[] drawers;
public ToolBoxVisual(VisualizationContext context, ToolboxBlockEntity blockEntity) { public ToolBoxVisual(VisualizationContext context, ToolboxBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
facing = blockState.getValue(ToolboxBlock.FACING) facing = blockState.getValue(ToolboxBlock.FACING)
.getOpposite(); .getOpposite();
}
@Override
public void init(float pt) {
Instancer<TransformedInstance> drawerModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_DRAWER)); Instancer<TransformedInstance> drawerModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_DRAWER));
drawers = new TransformedInstance[]{drawerModel.createInstance(), drawerModel.createInstance()}; drawers = new TransformedInstance[]{drawerModel.createInstance(), drawerModel.createInstance()};
lid = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_LIDS.get(blockEntity.getColor()))) lid = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_LIDS.get(blockEntity.getColor())))
.createInstance(); .createInstance();
super.init(pt);
} }
@Override @Override
@ -78,7 +73,7 @@ public class ToolBoxVisual extends AbstractBlockEntityVisual<ToolboxBlockEntity>
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, drawers); relight(pos, drawers);
relight(pos, lid); relight(pos, lid);
} }

View file

@ -26,8 +26,8 @@ public class FluidValveVisual extends ShaftVisual<FluidValveBlockEntity> impleme
protected final double yRot; protected final double yRot;
protected final int pointerRotationOffset; protected final int pointerRotationOffset;
public FluidValveVisual(VisualizationContext dispatcher, FluidValveBlockEntity blockEntity) { public FluidValveVisual(VisualizationContext dispatcher, FluidValveBlockEntity blockEntity, float partialTick) {
super(dispatcher, blockEntity); super(dispatcher, blockEntity, partialTick);
Direction facing = blockState.getValue(FluidValveBlock.FACING); Direction facing = blockState.getValue(FluidValveBlock.FACING);
@ -75,8 +75,8 @@ public class FluidValveVisual extends ShaftVisual<FluidValveBlockEntity> impleme
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos, pointer); relight(pos, pointer);
} }

View file

@ -12,8 +12,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class PumpCogVisual extends SingleRotatingVisual<PumpBlockEntity> { public class PumpCogVisual extends SingleRotatingVisual<PumpBlockEntity> {
public PumpCogVisual(VisualizationContext context, PumpBlockEntity blockEntity) { public PumpCogVisual(VisualizationContext context, PumpBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -6,8 +6,8 @@ import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class BackHalfShaftVisual<T extends KineticBlockEntity> extends HalfShaftVisual<T> { public class BackHalfShaftVisual<T extends KineticBlockEntity> extends HalfShaftVisual<T> {
public BackHalfShaftVisual(VisualizationContext context, T blockEntity) { public BackHalfShaftVisual(VisualizationContext context, T blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -9,8 +9,8 @@ import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class HalfShaftVisual<T extends KineticBlockEntity> extends SingleRotatingVisual<T> { public class HalfShaftVisual<T extends KineticBlockEntity> extends SingleRotatingVisual<T> {
public HalfShaftVisual(VisualizationContext context, T blockEntity) { public HalfShaftVisual(VisualizationContext context, T blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -7,8 +7,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class HorizontalHalfShaftVisual<T extends KineticBlockEntity> extends HalfShaftVisual<T> { public class HorizontalHalfShaftVisual<T extends KineticBlockEntity> extends HalfShaftVisual<T> {
public HorizontalHalfShaftVisual(VisualizationContext context, T blockEntity) { public HorizontalHalfShaftVisual(VisualizationContext context, T blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -14,8 +14,8 @@ public abstract class KineticBlockEntityVisual<T extends KineticBlockEntity> ext
protected final Direction.Axis axis; protected final Direction.Axis axis;
public KineticBlockEntityVisual(VisualizationContext context, T blockEntity) { public KineticBlockEntityVisual(VisualizationContext context, T blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
axis = (blockState.getBlock() instanceof IRotate irotate) ? irotate.getRotationAxis(blockState) : Axis.Y; axis = (blockState.getBlock() instanceof IRotate irotate) ? irotate.getRotationAxis(blockState) : Axis.Y;
} }

View file

@ -46,13 +46,13 @@ public class KineticInstance extends ColoredLitInstance {
if (blockEntity.hasNetwork()) { if (blockEntity.hasNetwork()) {
setColor(Color.generateFromLong(blockEntity.network)); setColor(Color.generateFromLong(blockEntity.network));
}else { }else {
setColor(0xFF, 0xFF, 0xFF); color(0xFF, 0xFF, 0xFF);
} }
return this; return this;
} }
public KineticInstance setColor(Color c) { public KineticInstance setColor(Color c) {
setColor(c.getRed(), c.getGreen(), c.getBlue()); color(c.getRed(), c.getGreen(), c.getBlue());
return this; return this;
} }

View file

@ -6,8 +6,8 @@ import com.simibubi.create.foundation.render.VirtualRenderHelper;
public class ShaftVisual<T extends KineticBlockEntity> extends SingleRotatingVisual<T> { public class ShaftVisual<T extends KineticBlockEntity> extends SingleRotatingVisual<T> {
public ShaftVisual(VisualizationContext context, T blockEntity) { public ShaftVisual(VisualizationContext context, T blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -13,16 +13,14 @@ public class SingleRotatingVisual<T extends KineticBlockEntity> extends KineticB
protected RotatingInstance rotatingModel; protected RotatingInstance rotatingModel;
public SingleRotatingVisual(VisualizationContext context, T blockEntity) { public SingleRotatingVisual(VisualizationContext context, T blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override
public void init(float pt) { public void init(float pt) {
rotatingModel = instancerProvider.instancer(AllInstanceTypes.ROTATING, model()) rotatingModel = instancerProvider.instancer(AllInstanceTypes.ROTATING, model())
.createInstance(); .createInstance();
setup(rotatingModel); setup(rotatingModel);
super.init(pt);
} }
@Override @Override
@ -31,7 +29,7 @@ public class SingleRotatingVisual<T extends KineticBlockEntity> extends KineticB
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, rotatingModel); relight(pos, rotatingModel);
} }

View file

@ -12,8 +12,6 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import dev.engine_room.flywheel.lib.box.Box;
import dev.engine_room.flywheel.lib.box.MutableBox;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.kinetics.base.IRotate; import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
@ -30,6 +28,9 @@ import com.simibubi.create.content.logistics.tunnel.BrassTunnelBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.flywheel.box.Box;
import com.simibubi.create.foundation.utility.flywheel.box.MutableBox;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.BlockPos.MutableBlockPos;

View file

@ -3,6 +3,8 @@ package com.simibubi.create.content.kinetics.belt;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.function.Consumer; import java.util.function.Consumer;
import dev.engine_room.flywheel.lib.instance.FlatLit;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.Instance;
@ -38,8 +40,8 @@ public class BeltVisual extends KineticBlockEntityVisual<BeltBlockEntity> {
protected ArrayList<BeltInstance> keys; protected ArrayList<BeltInstance> keys;
protected RotatingInstance pulleyKey; protected RotatingInstance pulleyKey;
public BeltVisual(VisualizationContext context, BeltBlockEntity blockEntity) { public BeltVisual(VisualizationContext context, BeltBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
if (!AllBlocks.BELT.has(blockState)) if (!AllBlocks.BELT.has(blockState))
return; return;
@ -99,8 +101,8 @@ public class BeltVisual extends KineticBlockEntityVisual<BeltBlockEntity> {
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, keys.stream()); relight(pos, keys.toArray(FlatLit[]::new));
if (pulleyKey != null) relight(pos, pulleyKey); if (pulleyKey != null) relight(pos, pulleyKey);
} }

View file

@ -13,8 +13,8 @@ import net.minecraft.core.Direction;
public class ShaftlessCogwheelVisual extends SingleRotatingVisual<KineticBlockEntity> { public class ShaftlessCogwheelVisual extends SingleRotatingVisual<KineticBlockEntity> {
public ShaftlessCogwheelVisual(VisualizationContext context, KineticBlockEntity blockEntity) { public ShaftlessCogwheelVisual(VisualizationContext context, KineticBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -16,15 +16,22 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class HandCrankVisual extends SingleRotatingVisual<HandCrankBlockEntity> implements SimpleDynamicVisual { public class HandCrankVisual extends SingleRotatingVisual<HandCrankBlockEntity> implements SimpleDynamicVisual {
private TransformedInstance crank; private final TransformedInstance crank;
private Direction facing; private final Direction facing;
public HandCrankVisual(VisualizationContext modelManager, HandCrankBlockEntity blockEntity) { public HandCrankVisual(VisualizationContext modelManager, HandCrankBlockEntity blockEntity, float partialTick) {
super(modelManager, blockEntity); super(modelManager, blockEntity, partialTick);
facing = blockState.getValue(BlockStateProperties.FACING); facing = blockState.getValue(BlockStateProperties.FACING);
Model model = blockEntity.getRenderedHandleInstance(); Model model = blockEntity.getRenderedHandleInstance();
crank = instancerProvider.instancer(InstanceTypes.TRANSFORMED, model) crank = instancerProvider.instancer(InstanceTypes.TRANSFORMED, model)
.createInstance(); .createInstance();
rotateCrank(partialTick);
if (blockEntity.shouldRenderShaft())
setup(rotatingModel);
updateLight(partialTick);
} }
@Override @Override
@ -47,17 +54,6 @@ public class HandCrankVisual extends SingleRotatingVisual<HandCrankBlockEntity>
.setChanged(); .setChanged();
} }
@Override
public void init(float pt) {
rotateCrank(pt);
// FIXME: need to call super.super.init here
if (blockEntity.shouldRenderShaft())
super.init(pt);
updateLight();
}
@Override @Override
protected void _delete() { protected void _delete() {
if (blockEntity.shouldRenderShaft()) if (blockEntity.shouldRenderShaft())
@ -73,9 +69,9 @@ public class HandCrankVisual extends SingleRotatingVisual<HandCrankBlockEntity>
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
if (blockEntity.shouldRenderShaft()) if (blockEntity.shouldRenderShaft())
super.updateLight(); super.updateLight(partialTick);
if (crank != null) if (crank != null)
relight(pos, crank); relight(pos, crank);
} }

View file

@ -124,9 +124,4 @@ public class DeployerActorVisual extends ActorVisual {
hand.delete(); hand.delete();
shaft.delete(); shaft.delete();
} }
@Override
public void init(float partialTick) {
}
} }

View file

@ -41,8 +41,8 @@ public class DeployerVisual extends ShaftVisual<DeployerBlockEntity> implements
PartialModel currentHand; PartialModel currentHand;
float progress; float progress;
public DeployerVisual(VisualizationContext context, DeployerBlockEntity blockEntity) { public DeployerVisual(VisualizationContext context, DeployerBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
facing = blockState.getValue(FACING); facing = blockState.getValue(FACING);
@ -57,16 +57,11 @@ public class DeployerVisual extends ShaftVisual<DeployerBlockEntity> implements
currentHand = this.blockEntity.getHandPose(); currentHand = this.blockEntity.getHandPose();
hand = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(currentHand)).createInstance(); hand = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(currentHand)).createInstance();
}
@Override progress = getProgress(partialTick);
public void init(float pt) {
progress = getProgress(pt);
updateRotation(pole, hand, yRot, xRot, zRot); updateRotation(pole, hand, yRot, xRot, zRot);
updatePosition(); updatePosition();
}
super.init(pt);
}
@Override @Override
public void tick(TickableVisual.Context context) { public void tick(TickableVisual.Context context) {
@ -91,8 +86,8 @@ public class DeployerVisual extends ShaftVisual<DeployerBlockEntity> implements
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos, hand, pole); relight(pos, hand, pole);
} }

View file

@ -66,9 +66,4 @@ public class DrillActorVisual extends ActorVisual {
protected void _delete() { protected void _delete() {
drillHead.delete(); drillHead.delete();
} }
@Override
public void init(float partialTick) {
}
} }

View file

@ -11,8 +11,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class DrillVisual extends SingleRotatingVisual<DrillBlockEntity> { public class DrillVisual extends SingleRotatingVisual<DrillBlockEntity> {
public DrillVisual(VisualizationContext context, DrillBlockEntity blockEntity) { public DrillVisual(VisualizationContext context, DrillBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -23,8 +23,8 @@ public class FanVisual extends KineticBlockEntityVisual<EncasedFanBlockEntity> {
final Direction direction; final Direction direction;
private final Direction opposite; private final Direction opposite;
public FanVisual(VisualizationContext context, EncasedFanBlockEntity blockEntity) { public FanVisual(VisualizationContext context, EncasedFanBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
direction = blockState.getValue(FACING); direction = blockState.getValue(FACING);
@ -53,7 +53,7 @@ public class FanVisual extends KineticBlockEntityVisual<EncasedFanBlockEntity> {
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
BlockPos behind = pos.relative(opposite); BlockPos behind = pos.relative(opposite);
relight(behind, shaft); relight(behind, shaft);

View file

@ -24,8 +24,8 @@ public class FlywheelVisual extends KineticBlockEntityVisual<FlywheelBlockEntity
protected final TransformedInstance wheel; protected final TransformedInstance wheel;
protected float lastAngle = Float.NaN; protected float lastAngle = Float.NaN;
public FlywheelVisual(VisualizationContext context, FlywheelBlockEntity blockEntity) { public FlywheelVisual(VisualizationContext context, FlywheelBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
shaft = setup(instancerProvider.instancer(AllInstanceTypes.ROTATING, VirtualRenderHelper.blockModel(shaft())) shaft = setup(instancerProvider.instancer(AllInstanceTypes.ROTATING, VirtualRenderHelper.blockModel(shaft()))
.createInstance()); .createInstance());
@ -70,7 +70,7 @@ public class FlywheelVisual extends KineticBlockEntityVisual<FlywheelBlockEntity
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, shaft, wheel); relight(pos, shaft, wheel);
} }

View file

@ -7,6 +7,7 @@ import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.FlatLit;
import dev.engine_room.flywheel.lib.instance.InstanceTypes; import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.Models;
@ -28,12 +29,13 @@ public abstract class GaugeVisual extends ShaftVisual<GaugeBlockEntity> implemen
protected final PoseStack ms = new PoseStack(); protected final PoseStack ms = new PoseStack();
protected GaugeVisual(VisualizationContext context, GaugeBlockEntity blockEntity) { protected GaugeVisual(VisualizationContext context, GaugeBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
init(partialTick);
} }
@Override public void init(float partialTick) {
public void init(float pt) {
GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock(); GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock();
Instancer<TransformedInstance> dialModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_DIAL)); Instancer<TransformedInstance> dialModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_DIAL));
@ -54,8 +56,6 @@ public abstract class GaugeVisual extends ShaftVisual<GaugeBlockEntity> implemen
face.setupTransform(msr, progress); face.setupTransform(msr, progress);
} }
super.init(pt);
} }
private DialFace makeFace(Direction face, Instancer<TransformedInstance> dialModel, Instancer<TransformedInstance> headModel) { private DialFace makeFace(Direction face, Instancer<TransformedInstance> dialModel, Instancer<TransformedInstance> headModel) {
@ -77,11 +77,11 @@ public abstract class GaugeVisual extends ShaftVisual<GaugeBlockEntity> implemen
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos, faces.stream() relight(pos, faces.stream()
.flatMap(Couple::stream)); .flatMap(Couple::stream).toArray(FlatLit[]::new));
} }
@Override @Override
@ -155,8 +155,8 @@ public abstract class GaugeVisual extends ShaftVisual<GaugeBlockEntity> implemen
} }
public static class Speed extends GaugeVisual { public static class Speed extends GaugeVisual {
public Speed(VisualizationContext context, GaugeBlockEntity blockEntity) { public Speed(VisualizationContext context, GaugeBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override
@ -166,8 +166,8 @@ public abstract class GaugeVisual extends ShaftVisual<GaugeBlockEntity> implemen
} }
public static class Stress extends GaugeVisual { public static class Stress extends GaugeVisual {
public Stress(VisualizationContext context, GaugeBlockEntity blockEntity) { public Stress(VisualizationContext context, GaugeBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -7,6 +7,7 @@ import java.util.function.Consumer;
import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.AbstractInstance; import dev.engine_room.flywheel.lib.instance.AbstractInstance;
import dev.engine_room.flywheel.lib.instance.FlatLit;
import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.Models;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual; import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual;
@ -24,8 +25,8 @@ public class GearboxVisual extends KineticBlockEntityVisual<GearboxBlockEntity>
protected final EnumMap<Direction, RotatingInstance> keys; protected final EnumMap<Direction, RotatingInstance> keys;
protected Direction sourceFacing; protected Direction sourceFacing;
public GearboxVisual(VisualizationContext context, GearboxBlockEntity blockEntity) { public GearboxVisual(VisualizationContext context, GearboxBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
keys = new EnumMap<>(Direction.class); keys = new EnumMap<>(Direction.class);
@ -87,8 +88,8 @@ public class GearboxVisual extends KineticBlockEntityVisual<GearboxBlockEntity>
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, keys.values().stream()); relight(pos, keys.values().toArray(FlatLit[]::new));
} }
@Override @Override

View file

@ -9,6 +9,7 @@ import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.AbstractInstance; import dev.engine_room.flywheel.lib.instance.AbstractInstance;
import dev.engine_room.flywheel.lib.instance.FlatLit;
import dev.engine_room.flywheel.lib.instance.InstanceTypes; import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.Models;
@ -45,8 +46,8 @@ public class ArmVisual extends SingleRotatingVisual<ArmBlockEntity> implements S
private float upperArmAngle = Float.NaN; private float upperArmAngle = Float.NaN;
private float headAngle = Float.NaN; private float headAngle = Float.NaN;
public ArmVisual(VisualizationContext context, ArmBlockEntity blockEntity) { public ArmVisual(VisualizationContext context, ArmBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
base = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_BASE)) base = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_BASE))
.createInstance(); .createInstance();
@ -131,12 +132,12 @@ public class ArmVisual extends SingleRotatingVisual<ArmBlockEntity> implements S
ArmRenderer.transformLowerArm(msr, lowerArmAngle); ArmRenderer.transformLowerArm(msr, lowerArmAngle);
lowerBody.setTransform(msLocal) lowerBody.setTransform(msLocal)
.setColor(color) .color(color)
.setChanged(); .setChanged();
ArmRenderer.transformUpperArm(msr, upperArmAngle); ArmRenderer.transformUpperArm(msr, upperArmAngle);
upperBody.setTransform(msLocal) upperBody.setTransform(msLocal)
.setColor(color) .color(color)
.setChanged(); .setChanged();
ArmRenderer.transformHead(msr, headAngle); ArmRenderer.transformHead(msr, headAngle);
@ -177,15 +178,15 @@ public class ArmVisual extends SingleRotatingVisual<ArmBlockEntity> implements S
claw = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(blockEntity.goggles ? AllPartialModels.ARM_CLAW_BASE_GOGGLES : AllPartialModels.ARM_CLAW_BASE)) claw = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(blockEntity.goggles ? AllPartialModels.ARM_CLAW_BASE_GOGGLES : AllPartialModels.ARM_CLAW_BASE))
.createInstance(); .createInstance();
models.add(claw); models.add(claw);
updateLight(); updateLight(pt);
animateArm(); animateArm();
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos, models.stream()); relight(pos, models.toArray(FlatLit[]::new));
} }
@Override @Override

View file

@ -8,8 +8,8 @@ import com.simibubi.create.content.kinetics.base.SingleRotatingVisual;
public class MillstoneCogVisual extends SingleRotatingVisual<MillstoneBlockEntity> { public class MillstoneCogVisual extends SingleRotatingVisual<MillstoneBlockEntity> {
public MillstoneCogVisual(VisualizationContext context, MillstoneBlockEntity blockEntity) { public MillstoneCogVisual(VisualizationContext context, MillstoneBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -23,8 +23,8 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual
private final OrientedInstance mixerPole; private final OrientedInstance mixerPole;
private final MechanicalMixerBlockEntity mixer; private final MechanicalMixerBlockEntity mixer;
public MixerVisual(VisualizationContext context, MechanicalMixerBlockEntity blockEntity) { public MixerVisual(VisualizationContext context, MechanicalMixerBlockEntity blockEntity, float partialTick) {
super(context, blockEntity, false); super(context, blockEntity, false, partialTick);
this.mixer = blockEntity; this.mixer = blockEntity;
mixerHead = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.MECHANICAL_MIXER_HEAD)) mixerHead = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.MECHANICAL_MIXER_HEAD))
@ -34,13 +34,8 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual
mixerPole = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_MIXER_POLE)) mixerPole = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_MIXER_POLE))
.createInstance(); .createInstance();
}
@Override animate(partialTick);
public void init(float pt) {
super.init(pt);
animate(pt);
} }
@Override @Override
@ -76,8 +71,8 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos.below(), mixerHead); relight(pos.below(), mixerHead);
relight(pos, mixerPole); relight(pos, mixerPole);

View file

@ -20,8 +20,8 @@ public class PressVisual extends ShaftVisual<MechanicalPressBlockEntity> impleme
private final OrientedInstance pressHead; private final OrientedInstance pressHead;
public PressVisual(VisualizationContext context, MechanicalPressBlockEntity blockEntity) { public PressVisual(VisualizationContext context, MechanicalPressBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
pressHead = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_PRESS_HEAD)) pressHead = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_PRESS_HEAD))
.createInstance(); .createInstance();
@ -30,13 +30,8 @@ public class PressVisual extends ShaftVisual<MechanicalPressBlockEntity> impleme
.rotationDegrees(AngleHelper.horizontalAngle(blockState.getValue(MechanicalPressBlock.HORIZONTAL_FACING))); .rotationDegrees(AngleHelper.horizontalAngle(blockState.getValue(MechanicalPressBlock.HORIZONTAL_FACING)));
pressHead.setRotation(q); pressHead.setRotation(q);
}
@Override transformModels(partialTick);
public void init(float pt) {
super.init(pt);
transformModels(pt);
} }
@Override @Override
@ -59,8 +54,8 @@ public class PressVisual extends ShaftVisual<MechanicalPressBlockEntity> impleme
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos, pressHead); relight(pos, pressHead);
} }

View file

@ -14,8 +14,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class SawVisual extends SingleRotatingVisual<SawBlockEntity> { public class SawVisual extends SingleRotatingVisual<SawBlockEntity> {
public SawVisual(VisualizationContext context, SawBlockEntity blockEntity) { public SawVisual(VisualizationContext context, SawBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
} }
@Override @Override

View file

@ -24,12 +24,13 @@ public class BracketedKineticBlockEntityVisual extends SingleRotatingVisual<Brac
protected RotatingInstance additionalShaft; protected RotatingInstance additionalShaft;
public BracketedKineticBlockEntityVisual(VisualizationContext context, BracketedKineticBlockEntity blockEntity) { public BracketedKineticBlockEntityVisual(VisualizationContext context, BracketedKineticBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
init(partialTick);
} }
@Override public void init(float partialTick) {
public void init(float pt) {
if (ICogWheel.isLargeCog(blockEntity.getBlockState())) { if (ICogWheel.isLargeCog(blockEntity.getBlockState())) {
// Large cogs sometimes have to offset their teeth by 11.25 degrees in order to // Large cogs sometimes have to offset their teeth by 11.25 degrees in order to
// mesh properly // mesh properly
@ -45,7 +46,6 @@ public class BracketedKineticBlockEntityVisual extends SingleRotatingVisual<Brac
additionalShaft.setRotationOffset(offset) additionalShaft.setRotationOffset(offset)
.setChanged(); .setChanged();
} }
super.init(pt);
} }
@Override @Override
@ -77,8 +77,8 @@ public class BracketedKineticBlockEntityVisual extends SingleRotatingVisual<Brac
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
if (additionalShaft != null) if (additionalShaft != null)
relight(pos, additionalShaft); relight(pos, additionalShaft);
} }

View file

@ -29,27 +29,28 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class EncasedCogVisual extends KineticBlockEntityVisual<KineticBlockEntity> { public class EncasedCogVisual extends KineticBlockEntityVisual<KineticBlockEntity> {
private boolean large; private final boolean large;
protected RotatingInstance rotatingModel; protected RotatingInstance rotatingModel;
protected Optional<RotatingInstance> rotatingTopShaft; protected Optional<RotatingInstance> rotatingTopShaft;
protected Optional<RotatingInstance> rotatingBottomShaft; protected Optional<RotatingInstance> rotatingBottomShaft;
public static EncasedCogVisual small(VisualizationContext modelManager, KineticBlockEntity blockEntity) { public static EncasedCogVisual small(VisualizationContext modelManager, KineticBlockEntity blockEntity, float partialTick) {
return new EncasedCogVisual(modelManager, blockEntity, false); return new EncasedCogVisual(modelManager, blockEntity, false, partialTick);
} }
public static EncasedCogVisual large(VisualizationContext modelManager, KineticBlockEntity blockEntity) { public static EncasedCogVisual large(VisualizationContext modelManager, KineticBlockEntity blockEntity, float partialTick) {
return new EncasedCogVisual(modelManager, blockEntity, true); return new EncasedCogVisual(modelManager, blockEntity, true, partialTick);
} }
public EncasedCogVisual(VisualizationContext modelManager, KineticBlockEntity blockEntity, boolean large) { public EncasedCogVisual(VisualizationContext modelManager, KineticBlockEntity blockEntity, boolean large, float partialTick) {
super(modelManager, blockEntity); super(modelManager, blockEntity, partialTick);
this.large = large; this.large = large;
init(partialTick);
} }
@Override public void init(float partialTick) {
public void init(float pt) {
var instancer = instancerProvider.instancer(AllInstanceTypes.ROTATING, getCogModel()); var instancer = instancerProvider.instancer(AllInstanceTypes.ROTATING, getCogModel());
rotatingModel = setup(instancer.createInstance()); rotatingModel = setup(instancer.createInstance());
@ -72,8 +73,6 @@ public class EncasedCogVisual extends KineticBlockEntityVisual<KineticBlockEntit
else else
rotatingBottomShaft = Optional.of(data); rotatingBottomShaft = Optional.of(data);
} }
super.init(pt);
} }
@Override @Override
@ -84,7 +83,7 @@ public class EncasedCogVisual extends KineticBlockEntityVisual<KineticBlockEntit
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, rotatingModel); relight(pos, rotatingModel);
rotatingTopShaft.ifPresent(d -> relight(pos, d)); rotatingTopShaft.ifPresent(d -> relight(pos, d));
rotatingBottomShaft.ifPresent(d -> relight(pos, d)); rotatingBottomShaft.ifPresent(d -> relight(pos, d));

View file

@ -24,8 +24,8 @@ public class SteamEngineVisual extends AbstractBlockEntityVisual<SteamEngineBloc
protected final TransformedInstance linkage; protected final TransformedInstance linkage;
protected final TransformedInstance connector; protected final TransformedInstance connector;
public SteamEngineVisual(VisualizationContext context, SteamEngineBlockEntity blockEntity) { public SteamEngineVisual(VisualizationContext context, SteamEngineBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
piston = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ENGINE_PISTON)) piston = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ENGINE_PISTON))
.createInstance(); .createInstance();
@ -91,7 +91,7 @@ public class SteamEngineVisual extends AbstractBlockEntityVisual<SteamEngineBloc
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, piston, linkage, connector); relight(pos, piston, linkage, connector);
} }

View file

@ -6,6 +6,7 @@ import java.util.function.Consumer;
import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.AbstractInstance; import dev.engine_room.flywheel.lib.instance.AbstractInstance;
import dev.engine_room.flywheel.lib.instance.FlatLit;
import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.Models;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.IRotate; import com.simibubi.create.content.kinetics.base.IRotate;
@ -21,8 +22,8 @@ public class SplitShaftVisual extends KineticBlockEntityVisual<SplitShaftBlockEn
protected final ArrayList<RotatingInstance> keys; protected final ArrayList<RotatingInstance> keys;
public SplitShaftVisual(VisualizationContext modelManager, SplitShaftBlockEntity blockEntity) { public SplitShaftVisual(VisualizationContext modelManager, SplitShaftBlockEntity blockEntity, float partialTick) {
super(modelManager, blockEntity); super(modelManager, blockEntity, partialTick);
keys = new ArrayList<>(2); keys = new ArrayList<>(2);
@ -52,8 +53,8 @@ public class SplitShaftVisual extends KineticBlockEntityVisual<SplitShaftBlockEn
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, keys.stream()); relight(pos, keys.toArray(FlatLit[]::new));
} }
@Override @Override

View file

@ -25,23 +25,19 @@ public class WaterWheelVisual<T extends WaterWheelBlockEntity> extends KineticBl
protected BlockState lastMaterial; protected BlockState lastMaterial;
protected RotatingInstance rotatingModel; protected RotatingInstance rotatingModel;
public WaterWheelVisual(VisualizationContext context, T blockEntity, boolean large) { public WaterWheelVisual(VisualizationContext context, T blockEntity, boolean large, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
this.large = large; this.large = large;
}
public static <T extends WaterWheelBlockEntity> WaterWheelVisual<T> standard(VisualizationContext context, T blockEntity) {
return new WaterWheelVisual<>(context, blockEntity, false);
}
public static <T extends WaterWheelBlockEntity> WaterWheelVisual<T> large(VisualizationContext context, T blockEntity) {
return new WaterWheelVisual<>(context, blockEntity, true);
}
@Override
public void init(float pt) {
setupInstance(); setupInstance();
super.init(pt); }
public static <T extends WaterWheelBlockEntity> WaterWheelVisual<T> standard(VisualizationContext context, T blockEntity, float partialTick) {
return new WaterWheelVisual<>(context, blockEntity, false, partialTick);
}
public static <T extends WaterWheelBlockEntity> WaterWheelVisual<T> large(VisualizationContext context, T blockEntity, float partialTick) {
return new WaterWheelVisual<>(context, blockEntity, true, partialTick);
} }
private void setupInstance() { private void setupInstance() {
@ -62,7 +58,7 @@ public class WaterWheelVisual<T extends WaterWheelBlockEntity> extends KineticBl
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, rotatingModel); relight(pos, rotatingModel);
} }

View file

@ -18,17 +18,12 @@ public class EjectorVisual extends ShaftVisual<EjectorBlockEntity> implements Si
private float lastProgress = Float.NaN; private float lastProgress = Float.NaN;
public EjectorVisual(VisualizationContext dispatcher, EjectorBlockEntity blockEntity) { public EjectorVisual(VisualizationContext dispatcher, EjectorBlockEntity blockEntity, float partialTick) {
super(dispatcher, blockEntity); super(dispatcher, blockEntity, partialTick);
plate = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.EJECTOR_TOP)).createInstance(); plate = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.EJECTOR_TOP)).createInstance();
}
@Override pivotPlate(getLidProgress(partialTick));
public void init(float pt) {
pivotPlate(getLidProgress(pt));
super.init(pt);
} }
@Override @Override
@ -44,8 +39,8 @@ public class EjectorVisual extends ShaftVisual<EjectorBlockEntity> implements Si
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
relight(pos, plate); relight(pos, plate);
} }

View file

@ -8,6 +8,7 @@ import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.AbstractInstance; import dev.engine_room.flywheel.lib.instance.AbstractInstance;
import dev.engine_room.flywheel.lib.instance.FlatLit;
import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.model.baked.PartialModel; import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
@ -24,8 +25,8 @@ public class FunnelVisual extends AbstractBlockEntityVisual<FunnelBlockEntity> i
private final ArrayList<FlapInstance> flaps; private final ArrayList<FlapInstance> flaps;
public FunnelVisual(VisualizationContext context, FunnelBlockEntity blockEntity) { public FunnelVisual(VisualizationContext context, FunnelBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
flaps = new ArrayList<>(4); flaps = new ArrayList<>(4);
@ -76,9 +77,9 @@ public class FunnelVisual extends AbstractBlockEntityVisual<FunnelBlockEntity> i
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
if (flaps != null) if (flaps != null)
relight(pos, flaps.stream()); relight(pos, flaps.toArray(FlatLit[]::new));
} }
@Override @Override

View file

@ -11,6 +11,7 @@ import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.AbstractInstance; import dev.engine_room.flywheel.lib.instance.AbstractInstance;
import dev.engine_room.flywheel.lib.instance.FlatLit;
import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
@ -26,8 +27,10 @@ public class BeltTunnelVisual extends AbstractBlockEntityVisual<BeltTunnelBlockE
private final Map<Direction, ArrayList<FlapInstance>> tunnelFlaps = new EnumMap<>(Direction.class); private final Map<Direction, ArrayList<FlapInstance>> tunnelFlaps = new EnumMap<>(Direction.class);
public BeltTunnelVisual(VisualizationContext context, BeltTunnelBlockEntity blockEntity) { public BeltTunnelVisual(VisualizationContext context, BeltTunnelBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
setupFlaps(partialTick);
} }
private void setupFlaps(float partialTick) { private void setupFlaps(float partialTick) {
@ -69,13 +72,6 @@ public class BeltTunnelVisual extends AbstractBlockEntityVisual<BeltTunnelBlockE
}); });
} }
@Override
public void init(float partialTick) {
setupFlaps(partialTick);
super.init(partialTick);
}
@Override @Override
public void update(float partialTick) { public void update(float partialTick) {
super.update(partialTick); super.update(partialTick);
@ -100,8 +96,8 @@ public class BeltTunnelVisual extends AbstractBlockEntityVisual<BeltTunnelBlockE
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, tunnelFlaps.values().stream().flatMap(Collection::stream)); relight(pos, tunnelFlaps.values().stream().flatMap(Collection::stream).toArray(FlatLit[]::new));
} }
@Override @Override

View file

@ -27,8 +27,8 @@ public class AnalogLeverVisual extends AbstractBlockEntityVisual<AnalogLeverBloc
final float rX; final float rX;
final float rY; final float rY;
public AnalogLeverVisual(VisualizationContext context, AnalogLeverBlockEntity blockEntity) { public AnalogLeverVisual(VisualizationContext context, AnalogLeverBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
handle = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ANALOG_LEVER_HANDLE)) handle = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ANALOG_LEVER_HANDLE))
.createInstance(); .createInstance();
@ -38,11 +38,6 @@ public class AnalogLeverVisual extends AbstractBlockEntityVisual<AnalogLeverBloc
AttachFace face = blockState.getValue(AnalogLeverBlock.FACE); AttachFace face = blockState.getValue(AnalogLeverBlock.FACE);
rX = face == AttachFace.FLOOR ? 0 : face == AttachFace.WALL ? 90 : 180; rX = face == AttachFace.FLOOR ? 0 : face == AttachFace.WALL ? 90 : 180;
rY = AngleHelper.horizontalAngle(blockState.getValue(AnalogLeverBlock.FACING)); rY = AngleHelper.horizontalAngle(blockState.getValue(AnalogLeverBlock.FACING));
}
@Override
public void init(float partialTick) {
super.init(partialTick);
transform(indicator.loadIdentity()); transform(indicator.loadIdentity());
@ -58,7 +53,7 @@ public class AnalogLeverVisual extends AbstractBlockEntityVisual<AnalogLeverBloc
protected void animateLever(float pt) { protected void animateLever(float pt) {
float state = blockEntity.clientState.getValue(pt); float state = blockEntity.clientState.getValue(pt);
indicator.setColor(Color.mixColors(0x2C0300, 0xCD0000, state / 15f)); indicator.color(Color.mixColors(0x2C0300, 0xCD0000, state / 15f));
indicator.setChanged(); indicator.setChanged();
float angle = (float) ((state / 15) * 90 / 180 * Math.PI); float angle = (float) ((state / 15) * 90 / 180 * Math.PI);
@ -76,7 +71,7 @@ public class AnalogLeverVisual extends AbstractBlockEntityVisual<AnalogLeverBloc
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, handle, indicator); relight(pos, handle, indicator);
} }

View file

@ -19,14 +19,14 @@ public class BrassDiodeVisual extends AbstractBlockEntityVisual<BrassDiodeBlockE
protected int previousState; protected int previousState;
public BrassDiodeVisual(VisualizationContext context, BrassDiodeBlockEntity blockEntity) { public BrassDiodeVisual(VisualizationContext context, BrassDiodeBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
indicator = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.FLEXPEATER_INDICATOR)).createInstance(); indicator = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.FLEXPEATER_INDICATOR)).createInstance();
indicator.loadIdentity() indicator.loadIdentity()
.translate(getVisualPosition()) .translate(getVisualPosition())
.setColor(getColor()) .color(getColor())
.setChanged(); .setChanged();
previousState = blockEntity.state; previousState = blockEntity.state;
@ -36,14 +36,14 @@ public class BrassDiodeVisual extends AbstractBlockEntityVisual<BrassDiodeBlockE
public void tick(TickableVisual.Context context) { public void tick(TickableVisual.Context context) {
if (previousState == blockEntity.state) return; if (previousState == blockEntity.state) return;
indicator.setColor(getColor()); indicator.color(getColor());
indicator.setChanged(); indicator.setChanged();
previousState = blockEntity.state; previousState = blockEntity.state;
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, indicator); relight(pos, indicator);
} }

View file

@ -21,8 +21,8 @@ public class SchematicannonVisual extends AbstractBlockEntityVisual<Schematicann
private final TransformedInstance connector; private final TransformedInstance connector;
private final TransformedInstance pipe; private final TransformedInstance pipe;
public SchematicannonVisual(VisualizationContext context, SchematicannonBlockEntity blockEntity) { public SchematicannonVisual(VisualizationContext context, SchematicannonBlockEntity blockEntity, float partialTick) {
super(context, blockEntity); super(context, blockEntity, partialTick);
connector = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.SCHEMATICANNON_CONNECTOR)).createInstance(); connector = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.SCHEMATICANNON_CONNECTOR)).createInstance();
pipe = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.SCHEMATICANNON_PIPE)).createInstance(); pipe = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.SCHEMATICANNON_PIPE)).createInstance();
@ -70,7 +70,7 @@ public class SchematicannonVisual extends AbstractBlockEntityVisual<Schematicann
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, connector, pipe); relight(pos, connector, pipe);
} }

View file

@ -20,8 +20,8 @@ public class CarriageContraptionVisual extends ContraptionVisual<CarriageContrap
private Couple<BogeyVisual> bogeys; private Couple<BogeyVisual> bogeys;
private Couple<Boolean> bogeyHidden; private Couple<Boolean> bogeyHidden;
public CarriageContraptionVisual(VisualizationContext context, CarriageContraptionEntity entity) { public CarriageContraptionVisual(VisualizationContext context, CarriageContraptionEntity entity, float partialTick) {
super(context, entity); super(context, entity, partialTick);
bogeyHidden = Couple.create(() -> false); bogeyHidden = Couple.create(() -> false);
entity.bindInstance(this); entity.bindInstance(this);
} }
@ -33,7 +33,7 @@ public class CarriageContraptionVisual extends ContraptionVisual<CarriageContrap
if (carriage != null) { if (carriage != null) {
bogeys = carriage.bogeys.mapNotNullWithParam((bogey, manager) -> bogey.getStyle() bogeys = carriage.bogeys.mapNotNullWithParam((bogey, manager) -> bogey.getStyle()
.createVisual(bogey, bogey.type.getSize(), manager), visualizationContext); .createVisual(bogey, bogey.type.getSize(), manager), visualizationContext);
updateLight(); updateLight(pt);
} }
super.init(pt); super.init(pt);
@ -86,8 +86,8 @@ public class CarriageContraptionVisual extends ContraptionVisual<CarriageContrap
ms.popPose(); ms.popPose();
} }
public void updateLight() { public void updateLight(float partialTick) {
super.updateLight(); super.updateLight(partialTick);
if (bogeys == null) if (bogeys == null)
return; return;

View file

@ -23,6 +23,9 @@ import com.simibubi.create.content.trains.track.BezierConnection.SegmentAngles;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.longs.LongSets;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos; import net.minecraft.core.SectionPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@ -30,21 +33,16 @@ import net.minecraft.world.level.LightLayer;
public class TrackVisual extends AbstractBlockEntityVisual<TrackBlockEntity> { public class TrackVisual extends AbstractBlockEntityVisual<TrackBlockEntity> {
private List<BezierTrackVisual> visuals; private final List<BezierTrackVisual> visuals;
public TrackVisual(VisualizationContext context, TrackBlockEntity track) { public TrackVisual(VisualizationContext context, TrackBlockEntity track, float partialTick) {
super(context, track); super(context, track, partialTick);
}
@Override
public void init(float partialTick) {
visuals = blockEntity.connections.values() visuals = blockEntity.connections.values()
.stream() .stream()
.map(this::createInstance) .map(this::createInstance)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.toList(); .toList();
super.init(partialTick);
} }
@Override @Override
@ -53,12 +51,11 @@ public class TrackVisual extends AbstractBlockEntityVisual<TrackBlockEntity> {
return; return;
_delete(); _delete();
init(pt); lightSections.sections(collectLightSections());
notifier.notifySectionsChanged();
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
if (visuals == null) if (visuals == null)
return; return;
visuals.forEach(BezierTrackVisual::updateLight); visuals.forEach(BezierTrackVisual::updateLight);
@ -78,10 +75,11 @@ public class TrackVisual extends AbstractBlockEntityVisual<TrackBlockEntity> {
visuals.forEach(BezierTrackVisual::delete); visuals.forEach(BezierTrackVisual::delete);
} }
@Override public LongSet collectLightSections() {
public void collectLightSections(LongConsumer consumer) { LongSet longSet = new LongArraySet();
if (blockEntity.connections.isEmpty()) { if (blockEntity.connections.isEmpty()) {
return; return LongSet.of();
} }
int minX = Integer.MAX_VALUE; int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE; int minY = Integer.MAX_VALUE;
@ -99,7 +97,9 @@ public class TrackVisual extends AbstractBlockEntityVisual<TrackBlockEntity> {
} }
SectionPos.betweenClosedStream(SectionPos.blockToSectionCoord(minX), SectionPos.blockToSectionCoord(minY), SectionPos.blockToSectionCoord(minZ), SectionPos.blockToSectionCoord(maxX), SectionPos.blockToSectionCoord(maxY), SectionPos.blockToSectionCoord(maxZ)) SectionPos.betweenClosedStream(SectionPos.blockToSectionCoord(minX), SectionPos.blockToSectionCoord(minY), SectionPos.blockToSectionCoord(minZ), SectionPos.blockToSectionCoord(maxX), SectionPos.blockToSectionCoord(maxY), SectionPos.blockToSectionCoord(maxZ))
.mapToLong(SectionPos::asLong) .mapToLong(SectionPos::asLong)
.forEach(consumer); .forEach(longSet::add);
return longSet;
} }
@Override @Override

View file

@ -36,8 +36,8 @@ public class AllInstanceTypes {
MemoryUtil.memPutByte(ptr + 1, instance.g); MemoryUtil.memPutByte(ptr + 1, instance.g);
MemoryUtil.memPutByte(ptr + 2, instance.b); MemoryUtil.memPutByte(ptr + 2, instance.b);
MemoryUtil.memPutByte(ptr + 3, instance.a); MemoryUtil.memPutByte(ptr + 3, instance.a);
MemoryUtil.memPutShort(ptr + 4, (short) (instance.packedLight & 0xFFFF)); MemoryUtil.memPutShort(ptr + 4, (short) (instance.light & 0xFFFF));
MemoryUtil.memPutShort(ptr + 6, (short) (instance.packedLight >> 16 & 0xFFFF)); MemoryUtil.memPutShort(ptr + 6, (short) (instance.light >> 16 & 0xFFFF));
MemoryUtil.memPutInt(ptr + 8, instance.overlay); MemoryUtil.memPutInt(ptr + 8, instance.overlay);
MemoryUtil.memPutFloat(ptr + 12, instance.x); MemoryUtil.memPutFloat(ptr + 12, instance.x);
MemoryUtil.memPutFloat(ptr + 16, instance.y); MemoryUtil.memPutFloat(ptr + 16, instance.y);
@ -70,8 +70,8 @@ public class AllInstanceTypes {
MemoryUtil.memPutByte(ptr + 1, instance.g); MemoryUtil.memPutByte(ptr + 1, instance.g);
MemoryUtil.memPutByte(ptr + 2, instance.b); MemoryUtil.memPutByte(ptr + 2, instance.b);
MemoryUtil.memPutByte(ptr + 3, instance.a); MemoryUtil.memPutByte(ptr + 3, instance.a);
MemoryUtil.memPutShort(ptr + 4, (short) (instance.packedLight & 0xFFFF)); MemoryUtil.memPutShort(ptr + 4, (short) (instance.light & 0xFFFF));
MemoryUtil.memPutShort(ptr + 6, (short) (instance.packedLight >> 16 & 0xFFFF)); MemoryUtil.memPutShort(ptr + 6, (short) (instance.light >> 16 & 0xFFFF));
MemoryUtil.memPutInt(ptr + 8, instance.overlay); MemoryUtil.memPutInt(ptr + 8, instance.overlay);
MemoryUtil.memPutFloat(ptr + 12, instance.x); MemoryUtil.memPutFloat(ptr + 12, instance.x);
MemoryUtil.memPutFloat(ptr + 16, instance.y); MemoryUtil.memPutFloat(ptr + 16, instance.y);

View file

@ -0,0 +1,142 @@
package com.simibubi.create.foundation.utility.flywheel.box;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.AABB;
public interface Box {
int getMinX();
int getMinY();
int getMinZ();
int getMaxX();
int getMaxY();
int getMaxZ();
default int sizeX() {
return getMaxX() - getMinX();
}
default int sizeY() {
return getMaxY() - getMinY();
}
default int sizeZ() {
return getMaxZ() - getMinZ();
}
default int volume() {
return sizeX() * sizeY() * sizeZ();
}
default boolean isEmpty() {
// if any dimension has side length 0 this box contains no volume
return getMinX() == getMaxX() || getMinY() == getMaxY() || getMinZ() == getMaxZ();
}
default boolean sameAs(Box other) {
return getMinX() == other.getMinX() && getMinY() == other.getMinY() && getMinZ() == other.getMinZ() && getMaxX() == other.getMaxX() && getMaxY() == other.getMaxY() && getMaxZ() == other.getMaxZ();
}
default boolean sameAs(Box other, int margin) {
return getMinX() == other.getMinX() - margin &&
getMinY() == other.getMinY() - margin &&
getMinZ() == other.getMinZ() - margin &&
getMaxX() == other.getMaxX() + margin &&
getMaxY() == other.getMaxY() + margin &&
getMaxZ() == other.getMaxZ() + margin;
}
default boolean sameAs(AABB other) {
return getMinX() == Math.floor(other.minX)
&& getMinY() == Math.floor(other.minY)
&& getMinZ() == Math.floor(other.minZ)
&& getMaxX() == Math.ceil(other.maxX)
&& getMaxY() == Math.ceil(other.maxY)
&& getMaxZ() == Math.ceil(other.maxZ);
}
default boolean intersects(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
return this.getMinX() < maxX && this.getMaxX() > minX && this.getMinY() < maxY && this.getMaxY() > minY && this.getMinZ() < maxZ && this.getMaxZ() > minZ;
}
default boolean intersects(Box other) {
return this.intersects(other.getMinX(), other.getMinY(), other.getMinZ(), other.getMaxX(), other.getMaxY(), other.getMaxZ());
}
default boolean contains(int x, int y, int z) {
return x >= getMinX()
&& x <= getMaxX()
&& y >= getMinY()
&& y <= getMaxY()
&& z >= getMinZ()
&& z <= getMaxZ();
}
default boolean contains(Box other) {
return other.getMinX() >= this.getMinX()
&& other.getMaxX() <= this.getMaxX()
&& other.getMinY() >= this.getMinY()
&& other.getMaxY() <= this.getMaxY()
&& other.getMinZ() >= this.getMinZ()
&& other.getMaxZ() <= this.getMaxZ();
}
default void forEachContained(CoordinateConsumer func) {
int minX = getMinX();
int minY = getMinY();
int minZ = getMinZ();
int maxX = getMaxX();
int maxY = getMaxY();
int maxZ = getMaxZ();
for (int x = minX; x < maxX; x++) {
for (int y = minY; y < maxY; y++) {
for (int z = minZ; z < maxZ; z++) {
func.accept(x, y, z);
}
}
}
}
default boolean hasPowerOf2Sides() {
// this is only true if all individual side lengths are powers of 2
return Mth.isPowerOfTwo(volume());
}
default MutableBox union(Box other) {
int minX = Math.min(this.getMinX(), other.getMinX());
int minY = Math.min(this.getMinY(), other.getMinY());
int minZ = Math.min(this.getMinZ(), other.getMinZ());
int maxX = Math.max(this.getMaxX(), other.getMaxX());
int maxY = Math.max(this.getMaxY(), other.getMaxY());
int maxZ = Math.max(this.getMaxZ(), other.getMaxZ());
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
}
default MutableBox intersect(Box other) {
int minX = Math.max(this.getMinX(), other.getMinX());
int minY = Math.max(this.getMinY(), other.getMinY());
int minZ = Math.max(this.getMinZ(), other.getMinZ());
int maxX = Math.min(this.getMaxX(), other.getMaxX());
int maxY = Math.min(this.getMaxY(), other.getMaxY());
int maxZ = Math.min(this.getMaxZ(), other.getMaxZ());
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
}
default AABB toAABB() {
return new AABB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
}
default MutableBox copy() {
return new MutableBox(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
}
@FunctionalInterface
interface CoordinateConsumer {
void accept(int x, int y, int z);
}
}

View file

@ -0,0 +1,329 @@
package com.simibubi.create.foundation.utility.flywheel.box;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.SectionPos;
import net.minecraft.core.Vec3i;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.AABB;
import java.util.Collection;
public class MutableBox implements Box {
protected int minX;
protected int minY;
protected int minZ;
protected int maxX;
protected int maxY;
protected int maxZ;
public MutableBox() {
}
public MutableBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
this.minX = minX;
this.minY = minY;
this.minZ = minZ;
this.maxX = maxX;
this.maxY = maxY;
this.maxZ = maxZ;
}
public static MutableBox from(AABB aabb) {
int minX = (int) Math.floor(aabb.minX);
int minY = (int) Math.floor(aabb.minY);
int minZ = (int) Math.floor(aabb.minZ);
int maxX = (int) Math.ceil(aabb.maxX);
int maxY = (int) Math.ceil(aabb.maxY);
int maxZ = (int) Math.ceil(aabb.maxZ);
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
}
public static MutableBox from(Vec3i pos) {
return new MutableBox(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
}
public static MutableBox from(SectionPos pos) {
return new MutableBox(pos.minBlockX(), pos.minBlockY(), pos.minBlockZ(), pos.maxBlockX() + 1, pos.maxBlockY() + 1, pos.maxBlockZ() + 1);
}
public static MutableBox from(Vec3i start, Vec3i end) {
return new MutableBox(start.getX(), start.getY(), start.getZ(), end.getX() + 1, end.getY() + 1, end.getZ() + 1);
}
public static MutableBox ofRadius(int radius) {
return new MutableBox(-radius, -radius, -radius, radius + 1, radius + 1, radius + 1);
}
public static Box containingAll(Collection<BlockPos> positions) {
if (positions.isEmpty()) {
return new MutableBox();
}
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int minZ = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
int maxZ = Integer.MIN_VALUE;
for (BlockPos pos : positions) {
minX = Math.min(minX, pos.getX());
minY = Math.min(minY, pos.getY());
minZ = Math.min(minZ, pos.getZ());
maxX = Math.max(maxX, pos.getX());
maxY = Math.max(maxY, pos.getY());
maxZ = Math.max(maxZ, pos.getZ());
}
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
}
@Override
public int getMinX() {
return minX;
}
@Override
public int getMinY() {
return minY;
}
@Override
public int getMinZ() {
return minZ;
}
@Override
public int getMaxX() {
return maxX;
}
@Override
public int getMaxY() {
return maxY;
}
@Override
public int getMaxZ() {
return maxZ;
}
public void setMinX(int minX) {
this.minX = minX;
}
public void setMinY(int minY) {
this.minY = minY;
}
public MutableBox setMinZ(int minZ) {
this.minZ = minZ;
return this;
}
public void setMaxX(int maxX) {
this.maxX = maxX;
}
public void setMaxY(int maxY) {
this.maxY = maxY;
}
public void setMaxZ(int maxZ) {
this.maxZ = maxZ;
}
public void setMin(int x, int y, int z) {
minX = x;
minY = y;
minZ = z;
}
public void setMax(int x, int y, int z) {
maxX = x;
maxY = y;
maxZ = z;
}
public void setMin(Vec3i v) {
setMin(v.getX(), v.getY(), v.getZ());
}
public void setMax(Vec3i v) {
setMax(v.getX(), v.getY(), v.getZ());
}
public void assign(Box other) {
minX = other.getMinX();
minY = other.getMinY();
minZ = other.getMinZ();
maxX = other.getMaxX();
maxY = other.getMaxY();
maxZ = other.getMaxZ();
}
public void assign(AABB other) {
minX = (int) Math.floor(other.minX);
minY = (int) Math.floor(other.minY);
minZ = (int) Math.floor(other.minZ);
maxX = (int) Math.ceil(other.maxX);
maxY = (int) Math.ceil(other.maxY);
maxZ = (int) Math.ceil(other.maxZ);
}
public void assign(Vec3i start, Vec3i end) {
minX = start.getX();
minY = start.getY();
minZ = start.getZ();
maxX = end.getX() + 1;
maxY = end.getY() + 1;
maxZ = end.getZ() + 1;
}
public void unionAssign(Box other) {
minX = Math.min(this.minX, other.getMinX());
minY = Math.min(this.minY, other.getMinY());
minZ = Math.min(this.minZ, other.getMinZ());
maxX = Math.max(this.maxX, other.getMaxX());
maxY = Math.max(this.maxY, other.getMaxY());
maxZ = Math.max(this.maxZ, other.getMaxZ());
}
public void unionAssign(AABB other) {
minX = Math.min(this.minX, (int) Math.floor(other.minX));
minY = Math.min(this.minY, (int) Math.floor(other.minY));
minZ = Math.min(this.minZ, (int) Math.floor(other.minZ));
maxX = Math.max(this.maxX, (int) Math.ceil(other.maxX));
maxY = Math.max(this.maxY, (int) Math.ceil(other.maxY));
maxZ = Math.max(this.maxZ, (int) Math.ceil(other.maxZ));
}
public void intersectAssign(Box other) {
minX = Math.max(this.minX, other.getMinX());
minY = Math.max(this.minY, other.getMinY());
minZ = Math.max(this.minZ, other.getMinZ());
maxX = Math.min(this.maxX, other.getMaxX());
maxY = Math.min(this.maxY, other.getMaxY());
maxZ = Math.min(this.maxZ, other.getMaxZ());
}
public void fixMinMax() {
int minX = Math.min(this.minX, this.maxX);
int minY = Math.min(this.minY, this.maxY);
int minZ = Math.min(this.minZ, this.maxZ);
int maxX = Math.max(this.minX, this.maxX);
int maxY = Math.max(this.minY, this.maxY);
int maxZ = Math.max(this.minZ, this.maxZ);
this.minX = minX;
this.minY = minY;
this.minZ = minZ;
this.maxX = maxX;
this.maxY = maxY;
this.maxZ = maxZ;
}
public void translate(int x, int y, int z) {
minX = minX + x;
maxX = maxX + x;
minY = minY + y;
maxY = maxY + y;
minZ = minZ + z;
maxZ = maxZ + z;
}
public void translate(Vec3i by) {
translate(by.getX(), by.getY(), by.getZ());
}
public void grow(int x, int y, int z) {
minX = minX - x;
minY = minY - y;
minZ = minZ - z;
maxX = maxX + x;
maxY = maxY + y;
maxZ = maxZ + z;
}
public void grow(int s) {
this.grow(s, s, s);
}
/**
* Grow this box to have power of 2 side lengths, scaling from the minimum coords.
*/
public void nextPowerOf2() {
int sizeX = Mth.smallestEncompassingPowerOfTwo(sizeX());
int sizeY = Mth.smallestEncompassingPowerOfTwo(sizeY());
int sizeZ = Mth.smallestEncompassingPowerOfTwo(sizeZ());
maxX = minX + sizeX;
maxY = minY + sizeY;
maxZ = minZ + sizeZ;
}
/**
* Grow this box to have power of 2 side length, scaling from the center.
*/
public void nextPowerOf2Centered() {
int sizeX = sizeX();
int sizeY = sizeY();
int sizeZ = sizeZ();
int newSizeX = Mth.smallestEncompassingPowerOfTwo(sizeX);
int newSizeY = Mth.smallestEncompassingPowerOfTwo(sizeY);
int newSizeZ = Mth.smallestEncompassingPowerOfTwo(sizeZ);
int diffX = newSizeX - sizeX;
int diffY = newSizeY - sizeY;
int diffZ = newSizeZ - sizeZ;
minX = minX - diffX / 2; // floor division for the minimums
minY = minY - diffY / 2;
minZ = minZ - diffZ / 2;
maxX = maxX + (diffX + 1) / 2; // ceiling divison for the maximums
maxY = maxY + (diffY + 1) / 2;
maxZ = maxZ + (diffZ + 1) / 2;
}
public void mirrorAbout(Direction.Axis axis) {
Vec3i axisVec = Direction.get(Direction.AxisDirection.POSITIVE, axis)
.getNormal();
int flipX = axisVec.getX() - 1;
int flipY = axisVec.getY() - 1;
int flipZ = axisVec.getZ() - 1;
int maxX = this.maxX * flipX;
int maxY = this.maxY * flipY;
int maxZ = this.maxZ * flipZ;
this.maxX = this.minX * flipX;
this.maxY = this.minY * flipY;
this.maxZ = this.minZ * flipZ;
this.minX = maxX;
this.minY = maxY;
this.minZ = maxZ;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (!(o instanceof Box that)) return false;
return this.sameAs(that);
}
@Override
public int hashCode() {
int result = minX;
result = 31 * result + minY;
result = 31 * result + minZ;
result = 31 * result + maxX;
result = 31 * result + maxY;
result = 31 * result + maxZ;
return result;
}
@Override
public String toString() {
return "(" + minX + ", " + minY + ", " + minZ + ")->(" + maxX + ", " + maxY + ", " + maxZ + ')';
}
}

View file

@ -0,0 +1,219 @@
package com.simibubi.create.foundation.utility.flywheel.light;
import com.simibubi.create.foundation.utility.flywheel.box.Box;
import com.simibubi.create.foundation.utility.flywheel.box.MutableBox;
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.LightLayer;
import org.lwjgl.system.MemoryUtil;
public class LightVolume implements Box {
protected final BlockAndTintGetter level;
protected final MutableBox box = new MutableBox();
protected MemoryBlock lightData;
public LightVolume(BlockAndTintGetter level, Box sampleVolume) {
this.level = level;
this.setBox(sampleVolume);
this.lightData = MemoryBlock.malloc(this.box.volume() * 2);
}
public Box getVolume() {
return box;
}
@Override
public int getMinX() {
return box.getMinX();
}
@Override
public int getMinY() {
return box.getMinY();
}
@Override
public int getMinZ() {
return box.getMinZ();
}
@Override
public int getMaxX() {
return box.getMaxX();
}
@Override
public int getMaxY() {
return box.getMaxY();
}
@Override
public int getMaxZ() {
return box.getMaxZ();
}
public boolean isInvalid() {
return lightData == null;
}
protected void setBox(Box box) {
this.box.assign(box);
}
public short getPackedLight(int x, int y, int z) {
if (box.contains(x, y, z)) {
return MemoryUtil.memGetShort(levelPosToPtr(x, y, z));
} else {
return 0;
}
}
public void move(Box newSampleVolume) {
if (lightData == null) return;
setBox(newSampleVolume);
int neededCapacity = box.volume() * 2;
if (neededCapacity > lightData.size()) {
lightData = lightData.realloc(neededCapacity);
}
initialize();
}
/**
* Completely (re)populate this volume with block and sky lighting data.
* This is expensive and should be avoided.
*/
public void initialize() {
if (lightData == null) return;
copyLight(getVolume());
markDirty();
}
protected void markDirty() {
// noop
}
public void delete() {
lightData.free();
lightData = null;
}
/**
* Copy all light from the level into this volume.
*
* @param levelVolume the region in the level to copy data from.
*/
public void copyLight(Box levelVolume) {
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
int xShift = box.getMinX();
int yShift = box.getMinY();
int zShift = box.getMinZ();
levelVolume.forEachContained((x, y, z) -> {
pos.set(x, y, z);
int block = this.level.getBrightness(LightLayer.BLOCK, pos);
int sky = this.level.getBrightness(LightLayer.SKY, pos);
writeLight(x - xShift, y - yShift, z - zShift, block, sky);
});
}
protected void writeLight(int x, int y, int z, int block, int sky) {
byte b = (byte) ((block & 0xF) << 4);
byte s = (byte) ((sky & 0xF) << 4);
long ptr = boxPosToPtr(x, y, z);
MemoryUtil.memPutByte(ptr, b);
MemoryUtil.memPutByte(ptr + 1, s);
}
/**
* Copy block light from the level into this volume.
*
* @param levelVolume the region in the level to copy data from.
*/
public void copyBlock(Box levelVolume) {
var pos = new BlockPos.MutableBlockPos();
int xShift = box.getMinX();
int yShift = box.getMinY();
int zShift = box.getMinZ();
levelVolume.forEachContained((x, y, z) -> {
int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z));
writeBlock(x - xShift, y - yShift, z - zShift, light);
});
}
protected void writeBlock(int x, int y, int z, int block) {
byte b = (byte) ((block & 0xF) << 4);
MemoryUtil.memPutByte(boxPosToPtr(x, y, z), b);
}
/**
* Copy sky light from the level into this volume.
*
* @param levelVolume the region in the level to copy data from.
*/
public void copySky(Box levelVolume) {
var pos = new BlockPos.MutableBlockPos();
int xShift = box.getMinX();
int yShift = box.getMinY();
int zShift = box.getMinZ();
levelVolume.forEachContained((x, y, z) -> {
int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z));
writeSky(x - xShift, y - yShift, z - zShift, light);
});
}
protected void writeSky(int x, int y, int z, int sky) {
byte s = (byte) ((sky & 0xF) << 4);
MemoryUtil.memPutByte(boxPosToPtr(x, y, z) + 1, s);
}
protected long levelPosToPtr(int x, int y, int z) {
return lightData.ptr() + levelPosToPtrOffset(x, y, z);
}
protected long boxPosToPtr(int x, int y, int z) {
return lightData.ptr() + boxPosToPtrOffset(x, y, z);
}
protected int levelPosToPtrOffset(int x, int y, int z) {
x -= box.getMinX();
y -= box.getMinY();
z -= box.getMinZ();
return boxPosToPtrOffset(x, y, z);
}
protected int boxPosToPtrOffset(int x, int y, int z) {
return (x + box.sizeX() * (y + z * box.sizeY())) * 2;
}
public void onLightUpdate(LightLayer type, SectionPos pos) {
if (lightData == null) return;
MutableBox vol = MutableBox.from(pos);
if (!vol.intersects(getVolume())) return;
vol.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data.
if (type == LightLayer.BLOCK) copyBlock(vol);
else if (type == LightLayer.SKY) copySky(vol);
markDirty();
}
}