From eb74505ce86061e252ee01067b511128ccb28ec4 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Wed, 16 Mar 2022 19:03:10 -0700 Subject: [PATCH] Instanced bogeys --- .../com/simibubi/create/AllEntityTypes.java | 19 +- .../render/ContraptionGroup.java | 2 +- .../content/logistics/trains/IBogeyBlock.java | 6 + .../trains/entity/BogeyInstance.java | 183 ++++++++++++++++++ .../logistics/trains/entity/Carriage.java | 1 + .../trains/entity/CarriageBogey.java | 12 +- .../CarriageContraptionEntityRenderer.java | 13 +- .../entity/CarriageContraptionInstance.java | 101 ++++++++++ .../trains/track/StandardBogeyBlock.java | 57 ++++-- .../foundation/data/CreateEntityBuilder.java | 2 +- .../create/foundation/utility/Couple.java | 9 +- 11 files changed, 368 insertions(+), 37 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionInstance.java diff --git a/src/main/java/com/simibubi/create/AllEntityTypes.java b/src/main/java/com/simibubi/create/AllEntityTypes.java index 05c266307..195d6e554 100644 --- a/src/main/java/com/simibubi/create/AllEntityTypes.java +++ b/src/main/java/com/simibubi/create/AllEntityTypes.java @@ -16,8 +16,10 @@ import com.simibubi.create.content.curiosities.weapons.PotatoProjectileEntity; import com.simibubi.create.content.curiosities.weapons.PotatoProjectileRenderer; import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntityRenderer; +import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionInstance; import com.simibubi.create.foundation.data.CreateEntityBuilder; import com.simibubi.create.foundation.utility.Lang; +import com.tterrag.registrate.builders.EntityBuilder; import com.tterrag.registrate.util.entry.EntityEntry; import com.tterrag.registrate.util.nullness.NonNullConsumer; import com.tterrag.registrate.util.nullness.NonNullFunction; @@ -33,15 +35,20 @@ import net.minecraft.world.entity.MobCategory; public class AllEntityTypes { public static final EntityEntry ORIENTED_CONTRAPTION = contraption("contraption", - OrientedContraptionEntity::new, () -> OrientedContraptionEntityRenderer::new, 5, 3, true); + OrientedContraptionEntity::new, () -> OrientedContraptionEntityRenderer::new, 5, 3, true) + .register(); public static final EntityEntry CONTROLLED_CONTRAPTION = contraption("stationary_contraption", ControlledContraptionEntity::new, () -> ContraptionEntityRenderer::new, - 20, 40, false); + 20, 40, false) + .register(); public static final EntityEntry GANTRY_CONTRAPTION = contraption("gantry_contraption", - GantryContraptionEntity::new, () -> ContraptionEntityRenderer::new, 10, 40, false); + GantryContraptionEntity::new, () -> ContraptionEntityRenderer::new, 10, 40, false) + .register(); public static final EntityEntry CARRIAGE_CONTRAPTION = contraption("carriage_contraption", CarriageContraptionEntity::new, - () -> CarriageContraptionEntityRenderer::new, 15, 3, true); + () -> CarriageContraptionEntityRenderer::new, 15, 3, true) + .instance(() -> CarriageContraptionInstance::new) + .register(); public static final EntityEntry SUPER_GLUE = register("super_glue", SuperGlueEntity::new, () -> SuperGlueRenderer::new, MobCategory.MISC, 10, @@ -61,11 +68,11 @@ public class AllEntityTypes { // - private static EntityEntry contraption(String name, EntityFactory factory, + private static CreateEntityBuilder contraption(String name, EntityFactory factory, NonNullSupplier>> renderer, int range, int updateFrequency, boolean sendVelocity) { return register(name, factory, renderer, MobCategory.MISC, range, updateFrequency, sendVelocity, true, - AbstractContraptionEntity::build).register(); + AbstractContraptionEntity::build); } private static CreateEntityBuilder register(String name, EntityFactory factory, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionGroup.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionGroup.java index c52a7d882..a51193ecd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionGroup.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionGroup.java @@ -16,7 +16,7 @@ public class ContraptionGroup

extends InstancedMat } @Override - public void setup(P program) { + protected void setup(P program) { contraption.setup(program); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/IBogeyBlock.java b/src/main/java/com/simibubi/create/content/logistics/trains/IBogeyBlock.java index 5663162dc..4959593c9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/IBogeyBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/IBogeyBlock.java @@ -6,8 +6,11 @@ import java.util.List; import javax.annotation.Nullable; +import com.jozufozu.flywheel.api.MaterialManager; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.content.contraptions.wrench.IWrenchable; +import com.simibubi.create.content.logistics.trains.entity.BogeyInstance; +import com.simibubi.create.content.logistics.trains.entity.CarriageBogey; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.BlockPos; @@ -43,6 +46,9 @@ public interface IBogeyBlock extends IWrenchable { public void render(@Nullable BlockState state, float wheelAngle, PoseStack ms, float partialTicks, MultiBufferSource buffers, int light, int overlay); + @OnlyIn(Dist.CLIENT) + public BogeyInstance createInstance(MaterialManager materialManager, CarriageBogey bogey); + public default Direction getBogeyUpDirection() { return Direction.UP; } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java new file mode 100644 index 000000000..92ff2c913 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java @@ -0,0 +1,183 @@ +package com.simibubi.create.content.logistics.trains.entity; + +import com.jozufozu.flywheel.api.Material; +import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.materials.model.ModelData; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; +import com.simibubi.create.foundation.render.CachedBufferer; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.Iterate; + +import net.minecraft.core.Direction; + +public sealed class BogeyInstance { + + public final CarriageBogey bogey; + private final ModelData[] shafts; + + protected BogeyInstance(CarriageBogey bogey, MaterialManager materialManager) { + this.bogey = bogey; + + shafts = new ModelData[2]; + + materialManager.defaultSolid() + .material(Materials.TRANSFORMED) + .getModel(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.Z)) + .createInstances(shafts); + + } + + public void remove() { + for (ModelData shaft : shafts) + shaft.delete(); + } + + public void beginFrame(float wheelAngle, PoseStack ms) { + + for (int i : Iterate.zeroAndOne) + shafts[i].setTransform(ms) + .translate(-.5f, .25f, i * -1) + .centre() + .rotateZ(wheelAngle) + .unCentre(); + } + + public void updateLight(int blockLight, int skyLight) { + for (ModelData shaft : shafts) { + shaft.setBlockLight(blockLight).setSkyLight(skyLight); + } + } + + public static final class Frame extends BogeyInstance { + + private final ModelData frame; + private final ModelData[] wheels; + + public Frame(CarriageBogey bogey, MaterialManager materialManager) { + super(bogey, materialManager); + + frame = materialManager.defaultSolid() + .material(Materials.TRANSFORMED) + .getModel(AllBlockPartials.BOGEY_FRAME) + .createInstance(); + + wheels = new ModelData[2]; + + materialManager.defaultSolid() + .material(Materials.TRANSFORMED) + .getModel(AllBlockPartials.SMALL_BOGEY_WHEELS) + .createInstances(wheels); + } + + @Override + public void beginFrame(float wheelAngle, PoseStack ms) { + super.beginFrame(wheelAngle, ms); + + frame.setTransform(ms); + + for (int side : Iterate.positiveAndNegative) { + wheels[(side + 1) / 2].setTransform(ms) + .translate(0, 12 / 16f, side) + .rotateX(wheelAngle); + } + } + + @Override + public void updateLight(int blockLight, int skyLight) { + super.updateLight(blockLight, skyLight); + frame.setBlockLight(blockLight).setSkyLight(skyLight); + for (ModelData wheel : wheels) + wheel.setBlockLight(blockLight).setSkyLight(skyLight); + } + + @Override + public void remove() { + super.remove(); + frame.delete(); + for (ModelData wheel : wheels) + wheel.delete(); + } + } + + public static final class Drive extends BogeyInstance { + + private final ModelData[] secondShaft; + private final ModelData drive; + private final ModelData piston; + private final ModelData wheels; + private final ModelData pin; + + public Drive(CarriageBogey bogey, MaterialManager materialManager) { + super(bogey, materialManager); + Material mat = materialManager.defaultSolid() + .material(Materials.TRANSFORMED); + + secondShaft = new ModelData[2]; + + mat.getModel(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.X)) + .createInstances(secondShaft); + + drive = mat.getModel(AllBlockPartials.BOGEY_DRIVE) + .createInstance(); + piston = mat.getModel(AllBlockPartials.BOGEY_PISTON) + .createInstance(); + wheels = mat.getModel(AllBlockPartials.LARGE_BOGEY_WHEELS) + .createInstance(); + pin = mat.getModel(AllBlockPartials.BOGEY_PIN) + .createInstance(); + } + + @Override + public void beginFrame(float wheelAngle, PoseStack ms) { + super.beginFrame(wheelAngle, ms); + + for (int i : Iterate.zeroAndOne) + secondShaft[i].setTransform(ms) + .translate(-.5f, .25f, .5f + i * -2) + .centre() + .rotateX(wheelAngle) + .unCentre(); + + drive.setTransform(ms); + piston.setTransform(ms) + .translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle))); + + wheels.setTransform(ms) + .translate(0, 1, 0) + .rotateX(wheelAngle); + pin.setTransform(ms) + .translate(0, 1, 0) + .rotateX(wheelAngle) + .translate(0, 1 / 4f, 0) + .rotateX(-wheelAngle); + } + + @Override + public void updateLight(int blockLight, int skyLight) { + super.updateLight(blockLight, skyLight); + for (ModelData shaft : secondShaft) + shaft.setBlockLight(blockLight).setSkyLight(skyLight); + drive.setBlockLight(blockLight).setSkyLight(skyLight); + piston.setBlockLight(blockLight).setSkyLight(skyLight); + wheels.setBlockLight(blockLight).setSkyLight(skyLight); + pin.setBlockLight(blockLight).setSkyLight(skyLight); + } + + @Override + public void remove() { + super.remove(); + for (ModelData shaft : secondShaft) + shaft.delete(); + drive.delete(); + piston.delete(); + wheels.delete(); + pin.delete(); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java index 7249026b0..128041bb5 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java @@ -63,6 +63,7 @@ public class Carriage { updateContraptionAnchors(); + bogey1.setLeading(); bogey1.carriage = this; if (bogey2 != null) bogey2.carriage = this; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java index 10b5ab3f1..dd1285718 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.logistics.trains.entity; import javax.annotation.Nullable; +import com.jozufozu.flywheel.api.MaterialManager; import com.simibubi.create.Create; import com.simibubi.create.content.logistics.trains.IBogeyBlock; import com.simibubi.create.content.logistics.trains.TrackGraph; @@ -24,6 +25,8 @@ public class CarriageBogey { public Carriage carriage; + boolean isLeading; + IBogeyBlock type; Couple points; @@ -133,4 +136,11 @@ public class CarriageBogey { return carriageBogey; } -} \ No newline at end of file + public BogeyInstance createInstance(MaterialManager materialManager) { + return type.createInstance(materialManager, this); + } + + void setLeading() { + isLeading = true; + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java index 2c6d81801..b8dd14784 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.logistics.trains.entity; +import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntityRenderer; @@ -33,6 +34,8 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer MultiBufferSource buffers, int overlay) { super.render(entity, yaw, partialTicks, ms, buffers, overlay); + if (Backend.isOn()) return; + Carriage carriage = entity.getCarriage(); if (carriage == null) return; @@ -40,8 +43,8 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer Vec3 position = entity.getPosition(partialTicks); ms.pushPose(); - carriage.bogeys.forEachWithContext((bogey, first) -> { - if (!first && !carriage.isOnTwoBogeys()) + carriage.bogeys.forEach(bogey -> { + if (bogey == null) return; ms.pushPose(); @@ -52,7 +55,7 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer .rotateY(viewYRot + 90) .rotateX(-viewXRot) .rotateY(180) - .translate(0, 0, first ? 0 : -bogeySpacing) + .translate(0, 0, bogey.isLeading ? 0 : -bogeySpacing) .rotateY(-180) .rotateX(viewXRot) .rotateY(-viewYRot - 90) @@ -62,9 +65,9 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer bogey.type.render(null, bogey.wheelAngle.getValue(partialTicks), ms, partialTicks, buffers, getPackedLightCoords(entity, partialTicks), overlay); - bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, first); + bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, bogey.isLeading); if (!carriage.isOnTwoBogeys()) - bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, !first); + bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, !bogey.isLeading); ms.popPose(); }); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionInstance.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionInstance.java new file mode 100644 index 000000000..7f47c8280 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionInstance.java @@ -0,0 +1,101 @@ +package com.simibubi.create.content.logistics.trains.entity; + +import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; +import com.jozufozu.flywheel.util.AnimationTickHolder; +import com.jozufozu.flywheel.util.transform.TransformStack; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.utility.Couple; + +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LightLayer; +import net.minecraft.world.phys.Vec3; + +public class CarriageContraptionInstance extends EntityInstance implements DynamicInstance { + + private final PoseStack ms = new PoseStack(); + + private Carriage carriage; + private Couple bogeys; + + public CarriageContraptionInstance(MaterialManager materialManager, CarriageContraptionEntity entity) { + super(materialManager, entity); + } + + @Override + public void init() { + carriage = entity.getCarriage(); + + if (carriage == null) return; + + bogeys = carriage.bogeys.mapNotNullWithParam(CarriageBogey::createInstance, materialManager); + updateLight(); + } + + @Override + public void beginFrame() { + if (bogeys == null) { + init(); + return; + } + + float partialTicks = AnimationTickHolder.getPartialTicks(); + + float viewYRot = entity.getViewYRot(partialTicks); + float viewXRot = entity.getViewXRot(partialTicks); + int bogeySpacing = carriage.bogeySpacing; + + ms.pushPose(); + + TransformStack.cast(ms) + .translate(getInstancePosition(partialTicks)) + .translate(0, -1.5 - 1 / 128f, 0);; + + for (BogeyInstance instance : bogeys) { + if (instance != null) { + ms.pushPose(); + CarriageBogey bogey = instance.bogey; + + TransformStack.cast(ms) + .rotateY(viewYRot + 90) + .rotateX(-viewXRot) + .rotateY(180) + .translate(0, 0, bogey.isLeading ? 0 : -bogeySpacing) + .rotateY(-180) + .rotateX(viewXRot) + .rotateY(-viewYRot - 90) + .rotateY(bogey.yaw.getValue(partialTicks)) + .rotateX(bogey.pitch.getValue(partialTicks)) + .translate(0, .5f, 0); + + instance.beginFrame(bogey.wheelAngle.getValue(partialTicks), ms); + ms.popPose(); + } + } + + ms.popPose(); + } + + @Override + public void updateLight() { + if (bogeys == null) return; + + var pos = new BlockPos(entity.getLightProbePosition(AnimationTickHolder.getPartialTicks())); + int block = world.getBrightness(LightLayer.BLOCK, pos); + int sky = world.getBrightness(LightLayer.SKY, pos); + + bogeys.forEach(instance -> { + if (instance != null) + instance.updateLight(block, sky); + }); + } + + @Override + public void remove() { + bogeys.forEach(BogeyInstance::remove); + } + + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java index 72064ea39..e579cbf35 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.logistics.trains.track; import java.util.EnumSet; +import com.jozufozu.flywheel.api.MaterialManager; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Vector3f; @@ -10,6 +11,8 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; import com.simibubi.create.content.logistics.trains.IBogeyBlock; +import com.simibubi.create.content.logistics.trains.entity.BogeyInstance; +import com.simibubi.create.content.logistics.trains.entity.CarriageBogey; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.utility.AngleHelper; @@ -36,7 +39,7 @@ import net.minecraftforge.api.distmarker.OnlyIn; public class StandardBogeyBlock extends Block implements IBogeyBlock, ITE { public static final EnumProperty AXIS = BlockStateProperties.HORIZONTAL_AXIS; - private boolean large; + private final boolean large; public StandardBogeyBlock(Properties p_i48440_1_, boolean large) { super(p_i48440_1_); @@ -114,23 +117,30 @@ public class StandardBogeyBlock extends Block implements IBogeyBlock, ITE pState.cycle(AXIS); + default -> pState; + }; } @Override diff --git a/src/main/java/com/simibubi/create/foundation/data/CreateEntityBuilder.java b/src/main/java/com/simibubi/create/foundation/data/CreateEntityBuilder.java index f40420188..ee411cfdc 100644 --- a/src/main/java/com/simibubi/create/foundation/data/CreateEntityBuilder.java +++ b/src/main/java/com/simibubi/create/foundation/data/CreateEntityBuilder.java @@ -42,7 +42,7 @@ public class CreateEntityBuilder extends EntityBuilder instance(NonNullSupplier>> instanceFactory, boolean renderNormally) { - return instance(instanceFactory, be -> true); + return instance(instanceFactory, be -> renderNormally); } public CreateEntityBuilder instance(NonNullSupplier>> instanceFactory, NonNullPredicate renderNormally) { 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 36b257a23..608ab696c 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/Couple.java +++ b/src/main/java/com/simibubi/create/foundation/utility/Couple.java @@ -63,10 +63,15 @@ public class Couple extends Pair implements Iterable { return Couple.create(function.apply(first, values.first), function.apply(second, values.second)); } + public Couple mapNotNullWithParam(BiFunction function, R value) { + return Couple.create(first != null ? function.apply(first, value) : null, + second != null ? function.apply(second, value) : null); + } + public boolean both(Predicate test) { return test.test(getFirst()) && test.test(getSecond()); } - + public boolean either(Predicate test) { return test.test(getFirst()) || test.test(getSecond()); } @@ -125,7 +130,7 @@ public class Couple extends Pair implements Iterable { private static class Couplerator implements Iterator { int state; - private Couple couple; + private final Couple couple; public Couplerator(Couple couple) { this.couple = couple;