Create/src/main/java/com/simibubi/create/content/kinetics/saw/SawRenderer.java
zelophed 9098002c17 Wait it's all Flywheel? Always has been.
- add flywheel as a dependency to catnip
2023-08-13 23:39:10 +02:00

206 lines
7.8 KiB
Java

package com.simibubi.create.content.kinetics.saw;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
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.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
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.VecHelper;
import net.createmod.catnip.utility.math.AngleHelper;
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;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
public class SawRenderer extends SafeBlockEntityRenderer<SawBlockEntity> {
public SawRenderer(BlockEntityRendererProvider.Context context) {
}
@Override
protected void renderSafe(SawBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light,
int overlay) {
renderBlade(be, ms, buffer, light);
renderItems(be, partialTicks, ms, buffer, light, overlay);
FilteringRenderer.renderOnBlockEntity(be, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(be.getLevel()))
return;
renderShaft(be, ms, buffer, light, overlay);
}
protected void renderBlade(SawBlockEntity be, PoseStack ms, MultiBufferSource buffer, int light) {
BlockState blockState = be.getBlockState();
PartialModel partial;
float speed = be.getSpeed();
boolean rotate = false;
if (SawBlock.isHorizontal(blockState)) {
if (speed > 0) {
partial = AllPartialModels.SAW_BLADE_HORIZONTAL_ACTIVE;
} else if (speed < 0) {
partial = AllPartialModels.SAW_BLADE_HORIZONTAL_REVERSED;
} else {
partial = AllPartialModels.SAW_BLADE_HORIZONTAL_INACTIVE;
}
} else {
if (be.getSpeed() > 0) {
partial = AllPartialModels.SAW_BLADE_VERTICAL_ACTIVE;
} else if (speed < 0) {
partial = AllPartialModels.SAW_BLADE_VERTICAL_REVERSED;
} else {
partial = AllPartialModels.SAW_BLADE_VERTICAL_INACTIVE;
}
if (blockState.getValue(SawBlock.AXIS_ALONG_FIRST_COORDINATE))
rotate = true;
}
SuperByteBuffer superBuffer = CachedBuffers.partialFacing(partial, blockState);
if (rotate) {
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(90));
}
superBuffer.color(0xFFFFFF)
.light(light)
.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped()));
}
protected void renderShaft(SawBlockEntity be, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
KineticBlockEntityRenderer.renderRotatingBuffer(be, getRotatedModel(be), ms,
buffer.getBuffer(RenderType.solid()), light);
}
protected void renderItems(SawBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
boolean processingMode = be.getBlockState()
.getValue(SawBlock.FACING) == Direction.UP;
if (processingMode && !be.inventory.isEmpty()) {
boolean alongZ = !be.getBlockState()
.getValue(SawBlock.AXIS_ALONG_FIRST_COORDINATE);
ms.pushPose();
boolean moving = be.inventory.recipeDuration != 0;
float offset = moving ? (float) (be.inventory.remainingTime) / be.inventory.recipeDuration : 0;
float processingSpeed = Mth.clamp(Math.abs(be.getSpeed()) / 32, 1, 128);
if (moving) {
offset = Mth
.clamp(offset + ((-partialTicks + .5f) * processingSpeed) / be.inventory.recipeDuration, 0.125f, 1f);
if (!be.inventory.appliedRecipe)
offset += 1;
offset /= 2;
}
if (be.getSpeed() == 0)
offset = .5f;
if (be.getSpeed() < 0 ^ alongZ)
offset = 1 - offset;
for (int i = 0; i < be.inventory.getSlots(); i++) {
ItemStack stack = be.inventory.getStackInSlot(i);
if (stack.isEmpty())
continue;
ItemRenderer itemRenderer = Minecraft.getInstance()
.getItemRenderer();
BakedModel modelWithOverrides = itemRenderer.getModel(stack, be.getLevel(), null, 0);
boolean blockItem = modelWithOverrides.isGui3d();
ms.translate(alongZ ? offset : .5, blockItem ? .925f : 13f / 16f, alongZ ? .5 : offset);
ms.scale(.5f, .5f, .5f);
if (alongZ)
ms.mulPose(Vector3f.YP.rotationDegrees(90));
ms.mulPose(Vector3f.XP.rotationDegrees(90));
itemRenderer.renderStatic(stack, ItemTransforms.TransformType.FIXED, light, overlay, ms, buffer, 0);
break;
}
ms.popPose();
}
}
protected SuperByteBuffer getRotatedModel(KineticBlockEntity be) {
BlockState state = be.getBlockState();
if (state.getValue(FACING)
.getAxis()
.isHorizontal())
return CachedBuffers.partialFacing(AllPartialModels.SHAFT_HALF,
state.rotate(be.getLevel(), be.getBlockPos(), Rotation.CLOCKWISE_180));
return CachedBuffers.block(KineticBlockEntityRenderer.KINETIC_BLOCK,
getRenderedBlockState(be));
}
protected BlockState getRenderedBlockState(KineticBlockEntity be) {
return KineticBlockEntityRenderer.shaft(KineticBlockEntityRenderer.getRotationAxisOf(be));
}
public static void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) {
BlockState state = context.state;
Direction facing = state.getValue(SawBlock.FACING);
Vec3 facingVec = Vec3.atLowerCornerOf(context.state.getValue(SawBlock.FACING)
.getNormal());
facingVec = context.rotation.apply(facingVec);
Direction closestToFacing = Direction.getNearest(facingVec.x, facingVec.y, facingVec.z);
boolean horizontal = closestToFacing.getAxis()
.isHorizontal();
boolean backwards = VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite());
boolean moving = context.getAnimationSpeed() != 0;
boolean shouldAnimate =
(context.contraption.stalled && horizontal) || (!context.contraption.stalled && !backwards && moving);
SuperByteBuffer superBuffer;
if (SawBlock.isHorizontal(state)) {
if (shouldAnimate)
superBuffer = CachedBuffers.partial(AllPartialModels.SAW_BLADE_HORIZONTAL_ACTIVE, state);
else
superBuffer = CachedBuffers.partial(AllPartialModels.SAW_BLADE_HORIZONTAL_INACTIVE, state);
} else {
if (shouldAnimate)
superBuffer = CachedBuffers.partial(AllPartialModels.SAW_BLADE_VERTICAL_ACTIVE, state);
else
superBuffer = CachedBuffers.partial(AllPartialModels.SAW_BLADE_VERTICAL_INACTIVE, state);
}
superBuffer.transform(matrices.getModel())
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing));
if (!SawBlock.isHorizontal(state)) {
superBuffer.rotateZ(state.getValue(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? 90 : 0);
}
superBuffer.unCentre()
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped()));
}
}