185 lines
6 KiB
Java
185 lines
6 KiB
Java
package net.minecraft.client.renderer.block.model;
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
import com.google.gson.JsonDeserializationContext;
|
|
import com.google.gson.JsonDeserializer;
|
|
import com.google.gson.JsonElement;
|
|
import com.google.gson.JsonObject;
|
|
import com.google.gson.JsonParseException;
|
|
import java.io.Reader;
|
|
import java.lang.reflect.Type;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.renderer.texture.TextureAtlas;
|
|
import net.minecraft.client.resources.model.BakedModel;
|
|
import net.minecraft.client.resources.model.ModelBaker;
|
|
import net.minecraft.client.resources.model.ModelState;
|
|
import net.minecraft.client.resources.model.ResolvableModel;
|
|
import net.minecraft.client.resources.model.SimpleBakedModel;
|
|
import net.minecraft.client.resources.model.UnbakedModel;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.util.GsonHelper;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class BlockModel implements UnbakedModel {
|
|
@VisibleForTesting
|
|
static final Gson GSON = new GsonBuilder()
|
|
.registerTypeAdapter(BlockModel.class, new BlockModel.Deserializer())
|
|
.registerTypeAdapter(BlockElement.class, new BlockElement.Deserializer())
|
|
.registerTypeAdapter(BlockElementFace.class, new BlockElementFace.Deserializer())
|
|
.registerTypeAdapter(BlockFaceUV.class, new BlockFaceUV.Deserializer())
|
|
.registerTypeAdapter(ItemTransform.class, new ItemTransform.Deserializer())
|
|
.registerTypeAdapter(ItemTransforms.class, new ItemTransforms.Deserializer())
|
|
.create();
|
|
private final List<BlockElement> elements;
|
|
@Nullable
|
|
private final UnbakedModel.GuiLight guiLight;
|
|
@Nullable
|
|
private final Boolean hasAmbientOcclusion;
|
|
@Nullable
|
|
private final ItemTransforms transforms;
|
|
@VisibleForTesting
|
|
private final TextureSlots.Data textureSlots;
|
|
@Nullable
|
|
private UnbakedModel parent;
|
|
@Nullable
|
|
private final ResourceLocation parentLocation;
|
|
|
|
public static BlockModel fromStream(Reader reader) {
|
|
return GsonHelper.fromJson(GSON, reader, BlockModel.class);
|
|
}
|
|
|
|
public BlockModel(
|
|
@Nullable ResourceLocation parentLocation,
|
|
List<BlockElement> elements,
|
|
TextureSlots.Data textureSlots,
|
|
@Nullable Boolean hasAmbientOcclusion,
|
|
@Nullable UnbakedModel.GuiLight guiLight,
|
|
@Nullable ItemTransforms transforms
|
|
) {
|
|
this.elements = elements;
|
|
this.hasAmbientOcclusion = hasAmbientOcclusion;
|
|
this.guiLight = guiLight;
|
|
this.textureSlots = textureSlots;
|
|
this.parentLocation = parentLocation;
|
|
this.transforms = transforms;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public Boolean getAmbientOcclusion() {
|
|
return this.hasAmbientOcclusion;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public UnbakedModel.GuiLight getGuiLight() {
|
|
return this.guiLight;
|
|
}
|
|
|
|
@Override
|
|
public void resolveDependencies(ResolvableModel.Resolver resolver) {
|
|
if (this.parentLocation != null) {
|
|
this.parent = resolver.resolve(this.parentLocation);
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public UnbakedModel getParent() {
|
|
return this.parent;
|
|
}
|
|
|
|
@Override
|
|
public TextureSlots.Data getTextureSlots() {
|
|
return this.textureSlots;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public ItemTransforms getTransforms() {
|
|
return this.transforms;
|
|
}
|
|
|
|
@Override
|
|
public BakedModel bake(
|
|
TextureSlots textureSlots, ModelBaker baker, ModelState modelState, boolean hasAmbientOcclusion, boolean useBlockLight, ItemTransforms transforms
|
|
) {
|
|
return this.elements.isEmpty() && this.parent != null
|
|
? this.parent.bake(textureSlots, baker, modelState, hasAmbientOcclusion, useBlockLight, transforms)
|
|
: SimpleBakedModel.bakeElements(this.elements, textureSlots, baker.sprites(), modelState, hasAmbientOcclusion, useBlockLight, true, transforms);
|
|
}
|
|
|
|
@Nullable
|
|
@VisibleForTesting
|
|
List<BlockElement> getElements() {
|
|
return this.elements;
|
|
}
|
|
|
|
@Nullable
|
|
@VisibleForTesting
|
|
ResourceLocation getParentLocation() {
|
|
return this.parentLocation;
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public static class Deserializer implements JsonDeserializer<BlockModel> {
|
|
public BlockModel deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
|
|
JsonObject jsonObject = json.getAsJsonObject();
|
|
List<BlockElement> list = this.getElements(context, jsonObject);
|
|
String string = this.getParentName(jsonObject);
|
|
TextureSlots.Data data = this.getTextureMap(jsonObject);
|
|
Boolean boolean_ = this.getAmbientOcclusion(jsonObject);
|
|
ItemTransforms itemTransforms = null;
|
|
if (jsonObject.has("display")) {
|
|
JsonObject jsonObject2 = GsonHelper.getAsJsonObject(jsonObject, "display");
|
|
itemTransforms = context.deserialize(jsonObject2, ItemTransforms.class);
|
|
}
|
|
|
|
UnbakedModel.GuiLight guiLight = null;
|
|
if (jsonObject.has("gui_light")) {
|
|
guiLight = UnbakedModel.GuiLight.getByName(GsonHelper.getAsString(jsonObject, "gui_light"));
|
|
}
|
|
|
|
ResourceLocation resourceLocation = string.isEmpty() ? null : ResourceLocation.parse(string);
|
|
return new BlockModel(resourceLocation, list, data, boolean_, guiLight, itemTransforms);
|
|
}
|
|
|
|
private TextureSlots.Data getTextureMap(JsonObject json) {
|
|
if (json.has("textures")) {
|
|
JsonObject jsonObject = GsonHelper.getAsJsonObject(json, "textures");
|
|
return TextureSlots.parseTextureMap(jsonObject, TextureAtlas.LOCATION_BLOCKS);
|
|
} else {
|
|
return TextureSlots.Data.EMPTY;
|
|
}
|
|
}
|
|
|
|
private String getParentName(JsonObject json) {
|
|
return GsonHelper.getAsString(json, "parent", "");
|
|
}
|
|
|
|
@Nullable
|
|
protected Boolean getAmbientOcclusion(JsonObject json) {
|
|
return json.has("ambientocclusion") ? GsonHelper.getAsBoolean(json, "ambientocclusion") : null;
|
|
}
|
|
|
|
protected List<BlockElement> getElements(JsonDeserializationContext context, JsonObject json) {
|
|
if (!json.has("elements")) {
|
|
return List.of();
|
|
} else {
|
|
List<BlockElement> list = new ArrayList();
|
|
|
|
for (JsonElement jsonElement : GsonHelper.getAsJsonArray(json, "elements")) {
|
|
list.add((BlockElement)context.deserialize(jsonElement, BlockElement.class));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
}
|
|
}
|
|
}
|