182 lines
5.4 KiB
Java
182 lines
5.4 KiB
Java
package net.minecraft.client.renderer.item;
|
|
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import java.util.Arrays;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
import net.minecraft.client.renderer.RenderType;
|
|
import net.minecraft.client.renderer.block.model.ItemTransform;
|
|
import net.minecraft.client.renderer.entity.ItemRenderer;
|
|
import net.minecraft.client.renderer.special.SpecialModelRenderer;
|
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
import net.minecraft.client.resources.model.BakedModel;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.item.ItemDisplayContext;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class ItemStackRenderState {
|
|
ItemDisplayContext displayContext = ItemDisplayContext.NONE;
|
|
boolean isLeftHand;
|
|
private int activeLayerCount;
|
|
private ItemStackRenderState.LayerRenderState[] layers = new ItemStackRenderState.LayerRenderState[]{new ItemStackRenderState.LayerRenderState()};
|
|
|
|
public void ensureCapacity(int expectedSize) {
|
|
int i = this.layers.length;
|
|
int j = this.activeLayerCount + expectedSize;
|
|
if (j > i) {
|
|
this.layers = (ItemStackRenderState.LayerRenderState[])Arrays.copyOf(this.layers, j);
|
|
|
|
for (int k = i; k < j; k++) {
|
|
this.layers[k] = new ItemStackRenderState.LayerRenderState();
|
|
}
|
|
}
|
|
}
|
|
|
|
public ItemStackRenderState.LayerRenderState newLayer() {
|
|
this.ensureCapacity(1);
|
|
return this.layers[this.activeLayerCount++];
|
|
}
|
|
|
|
public void clear() {
|
|
this.displayContext = ItemDisplayContext.NONE;
|
|
this.isLeftHand = false;
|
|
|
|
for (int i = 0; i < this.activeLayerCount; i++) {
|
|
this.layers[i].clear();
|
|
}
|
|
|
|
this.activeLayerCount = 0;
|
|
}
|
|
|
|
private ItemStackRenderState.LayerRenderState firstLayer() {
|
|
return this.layers[0];
|
|
}
|
|
|
|
public boolean isEmpty() {
|
|
return this.activeLayerCount == 0;
|
|
}
|
|
|
|
public boolean isGui3d() {
|
|
return this.firstLayer().isGui3d();
|
|
}
|
|
|
|
public boolean usesBlockLight() {
|
|
return this.firstLayer().usesBlockLight();
|
|
}
|
|
|
|
@Nullable
|
|
public TextureAtlasSprite pickParticleIcon(RandomSource random) {
|
|
if (this.activeLayerCount == 0) {
|
|
return null;
|
|
} else {
|
|
BakedModel bakedModel = this.layers[random.nextInt(this.activeLayerCount)].model;
|
|
return bakedModel == null ? null : bakedModel.getParticleIcon();
|
|
}
|
|
}
|
|
|
|
public ItemTransform transform() {
|
|
return this.firstLayer().transform();
|
|
}
|
|
|
|
public void render(PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
|
|
for (int i = 0; i < this.activeLayerCount; i++) {
|
|
this.layers[i].render(poseStack, bufferSource, packedLight, packedOverlay);
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public static enum FoilType {
|
|
NONE,
|
|
STANDARD,
|
|
SPECIAL;
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class LayerRenderState {
|
|
@Nullable
|
|
BakedModel model;
|
|
@Nullable
|
|
private RenderType renderType;
|
|
private ItemStackRenderState.FoilType foilType = ItemStackRenderState.FoilType.NONE;
|
|
private int[] tintLayers = new int[0];
|
|
@Nullable
|
|
private SpecialModelRenderer<Object> specialRenderer;
|
|
@Nullable
|
|
private Object argumentForSpecialRendering;
|
|
|
|
public void clear() {
|
|
this.model = null;
|
|
this.renderType = null;
|
|
this.foilType = ItemStackRenderState.FoilType.NONE;
|
|
this.specialRenderer = null;
|
|
this.argumentForSpecialRendering = null;
|
|
Arrays.fill(this.tintLayers, -1);
|
|
}
|
|
|
|
public void setupBlockModel(BakedModel model, RenderType renderType) {
|
|
this.model = model;
|
|
this.renderType = renderType;
|
|
}
|
|
|
|
public <T> void setupSpecialModel(SpecialModelRenderer<T> specialRenderer, @Nullable T argumentForSpecialRendering, BakedModel model) {
|
|
this.model = model;
|
|
this.specialRenderer = eraseSpecialRenderer(specialRenderer);
|
|
this.argumentForSpecialRendering = argumentForSpecialRendering;
|
|
}
|
|
|
|
private static SpecialModelRenderer<Object> eraseSpecialRenderer(SpecialModelRenderer<?> specialRenderer) {
|
|
return (SpecialModelRenderer<Object>)specialRenderer;
|
|
}
|
|
|
|
public void setFoilType(ItemStackRenderState.FoilType foilType) {
|
|
this.foilType = foilType;
|
|
}
|
|
|
|
public int[] prepareTintLayers(int count) {
|
|
if (count > this.tintLayers.length) {
|
|
this.tintLayers = new int[count];
|
|
Arrays.fill(this.tintLayers, -1);
|
|
}
|
|
|
|
return this.tintLayers;
|
|
}
|
|
|
|
ItemTransform transform() {
|
|
return this.model != null ? this.model.getTransforms().getTransform(ItemStackRenderState.this.displayContext) : ItemTransform.NO_TRANSFORM;
|
|
}
|
|
|
|
void render(PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
|
|
poseStack.pushPose();
|
|
this.transform().apply(ItemStackRenderState.this.isLeftHand, poseStack);
|
|
poseStack.translate(-0.5F, -0.5F, -0.5F);
|
|
if (this.specialRenderer != null) {
|
|
this.specialRenderer
|
|
.render(
|
|
this.argumentForSpecialRendering,
|
|
ItemStackRenderState.this.displayContext,
|
|
poseStack,
|
|
bufferSource,
|
|
packedLight,
|
|
packedOverlay,
|
|
this.foilType != ItemStackRenderState.FoilType.NONE
|
|
);
|
|
} else if (this.model != null) {
|
|
ItemRenderer.renderItem(
|
|
ItemStackRenderState.this.displayContext, poseStack, bufferSource, packedLight, packedOverlay, this.tintLayers, this.model, this.renderType, this.foilType
|
|
);
|
|
}
|
|
|
|
poseStack.popPose();
|
|
}
|
|
|
|
boolean isGui3d() {
|
|
return this.model != null && this.model.isGui3d();
|
|
}
|
|
|
|
boolean usesBlockLight() {
|
|
return this.model != null && this.model.usesBlockLight();
|
|
}
|
|
}
|
|
}
|