diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index dcef481c9..bfc1cb9fd 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -16,8 +16,11 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.content.contraptions.relays.belt.BeltData; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; @@ -259,4 +262,22 @@ public class AllBlockPartials { return dispatcher.getMaterial(KineticRenderMaterials.ROTATING).getModel(this, referenceState, facing, ms); } + public InstancedModel renderOnHorizontalModel(InstancedTileRenderer dispatcher, BlockState referenceState) { + Direction facing = referenceState.get(HORIZONTAL_FACING); + return renderOnDirectionalSouthModel(dispatcher, referenceState, facing); + } + + public InstancedModel renderOnDirectionalSouthModel(InstancedTileRenderer dispatcher, BlockState referenceState, Direction facing) { + Supplier ms = () -> { + MatrixStack stack = new MatrixStack(); + MatrixStacker.of(stack) + .centre() + .rotateY(AngleHelper.horizontalAngle(facing)) + .rotateX(AngleHelper.verticalAngle(facing)) + .unCentre(); + return stack; + }; + return dispatcher.getMaterial(RenderMaterials.MODELS).getModel(this, referenceState, facing, ms); + } + } diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 6f4e55685..e480efc82 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -32,6 +32,7 @@ import com.simibubi.create.content.contraptions.components.fan.NozzleTileEntity; import com.simibubi.create.content.contraptions.components.flywheel.FlyWheelInstance; import com.simibubi.create.content.contraptions.components.flywheel.FlywheelRenderer; import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity; +import com.simibubi.create.content.contraptions.components.flywheel.engine.EngineInstance; import com.simibubi.create.content.contraptions.components.flywheel.engine.EngineRenderer; import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineTileEntity; import com.simibubi.create.content.contraptions.components.millstone.MillStoneCogInstance; @@ -139,6 +140,7 @@ import com.simibubi.create.content.logistics.block.redstone.NixieTubeTileEntity; import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkTileEntity; import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchTileEntity; import com.simibubi.create.content.schematics.block.SchematicTableTileEntity; +import com.simibubi.create.content.schematics.block.SchematicannonInstance; import com.simibubi.create.content.schematics.block.SchematicannonRenderer; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; @@ -151,6 +153,7 @@ public class AllTileEntities { .tileEntity("schematicannon", SchematicannonTileEntity::new) .validBlocks(AllBlocks.SCHEMATICANNON) .renderer(() -> SchematicannonRenderer::new) + .onRegister(SchematicannonInstance::register) .register(); public static final TileEntityEntry SCHEMATIC_TABLE = Create.registrate() @@ -456,6 +459,7 @@ public class AllTileEntities { .tileEntity("furnace_engine", FurnaceEngineTileEntity::new) .validBlocks(AllBlocks.FURNACE_ENGINE) .renderer(() -> EngineRenderer::new) + .onRegister(EngineInstance::register) .register(); public static final TileEntityEntry MILLSTONE = Create.registrate() diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index e81756d8f..2bc3cb728 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -1,34 +1,57 @@ package com.simibubi.create.content.contraptions.components.flywheel; -import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; -import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; -import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.RenderMaterials; +import com.simibubi.create.foundation.render.backend.instancing.*; -import net.minecraft.block.BlockState; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.LightType; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; -public class FlyWheelInstance extends KineticTileInstance { +public class FlyWheelInstance extends KineticTileInstance implements ITickableInstance { public static void register(TileEntityType type) { DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedTileRenderRegistry.instance.register(type, FlyWheelInstance::new)); } protected Direction facing; + protected boolean connectedLeft; + protected float connectorAngleMult; + + protected Direction connection; protected InstanceKey shaft; -// protected InstanceKey wheel; + + protected InstanceKey wheel; + protected InstanceKey upperRotating; + protected InstanceKey lowerRotating; + protected InstanceKey upperSliding; + protected InstanceKey lowerSliding; + + protected List> connectors; + + protected float lastAngle = Float.NaN; public FlyWheelInstance(InstancedTileRenderer modelManager, FlywheelTileEntity tile) { super(modelManager, tile); @@ -40,35 +63,152 @@ public class FlyWheelInstance extends KineticTileInstance { Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState); shaft = setup(shaftModel().createInstance(), tile.getSpeed(), axis); -// wheel = wheelModel().setupInstance(setup); + + wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontalModel(modelManager, lastState.rotate(Rotation.CLOCKWISE_90)).createInstance(); + + connection = FlywheelBlock.getConnection(lastState); + if (connection != null) { + connectedLeft = lastState.get(FlywheelBlock.CONNECTION) == FlywheelBlock.ConnectionState.LEFT; + + boolean flipAngle = connection.getAxis() == Direction.Axis.X ^ connection.getAxisDirection() == Direction.AxisDirection.NEGATIVE; + + connectorAngleMult = flipAngle ? -1 : 1; + + RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); + + upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, lastState).createInstance(); + lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, lastState).createInstance(); + upperSliding = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_SLIDING, lastState).createInstance(); + lowerSliding = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_SLIDING, lastState).createInstance(); + + connectors = Lists.newArrayList(upperRotating, lowerRotating, upperSliding, lowerSliding); + } else { + connectors = Collections.emptyList(); + } + + updateLight(); + } + + @Override + public void tick() { + + float partialTicks = AnimationTickHolder.getPartialTicks(); + + float speed = tile.visualSpeed.get(partialTicks) * 3 / 10f; + float angle = tile.angle + speed * partialTicks; + + if (Math.abs(angle - lastAngle) < 0.001) return; + + MatrixStack ms = new MatrixStack(); + MatrixStacker msr = MatrixStacker.of(ms); + + msr.translate(getFloatingPos()); + + if (connection != null) { + float rotation = angle * connectorAngleMult; + + ms.push(); + rotateToFacing(msr, connection); + + ms.push(); + transformConnector(msr, true, true, rotation, connectedLeft); + upperRotating.getInstance().setTransform(ms); + ms.pop(); + + ms.push(); + transformConnector(msr, false, true, rotation, connectedLeft); + lowerRotating.getInstance().setTransform(ms); + ms.pop(); + + ms.push(); + transformConnector(msr, true, false, rotation, connectedLeft); + upperSliding.getInstance().setTransform(ms); + ms.pop(); + + ms.push(); + transformConnector(msr, false, false, rotation, connectedLeft); + lowerSliding.getInstance().setTransform(ms); + ms.pop(); + + ms.pop(); + } + + msr.centre() + .rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()), AngleHelper.rad(angle)) + .unCentre(); + + wheel.getInstance().setTransformNoCopy(ms); + + lastAngle = angle; } @Override protected void onUpdate() { Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState); updateRotation(shaft, axis); -// updateRotation(wheel, axis); } @Override public void updateLight() { - relight(shaft); -// wheel.modifyInstance(this::relight); + int block = world.getLightLevel(LightType.BLOCK, pos); + int sky = world.getLightLevel(LightType.SKY, pos); + + shaft.getInstance().setBlockLight(block).setSkyLight(sky); + wheel.getInstance().setBlockLight(block).setSkyLight(sky); + + if (connection != null) { + BlockPos pos = this.pos.offset(connection); + + int connectionBlock = world.getLightLevel(LightType.BLOCK, pos); + int connectionSky = world.getLightLevel(LightType.SKY, pos); + connectors.stream() + .map(InstanceKey::getInstance) + .forEach(data -> data.setBlockLight(connectionBlock).setSkyLight(connectionSky)); + } } @Override public void remove() { shaft.delete(); -// wheel.delete(); -// wheel = null; + wheel.delete(); + + connectors.forEach(InstanceKey::delete); + connectors.clear(); } protected InstancedModel shaftModel() { return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, facing.getOpposite()); } - protected InstancedModel wheelModel() { - BlockState rotate = lastState.rotate(Rotation.CLOCKWISE_90); - return AllBlockPartials.FLYWHEEL.renderOnDirectionalSouthRotating(modelManager, rotate, rotate.get(BlockStateProperties.HORIZONTAL_FACING)); + protected void transformConnector(MatrixStacker ms, boolean upper, boolean rotating, float angle, boolean flip) { + float shift = upper ? 1 / 4f : -1 / 8f; + float offset = upper ? 1 / 4f : 1 / 4f; + float radians = (float) (angle / 180 * Math.PI); + float shifting = MathHelper.sin(radians) * shift + offset; + + float maxAngle = upper ? -5 : -15; + float minAngle = upper ? -45 : 5; + float barAngle = 0; + + if (rotating) + barAngle = MathHelper.lerp((MathHelper.sin((float) (radians + Math.PI / 2)) + 1) / 2, minAngle, maxAngle); + + float pivotX = (upper ? 8f : 3f) / 16; + float pivotY = (upper ? 8f : 2f) / 16; + float pivotZ = (upper ? 23f : 21.5f) / 16f; + + ms.translate(pivotX, pivotY, pivotZ + shifting); + if (rotating) + ms.rotate(Direction.EAST, AngleHelper.rad(barAngle)); + ms.translate(-pivotX, -pivotY, -pivotZ); + + if (flip && !upper) + ms.translate(9 / 16f, 0, 0); + } + + protected void rotateToFacing(MatrixStacker buffer, Direction facing) { + buffer.centre() + .rotate(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing))) + .unCentre(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java index be3d3e108..03434b9e9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java @@ -9,6 +9,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.utility.AngleHelper; import net.minecraft.block.BlockState; @@ -33,10 +34,11 @@ public class FlywheelRenderer extends KineticTileEntityRenderer { int light, int overlay) { super.renderSafe(te, partialTicks, ms, buffer, light, overlay); + if (FastRenderDispatcher.available(te.getWorld())) return; + BlockState blockState = te.getBlockState(); FlywheelTileEntity wte = (FlywheelTileEntity) te; - SuperByteBuffer wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontal(blockState.rotate(Rotation.CLOCKWISE_90)); float speed = wte.visualSpeed.get(partialTicks) * 3 / 10f; float angle = wte.angle + speed * partialTicks; @@ -68,6 +70,7 @@ public class FlywheelRenderer extends KineticTileEntityRenderer { .renderInto(ms, vb); } + SuperByteBuffer wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontal(blockState.rotate(Rotation.CLOCKWISE_90)); kineticRotationTransform(wheel, te, blockState.get(HORIZONTAL_FACING) .getAxis(), AngleHelper.rad(angle), light); wheel.renderInto(ms, vb); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java index 67f4952b7..2dab48a50 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java @@ -100,9 +100,4 @@ public class FlywheelTileEntity extends GeneratingKineticTileEntity { updateGeneratedRotation(); } } - - @Override - public boolean shouldRenderAsTE() { - return true; - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java new file mode 100644 index 000000000..2324e3a7d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java @@ -0,0 +1,80 @@ +package com.simibubi.create.content.contraptions.components.flywheel.engine; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.backend.RenderMaterials; +import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.MatrixStacker; +import net.minecraft.block.Block; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.LightType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; + +public class EngineInstance extends TileEntityInstance { + public static void register(TileEntityType type) { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> + InstancedTileRenderRegistry.instance.register(type, EngineInstance::new)); + } + + protected BlockPos baseBlockPos; + protected InstanceKey frame; + + public EngineInstance(InstancedTileRenderer modelManager, EngineTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + Block block = lastState + .getBlock(); + if (!(block instanceof EngineBlock)) + return; + + EngineBlock engineBlock = (EngineBlock) block; + AllBlockPartials frame = engineBlock.getFrameModel(); + + Direction facing = lastState.get(BlockStateProperties.HORIZONTAL_FACING); + + baseBlockPos = EngineBlock.getBaseBlockPos(lastState, pos); + + this.frame = modelManager.getMaterial(RenderMaterials.MODELS).getModel(frame, lastState).createInstance(); + + float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing)); + + MatrixStack ms = new MatrixStack(); + MatrixStacker msr = MatrixStacker.of(ms); + + msr.translate(getFloatingPos()) + .centre() + .rotate(Direction.UP, angle) + .unCentre() + .translate(0, 0, -1); + + this.frame.getInstance() + .setTransformNoCopy(ms); + + updateLight(); + } + + @Override + public void remove() { + frame.delete(); + } + + @Override + public void updateLight() { + int block = world.getLightLevel(LightType.BLOCK, baseBlockPos); + int sky = world.getLightLevel(LightType.SKY, baseBlockPos); + + frame.getInstance().setBlockLight(block).setSkyLight(sky); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineRenderer.java index 477348870..597895c48 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineRenderer.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; @@ -21,6 +22,9 @@ public class EngineRenderer extends SafeTileEntityRe @Override protected void renderSafe(T te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { + + if (FastRenderDispatcher.available(te.getWorld())) return; + Block block = te.getBlockState() .getBlock(); if (block instanceof EngineBlock) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineTileEntity.java index 6a3988caa..b14e7e47e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineTileEntity.java @@ -3,8 +3,10 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine; import java.util.List; import com.simibubi.create.AllBlocks; +import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock; import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity; +import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -16,8 +18,10 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; +import org.apache.http.client.CredentialsProvider; -public class EngineTileEntity extends SmartTileEntity { +public class EngineTileEntity extends SmartTileEntity implements IInstanceRendered { public float appliedCapacity; public float appliedSpeed; @@ -100,4 +104,16 @@ public class EngineTileEntity extends SmartTileEntity { poweredWheel.setRotation(appliedSpeed, appliedCapacity); } + @Override + public void onChunkLightUpdate() { + CreateClient.kineticRenderer.onLightUpdate(this); + } + + @Override + public void initialize() { + super.initialize(); + + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.add(this)); + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java index cdf738df3..4beadc933 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java @@ -48,9 +48,12 @@ public class MixerInstance extends ShaftlessCogInstance implements ITickableInst .createInstance(); - updateLight(); MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) tile; - transformPole(getRenderedHeadOffset(mixer)); + float renderedHeadOffset = getRenderedHeadOffset(mixer); + + transformPole(renderedHeadOffset); + transformHead(mixer, renderedHeadOffset); + updateLight(); } @Override diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java new file mode 100644 index 000000000..47ddbaf4c --- /dev/null +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java @@ -0,0 +1,99 @@ +package com.simibubi.create.content.schematics.block; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance; +import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.RenderMaterials; +import com.simibubi.create.foundation.render.backend.instancing.*; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.MatrixStacker; +import net.minecraft.block.BlockState; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.LightType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; + +public class SchematicannonInstance extends TileEntityInstance implements ITickableInstance { + public static void register(TileEntityType type) { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> + InstancedTileRenderRegistry.instance.register(type, SchematicannonInstance::new)); + } + + private InstanceKey connector; + private InstanceKey pipe; + + public SchematicannonInstance(InstancedTileRenderer modelManager, SchematicannonTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + + RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); + + connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, lastState).createInstance(); + pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, lastState).createInstance(); + + updateLight(); + } + + @Override + public void tick() { + float partialTicks = AnimationTickHolder.getPartialTicks(); + + double[] cannonAngles = SchematicannonRenderer.getCannonAngles(tile, pos, partialTicks); + + double pitch = cannonAngles[0]; + double yaw = cannonAngles[1]; + + double recoil = SchematicannonRenderer.getRecoil(tile, partialTicks); + + MatrixStack ms = new MatrixStack(); + MatrixStacker msr = MatrixStacker.of(ms); + + msr.translate(getFloatingPos()); + + ms.push(); + msr.centre(); + msr.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI)); + msr.unCentre(); + connector.getInstance().setTransform(ms); + ms.pop(); + + msr.translate(.5f, 15 / 16f, .5f); + msr.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI)); + msr.rotate(Direction.SOUTH, (float) (pitch / 180 * Math.PI)); + msr.translate(-.5f, -15 / 16f, -.5f); + msr.translate(0, -recoil / 100, 0); + + pipe.getInstance().setTransformNoCopy(ms); + } + + @Override + public void remove() { + connector.delete(); + pipe.delete(); + } + + @Override + public void updateLight() { + int block = world.getLightLevel(LightType.BLOCK, pos); + int sky = world.getLightLevel(LightType.SKY, pos); + + connector.getInstance() + .setBlockLight(block) + .setSkyLight(sky); + + pipe.getInstance() + .setBlockLight(block) + .setSkyLight(sky); + } +} diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonRenderer.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonRenderer.java index 6163c07fc..32856a392 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonRenderer.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonRenderer.java @@ -8,6 +8,7 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.schematics.block.LaunchedItem.ForBlockState; import com.simibubi.create.content.schematics.block.LaunchedItem.ForEntity; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import net.minecraft.block.BlockState; @@ -40,33 +41,20 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer launched.totalTicks - 10) + recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10); + } + + return recoil; + } + + private static void renderLaunchedBlocks(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { for (LaunchedItem launched : tileEntityIn.flyingBlocks) { if (launched.ticksRemaining == 0) @@ -141,10 +171,6 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer launched.totalTicks - 10) - recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10); - // Render particles for launch if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) { tileEntityIn.firstRenderTick = false; @@ -162,8 +188,6 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer () -> CreateClient.kineticRenderer.add(this)); + } + + @Override + public void onChunkLightUpdate() { + CreateClient.kineticRenderer.onLightUpdate(this); + } + + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/MatrixStacker.java b/src/main/java/com/simibubi/create/foundation/utility/MatrixStacker.java index 5db42563c..9b41a4ed2 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/MatrixStacker.java +++ b/src/main/java/com/simibubi/create/foundation/utility/MatrixStacker.java @@ -4,6 +4,7 @@ import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.client.renderer.Quaternion; import net.minecraft.client.renderer.Vector3f; +import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -23,6 +24,14 @@ public class MatrixStacker { return instance; } + public MatrixStacker rotate(Direction axis, float radians) { + if (radians == 0) + return this; + ms.multiply(axis.getUnitVector() + .getRadialQuaternion(radians)); + return this; + } + public MatrixStacker rotate(double angle, Axis axis) { Vector3f vec = axis == Axis.X ? Vector3f.POSITIVE_X : axis == Axis.Y ? Vector3f.POSITIVE_Y : Vector3f.POSITIVE_Z;