mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-10 20:45:10 +01:00
Instanced flywheels, engines, and schematicannons.
This commit is contained in:
parent
d8ab00b66e
commit
d0a6f4123b
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -100,9 +100,4 @@ public class FlywheelTileEntity extends GeneratingKineticTileEntity {
|
||||
updateGeneratedRotation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderAsTE() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user