armory/Sources/armory/math/Rotator.hx
2020-02-19 14:24:31 +01:00

209 lines
6.3 KiB
Haxe

package armory.math;
import kha.FastFloat;
import iron.math.Mat4;
class Rotator {
public var pitch: FastFloat; // X - look up or down around the X axis
public var roll: FastFloat; // Y - axis tilt left or right around the Y axis
public var yaw: FastFloat; // Z - heading or facing angle around the Z (up) axis
public function new(pitch: FastFloat = 0.0, roll: FastFloat = 0.0, yaw: FastFloat = 0.0) {
this.pitch = pitch;
this.roll = roll;
this.yaw = yaw;
}
public function toDegrees(): Rotator {
pitch = Helper.radToDeg(pitch);
roll = Helper.radToDeg(roll);
yaw = Helper.radToDeg(yaw);
return this;
}
public function toRadians(): Rotator {
pitch = Helper.degToRad(pitch);
roll = Helper.degToRad(roll);
yaw = Helper.degToRad(yaw);
return this;
}
public function cross(r: Rotator): Rotator {
var x2 = roll * r.yaw - yaw * r.roll;
var y2 = yaw * r.pitch - pitch * r.yaw;
var z2 = pitch * r.roll - roll * r.pitch;
pitch = x2;
roll = y2;
yaw = z2;
return this;
}
public function crossvecs(a: Rotator, b: Rotator): Rotator {
var x2 = a.roll * b.yaw - a.yaw * b.roll;
var y2 = a.yaw * b.pitch - a.pitch * b.yaw;
var z2 = a.pitch * b.roll - a.roll * b.pitch;
pitch = x2;
roll = y2;
yaw = z2;
return this;
}
public function set(pitch: FastFloat, roll: FastFloat, yaw: FastFloat): Rotator{
this.pitch = pitch;
this.roll = roll;
this.yaw = yaw;
return this;
}
public function add(r: Rotator): Rotator {
pitch += r.pitch;
roll += r.roll;
yaw += r.yaw;
return this;
}
public function addf(pitch: FastFloat, roll: FastFloat, yaw: FastFloat): Rotator {
this.pitch += pitch;
this.roll += roll;
this.yaw += yaw;
return this;
}
public function addvecs(a: Rotator, b: Rotator): Rotator {
pitch = a.pitch + b.pitch;
roll = a.roll + b.roll;
yaw = a.yaw + b.yaw;
return this;
}
public function subvecs(a: Rotator, b: Rotator): Rotator {
pitch = a.pitch - b.pitch;
roll = a.roll - b.roll;
yaw = a.yaw - b.yaw;
return this;
}
public function normalize(): Rotator {
var n = length();
if (n > 0.0) {
var invN = 1.0 / n;
this.pitch *= invN; this.roll *= invN; this.yaw *= invN;
}
return this;
}
public function mult(f: FastFloat): Rotator {
pitch *= f; roll *= f; yaw *= f;
return this;
}
public function dot(r: Rotator): FastFloat {
return pitch * r.pitch + roll * r.roll + yaw * r.yaw;
}
public function setFrom(r: Rotator): Rotator {
pitch = r.pitch; roll = r.roll; yaw = r.yaw;
return this;
}
public function clone(): Rotator {
return new Rotator(pitch, roll, yaw);
}
public static function lerp(from: Rotator, to: Rotator, s: FastFloat): Rotator {
var target = new Rotator();
target.pitch = from.pitch + (to.pitch - from.pitch) * s;
target.roll = from.roll + (to.roll - from.roll) * s;
target.yaw = from.yaw + (to.yaw - from.yaw) * s;
return target;
}
public function applyproj(m: Mat4): Rotator {
var pitch = this.pitch; var roll = this.roll; var yaw = this.yaw;
// Perspective divide
var d = 1.0 / (m._03 * pitch + m._13 * roll + m._23 * yaw + m._33);
this.pitch = (m._00 * pitch + m._10 * roll + m._20 * yaw + m._30) * d;
this.roll = (m._01 * pitch + m._11 * roll + m._21 * yaw + m._31) * d;
this.yaw = (m._02 * pitch + m._12 * roll + m._22 * yaw + m._32) * d;
return this;
}
public function applymat(m: Mat4): Rotator {
var pitch = this.pitch; var roll = this.roll; var yaw = this.yaw;
this.pitch = m._00 * pitch + m._10 * roll + m._20 * yaw + m._30;
this.roll = m._01 * pitch + m._11 * roll + m._21 * yaw + m._31;
this.yaw = m._02 * pitch + m._12 * roll + m._22 * yaw + m._32;
return this;
}
public inline function equals(r: Rotator): Bool {
return pitch == r.pitch && roll == r.roll && yaw == r.yaw;
}
public inline function length(): FastFloat {
return Math.sqrt(pitch * pitch + roll * roll + yaw * yaw);
}
public inline function normalizeTo(newLength: FastFloat): Rotator {
var v = normalize();
v = mult(newLength);
return v;
}
public function sub(r: Rotator): Rotator {
pitch -= r.pitch; roll -= r.roll; yaw -= r.yaw;
return this;
}
public static inline function distance(r1: Rotator, r2: Rotator): FastFloat {
return distancef(r1.pitch, r1.roll, r1.yaw, r2.pitch, r2.roll, r2.yaw);
}
public static inline function distancef(r1pitch: FastFloat, r1roll: FastFloat, r1yaw: FastFloat, r2pitch: FastFloat, r2roll: FastFloat, r2yaw: FastFloat): FastFloat {
var pitch = r1pitch - r2pitch;
var roll = r1roll - r2roll;
var yaw = r1yaw - r2yaw;
return Math.sqrt(pitch * pitch + roll * roll + yaw * yaw);
}
public function distanceTo(r: Rotator): FastFloat {
return Math.sqrt((r.pitch - pitch) * (r.pitch - pitch) + (r.roll - roll) * (r.roll - roll) + (r.yaw - yaw) * (r.yaw - yaw));
}
public function clamp(): Rotator {
this.pitch = clampAxis(this.pitch);
this.roll = clampAxis(this.roll);
this.yaw = clampAxis(this.yaw);
return this;
}
public static inline function clampAxis(angle: FastFloat): FastFloat {
angle = angle % 360; // Makes the angle between -360 and +360
if (angle < 0.0) angle += 360.0;
return angle;
}
public static function xAxis(): Rotator { return new Rotator(1.0, 0.0, 0.0); }
public static function yAxis(): Rotator { return new Rotator(0.0, 1.0, 0.0); }
public static function zAxis(): Rotator { return new Rotator(0.0, 0.0, 1.0); }
public static function one(): Rotator { return new Rotator(1.0, 1.0, 1.0); }
public static function zero(): Rotator { return new Rotator(0.0, 0.0, 0.0); }
public static function back(): Rotator { return new Rotator(0.0, -1.0, 0.0); }
public static function forward(): Rotator { return new Rotator(0.0, 1.0, 0.0); }
public static function down(): Rotator { return new Rotator(0.0, 0.0, -1.0); }
public static function up(): Rotator { return new Rotator(0.0, 0.0, 1.0); }
public static function left(): Rotator { return new Rotator(-1.0, 0.0, 0.0); }
public static function right(): Rotator { return new Rotator(1.0, 0.0, 0.0); }
public static function negativeInfinity(): Rotator { return new Rotator(Math.NEGATIVE_INFINITY, Math.NEGATIVE_INFINITY, Math.NEGATIVE_INFINITY); }
public static function positiveInfinity(): Rotator { return new Rotator(Math.POSITIVE_INFINITY, Math.POSITIVE_INFINITY, Math.POSITIVE_INFINITY); }
public function toString(): String {
return "(" + this.pitch + ", " + this.roll + ", " + this.yaw + ")";
}
}