mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-06-11 07:09:01 +02:00
9098002c17
- add flywheel as a dependency to catnip
233 lines
9.5 KiB
Java
233 lines
9.5 KiB
Java
package com.simibubi.create.content.kinetics.deployer;
|
|
|
|
import static com.simibubi.create.content.kinetics.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE;
|
|
import static com.simibubi.create.content.kinetics.base.DirectionalKineticBlock.FACING;
|
|
|
|
import com.jozufozu.flywheel.backend.Backend;
|
|
import com.jozufozu.flywheel.core.PartialModel;
|
|
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
|
|
import com.jozufozu.flywheel.util.transform.TransformStack;
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
|
import com.mojang.math.Vector3f;
|
|
import com.simibubi.create.AllBlocks;
|
|
import com.simibubi.create.AllPartialModels;
|
|
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
|
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
|
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
|
|
import com.simibubi.create.content.kinetics.base.IRotate;
|
|
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
|
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
|
|
import com.simibubi.create.content.kinetics.deployer.DeployerBlockEntity.Mode;
|
|
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringRenderer;
|
|
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
|
|
|
|
import net.createmod.catnip.render.CachedBuffers;
|
|
import net.createmod.catnip.render.SuperByteBuffer;
|
|
import net.createmod.catnip.utility.AnimationTickHolder;
|
|
import net.createmod.catnip.utility.NBTHelper;
|
|
import net.createmod.catnip.utility.VecHelper;
|
|
import net.createmod.catnip.utility.math.AngleHelper;
|
|
import net.createmod.ponder.utility.WorldTickHolder;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
import net.minecraft.client.renderer.RenderType;
|
|
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
|
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
|
import net.minecraft.client.renderer.entity.ItemRenderer;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.Direction.Axis;
|
|
import net.minecraft.core.Direction.AxisDirection;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.item.BlockItem;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.phys.Vec3;
|
|
|
|
public class DeployerRenderer extends SafeBlockEntityRenderer<DeployerBlockEntity> {
|
|
|
|
public DeployerRenderer(BlockEntityRendererProvider.Context context) {
|
|
}
|
|
|
|
@Override
|
|
protected void renderSafe(DeployerBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
|
|
int light, int overlay) {
|
|
renderItem(be, partialTicks, ms, buffer, light, overlay);
|
|
FilteringRenderer.renderOnBlockEntity(be, partialTicks, ms, buffer, light, overlay);
|
|
|
|
if (Backend.canUseInstancing(be.getLevel())) return;
|
|
|
|
renderComponents(be, partialTicks, ms, buffer, light, overlay);
|
|
}
|
|
|
|
protected void renderItem(DeployerBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
|
|
int light, int overlay) {
|
|
|
|
if (be.heldItem.isEmpty()) return;
|
|
|
|
BlockState deployerState = be.getBlockState();
|
|
Vec3 offset = getHandOffset(be, partialTicks, deployerState).add(VecHelper.getCenterOf(BlockPos.ZERO));
|
|
ms.pushPose();
|
|
ms.translate(offset.x, offset.y, offset.z);
|
|
|
|
Direction facing = deployerState.getValue(FACING);
|
|
boolean punching = be.mode == Mode.PUNCH;
|
|
|
|
float yRot = AngleHelper.horizontalAngle(facing) + 180;
|
|
float xRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0;
|
|
boolean displayMode = facing == Direction.UP && be.getSpeed() == 0 && !punching;
|
|
|
|
ms.mulPose(Vector3f.YP.rotationDegrees(yRot));
|
|
if (!displayMode) {
|
|
ms.mulPose(Vector3f.XP.rotationDegrees(xRot));
|
|
ms.translate(0, 0, -11 / 16f);
|
|
}
|
|
|
|
if (punching)
|
|
ms.translate(0, 1 / 8f, -1 / 16f);
|
|
|
|
ItemRenderer itemRenderer = Minecraft.getInstance()
|
|
.getItemRenderer();
|
|
|
|
TransformType transform = TransformType.NONE;
|
|
boolean isBlockItem = (be.heldItem.getItem() instanceof BlockItem)
|
|
&& itemRenderer.getModel(be.heldItem, be.getLevel(), null, 0)
|
|
.isGui3d();
|
|
|
|
if (displayMode) {
|
|
float scale = isBlockItem ? 1.25f : 1;
|
|
ms.translate(0, isBlockItem ? 9 / 16f : 11 / 16f, 0);
|
|
ms.scale(scale, scale, scale);
|
|
transform = TransformType.GROUND;
|
|
ms.mulPose(Vector3f.YP.rotationDegrees(WorldTickHolder.getRenderTime(be.getLevel())));
|
|
|
|
} else {
|
|
float scale = punching ? .75f : isBlockItem ? .75f - 1 / 64f : .5f;
|
|
ms.scale(scale, scale, scale);
|
|
transform = punching ? TransformType.THIRD_PERSON_RIGHT_HAND : TransformType.FIXED;
|
|
}
|
|
|
|
itemRenderer.renderStatic(be.heldItem, transform, light, overlay, ms, buffer, 0);
|
|
ms.popPose();
|
|
}
|
|
|
|
protected void renderComponents(DeployerBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
|
|
int light, int overlay) {
|
|
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
|
|
if (!Backend.canUseInstancing(be.getLevel())) {
|
|
KineticBlockEntityRenderer.renderRotatingKineticBlock(be, getRenderedBlockState(be), ms, vb, light);
|
|
}
|
|
|
|
BlockState blockState = be.getBlockState();
|
|
Vec3 offset = getHandOffset(be, partialTicks, blockState);
|
|
|
|
SuperByteBuffer pole = CachedBuffers.partial(AllPartialModels.DEPLOYER_POLE, blockState);
|
|
SuperByteBuffer hand = CachedBuffers.partial(be.getHandPose(), blockState);
|
|
|
|
transform(pole.translate(offset.x, offset.y, offset.z), blockState, true)
|
|
.light(light)
|
|
.renderInto(ms, vb);
|
|
transform(hand.translate(offset.x, offset.y, offset.z), blockState, false)
|
|
.light(light)
|
|
.renderInto(ms, vb);
|
|
}
|
|
|
|
protected Vec3 getHandOffset(DeployerBlockEntity be, float partialTicks, BlockState blockState) {
|
|
float distance = be.getHandOffset(partialTicks);
|
|
return Vec3.atLowerCornerOf(blockState.getValue(FACING).getNormal()).scale(distance);
|
|
}
|
|
|
|
protected BlockState getRenderedBlockState(KineticBlockEntity be) {
|
|
return KineticBlockEntityRenderer.shaft(KineticBlockEntityRenderer.getRotationAxisOf(be));
|
|
}
|
|
|
|
private static SuperByteBuffer transform(SuperByteBuffer buffer, BlockState deployerState, boolean axisDirectionMatters) {
|
|
Direction facing = deployerState.getValue(FACING);
|
|
|
|
float yRot = AngleHelper.horizontalAngle(facing);
|
|
float xRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
|
|
float zRot =
|
|
axisDirectionMatters && (deployerState.getValue(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Axis.Z) ? 90
|
|
: 0;
|
|
|
|
buffer.rotateCentered(Direction.UP, (float) ((yRot) / 180 * Math.PI));
|
|
buffer.rotateCentered(Direction.EAST, (float) ((xRot) / 180 * Math.PI));
|
|
buffer.rotateCentered(Direction.SOUTH, (float) ((zRot) / 180 * Math.PI));
|
|
return buffer;
|
|
}
|
|
|
|
public static void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
|
|
ContraptionMatrices matrices, MultiBufferSource buffer) {
|
|
VertexConsumer builder = buffer.getBuffer(RenderType.solid());
|
|
BlockState blockState = context.state;
|
|
Mode mode = NBTHelper.readEnum(context.blockEntityData, "Mode", Mode.class);
|
|
PartialModel handPose = getHandPose(mode);
|
|
|
|
float speed = (float) context.getAnimationSpeed();
|
|
if (context.contraption.stalled)
|
|
speed = 0;
|
|
|
|
SuperByteBuffer shaft = CachedBuffers.block(AllBlocks.SHAFT.getDefaultState());
|
|
SuperByteBuffer pole = CachedBuffers.partial(AllPartialModels.DEPLOYER_POLE, blockState);
|
|
SuperByteBuffer hand = CachedBuffers.partial(handPose, blockState);
|
|
|
|
double factor;
|
|
if (context.contraption.stalled || context.position == null || context.data.contains("StationaryTimer")) {
|
|
factor = Mth.sin(AnimationTickHolder.getRenderTime() * .5f) * .25f + .25f;
|
|
} else {
|
|
Vec3 center = VecHelper.getCenterOf(new BlockPos(context.position));
|
|
double distance = context.position.distanceTo(center);
|
|
double nextDistance = context.position.add(context.motion)
|
|
.distanceTo(center);
|
|
factor = .5f - Mth.clamp(Mth.lerp(AnimationTickHolder.getPartialTicks(), distance, nextDistance), 0, 1);
|
|
}
|
|
|
|
Vec3 offset = Vec3.atLowerCornerOf(blockState.getValue(FACING)
|
|
.getNormal()).scale(factor);
|
|
|
|
PoseStack m = matrices.getModel();
|
|
m.pushPose();
|
|
|
|
m.pushPose();
|
|
Axis axis = Axis.Y;
|
|
if (context.state.getBlock() instanceof IRotate) {
|
|
IRotate def = (IRotate) context.state.getBlock();
|
|
axis = def.getRotationAxis(context.state);
|
|
}
|
|
|
|
float time = WorldTickHolder.getRenderTime(context.world) / 20;
|
|
float angle = (time * speed) % 360;
|
|
|
|
TransformStack.cast(m)
|
|
.centre()
|
|
.rotateY(axis == Axis.Z ? 90 : 0)
|
|
.rotateZ(axis.isHorizontal() ? 90 : 0)
|
|
.unCentre();
|
|
shaft.transform(m);
|
|
shaft.rotateCentered(Direction.get(AxisDirection.POSITIVE, Axis.Y), angle);
|
|
m.popPose();
|
|
|
|
if (!context.disabled)
|
|
m.translate(offset.x, offset.y, offset.z);
|
|
pole.transform(m);
|
|
hand.transform(m);
|
|
|
|
transform(pole, blockState, true);
|
|
transform(hand, blockState, false);
|
|
|
|
shaft.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
|
|
.renderInto(matrices.getViewProjection(), builder);
|
|
pole.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
|
|
.renderInto(matrices.getViewProjection(), builder);
|
|
hand.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
|
|
.renderInto(matrices.getViewProjection(), builder);
|
|
|
|
m.popPose();
|
|
}
|
|
|
|
static PartialModel getHandPose(DeployerBlockEntity.Mode mode) {
|
|
return mode == DeployerBlockEntity.Mode.PUNCH ? AllPartialModels.DEPLOYER_HAND_PUNCHING : AllPartialModels.DEPLOYER_HAND_POINTING;
|
|
}
|
|
|
|
}
|