1
Fork 0
mirror of https://github.com/RGBCube/rgbcube.github.io synced 2025-06-23 16:32:12 +00:00

Somewhat basic movement

This commit is contained in:
RGBCube 2023-12-17 22:43:16 +03:00
parent 43854c4adf
commit 169634ee44
No known key found for this signature in database

View file

@ -189,89 +189,124 @@
<script> <script>
class Quaternion { class Quaternion {
constructor(x, y, z, w) { static __cube = document.querySelector(".cube");
static up = new Quaternion({x: 0, y: 1, z: 0, w: 0});
static right = new Quaternion({x: 1, y: 0, z: 0, w: 0});
constructor({x, y, z, w}) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.w = w; this.w = w;
} }
static multiply(q1, q2) { static fromAngleAxis(angle, axis) {
return new Quaternion( axis.normalize();
q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x, const half = angle / 2;
q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w,
q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z, const sinHalf = Math.sin(half);
) const cosHalf = Math.cos(half);
const x = axis.x * sinHalf;
const y = axis.y * sinHalf;
const z = axis.z * sinHalf;
const w = cosHalf;
return new Quaternion({x: x, y: y, z: z, w: w})
} }
static fromAxisAngle(axis, angle) { apply() {
const halfAngle = angle / 2; Quaternion.__cube.style.transform = `rotate3d(${this.x}, ${this.y}, ${this.z}, ${this.w}rad)`;
const sinHalfAngle = Math.sin(halfAngle);
const cosHalfAngle = Math.cos(halfAngle);
return new Quaternion(
axis.x * sinHalfAngle,
axis.y * sinHalfAngle,
axis.z * sinHalfAngle,
cosHalfAngle
);
} }
normalize() { normalize() {
const length = Math.sqrt( const length = Math.sqrt(this.x ** 2 + this.y ** 2 + this.z ** 2);
this.x ** 2 + this.y ** 2 + this.z ** 2 + this.w ** 2
);
if (length != 0) {
this.x /= length; this.x /= length;
this.y /= length; this.y /= length;
this.z /= length; this.z /= length;
this.w /= length;
return this;
} }
} }
const cube = document.querySelector(".cube"); static multiply(q, r) {
return new Quaternion({
x: q.w * r.x + q.x * r.w + q.y * r.z - q.z * r.y,
y: q.w * r.y - q.x * r.z + q.y * r.w + q.z * r.x,
z: q.w * r.z + q.x * r.y - q.y * r.x + q.z * r.w,
w: q.w * r.w - q.x * r.x - q.y * r.y - q.z * r.z,
});
}
}
let isMouseDown = false; let friction = 0.01;
let sensitivity = 0.001;
let lastX = 0; const orientation = {
let lastY = 0; __value: new Quaternion({x: 0, y: 0, z: 0, w: 1}),
let rotationVelocity = new Quaternion(0, 0, 0, 1); set(value) {
console.log(value);
this.__value = value;
this.__value.apply();
},
document.addEventListener("mousemove", (e) => { get() {
if (isMouseDown) { return this.__value;
const deltaX = e.clientX - lastX; },
const deltaY = e.clientY - lastY; };
const axis = new Quaternion(deltaY, deltaX, 0, 0).normalize(); (() => {
const angle = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.01; const mouse = {
down: false,
previous: {
x: 0,
y: 0,
},
};
const deltaRotation = Quaternion.fromAxisAngle(axis, angle); let velocity = 0;
rotationVelocity = Quaternion.multiply(deltaRotation, rotationVelocity);
cube.style.transform = `rotate3d(${rotationVelocity.x}, ${rotationVelocity.y}, ${rotationVelocity.z}, ${rotationVelocity.w}rad)`; const mouseLeaveListener = (event) => {
mouse.down = false;
mouse.previous = {
x: event.clientX,
y: event.clientY,
};
};
lastX = e.clientX; document.addEventListener("mouseleave", mouseLeaveListener);
lastY = e.clientY; document.addEventListener("mouseup", mouseLeaveListener);
document.addEventListener("mousedown", () => {
mouse.down = true;
});
document.addEventListener("mousemove", (event) => {
if (mouse.down) {
const newMouse = {
x: event.clientX,
y: event.clientY,
}
const delta = {
x: newMouse.x - mouse.previous.x,
y: newMouse.y - mouse.previous.y,
}
mouse.previous = newMouse
const rotation = Quaternion.multiply(
Quaternion.fromAngleAxis(delta.x * sensitivity, Quaternion.up),
Quaternion.fromAngleAxis(delta.y * sensitivity, Quaternion.right),
);
orientation.set(Quaternion.multiply(orientation.get(), rotation))
} }
}); });
})();
document.addEventListener("mousedown", (e) => {
isMouseDown = true;
lastX = e.clientX;
lastY = e.clientY;
});
document.addEventListener("mouseup", () => {
isMouseDown = false;
});
document.addEventListener("mouseleave", () => {
isMouseDown = false;
});
</script> </script>
</body> </body>