174 lines
6.1 KiB
Java
174 lines
6.1 KiB
Java
package net.minecraft.client.renderer.block.model;
|
|
|
|
import com.google.common.collect.Maps;
|
|
import com.google.gson.JsonArray;
|
|
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.lang.reflect.Type;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.util.GsonHelper;
|
|
import net.minecraft.util.Mth;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector3fc;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public record BlockElement(
|
|
Vector3fc from, Vector3fc to, Map<Direction, BlockElementFace> faces, @Nullable BlockElementRotation rotation, boolean shade, int lightEmission
|
|
) {
|
|
private static final boolean DEFAULT_RESCALE = false;
|
|
private static final float MIN_EXTENT = -16.0F;
|
|
private static final float MAX_EXTENT = 32.0F;
|
|
|
|
public BlockElement(Vector3fc from, Vector3fc to, Map<Direction, BlockElementFace> faces) {
|
|
this(from, to, faces, null, true, 0);
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
protected static class Deserializer implements JsonDeserializer<BlockElement> {
|
|
private static final boolean DEFAULT_SHADE = true;
|
|
private static final int DEFAULT_LIGHT_EMISSION = 0;
|
|
|
|
public BlockElement deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
|
|
JsonObject jsonObject = json.getAsJsonObject();
|
|
Vector3f vector3f = this.getFrom(jsonObject);
|
|
Vector3f vector3f2 = this.getTo(jsonObject);
|
|
BlockElementRotation blockElementRotation = this.getRotation(jsonObject);
|
|
Map<Direction, BlockElementFace> map = this.getFaces(context, jsonObject);
|
|
if (jsonObject.has("shade") && !GsonHelper.isBooleanValue(jsonObject, "shade")) {
|
|
throw new JsonParseException("Expected shade to be a Boolean");
|
|
} else {
|
|
boolean bl = GsonHelper.getAsBoolean(jsonObject, "shade", true);
|
|
int i = 0;
|
|
if (jsonObject.has("light_emission")) {
|
|
boolean bl2 = GsonHelper.isNumberValue(jsonObject, "light_emission");
|
|
if (bl2) {
|
|
i = GsonHelper.getAsInt(jsonObject, "light_emission");
|
|
}
|
|
|
|
if (!bl2 || i < 0 || i > 15) {
|
|
throw new JsonParseException("Expected light_emission to be an Integer between (inclusive) 0 and 15");
|
|
}
|
|
}
|
|
|
|
return new BlockElement(vector3f, vector3f2, map, blockElementRotation, bl, i);
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
private BlockElementRotation getRotation(JsonObject json) {
|
|
BlockElementRotation blockElementRotation = null;
|
|
if (json.has("rotation")) {
|
|
JsonObject jsonObject = GsonHelper.getAsJsonObject(json, "rotation");
|
|
Vector3f vector3f = this.getVector3f(jsonObject, "origin");
|
|
vector3f.mul(0.0625F);
|
|
Direction.Axis axis = this.getAxis(jsonObject);
|
|
float f = this.getAngle(jsonObject);
|
|
boolean bl = GsonHelper.getAsBoolean(jsonObject, "rescale", false);
|
|
blockElementRotation = new BlockElementRotation(vector3f, axis, f, bl);
|
|
}
|
|
|
|
return blockElementRotation;
|
|
}
|
|
|
|
private float getAngle(JsonObject json) {
|
|
float f = GsonHelper.getAsFloat(json, "angle");
|
|
if (f != 0.0F && Mth.abs(f) != 22.5F && Mth.abs(f) != 45.0F) {
|
|
throw new JsonParseException("Invalid rotation " + f + " found, only -45/-22.5/0/22.5/45 allowed");
|
|
} else {
|
|
return f;
|
|
}
|
|
}
|
|
|
|
private Direction.Axis getAxis(JsonObject json) {
|
|
String string = GsonHelper.getAsString(json, "axis");
|
|
Direction.Axis axis = Direction.Axis.byName(string.toLowerCase(Locale.ROOT));
|
|
if (axis == null) {
|
|
throw new JsonParseException("Invalid rotation axis: " + string);
|
|
} else {
|
|
return axis;
|
|
}
|
|
}
|
|
|
|
private Map<Direction, BlockElementFace> getFaces(JsonDeserializationContext context, JsonObject json) {
|
|
Map<Direction, BlockElementFace> map = this.filterNullFromFaces(context, json);
|
|
if (map.isEmpty()) {
|
|
throw new JsonParseException("Expected between 1 and 6 unique faces, got 0");
|
|
} else {
|
|
return map;
|
|
}
|
|
}
|
|
|
|
private Map<Direction, BlockElementFace> filterNullFromFaces(JsonDeserializationContext context, JsonObject json) {
|
|
Map<Direction, BlockElementFace> map = Maps.newEnumMap(Direction.class);
|
|
JsonObject jsonObject = GsonHelper.getAsJsonObject(json, "faces");
|
|
|
|
for (Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
|
Direction direction = this.getFacing((String)entry.getKey());
|
|
map.put(direction, (BlockElementFace)context.deserialize((JsonElement)entry.getValue(), BlockElementFace.class));
|
|
}
|
|
|
|
return map;
|
|
}
|
|
|
|
private Direction getFacing(String name) {
|
|
Direction direction = Direction.byName(name);
|
|
if (direction == null) {
|
|
throw new JsonParseException("Unknown facing: " + name);
|
|
} else {
|
|
return direction;
|
|
}
|
|
}
|
|
|
|
private Vector3f getTo(JsonObject json) {
|
|
Vector3f vector3f = this.getVector3f(json, "to");
|
|
if (!(vector3f.x() < -16.0F)
|
|
&& !(vector3f.y() < -16.0F)
|
|
&& !(vector3f.z() < -16.0F)
|
|
&& !(vector3f.x() > 32.0F)
|
|
&& !(vector3f.y() > 32.0F)
|
|
&& !(vector3f.z() > 32.0F)) {
|
|
return vector3f;
|
|
} else {
|
|
throw new JsonParseException("'to' specifier exceeds the allowed boundaries: " + vector3f);
|
|
}
|
|
}
|
|
|
|
private Vector3f getFrom(JsonObject json) {
|
|
Vector3f vector3f = this.getVector3f(json, "from");
|
|
if (!(vector3f.x() < -16.0F)
|
|
&& !(vector3f.y() < -16.0F)
|
|
&& !(vector3f.z() < -16.0F)
|
|
&& !(vector3f.x() > 32.0F)
|
|
&& !(vector3f.y() > 32.0F)
|
|
&& !(vector3f.z() > 32.0F)) {
|
|
return vector3f;
|
|
} else {
|
|
throw new JsonParseException("'from' specifier exceeds the allowed boundaries: " + vector3f);
|
|
}
|
|
}
|
|
|
|
private Vector3f getVector3f(JsonObject json, String memberName) {
|
|
JsonArray jsonArray = GsonHelper.getAsJsonArray(json, memberName);
|
|
if (jsonArray.size() != 3) {
|
|
throw new JsonParseException("Expected 3 " + memberName + " values, found: " + jsonArray.size());
|
|
} else {
|
|
float[] fs = new float[3];
|
|
|
|
for (int i = 0; i < fs.length; i++) {
|
|
fs[i] = GsonHelper.convertToFloat(jsonArray.get(i), memberName + "[" + i + "]");
|
|
}
|
|
|
|
return new Vector3f(fs[0], fs[1], fs[2]);
|
|
}
|
|
}
|
|
}
|
|
}
|