diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 1eb2881ad..bc0c28e66 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -1,23 +1,17 @@ package com.simibubi.create; -import static net.minecraft.state.properties.BlockStateProperties.FACING; -import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.AttachmentTypes; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; -import com.simibubi.create.foundation.utility.*; - -import com.simibubi.create.foundation.render.instancing.*; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.instancing.*; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.util.Direction; @@ -26,6 +20,15 @@ import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import static net.minecraft.state.properties.BlockStateProperties.FACING; +import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; + public class AllBlockPartials { private static final List all = new ArrayList<>(); @@ -219,20 +222,41 @@ public class AllBlockPartials { return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms); } - public InstanceBuffer renderOnRotating(InstanceContext ctx, BlockState referenceState) { + @Deprecated + public InstancedModel renderOnRotating(InstanceContext ctx, BlockState referenceState) { return ctx.getRotating().getModel(this, referenceState); } - public InstanceBuffer renderOnBelt(InstanceContext ctx, BlockState referenceState) { + public InstancedModel renderOnRotating(InstancedTileRenderDispatcher ctx, BlockState referenceState) { + return ctx.get(KineticRenderMaterials.ROTATING).getModel(this, referenceState); + } + + @Deprecated + public InstancedModel renderOnBelt(InstanceContext ctx, BlockState referenceState) { return ctx.getBelts().getModel(this, referenceState); } - public InstanceBuffer renderOnDirectionalSouthRotating(InstanceContext ctx, BlockState referenceState) { + public InstancedModel renderOnBelt(InstancedTileRenderDispatcher ctx, BlockState referenceState) { + return ctx.get(KineticRenderMaterials.BELTS).getModel(this, referenceState); + } + + @Deprecated + public InstancedModel renderOnDirectionalSouthRotating(InstanceContext ctx, BlockState referenceState) { Direction facing = referenceState.get(FACING); return renderOnDirectionalSouthRotating(ctx, referenceState, facing); } - public InstanceBuffer renderOnDirectionalSouthRotating(InstanceContext ctx, BlockState referenceState, Direction facing) { + public InstancedModel renderOnDirectionalSouthRotating(InstancedTileRenderDispatcher dispatcher, BlockState referenceState) { + Direction facing = referenceState.get(FACING); + return renderOnDirectionalSouthRotating(dispatcher, referenceState, facing); + } + + @Deprecated + public InstancedModel renderOnDirectionalSouthRotating(InstanceContext ctx, BlockState referenceState, Direction facing) { + return renderOnDirectionalSouthRotating(ctx.getKinetics(), referenceState, facing); + } + + public InstancedModel renderOnDirectionalSouthRotating(InstancedTileRenderDispatcher dispatcher, BlockState referenceState, Direction facing) { Supplier ms = () -> { MatrixStack stack = new MatrixStack(); MatrixStacker.of(stack) @@ -242,7 +266,7 @@ public class AllBlockPartials { .unCentre(); return stack; }; - return ctx.getRotating().getModel(this, referenceState, facing, ms); + return dispatcher.get(KineticRenderMaterials.ROTATING).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 55b71eaee..8900b34c5 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -1,13 +1,7 @@ package com.simibubi.create; -import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.content.contraptions.components.actors.DrillRenderer; -import com.simibubi.create.content.contraptions.components.actors.DrillTileEntity; -import com.simibubi.create.content.contraptions.components.actors.HarvesterRenderer; -import com.simibubi.create.content.contraptions.components.actors.HarvesterTileEntity; -import com.simibubi.create.content.contraptions.components.actors.PortableFluidInterfaceTileEntity; -import com.simibubi.create.content.contraptions.components.actors.PortableItemInterfaceTileEntity; -import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceRenderer; +import com.simibubi.create.content.contraptions.base.*; +import com.simibubi.create.content.contraptions.components.actors.*; import com.simibubi.create.content.contraptions.components.clock.CuckooClockRenderer; import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterRenderer; @@ -25,6 +19,7 @@ import com.simibubi.create.content.contraptions.components.flywheel.FlywheelRend import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity; 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; import com.simibubi.create.content.contraptions.components.millstone.MillstoneRenderer; import com.simibubi.create.content.contraptions.components.millstone.MillstoneTileEntity; import com.simibubi.create.content.contraptions.components.mixer.MechanicalMixerRenderer; @@ -47,20 +42,11 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pul import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; import com.simibubi.create.content.contraptions.components.turntable.TurntableTileEntity; import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelTileEntity; +import com.simibubi.create.content.contraptions.fluids.PumpCogInstance; import com.simibubi.create.content.contraptions.fluids.PumpRenderer; import com.simibubi.create.content.contraptions.fluids.PumpTileEntity; -import com.simibubi.create.content.contraptions.fluids.actors.HosePulleyRenderer; -import com.simibubi.create.content.contraptions.fluids.actors.HosePulleyTileEntity; -import com.simibubi.create.content.contraptions.fluids.actors.ItemDrainRenderer; -import com.simibubi.create.content.contraptions.fluids.actors.ItemDrainTileEntity; -import com.simibubi.create.content.contraptions.fluids.actors.SpoutRenderer; -import com.simibubi.create.content.contraptions.fluids.actors.SpoutTileEntity; -import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeTileEntity; -import com.simibubi.create.content.contraptions.fluids.pipes.FluidValveRenderer; -import com.simibubi.create.content.contraptions.fluids.pipes.FluidValveTileEntity; -import com.simibubi.create.content.contraptions.fluids.pipes.SmartFluidPipeTileEntity; -import com.simibubi.create.content.contraptions.fluids.pipes.StraightPipeTileEntity; -import com.simibubi.create.content.contraptions.fluids.pipes.TransparentStraightPipeRenderer; +import com.simibubi.create.content.contraptions.fluids.actors.*; +import com.simibubi.create.content.contraptions.fluids.pipes.*; import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankRenderer; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; @@ -71,17 +57,15 @@ import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerTil import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerRenderer; import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerTileEntity; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity; +import com.simibubi.create.content.contraptions.relays.belt.BeltInstance; import com.simibubi.create.content.contraptions.relays.belt.BeltRenderer; import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.content.contraptions.relays.elementary.SimpleKineticTileEntity; -import com.simibubi.create.content.contraptions.relays.encased.AdjustablePulleyTileEntity; -import com.simibubi.create.content.contraptions.relays.encased.ClutchTileEntity; -import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftRenderer; -import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftTileEntity; -import com.simibubi.create.content.contraptions.relays.encased.SplitShaftRenderer; +import com.simibubi.create.content.contraptions.relays.encased.*; import com.simibubi.create.content.contraptions.relays.gauge.GaugeRenderer; import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity; import com.simibubi.create.content.contraptions.relays.gauge.StressGaugeTileEntity; +import com.simibubi.create.content.contraptions.relays.gearbox.GearboxInstance; import com.simibubi.create.content.contraptions.relays.gearbox.GearboxRenderer; import com.simibubi.create.content.contraptions.relays.gearbox.GearboxTileEntity; import com.simibubi.create.content.contraptions.relays.gearbox.GearshiftTileEntity; @@ -99,15 +83,10 @@ import com.simibubi.create.content.logistics.block.funnel.FunnelRenderer; import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateTileEntity; import com.simibubi.create.content.logistics.block.inventories.CreativeCrateTileEntity; +import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInstance; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmRenderer; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity; -import com.simibubi.create.content.logistics.block.redstone.AnalogLeverRenderer; -import com.simibubi.create.content.logistics.block.redstone.AnalogLeverTileEntity; -import com.simibubi.create.content.logistics.block.redstone.ContentObserverTileEntity; -import com.simibubi.create.content.logistics.block.redstone.NixieTubeRenderer; -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.logistics.block.redstone.*; import com.simibubi.create.content.schematics.block.SchematicTableTileEntity; import com.simibubi.create.content.schematics.block.SchematicannonRenderer; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; @@ -133,30 +112,35 @@ public class AllTileEntities { .tileEntity("simple_kinetic", SimpleKineticTileEntity::new) .validBlocks(AllBlocks.SHAFT, AllBlocks.COGWHEEL, AllBlocks.LARGE_COGWHEEL) .renderer(() -> KineticTileEntityRenderer::new) + .onRegister(SingleRotatingInstance::register) .register(); public static final TileEntityEntry MOTOR = Create.registrate() .tileEntity("motor", CreativeMotorTileEntity::new) .validBlocks(AllBlocks.CREATIVE_MOTOR) .renderer(() -> CreativeMotorRenderer::new) + .onRegister(HalfShaftInstance::register) .register(); public static final TileEntityEntry GEARBOX = Create.registrate() .tileEntity("gearbox", GearboxTileEntity::new) .validBlocks(AllBlocks.GEARBOX) .renderer(() -> GearboxRenderer::new) + .onRegister(GearboxInstance::register) .register(); public static final TileEntityEntry ENCASED_SHAFT = Create.registrate() .tileEntity("encased_shaft", EncasedShaftTileEntity::new) .validBlocks(AllBlocks.ANDESITE_ENCASED_SHAFT, AllBlocks.BRASS_ENCASED_SHAFT, AllBlocks.ENCASED_CHAIN_DRIVE) .renderer(() -> EncasedShaftRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry ADJUSTABLE_PULLEY = Create.registrate() .tileEntity("adjustable_pulley", AdjustablePulleyTileEntity::new) .validBlocks(AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT) .renderer(() -> EncasedShaftRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry ENCASED_FAN = Create.registrate() @@ -175,12 +159,14 @@ public class AllTileEntities { .tileEntity("clutch", ClutchTileEntity::new) .validBlocks(AllBlocks.CLUTCH) .renderer(() -> SplitShaftRenderer::new) + .onRegister(SplitShaftInstance::register) .register(); public static final TileEntityEntry GEARSHIFT = Create.registrate() .tileEntity("gearshift", GearshiftTileEntity::new) .validBlocks(AllBlocks.GEARSHIFT) .renderer(() -> SplitShaftRenderer::new) + .onRegister(SplitShaftInstance::register) .register(); public static final TileEntityEntry TURNTABLE = Create.registrate() @@ -194,18 +180,21 @@ public class AllTileEntities { .validBlocks(AllBlocks.HAND_CRANK, AllBlocks.COPPER_VALVE_HANDLE) .validBlocks(AllBlocks.DYED_VALVE_HANDLES) .renderer(() -> HandCrankRenderer::new) + .onRegister(BackHalfShaftInstance::register) .register(); public static final TileEntityEntry CUCKOO_CLOCK = Create.registrate() .tileEntity("cuckoo_clock", CuckooClockTileEntity::new) .validBlocks(AllBlocks.CUCKOO_CLOCK, AllBlocks.MYSTERIOUS_CUCKOO_CLOCK) .renderer(() -> CuckooClockRenderer::new) + .onRegister(HorizontalHalfShaftInstance::register) .register(); public static final TileEntityEntry MECHANICAL_PUMP = Create.registrate() .tileEntity("mechanical_pump", PumpTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_PUMP) .renderer(() -> PumpRenderer::new) + .onRegister(PumpCogInstance::register) .register(); public static final TileEntityEntry SMART_FLUID_PIPE = Create.registrate() @@ -234,6 +223,7 @@ public class AllTileEntities { .tileEntity("fluid_valve", FluidValveTileEntity::new) .validBlocks(AllBlocks.FLUID_VALVE) .renderer(() -> FluidValveRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry FLUID_TANK = Create.registrate() @@ -252,6 +242,7 @@ public class AllTileEntities { .tileEntity("hose_pulley", HosePulleyTileEntity::new) .validBlocks(AllBlocks.HOSE_PULLEY) .renderer(() -> HosePulleyRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry SPOUT = Create.registrate() @@ -270,6 +261,7 @@ public class AllTileEntities { .tileEntity("belt", BeltTileEntity::new) .validBlocks(AllBlocks.BELT) .renderer(() -> BeltRenderer::new) + .onRegister(BeltInstance::register) .register(); public static final TileEntityEntry CHUTE = Create.registrate() @@ -294,36 +286,42 @@ public class AllTileEntities { .tileEntity("mechanical_arm", ArmTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_ARM) .renderer(() -> ArmRenderer::new) + .onRegister(ArmInstance::register) .register(); public static final TileEntityEntry MECHANICAL_PISTON = Create.registrate() .tileEntity("mechanical_piston", MechanicalPistonTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON) .renderer(() -> MechanicalPistonRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry WINDMILL_BEARING = Create.registrate() .tileEntity("windmill_bearing", WindmillBearingTileEntity::new) .validBlocks(AllBlocks.WINDMILL_BEARING) .renderer(() -> BearingRenderer::new) + .onRegister(BackHalfShaftInstance::register) .register(); public static final TileEntityEntry MECHANICAL_BEARING = Create.registrate() .tileEntity("mechanical_bearing", MechanicalBearingTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_BEARING) .renderer(() -> BearingRenderer::new) + .onRegister(BackHalfShaftInstance::register) .register(); public static final TileEntityEntry CLOCKWORK_BEARING = Create.registrate() .tileEntity("clockwork_bearing", ClockworkBearingTileEntity::new) .validBlocks(AllBlocks.CLOCKWORK_BEARING) .renderer(() -> BearingRenderer::new) + .onRegister(BackHalfShaftInstance::register) .register(); public static final TileEntityEntry ROPE_PULLEY = Create.registrate() .tileEntity("rope_pulley", PulleyTileEntity::new) .validBlocks(AllBlocks.ROPE_PULLEY) .renderer(() -> PulleyRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry CHASSIS = Create.registrate() @@ -336,6 +334,7 @@ public class AllTileEntities { .tileEntity("drill", DrillTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_DRILL) .renderer(() -> DrillRenderer::new) + .onRegister(DrillInstance::register) .register(); public static final TileEntityEntry SAW = Create.registrate() @@ -367,6 +366,7 @@ public class AllTileEntities { .tileEntity("flywheel", FlywheelTileEntity::new) .validBlocks(AllBlocks.FLYWHEEL) .renderer(() -> FlywheelRenderer::new) + .onRegister(HorizontalHalfShaftInstance::register) .register(); public static final TileEntityEntry FURNACE_ENGINE = Create.registrate() @@ -379,12 +379,14 @@ public class AllTileEntities { .tileEntity("millstone", MillstoneTileEntity::new) .validBlocks(AllBlocks.MILLSTONE) .renderer(() -> MillstoneRenderer::new) + .onRegister(MillStoneCogInstance::register) .register(); public static final TileEntityEntry CRUSHING_WHEEL = Create.registrate() .tileEntity("crushing_wheel", CrushingWheelTileEntity::new) .validBlocks(AllBlocks.CRUSHING_WHEEL) .renderer(() -> KineticTileEntityRenderer::new) + .onRegister(SingleRotatingInstance::register) .register(); public static final TileEntityEntry CRUSHING_WHEEL_CONTROLLER = @@ -398,24 +400,28 @@ public class AllTileEntities { .tileEntity("water_wheel", WaterWheelTileEntity::new) .validBlocks(AllBlocks.WATER_WHEEL) .renderer(() -> KineticTileEntityRenderer::new) + .onRegister(SingleRotatingInstance::register) .register(); public static final TileEntityEntry MECHANICAL_PRESS = Create.registrate() .tileEntity("mechanical_press", MechanicalPressTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_PRESS) .renderer(() -> MechanicalPressRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry MECHANICAL_MIXER = Create.registrate() .tileEntity("mechanical_mixer", MechanicalMixerTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_MIXER) .renderer(() -> MechanicalMixerRenderer::new) + .onRegister(ShaftlessCogInstance::register) .register(); public static final TileEntityEntry DEPLOYER = Create.registrate() .tileEntity("deployer", DeployerTileEntity::new) .validBlocks(AllBlocks.DEPLOYER) .renderer(() -> DeployerRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry BASIN = Create.registrate() @@ -434,30 +440,35 @@ public class AllTileEntities { .tileEntity("mechanical_crafter", MechanicalCrafterTileEntity::new) .validBlocks(AllBlocks.MECHANICAL_CRAFTER) .renderer(() -> MechanicalCrafterRenderer::new) + .onRegister(ShaftlessCogInstance::register) .register(); public static final TileEntityEntry SEQUENCED_GEARSHIFT = Create.registrate() .tileEntity("sequenced_gearshift", SequencedGearshiftTileEntity::new) .validBlocks(AllBlocks.SEQUENCED_GEARSHIFT) .renderer(() -> SplitShaftRenderer::new) + .onRegister(SplitShaftInstance::register) .register(); public static final TileEntityEntry ROTATION_SPEED_CONTROLLER = Create.registrate() .tileEntity("rotation_speed_controller", SpeedControllerTileEntity::new) .validBlocks(AllBlocks.ROTATION_SPEED_CONTROLLER) .renderer(() -> SpeedControllerRenderer::new) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry SPEEDOMETER = Create.registrate() .tileEntity("speedometer", SpeedGaugeTileEntity::new) .validBlocks(AllBlocks.SPEEDOMETER) .renderer(() -> GaugeRenderer::speed) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry STRESSOMETER = Create.registrate() .tileEntity("stressometer", StressGaugeTileEntity::new) .validBlocks(AllBlocks.STRESSOMETER) .renderer(() -> GaugeRenderer::stress) + .onRegister(SingleRotatingShaftInstance::register) .register(); public static final TileEntityEntry ANALOG_LEVER = Create.registrate() diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 02fbacc5d..ca0dcbdec 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -1,10 +1,5 @@ package com.simibubi.create; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRenderer; import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity; @@ -16,12 +11,11 @@ import com.simibubi.create.foundation.block.render.CustomBlockModels; import com.simibubi.create.foundation.block.render.SpriteShifter; import com.simibubi.create.foundation.item.CustomItemModels; import com.simibubi.create.foundation.item.CustomRenderedItems; -import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher; -import com.simibubi.create.foundation.render.FastKineticRenderer; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; import com.simibubi.create.foundation.render.SuperByteBufferCache; +import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher; +import com.simibubi.create.foundation.render.gl.shader.ShaderHelper; import com.simibubi.create.foundation.utility.outliner.Outliner; - -import com.simibubi.create.foundation.render.shader.ShaderHelper; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BlockModelShapes; @@ -39,13 +33,18 @@ import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + public class CreateClient { public static ClientSchematicLoader schematicSender; public static SchematicHandler schematicHandler; public static SchematicAndQuillHandler schematicAndQuillHandler; public static SuperByteBufferCache bufferCache; - public static FastKineticRenderer kineticRenderer; + public static InstancedTileRenderDispatcher kineticRenderer; public static final Outliner outliner = new Outliner(); private static CustomBlockModels customBlockModels; @@ -73,7 +72,7 @@ public class CreateClient { bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE); bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20); - kineticRenderer = new FastKineticRenderer(); + kineticRenderer = new InstancedTileRenderDispatcher(); AllKeys.register(); AllContainerTypes.registerScreenFactories(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/BackHalfShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/BackHalfShaftInstance.java new file mode 100644 index 000000000..6538232d7 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/base/BackHalfShaftInstance.java @@ -0,0 +1,22 @@ +package com.simibubi.create.content.contraptions.base; + +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; + +public class BackHalfShaftInstance extends HalfShaftInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, BackHalfShaftInstance::new); + } + + public BackHalfShaftInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected Direction getShaftDirection() { + return tile.getBlockState().get(BlockStateProperties.FACING).getOpposite(); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java new file mode 100644 index 000000000..57611c092 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java @@ -0,0 +1,32 @@ +package com.simibubi.create.content.contraptions.base; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import net.minecraft.block.BlockState; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; + +public class HalfShaftInstance extends SingleRotatingInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, HalfShaftInstance::new); + } + + public HalfShaftInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected InstancedModel getModel() { + BlockState state = tile.getBlockState(); + Direction dir = getShaftDirection(); + return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, state, dir); + } + + protected Direction getShaftDirection() { + return tile.getBlockState().get(BlockStateProperties.FACING); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalHalfShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalHalfShaftInstance.java new file mode 100644 index 000000000..a4f9d2471 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalHalfShaftInstance.java @@ -0,0 +1,22 @@ +package com.simibubi.create.content.contraptions.base; + +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; + +public class HorizontalHalfShaftInstance extends HalfShaftInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, HorizontalHalfShaftInstance::new); + } + + public HorizontalHalfShaftInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected Direction getShaftDirection() { + return tile.getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getOpposite(); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index 90b76469d..d7973d1cb 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.Create; +import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.KineticNetwork; import com.simibubi.create.content.contraptions.RotationPropagator; import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel; @@ -246,7 +247,7 @@ public abstract class KineticTileEntity extends SmartTileEntity effects.triggerOverStressedEffect(); if (clientPacket) - FastRenderDispatcher.markForRebuild(this); + CreateClient.kineticRenderer.update(this); } public float getGeneratedSpeed() { @@ -458,8 +459,6 @@ public abstract class KineticTileEntity extends SmartTileEntity return overStressed; } - public static AxisAlignedBB NOWHERE_AABB = new AxisAlignedBB(Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN); - @Override public AxisAlignedBB getRenderBoundingBox() { return super.getRenderBoundingBox(); @@ -469,4 +468,19 @@ public abstract class KineticTileEntity extends SmartTileEntity public double getMaxRenderDistanceSquared() { return 16384.0D; // TODO: make this a config option } + + @Override + public void requestModelDataUpdate() { + super.requestModelDataUpdate(); + if (this.removed) { + FastRenderDispatcher.enqueueRemove(this); + } else { + FastRenderDispatcher.enqueueUpdate(this); + } + } + + @Override + public void onChunkLightUpdate() { + CreateClient.kineticRenderer.onLightUpdate(this); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java index fe5f8387c..903b92b72 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java @@ -4,11 +4,11 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; -import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.Compartment; +import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -56,7 +56,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer void renderRotatingKineticBlock(InstanceContext ctx, BlockState renderedState) { - InstanceBuffer instancedRenderer = ctx.getRotating().getModel(KINETIC_TILE, renderedState); + InstancedModel instancedRenderer = ctx.getRotating().getModel(KINETIC_TILE, renderedState); renderRotatingBuffer(ctx, instancedRenderer); } @@ -64,7 +64,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer void renderRotatingBuffer(InstanceContext ctx, InstanceBuffer instancer) { + public static void renderRotatingBuffer(InstanceContext ctx, InstancedModel instancer) { instancer.setupInstance(data -> { T te = ctx.te; final BlockPos pos = te.getPos(); @@ -145,7 +145,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return ctx.getRotating().getModel(KINETIC_TILE, getRenderedBlockState(ctx.te)); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java new file mode 100644 index 000000000..ccfd9515f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java @@ -0,0 +1,75 @@ +package com.simibubi.create.content.contraptions.base; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; +import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.*; +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.LightType; +import net.minecraft.world.World; + +import java.util.function.Consumer; + +public abstract class KineticTileInstance extends TileEntityInstance { + + public KineticTileInstance(InstancedTileRenderDispatcher modelManager, T tile) { + super(modelManager, tile); + } + + protected void updateRotation(InstanceKey key, Direction.Axis axis) { + key.modifyInstance(data -> { + final BlockPos pos = tile.getPos(); + + data.setRotationalSpeed(tile.getSpeed()) + .setRotationOffset(getRotationOffsetForPosition(tile, pos, axis)) + .setRotationAxis(axis); + }); + } + + protected final Consumer setupFunc(float speed, Direction.Axis axis) { + return data -> { + final BlockPos pos = tile.getPos(); + + data.setBlockLight(tile.getWorld().getLightLevel(LightType.BLOCK, tile.getPos())) + .setSkyLight(tile.getWorld().getLightLevel(LightType.SKY, tile.getPos())) + .setTileEntity(tile) + .setRotationalSpeed(speed) + .setRotationOffset(getRotationOffsetForPosition(tile, pos, axis)) + .setRotationAxis(axis); + }; + } + + protected final void relight(KineticData data) { + World world = tile.getWorld(); + + data.setBlockLight(world.getLightLevel(LightType.BLOCK, tile.getPos())) + .setSkyLight(world.getLightLevel(LightType.SKY, tile.getPos())); + } + + protected static float getRotationOffsetForPosition(KineticTileEntity te, final BlockPos pos, final Direction.Axis axis) { + float offset = CogWheelBlock.isLargeCog(te.getBlockState()) ? 11.25f : 0; + double d = (((axis == Direction.Axis.X) ? 0 : pos.getX()) + ((axis == Direction.Axis.Y) ? 0 : pos.getY()) + + ((axis == Direction.Axis.Z) ? 0 : pos.getZ())) % 2; + if (d == 0) { + offset = 22.5f; + } + return offset; + } + + public static BlockState shaft(Direction.Axis axis) { + return AllBlocks.SHAFT.getDefaultState() + .with(ShaftBlock.AXIS, axis); + } + + public static Direction.Axis getRotationAxisOf(KineticTileEntity te) { + return ((IRotate) te.getBlockState() + .getBlock()).getRotationAxis(te.getBlockState()); + } + + protected final RenderMaterial> rotatingMaterial() { + return modelManager.get(KineticRenderMaterials.ROTATING); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatedPillarKineticBlock.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatedPillarKineticBlock.java index 2e86a897a..f76ff0319 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatedPillarKineticBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/RotatedPillarKineticBlock.java @@ -1,7 +1,6 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.foundation.utility.Iterate; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.item.BlockItemUseContext; @@ -27,7 +26,7 @@ public abstract class RotatedPillarKineticBlock extends KineticBlock { switch (rot) { case COUNTERCLOCKWISE_90: case CLOCKWISE_90: - switch ((Direction.Axis) state.get(AXIS)) { + switch (state.get(AXIS)) { case X: return state.with(AXIS, Direction.Axis.Z); case Z: diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java new file mode 100644 index 000000000..d6f318f3f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java @@ -0,0 +1,23 @@ +package com.simibubi.create.content.contraptions.base; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import net.minecraft.tileentity.TileEntityType; + +public class ShaftlessCogInstance extends SingleRotatingInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, ShaftlessCogInstance::new); + } + + public ShaftlessCogInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected InstancedModel getModel() { + return AllBlockPartials.SHAFTLESS_COGWHEEL.renderOnRotating(modelManager, tile.getBlockState()); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java new file mode 100644 index 000000000..9e1732cd2 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java @@ -0,0 +1,55 @@ +package com.simibubi.create.content.contraptions.base; + +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstanceKey; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; + +import static com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer.KINETIC_TILE; + +public class SingleRotatingInstance extends KineticTileInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, SingleRotatingInstance::new); + } + + protected InstanceKey rotatingModelKey; + + public SingleRotatingInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + Direction.Axis axis = ((IRotate) tile.getBlockState().getBlock()).getRotationAxis(tile.getBlockState()); + rotatingModelKey = getModel().setupInstance(setupFunc(tile.getSpeed(), axis)); + } + + @Override + public void onUpdate() { + Direction.Axis axis = ((IRotate) tile.getBlockState().getBlock()).getRotationAxis(tile.getBlockState()); + updateRotation(rotatingModelKey, axis); + } + + @Override + public void updateLight() { + rotatingModelKey.modifyInstance(this::relight); + } + + @Override + public void remove() { + rotatingModelKey.delete(); + rotatingModelKey = null; + } + + protected BlockState getRenderedBlockState() { + return tile.getBlockState(); + } + + protected InstancedModel getModel() { + return rotatingMaterial().getModel(KINETIC_TILE, getRenderedBlockState()); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java new file mode 100644 index 000000000..2082919b6 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java @@ -0,0 +1,25 @@ +package com.simibubi.create.content.contraptions.components.actors; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import net.minecraft.tileentity.TileEntityType; + +public class DrillInstance extends SingleRotatingInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, DrillInstance::new); + } + + public DrillInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected InstancedModel getModel() { + return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(modelManager, tile.getBlockState()); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java index 9d2414870..e528be196 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java @@ -1,31 +1,29 @@ package com.simibubi.create.content.contraptions.components.actors; -import static net.minecraft.state.properties.BlockStateProperties.FACING; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.contraption.RenderedContraption; +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RenderMaterial; +import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.render.instancing.actors.StaticRotatingActorData; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; -import com.simibubi.create.foundation.render.instancing.InstanceContext; -import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.utility.VecHelper; - -import com.simibubi.create.foundation.render.instancing.RotatingData; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.util.Direction; +import static net.minecraft.state.properties.BlockStateProperties.FACING; + public class DrillRenderer extends KineticTileEntityRenderer { public DrillRenderer(TileEntityRendererDispatcher dispatcher) { @@ -33,7 +31,7 @@ public class DrillRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState()); } @@ -42,18 +40,19 @@ public class DrillRenderer extends KineticTileEntityRenderer { } public static void addInstanceForContraption(RenderedContraption contraption, MovementContext context) { - RenderMaterial> renderMaterial = contraption.getActorMaterial(); + RenderMaterial> renderMaterial = contraption.getActorMaterial(); BlockState state = context.state; - InstanceBuffer model = renderMaterial.getModel(AllBlockPartials.DRILL_HEAD, state); + InstancedModel model = renderMaterial.getModel(AllBlockPartials.DRILL_HEAD, state); model.setupInstance(data -> { Direction facing = state.get(DrillBlock.FACING); - float localRotationX = AngleHelper.verticalAngle(facing) + ((facing.getAxis() == Direction.Axis.Y) ? 180 : 0); + float eulerX = AngleHelper.verticalAngle(facing) + ((facing.getAxis() == Direction.Axis.Y) ? 180 : 0); + float eulerY = facing.getHorizontalAngle(); data.setPosition(context.localPos) .setRotationOffset(0) .setRotationAxis(0, 0, 1) - .setLocalRotation(localRotationX, facing.getHorizontalAngle(), 0); + .setLocalRotation(eulerX, eulerY, 0); }); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java index 29a006d6f..094ab403f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java @@ -1,20 +1,17 @@ package com.simibubi.create.content.contraptions.components.actors; -import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.contraption.RenderedContraption; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RenderMaterial; import com.simibubi.create.foundation.render.instancing.actors.StaticRotatingActorData; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; -import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.utility.VecHelper; - import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; @@ -24,6 +21,8 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; + public class HarvesterRenderer extends SafeTileEntityRenderer { public HarvesterRenderer(TileEntityRendererDispatcher dispatcher) { @@ -40,10 +39,10 @@ public class HarvesterRenderer extends SafeTileEntityRenderer> renderMaterial = contraption.getActorMaterial(); + RenderMaterial> renderMaterial = contraption.getActorMaterial(); BlockState state = context.state; - InstanceBuffer model = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state); + InstancedModel model = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state); model.setupInstance(data -> { Direction facing = state.get(HORIZONTAL_FACING); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockRenderer.java index 9b2406d28..7d8656958 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockRenderer.java @@ -6,12 +6,11 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity.Animation; -import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; -import com.simibubi.create.foundation.render.instancing.InstanceContext; import com.simibubi.create.foundation.render.SuperByteBuffer; - +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.AngleHelper; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; @@ -93,7 +92,7 @@ public class CuckooClockRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { BlockState blockState = ctx.te.getBlockState(); return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, blockState, blockState.get(CuckooClockBlock.HORIZONTAL_FACING).getOpposite()); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java index f5068e880..740b1ca59 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java @@ -1,20 +1,16 @@ package com.simibubi.create.content.contraptions.components.crafter; -import static com.simibubi.create.content.contraptions.base.HorizontalKineticBlock.HORIZONTAL_FACING; -import static com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer.standardKineticRotationTransform; - import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllSpriteShifts; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity.Phase; import com.simibubi.create.content.contraptions.components.crafter.RecipeGridHandler.GroupedItems; +import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; -import com.simibubi.create.foundation.render.SuperByteBuffer; - import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -25,11 +21,12 @@ import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.item.ItemStack; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import static com.simibubi.create.content.contraptions.base.HorizontalKineticBlock.HORIZONTAL_FACING; + public class MechanicalCrafterRenderer extends SafeTileEntityRenderer { public MechanicalCrafterRenderer(TileEntityRendererDispatcher dispatcher) { @@ -154,12 +151,12 @@ public class MechanicalCrafterRenderer extends SafeTileEntityRenderer protected void renderComponents(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid()); - KineticTileEntityRenderer.renderRotatingKineticBlock(new InstanceContext.World<>(te), getRenderedBlockState(te)); BlockState blockState = te.getBlockState(); BlockPos pos = te.getPos(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java index 4fbce8fb9..694afdf78 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java @@ -5,8 +5,8 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; @@ -35,9 +35,9 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer { Direction direction = te.getBlockState() .get(FACING); - InstanceBuffer shaftHalf = + InstancedModel shaftHalf = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite()); - InstanceBuffer fanInner = + InstancedModel fanInner = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite()); shaftHalf.setupInstance(data -> { @@ -91,9 +91,9 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer { Direction direction = te.getBlockState() .get(FACING); - InstanceBuffer shaftHalf = + InstancedModel shaftHalf = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite()); - InstanceBuffer fanInner = + InstancedModel fanInner = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite()); shaftHalf.clearInstanceData(); 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 89508a0cd..fd77e7f42 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 @@ -1,19 +1,16 @@ package com.simibubi.create.content.contraptions.components.flywheel; -import static com.simibubi.create.content.contraptions.base.HorizontalKineticBlock.HORIZONTAL_FACING; - import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; 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.utility.AngleHelper; import com.simibubi.create.foundation.render.SuperByteBuffer; - -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.AngleHelper; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; @@ -25,6 +22,8 @@ import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Rotation; import net.minecraft.util.math.MathHelper; +import static com.simibubi.create.content.contraptions.base.HorizontalKineticBlock.HORIZONTAL_FACING; + public class FlywheelRenderer extends KineticTileEntityRenderer { public FlywheelRenderer(TileEntityRendererDispatcher dispatcher) { @@ -77,7 +76,7 @@ public class FlywheelRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState(), ctx.te.getBlockState() .get(HORIZONTAL_FACING) .getOpposite()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java new file mode 100644 index 000000000..03c408569 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java @@ -0,0 +1,25 @@ +package com.simibubi.create.content.contraptions.components.millstone; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import net.minecraft.tileentity.TileEntityType; + +public class MillStoneCogInstance extends SingleRotatingInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, MillStoneCogInstance::new); + } + + public MillStoneCogInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected InstancedModel getModel() { + return AllBlockPartials.MILLSTONE_COG.renderOnRotating(modelManager, tile.getBlockState()); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java index 26316a422..7121fe9d2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java @@ -3,9 +3,8 @@ package com.simibubi.create.content.contraptions.components.millstone; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; - -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; @@ -16,7 +15,7 @@ public class MillstoneRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return AllBlockPartials.MILLSTONE_COG.renderOnRotating(ctx, ctx.te.getBlockState()); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java index b6344d5bd..fc1fc2df6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java @@ -6,8 +6,8 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.block.BlockState; @@ -57,7 +57,7 @@ public class MechanicalMixerRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return AllBlockPartials.SHAFTLESS_COGWHEEL.renderOnRotating(ctx, ctx.te.getBlockState()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java index 96d02d5b2..5d74bf9ac 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java @@ -3,9 +3,8 @@ package com.simibubi.create.content.contraptions.components.motor; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; - -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; @@ -16,7 +15,7 @@ public class CreativeMotorRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState()); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java index e35d85a0b..d357081eb 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java @@ -7,8 +7,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; @@ -136,7 +136,7 @@ public class SawRenderer extends SafeTileEntityRenderer implement } } - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { KineticTileEntity te = ctx.te; BlockState state = te.getBlockState(); if (state.get(FACING).getAxis().isHorizontal()) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java index 6c6bc65fc..bb7a8765b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java @@ -4,12 +4,11 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.render.SuperByteBuffer; - -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.AngleHelper; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; @@ -47,7 +46,7 @@ public class BearingRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { BlockState blockState = ctx.te.getBlockState(); return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, blockState, blockState.get(BearingBlock.FACING).getOpposite()); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java new file mode 100644 index 000000000..cd8558bd0 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java @@ -0,0 +1,25 @@ +package com.simibubi.create.content.contraptions.fluids; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import net.minecraft.tileentity.TileEntityType; + +public class PumpCogInstance extends SingleRotatingInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, PumpCogInstance::new); + } + + public PumpCogInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected InstancedModel getModel() { + return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(modelManager, tile.getBlockState()); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java index fed7f4b04..985a775fe 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java @@ -4,13 +4,12 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.MatrixStacker; -import com.simibubi.create.foundation.render.SuperByteBuffer; - -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; -import com.simibubi.create.foundation.render.instancing.InstanceContext; -import com.simibubi.create.foundation.render.instancing.RotatingData; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; @@ -54,7 +53,7 @@ public class PumpRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState()); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java index 5fade0d1d..5ae680b64 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java @@ -3,8 +3,8 @@ package com.simibubi.create.content.contraptions.relays.advanced; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -33,7 +33,7 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer getRotatedModel(InstanceContext ctx) { + private InstancedModel getRotatedModel(InstanceContext ctx) { return ctx.getRotating().getModel(KineticTileEntityRenderer.KINETIC_TILE, KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(ctx.te))); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java new file mode 100644 index 000000000..f76a5b502 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java @@ -0,0 +1,171 @@ +package com.simibubi.create.content.contraptions.relays.belt; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.base.KineticTileInstance; +import com.simibubi.create.foundation.block.render.SpriteShiftEntry; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.*; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.MatrixStacker; +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.LightType; + +import java.util.ArrayList; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class BeltInstance extends KineticTileInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, BeltInstance::new); + } + + private boolean upward; + private boolean diagonal; + private boolean sideways; + private boolean vertical; + private boolean alongX; + private boolean alongZ; + private BeltSlope beltSlope; + private Direction facing; + protected ArrayList> keys; + protected InstanceKey pulleyKey; + + public BeltInstance(InstancedTileRenderDispatcher modelManager, BeltTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + BlockState blockState = tile.getBlockState(); + if (!AllBlocks.BELT.has(blockState)) + return; + + keys = new ArrayList<>(2); + + beltSlope = blockState.get(BeltBlock.SLOPE); + facing = blockState.get(BeltBlock.HORIZONTAL_FACING); + upward = beltSlope == BeltSlope.UPWARD; + diagonal = beltSlope.isDiagonal(); + sideways = beltSlope == BeltSlope.SIDEWAYS; + vertical = beltSlope == BeltSlope.VERTICAL; + alongX = facing.getAxis() == Direction.Axis.X; + alongZ = facing.getAxis() == Direction.Axis.Z; + + BeltPart part = blockState.get(BeltBlock.PART); + boolean start = part == BeltPart.START; + boolean end = part == BeltPart.END; + + for (boolean bottom : Iterate.trueAndFalse) { + AllBlockPartials beltPartial = BeltRenderer.getBeltPartial(diagonal, start, end, bottom); + SpriteShiftEntry spriteShift = BeltRenderer.getSpriteShiftEntry(diagonal, bottom); + + InstancedModel beltModel = beltPartial.renderOnBelt(modelManager, blockState); + Consumer setupFunc = setupFunc(spriteShift); + + keys.add(beltModel.setupInstance(setupFunc)); + + if (diagonal) break; + } + + if (tile.hasPulley()) { + InstancedModel pulleyModel = getPulleyModel(blockState); + + pulleyKey = pulleyModel.setupInstance(setupFunc(tile.getSpeed(), getRotationAxisOf(tile))); + } + } + + @Override + public void onUpdate() { + for (InstanceKey key : keys) { + key.modifyInstance(data -> data.setRotationalSpeed(getScrollSpeed())); + } + + if (pulleyKey != null) { + updateRotation(pulleyKey, getRotationAxisOf(tile)); + } + } + + @Override + public void updateLight() { + for (InstanceKey key : keys) { + key.modifyInstance(this::relight); + } + + if (pulleyKey != null) pulleyKey.modifyInstance(this::relight); + } + + @Override + public void remove() { + keys.forEach(InstanceKey::delete); + keys.clear(); + if (pulleyKey != null) pulleyKey.delete(); + pulleyKey = null; + } + + private float getScrollSpeed() { + float speed = tile.getSpeed(); + if (((facing.getAxisDirection() == Direction.AxisDirection.NEGATIVE) ^ upward) ^ + ((alongX && !diagonal) || (alongZ && diagonal)) ^ (vertical && facing.getAxisDirection() == Direction.AxisDirection.NEGATIVE)) { + speed = -speed; + } + if (sideways && (facing == Direction.SOUTH || facing == Direction.WEST)) + speed = -speed; + + return speed; + } + + private InstancedModel getPulleyModel(BlockState blockState) { + Direction dir = getOrientation(blockState); + + Direction.Axis axis = dir.getAxis(); + + Supplier ms = () -> { + MatrixStack modelTransform = new MatrixStack(); + MatrixStacker msr = MatrixStacker.of(modelTransform); + msr.centre(); + if (axis == Direction.Axis.X) + msr.rotateY(90); + if (axis == Direction.Axis.Y) + msr.rotateX(90); + msr.rotateX(90); + msr.unCentre(); + + return modelTransform; + }; + + return rotatingMaterial().getModel(AllBlockPartials.BELT_PULLEY, blockState, dir, ms); + } + + private Direction getOrientation(BlockState blockState) { + Direction dir = blockState.get(BeltBlock.HORIZONTAL_FACING) + .rotateY(); + if (beltSlope == BeltSlope.SIDEWAYS) + dir = Direction.UP; + + return dir; + } + + private Consumer setupFunc(SpriteShiftEntry spriteShift) { + return data -> { + float rotX = (!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0) + (beltSlope == BeltSlope.DOWNWARD ? 180 : 0); + float rotY = facing.getHorizontalAngle() + (upward ? 180 : 0) + (sideways ? 90 : 0); + float rotZ = sideways ? 90 : ((vertical && facing.getAxisDirection() == Direction.AxisDirection.NEGATIVE) ? 180 : 0); + + BlockPos pos = tile.getPos(); + data.setTileEntity(tile) + .setBlockLight(tile.getWorld().getLightLevel(LightType.BLOCK, pos)) + .setSkyLight(tile.getWorld().getLightLevel(LightType.SKY, pos)) + .setRotation(rotX, rotY, rotZ) + .setRotationalSpeed(getScrollSpeed()) + .setRotationOffset(0) + .setScrollTexture(spriteShift) + .setScrollMult(diagonal ? 3f / 8f : 0.5f); + }; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java index 8e4c1bcfd..c598fe765 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java @@ -7,7 +7,6 @@ import com.simibubi.create.AllSpriteShifts; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; -import com.simibubi.create.foundation.render.FastKineticRenderer; import com.simibubi.create.foundation.render.ShadowRenderHelper; import com.simibubi.create.foundation.render.instancing.*; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; @@ -85,18 +84,10 @@ public class BeltRenderer extends SafeTileEntityRenderer impleme for (boolean bottom : Iterate.trueAndFalse) { - AllBlockPartials beltPartial = diagonal - ? start ? AllBlockPartials.BELT_DIAGONAL_START - : end ? AllBlockPartials.BELT_DIAGONAL_END : AllBlockPartials.BELT_DIAGONAL_MIDDLE - : bottom - ? start ? AllBlockPartials.BELT_START_BOTTOM - : end ? AllBlockPartials.BELT_END_BOTTOM : AllBlockPartials.BELT_MIDDLE_BOTTOM - : start ? AllBlockPartials.BELT_START - : end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE; + AllBlockPartials beltPartial = getBeltPartial(diagonal, start, end, bottom); - InstanceBuffer beltBuffer = beltPartial.renderOnBelt(ctx, blockState); - SpriteShiftEntry spriteShift = - diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT; + InstancedModel beltBuffer = beltPartial.renderOnBelt(ctx, blockState); + SpriteShiftEntry spriteShift = getSpriteShiftEntry(diagonal, bottom); beltBuffer.setupInstance(data -> { float speed = te.getSpeed(); @@ -127,11 +118,34 @@ public class BeltRenderer extends SafeTileEntityRenderer impleme } if (te.hasPulley()) { - InstanceBuffer rotatingBuffer = getPulleyModel(ctx, blockState, sideways); + InstancedModel rotatingBuffer = getPulleyModel(ctx, blockState, sideways); KineticTileEntityRenderer.renderRotatingBuffer(ctx, rotatingBuffer); } } + public static SpriteShiftEntry getSpriteShiftEntry(boolean diagonal, boolean bottom) { + if (diagonal) return AllSpriteShifts.BELT_DIAGONAL; + if (bottom) return AllSpriteShifts.BELT_OFFSET; + return AllSpriteShifts.BELT; + } + + public static AllBlockPartials getBeltPartial(boolean diagonal, boolean start, boolean end, boolean bottom) { + if (diagonal) { + if (start) return AllBlockPartials.BELT_DIAGONAL_START; + if (end) return AllBlockPartials.BELT_DIAGONAL_END; + return AllBlockPartials.BELT_DIAGONAL_MIDDLE; + } else { + if (bottom) { + if (start) return AllBlockPartials.BELT_START_BOTTOM; + if (end) return AllBlockPartials.BELT_END_BOTTOM; + return AllBlockPartials.BELT_MIDDLE_BOTTOM; + } + if (start) return AllBlockPartials.BELT_START; + if (end) return AllBlockPartials.BELT_END; + return AllBlockPartials.BELT_MIDDLE; + } + } + @Override public void markForRebuild(InstanceContext ctx) { BeltTileEntity te = ctx.te; @@ -161,16 +175,9 @@ public class BeltRenderer extends SafeTileEntityRenderer impleme for (boolean bottom : Iterate.trueAndFalse) { - AllBlockPartials beltPartial = diagonal - ? start ? AllBlockPartials.BELT_DIAGONAL_START - : end ? AllBlockPartials.BELT_DIAGONAL_END : AllBlockPartials.BELT_DIAGONAL_MIDDLE - : bottom - ? start ? AllBlockPartials.BELT_START_BOTTOM - : end ? AllBlockPartials.BELT_END_BOTTOM : AllBlockPartials.BELT_MIDDLE_BOTTOM - : start ? AllBlockPartials.BELT_START - : end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE; + AllBlockPartials beltPartial = getBeltPartial(diagonal, start, end, bottom); - InstanceBuffer beltBuffer = beltPartial.renderOnBelt(ctx, blockState); + InstancedModel beltBuffer = beltPartial.renderOnBelt(ctx, blockState); beltBuffer.clearInstanceData(); @@ -179,12 +186,12 @@ public class BeltRenderer extends SafeTileEntityRenderer impleme break; } - InstanceBuffer rotatingBuffer = getPulleyModel(ctx, blockState, sideways); + InstancedModel rotatingBuffer = getPulleyModel(ctx, blockState, sideways); rotatingBuffer.clearInstanceData(); } - private InstanceBuffer getPulleyModel(InstanceContext ctx, BlockState blockState, boolean sideways) { + private InstancedModel getPulleyModel(InstanceContext ctx, BlockState blockState, boolean sideways) { Direction dir = blockState.get(BeltBlock.HORIZONTAL_FACING) .rotateY(); if (sideways) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltSlope.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltSlope.java index 8f934e10f..ab6cf32a8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltSlope.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltSlope.java @@ -1,7 +1,6 @@ package com.simibubi.create.content.contraptions.relays.belt; import com.simibubi.create.foundation.utility.Lang; - import net.minecraft.util.IStringSerializable; public enum BeltSlope implements IStringSerializable { @@ -11,4 +10,8 @@ public enum BeltSlope implements IStringSerializable { public String getName() { return Lang.asId(name()); } + + public boolean isDiagonal() { + return this == UPWARD || this == DOWNWARD; + } } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SingleRotatingShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SingleRotatingShaftInstance.java new file mode 100644 index 000000000..89a661795 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SingleRotatingShaftInstance.java @@ -0,0 +1,25 @@ +package com.simibubi.create.content.contraptions.relays.encased; + +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntityType; + +public class SingleRotatingShaftInstance extends SingleRotatingInstance { + + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, SingleRotatingShaftInstance::new); + } + + public SingleRotatingShaftInstance(InstancedTileRenderDispatcher dispatcher, KineticTileEntity tile) { + super(dispatcher, tile); + } + + @Override + protected BlockState getRenderedBlockState() { + return shaft(getRotationAxisOf(tile)); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java new file mode 100644 index 000000000..077b9b091 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -0,0 +1,87 @@ +package com.simibubi.create.content.contraptions.relays.encased; + +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.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstanceKey; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.Iterate; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; + +import java.util.ArrayList; + +public class SplitShaftInstance extends KineticTileInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, SplitShaftInstance::new); + } + + protected ArrayList> keys; + + public SplitShaftInstance(InstancedTileRenderDispatcher modelManager, SplitShaftTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + keys = new ArrayList<>(2); + + BlockState state = tile.getBlockState(); + Block block = state.getBlock(); + final Direction.Axis boxAxis = ((IRotate) block).getRotationAxis(state); + + float speed = tile.getSpeed(); + + for (Direction dir : Iterate.directionsInAxis(boxAxis)) { + + InstancedModel half = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, state, dir); + + float splitSpeed = speed * tile.getRotationSpeedModifier(dir); + + keys.add(half.setupInstance(setupFunc(splitSpeed, boxAxis))); + } + } + + @Override + public void onUpdate() { + BlockState state = tile.getBlockState(); + Block block = state.getBlock(); + final Direction.Axis boxAxis = ((IRotate) block).getRotationAxis(state); + + Direction[] directions = Iterate.directionsInAxis(boxAxis); + + for (int i : Iterate.zeroAndOne) { + updateRotation(keys.get(i), directions[i]); + } + } + + @Override + public void updateLight() { + for (InstanceKey key : keys) { + key.modifyInstance(this::relight); + } + } + + @Override + public void remove() { + keys.forEach(InstanceKey::delete); + keys.clear(); + } + + protected void updateRotation(InstanceKey key, Direction dir) { + key.modifyInstance(data -> { + Direction.Axis axis = dir.getAxis(); + final BlockPos pos = tile.getPos(); + + data.setRotationalSpeed(tile.getSpeed() * tile.getRotationSpeedModifier(dir)) + .setRotationOffset(getRotationOffsetForPosition(tile, pos, axis)) + .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()); + }); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java index cf0affbfc..4e41c84f3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java @@ -5,8 +5,8 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.Block; @@ -52,7 +52,7 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer { if (boxAxis != axis) continue; - InstanceBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); + InstancedModel shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); shaft.setupInstance(data -> { float speed = te.getSpeed(); @@ -84,7 +84,7 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer { Axis axis = direction.getAxis(); if (boxAxis != axis) continue; - InstanceBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); + InstancedModel shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); shaft.clearInstanceData(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java new file mode 100644 index 000000000..58a259be2 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -0,0 +1,121 @@ +package com.simibubi.create.content.contraptions.relays.gearbox; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileInstance; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstanceKey; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.Iterate; +import net.minecraft.block.BlockState; +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 java.util.EnumMap; +import java.util.Map; + +public class GearboxInstance extends KineticTileInstance { + public static void register(TileEntityType type) { + InstancedTileRenderRegistry.instance.register(type, GearboxInstance::new); + } + + protected EnumMap> keys; + protected Direction sourceFacing; + + public GearboxInstance(InstancedTileRenderDispatcher modelManager, GearboxTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + keys = new EnumMap<>(Direction.class); + + BlockState state = tile.getBlockState(); + + final Direction.Axis boxAxis = state.get(BlockStateProperties.AXIS); + + BlockPos pos = tile.getPos(); + int blockLight = tile.getWorld().getLightLevel(LightType.BLOCK, pos); + int skyLight = tile.getWorld().getLightLevel(LightType.SKY, pos); + updateSourceFacing(); + + for (Direction direction : Iterate.directions) { + final Direction.Axis axis = direction.getAxis(); + if (boxAxis == axis) + continue; + + InstancedModel shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, state, direction); + + InstanceKey key = shaft.setupInstance(data -> { + data.setBlockLight(blockLight) + .setSkyLight(skyLight) + .setRotationalSpeed(getSpeed(direction)) + .setRotationOffset(getRotationOffsetForPosition(tile, pos, axis)) + .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) + .setTileEntity(tile); + }); + keys.put(direction, key); + } + } + + private float getSpeed(Direction direction) { + float speed = tile.getSpeed(); + + if (speed != 0 && sourceFacing != null) { + if (sourceFacing.getAxis() == direction.getAxis()) + speed *= sourceFacing == direction ? 1 : -1; + else if (sourceFacing.getAxisDirection() == direction.getAxisDirection()) + speed *= -1; + } + return speed; + } + + protected void updateSourceFacing() { + if (tile.hasSource()) { + BlockPos source = tile.source.subtract(tile.getPos()); + sourceFacing = Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ()); + } else { + sourceFacing = null; + } + } + + @Override + public void onUpdate() { + updateSourceFacing(); + BlockPos pos = tile.getPos(); + for (Map.Entry> key : keys.entrySet()) { + key.getValue().modifyInstance(data -> { + Direction direction = key.getKey(); + Direction.Axis axis = direction.getAxis(); + + data.setRotationalSpeed(getSpeed(direction)) + .setRotationOffset(getRotationOffsetForPosition(tile, pos, axis)) + .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()); + }); + } + } + + @Override + public void updateLight() { + BlockPos pos = tile.getPos(); + int blockLight = tile.getWorld().getLightLevel(LightType.BLOCK, pos); + int skyLight = tile.getWorld().getLightLevel(LightType.SKY, pos); + + for (InstanceKey key : keys.values()) { + key.modifyInstance(data -> data.setBlockLight(blockLight).setSkyLight(skyLight)); + } + } + + @Override + public void remove() { + for (InstanceKey key : keys.values()) { + key.delete(); + } + + keys.clear(); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java index 0a01c1bd6..87e6c6708 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java @@ -5,8 +5,8 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Pair; @@ -48,7 +48,7 @@ public class GearboxRenderer extends KineticTileEntityRenderer { skyLight = 0; } - for (Pair> shaft : getBuffers(ctx)) { + for (Pair> shaft : getBuffers(ctx)) { shaft.getSecond().setupInstance(data -> { float speed = te.getSpeed(); Direction direction = shaft.getFirst(); @@ -75,22 +75,22 @@ public class GearboxRenderer extends KineticTileEntityRenderer { @Override public void markForRebuild(InstanceContext ctx) { - getBuffers(ctx).stream().map(Pair::getSecond).forEach(InstanceBuffer::clearInstanceData); + getBuffers(ctx).stream().map(Pair::getSecond).forEach(InstancedModel::clearInstanceData); } - private List>> getBuffers(InstanceContext ctx) { + private List>> getBuffers(InstanceContext ctx) { KineticTileEntity te = ctx.te; final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS); - List>> buffers = Lists.newArrayListWithCapacity(4); + List>> buffers = Lists.newArrayListWithCapacity(4); for (Direction direction : Iterate.directions) { final Axis axis = direction.getAxis(); if (boxAxis == axis) continue; - InstanceBuffer buffer = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); - Pair> pair = Pair.of(direction, buffer); + InstancedModel buffer = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); + Pair> pair = Pair.of(direction, buffer); buffers.add(pair); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java new file mode 100644 index 000000000..0d931d6c1 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java @@ -0,0 +1,19 @@ +package com.simibubi.create.content.logistics.block.mechanicalArm; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.InstancedModel; +import com.simibubi.create.foundation.render.instancing.RotatingData; + +public class ArmInstance extends SingleRotatingInstance { + public ArmInstance(InstancedTileRenderDispatcher modelManager, KineticTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected InstancedModel getModel() { + return AllBlockPartials.ARM_COG.renderOnRotating(modelManager, tile.getBlockState()); + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java index 71b7224f1..4e2b715d9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java @@ -6,12 +6,14 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase; -import com.simibubi.create.foundation.utility.*; - import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -123,7 +125,7 @@ public class ArmRenderer extends KineticTileEntityRenderer { } @Override - protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + protected InstancedModel getRotatedModel(InstanceContext ctx) { return AllBlockPartials.ARM_COG.renderOnRotating(ctx, ctx.te.getBlockState()); } diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 8abe10395..d0bd82064 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -27,7 +27,6 @@ import com.simibubi.create.foundation.networking.LeftClickPacket; import com.simibubi.create.foundation.render.FastRenderDispatcher; import com.simibubi.create.foundation.render.RenderWork; import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher; -import com.simibubi.create.foundation.render.light.LightVolumeDebugger; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionRenderer; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer; @@ -79,6 +78,7 @@ public class ClientEvents { return; AnimationTickHolder.tick(); + FastRenderDispatcher.tick(); CreateClient.schematicSender.tick(); CreateClient.schematicAndQuillHandler.tick(); diff --git a/src/main/java/com/simibubi/create/foundation/mixin/OnRemoveTileMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/OnRemoveTileMixin.java deleted file mode 100644 index 5fe04753a..000000000 --- a/src/main/java/com/simibubi/create/foundation/mixin/OnRemoveTileMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.simibubi.create.foundation.mixin; - -import com.simibubi.create.foundation.render.FastRenderDispatcher; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -@OnlyIn(Dist.CLIENT) -@Mixin(World.class) -public class OnRemoveTileMixin { - - @Shadow @Final public boolean isRemote; - - /** - * JUSTIFICATION: This method is called whenever a tile entity is removed due - * to a change in block state, even on the client. By hooking into this method, - * we gain easy access to the information while having no impact on performance. - */ - @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD) - private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) { - if (isRemote) FastRenderDispatcher.markForRebuild(te); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/GPUBuffer.java b/src/main/java/com/simibubi/create/foundation/render/BufferedModel.java similarity index 95% rename from src/main/java/com/simibubi/create/foundation/render/GPUBuffer.java rename to src/main/java/com/simibubi/create/foundation/render/BufferedModel.java index 8f1b845d6..585ec2c0b 100644 --- a/src/main/java/com/simibubi/create/foundation/render/GPUBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/BufferedModel.java @@ -9,7 +9,7 @@ import org.lwjgl.opengl.GL40; import java.nio.ByteBuffer; -public abstract class GPUBuffer extends TemplateBuffer { +public abstract class BufferedModel extends TemplateBuffer { protected GlVertexArray vao; @@ -17,7 +17,7 @@ public abstract class GPUBuffer extends TemplateBuffer { protected GlBuffer invariantVBO; protected boolean removed; - public GPUBuffer(BufferBuilder buf) { + public BufferedModel(BufferBuilder buf) { super(buf); if (vertexCount > 0) setup(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java index 8ce6ef538..20386c6f3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java @@ -4,11 +4,10 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher; -import com.simibubi.create.foundation.render.instancing.IInstanceRendered; -import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceContext; -import com.simibubi.create.foundation.render.shader.ShaderHelper; +import com.simibubi.create.foundation.render.gl.shader.ShaderHelper; +import com.simibubi.create.foundation.render.light.ILightListener; import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.WorldAttached; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.multiplayer.ClientChunkProvider; @@ -16,8 +15,7 @@ import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Vector3f; -import net.minecraft.client.renderer.tileentity.TileEntityRenderer; -import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.client.world.ClientWorld; import net.minecraft.potion.Effects; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.MathHelper; @@ -28,15 +26,51 @@ import net.minecraft.world.chunk.Chunk; import org.lwjgl.opengl.GL11; import java.util.Map; +import java.util.concurrent.ConcurrentLinkedQueue; public class FastRenderDispatcher { + public static WorldAttached> addedTiles = new WorldAttached<>(ConcurrentLinkedQueue::new); + public static WorldAttached> removedTiles = new WorldAttached<>(ConcurrentLinkedQueue::new); + private static Matrix4f projectionMatrixThisFrame = null; public static void endFrame() { projectionMatrixThisFrame = null; } + public static void enqueueUpdate(TileEntity te) { + addedTiles.get(te.getWorld()).add(te); + } + + public static void enqueueRemove(TileEntity te) { + removedTiles.get(te.getWorld()).add(te); + } + + public static void tick() { + ClientWorld world = Minecraft.getInstance().world; + + ConcurrentLinkedQueue added = addedTiles.get(world); + + if (added != null) { + while (!added.isEmpty()) { + TileEntity te = added.poll(); + + CreateClient.kineticRenderer.update(te); + } + } + + ConcurrentLinkedQueue removed = removedTiles.get(world); + + if (removed != null) { + while (!removed.isEmpty()) { + TileEntity te = removed.poll(); + + CreateClient.kineticRenderer.remove(te); + } + } + } + public static void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ) { Matrix4f view = Matrix4f.translate((float) -cameraX, (float) -cameraY, (float) -cameraZ); view.multiplyBackward(stack.peek().getModel()); @@ -69,25 +103,12 @@ public class FastRenderDispatcher { .stream() .filter(entry -> SectionPos.toChunk(entry.getKey().getY()) == sectionY) .map(Map.Entry::getValue) - .forEach(FastRenderDispatcher::markForRebuild); + .filter(tile -> tile instanceof ILightListener) + .map(tile -> (ILightListener) tile) + .forEach(ILightListener::onChunkLightUpdate); } } - public static void markForRebuild(TileEntity te) { - if (te instanceof IInstanceRendered) { - TileEntityRenderer renderer = TileEntityRendererDispatcher.instance.getRenderer(te); - - if (renderer instanceof IInstancedTileEntityRenderer) { - markForRebuild(te, (IInstancedTileEntityRenderer) renderer); - } - } - } - - private static void markForRebuild(T te, IInstancedTileEntityRenderer renderer) { - CreateClient.kineticRenderer.dirty = true; - renderer.markForRebuild(new InstanceContext.World<>(te)); - } - // copied from GameRenderer.renderWorld private static Matrix4f getProjectionMatrix() { if (projectionMatrixThisFrame != null) return projectionMatrixThisFrame; diff --git a/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java b/src/main/java/com/simibubi/create/foundation/render/InstancedTileRenderDispatcher.java similarity index 51% rename from src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java rename to src/main/java/com/simibubi/create/foundation/render/InstancedTileRenderDispatcher.java index 85a020d00..b1eb363e3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/InstancedTileRenderDispatcher.java @@ -1,59 +1,78 @@ package com.simibubi.create.foundation.render; import com.simibubi.create.foundation.render.contraption.RenderedContraption; +import com.simibubi.create.foundation.render.gl.shader.Shader; +import com.simibubi.create.foundation.render.gl.shader.ShaderCallback; +import com.simibubi.create.foundation.render.gl.shader.ShaderHelper; import com.simibubi.create.foundation.render.instancing.*; -import com.simibubi.create.foundation.render.shader.Shader; -import com.simibubi.create.foundation.render.shader.ShaderCallback; -import com.simibubi.create.foundation.render.shader.ShaderHelper; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.*; -import net.minecraft.client.renderer.tileentity.TileEntityRenderer; -import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.client.renderer.Matrix4f; +import net.minecraft.client.renderer.RenderType; import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; +import javax.annotation.Nullable; import java.util.HashMap; -import java.util.List; import java.util.Map; -public class FastKineticRenderer { +public class InstancedTileRenderDispatcher { + protected Map> renderers = new HashMap<>(); + protected Map, RenderMaterial> materials = new HashMap<>(); - public boolean dirty = false; - - public FastKineticRenderer() { + public InstancedTileRenderDispatcher() { registerMaterials(); } public void registerMaterials() { - materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.BELT, BeltBuffer::new)); - materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.ROTATING, RotatingBuffer::new)); + materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.BELT, BeltModel::new)); + materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.ROTATING, RotatingModel::new)); } @SuppressWarnings("unchecked") - public > RenderMaterial get(MaterialType materialType) { + public > RenderMaterial get(MaterialType materialType) { return (RenderMaterial) materials.get(materialType); } @SuppressWarnings("unchecked") - public void buildTileEntityBuffers(World world) { - List tileEntities = world.loadedTileEntityList; + @Nullable + public TileEntityInstance getRenderer(T tile) { + if (renderers.containsKey(tile)) { + return (TileEntityInstance) renderers.get(tile); + } else { + TileEntityInstance renderer = InstancedTileRenderRegistry.instance.create(this, tile); - if (!tileEntities.isEmpty()) { - for (TileEntity te : tileEntities) { - if (te instanceof IInstanceRendered) { - TileEntityRenderer renderer = TileEntityRendererDispatcher.instance.getRenderer(te); + renderers.put(tile, renderer); - if (renderer instanceof IInstancedTileEntityRenderer) { - addInstancedData(te, (IInstancedTileEntityRenderer) renderer); - } - } - } + return renderer; } } - public void addInstancedData(T te, IInstancedTileEntityRenderer renderer) { - renderer.addInstanceData(new InstanceContext.World<>(te)); + public void onLightUpdate(T tile) { + if (tile instanceof IInstanceRendered) { + TileEntityInstance renderer = getRenderer(tile); + + if (renderer != null) + renderer.updateLight(); + } + } + + public void update(T tile) { + if (tile instanceof IInstanceRendered) { + TileEntityInstance renderer = getRenderer(tile); + + if (renderer != null) + renderer.update(); + } + } + + public void remove(T tile) { + if (tile instanceof IInstanceRendered) { + TileEntityInstance renderer = getRenderer(tile); + + if (renderer != null) { + renderer.remove(); + renderers.remove(tile); + } + } } public void addInstancedData(RenderedContraption c, T te, IInstancedTileEntityRenderer renderer) { @@ -67,7 +86,7 @@ public class FastKineticRenderer { */ public void markAllDirty() { for (RenderMaterial material : materials.values()) { - material.runOnAll(InstanceBuffer::markDirty); + material.runOnAll(InstancedModel::markDirty); } } @@ -75,25 +94,13 @@ public class FastKineticRenderer { for (RenderMaterial material : materials.values()) { material.delete(); } - dirty = true; } public void render(RenderType layer, Matrix4f projection, Matrix4f view) { render(layer, projection, view, null); } - protected void prepareFrame() { - if (dirty) { - buildTileEntityBuffers(Minecraft.getInstance().world); - markAllDirty(); - - dirty = false; - } - } - public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback callback) { - prepareFrame(); - for (RenderMaterial material : materials.values()) { if (material.canRenderInLayer(layer)) material.render(layer, projection, view, callback); diff --git a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionKineticRenderer.java index 215180d86..f5761bedd 100644 --- a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionKineticRenderer.java @@ -1,22 +1,19 @@ package com.simibubi.create.foundation.render.contraption; -import com.simibubi.create.foundation.render.FastKineticRenderer; -import com.simibubi.create.foundation.render.instancing.BeltBuffer; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import com.simibubi.create.foundation.render.gl.shader.Shader; +import com.simibubi.create.foundation.render.instancing.BeltModel; import com.simibubi.create.foundation.render.instancing.KineticRenderMaterials; import com.simibubi.create.foundation.render.instancing.RenderMaterial; -import com.simibubi.create.foundation.render.instancing.RotatingBuffer; -import com.simibubi.create.foundation.render.instancing.actors.RotatingActorBuffer; -import com.simibubi.create.foundation.render.shader.Shader; +import com.simibubi.create.foundation.render.instancing.RotatingModel; +import com.simibubi.create.foundation.render.instancing.actors.RotatingActorModel; -public class ContraptionKineticRenderer extends FastKineticRenderer { +public class ContraptionKineticRenderer extends InstancedTileRenderDispatcher { @Override public void registerMaterials() { - materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.CONTRAPTION_BELT, BeltBuffer::new)); - materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.CONTRAPTION_ROTATING, RotatingBuffer::new)); - materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(Shader.CONTRAPTION_ACTOR, RotatingActorBuffer::new)); + materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.CONTRAPTION_BELT, BeltModel::new)); + materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.CONTRAPTION_ROTATING, RotatingModel::new)); + materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(Shader.CONTRAPTION_ACTOR, RotatingActorModel::new)); } - - @Override - protected void prepareFrame() {} } diff --git a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionBuffer.java b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionModel.java similarity index 81% rename from src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionBuffer.java rename to src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionModel.java index d9d59f0e9..2d778b389 100644 --- a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionModel.java @@ -1,20 +1,20 @@ package com.simibubi.create.foundation.render.contraption; -import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.foundation.render.GPUBuffer; -import com.simibubi.create.foundation.render.instancing.InstanceBuffer; +import com.simibubi.create.foundation.render.BufferedModel; +import com.simibubi.create.foundation.render.instancing.InstancedModel; import com.simibubi.create.foundation.render.instancing.VertexFormat; import net.minecraft.client.renderer.BufferBuilder; -import org.lwjgl.opengl.*; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL40; import java.nio.ByteBuffer; -import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; +import static com.simibubi.create.foundation.render.instancing.VertexAttribute.RGBA; -public class ContraptionBuffer extends GPUBuffer { - public static final VertexFormat FORMAT = new VertexFormat(InstanceBuffer.FORMAT, RGBA); +public class ContraptionModel extends BufferedModel { + public static final VertexFormat FORMAT = new VertexFormat(InstancedModel.FORMAT, RGBA); - public ContraptionBuffer(BufferBuilder buf) { + public ContraptionModel(BufferBuilder buf) { super(buf); } diff --git a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java index 8e85c187e..7ff467501 100644 --- a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java @@ -5,9 +5,9 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Abs import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler; -import com.simibubi.create.foundation.render.shader.Shader; -import com.simibubi.create.foundation.render.shader.ShaderCallback; -import com.simibubi.create.foundation.render.shader.ShaderHelper; +import com.simibubi.create.foundation.render.gl.shader.Shader; +import com.simibubi.create.foundation.render.gl.shader.ShaderCallback; +import com.simibubi.create.foundation.render.gl.shader.ShaderHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Matrix4f; diff --git a/src/main/java/com/simibubi/create/foundation/render/contraption/RenderedContraption.java b/src/main/java/com/simibubi/create/foundation/render/contraption/RenderedContraption.java index b36430fc3..aac348e79 100644 --- a/src/main/java/com/simibubi/create/foundation/render/contraption/RenderedContraption.java +++ b/src/main/java/com/simibubi/create/foundation/render/contraption/RenderedContraption.java @@ -6,10 +6,10 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.render.gl.shader.ShaderHelper; import com.simibubi.create.foundation.render.instancing.*; import com.simibubi.create.foundation.render.instancing.actors.StaticRotatingActorData; import com.simibubi.create.foundation.render.light.ContraptionLighter; -import com.simibubi.create.foundation.render.shader.ShaderHelper; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.RenderType; @@ -26,7 +26,7 @@ import java.util.HashMap; import java.util.List; public class RenderedContraption { - private HashMap renderLayers = new HashMap<>(); + private HashMap renderLayers = new HashMap<>(); private final ContraptionLighter lighter; @@ -59,12 +59,12 @@ public class RenderedContraption { return lighter; } - public RenderMaterial> getActorMaterial() { + public RenderMaterial> getActorMaterial() { return kinetics.get(KineticRenderMaterials.ACTORS); } public void doRenderLayer(RenderType layer, int shader) { - ContraptionBuffer buffer = renderLayers.get(layer); + ContraptionModel buffer = renderLayers.get(layer); if (buffer != null) { setup(shader); buffer.render(); @@ -73,7 +73,7 @@ public class RenderedContraption { } private void buildLayers(Contraption c) { - for (ContraptionBuffer buffer : renderLayers.values()) { + for (ContraptionModel buffer : renderLayers.values()) { buffer.delete(); } @@ -153,7 +153,7 @@ public class RenderedContraption { } void invalidate() { - for (ContraptionBuffer buffer : renderLayers.values()) { + for (ContraptionModel buffer : renderLayers.values()) { buffer.delete(); } renderLayers.clear(); @@ -163,8 +163,8 @@ public class RenderedContraption { kinetics.invalidate(); } - private static ContraptionBuffer buildStructureBuffer(Contraption c, RenderType layer) { + private static ContraptionModel buildStructureBuffer(Contraption c, RenderType layer) { BufferBuilder builder = ContraptionRenderer.buildStructure(c, layer); - return new ContraptionBuffer(builder); + return new ContraptionModel(builder); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/shader/Shader.java b/src/main/java/com/simibubi/create/foundation/render/gl/shader/Shader.java similarity index 91% rename from src/main/java/com/simibubi/create/foundation/render/shader/Shader.java rename to src/main/java/com/simibubi/create/foundation/render/gl/shader/Shader.java index 075b963b5..3ada3d9b3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/shader/Shader.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/shader/Shader.java @@ -1,4 +1,4 @@ -package com.simibubi.create.foundation.render.shader; +package com.simibubi.create.foundation.render.gl.shader; public enum Shader { ROTATING("shader/rotating.vert", "shader/instanced.frag"), diff --git a/src/main/java/com/simibubi/create/foundation/render/shader/ShaderCallback.java b/src/main/java/com/simibubi/create/foundation/render/gl/shader/ShaderCallback.java similarity index 84% rename from src/main/java/com/simibubi/create/foundation/render/shader/ShaderCallback.java rename to src/main/java/com/simibubi/create/foundation/render/gl/shader/ShaderCallback.java index 4c950f355..d894b70b2 100644 --- a/src/main/java/com/simibubi/create/foundation/render/shader/ShaderCallback.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/shader/ShaderCallback.java @@ -1,4 +1,4 @@ -package com.simibubi.create.foundation.render.shader; +package com.simibubi.create.foundation.render.gl.shader; /** * A Callback for when a shader is called. Used to define shader uniforms. diff --git a/src/main/java/com/simibubi/create/foundation/render/shader/ShaderHelper.java b/src/main/java/com/simibubi/create/foundation/render/gl/shader/ShaderHelper.java similarity index 98% rename from src/main/java/com/simibubi/create/foundation/render/shader/ShaderHelper.java rename to src/main/java/com/simibubi/create/foundation/render/gl/shader/ShaderHelper.java index e0f915231..817efb853 100644 --- a/src/main/java/com/simibubi/create/foundation/render/shader/ShaderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/shader/ShaderHelper.java @@ -1,4 +1,4 @@ -package com.simibubi.create.foundation.render.shader; +package com.simibubi.create.foundation.render.gl.shader; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.Create; @@ -11,7 +11,6 @@ import net.minecraft.client.shader.ShaderLinkHelper; import net.minecraft.client.shader.ShaderLoader; import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.resources.IResourceManager; -import net.minecraft.resources.IResourceManagerReloadListener; import net.minecraft.util.ResourceLocation; import net.minecraftforge.resource.ISelectiveResourceReloadListener; import net.minecraftforge.resource.VanillaResourceType; diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/BasicData.java b/src/main/java/com/simibubi/create/foundation/render/instancing/BasicData.java deleted file mode 100644 index d2d6bc94c..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/BasicData.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.simibubi.create.foundation.render.instancing; - -import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.foundation.utility.ColorHelper; -import net.minecraft.client.renderer.Vector3f; -import net.minecraft.util.math.BlockPos; - -import java.nio.ByteBuffer; - -import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; - -public class BasicData> extends InstanceData { - public static final VertexFormat FORMAT = new VertexFormat(RGB, POSITION, LIGHT); - - private byte r; - private byte g; - private byte b; - private float x; - private float y; - private float z; - private byte blockLight; - private byte skyLight; - - public D setBlockLight(int blockLight) { - this.blockLight = (byte) ((blockLight & 0xF) << 4); - return (D) this; - } - - public D setSkyLight(int skyLight) { - this.skyLight = (byte) ((skyLight & 0xF) << 4); - return (D) this; - } - - public D setPosition(Vector3f pos) { - this.x = pos.getX(); - this.y = pos.getY(); - this.z = pos.getZ(); - return (D) this; - } - - public D setTileEntity(KineticTileEntity te) { - setPosition(te.getPos()); - if (te.hasSource()) { - int color = ColorHelper.colorFromLong(te.network); - r = (byte) ((color >> 16) & 0xFF); - g = (byte) ((color >> 8) & 0xFF); - b = (byte) (color & 0xFF); - } - else { - r = (byte) 0xFF; - g = (byte) 0xFF; - b = (byte) 0x00; - } - return (D) this; - } - - public D setPosition(BlockPos pos) { - this.x = pos.getX(); - this.y = pos.getY(); - this.z = pos.getZ(); - return (D) this; - } - - @Override - public void write(ByteBuffer buf) { - putVec3(buf, r, g, b); - - putVec3(buf, x, y, z); - - putVec2(buf, blockLight, skyLight); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java b/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java index b103a282e..86c686157 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java @@ -2,25 +2,28 @@ package com.simibubi.create.foundation.render.instancing; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormatElement; import java.nio.ByteBuffer; import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; -public class BeltData extends BasicData { - public static VertexFormat FORMAT = new VertexFormat(BasicData.FORMAT, VEC3, FLOAT, VEC2, VEC4, FLOAT); +public class BeltData extends KineticData { + public static final VertexAttribute TARGET_UV = copy("scrollTexture", VEC4); + public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", VertexFormatElement.Type.BYTE, 1, true); + + public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, ROTATION, UV, TARGET_UV, SCROLL_MULT); private float rotX; private float rotY; private float rotZ; - private float rotationalSpeed; private float sourceU; private float sourceV; private float minU; private float minV; private float maxU; private float maxV; - private float scrollMult; + private byte scrollMult; public BeltData setRotation(float rotX, float rotY, float rotZ) { this.rotX = rotX; @@ -29,10 +32,6 @@ public class BeltData extends BasicData { return this; } - public BeltData setRotationalSpeed(float rotationalSpeed) { - this.rotationalSpeed = rotationalSpeed; - return this; - } public BeltData setScrollTexture(SpriteShiftEntry spriteShift) { TextureAtlasSprite source = spriteShift.getOriginal(); @@ -49,7 +48,7 @@ public class BeltData extends BasicData { } public BeltData setScrollMult(float scrollMult) { - this.scrollMult = scrollMult; + this.scrollMult = (byte) (scrollMult * 127); return this; } @@ -59,8 +58,6 @@ public class BeltData extends BasicData { putVec3(buf, rotX, rotY, rotZ); - put(buf, rotationalSpeed); - putVec2(buf, sourceU, sourceV); putVec4(buf, minU, minV, maxU, maxV); diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/BeltBuffer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/BeltModel.java similarity index 76% rename from src/main/java/com/simibubi/create/foundation/render/instancing/BeltBuffer.java rename to src/main/java/com/simibubi/create/foundation/render/instancing/BeltModel.java index 7007d30ec..d323101a4 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/BeltBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/BeltModel.java @@ -2,8 +2,8 @@ package com.simibubi.create.foundation.render.instancing; import net.minecraft.client.renderer.BufferBuilder; -public class BeltBuffer extends InstanceBuffer { - public BeltBuffer(BufferBuilder buf) { +public class BeltModel extends InstancedModel { + public BeltModel(BufferBuilder buf) { super(buf); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstanceBuffer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstancedModel.java similarity index 81% rename from src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstanceBuffer.java rename to src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstancedModel.java index 540ec55e4..ebe8844e2 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstanceBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstancedModel.java @@ -2,15 +2,14 @@ package com.simibubi.create.foundation.render.instancing; import com.simibubi.create.foundation.render.gl.GlBuffer; import net.minecraft.client.renderer.BufferBuilder; -import org.lwjgl.opengl.*; -public abstract class DynamicInstanceBuffer extends InstanceBuffer { +public abstract class DynamicInstancedModel extends InstancedModel { protected GlBuffer dynamicVBO; protected int dynamicBufferSize = -1; - public DynamicInstanceBuffer(BufferBuilder buf) { + public DynamicInstancedModel(BufferBuilder buf) { super(buf); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java b/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java index e169de311..f83e47001 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java @@ -1,6 +1,8 @@ package com.simibubi.create.foundation.render.instancing; -public interface IInstanceRendered { +import com.simibubi.create.foundation.render.light.ILightListener; + +public interface IInstanceRendered extends ILightListener { default boolean shouldRenderAsTE() { return false; } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/IRendererFactory.java b/src/main/java/com/simibubi/create/foundation/render/instancing/IRendererFactory.java new file mode 100644 index 000000000..2ad3a86bd --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/IRendererFactory.java @@ -0,0 +1,9 @@ +package com.simibubi.create.foundation.render.instancing; + +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import net.minecraft.tileentity.TileEntity; + +@FunctionalInterface +public interface IRendererFactory { + TileEntityInstance create(InstancedTileRenderDispatcher manager, T te); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceBuffer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceBuffer.java deleted file mode 100644 index 6baa5ada4..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceBuffer.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.simibubi.create.foundation.render.instancing; - - -import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.foundation.render.GPUBuffer; -import com.simibubi.create.foundation.render.RenderMath; -import com.simibubi.create.foundation.render.RenderWork; -import com.simibubi.create.foundation.render.TemplateBuffer; -import com.simibubi.create.foundation.render.gl.GlBuffer; -import net.minecraft.client.renderer.BufferBuilder; -import org.lwjgl.opengl.*; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.function.Consumer; - -import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; - -public abstract class InstanceBuffer extends GPUBuffer { - public static final VertexFormat FORMAT = new VertexFormat(POSITION, NORMAL, UV); - - protected GlBuffer instanceVBO; - protected int instanceCount; - - protected int instanceBufferSize = -1; - - protected final ArrayList data = new ArrayList<>(); - protected boolean rebuffer = false; - protected boolean shouldBuild = true; - - public InstanceBuffer(BufferBuilder buf) { - super(buf); - } - - @Override - protected void setup() { - super.setup(); - instanceVBO = new GlBuffer(); - } - - @Override - protected VertexFormat getModelFormat() { - return FORMAT; - } - - @Override - protected void copyVertex(ByteBuffer constant, int i) { - constant.putFloat(getX(template, i)); - constant.putFloat(getY(template, i)); - constant.putFloat(getZ(template, i)); - - constant.put(getNX(template, i)); - constant.put(getNY(template, i)); - constant.put(getNZ(template, i)); - - constant.putFloat(getU(template, i)); - constant.putFloat(getV(template, i)); - } - - protected abstract VertexFormat getInstanceFormat(); - - public int numInstances() { - return instanceCount + data.size(); - } - - public boolean isEmpty() { - return numInstances() == 0; - } - - public void clearInstanceData() { - instanceCount = 0; - shouldBuild = true; - } - - public void markDirty() { - if (shouldBuild) rebuffer = true; - } - - protected void deleteInternal() { - super.deleteInternal(); - instanceVBO.delete(); - } - - protected abstract D newInstance(); - - public void setupInstance(Consumer setup) { - if (!shouldBuild) return; - - D instanceData = newInstance(); - setup.accept(instanceData); - - data.add(instanceData); - } - - protected int getTotalShaderAttributeCount() { - return getInstanceFormat().getShaderAttributeCount() + super.getTotalShaderAttributeCount(); - } - - @Override - protected void drawCall() { - GL31.glDrawElementsInstanced(GL11.GL_QUADS, vertexCount, GL11.GL_UNSIGNED_SHORT, 0, instanceCount); - } - - protected void preDrawTask() { - if (!rebuffer || data.isEmpty()) return; - - instanceCount = data.size(); - - VertexFormat instanceFormat = getInstanceFormat(); - - int instanceSize = RenderMath.nextPowerOf2(instanceCount * instanceFormat.getStride()); - - instanceVBO.bind(GL15.GL_ARRAY_BUFFER); - - // this changes enough that it's not worth reallocating the entire buffer every time. - if (instanceSize > instanceBufferSize) { - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, instanceSize, GL15.GL_STATIC_DRAW); - instanceBufferSize = instanceSize; - } - - ByteBuffer buffer = GL15.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY); - - data.forEach(instanceData -> instanceData.write(buffer)); - buffer.rewind(); - GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER); - - int staticAttributes = getModelFormat().getShaderAttributeCount(); - instanceFormat.informAttributes(staticAttributes); - - for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) { - GL33.glVertexAttribDivisor(i + staticAttributes, 1); - } - - instanceVBO.unbind(GL15.GL_ARRAY_BUFFER); - - shouldBuild = false; - rebuffer = false; - data.clear(); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceContext.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceContext.java index abad52793..711d2a393 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceContext.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceContext.java @@ -1,10 +1,11 @@ package com.simibubi.create.foundation.render.instancing; import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; import com.simibubi.create.foundation.render.contraption.RenderedContraption; -import com.simibubi.create.foundation.render.FastKineticRenderer; import net.minecraft.tileentity.TileEntity; +@Deprecated public abstract class InstanceContext { public final T te; @@ -13,15 +14,15 @@ public abstract class InstanceContext { this.te = te; } - public RenderMaterial> getRotating() { + public RenderMaterial> getRotating() { return getKinetics().get(KineticRenderMaterials.ROTATING); } - public RenderMaterial> getBelts() { + public RenderMaterial> getBelts() { return getKinetics().get(KineticRenderMaterials.BELTS); } - public abstract FastKineticRenderer getKinetics(); + public abstract InstancedTileRenderDispatcher getKinetics(); public abstract boolean checkWorldLight(); @@ -35,7 +36,7 @@ public abstract class InstanceContext { } @Override - public FastKineticRenderer getKinetics() { + public InstancedTileRenderDispatcher getKinetics() { return c.kinetics; } @@ -52,7 +53,7 @@ public abstract class InstanceContext { } @Override - public FastKineticRenderer getKinetics() { + public InstancedTileRenderDispatcher getKinetics() { return CreateClient.kineticRenderer; } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceKey.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceKey.java new file mode 100644 index 000000000..9ba7f1141 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceKey.java @@ -0,0 +1,31 @@ +package com.simibubi.create.foundation.render.instancing; + +import java.util.function.Consumer; + +public class InstanceKey { + public static final int INVALID = -1; + + InstancedModel model; + int index; + + public InstanceKey(InstancedModel model, int index) { + this.model = model; + this.index = index; + } + + void invalidate() { + index = INVALID; + } + + public boolean isValid() { + return index != INVALID; + } + + public void modifyInstance(Consumer edit) { + model.modifyInstance(this, edit); + } + + public void delete() { + model.deleteInstance(this); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedModel.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedModel.java new file mode 100644 index 000000000..edd1ed544 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedModel.java @@ -0,0 +1,191 @@ +package com.simibubi.create.foundation.render.instancing; + + +import com.simibubi.create.foundation.render.BufferedModel; +import com.simibubi.create.foundation.render.RenderMath; +import com.simibubi.create.foundation.render.gl.GlBuffer; +import net.minecraft.client.renderer.BufferBuilder; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL31; +import org.lwjgl.opengl.GL33; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.function.Consumer; + +import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; + +public abstract class InstancedModel extends BufferedModel { + public static final VertexFormat FORMAT = new VertexFormat(POSITION, NORMAL, UV); + + protected GlBuffer instanceVBO; + protected int glBufferSize = -1; + protected int glInstanceCount = 0; + + protected final ArrayList> keys = new ArrayList<>(); + protected final ArrayList data = new ArrayList<>(); + protected int minIndexChanged = -1; + + public InstancedModel(BufferBuilder buf) { + super(buf); + } + + @Override + protected void setup() { + super.setup(); + instanceVBO = new GlBuffer(); + } + + @Override + protected VertexFormat getModelFormat() { + return FORMAT; + } + + @Override + protected void copyVertex(ByteBuffer constant, int i) { + constant.putFloat(getX(template, i)); + constant.putFloat(getY(template, i)); + constant.putFloat(getZ(template, i)); + + constant.put(getNX(template, i)); + constant.put(getNY(template, i)); + constant.put(getNZ(template, i)); + + constant.putFloat(getU(template, i)); + constant.putFloat(getV(template, i)); + } + + protected abstract VertexFormat getInstanceFormat(); + + public int instanceCount() { + return data.size(); + } + + public boolean isEmpty() { + return instanceCount() == 0; + } + + public void clearInstanceData() { + + } + + public void markDirty() { + minIndexChanged = 0; + } + + protected void deleteInternal() { + super.deleteInternal(); + instanceVBO.delete(); + keys.forEach(InstanceKey::invalidate); + } + + protected abstract D newInstance(); + + public synchronized void deleteInstance(InstanceKey key) { + verifyKey(key); + + int index = key.index; + + keys.remove(index); + data.remove(index); + + for (int i = index; i < keys.size(); i++) { + keys.get(i).index--; + } + + setMinIndexChanged(key.index); + + key.invalidate(); + } + + public synchronized void modifyInstance(InstanceKey key, Consumer edit) { + verifyKey(key); + + D data = this.data.get(key.index); + + edit.accept(data); + + setMinIndexChanged(key.index); + } + + public synchronized InstanceKey setupInstance(Consumer setup) { + D instanceData = newInstance(); + setup.accept(instanceData); + + InstanceKey key = new InstanceKey<>(this, data.size()); + data.add(instanceData); + keys.add(key); + + setMinIndexChanged(key.index); + + return key; + } + + protected void setMinIndexChanged(int index) { + if (minIndexChanged < 0) { + minIndexChanged = index; + } else { + minIndexChanged = Math.min(minIndexChanged, index); + } + } + + protected final void verifyKey(InstanceKey key) { + if (key.model != this) throw new IllegalStateException("Provided key does not belong to model."); + + if (!key.isValid()) throw new IllegalStateException("Provided key has been invalidated."); + + if (key.index >= data.size()) throw new IndexOutOfBoundsException("Key points out of bounds. (" + key.index + " > " + (data.size() - 1) + ")"); + + if (keys.get(key.index) != key) throw new IllegalStateException("Key desync!!"); + } + + protected int getTotalShaderAttributeCount() { + return getInstanceFormat().getShaderAttributeCount() + super.getTotalShaderAttributeCount(); + } + + @Override + protected void drawCall() { + GL31.glDrawElementsInstanced(GL11.GL_QUADS, vertexCount, GL11.GL_UNSIGNED_SHORT, 0, glInstanceCount); + } + + protected void preDrawTask() { + if (minIndexChanged < 0 || data.isEmpty()) return; + + VertexFormat instanceFormat = getInstanceFormat(); + + int stride = instanceFormat.getStride(); + int instanceSize = RenderMath.nextPowerOf2((instanceCount() + 1) * stride); + + instanceVBO.bind(GL15.GL_ARRAY_BUFFER); + + // this probably changes enough that it's not worth reallocating the entire buffer every time. + if (instanceSize > glBufferSize) { + GL15.glBufferData(GL15.GL_ARRAY_BUFFER, instanceSize, GL15.GL_STATIC_DRAW); + glBufferSize = instanceSize; + minIndexChanged = 0; + } + + ByteBuffer buffer = GL15.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY); + + buffer.position(stride * minIndexChanged); + for (int i = minIndexChanged; i < data.size(); i++) { + data.get(i).write(buffer); + } + buffer.rewind(); + GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER); + + glInstanceCount = data.size(); + + int staticAttributes = getModelFormat().getShaderAttributeCount(); + instanceFormat.informAttributes(staticAttributes); + + for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) { + GL33.glVertexAttribDivisor(i + staticAttributes, 1); + } + + instanceVBO.unbind(GL15.GL_ARRAY_BUFFER); + + minIndexChanged = -1; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderRegistry.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderRegistry.java new file mode 100644 index 000000000..71cd04266 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderRegistry.java @@ -0,0 +1,30 @@ +package com.simibubi.create.foundation.render.instancing; + +import com.google.common.collect.Maps; +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityType; + +import javax.annotation.Nullable; +import java.util.Map; + +public class InstancedTileRenderRegistry { + public static final InstancedTileRenderRegistry instance = new InstancedTileRenderRegistry(); + + private final Map, IRendererFactory> renderers = Maps.newHashMap(); + + public void register(TileEntityType type, IRendererFactory rendererFactory) { + this.renderers.put(type, rendererFactory); + } + + @SuppressWarnings("unchecked") + @Nullable + public TileEntityInstance create(InstancedTileRenderDispatcher manager, T tile) { + TileEntityType type = tile.getType(); + IRendererFactory factory = (IRendererFactory) this.renderers.get(type); + + if (factory == null) return null; + else return factory.create(manager, tile); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/KineticData.java b/src/main/java/com/simibubi/create/foundation/render/instancing/KineticData.java new file mode 100644 index 000000000..41ff3d0ab --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/KineticData.java @@ -0,0 +1,101 @@ +package com.simibubi.create.foundation.render.instancing; + +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.foundation.utility.ColorHelper; +import net.minecraft.client.renderer.Vector3f; +import net.minecraft.util.math.BlockPos; + +import java.nio.ByteBuffer; + +import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; + +public class KineticData> extends InstanceData { + public static final VertexAttribute ROTATION_CENTER = copy("rotationCenter", VEC3); + public static final VertexAttribute SPEED = copy("speed", FLOAT); + public static final VertexAttribute OFFSET = copy("offset", FLOAT); + public static final VertexFormat FORMAT = new VertexFormat(INSTANCE_POSITION, LIGHT, RGB, SPEED, OFFSET); + + private float x; + private float y; + private float z; + private byte blockLight; + private byte skyLight; + private byte r; + private byte g; + private byte b; + private float rotationalSpeed; + private float rotationOffset; + + public D setTileEntity(KineticTileEntity te) { + setPosition(te.getPos()); + if (te.hasSource()) { + setColor(te.network); + }else { + setColor(0xFF, 0xFF, 0x00); + } + return (D) this; + } + + public D setPosition(BlockPos pos) { + return setPosition(pos.getX(), pos.getY(), pos.getZ()); + } + + public D setPosition(Vector3f pos) { + return setPosition(pos.getX(), pos.getY(), pos.getZ()); + } + + public D setPosition(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + return (D) this; + } + + public D setBlockLight(int blockLight) { + this.blockLight = (byte) ((blockLight & 0xF) << 4); + return (D) this; + } + + public D setSkyLight(int skyLight) { + this.skyLight = (byte) ((skyLight & 0xF) << 4); + return (D) this; + } + + private void setColor(long l) { + int color = ColorHelper.colorFromLong(l); + r = (byte) ((color >> 16) & 0xFF); + g = (byte) ((color >> 8) & 0xFF); + b = (byte) (color & 0xFF); + } + + public D setColor(int r, int g, int b) { + return setColor((byte) r, (byte) g, (byte) b); + } + + public D setColor(byte r, byte g, byte b) { + this.r = r; + this.g = g; + this.b = b; + return (D) this; + } + + public D setRotationalSpeed(float rotationalSpeed) { + this.rotationalSpeed = rotationalSpeed; + return (D) this; + } + + public D setRotationOffset(float rotationOffset) { + this.rotationOffset = rotationOffset; + return (D) this; + } + + + @Override + public void write(ByteBuffer buf) { + putVec3(buf, x, y, z); + putVec2(buf, blockLight, skyLight); + putVec3(buf, r, g, b); + put(buf, rotationalSpeed); + put(buf, rotationOffset); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/KineticRenderMaterials.java b/src/main/java/com/simibubi/create/foundation/render/instancing/KineticRenderMaterials.java index cd941f5d9..37ac5b379 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/KineticRenderMaterials.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/KineticRenderMaterials.java @@ -3,8 +3,8 @@ package com.simibubi.create.foundation.render.instancing; import com.simibubi.create.foundation.render.instancing.actors.StaticRotatingActorData; public class KineticRenderMaterials { - public static final MaterialType> ROTATING = new MaterialType<>(); - public static final MaterialType> BELTS = new MaterialType<>(); + public static final MaterialType> ROTATING = new MaterialType<>(); + public static final MaterialType> BELTS = new MaterialType<>(); - public static final MaterialType> ACTORS = new MaterialType<>(); + public static final MaterialType> ACTORS = new MaterialType<>(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/ModelFactory.java b/src/main/java/com/simibubi/create/foundation/render/instancing/ModelFactory.java index 36120053b..3024abcf5 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/ModelFactory.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/ModelFactory.java @@ -3,6 +3,6 @@ package com.simibubi.create.foundation.render.instancing; import net.minecraft.client.renderer.BufferBuilder; @FunctionalInterface -public interface ModelFactory> { +public interface ModelFactory> { B convert(BufferBuilder buf); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java b/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java index 95cf9aa59..cefd13d8e 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java @@ -7,9 +7,9 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.foundation.render.Compartment; import com.simibubi.create.foundation.render.SuperByteBufferCache; -import com.simibubi.create.foundation.render.shader.Shader; -import com.simibubi.create.foundation.render.shader.ShaderCallback; -import com.simibubi.create.foundation.render.shader.ShaderHelper; +import com.simibubi.create.foundation.render.gl.shader.Shader; +import com.simibubi.create.foundation.render.gl.shader.ShaderCallback; +import com.simibubi.create.foundation.render.gl.shader.ShaderHelper; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BlockRendererDispatcher; @@ -19,7 +19,6 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.util.Direction; import org.apache.commons.lang3.tuple.Pair; -import org.lwjgl.opengl.GL40; import java.util.HashMap; import java.util.Map; @@ -30,7 +29,7 @@ import java.util.function.Supplier; import static com.simibubi.create.foundation.render.Compartment.PARTIAL; -public class RenderMaterial> { +public class RenderMaterial> { protected final Map, Cache> models; protected final ModelFactory factory; @@ -75,7 +74,7 @@ public class RenderMaterial> { public void teardown() {} public void delete() { - runOnAll(InstanceBuffer::delete); + runOnAll(InstancedModel::delete); models.values().forEach(Cache::invalidateAll); } @@ -105,6 +104,11 @@ public class RenderMaterial> { return get(PARTIAL, partial, () -> buildModel(partial.get(), referenceState)); } + public MODEL getModel(AllBlockPartials partial, BlockState referenceState, Direction dir) { + return get(Compartment.DIRECTIONAL_PARTIAL, Pair.of(dir, partial), + () -> buildModel(partial.get(), referenceState)); + } + public MODEL getModel(AllBlockPartials partial, BlockState referenceState, Direction dir, Supplier modelTransform) { return get(Compartment.DIRECTIONAL_PARTIAL, Pair.of(dir, partial), () -> buildModel(partial.get(), referenceState, modelTransform.get())); diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingData.java b/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingData.java index c905d93e9..2d2dc99e1 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingData.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingData.java @@ -1,27 +1,22 @@ package com.simibubi.create.foundation.render.instancing; import net.minecraft.client.renderer.Vector3f; +import net.minecraft.util.Direction; import java.nio.ByteBuffer; -import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; +import static com.simibubi.create.foundation.render.instancing.VertexAttribute.NORMAL; -public class RotatingData extends BasicData { - public static VertexFormat FORMAT = new VertexFormat(BasicData.FORMAT, FLOAT, FLOAT, NORMAL); +public class RotatingData extends KineticData { + public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, NORMAL); - private float rotationalSpeed; - private float rotationOffset; private byte rotationAxisX; private byte rotationAxisY; private byte rotationAxisZ; - public RotatingData setRotationalSpeed(float rotationalSpeed) { - this.rotationalSpeed = rotationalSpeed; - return this; - } - - public RotatingData setRotationOffset(float rotationOffset) { - this.rotationOffset = rotationOffset; + public RotatingData setRotationAxis(Direction.Axis axis) { + Direction orientation = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis); + setRotationAxis(orientation.getUnitVector()); return this; } @@ -40,8 +35,6 @@ public class RotatingData extends BasicData { @Override public void write(ByteBuffer buf) { super.write(buf); - put(buf, rotationalSpeed); - put(buf, rotationOffset); putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingBuffer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingModel.java similarity index 75% rename from src/main/java/com/simibubi/create/foundation/render/instancing/RotatingBuffer.java rename to src/main/java/com/simibubi/create/foundation/render/instancing/RotatingModel.java index 7a7b24f4e..4b6a47150 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/RotatingModel.java @@ -2,8 +2,8 @@ package com.simibubi.create.foundation.render.instancing; import net.minecraft.client.renderer.BufferBuilder; -public class RotatingBuffer extends InstanceBuffer { - public RotatingBuffer(BufferBuilder buf) { +public class RotatingModel extends InstancedModel { + public RotatingModel(BufferBuilder buf) { super(buf); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/TileEntityInstance.java b/src/main/java/com/simibubi/create/foundation/render/instancing/TileEntityInstance.java new file mode 100644 index 000000000..2bd228c58 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/TileEntityInstance.java @@ -0,0 +1,38 @@ +package com.simibubi.create.foundation.render.instancing; + +import com.simibubi.create.foundation.render.InstancedTileRenderDispatcher; +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntity; + +public abstract class TileEntityInstance { + + protected final InstancedTileRenderDispatcher modelManager; + protected final T tile; + protected BlockState lastState; + + public TileEntityInstance(InstancedTileRenderDispatcher modelManager, T tile) { + this.modelManager = modelManager; + this.tile = tile; + this.lastState = tile.getBlockState(); + init(); + } + + protected abstract void init(); + + public final void update() { + BlockState currentState = tile.getBlockState(); + if (lastState == currentState) { + onUpdate(); + } else { + remove(); + init(); + lastState = currentState; + } + } + + protected abstract void onUpdate(); + + public abstract void updateLight(); + + public abstract void remove(); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/VertexAttribute.java b/src/main/java/com/simibubi/create/foundation/render/instancing/VertexAttribute.java index d4921bfba..1ed7fee2f 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/VertexAttribute.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/VertexAttribute.java @@ -4,30 +4,47 @@ import net.minecraft.client.renderer.vertex.VertexFormatElement; import org.lwjgl.opengl.GL20; public class VertexAttribute { - public static final VertexAttribute MAT4 = new VertexAttribute(VertexFormatElement.Type.FLOAT, 16); - public static final VertexAttribute VEC4 = new VertexAttribute(VertexFormatElement.Type.FLOAT, 4); - public static final VertexAttribute VEC3 = new VertexAttribute(VertexFormatElement.Type.FLOAT, 3); - public static final VertexAttribute VEC2 = new VertexAttribute(VertexFormatElement.Type.FLOAT, 2); - public static final VertexAttribute FLOAT = new VertexAttribute(VertexFormatElement.Type.FLOAT, 1); + public static final VertexAttribute MAT4 = new VertexAttribute("mat4", VertexFormatElement.Type.FLOAT, 16); + public static final VertexAttribute VEC4 = new VertexAttribute("vec4", VertexFormatElement.Type.FLOAT, 4); + public static final VertexAttribute VEC3 = new VertexAttribute("vec3", VertexFormatElement.Type.FLOAT, 3); + public static final VertexAttribute VEC2 = new VertexAttribute("vec2", VertexFormatElement.Type.FLOAT, 2); + public static final VertexAttribute FLOAT = new VertexAttribute("float", VertexFormatElement.Type.FLOAT, 1); - public static final VertexAttribute POSITION = VEC3; - public static final VertexAttribute NORMAL = new VertexAttribute(VertexFormatElement.Type.BYTE, 3, true); - public static final VertexAttribute RGBA = new VertexAttribute(VertexFormatElement.Type.UBYTE, 4, true); - public static final VertexAttribute RGB = new VertexAttribute(VertexFormatElement.Type.UBYTE, 3, true); - public static final VertexAttribute UV = VEC2; - public static final VertexAttribute LIGHT = new VertexAttribute(VertexFormatElement.Type.UBYTE, 2, true); + public static final VertexAttribute POSITION = copy("pos", VEC3); + public static final VertexAttribute INSTANCE_POSITION = copy("instancePos", VEC3); + public static final VertexAttribute ROTATION = copy("eulerAngles", VEC3); + public static final VertexAttribute NORMAL = new VertexAttribute("normal", VertexFormatElement.Type.BYTE, 3, true); + public static final VertexAttribute RGBA = new VertexAttribute("rgba", VertexFormatElement.Type.UBYTE, 4, true); + public static final VertexAttribute RGB = new VertexAttribute("rgb", VertexFormatElement.Type.UBYTE, 3, true); + public static final VertexAttribute UV = copy("uv", VEC2); + public static final VertexAttribute LIGHT = new VertexAttribute("light", VertexFormatElement.Type.UBYTE, 2, true); + private final String name; private final VertexFormatElement.Type type; private final int count; private final int size; private final int attributeCount; private final boolean normalized; - public VertexAttribute(VertexFormatElement.Type type, int count) { - this(type, count, false); + public static VertexAttribute copy(String name, VertexAttribute other) { + return new VertexAttribute(name, other); } - public VertexAttribute(VertexFormatElement.Type type, int count, boolean normalized) { + public VertexAttribute(String name, VertexAttribute that) { + this.name = name; + this.type = that.type; + this.count = that.count; + this.size = that.size; + this.attributeCount = that.attributeCount; + this.normalized = that.normalized; + } + + public VertexAttribute(String name, VertexFormatElement.Type type, int count) { + this(name, type, count, false); + } + + public VertexAttribute(String name, VertexFormatElement.Type type, int count, boolean normalized) { + this.name = name; this.type = type; this.count = count; this.size = type.getSize() * count; diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/actors/RotatingActorBuffer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/actors/RotatingActorModel.java similarity index 80% rename from src/main/java/com/simibubi/create/foundation/render/instancing/actors/RotatingActorBuffer.java rename to src/main/java/com/simibubi/create/foundation/render/instancing/actors/RotatingActorModel.java index 6e33fc9f4..5bdfe4c9b 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/actors/RotatingActorBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/actors/RotatingActorModel.java @@ -1,11 +1,11 @@ package com.simibubi.create.foundation.render.instancing.actors; -import com.simibubi.create.foundation.render.instancing.DynamicInstanceBuffer; +import com.simibubi.create.foundation.render.instancing.DynamicInstancedModel; import com.simibubi.create.foundation.render.instancing.VertexFormat; import net.minecraft.client.renderer.BufferBuilder; -public class RotatingActorBuffer extends DynamicInstanceBuffer { - public RotatingActorBuffer(BufferBuilder buf) { +public class RotatingActorModel extends DynamicInstancedModel { + public RotatingActorModel(BufferBuilder buf) { super(buf); } diff --git a/src/main/java/com/simibubi/create/foundation/render/light/ILightListener.java b/src/main/java/com/simibubi/create/foundation/render/light/ILightListener.java new file mode 100644 index 000000000..8b4a571f0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/light/ILightListener.java @@ -0,0 +1,5 @@ +package com.simibubi.create.foundation.render.light; + +public interface ILightListener { + void onChunkLightUpdate(); +} diff --git a/src/main/resources/assets/create/shader/belt.vert b/src/main/resources/assets/create/shader/belt.vert index 8a9c50380..de852ff85 100644 --- a/src/main/resources/assets/create/shader/belt.vert +++ b/src/main/resources/assets/create/shader/belt.vert @@ -5,14 +5,15 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal; layout (location = 2) in vec2 aTexCoords; -layout (location = 3) in vec3 networkTint; -layout (location = 4) in vec3 instancePos; -layout (location = 5) in vec2 light; -layout (location = 6) in vec3 rotationDegrees; -layout (location = 7) in float speed; -layout (location = 8) in vec2 sourceUV; -layout (location = 9) in vec4 scrollTexture; -layout (location = 10) in float scrollMult; +layout (location = 3) in vec3 instancePos; +layout (location = 4) in vec2 light; +layout (location = 5) in vec3 networkTint; +layout (location = 6) in float speed; +layout (location = 7) in float offset; +layout (location = 8) in vec3 eulerAngles; +layout (location = 9) in vec2 uv; +layout (location = 10) in vec4 scrollTexture; +layout (location = 11) in float scrollMult; out vec2 TexCoords; out vec2 Light; @@ -36,6 +37,10 @@ mat4 rotate(vec3 axis, float angle) { 0, 0, 0, 1); } +mat4 rotation(vec3 rot) { + return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x); +} + float diffuse(vec3 normal) { float x = normal.x; float y = normal.y; @@ -43,23 +48,23 @@ float diffuse(vec3 normal) { return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1); } +mat4 localRotation() { + vec3 rot = fract(eulerAngles / 360) * PI * 2; + return rotation(rot); +} + void main() { - vec3 rot = fract(rotationDegrees / 360) * PI * 2; - - mat4 rotation = rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x); - - vec4 renderPos = rotation * vec4(aPos - vec3(.5), 1); - renderPos += vec4(instancePos + vec3(.5), 0); + mat4 localRotation = localRotation(); + vec4 renderPos = localRotation * vec4(aPos - vec3(.5), 1) + vec4(instancePos + vec3(.5), 0); float scrollSize = scrollTexture.w - scrollTexture.y; + float scroll = fract(speed * time / (36 * 16) + offset) * scrollSize * scrollMult; - float scroll = fract(speed * time / (36 * 16)) * scrollSize * scrollMult; - - vec3 norm = (rotation * vec4(aNormal, 0)).xyz; + vec3 norm = (localRotation * vec4(aNormal, 0)).xyz; Diffuse = diffuse(norm); Light = light; - TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0, scroll); + TexCoords = aTexCoords - uv + scrollTexture.xy + vec2(0, scroll); gl_Position = projection * view * renderPos; if (debug == 1) { diff --git a/src/main/resources/assets/create/shader/contraption_belt.vert b/src/main/resources/assets/create/shader/contraption_belt.vert index e965c2e98..8a0b8fbeb 100644 --- a/src/main/resources/assets/create/shader/contraption_belt.vert +++ b/src/main/resources/assets/create/shader/contraption_belt.vert @@ -5,14 +5,15 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal; layout (location = 2) in vec2 aTexCoords; -layout (location = 3) in vec3 networkTint; -layout (location = 4) in vec3 instancePos; -layout (location = 5) in vec2 light; -layout (location = 6) in vec3 rotationDegrees; -layout (location = 7) in float speed; -layout (location = 8) in vec2 sourceUV; -layout (location = 9) in vec4 scrollTexture; -layout (location = 10) in float scrollMult; +layout (location = 3) in vec3 instancePos; +layout (location = 4) in vec2 light; +layout (location = 5) in vec3 networkTint; +layout (location = 6) in float speed; +layout (location = 7) in float offset; +layout (location = 8) in vec3 eulerAngles; +layout (location = 9) in vec2 uv; +layout (location = 10) in vec4 scrollTexture; +layout (location = 11) in float scrollMult; out float Diffuse; out vec2 TexCoords; @@ -53,7 +54,7 @@ mat4 rotation(vec3 rot) { } mat4 localRotation() { - vec3 rot = fract(rotationDegrees / 360) * PI * 2; + vec3 rot = fract(eulerAngles / 360) * PI * 2; return rotation(rot); } @@ -64,13 +65,13 @@ void main() { vec4 worldPos = model * localPos; float scrollSize = scrollTexture.w - scrollTexture.y; - float scroll = fract(speed * time / (36 * 16)) * scrollSize * scrollMult; + float scroll = fract(speed * time / (36 * 16) + offset) * scrollSize * scrollMult; vec3 norm = normalize(model * localRotation * vec4(aNormal, 0)).xyz; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; Diffuse = diffuse(norm); - TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0, scroll); + TexCoords = aTexCoords - uv + scrollTexture.xy + vec2(0, scroll); gl_Position = projection * view * worldPos; if (debug == 2) { diff --git a/src/main/resources/assets/create/shader/contraption_rotating.vert b/src/main/resources/assets/create/shader/contraption_rotating.vert index 1c1887511..adf818290 100644 --- a/src/main/resources/assets/create/shader/contraption_rotating.vert +++ b/src/main/resources/assets/create/shader/contraption_rotating.vert @@ -4,11 +4,11 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal; layout (location = 2) in vec2 aTexCoords; -layout (location = 3) in vec3 networkTint; -layout (location = 4) in vec3 instancePos; -layout (location = 5) in vec2 light; +layout (location = 3) in vec3 instancePos; +layout (location = 4) in vec2 light; +layout (location = 5) in vec3 networkTint; layout (location = 6) in float speed; -layout (location = 7) in float rotationOffset; +layout (location = 7) in float offset; layout (location = 8) in vec3 rotationAxis; out float Diffuse; @@ -26,6 +26,7 @@ uniform mat4 projection; uniform mat4 view; uniform int debug; + mat4 rotate(vec3 axis, float angle) { float s = sin(angle); float c = cos(angle); @@ -44,16 +45,20 @@ float diffuse(vec3 normal) { return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1); } +mat4 rotation(vec3 rot) { + return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x); +} + mat4 kineticRotation() { - float degrees = rotationOffset + time * speed * -3/10; + float degrees = offset + time * speed * -3/10; float angle = fract(degrees / 360) * PI * 2; - return rotate(normalize(rotationAxis), angle); + return rotate(vec3(0, 1, 0), angle); } void main() { mat4 kineticRotation = kineticRotation(); - vec4 localPos = kineticRotation * vec4(aPos - .5, 1) + vec4(instancePos + .5, 0); + vec4 localPos = kineticRotation * vec4(aPos - 0.5, 1) + vec4(instancePos + .5, 0); vec4 worldPos = model * localPos; diff --git a/src/main/resources/assets/create/shader/rotating.vert b/src/main/resources/assets/create/shader/rotating.vert index 93b292516..42d22357d 100644 --- a/src/main/resources/assets/create/shader/rotating.vert +++ b/src/main/resources/assets/create/shader/rotating.vert @@ -4,11 +4,11 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal; layout (location = 2) in vec2 aTexCoords; -layout (location = 3) in vec3 networkTint; -layout (location = 4) in vec3 instancePos; -layout (location = 5) in vec2 light; +layout (location = 3) in vec3 instancePos; +layout (location = 4) in vec2 light; +layout (location = 5) in vec3 networkTint; layout (location = 6) in float speed; -layout (location = 7) in float rotationOffset; +layout (location = 7) in float offset; layout (location = 8) in vec3 rotationAxis; out vec2 TexCoords; @@ -40,24 +40,26 @@ float diffuse(vec3 normal) { return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1); } +mat4 rotation(vec3 rot) { + return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x); +} + mat4 kineticRotation() { - float degrees = rotationOffset + time * speed * -3/10; + float degrees = offset + time * speed * -3/10; float angle = fract(degrees / 360) * PI * 2; - return rotate(normalize(rotationAxis), angle); + return rotate(rotationAxis, angle); } void main() { - mat4 rotation = kineticRotation(); - vec4 renderPos = rotation * vec4(aPos - vec3(0.5), 1); + mat4 kineticRotation = kineticRotation(); + vec4 localPos = kineticRotation * vec4(aPos - 0.5, 1) + vec4(instancePos + .5, 0); - renderPos += vec4(instancePos + vec3(0.5), 0); - - vec3 norm = (rotation * vec4(aNormal, 0)).xyz; + vec3 norm = (kineticRotation * vec4(aNormal, 0)).xyz; Diffuse = diffuse(norm); TexCoords = aTexCoords; - gl_Position = projection * view * renderPos; + gl_Position = projection * view * localPos; Light = light; if (debug == 1) { diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index f674ecc82..beb9f49c8 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -3,7 +3,7 @@ "package": "com.simibubi.create.foundation.mixin", "compatibilityLevel": "JAVA_8", "refmap": "create.refmap.json", - "client": ["CancelTileEntityRenderMixin", "LightUpdateMixin", "OnRemoveTileMixin", "RenderInLayerMixin"], + "client": ["CancelTileEntityRenderMixin", "LightUpdateMixin", "RenderInLayerMixin"], "injectors": { "defaultRequire": 1 },