diff --git a/src/engine/math/Quaternion.java b/src/engine/math/Quaternion.java index 448bd84b..ec879168 100644 --- a/src/engine/math/Quaternion.java +++ b/src/engine/math/Quaternion.java @@ -1142,6 +1142,17 @@ public class Quaternion { return opposite(this); } + // Client MakeRotateY (Math.dll 0x10002960): w = cos θ/2, y = sin θ/2, radians. + // Math rather than FastMath: FastMath.reduceSinAngle mis-reduces angles below -π. + public static Quaternion fromYaw(float yaw) { + return new Quaternion(0f, (float) Math.sin(yaw * 0.5), 0f, (float) Math.cos(yaw * 0.5)); + } + + // The angle MakeRotateY would need to produce this rotation; characters send it as one float. + public float getYaw() { + return 2 * FastMath.atan2(y, w); + } + @Override public Quaternion clone() { try { diff --git a/src/engine/math/Transform.java b/src/engine/math/Transform.java new file mode 100644 index 00000000..a3314915 --- /dev/null +++ b/src/engine/math/Transform.java @@ -0,0 +1,45 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2026 +// https://www.magicbane.com + +package engine.math; + +// The client's placement (ArcObjectInfo +0x28/+0x34/+0x44, math::Transformation); see MBDATA/specs/WorldPlacement.md §7. + +public class Transform { + + public final Vector3fImmutable location; + public final Quaternion rotation; + public final Vector3f scale; + + public Transform(Vector3fImmutable location, Quaternion rotation, Vector3f scale) { + this.location = location; + this.rotation = rotation; + this.scale = scale; + } + + public static Transform fromYaw(Vector3fImmutable location, float yaw) { + return new Transform(location, Quaternion.fromYaw(yaw), new Vector3f(1.0f, 1.0f, 1.0f)); + } + + // world = parent × local, as the client composes zone and object transforms (sb.exe 0x6516C0). + public static Transform mult(Transform parent, Transform local) { + + Vector3f scaledLocation; + Vector3f rotatedLocation; + Quaternion rotation; + Vector3f scale; + + scaledLocation = new Vector3f(local.location).mult(parent.scale); + rotatedLocation = parent.rotation.mult(scaledLocation); + rotation = parent.rotation.mult(local.rotation); + scale = parent.scale.mult(local.scale); + + return new Transform(parent.location.add(rotatedLocation), rotation, scale); + } + +}