block bench 'support boilerplate
This commit is contained in:
parent
9d9f8aeedf
commit
715eafaf51
11 changed files with 618 additions and 3 deletions
4
block-bench-addon/README.md
Normal file
4
block-bench-addon/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
Block Bench addon for EntityLib
|
||||
|
||||
Gives complete support of making block bench bedrock compatible models in EntityLib, with animations.
|
||||
This is a direct port of the WorldSeedEntityEngine made by my good pal iam https://github.com/AtlasEngineCa/WorldSeedEntityEngine/blob/master. Permission was granted to port this repository to EntityLib by iam himself.
|
|
@ -11,9 +11,9 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
// compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.4")
|
||||
api(project(":api"))
|
||||
|
||||
compileOnly(libs.packetevents.api)
|
||||
compileOnly(libs.gson)
|
||||
implementation("commons-io:commons-io:2.11.0")
|
||||
implementation("org.zeroturnaround:zt-zip:1.8")
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
package me.tofaa.entitylib.bb;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.component.ComponentTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.google.gson.*;
|
||||
import me.tofaa.entitylib.bb.mql.MQLPoint;
|
||||
|
||||
import javax.json.JsonNumber;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class ModelEngine {
|
||||
|
||||
public final static HashMap<String, Vector3d> offsetMappings = new HashMap<>();
|
||||
public final static HashMap<String, Vector3d> diffMappings = new HashMap<>();
|
||||
static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
private final static HashMap<String, HashMap<String, ItemStack>> blockMappings = new HashMap<>();
|
||||
|
||||
private static Path modelPath;
|
||||
private static ItemType modelMaterial = ItemTypes.MAGMA_CREAM;
|
||||
|
||||
/**
|
||||
* Loads the model from the given path
|
||||
*
|
||||
* @param mappingsData mappings file created by model parser
|
||||
* @param modelPath path of the models
|
||||
*/
|
||||
public static void loadMappings(Reader mappingsData, Path modelPath) {
|
||||
JsonObject map = GSON.fromJson(mappingsData, JsonObject.class);
|
||||
ModelEngine.modelPath = modelPath;
|
||||
|
||||
blockMappings.clear();
|
||||
offsetMappings.clear();
|
||||
diffMappings.clear();
|
||||
ModelLoader.clearCache();
|
||||
|
||||
map.entrySet().forEach(entry -> {
|
||||
HashMap<String, ItemStack> keys = new HashMap<>();
|
||||
|
||||
entry.getValue().getAsJsonObject()
|
||||
.get("id")
|
||||
.getAsJsonObject()
|
||||
.entrySet()
|
||||
.forEach(id -> keys.put(id.getKey(), generateBoneItem(id.getValue().getAsInt())));
|
||||
|
||||
blockMappings.put(entry.getKey(), keys);
|
||||
offsetMappings.put(entry.getKey(), getPos(entry.getValue().getAsJsonObject().get("offset").getAsJsonArray()).orElse(Vector3d.zero()));
|
||||
diffMappings.put(entry.getKey(), getPos(entry.getValue().getAsJsonObject().get("diff").getAsJsonArray()).orElse(Vector3d.zero()));
|
||||
});
|
||||
}
|
||||
|
||||
private static ItemStack generateBoneItem(int model_id) {
|
||||
return ItemStack.builder()
|
||||
.type(modelMaterial)
|
||||
.component(ComponentTypes.CUSTOM_MODEL_DATA, model_id)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static HashMap<String, ItemStack> getItems(String model, String name) {
|
||||
return blockMappings.get(model + "/" + name);
|
||||
}
|
||||
|
||||
public static Path getGeoPath(String id) {
|
||||
return modelPath.resolve(id).resolve("model.geo.json");
|
||||
}
|
||||
|
||||
public static Path getAnimationPath(String id) {
|
||||
return modelPath.resolve(id).resolve("model.animation.json");
|
||||
}
|
||||
|
||||
public static Optional<Vector3d> getPos(JsonElement pivot) {
|
||||
if (pivot == null) return Optional.empty();
|
||||
else {
|
||||
JsonArray arr = pivot.getAsJsonArray();
|
||||
return Optional.of(new Vector3d(arr.get(0).getAsDouble(), arr.get(1).getAsDouble(), arr.get(2).getAsDouble()));
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<MQLPoint> getMQLPos(JsonElement pivot) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
if (pivot == null) return Optional.empty();
|
||||
else if (pivot instanceof JsonObject) {
|
||||
JsonObject obj = (JsonObject) pivot;
|
||||
return Optional.of(new MQLPoint(obj));
|
||||
} else if (pivot instanceof JsonNumber) {
|
||||
JsonNumber num = (JsonNumber) pivot;
|
||||
return Optional.of(new MQLPoint(num.doubleValue(), num.doubleValue(), num.doubleValue()));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemType getModelMaterial() {
|
||||
return modelMaterial;
|
||||
}
|
||||
|
||||
public static void setModelMaterial(ItemType modelMaterial) {
|
||||
ModelEngine.modelMaterial = modelMaterial;
|
||||
}
|
||||
|
||||
public static Optional<MQLPoint> getMQLPos(JsonArray arr) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
if (arr == null) return Optional.empty();
|
||||
else {
|
||||
return Optional.of(new MQLPoint(arr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
package me.tofaa.entitylib.bb;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import me.tofaa.entitylib.bb.animation.FrameProvider;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ModelLoader {
|
||||
protected static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
private static final Map<String, JsonObject> loadedAnimations = new HashMap<>();
|
||||
private static final Map<String, JsonObject> loadedModels = new HashMap<>();
|
||||
|
||||
// <Model> -> <Bone/Animation>
|
||||
private static final Map<String, Map<String, FrameProvider>> interpolationTranslateCache = new HashMap<>();
|
||||
private static final Map<String, Map<String, FrameProvider>> interpolationRotateCache = new HashMap<>();
|
||||
private static final Map<String, Map<String, FrameProvider>> interpolationScaleCache = new HashMap<>();
|
||||
|
||||
public static void clearCache() {
|
||||
interpolationTranslateCache.clear();
|
||||
interpolationRotateCache.clear();
|
||||
interpolationScaleCache.clear();
|
||||
loadedAnimations.clear();
|
||||
loadedModels.clear();
|
||||
}
|
||||
|
||||
public static JsonObject loadAnimations(String toLoad) {
|
||||
if (loadedAnimations.containsKey(toLoad))
|
||||
return loadedAnimations.get(toLoad);
|
||||
|
||||
JsonObject loadedAnimations1;
|
||||
|
||||
try {
|
||||
loadedAnimations1 = GSON
|
||||
.fromJson(
|
||||
new InputStreamReader(Files.newInputStream(ModelEngine.getAnimationPath(toLoad))),
|
||||
JsonObject.class
|
||||
);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
loadedAnimations1 = null;
|
||||
}
|
||||
|
||||
loadedAnimations.put(toLoad, loadedAnimations1);
|
||||
return loadedAnimations1;
|
||||
}
|
||||
|
||||
public static JsonObject loadModel(String id) {
|
||||
if (loadedModels.containsKey(id))
|
||||
return loadedModels.get(id);
|
||||
|
||||
JsonObject loadedModel1;
|
||||
try {
|
||||
loadedModel1 = GSON.fromJson(new InputStreamReader(Files.newInputStream(ModelEngine.getGeoPath(id))), JsonObject.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
loadedModel1 = null;
|
||||
}
|
||||
|
||||
loadedModels.put(id, loadedModel1);
|
||||
return loadedModel1;
|
||||
}
|
||||
|
||||
public static void addToTranslationCache(String key, String model, FrameProvider val) {
|
||||
if (!interpolationTranslateCache.containsKey(model))
|
||||
interpolationTranslateCache.put(model, new HashMap<>());
|
||||
|
||||
interpolationTranslateCache.get(model).put(key, val);
|
||||
}
|
||||
|
||||
public static void addToRotationCache(String key, String model, FrameProvider val) {
|
||||
if (!interpolationRotateCache.containsKey(model))
|
||||
interpolationRotateCache.put(model, new HashMap<>());
|
||||
|
||||
interpolationRotateCache.get(model).put(key, val);
|
||||
}
|
||||
|
||||
public static void addToScaleCache(String key, String model, FrameProvider val) {
|
||||
if (!interpolationScaleCache.containsKey(model))
|
||||
interpolationScaleCache.put(model, new HashMap<>());
|
||||
|
||||
interpolationScaleCache.get(model).put(key, val);
|
||||
}
|
||||
|
||||
public static FrameProvider getCacheRotation(String key, String model) {
|
||||
Map<String, FrameProvider> m = interpolationRotateCache.get(model);
|
||||
if (m == null) return null;
|
||||
return m.get(key);
|
||||
}
|
||||
|
||||
public static FrameProvider getCacheTranslation(String key, String model) {
|
||||
Map<String, FrameProvider> m = interpolationTranslateCache.get(model);
|
||||
if (m == null) return null;
|
||||
return m.get(key);
|
||||
}
|
||||
|
||||
public static FrameProvider getCacheScale(String modelName, String s) {
|
||||
Map<String, FrameProvider> m = interpolationScaleCache.get(modelName);
|
||||
if (m == null) return null;
|
||||
return m.get(s);
|
||||
}
|
||||
|
||||
public static Map<String, JsonObject> parseAnimations(String animationString) {
|
||||
Map<String, JsonObject> res = new LinkedHashMap<>();
|
||||
|
||||
JsonObject animations = GSON.fromJson(new StringReader(animationString), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> animation : animations.get("animations").getAsJsonObject().entrySet()) {
|
||||
res.put(animation.getKey(), animation.getValue().getAsJsonObject());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public enum AnimationType {
|
||||
ROTATION, SCALE, TRANSLATION
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package me.tofaa.entitylib.bb;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
|
||||
class Matrix3 {
|
||||
double x1, x2, x3;
|
||||
double y1, y2, y3;
|
||||
double z1, z2, z3;
|
||||
|
||||
Matrix3(double x1, double x2, double x3, double y1, double y2, double y3, double z1, double z2, double z3) {
|
||||
this.x1 = x1;
|
||||
this.x2 = x2;
|
||||
this.x3 = x3;
|
||||
this.y1 = y1;
|
||||
this.y2 = y2;
|
||||
this.y3 = y3;
|
||||
this.z1 = z1;
|
||||
this.z2 = z2;
|
||||
this.z3 = z3;
|
||||
}
|
||||
|
||||
Matrix3 mul(Matrix3 matrix3) {
|
||||
double x1 = this.x1 * matrix3.x1 + this.x2 * matrix3.y1 + this.x3 * matrix3.z1;
|
||||
double x2 = this.x1 * matrix3.x2 + this.x2 * matrix3.y2 + this.x3 * matrix3.z2;
|
||||
double x3 = this.x1 * matrix3.x3 + this.x2 * matrix3.y3 + this.x3 * matrix3.z3;
|
||||
|
||||
double y1 = this.y1 * matrix3.x1 + this.y2 * matrix3.y1 + this.y3 * matrix3.z1;
|
||||
double y2 = this.y1 * matrix3.x2 + this.y2 * matrix3.y2 + this.y3 * matrix3.z2;
|
||||
double y3 = this.y1 * matrix3.x3 + this.y2 * matrix3.y3 + this.y3 * matrix3.z3;
|
||||
|
||||
double z1 = this.z1 * matrix3.x1 + this.z2 * matrix3.y1 + this.z3 * matrix3.z1;
|
||||
double z2 = this.z1 * matrix3.x2 + this.z2 * matrix3.y2 + this.z3 * matrix3.z2;
|
||||
double z3 = this.z1 * matrix3.x3 + this.z2 * matrix3.y3 + this.z3 * matrix3.z3;
|
||||
|
||||
return new Matrix3(x1, x2, x3, y1, y2, y3, z1, z2, z3);
|
||||
}
|
||||
|
||||
Vector3d mul(Vector3d vec) {
|
||||
double vx = vec.getX() * x1 + vec.getY() * x2 + vec.getZ() * x3;
|
||||
double vy = vec.getX() * y1 + vec.getY() * y2 + vec.getZ() * y3;
|
||||
double vz = vec.getX() * z1 + vec.getY() * z2 + vec.getZ() * z3;
|
||||
|
||||
return new Vector3d(vx, vy, vz);
|
||||
}
|
||||
}
|
||||
|
||||
public class ModelMath {
|
||||
private static final float DEGREE = 0.017453292519943295F;
|
||||
private static final float RADIAN = 57.29577951308232F;
|
||||
|
||||
static Vector3d toRadians(Vector3d vector) {
|
||||
return vector.multiply(DEGREE);
|
||||
}
|
||||
|
||||
static Vector3d toDegrees(Vector3d vector) {
|
||||
return vector.multiply(RADIAN);
|
||||
}
|
||||
|
||||
public static Vector3d rotate(Vector3d vector, Vector3d rotation) {
|
||||
Vector3d rot = toRadians(rotation);
|
||||
|
||||
double rotX = rot.getX();
|
||||
double rotY = rot.getY();
|
||||
double rotZ = rot.getZ();
|
||||
|
||||
double cosX = Math.cos(rotX);
|
||||
double sinX = Math.sin(rotX);
|
||||
double cosY = Math.cos(rotY);
|
||||
double sinY = Math.sin(rotY);
|
||||
double cosZ = Math.cos(rotZ);
|
||||
double sinZ = Math.sin(rotZ);
|
||||
|
||||
Matrix3 rotMatrixX = new Matrix3(1, 0, 0, 0, cosX, -sinX, 0, sinX, cosX);
|
||||
Matrix3 rotMatrixY = new Matrix3(cosY, 0, sinY, 0, 1, 0, -sinY, 0, cosY);
|
||||
Matrix3 rotMatrixZ = new Matrix3(cosZ, -sinZ, 0, sinZ, cosZ, 0, 0, 0, 1);
|
||||
|
||||
return rotMatrixZ.mul(rotMatrixY).mul(rotMatrixX).mul(vector);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package me.tofaa.entitylib.bb;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
|
||||
public final class Quaternion {
|
||||
|
||||
private final double x;
|
||||
private final double y;
|
||||
private final double z;
|
||||
|
||||
private final double w;
|
||||
|
||||
public Quaternion(double x, double y, double z, double w) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
public Quaternion(Vector3d p) {
|
||||
p = ModelMath.toRadians(p);
|
||||
|
||||
double cy = Math.cos(p.getZ() * 0.5);
|
||||
double sy = Math.sin(p.getZ() * 0.5);
|
||||
double cp = Math.cos(p.getY() * 0.5);
|
||||
double sp = Math.sin(p.getY() * 0.5);
|
||||
double cr = Math.cos(p.getX() * 0.5);
|
||||
double sr = Math.sin(p.getX() * 0.5);
|
||||
|
||||
w = cr * cp * cy + sr * sp * sy;
|
||||
x = sr * cp * cy - cr * sp * sy;
|
||||
y = cr * sp * cy + sr * cp * sy;
|
||||
z = cr * cp * sy - sr * sp * cy;
|
||||
}
|
||||
|
||||
public double x() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double y() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double z() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public double w() {
|
||||
return w;
|
||||
}
|
||||
|
||||
public Vector3d toEuler() {
|
||||
double t0 = (x + z) * (x - z); // x^2-z^2
|
||||
double t1 = (w + y) * (w - y); // w^2-y^2
|
||||
double xx = 0.5 * (t0 + t1); // 1/2 x of x'
|
||||
double xy = x * y + w * z; // 1/2 y of x'
|
||||
double xz = w * y - x * z; // 1/2 z of x'
|
||||
double t = xx * xx + xy * xy; // cos(theta)^2
|
||||
double yz = 2.0 * (y * z + w * x); // z of y'
|
||||
|
||||
double vx, vy, vz;
|
||||
|
||||
vz = (float) Math.atan2(xy, xx); // yaw (psi)
|
||||
vy = (float) Math.atan(xz / Math.sqrt(t)); // pitch (theta)
|
||||
|
||||
if (t != 0)
|
||||
vx = (float) Math.atan2(yz, t1 - t0);
|
||||
else
|
||||
vx = (float) (2.0 * Math.atan2(x, w) - Math.signum(xz) * vz);
|
||||
|
||||
return ModelMath.toDegrees(new Vector3d(vx, vy, vz));
|
||||
}
|
||||
|
||||
public Quaternion multiply(Quaternion q) {
|
||||
double w = this.w * q.w - this.x * q.x - this.y * q.y - this.z * q.z;
|
||||
double x = this.w * q.x + this.x * q.w + this.y * q.z - this.z * q.y;
|
||||
double y = this.w * q.y - this.x * q.z + this.y * q.w + this.z * q.x;
|
||||
double z = this.w * q.z + this.x * q.y - this.y * q.x + this.z * q.w;
|
||||
|
||||
return new Quaternion(
|
||||
x, y, z, w
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "me.tofaa.entitylib.bb.Quaternion{" +
|
||||
"x=" + x +
|
||||
", y=" + y +
|
||||
", z=" + z +
|
||||
", w=" + w +
|
||||
'}';
|
||||
}
|
||||
|
||||
Vector3d threeAxisRot(double r11, double r12, double r21, double r31, double r32) {
|
||||
double x = Math.atan2(r31, r32);
|
||||
double y = Math.asin(r21);
|
||||
double z = Math.atan2(r11, r12);
|
||||
return new Vector3d(x, z, y);
|
||||
}
|
||||
|
||||
public Vector3d toEulerYZX() {
|
||||
Quaternion q = this;
|
||||
return ModelMath.toDegrees(threeAxisRot(-2 * (q.x * q.z - q.w * q.y),
|
||||
q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
|
||||
2 * (q.x * q.y + q.w * q.z),
|
||||
-2 * (q.y * q.z - q.w * q.x),
|
||||
q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package me.tofaa.entitylib.bb.animation;
|
||||
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
|
||||
public interface FrameProvider {
|
||||
Vector3d RotationMul = new Vector3d(-1, -1, 1);
|
||||
Vector3d TranslationMul = new Vector3d(-1, 1, 1);
|
||||
|
||||
Vector3d getFrame(int tick);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package me.tofaa.entitylib.bb.mql;
|
||||
|
||||
import net.hollowcube.mql.foreign.Query;
|
||||
|
||||
public class MQLData {
|
||||
private double time;
|
||||
|
||||
public void setTime(double time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Query
|
||||
public double anim_time() {
|
||||
return time;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package me.tofaa.entitylib.bb.mql;
|
||||
|
||||
import net.hollowcube.mql.jit.MqlEnv;
|
||||
|
||||
public interface MQLEvaluator {
|
||||
double evaluate(@MqlEnv({"q", "query"}) MQLData data);
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package me.tofaa.entitylib.bb.mql;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.hollowcube.mql.jit.MqlCompiler;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class MQLPoint {
|
||||
public static final MQLPoint ZERO = new MQLPoint();
|
||||
MQLEvaluator molangX = null;
|
||||
MQLEvaluator molangY = null;
|
||||
MQLEvaluator molangZ = null;
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
MQLData data = new MQLData();
|
||||
|
||||
public MQLPoint() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
}
|
||||
|
||||
public MQLPoint(double x_, double y_, double z_) {
|
||||
x = x_;
|
||||
y = y_;
|
||||
z = z_;
|
||||
}
|
||||
|
||||
public MQLPoint(JsonObject json) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
JsonElement fx = json.get("x");
|
||||
if (fx != null) {
|
||||
try {
|
||||
x = fx.getAsDouble();
|
||||
} catch (Exception ignored) {
|
||||
molangX = fromString(fx.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
JsonElement fy = json.get("y");
|
||||
if (fy != null) {
|
||||
try {
|
||||
y = fy.getAsDouble();
|
||||
} catch (Exception ignored) {
|
||||
molangY = fromString(fy.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
JsonElement fz = json.get("z");
|
||||
if (fz != null) {
|
||||
try {
|
||||
z = fz.getAsDouble();
|
||||
} catch (Exception ignored) {
|
||||
molangZ = fromString(fz.getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MQLPoint(JsonArray arr) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
JsonElement fx = arr.get(0);
|
||||
if (fx != null) {
|
||||
try {
|
||||
x = fx.getAsDouble();
|
||||
} catch (Exception ignored) {
|
||||
molangX = fromString(fx.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
JsonElement fy = arr.get(1);
|
||||
if (fy != null) {
|
||||
try {
|
||||
y = fy.getAsDouble();
|
||||
} catch (Exception ignored) {
|
||||
molangY = fromString(fy.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
JsonElement fz = arr.get(2);
|
||||
if (fz != null) {
|
||||
try {
|
||||
z = fz.getAsDouble();
|
||||
} catch (Exception ignored) {
|
||||
molangZ = fromString(fz.getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MQLEvaluator fromDouble(double value) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
return fromString(Double.toString(value));
|
||||
}
|
||||
|
||||
static MQLEvaluator fromString(String s) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
if (s == null || s.isEmpty()) return fromDouble(0);
|
||||
MqlCompiler<MQLEvaluator> compiler = new MqlCompiler<>(MQLEvaluator.class);
|
||||
Class<MQLEvaluator> scriptClass = compiler.compile(s.trim().replace("Math", "math"));
|
||||
return scriptClass.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
public Vector3d evaluate(double time) {
|
||||
data.setTime(time);
|
||||
|
||||
double evaluatedX = x;
|
||||
if (molangX != null) {
|
||||
try {
|
||||
evaluatedX = molangX.evaluate(data);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
double evaluatedY = y;
|
||||
if (molangY != null) {
|
||||
try {
|
||||
evaluatedY = molangY.evaluate(data);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
double evaluatedZ = z;
|
||||
if (molangZ != null) {
|
||||
try {
|
||||
evaluatedZ = molangZ.evaluate(data);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector3d(evaluatedX, evaluatedY, evaluatedZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (molangX != null || molangY != null || molangZ != null) {
|
||||
return "MQLPoint{" +
|
||||
"x=" + molangX +
|
||||
", y=" + molangY +
|
||||
", z=" + molangZ +
|
||||
'}';
|
||||
}
|
||||
|
||||
return "MQLPoint{" +
|
||||
"x=" + x +
|
||||
", y=" + y +
|
||||
", z=" + z +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -37,5 +37,5 @@ include(":platforms:standalone")
|
|||
if (!System.getenv("JITPACK").toBoolean()) {
|
||||
include(":code-gen")
|
||||
include(":test-plugin")
|
||||
include(":model-engine-addon")
|
||||
include(":block-bench-addon")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue