UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

74 lines (71 loc) 2.86 kB
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 };