87 lines
3.2 KiB
Java
87 lines
3.2 KiB
Java
package net.minecraft.client.renderer.entity.layers;
|
|
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import com.mojang.math.Axis;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.model.Model;
|
|
import net.minecraft.client.model.PlayerModel;
|
|
import net.minecraft.client.model.geom.ModelPart;
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
|
|
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.RandomSource;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public abstract class StuckInBodyLayer<M extends PlayerModel> extends RenderLayer<PlayerRenderState, M> {
|
|
private final Model model;
|
|
private final ResourceLocation texture;
|
|
private final StuckInBodyLayer.PlacementStyle placementStyle;
|
|
|
|
public StuckInBodyLayer(
|
|
LivingEntityRenderer<?, PlayerRenderState, M> renderer, Model model, ResourceLocation texture, StuckInBodyLayer.PlacementStyle placementStyle
|
|
) {
|
|
super(renderer);
|
|
this.model = model;
|
|
this.texture = texture;
|
|
this.placementStyle = placementStyle;
|
|
}
|
|
|
|
protected abstract int numStuck(PlayerRenderState renderState);
|
|
|
|
private void renderStuckItem(PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, float x, float y, float z) {
|
|
float f = Mth.sqrt(x * x + z * z);
|
|
float g = (float)(Math.atan2(x, z) * 180.0F / (float)Math.PI);
|
|
float h = (float)(Math.atan2(y, f) * 180.0F / (float)Math.PI);
|
|
poseStack.mulPose(Axis.YP.rotationDegrees(g - 90.0F));
|
|
poseStack.mulPose(Axis.ZP.rotationDegrees(h));
|
|
this.model.renderToBuffer(poseStack, bufferSource.getBuffer(this.model.renderType(this.texture)), packedLight, OverlayTexture.NO_OVERLAY);
|
|
}
|
|
|
|
public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, PlayerRenderState playerRenderState, float f, float g) {
|
|
int j = this.numStuck(playerRenderState);
|
|
if (j > 0) {
|
|
RandomSource randomSource = RandomSource.create(playerRenderState.id);
|
|
|
|
for (int k = 0; k < j; k++) {
|
|
poseStack.pushPose();
|
|
ModelPart modelPart = this.getParentModel().getRandomBodyPart(randomSource);
|
|
ModelPart.Cube cube = modelPart.getRandomCube(randomSource);
|
|
modelPart.translateAndRotate(poseStack);
|
|
float h = randomSource.nextFloat();
|
|
float l = randomSource.nextFloat();
|
|
float m = randomSource.nextFloat();
|
|
if (this.placementStyle == StuckInBodyLayer.PlacementStyle.ON_SURFACE) {
|
|
int n = randomSource.nextInt(3);
|
|
switch (n) {
|
|
case 0:
|
|
h = snapToFace(h);
|
|
break;
|
|
case 1:
|
|
l = snapToFace(l);
|
|
break;
|
|
default:
|
|
m = snapToFace(m);
|
|
}
|
|
}
|
|
|
|
poseStack.translate(Mth.lerp(h, cube.minX, cube.maxX) / 16.0F, Mth.lerp(l, cube.minY, cube.maxY) / 16.0F, Mth.lerp(m, cube.minZ, cube.maxZ) / 16.0F);
|
|
this.renderStuckItem(poseStack, multiBufferSource, i, -(h * 2.0F - 1.0F), -(l * 2.0F - 1.0F), -(m * 2.0F - 1.0F));
|
|
poseStack.popPose();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static float snapToFace(float value) {
|
|
return value > 0.5F ? 1.0F : 0.5F;
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public static enum PlacementStyle {
|
|
IN_CUBE,
|
|
ON_SURFACE;
|
|
}
|
|
}
|