playcanvas
Version:
PlayCanvas WebGL game engine
74 lines (71 loc) • 2.86 kB
JavaScript
import { math } from '../../core/math/math.js';
import { Quat } from '../../core/math/quat.js';
import { Vec2 } from '../../core/math/vec2.js';
import { Vec3 } from '../../core/math/vec3.js';
const tmpV1 = new Vec3();
const rotation = new Quat();
class Pose {
constructor(position = Vec3.ZERO, angles = Vec3.ZERO, distance = 0){
this.position = new Vec3();
this.angles = new Vec3();
this.distance = 0;
this.pitchRange = new Vec2(-Infinity, Infinity);
this.yawRange = new Vec2(-Infinity, Infinity);
this.xRange = new Vec2(-Infinity, Infinity);
this.yRange = new Vec2(-Infinity, Infinity);
this.zRange = new Vec2(-Infinity, Infinity);
this.set(position, angles, distance);
}
copy(other) {
return this.set(other.position, other.angles, other.distance);
}
clone() {
return new Pose(this.position.clone(), this.angles.clone(), this.distance);
}
equalsApprox(other, epsilon = 1e-6) {
return this.position.equalsApprox(other.position, epsilon) && this.angles.equalsApprox(other.angles, epsilon) && Math.abs(this.distance - other.distance) < epsilon;
}
lerp(lhs, rhs, alpha1, alpha2 = alpha1, alpha3 = alpha1) {
this.position.lerp(lhs.position, rhs.position, alpha1);
this.angles.x = math.lerpAngle(lhs.angles.x, rhs.angles.x, alpha2) % 360;
this.angles.y = math.lerpAngle(lhs.angles.y, rhs.angles.y, alpha2) % 360;
this.angles.z = math.lerpAngle(lhs.angles.z, rhs.angles.z, alpha2) % 360;
this.distance = math.lerp(lhs.distance, rhs.distance, alpha3);
return this;
}
move(offset) {
this.position.add(offset);
this.position.x = math.clamp(this.position.x, this.xRange.x, this.xRange.y);
this.position.y = math.clamp(this.position.y, this.yRange.x, this.yRange.y);
this.position.z = math.clamp(this.position.z, this.zRange.x, this.zRange.y);
return this;
}
rotate(euler) {
this.angles.add(euler);
this.angles.x %= 360;
this.angles.y %= 360;
this.angles.z %= 360;
this.angles.x = math.clamp(this.angles.x, this.pitchRange.x, this.pitchRange.y);
this.angles.y = math.clamp(this.angles.y, this.yawRange.x, this.yawRange.y);
return this;
}
set(position, angles, distance) {
this.position.copy(position);
this.angles.copy(angles);
this.distance = distance;
return this;
}
look(from, to) {
this.position.copy(from);
this.distance = from.distance(to);
const dir = tmpV1.sub2(to, from).normalize();
const elev = Math.atan2(-dir.y, Math.sqrt(dir.x * dir.x + dir.z * dir.z)) * math.RAD_TO_DEG;
const azim = Math.atan2(-dir.x, -dir.z) * math.RAD_TO_DEG;
this.angles.set(-elev, azim, 0);
return this;
}
getFocus(out) {
return rotation.setFromEulerAngles(this.angles).transformVector(Vec3.FORWARD, out).mulScalar(this.distance).add(this.position);
}
}
export { Pose };