From 03a94dd74d5fb155f95929a5216538c12a6d1931 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Sat, 19 Oct 2024 16:18:54 -0700 Subject: [PATCH] Refactor bogey rendering --- .../com/simibubi/create/AllBogeyStyles.java | 128 +----- src/main/java/com/simibubi/create/Create.java | 2 +- .../trains/bogey/AbstractBogeyBlock.java | 44 +- .../bogey/AbstractBogeyBlockEntity.java | 6 +- .../trains/bogey/BackupBogeyRenderer.java | 22 - .../bogey/BogeyBlockEntityRenderer.java | 15 +- .../content/trains/bogey/BogeyRenderer.java | 395 +----------------- .../content/trains/bogey/BogeySizes.java | 102 ++--- .../content/trains/bogey/BogeyStyle.java | 169 +++++--- .../content/trains/bogey/BogeyVisual.java | 62 +-- .../content/trains/bogey/BogeyVisualizer.java | 10 + .../trains/bogey/StandardBogeyRenderer.java | 147 +++---- .../trains/bogey/StandardBogeyVisual.java | 215 ++++++++++ .../content/trains/entity/CarriageBogey.java | 15 +- .../entity/CarriageContraptionEntity.java | 1 + .../CarriageContraptionEntityRenderer.java | 6 +- .../entity/CarriageContraptionVisual.java | 60 +-- .../content/trains/entity/CarriageSounds.java | 4 +- .../create/foundation/utility/Couple.java | 4 + 19 files changed, 544 insertions(+), 863 deletions(-) delete mode 100644 src/main/java/com/simibubi/create/content/trains/bogey/BackupBogeyRenderer.java create mode 100644 src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisualizer.java create mode 100644 src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyVisual.java diff --git a/src/main/java/com/simibubi/create/AllBogeyStyles.java b/src/main/java/com/simibubi/create/AllBogeyStyles.java index 96b5c1568..67506bb9d 100644 --- a/src/main/java/com/simibubi/create/AllBogeyStyles.java +++ b/src/main/java/com/simibubi/create/AllBogeyStyles.java @@ -1,132 +1,42 @@ package com.simibubi.create; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; -import com.google.common.collect.ImmutableMap; -import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock; -import com.simibubi.create.content.trains.bogey.BogeyRenderer; -import com.simibubi.create.content.trains.bogey.BogeyRenderer.CommonRenderer; +import org.jetbrains.annotations.ApiStatus; + import com.simibubi.create.content.trains.bogey.BogeySizes; import com.simibubi.create.content.trains.bogey.BogeyStyle; -import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer.CommonStandardBogeyRenderer; -import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer.LargeStandardBogeyRenderer; -import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer.SmallStandardBogeyRenderer; +import com.simibubi.create.content.trains.bogey.BogeyStyle.SizeRenderer; +import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer; +import com.simibubi.create.content.trains.bogey.StandardBogeyVisual; import com.simibubi.create.foundation.utility.Components; -import com.simibubi.create.foundation.utility.Lang; -import com.tterrag.registrate.util.entry.BlockEntry; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class AllBogeyStyles { public static final Map BOGEY_STYLES = new HashMap<>(); public static final Map> CYCLE_GROUPS = new HashMap<>(); - private static final Map EMPTY_GROUP = ImmutableMap.of(); + private static final Map EMPTY_GROUP = Collections.emptyMap(); + + public static final ResourceLocation STANDARD_CYCLE_GROUP = Create.asResource("standard"); + + public static final BogeyStyle STANDARD = + builder("standard", STANDARD_CYCLE_GROUP).displayName(Components.translatable("create.bogey.style.standard")) + .size(BogeySizes.SMALL, AllBlocks.SMALL_BOGEY, () -> new SizeRenderer(new StandardBogeyRenderer.Small(), StandardBogeyVisual.Small::new)) + .size(BogeySizes.LARGE, AllBlocks.LARGE_BOGEY, () -> new SizeRenderer(new StandardBogeyRenderer.Large(), StandardBogeyVisual.Large::new)) + .build(); public static Map getCycleGroup(ResourceLocation cycleGroup) { return CYCLE_GROUPS.getOrDefault(cycleGroup, EMPTY_GROUP); } - public static final String STANDARD_CYCLE_GROUP = "standard"; - - public static final BogeyStyle STANDARD = - create("standard", STANDARD_CYCLE_GROUP).commonRenderer(() -> CommonStandardBogeyRenderer::new) - .displayName(Components.translatable("create.bogey.style.standard")) - .size(BogeySizes.SMALL, () -> SmallStandardBogeyRenderer::new, AllBlocks.SMALL_BOGEY) - .size(BogeySizes.LARGE, () -> LargeStandardBogeyRenderer::new, AllBlocks.LARGE_BOGEY) - .build(); - - private static BogeyStyleBuilder create(String name, String cycleGroup) { - return create(Create.asResource(name), Create.asResource(cycleGroup)); + private static BogeyStyle.Builder builder(String name, ResourceLocation cycleGroup) { + return new BogeyStyle.Builder(Create.asResource(name), cycleGroup); } - public static BogeyStyleBuilder create(ResourceLocation name, ResourceLocation cycleGroup) { - return new BogeyStyleBuilder(name, cycleGroup); - } - - public static void register() {} - - public static class BogeyStyleBuilder { - protected final Map> sizeRenderers = new HashMap<>(); - protected final Map sizes = new HashMap<>(); - protected final ResourceLocation name; - protected final ResourceLocation cycleGroup; - - protected Component displayName = Lang.translateDirect("bogey.style.invalid"); - protected ResourceLocation soundType = AllSoundEvents.TRAIN2.getId(); - protected CompoundTag defaultData = new CompoundTag(); - protected ParticleOptions contactParticle = ParticleTypes.CRIT; - protected ParticleOptions smokeParticle = ParticleTypes.POOF; - protected Optional> commonRenderer = Optional.empty(); - - public BogeyStyleBuilder(ResourceLocation name, ResourceLocation cycleGroup) { - this.name = name; - this.cycleGroup = cycleGroup; - } - - public BogeyStyleBuilder displayName(Component displayName) { - this.displayName = displayName; - return this; - } - - public BogeyStyleBuilder soundType(ResourceLocation soundType) { - this.soundType = soundType; - return this; - } - - public BogeyStyleBuilder defaultData(CompoundTag defaultData) { - this.defaultData = defaultData; - return this; - } - - public BogeyStyleBuilder size(BogeySizes.BogeySize size, Supplier> renderer, - BlockEntry> blockEntry) { - this.size(size, renderer, blockEntry.getId()); - return this; - } - - public BogeyStyleBuilder size(BogeySizes.BogeySize size, Supplier> renderer, - ResourceLocation location) { - this.sizes.put(size, location); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - this.sizeRenderers.put(size, () -> new BogeyStyle.SizeRenderData(renderer.get(), renderer.get() - .get())); - }); - return this; - } - - public BogeyStyleBuilder contactParticle(ParticleOptions contactParticle) { - this.contactParticle = contactParticle; - return this; - } - - public BogeyStyleBuilder smokeParticle(ParticleOptions smokeParticle) { - this.smokeParticle = smokeParticle; - return this; - } - - public BogeyStyleBuilder commonRenderer(Supplier> commonRenderer) { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - this.commonRenderer = Optional.of(commonRenderer.get()); - }); - return this; - } - - public BogeyStyle build() { - BogeyStyle entry = new BogeyStyle(name, cycleGroup, displayName, soundType, contactParticle, smokeParticle, - defaultData, sizes, sizeRenderers, commonRenderer); - BOGEY_STYLES.put(name, entry); - CYCLE_GROUPS.computeIfAbsent(cycleGroup, l -> new HashMap<>()) - .put(name, entry); - return entry; - } + @ApiStatus.Internal + public static void init() { } } diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index b98042c45..2ef1094a8 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -136,7 +136,7 @@ public class Create { AllFanProcessingTypes.register(); BlockSpoutingBehaviour.registerDefaults(); BogeySizes.init(); - AllBogeyStyles.register(); + AllBogeyStyles.init(); // ---- ComputerCraftProxy.register(); diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java index 5478264bf..81a34571d 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java @@ -4,18 +4,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.List; -import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Axis; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.AllItems; @@ -33,8 +30,6 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.RegisteredObjects; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -57,8 +52,6 @@ import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.registries.ForgeRegistries; public abstract class AbstractBogeyBlock extends Block implements IBE, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable { @@ -66,7 +59,6 @@ public abstract class AbstractBogeyBlock ext static final List BOGEYS = new ArrayList<>(); public BogeySizes.BogeySize size; - public AbstractBogeyBlock(Properties pProperties, BogeySizes.BogeySize size) { super(pProperties); registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false)); @@ -91,7 +83,7 @@ public abstract class AbstractBogeyBlock ext /** * Only for internal Create use. If you have your own style set, do not call this method */ - @Deprecated + @ApiStatus.Internal public static void registerStandardBogey(ResourceLocation block) { BOGEYS.add(block); } @@ -147,30 +139,6 @@ public abstract class AbstractBogeyBlock ext return false; } - @OnlyIn(Dist.CLIENT) - public void render(@Nullable BlockState state, float wheelAngle, PoseStack ms, float partialTicks, - MultiBufferSource buffers, int light, int overlay, BogeyStyle style, CompoundTag bogeyData) { - if (style == null) - style = getDefaultStyle(); - - final Optional commonRenderer - = style.getInWorldCommonRenderInstance(); - final BogeyRenderer renderer = style.getInWorldRenderInstance(this.getSize()); - if (state != null) { - ms.translate(.5f, .5f, .5f); - if (state.getValue(AXIS) == Direction.Axis.X) - ms.mulPose(Axis.YP.rotationDegrees(90)); - } - ms.translate(0, -1.5 - 1 / 128f, 0); - VertexConsumer vb = buffers.getBuffer(RenderType.cutoutMipped()); - if (bogeyData == null) - bogeyData = new CompoundTag(); - renderer.render(bogeyData, wheelAngle, ms, light, vb, state == null); - CompoundTag finalBogeyData = bogeyData; - commonRenderer.ifPresent(common -> - common.render(finalBogeyData, wheelAngle, ms, light, vb, state == null)); - } - public BogeySizes.BogeySize getSize() { return this.size; } @@ -216,9 +184,9 @@ public abstract class AbstractBogeyBlock ext Set validSizes = style.validSizes(); - for (int i = 0; i < BogeySizes.count(); i++) { + for (int i = 0; i < BogeySizes.all().size(); i++) { if (validSizes.contains(size)) break; - size = size.increment(); + size = size.nextBySize(); } sbbe.setBogeyStyle(style); @@ -227,7 +195,7 @@ public abstract class AbstractBogeyBlock ext sbbe.setBogeyData(sbbe.getBogeyData().merge(defaultData)); if (size == getSize()) { - if (state.getBlock() != style.getBlockOfSize(size)) { + if (state.getBlock() != style.getBlockForSize(size)) { CompoundTag oldData = sbbe.getBogeyData(); level.setBlock(pos, copyProperties(state, getStateOfSize(sbbe, size)), Block.UPDATE_ALL); if (!(level.getBlockEntity(pos) instanceof AbstractBogeyBlockEntity bogeyBlockEntity)) @@ -328,7 +296,7 @@ public abstract class AbstractBogeyBlock ext public BlockState getStateOfSize(AbstractBogeyBlockEntity sbbe, BogeySizes.BogeySize size) { BogeyStyle style = sbbe.getStyle(); - BlockState state = style.getBlockOfSize(size).defaultBlockState(); + BlockState state = style.getBlockForSize(size).defaultBlockState(); return copyProperties(sbbe.getBlockState(), state); } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java index 59985cc7a..6fc496c50 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java @@ -37,14 +37,14 @@ public abstract class AbstractBogeyBlockEntity extends CachedRenderBBBlockEntity public void setBogeyData(@NotNull CompoundTag newData) { if (!newData.contains(BOGEY_STYLE_KEY)) { - ResourceLocation style = getDefaultStyle().name; + ResourceLocation style = getDefaultStyle().id; NBTHelper.writeResourceLocation(newData, BOGEY_STYLE_KEY, style); } this.bogeyData = newData; } public void setBogeyStyle(@NotNull BogeyStyle style) { - ResourceLocation location = style.name; + ResourceLocation location = style.id; CompoundTag data = this.getBogeyData(); NBTHelper.writeResourceLocation(data, BOGEY_STYLE_KEY, location); markUpdated(); @@ -80,7 +80,7 @@ public abstract class AbstractBogeyBlockEntity extends CachedRenderBBBlockEntity private CompoundTag createBogeyData() { CompoundTag nbt = new CompoundTag(); - NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, getDefaultStyle().name); + NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, getDefaultStyle().id); boolean upsideDown = false; if (getBlockState().getBlock() instanceof AbstractBogeyBlock bogeyBlock) upsideDown = bogeyBlock.isUpsideDown(getBlockState()); diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BackupBogeyRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BackupBogeyRenderer.java deleted file mode 100644 index ff93126a9..000000000 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BackupBogeyRenderer.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.simibubi.create.content.trains.bogey; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.simibubi.create.content.trains.entity.CarriageBogey; - -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import net.minecraft.nbt.CompoundTag; - -public class BackupBogeyRenderer extends BogeyRenderer.CommonRenderer { - public static BackupBogeyRenderer INSTANCE = new BackupBogeyRenderer(); - - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - - } - - @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - - } -} diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java index e570fa26b..d340cc5b3 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java @@ -1,16 +1,18 @@ package com.simibubi.create.content.trains.bogey; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.core.Direction; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; public class BogeyBlockEntityRenderer extends SafeBlockEntityRenderer { - - public BogeyBlockEntityRenderer(BlockEntityRendererProvider.Context context) {} + public BogeyBlockEntityRenderer(BlockEntityRendererProvider.Context context) { + } @Override protected void renderSafe(T be, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, @@ -18,9 +20,12 @@ public class BogeyBlockEntityRenderer extends SafeBlockEn BlockState blockState = be.getBlockState(); if (be instanceof AbstractBogeyBlockEntity sbbe) { float angle = sbbe.getVirtualAngle(partialTicks); - if (blockState.getBlock() instanceof AbstractBogeyBlock bogey) - bogey.render(blockState, angle, ms, partialTicks, buffer, light, overlay, sbbe.getStyle(), sbbe.getBogeyData()); + if (blockState.getBlock() instanceof AbstractBogeyBlock bogey) { + ms.translate(.5f, .5f, .5f); + if (blockState.getValue(AbstractBogeyBlock.AXIS) == Direction.Axis.X) + ms.mulPose(Axis.YP.rotationDegrees(90)); + sbbe.getStyle().render(bogey.getSize(), partialTicks, ms, buffer, light, overlay, angle, sbbe.getBogeyData(), false); + } } } - } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java index 22c44ae99..9afce4cb6 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java @@ -1,399 +1,10 @@ package com.simibubi.create.content.trains.bogey; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.IntStream; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3fc; -import org.joml.Matrix4fc; -import org.joml.Quaternionfc; - import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.simibubi.create.content.trains.entity.CarriageBogey; -import com.simibubi.create.foundation.render.CachedBufferer; -import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.render.VirtualRenderHelper; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.instance.InstanceTypes; -import dev.engine_room.flywheel.lib.instance.PosedInstance; -import dev.engine_room.flywheel.lib.model.Models; -import dev.engine_room.flywheel.lib.model.baked.PartialModel; -import dev.engine_room.flywheel.lib.transform.Transform; +import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -/** - * This is a port of the bogey api from Extended Bogeys, If you are looking to implement your own bogeys you can find some helpful resources below: - *

- * - Extended Bogeys (Examples) - * - Extended Bogeys (API documentation) - * - Steam n' Rails (Examples) - */ -public abstract class BogeyRenderer { - Map contraptionModelData = new HashMap<>(); - - /** - * A common interface for getting transform data for both in-world and in-contraption model data safely from a - * partial model - * - * @param model The key for the model data to instantiate or retrieve - * @param ms The posestack used for contraption model data - * @param inInstancedContraption The type of model needed - * @param size The amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData[] getTransform(PartialModel model, PoseStack ms, boolean inInstancedContraption, int size) { - return (inInstancedContraption) ? transformContraptionModelData(keyFromModel(model), ms) : createModelData(model, size); - } - - /** - * A common interface for getting transform data for both in-world and in-contraption model data safely from a - * blockstate - * - * @param state The key for the model data to instantiate or retrieve - * @param ms The posestack used for contraption model data - * @param inContraption The type of model needed - * @param size The amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData[] getTransform(BlockState state, PoseStack ms, boolean inContraption, int size) { - return inContraption ? transformContraptionModelData(keyFromModel(state), ms) : createModelData(state, size); - } - - /** - * Helper function to collect or create a single model from a partial model used for both in-world and - * in-contraption rendering - * - * @param model The key of the model to be collected or instantiated - * @param ms Posestack to bind the model to if it is within a contraption - * @param inInstancedContraption Type of rendering required - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData getTransform(PartialModel model, PoseStack ms, boolean inInstancedContraption) { - return inInstancedContraption ? contraptionModelData.get(keyFromModel(model))[0].setTransform(ms) - : BogeyModelData.from(model); - } - - /** - * A common interface for getting transform data for blockstates, for a single model - * - * @param state The state of the model to be collected or instantiated - * @param ms Posestack to bind the model to if it is within a contraption - * @param inContraption Type of model required - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData getTransform(BlockState state, PoseStack ms, boolean inContraption) { - return (inContraption) ? contraptionModelData.get(keyFromModel(state))[0].setTransform(ms) - : BogeyModelData.from(state); - } - - /** - * Used for calling both in-world and in-contraption rendering - * - * @param bogeyData Custom data stored on the bogey able to be used for rendering - * @param wheelAngle The angle of the wheel - * @param ms The posestack to render to - * @param light (Optional) Light used for in-world rendering - * @param vb (Optional) Vertex Consumer used for in-world rendering - */ - @OnlyIn(Dist.CLIENT) - public abstract void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, - VertexConsumer vb, boolean inContraption); - - /** - * Used for calling in-contraption rendering ensuring that falsey data is handled correctly - * - * @param bogeyData Custom data stored on the bogey able to be used for rendering - * @param wheelAngle The angle of the wheel - * @param ms The posestack to render to - */ - @OnlyIn(Dist.CLIENT) - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms) { - this.render(bogeyData, wheelAngle, ms, 0, null, true); - } - - public abstract BogeySizes.BogeySize getSize(); - - /** - * Used to collect Contraption Model Data for in-contraption rendering, should not be utilised directly when - * rendering to prevent render type mismatch - * - * @param key The key used to access the model - * @param ms Posestack of the contraption to bind the model data to - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] transformContraptionModelData(String key, PoseStack ms) { - BogeyModelData[] modelData = contraptionModelData.get(key); - Arrays.stream(modelData).forEach(modelDataElement -> modelDataElement.setTransform(ms)); - return modelData; - } - - - /** - * Used for in world rendering, creates a set count of model data to be rendered, allowing for a generic response - * when rendering multiple models both in-world and in-contraption for example, with wheels - * - * @param model The partial model of the model data ot be made - * @param size The Amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] createModelData(PartialModel model, int size) { - BogeyModelData[] data = { BogeyModelData.from(model) }; - return expandArrayToLength(data, size); - } - - /** - * Used for in world rendering, creates a set count of model data to be rendered, allowing for a generic response - * when rendering multiple models both in-world and in-contraption for example, with wheels - * - * @param state The state of the model data to be made - * @param size Amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] createModelData(BlockState state, int size) { - BogeyModelData[] data = { BogeyModelData.from(state) }; - return expandArrayToLength(data, size); - } - - /** - * Utility function to clone in-world models to a set size to allow for common handling of rendering with multiple - * instances of the same model for example with wheels - * - * @param data An in-world model to be replicated - * @param size Amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] expandArrayToLength(BogeyModelData[] data, int size) { - return Arrays.stream(Collections.nCopies(size, data).toArray()) - .flatMap(inner -> Arrays.stream((BogeyModelData[]) inner)) - .toArray(BogeyModelData[]::new); - } - - /** - * Provides render implementations a point in setup to instantiate all model data to be needed - * - * @param context The visualization context - * @param carriageBogey The bogey to create data for - */ - @OnlyIn(Dist.CLIENT) - public abstract void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey); - - /** - * Creates instances of models for in-world rendering to a set length from a provided partial model - * - * @param context The visualization context - * @param model Partial model to be instanced - * @param count Amount of models neeeded - */ - public void createModelInstance(VisualizationContext context, PartialModel model, int count) { - var instancer = context.instancerProvider() - .instancer(InstanceTypes.POSED, Models.partial(model)); - BogeyModelData[] modelData = IntStream.range(0, count) - .mapToObj(i -> instancer.createInstance()) - .map(BogeyModelData::new) - .toArray(BogeyModelData[]::new); - contraptionModelData.put(keyFromModel(model), modelData); - } - - /** - * Creates instances of models for in-contraption rendering to a set length from a provided blockstate - * - * @param context The visualization context - * @param state Blockstate of the model to be created - * @param count Amount of models needed - */ - public void createModelInstance(VisualizationContext context, BlockState state, int count) { - var instancer = context.instancerProvider() - .instancer(InstanceTypes.POSED, VirtualRenderHelper.blockModel(state)); - BogeyModelData[] modelData = IntStream.range(0, count) - .mapToObj(i -> instancer.createInstance()) - .map(BogeyModelData::new) - .toArray(BogeyModelData[]::new); - contraptionModelData.put(keyFromModel(state), modelData); - } - - /** - * Creates a single instance of models for in-contraption rendering from a provided blockstate - * - * @param context The visualization context - * @param states Blockstates of the models to be created - */ - public void createModelInstance(VisualizationContext context, BlockState... states) { - for (BlockState state : states) - this.createModelInstance(context, state, 1); - } - - /** - * Helper function to create a single model instance for in-contraption rendering - * - * @param context The visualization context - * @param models The type of model to create instances of - */ - public void createModelInstance(VisualizationContext context, PartialModel... models) { - for (PartialModel model : models) - createModelInstance(context, model, 1); - } - - /** - * This method is deprecated, use BogeyModelData#render instead, left in - * to avoid existing usages from crashing - * - * @param b The model data itself - * @param ms Pose stack to render to - * @param light light level of the scene - * @param vb Vertex Consumber to render to - * @param Generic alias for both contraption and in-world model data - */ - - @Deprecated - public static > void finalize(B b, PoseStack ms, int light, @Nullable VertexConsumer vb) { - b.scale(1 - 1/512f); - if (b instanceof SuperByteBuffer byteBuf && vb != null) - byteBuf.light(light).renderInto(ms, vb); - } - - /** - * Automatic handling for setting empty transforms for all model data - * - */ - - public void emptyTransforms() { - for (BogeyModelData[] data : contraptionModelData.values()) - for (BogeyModelData model : data) - model.setEmptyTransform(); - } - - /** - * Automatic handling for updating all model data's light - * - * @param blockLight the blocklight to be applied - * @param skyLight the skylight to be applied - */ - - public void updateLight(int blockLight, int skyLight) { - for (BogeyModelData[] data : contraptionModelData.values()) - for (BogeyModelData model : data) - model.updateLight(blockLight, skyLight); - } - - /** - * Automatic handling for clearing all model data of a contraption - * - */ - - public void remove() { - for (BogeyModelData[] data : contraptionModelData.values()) - for (BogeyModelData model : data) - model.delete(); - contraptionModelData.clear(); - } - - /** - * Create a model key from a partial model, so it can be easily accessed - * - * @param partialModel the model we want a unique key for - * @return Key of the model - */ - - private String keyFromModel(PartialModel partialModel) { - return partialModel.modelLocation().toString(); - } - - /** - * Create a model key from a blockstate, so it can be easily accessed - * - * @param state Blockstate of the model - * @return Key of the model - */ - - private String keyFromModel(BlockState state) { - return state.toString(); - } - - public static abstract class CommonRenderer extends BogeyRenderer { - @Override - public BogeySizes.BogeySize getSize() { - return null; - } - } - - public record BogeyModelData(Transform transform) implements Transform { - public static BogeyModelData from(PartialModel model) { - BlockState air = Blocks.AIR.defaultBlockState(); - return new BogeyModelData(CachedBufferer.partial(model, air)); - } - public static BogeyModelData from(BlockState model) { - return new BogeyModelData(CachedBufferer.block(model)); - } - public void render(PoseStack ms, int light, @Nullable VertexConsumer vb) { - transform.scale(1 - 1/512f); - if (transform instanceof SuperByteBuffer byteBuf && vb != null) - byteBuf.light(light).renderInto(ms, vb); - } - - public BogeyModelData setTransform(PoseStack ms) { - if (this.transform instanceof PosedInstance model) - model.setTransform(ms) - .setChanged(); - return this; - } - - public BogeyModelData setEmptyTransform() { - if (this.transform instanceof PosedInstance model) - model.setZeroTransform() - .setChanged(); - return this; - } - - public BogeyModelData delete() { - if (this.transform instanceof PosedInstance model) - model.delete(); - return this; - } - - public BogeyModelData updateLight(int blockLight, int skyLight) { - if (this.transform instanceof PosedInstance model) - model.light(blockLight, skyLight) - .setChanged(); - return this; - } - - @Override - public BogeyModelData mulPose(Matrix4fc pose) { - this.transform.mulPose(pose); - return this; - } - - @Override - public BogeyModelData mulNormal(Matrix3fc normal) { - this.transform.mulNormal(normal); - return this; - } - - @Override - public BogeyModelData rotate(Quaternionfc quaternion) { - this.transform.rotate(quaternion); - return this; - } - - @Override - public BogeyModelData scale(float factorX, float factorY, float factorZ) { - this.transform.scale(factorX, factorY, factorZ); - return this; - } - - @Override - public BogeyModelData translate(float x, float y, float z) { - this.transform.translate(x, y, z); - return this; - } - } +public interface BogeyRenderer { + void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, boolean inContraption); } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java index e9bcc2d48..879aec548 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java @@ -1,70 +1,78 @@ package com.simibubi.create.content.trains.bogey; -import java.util.Collection; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; +import java.util.HashMap; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.UnmodifiableView; import com.simibubi.create.Create; import net.minecraft.resources.ResourceLocation; -public class BogeySizes { - private static final Collection BOGEY_SIZES = new HashSet<>(); - public static final BogeySize SMALL = new BogeySize(Create.ID, "small", 6.5f / 16f); - public static final BogeySize LARGE = new BogeySize(Create.ID, "large", 12.5f / 16f); +public final class BogeySizes { + private static final Map BOGEY_SIZES = new HashMap<>(); + private static final List SORTED_INCREASING = new ArrayList<>(); + private static final List SORTED_DECREASING = new ArrayList<>(); + @UnmodifiableView + private static final Map BOGEY_SIZES_VIEW = Collections.unmodifiableMap(BOGEY_SIZES); + @UnmodifiableView + private static final List SORTED_INCREASING_VIEW = Collections.unmodifiableList(SORTED_INCREASING); + @UnmodifiableView + private static final List SORTED_DECREASING_VIEW = Collections.unmodifiableList(SORTED_DECREASING); + + public static final BogeySize SMALL = new BogeySize(Create.asResource("small"), 6.5f / 16f); + public static final BogeySize LARGE = new BogeySize(Create.asResource("large"), 12.5f / 16f); static { - BOGEY_SIZES.add(SMALL); - BOGEY_SIZES.add(LARGE); + register(SMALL); + register(LARGE); } - public static BogeySize addSize(String modId, String name, float size) { - ResourceLocation location = new ResourceLocation(modId, name); - return addSize(location, size); + private BogeySizes() { } - public static BogeySize addSize(ResourceLocation location, float size) { - BogeySize customSize = new BogeySize(location, size); - BOGEY_SIZES.add(customSize); - return customSize; - } - - public static List getAllSizesSmallToLarge() { - return BOGEY_SIZES.stream() - .sorted(Comparator.comparing(BogeySize::wheelRadius)) - .collect(Collectors.toList()); - } - - public static List getAllSizesLargeToSmall() { - List sizes = getAllSizesSmallToLarge(); - Collections.reverse(sizes); - return sizes; - } - - public static int count() { - return BOGEY_SIZES.size(); - } - - public record BogeySize(ResourceLocation location, float wheelRadius) { - public BogeySize(String modId, String name, float wheelRadius) { - this(new ResourceLocation(modId, name), wheelRadius); + public static void register(BogeySize size) { + ResourceLocation id = size.id(); + if (BOGEY_SIZES.containsKey(id)) { + throw new IllegalArgumentException(); } + BOGEY_SIZES.put(id, size); - public BogeySize increment() { - List values = getAllSizesSmallToLarge(); + SORTED_INCREASING.add(size); + SORTED_DECREASING.add(size); + SORTED_INCREASING.sort(Comparator.comparing(BogeySize::wheelRadius)); + SORTED_DECREASING.sort(Comparator.comparing(BogeySize::wheelRadius).reversed()); + } + + @UnmodifiableView + public static Map all() { + return BOGEY_SIZES_VIEW; + } + + @UnmodifiableView + public static List allSortedIncreasing() { + return SORTED_INCREASING_VIEW; + } + + @UnmodifiableView + public static List allSortedDecreasing() { + return SORTED_DECREASING_VIEW; + } + + @ApiStatus.Internal + public static void init() { + } + + public record BogeySize(ResourceLocation id, float wheelRadius) { + public BogeySize nextBySize() { + List values = allSortedIncreasing(); int ordinal = values.indexOf(this); return values.get((ordinal + 1) % values.size()); } - - public boolean is(BogeySize size) { - return size.location == this.location; - } - } - - public static void init() { - } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java index 1d7e355dc..9a375d7ee 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java @@ -2,60 +2,53 @@ package com.simibubi.create.content.trains.bogey; import java.util.HashMap; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.content.trains.bogey.BogeyRenderer.CommonRenderer; +import com.simibubi.create.content.trains.bogey.BogeySizes.BogeySize; import com.simibubi.create.content.trains.entity.CarriageBogey; +import com.simibubi.create.foundation.utility.Lang; import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.level.block.Block; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.registries.ForgeRegistries; - public class BogeyStyle { - - public final ResourceLocation name; + public final ResourceLocation id; public final ResourceLocation cycleGroup; public final Component displayName; - public final ResourceLocation soundType; + public final Supplier soundEvent; public final ParticleOptions contactParticle; public final ParticleOptions smokeParticle; public final CompoundTag defaultData; - - private Optional> commonRendererFactory; - private Map sizes; + private final Map>> sizes; @OnlyIn(Dist.CLIENT) - private Map sizeRenderers; + private Map sizeRenderers; - @OnlyIn(Dist.CLIENT) - private Optional commonRenderer; + public BogeyStyle(ResourceLocation id, ResourceLocation cycleGroup, Component displayName, + Supplier soundEvent, ParticleOptions contactParticle, ParticleOptions smokeParticle, + CompoundTag defaultData, Map>> sizes, + Map> sizeRenderers) { - public BogeyStyle(ResourceLocation name, ResourceLocation cycleGroup, Component displayName, - ResourceLocation soundType, ParticleOptions contactParticle, ParticleOptions smokeParticle, - CompoundTag defaultData, Map sizes, - Map> sizeRenderers, - Optional> commonRenderer) { - - this.name = name; + this.id = id; this.cycleGroup = cycleGroup; this.displayName = displayName; - this.soundType = soundType; + this.soundEvent = soundEvent; this.contactParticle = contactParticle; this.smokeParticle = smokeParticle; this.defaultData = defaultData; @@ -64,9 +57,6 @@ public class BogeyStyle { DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { this.sizeRenderers = new HashMap<>(); sizeRenderers.forEach((k, v) -> this.sizeRenderers.put(k, v.get())); - - this.commonRendererFactory = commonRenderer; - this.commonRenderer = commonRenderer.map(Supplier::get); }); } @@ -74,60 +64,109 @@ public class BogeyStyle { return AllBogeyStyles.getCycleGroup(cycleGroup); } - public Block getNextBlock(BogeySizes.BogeySize currentSize) { - return Stream.iterate(currentSize.increment(), BogeySizes.BogeySize::increment) - .filter(sizes::containsKey) - .findFirst() - .map(this::getBlockOfSize) - .orElse(getBlockOfSize(currentSize)); - } - - public Block getBlockOfSize(BogeySizes.BogeySize size) { - return ForgeRegistries.BLOCKS.getValue(sizes.get(size)); - } - public Set validSizes() { return sizes.keySet(); } - @NotNull - public SoundEvent getSoundType() { - AllSoundEvents.SoundEntry entry = AllSoundEvents.ALL.get(this.soundType); - if (entry == null || entry.getMainEvent() == null) entry = AllSoundEvents.TRAIN2; - return entry.getMainEvent(); + public AbstractBogeyBlock getBlockForSize(BogeySizes.BogeySize size) { + return sizes.get(size).get(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public AbstractBogeyBlock getNextBlock(BogeySizes.BogeySize currentSize) { + return Stream.iterate(currentSize.nextBySize(), BogeySizes.BogeySize::nextBySize) + .filter(sizes::containsKey) + .findFirst() + .map(this::getBlockForSize) + .orElse((AbstractBogeyBlock) getBlockForSize(currentSize)); } @OnlyIn(Dist.CLIENT) - public BogeyRenderer createRendererInstance(BogeySizes.BogeySize size) { - return this.sizeRenderers.get(size).createRenderInstance(); + public void render(BogeySize size, float partialTick, PoseStack poseStack, MultiBufferSource buffers, int light, int overlay, float wheelAngle, @Nullable CompoundTag bogeyData, boolean inContraption) { + if (bogeyData == null) + bogeyData = new CompoundTag(); + + poseStack.translate(0, -1.5 - 1 / 128f, 0); + + SizeRenderer renderer = sizeRenderers.get(size); + if (renderer != null) { + renderer.renderer.render(bogeyData, wheelAngle, partialTick, poseStack, buffers, light, overlay, inContraption); + } } @OnlyIn(Dist.CLIENT) - public BogeyRenderer getInWorldRenderInstance(BogeySizes.BogeySize size) { - SizeRenderData sizeData = this.sizeRenderers.get(size); - return sizeData != null ? sizeData.getInWorldInstance() : BackupBogeyRenderer.INSTANCE; - } - - public Optional getInWorldCommonRenderInstance() { - return this.commonRenderer; - } - - public Optional getNewCommonRenderInstance() { - return this.commonRendererFactory.map(Supplier::get); - } - - public BogeyVisual createVisual(CarriageBogey bogey, BogeySizes.BogeySize size, VisualizationContext context) { - return new BogeyVisual(bogey, this, size, context); + @Nullable + public BogeyVisual createVisual(VisualizationContext ctx, CarriageBogey bogey, float partialTick) { + SizeRenderer renderer = sizeRenderers.get(bogey.getSize()); + if (renderer != null) { + return renderer.visualizer.createVisual(ctx, bogey, partialTick); + } + return null; } @OnlyIn(Dist.CLIENT) - public record SizeRenderData(Supplier rendererFactory, BogeyRenderer instance) { - public BogeyRenderer createRenderInstance() { - return rendererFactory.get(); + public record SizeRenderer(BogeyRenderer renderer, BogeyVisualizer visualizer) { + } + + public static class Builder { + protected final ResourceLocation id; + protected final ResourceLocation cycleGroup; + protected final Map>> sizes = new HashMap<>(); + + protected Component displayName = Lang.translateDirect("bogey.style.invalid"); + protected Supplier soundEvent = AllSoundEvents.TRAIN2::getMainEvent; + protected ParticleOptions contactParticle = ParticleTypes.CRIT; + protected ParticleOptions smokeParticle = ParticleTypes.POOF; + protected CompoundTag defaultData = new CompoundTag(); + + protected final Map> sizeRenderers = new HashMap<>(); + + public Builder(ResourceLocation id, ResourceLocation cycleGroup) { + this.id = id; + this.cycleGroup = cycleGroup; } - public BogeyRenderer getInWorldInstance() { - return instance; + public Builder displayName(Component displayName) { + this.displayName = displayName; + return this; + } + + public Builder soundEvent(Supplier soundEvent) { + this.soundEvent = soundEvent; + return this; + } + + public Builder contactParticle(ParticleOptions contactParticle) { + this.contactParticle = contactParticle; + return this; + } + + public Builder smokeParticle(ParticleOptions smokeParticle) { + this.smokeParticle = smokeParticle; + return this; + } + + public Builder defaultData(CompoundTag defaultData) { + this.defaultData = defaultData; + return this; + } + + public Builder size(BogeySizes.BogeySize size, Supplier> block, + Supplier renderer) { + this.sizes.put(size, block); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { + this.sizeRenderers.put(size, renderer); + }); + return this; + } + + public BogeyStyle build() { + BogeyStyle entry = new BogeyStyle(id, cycleGroup, displayName, soundEvent, contactParticle, smokeParticle, + defaultData, sizes, sizeRenderers); + AllBogeyStyles.BOGEY_STYLES.put(id, entry); + AllBogeyStyles.CYCLE_GROUPS.computeIfAbsent(cycleGroup, l -> new HashMap<>()) + .put(id, entry); + return entry; } } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java index 9849caada..2b0eb6897 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java @@ -1,65 +1,13 @@ package com.simibubi.create.content.trains.bogey; -import java.util.Optional; - import com.mojang.blaze3d.vertex.PoseStack; -import com.simibubi.create.content.trains.entity.CarriageBogey; -import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; -import com.simibubi.create.foundation.utility.AnimationTickHolder; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.phys.Vec3; +public interface BogeyVisual { + void update(float wheelAngle, PoseStack poseStack); -public final class BogeyVisual { - private final BogeySizes.BogeySize size; - private final BogeyStyle style; + void hide(); - public final CarriageBogey bogey; - public final BogeyRenderer renderer; - public final Optional commonRenderer; + void updateLight(int packedLight); - public BogeyVisual(CarriageBogey bogey, BogeyStyle style, BogeySizes.BogeySize size, - VisualizationContext context) { - this.bogey = bogey; - this.size = size; - this.style = style; - - this.renderer = this.style.createRendererInstance(this.size); - this.commonRenderer = this.style.getNewCommonRenderInstance(); - - commonRenderer.ifPresent(bogeyRenderer -> bogeyRenderer.initialiseContraptionModelData(context, bogey)); - renderer.initialiseContraptionModelData(context, bogey); - } - - public void beginFrame(float wheelAngle, PoseStack ms) { - if (ms == null) { - renderer.emptyTransforms(); - return; - } - - commonRenderer.ifPresent(bogeyRenderer -> bogeyRenderer.render(bogey.bogeyData, wheelAngle, ms)); - renderer.render(bogey.bogeyData, wheelAngle, ms); - } - - public void updateLight(BlockAndTintGetter world, CarriageContraptionEntity entity) { - var lightPos = BlockPos.containing(getLightPos(entity)); - commonRenderer - .ifPresent(bogeyRenderer -> bogeyRenderer.updateLight(world.getBrightness(LightLayer.BLOCK, lightPos), - world.getBrightness(LightLayer.SKY, lightPos))); - renderer.updateLight(world.getBrightness(LightLayer.BLOCK, lightPos), - world.getBrightness(LightLayer.SKY, lightPos)); - } - - private Vec3 getLightPos(CarriageContraptionEntity entity) { - return bogey.getAnchorPosition() != null ? bogey.getAnchorPosition() - : entity.getLightProbePosition(AnimationTickHolder.getPartialTicks()); - } - - @FunctionalInterface - interface BogeyVisualFactory { - BogeyVisual create(CarriageBogey bogey, BogeySizes.BogeySize size, VisualizationContext context); - } + void delete(); } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisualizer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisualizer.java new file mode 100644 index 000000000..38acb77d4 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisualizer.java @@ -0,0 +1,10 @@ +package com.simibubi.create.content.trains.bogey; + +import com.simibubi.create.content.trains.entity.CarriageBogey; + +import dev.engine_room.flywheel.api.visualization.VisualizationContext; + +@FunctionalInterface +public interface BogeyVisualizer { + BogeyVisual createVisual(VisualizationContext ctx, CarriageBogey bogey, float partialTick); +} diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java index d7e3e835d..ec1cabbac 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java @@ -1,134 +1,109 @@ package com.simibubi.create.content.trains.bogey; -import static com.simibubi.create.AllPartialModels.BOGEY_DRIVE; -import static com.simibubi.create.AllPartialModels.BOGEY_FRAME; -import static com.simibubi.create.AllPartialModels.BOGEY_PIN; -import static com.simibubi.create.AllPartialModels.BOGEY_PISTON; -import static com.simibubi.create.AllPartialModels.LARGE_BOGEY_WHEELS; -import static com.simibubi.create.AllPartialModels.SMALL_BOGEY_WHEELS; - import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllPartialModels; import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock; -import com.simibubi.create.content.trains.entity.CarriageBogey; +import com.simibubi.create.foundation.render.CachedBufferer; +import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.Blocks; -public class StandardBogeyRenderer { - public static class CommonStandardBogeyRenderer extends BogeyRenderer.CommonRenderer { - @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - createModelInstance(context, AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.Z), 2); - } +public class StandardBogeyRenderer implements BogeyRenderer { + @Override + public void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int light, int overlay, boolean inContraption) { + VertexConsumer buffer = bufferSource.getBuffer(RenderType.cutoutMipped()); - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - boolean inInstancedContraption = vb == null; - BogeyModelData[] shafts = getTransform(AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.Z), ms, inInstancedContraption, 2); - for (int i : Iterate.zeroAndOne) { - shafts[i].translate(-.5f, .25f, i * -1) - .center() - .rotateZDegrees(wheelAngle) - .uncenter() - .render(ms, light, vb); - } + SuperByteBuffer shaft = CachedBufferer.block(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.Z)); + for (int i : Iterate.zeroAndOne) { + shaft.translate(-.5f, .25f, i * -1) + .center() + .rotateZDegrees(wheelAngle) + .uncenter() + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } } - - public static class SmallStandardBogeyRenderer extends BogeyRenderer { + public static class Small extends StandardBogeyRenderer { @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - createModelInstance(context, SMALL_BOGEY_WHEELS, 2); - createModelInstance(context, BOGEY_FRAME); - } + public void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int light, int overlay, boolean inContraption) { + super.render(bogeyData, wheelAngle, partialTick, poseStack, bufferSource, light, overlay, inContraption); + VertexConsumer buffer = bufferSource.getBuffer(RenderType.cutoutMipped()); - @Override - public BogeySizes.BogeySize getSize() { - return BogeySizes.SMALL; - } + CachedBufferer.partial(AllPartialModels.BOGEY_FRAME, Blocks.AIR.defaultBlockState()) + .scale(1 - 1 / 512f) + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - boolean inInstancedContraption = vb == null; - getTransform(BOGEY_FRAME, ms, inInstancedContraption) - .render(ms, light, vb); - - BogeyModelData[] wheels = getTransform(SMALL_BOGEY_WHEELS, ms, inInstancedContraption, 2); + SuperByteBuffer wheels = CachedBufferer.partial(AllPartialModels.SMALL_BOGEY_WHEELS, Blocks.AIR.defaultBlockState()); for (int side : Iterate.positiveAndNegative) { - if (!inInstancedContraption) - ms.pushPose(); - wheels[(side + 1)/2] - .translate(0, 12 / 16f, side) + wheels.translate(0, 12 / 16f, side) .rotateXDegrees(wheelAngle) - .render(ms, light, vb); - if (!inInstancedContraption) - ms.popPose(); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } } } - public static class LargeStandardBogeyRenderer extends BogeyRenderer { + public static class Large extends StandardBogeyRenderer { @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - createModelInstance(context, LARGE_BOGEY_WHEELS, BOGEY_DRIVE, BOGEY_PISTON, BOGEY_PIN); - createModelInstance(context, AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.X), 2); - } + public void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int light, int overlay, boolean inContraption) { + super.render(bogeyData, wheelAngle, partialTick, poseStack, bufferSource, light, overlay, inContraption); - @Override - public BogeySizes.BogeySize getSize() { - return BogeySizes.LARGE; - } - - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - boolean inInstancedContraption = vb == null; - - BogeyModelData[] secondaryShafts = getTransform(AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.X), ms, inInstancedContraption, 2); + VertexConsumer buffer = bufferSource.getBuffer(RenderType.cutoutMipped()); + SuperByteBuffer secondaryShaft = CachedBufferer.block(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.X)); for (int i : Iterate.zeroAndOne) { - secondaryShafts[i] - .translate(-.5f, .25f, .5f + i * -2) + secondaryShaft.translate(-.5f, .25f, .5f + i * -2) .center() .rotateXDegrees(wheelAngle) .uncenter() - .render(ms, light, vb); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } - getTransform(BOGEY_DRIVE, ms, inInstancedContraption) - .render(ms, light, vb); + CachedBufferer.partial(AllPartialModels.BOGEY_DRIVE, Blocks.AIR.defaultBlockState()) + .scale(1 - 1 / 512f) + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - getTransform(BOGEY_PISTON, ms, inInstancedContraption) + CachedBufferer.partial(AllPartialModels.BOGEY_PISTON, Blocks.AIR.defaultBlockState()) .translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle))) - .render(ms, light, vb); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - if (!inInstancedContraption) - ms.pushPose(); - - getTransform(LARGE_BOGEY_WHEELS, ms, inInstancedContraption) + CachedBufferer.partial(AllPartialModels.LARGE_BOGEY_WHEELS, Blocks.AIR.defaultBlockState()) .translate(0, 1, 0) .rotateXDegrees(wheelAngle) - .render(ms, light, vb); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - getTransform(BOGEY_PIN, ms, inInstancedContraption) + CachedBufferer.partial(AllPartialModels.BOGEY_PIN, Blocks.AIR.defaultBlockState()) .translate(0, 1, 0) .rotateXDegrees(wheelAngle) .translate(0, 1 / 4f, 0) .rotateXDegrees(-wheelAngle) - .render(ms, light, vb); - - if (!inInstancedContraption) - ms.popPose(); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyVisual.java b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyVisual.java new file mode 100644 index 000000000..feec031b8 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyVisual.java @@ -0,0 +1,215 @@ +package com.simibubi.create.content.trains.bogey; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllPartialModels; +import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock; +import com.simibubi.create.content.trains.entity.CarriageBogey; +import com.simibubi.create.foundation.render.VirtualRenderHelper; +import com.simibubi.create.foundation.utility.AngleHelper; + +import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import dev.engine_room.flywheel.lib.instance.InstanceTypes; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; +import dev.engine_room.flywheel.lib.model.Models; +import net.minecraft.core.Direction; + +public class StandardBogeyVisual implements BogeyVisual { + private final TransformedInstance shaft1; + private final TransformedInstance shaft2; + + public StandardBogeyVisual(VisualizationContext ctx, CarriageBogey bogey, float partialTick) { + var shaftInstancer = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.Z))); + shaft1 = shaftInstancer.createInstance(); + shaft2 = shaftInstancer.createInstance(); + } + + @Override + public void update(float wheelAngle, PoseStack poseStack) { + shaft1.setTransform(poseStack) + .translate(-.5f, .25f, 0) + .center() + .rotateZDegrees(wheelAngle) + .uncenter() + .setChanged(); + shaft2.setTransform(poseStack) + .translate(-.5f, .25f, -1) + .center() + .rotateZDegrees(wheelAngle) + .uncenter() + .setChanged(); + } + + @Override + public void hide() { + shaft1.setZeroTransform().setChanged(); + shaft2.setZeroTransform().setChanged(); + } + + @Override + public void updateLight(int packedLight) { + shaft1.light(packedLight).setChanged(); + shaft2.light(packedLight).setChanged(); + } + + @Override + public void delete() { + shaft1.delete(); + shaft2.delete(); + } + + public static class Small extends StandardBogeyVisual { + private final TransformedInstance frame; + private final TransformedInstance wheel1; + private final TransformedInstance wheel2; + + public Small(VisualizationContext ctx, CarriageBogey bogey, float partialTick) { + super(ctx, bogey, partialTick); + var wheelInstancer = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.SMALL_BOGEY_WHEELS)); + frame = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_FRAME)) + .createInstance(); + wheel1 = wheelInstancer.createInstance(); + wheel2 = wheelInstancer.createInstance(); + } + + @Override + public void update(float wheelAngle, PoseStack poseStack) { + super.update(wheelAngle, poseStack); + wheel1.setTransform(poseStack) + .translate(0, 12 / 16f, -1) + .rotateXDegrees(wheelAngle) + .setChanged(); + wheel2.setTransform(poseStack) + .translate(0, 12 / 16f, 1) + .rotateXDegrees(wheelAngle) + .setChanged(); + frame.setTransform(poseStack) + .scale(1 - 1 / 512f) + .setChanged(); + } + + @Override + public void hide() { + super.hide(); + frame.setZeroTransform().setChanged(); + wheel1.setZeroTransform().setChanged(); + wheel2.setZeroTransform().setChanged(); + } + + @Override + public void updateLight(int packedLight) { + super.updateLight(packedLight); + frame.light(packedLight).setChanged(); + wheel1.light(packedLight).setChanged(); + wheel2.light(packedLight).setChanged(); + } + + @Override + public void delete() { + super.delete(); + frame.delete(); + wheel1.delete(); + wheel2.delete(); + } + } + + public static class Large extends StandardBogeyVisual { + private final TransformedInstance secondaryShaft1; + private final TransformedInstance secondaryShaft2; + private final TransformedInstance drive; + private final TransformedInstance piston; + private final TransformedInstance wheels; + private final TransformedInstance pin; + + public Large(VisualizationContext ctx, CarriageBogey bogey, float partialTick) { + super(ctx, bogey, partialTick); + var secondaryShaftInstancer = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.X))); + secondaryShaft1 = secondaryShaftInstancer.createInstance(); + secondaryShaft2 = secondaryShaftInstancer.createInstance(); + drive = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_DRIVE)) + .createInstance(); + piston = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_PISTON)) + .createInstance(); + wheels = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.LARGE_BOGEY_WHEELS)) + .createInstance(); + pin = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_PIN)) + .createInstance(); + } + + @Override + public void update(float wheelAngle, PoseStack poseStack) { + super.update(wheelAngle, poseStack); + secondaryShaft1.setTransform(poseStack) + .translate(-.5f, .25f, .5f) + .center() + .rotateXDegrees(wheelAngle) + .uncenter() + .setChanged(); + secondaryShaft2.setTransform(poseStack) + .translate(-.5f, .25f, -1.5f) + .center() + .rotateXDegrees(wheelAngle) + .uncenter() + .setChanged(); + drive.setTransform(poseStack) + .scale(1 - 1/512f) + .setChanged(); + piston.setTransform(poseStack) + .translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle))) + .setChanged(); + wheels.setTransform(poseStack) + .translate(0, 1, 0) + .rotateXDegrees(wheelAngle) + .setChanged(); + pin.setTransform(poseStack) + .translate(0, 1, 0) + .rotateXDegrees(wheelAngle) + .translate(0, 1 / 4f, 0) + .rotateXDegrees(-wheelAngle) + .setChanged(); + } + + @Override + public void hide() { + super.hide(); + secondaryShaft1.setZeroTransform().setChanged(); + secondaryShaft2.setZeroTransform().setChanged(); + wheels.setZeroTransform().setChanged(); + drive.setZeroTransform().setChanged(); + piston.setZeroTransform().setChanged(); + pin.setZeroTransform().setChanged(); + } + + @Override + public void updateLight(int packedLight) { + super.updateLight(packedLight); + secondaryShaft1.light(packedLight).setChanged(); + secondaryShaft2.light(packedLight).setChanged(); + wheels.light(packedLight).setChanged(); + drive.light(packedLight).setChanged(); + piston.light(packedLight).setChanged(); + pin.light(packedLight).setChanged(); + } + + @Override + public void delete() { + super.delete(); + secondaryShaft1.delete(); + secondaryShaft2.delete(); + wheels.delete(); + drive.delete(); + piston.delete(); + pin.delete(); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java index 0f776c3db..937f238e5 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java @@ -9,8 +9,8 @@ import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.Create; import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock; import com.simibubi.create.content.trains.bogey.AbstractBogeyBlockEntity; +import com.simibubi.create.content.trains.bogey.BogeySizes.BogeySize; import com.simibubi.create.content.trains.bogey.BogeyStyle; -import com.simibubi.create.content.trains.bogey.BogeyVisual; import com.simibubi.create.content.trains.graph.DimensionPalette; import com.simibubi.create.content.trains.graph.TrackGraph; import com.simibubi.create.foundation.utility.AngleHelper; @@ -21,7 +21,6 @@ import com.simibubi.create.foundation.utility.RegisteredObjects; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.animation.LerpedFloat; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; import net.minecraft.core.Direction.Axis; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; @@ -184,7 +183,7 @@ public class CarriageBogey { tag.put("Points", points.serializeEach(tp -> tp.write(dimensions))); tag.putBoolean("UpsideDown", upsideDown); bogeyData.putBoolean(UPSIDE_DOWN_KEY, upsideDown); - NBTHelper.writeResourceLocation(bogeyData, BOGEY_STYLE_KEY, getStyle().name); + NBTHelper.writeResourceLocation(bogeyData, BOGEY_STYLE_KEY, getStyle().id); tag.put(BOGEY_DATA_KEY, bogeyData); return tag; } @@ -199,20 +198,20 @@ public class CarriageBogey { return new CarriageBogey(type, upsideDown, data, points.getFirst(), points.getSecond()); } - public BogeyVisual createVisual(VisualizationContext context) { - return this.getStyle().createVisual(this, type.getSize(), context); - } - public BogeyStyle getStyle() { ResourceLocation location = NBTHelper.readResourceLocation(this.bogeyData, BOGEY_STYLE_KEY); BogeyStyle style = AllBogeyStyles.BOGEY_STYLES.get(location); return style != null ? style : AllBogeyStyles.STANDARD; // just for safety } + public BogeySize getSize() { + return type.getSize(); + } + private CompoundTag createBogeyData() { BogeyStyle style = type != null ? type.getDefaultStyle() : AllBogeyStyles.STANDARD; CompoundTag nbt = style.defaultData != null ? style.defaultData : new CompoundTag(); - NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, style.name); + NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, style.id); nbt.putBoolean(UPSIDE_DOWN_KEY, isUpsideDown()); return nbt; } diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java index abfd3a669..c7c717a44 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java @@ -736,6 +736,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { dimensional.updateRenderedCutoff(); } + // FIXME: entities should not reference their visual in any way @OnlyIn(Dist.CLIENT) private WeakReference instanceHolder; diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java index 7d2d99e7a..0d802900e 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java @@ -66,8 +66,8 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer int light = getBogeyLightCoords(entity, bogey, partialTicks); - bogey.type.render(null, bogey.wheelAngle.getValue(partialTicks), ms, partialTicks, buffers, light, - overlay, bogey.getStyle(), bogey.bogeyData); + bogey.getStyle().render(bogey.getSize(), partialTicks, ms, buffers, light, + overlay, bogey.wheelAngle.getValue(partialTicks), bogey.bogeyData, true); ms.popPose(); } @@ -75,7 +75,6 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, bogey.isLeading); if (!carriage.isOnTwoBogeys()) bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, !bogey.isLeading); - }); } @@ -99,7 +98,6 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer } public static int getBogeyLightCoords(CarriageContraptionEntity entity, CarriageBogey bogey, float partialTicks) { - var lightPos = BlockPos.containing( Objects.requireNonNullElseGet(bogey.getAnchorPosition(), () -> entity.getLightProbePosition(partialTicks))); diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java index 376a99969..7fadc8e62 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java @@ -1,10 +1,10 @@ package com.simibubi.create.content.trains.entity; +import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.content.contraptions.render.ContraptionVisual; -import com.simibubi.create.content.trains.bogey.BogeyRenderer; import com.simibubi.create.content.trains.bogey.BogeyVisual; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; @@ -14,16 +14,16 @@ import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.transform.TransformStack; public class CarriageContraptionVisual extends ContraptionVisual { - private final PoseStack ms = new PoseStack(); + @Nullable private Carriage carriage; - private Couple bogeys; - private Couple bogeyHidden; + @Nullable + private Couple<@Nullable VisualizedBogey> bogeys; + private Couple bogeyHidden = Couple.create(() -> false); public CarriageContraptionVisual(VisualizationContext context, CarriageContraptionEntity entity, float partialTick) { super(context, entity, partialTick); - bogeyHidden = Couple.create(() -> false); entity.bindInstance(this); } @@ -31,13 +31,12 @@ public class CarriageContraptionVisual extends ContraptionVisual bogey.getStyle() - .createVisual(bogey, bogey.type.getSize(), manager), visualizationContext); - } + if (carriage != null) { + bogeys = carriage.bogeys.mapNotNull(bogey -> VisualizedBogey.of(visualizationContext, bogey, pt)); + } super.init(pt); - } + } public void setBogeyVisibility(boolean first, boolean visible) { bogeyHidden.set(first, !visible); @@ -62,26 +61,27 @@ public class CarriageContraptionVisual extends ContraptionVisual { - if (instance != null) - instance.updateLight(level, entity); + bogeys.forEach(bogey -> { + if (bogey != null) { + int packedLight = CarriageContraptionEntityRenderer.getBogeyLightCoords(entity, bogey.bogey, partialTick); + bogey.visual.updateLight(packedLight); + } }); } @@ -108,11 +110,21 @@ public class CarriageContraptionVisual extends ContraptionVisual { - if (instance != null) { - instance.commonRenderer.ifPresent(BogeyRenderer::remove); - instance.renderer.remove(); + bogeys.forEach(bogey -> { + if (bogey != null) { + bogey.visual.delete(); } }); } + + private record VisualizedBogey(CarriageBogey bogey, BogeyVisual visual) { + @Nullable + static VisualizedBogey of(VisualizationContext ctx, CarriageBogey bogey, float partialTick) { + BogeyVisual visual = bogey.getStyle().createVisual(ctx, bogey, partialTick); + if (visual == null) { + return null; + } + return new VisualizedBogey(bogey, visual); + } + } } diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java index f327b2cef..de30b39d7 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java @@ -42,7 +42,7 @@ public class CarriageSounds { public CarriageSounds(CarriageContraptionEntity entity) { this.entity = entity; bogeySounds = entity.getCarriage().bogeys.map(bogey -> - bogey != null && bogey.getStyle() != null ? bogey.getStyle().getSoundType() + bogey != null && bogey.getStyle() != null ? bogey.getStyle().soundEvent.get() : AllSoundEvents.TRAIN2.getMainEvent()); closestBogeySound = bogeySounds.getFirst(); distanceFactor = LerpedFloat.linear(); @@ -94,7 +94,7 @@ public class CarriageSounds { relevantBogey = bogeys.getFirst(); } if (relevantBogey != null) { - closestBogeySound = relevantBogey.getStyle().getSoundType(); + closestBogeySound = relevantBogey.getStyle().soundEvent.get(); } Vec3 toCarriage = distance1 > distance2 ? toBogey2 : toBogey1; diff --git a/src/main/java/com/simibubi/create/foundation/utility/Couple.java b/src/main/java/com/simibubi/create/foundation/utility/Couple.java index 608ab696c..4af598c24 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/Couple.java +++ b/src/main/java/com/simibubi/create/foundation/utility/Couple.java @@ -55,6 +55,10 @@ public class Couple extends Pair implements Iterable { return Couple.create(function.apply(first), function.apply(second)); } + public Couple mapNotNull(Function function) { + return Couple.create(first != null ? function.apply(first) : null, second != null ? function.apply(second) : null); + } + public Couple mapWithContext(BiFunction function) { return Couple.create(function.apply(first, true), function.apply(second, false)); }