Instanced flywheels, engines, and schematicannons.

This commit is contained in:
JozsefA 2021-03-10 13:44:04 -08:00
parent d8ab00b66e
commit d0a6f4123b
13 changed files with 473 additions and 56 deletions

View file

@ -16,8 +16,11 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.content.contraptions.relays.belt.BeltData;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
@ -259,4 +262,22 @@ public class AllBlockPartials {
return dispatcher.getMaterial(KineticRenderMaterials.ROTATING).getModel(this, referenceState, facing, ms);
}
public InstancedModel<ModelData> renderOnHorizontalModel(InstancedTileRenderer<?> dispatcher, BlockState referenceState) {
Direction facing = referenceState.get(HORIZONTAL_FACING);
return renderOnDirectionalSouthModel(dispatcher, referenceState, facing);
}
public InstancedModel<ModelData> renderOnDirectionalSouthModel(InstancedTileRenderer<?> dispatcher, BlockState referenceState, Direction facing) {
Supplier<MatrixStack> ms = () -> {
MatrixStack stack = new MatrixStack();
MatrixStacker.of(stack)
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing))
.unCentre();
return stack;
};
return dispatcher.getMaterial(RenderMaterials.MODELS).getModel(this, referenceState, facing, ms);
}
}

View file

@ -32,6 +32,7 @@ import com.simibubi.create.content.contraptions.components.fan.NozzleTileEntity;
import com.simibubi.create.content.contraptions.components.flywheel.FlyWheelInstance;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelRenderer;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity;
import com.simibubi.create.content.contraptions.components.flywheel.engine.EngineInstance;
import com.simibubi.create.content.contraptions.components.flywheel.engine.EngineRenderer;
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineTileEntity;
import com.simibubi.create.content.contraptions.components.millstone.MillStoneCogInstance;
@ -139,6 +140,7 @@ import com.simibubi.create.content.logistics.block.redstone.NixieTubeTileEntity;
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkTileEntity;
import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchTileEntity;
import com.simibubi.create.content.schematics.block.SchematicTableTileEntity;
import com.simibubi.create.content.schematics.block.SchematicannonInstance;
import com.simibubi.create.content.schematics.block.SchematicannonRenderer;
import com.simibubi.create.content.schematics.block.SchematicannonTileEntity;
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
@ -151,6 +153,7 @@ public class AllTileEntities {
.tileEntity("schematicannon", SchematicannonTileEntity::new)
.validBlocks(AllBlocks.SCHEMATICANNON)
.renderer(() -> SchematicannonRenderer::new)
.onRegister(SchematicannonInstance::register)
.register();
public static final TileEntityEntry<SchematicTableTileEntity> SCHEMATIC_TABLE = Create.registrate()
@ -456,6 +459,7 @@ public class AllTileEntities {
.tileEntity("furnace_engine", FurnaceEngineTileEntity::new)
.validBlocks(AllBlocks.FURNACE_ENGINE)
.renderer(() -> EngineRenderer::new)
.onRegister(EngineInstance::register)
.register();
public static final TileEntityEntry<MillstoneTileEntity> MILLSTONE = Create.registrate()

View file

@ -1,34 +1,57 @@
package com.simibubi.create.content.contraptions.components.flywheel;
import java.util.function.Consumer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.*;
import net.minecraft.block.BlockState;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.LightType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> {
public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> implements ITickableInstance {
public static void register(TileEntityType<? extends FlywheelTileEntity> type) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
InstancedTileRenderRegistry.instance.register(type, FlyWheelInstance::new));
}
protected Direction facing;
protected boolean connectedLeft;
protected float connectorAngleMult;
protected Direction connection;
protected InstanceKey<RotatingData> shaft;
// protected InstanceKey<RotatingData> wheel;
protected InstanceKey<ModelData> wheel;
protected InstanceKey<ModelData> upperRotating;
protected InstanceKey<ModelData> lowerRotating;
protected InstanceKey<ModelData> upperSliding;
protected InstanceKey<ModelData> lowerSliding;
protected List<InstanceKey<ModelData>> connectors;
protected float lastAngle = Float.NaN;
public FlyWheelInstance(InstancedTileRenderer<?> modelManager, FlywheelTileEntity tile) {
super(modelManager, tile);
@ -40,35 +63,152 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> {
Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState);
shaft = setup(shaftModel().createInstance(), tile.getSpeed(), axis);
// wheel = wheelModel().setupInstance(setup);
wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontalModel(modelManager, lastState.rotate(Rotation.CLOCKWISE_90)).createInstance();
connection = FlywheelBlock.getConnection(lastState);
if (connection != null) {
connectedLeft = lastState.get(FlywheelBlock.CONNECTION) == FlywheelBlock.ConnectionState.LEFT;
boolean flipAngle = connection.getAxis() == Direction.Axis.X ^ connection.getAxisDirection() == Direction.AxisDirection.NEGATIVE;
connectorAngleMult = flipAngle ? -1 : 1;
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS);
upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, lastState).createInstance();
lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, lastState).createInstance();
upperSliding = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_SLIDING, lastState).createInstance();
lowerSliding = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_SLIDING, lastState).createInstance();
connectors = Lists.newArrayList(upperRotating, lowerRotating, upperSliding, lowerSliding);
} else {
connectors = Collections.emptyList();
}
updateLight();
}
@Override
public void tick() {
float partialTicks = AnimationTickHolder.getPartialTicks();
float speed = tile.visualSpeed.get(partialTicks) * 3 / 10f;
float angle = tile.angle + speed * partialTicks;
if (Math.abs(angle - lastAngle) < 0.001) return;
MatrixStack ms = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(ms);
msr.translate(getFloatingPos());
if (connection != null) {
float rotation = angle * connectorAngleMult;
ms.push();
rotateToFacing(msr, connection);
ms.push();
transformConnector(msr, true, true, rotation, connectedLeft);
upperRotating.getInstance().setTransform(ms);
ms.pop();
ms.push();
transformConnector(msr, false, true, rotation, connectedLeft);
lowerRotating.getInstance().setTransform(ms);
ms.pop();
ms.push();
transformConnector(msr, true, false, rotation, connectedLeft);
upperSliding.getInstance().setTransform(ms);
ms.pop();
ms.push();
transformConnector(msr, false, false, rotation, connectedLeft);
lowerSliding.getInstance().setTransform(ms);
ms.pop();
ms.pop();
}
msr.centre()
.rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()), AngleHelper.rad(angle))
.unCentre();
wheel.getInstance().setTransformNoCopy(ms);
lastAngle = angle;
}
@Override
protected void onUpdate() {
Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState);
updateRotation(shaft, axis);
// updateRotation(wheel, axis);
}
@Override
public void updateLight() {
relight(shaft);
// wheel.modifyInstance(this::relight);
int block = world.getLightLevel(LightType.BLOCK, pos);
int sky = world.getLightLevel(LightType.SKY, pos);
shaft.getInstance().setBlockLight(block).setSkyLight(sky);
wheel.getInstance().setBlockLight(block).setSkyLight(sky);
if (connection != null) {
BlockPos pos = this.pos.offset(connection);
int connectionBlock = world.getLightLevel(LightType.BLOCK, pos);
int connectionSky = world.getLightLevel(LightType.SKY, pos);
connectors.stream()
.map(InstanceKey::getInstance)
.forEach(data -> data.setBlockLight(connectionBlock).setSkyLight(connectionSky));
}
}
@Override
public void remove() {
shaft.delete();
// wheel.delete();
// wheel = null;
wheel.delete();
connectors.forEach(InstanceKey::delete);
connectors.clear();
}
protected InstancedModel<RotatingData> shaftModel() {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, facing.getOpposite());
}
protected InstancedModel<RotatingData> wheelModel() {
BlockState rotate = lastState.rotate(Rotation.CLOCKWISE_90);
return AllBlockPartials.FLYWHEEL.renderOnDirectionalSouthRotating(modelManager, rotate, rotate.get(BlockStateProperties.HORIZONTAL_FACING));
protected void transformConnector(MatrixStacker ms, boolean upper, boolean rotating, float angle, boolean flip) {
float shift = upper ? 1 / 4f : -1 / 8f;
float offset = upper ? 1 / 4f : 1 / 4f;
float radians = (float) (angle / 180 * Math.PI);
float shifting = MathHelper.sin(radians) * shift + offset;
float maxAngle = upper ? -5 : -15;
float minAngle = upper ? -45 : 5;
float barAngle = 0;
if (rotating)
barAngle = MathHelper.lerp((MathHelper.sin((float) (radians + Math.PI / 2)) + 1) / 2, minAngle, maxAngle);
float pivotX = (upper ? 8f : 3f) / 16;
float pivotY = (upper ? 8f : 2f) / 16;
float pivotZ = (upper ? 23f : 21.5f) / 16f;
ms.translate(pivotX, pivotY, pivotZ + shifting);
if (rotating)
ms.rotate(Direction.EAST, AngleHelper.rad(barAngle));
ms.translate(-pivotX, -pivotY, -pivotZ);
if (flip && !upper)
ms.translate(9 / 16f, 0, 0);
}
protected void rotateToFacing(MatrixStacker buffer, Direction facing) {
buffer.centre()
.rotate(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing)))
.unCentre();
}
}

View file

@ -9,6 +9,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.utility.AngleHelper;
import net.minecraft.block.BlockState;
@ -33,10 +34,11 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
int light, int overlay) {
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
if (FastRenderDispatcher.available(te.getWorld())) return;
BlockState blockState = te.getBlockState();
FlywheelTileEntity wte = (FlywheelTileEntity) te;
SuperByteBuffer wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontal(blockState.rotate(Rotation.CLOCKWISE_90));
float speed = wte.visualSpeed.get(partialTicks) * 3 / 10f;
float angle = wte.angle + speed * partialTicks;
@ -68,6 +70,7 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
.renderInto(ms, vb);
}
SuperByteBuffer wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontal(blockState.rotate(Rotation.CLOCKWISE_90));
kineticRotationTransform(wheel, te, blockState.get(HORIZONTAL_FACING)
.getAxis(), AngleHelper.rad(angle), light);
wheel.renderInto(ms, vb);

View file

@ -100,9 +100,4 @@ public class FlywheelTileEntity extends GeneratingKineticTileEntity {
updateGeneratedRotation();
}
}
@Override
public boolean shouldRenderAsTE() {
return true;
}
}

View file

@ -0,0 +1,80 @@
package com.simibubi.create.content.contraptions.components.flywheel.engine;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.block.Block;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.LightType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
public static void register(TileEntityType<? extends EngineTileEntity> type) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
InstancedTileRenderRegistry.instance.register(type, EngineInstance::new));
}
protected BlockPos baseBlockPos;
protected InstanceKey<ModelData> frame;
public EngineInstance(InstancedTileRenderer<?> modelManager, EngineTileEntity tile) {
super(modelManager, tile);
}
@Override
protected void init() {
Block block = lastState
.getBlock();
if (!(block instanceof EngineBlock))
return;
EngineBlock engineBlock = (EngineBlock) block;
AllBlockPartials frame = engineBlock.getFrameModel();
Direction facing = lastState.get(BlockStateProperties.HORIZONTAL_FACING);
baseBlockPos = EngineBlock.getBaseBlockPos(lastState, pos);
this.frame = modelManager.getMaterial(RenderMaterials.MODELS).getModel(frame, lastState).createInstance();
float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing));
MatrixStack ms = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(ms);
msr.translate(getFloatingPos())
.centre()
.rotate(Direction.UP, angle)
.unCentre()
.translate(0, 0, -1);
this.frame.getInstance()
.setTransformNoCopy(ms);
updateLight();
}
@Override
public void remove() {
frame.delete();
}
@Override
public void updateLight() {
int block = world.getLightLevel(LightType.BLOCK, baseBlockPos);
int sky = world.getLightLevel(LightType.SKY, baseBlockPos);
frame.getInstance().setBlockLight(block).setSkyLight(sky);
}
}

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -21,6 +22,9 @@ public class EngineRenderer<T extends EngineTileEntity> extends SafeTileEntityRe
@Override
protected void renderSafe(T te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light,
int overlay) {
if (FastRenderDispatcher.available(te.getWorld())) return;
Block block = te.getBlockState()
.getBlock();
if (block instanceof EngineBlock) {

View file

@ -3,8 +3,10 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity;
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -16,8 +18,10 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor;
import org.apache.http.client.CredentialsProvider;
public class EngineTileEntity extends SmartTileEntity {
public class EngineTileEntity extends SmartTileEntity implements IInstanceRendered {
public float appliedCapacity;
public float appliedSpeed;
@ -100,4 +104,16 @@ public class EngineTileEntity extends SmartTileEntity {
poweredWheel.setRotation(appliedSpeed, appliedCapacity);
}
@Override
public void onChunkLightUpdate() {
CreateClient.kineticRenderer.onLightUpdate(this);
}
@Override
public void initialize() {
super.initialize();
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.add(this));
}
}

View file

@ -48,9 +48,12 @@ public class MixerInstance extends ShaftlessCogInstance implements ITickableInst
.createInstance();
updateLight();
MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) tile;
transformPole(getRenderedHeadOffset(mixer));
float renderedHeadOffset = getRenderedHeadOffset(mixer);
transformPole(renderedHeadOffset);
transformHead(mixer, renderedHeadOffset);
updateLight();
}
@Override

View file

@ -0,0 +1,99 @@
package com.simibubi.create.content.schematics.block;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance;
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.LightType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class SchematicannonInstance extends TileEntityInstance<SchematicannonTileEntity> implements ITickableInstance {
public static void register(TileEntityType<? extends SchematicannonTileEntity> type) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
InstancedTileRenderRegistry.instance.register(type, SchematicannonInstance::new));
}
private InstanceKey<ModelData> connector;
private InstanceKey<ModelData> pipe;
public SchematicannonInstance(InstancedTileRenderer<?> modelManager, SchematicannonTileEntity tile) {
super(modelManager, tile);
}
@Override
protected void init() {
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS);
connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, lastState).createInstance();
pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, lastState).createInstance();
updateLight();
}
@Override
public void tick() {
float partialTicks = AnimationTickHolder.getPartialTicks();
double[] cannonAngles = SchematicannonRenderer.getCannonAngles(tile, pos, partialTicks);
double pitch = cannonAngles[0];
double yaw = cannonAngles[1];
double recoil = SchematicannonRenderer.getRecoil(tile, partialTicks);
MatrixStack ms = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(ms);
msr.translate(getFloatingPos());
ms.push();
msr.centre();
msr.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI));
msr.unCentre();
connector.getInstance().setTransform(ms);
ms.pop();
msr.translate(.5f, 15 / 16f, .5f);
msr.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI));
msr.rotate(Direction.SOUTH, (float) (pitch / 180 * Math.PI));
msr.translate(-.5f, -15 / 16f, -.5f);
msr.translate(0, -recoil / 100, 0);
pipe.getInstance().setTransformNoCopy(ms);
}
@Override
public void remove() {
connector.delete();
pipe.delete();
}
@Override
public void updateLight() {
int block = world.getLightLevel(LightType.BLOCK, pos);
int sky = world.getLightLevel(LightType.SKY, pos);
connector.getInstance()
.setBlockLight(block)
.setSkyLight(sky);
pipe.getInstance()
.setBlockLight(block)
.setSkyLight(sky);
}
}

View file

@ -8,6 +8,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.schematics.block.LaunchedItem.ForBlockState;
import com.simibubi.create.content.schematics.block.LaunchedItem.ForEntity;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import net.minecraft.block.BlockState;
@ -40,33 +41,20 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
protected void renderSafe(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
IRenderTypeBuffer buffer, int light, int overlay) {
double yaw = 0;
double pitch = 40;
boolean blocksLaunching = !tileEntityIn.flyingBlocks.isEmpty();
if (blocksLaunching)
renderLaunchedBlocks(tileEntityIn, partialTicks, ms, buffer, light, overlay);
if (FastRenderDispatcher.available(tileEntityIn.getWorld())) return;
BlockPos pos = tileEntityIn.getPos();
if (tileEntityIn.target != null) {
// Calculate Angle of Cannon
Vec3d diff = new Vec3d(tileEntityIn.target.subtract(pos));
if (tileEntityIn.previousTarget != null) {
diff = (new Vec3d(tileEntityIn.previousTarget)
.add(new Vec3d(tileEntityIn.target.subtract(tileEntityIn.previousTarget)).scale(partialTicks)))
.subtract(new Vec3d(pos));
}
double[] cannonAngles = getCannonAngles(tileEntityIn, pos, partialTicks);
double diffX = diff.getX();
double diffZ = diff.getZ();
yaw = MathHelper.atan2(diffX, diffZ);
yaw = yaw / Math.PI * 180;
double pitch = cannonAngles[0];
double yaw = cannonAngles[1];
float distance = MathHelper.sqrt(diffX * diffX + diffZ * diffZ);
double yOffset = 0 + distance * 2f;
pitch = MathHelper.atan2(distance, diff.getY() * 3 + yOffset);
pitch = pitch / Math.PI * 180 + 10;
}
double recoil = !tileEntityIn.flyingBlocks.isEmpty() ? getRecoil(tileEntityIn, partialTicks, ms, buffer, light, overlay) : 0;
double recoil = getRecoil(tileEntityIn, partialTicks);
ms.push();
BlockState state = tileEntityIn.getBlockState();
@ -91,9 +79,51 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
ms.pop();
}
private double getRecoil(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
public static double[] getCannonAngles(SchematicannonTileEntity tile, BlockPos pos, float partialTicks) {
double yaw = 0;
double pitch = 40;
if (tile.target != null) {
// Calculate Angle of Cannon
Vec3d diff = new Vec3d(tile.target.subtract(pos));
if (tile.previousTarget != null) {
diff = (new Vec3d(tile.previousTarget)
.add(new Vec3d(tile.target.subtract(tile.previousTarget)).scale(partialTicks)))
.subtract(new Vec3d(pos));
}
double diffX = diff.getX();
double diffZ = diff.getZ();
yaw = MathHelper.atan2(diffX, diffZ);
yaw = yaw / Math.PI * 180;
float distance = MathHelper.sqrt(diffX * diffX + diffZ * diffZ);
double yOffset = 0 + distance * 2f;
pitch = MathHelper.atan2(distance, diff.getY() * 3 + yOffset);
pitch = pitch / Math.PI * 180 + 10;
}
return new double[] { pitch, yaw };
}
public static double getRecoil(SchematicannonTileEntity tileEntityIn, float partialTicks) {
double recoil = 0;
for (LaunchedItem launched : tileEntityIn.flyingBlocks) {
if (launched.ticksRemaining == 0) continue;
// Apply Recoil if block was just launched
if ((launched.ticksRemaining + 1 - partialTicks) > launched.totalTicks - 10)
recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10);
}
return recoil;
}
private static void renderLaunchedBlocks(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
for (LaunchedItem launched : tileEntityIn.flyingBlocks) {
if (launched.ticksRemaining == 0)
@ -141,10 +171,6 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
ms.pop();
// Apply Recoil if block was just launched
if ((launched.ticksRemaining + 1 - partialTicks) > launched.totalTicks - 10)
recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10);
// Render particles for launch
if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) {
tileEntityIn.firstRenderTick = false;
@ -162,8 +188,6 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
}
}
return recoil;
}
}

View file

@ -9,6 +9,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltPart;
import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
@ -23,6 +24,7 @@ import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.config.CSchematics;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.BlockHelper;
@ -63,11 +65,12 @@ import net.minecraft.world.gen.feature.template.Template;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
public class SchematicannonTileEntity extends SmartTileEntity implements INamedContainerProvider {
public class SchematicannonTileEntity extends SmartTileEntity implements INamedContainerProvider, IInstanceRendered {
public static final int NEIGHBOUR_CHECKING = 100;
public static final int MAX_ANCHOR_DISTANCE = 256;
@ -934,4 +937,20 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
findInventories();
}
@Override
public void initialize() {
super.initialize();
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.add(this));
}
@Override
public void onChunkLightUpdate() {
CreateClient.kineticRenderer.onLightUpdate(this);
}
@Override
public boolean shouldRenderAsTE() {
return true;
}
}

View file

@ -4,6 +4,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@ -23,6 +24,14 @@ public class MatrixStacker {
return instance;
}
public MatrixStacker rotate(Direction axis, float radians) {
if (radians == 0)
return this;
ms.multiply(axis.getUnitVector()
.getRadialQuaternion(radians));
return this;
}
public MatrixStacker rotate(double angle, Axis axis) {
Vector3f vec =
axis == Axis.X ? Vector3f.POSITIVE_X : axis == Axis.Y ? Vector3f.POSITIVE_Y : Vector3f.POSITIVE_Z;