用户:
萌新大佬查看:1 回复:4 评论:1 创建时间:2022-06-10T17:17:08
首先,你需要翻出 Box3Quaternion的源代码如下
class Box3Quaternion {
constructor(w, x, y, z) {
this.w = w;
this.x = x;
this.y = y;
this.z = z;
}
static rotationBetween(a, b) {
const dot = a.dot(b);
let tmpvec3;
if (dot < -0.999999) {
tmpvec3 = new Box3Vector3(1, 0, 0).cross(a);
if (tmpvec3.mag() < EPSILON) {
tmpvec3 = new Box3Vector3(0, 1, 0).cross(a);
}
tmpvec3 = tmpvec3.normalize();
return Box3Quaternion.fromAxisAngle(tmpvec3, Math.PI);
}
else if (dot > 0.999999) {
return new Box3Quaternion(1, 0, 0, 0);
}
else {
tmpvec3 = a.cross(b);
return new Box3Quaternion(1 + dot, tmpvec3.x, tmpvec3.y, tmpvec3.z).normalize();
}
}
static fromAxisAngle(axis, rad) {
rad = rad * 0.5;
const s = Math.sin(rad);
return new Box3Quaternion(Math.cos(rad), s * axis.x, s * axis.y, s * axis.z);
}
static fromEuler(x, y, z) {
const halfToRad = 0.5 * Math.PI / 180.0;
x *= halfToRad;
y *= halfToRad;
z *= halfToRad;
const sx = Math.sin(x);
const cx = Math.cos(x);
const sy = Math.sin(y);
const cy = Math.cos(y);
const sz = Math.sin(z);
const cz = Math.cos(z);
return new Box3Quaternion(cx * cy * cz + sx * sy * sz, sx * cy * cz - cx * sy * sz, cx * sy * cz + sx * cy * sz, cx * cy * sz - sx * sy * cz);
}
set(w, x, y, z) {
this.w = w;
this.x = x;
this.y = y;
this.z = z;
return this;
}
copy(q) {
this.w = q.w;
this.x = q.x;
this.y = q.y;
this.z = q.z;
return this;
}
getAxisAngle(_q) {
const q = _q.normalize();
const angle = Math.acos(q.w) * 2.0;
const s = Math.sin(angle / 2.0);
let axis;
if (s > EPSILON) {
axis = new Box3Vector3(q.x / s, q.y / s, q.z / s);
}
else {
axis = new Box3Vector3(1, 0, 0);
}
return { axis, angle };
}
rotateX(_rad) {
const aw = this.w;
const ax = this.x;
const ay = this.y;
const az = this.z;
const rad = 0.5 * _rad;
const bx = Math.sin(rad);
const bw = Math.cos(rad);
return new Box3Quaternion(aw * bw - ax * bx, ax * bw + aw * bx, ay * bw + az * bx, az * bw - ay * bx);
}
rotateY(_rad) {
const aw = this.w;
const ax = this.x;
const ay = this.y;
const az = this.z;
const rad = 0.5 * _rad;
const by = Math.sin(rad);
const bw = Math.cos(rad);
return new Box3Quaternion(aw * bw - ay * by, ax * bw - az * by, ay * bw + aw * by, az * bw + ax * by);
}
rotateZ(_rad) {
const aw = this.w;
const ax = this.x;
const ay = this.y;
const az = this.z;
const rad = 0.5 * _rad;
const bz = Math.sin(rad);
const bw = Math.cos(rad);
return new Box3Quaternion(aw * bw - az * bz, ax * bw + ay * bz, ay * bw - ax * bz, az * bw + aw * bz);
}
dot(q) {
return this.w * q.w + this.x * q.x + this.y * q.y + this.z * q.z;
}
add(v) {
return new Box3Quaternion(this.w + v.w, this.x + v.x, this.y + v.y, this.z + v.z);
}
sub(v) {
return new Box3Quaternion(this.w - v.w, this.x - v.x, this.y - v.y, this.z - v.z);
}
angle(q) {
const dotproduct = this.dot(q);
return Math.acos(2 * dotproduct * dotproduct - 1);
}
mul(q) {
const ax = this.x;
const ay = this.y;
const az = this.z;
const aw = this.w;
const bx = q.x;
const by = q.y;
const bz = q.z;
const bw = q.w;
return new Box3Quaternion(aw * bw - ax * bx - ay * by - az * bz, ax * bw + aw * bx + ay * bz - az * by, ay * bw + aw * by + az * bx - ax * bz, az * bw + aw * bz + ax * by - ay * bx);
}
inv() {
const a0 = this.x;
const a1 = this.y;
const a2 = this.z;
const a3 = this.w;
const dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
let r = dot;
if (Math.abs(r) > EPSILON) {
r = 1 / r;
}
return new Box3Quaternion(a3 * r, -a0 * r, -a1 * r, -a2 * r);
}
div(q) {
return this.mul(q.inv());
}
slerp(q, n) {
const aw = this.w;
const ax = this.x;
const ay = this.y;
const az = this.z;
let bw = q.w;
let bx = q.x;
let by = q.y;
let bz = q.z;
let omega;
let cosomg;
let sinomg;
let scale0;
let scale1;
cosomg = ax * bx + ay * by + az * bz + aw * bw;
if (cosomg < 0.0) {
cosomg = -cosomg;
bx = -bx;
by = -by;
bz = -bz;
bw = -bw;
}
if (1.0 - cosomg > EPSILON) {
omega = Math.acos(cosomg);
sinomg = Math.sin(omega);
scale0 = Math.sin((1.0 - n) * omega) / sinomg;
scale1 = Math.sin(n * omega) / sinomg;
}
else {
scale0 = 1.0 - n;
scale1 = n;
}
return new Box3Quaternion(scale0 * aw + scale1 * bw, scale0 * ax + scale1 * bx, scale0 * ay + scale1 * by, scale0 * az + scale1 * bz);
}
mag() {
return Math.sqrt(this.dot(this));
}
sqrMag() {
return this.dot(this);
}
normalize() {
const w = this.w;
const x = this.x;
const y = this.y;
const z = this.z;
let r = this.dot(this);
if (r > 0) {
r = 1 / Math.sqrt(r);
}
return new Box3Quaternion(r * w, r * x, r * y, r * z);
}
equals(q) {
return (Math.abs(this.w - q.w) < EPSILON &&
Math.abs(this.x - q.x) < EPSILON &&
Math.abs(this.y - q.y) < EPSILON &&
Math.abs(this.z - q.z) < EPSILON);
}
clone() {
return new Box3Quaternion(this.w, this.x, this.y, this.z);
}
toString() {
return `{ w:${this.w}, x:${this.x}, y:${this.y}, z:${this.z} }`;
}
}
这个static是什么意思呢,就是说只能通过“Box3Quaternion.什么什么”来访问。
然后其中有一个东西叫做fromEuler,百度翻译一下发现是指来自欧拉。
ok,现在我们有欧拉角转四元数的工具了,再也不需要用Quat.rotateX.rotateY.rotateZ……来设置初始角度了
至于其他的嘛,咳咳,咱们下次再说(等我搞明白了再说)
水掉一期()()
