Не работает механика вращения колеса на кватернионах и rotation.order three.js
Надеюсь, я еще не сильно всех тут достал глупыми вопросами, но уже неделю борюсь с механикой вращения движущихся предметов... https://mrmadgav.github.io/wheel/ - gitpages; https://github.com/mrmadgav/wheel/settings - github; Переписал код для одного колеса авто. Две механики пробовал - на кватернионах, и на obj.rotation.order. В первом случае появляется ошибка - object.quaternion.multiplySelf is not a function, хотя в примере работает, туда передается кватернион. Вторая логика заставляет колесо вращаться, но оси все равно съезжают. Сильно прошу помочь может быть с одним из этих способов. С кватернионами совсем всё плохо, уже видео штук 20 посмотрел, но не помогает)
var keyboard = new THREEx.KeyboardState();
window.onload = function () {
// Присвоили значения канвасу
let width = window.innerWidth;
let height = window.innerHeight;
let canvas = document.getElementById("canvas");
canvas.setAttribute("width", width);
canvas.setAttribute("height", height);
// Рендерер
let renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setClearColor(0x000000);
// Сцена
let scene = new THREE.Scene();
// Камера
let camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 5000);
camera.position.set(0, 0, 1000);
// Свет
let light = new THREE.AmbientLight(0xffffff);
scene.add(light);
// Настройки меша
let geometry = new THREE.TorusGeometry(100, 30, 16, 100);
let material = new THREE.MeshBasicMaterial({
color: 0xffffff,
vertexColors: THREE.FaceColors,
});
for (let i = 0; i < geometry.faces.length; i++) {
geometry.faces[i].color.setRGB(Math.random(), Math.random(), Math.random());
}
// Меш
let mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
mesh = new THREE.Object3D(); // ???
mesh.rotation.y = Math.PI / 2;
// mesh.rotation.order = "XYZ";
// var clock = new THREE.Clock();
// var elapsedTime = 0;
// var angleSpeed = THREE.Math.degToRad(10);
var rotationx = (rotationy = rotationz = 0);
var _q1 = new THREE.Quaternion(); // CHANGED
var axisX = new THREE.Vector3(1, 0, 0); // CHANGED
var axisZ = new THREE.Vector3(0, 0, 1); // CHANGED
function rotateOnAxis(object, axis, angle) {
// CHANGED
_q1.setFromAxisAngle(axis, angle);
object.quaternion.multiplySelf(_q1);
}
window.addEventListener("keydown", function (event) {
// elapsedTime = clock.getElapsedTime();
console.log(event.code);
switch (event.code) {
case "KeyW":
rotateOnAxis(mesh, axisX, 0.08); // CHANGED
// mesh.rotation.x -= 0.5;
break;
case "KeyS":
rotateOnAxis(mesh, axisX, -0.08); // CHANGED
// mesh.rotation.x += 0.5;
break;
case "KeyA":
rotateOnAxis(mesh, axisZ, 0.08); // CHANGED
// mesh.rotation.y += Math.sin(elapsedTime) * THREE.Math.degToRad(23);
break;
case "KeyD":
rotateOnAxis(mesh, axisX, -0.08); // CHANGED
// mesh.rotation.y -= Math.sin(elapsedTime) * THREE.Math.degToRad(23);
break;
}
});
function loop() {
renderer.render(scene, camera);
requestAnimationFrame(function () {
loop();
});
}
loop();
};
Ответы (2 шт):
Все вполне работает, если задать порядок вращения "YXZ":
body{
overflow: hidden;
margin: 0;
}
<script type="module">
console.clear();
import * as THREE from "https://threejs.org/build/three.module.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(2.5, 6, 6);
camera.lookAt(scene.position);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth,innerHeight);
document.body.appendChild(renderer.domElement);
scene.add(new THREE.GridHelper());
let g = new THREE.CylinderBufferGeometry(2, 2, 0.5, 32);
g.rotateZ(Math.PI * 0.5);
let m = new THREE.MeshBasicMaterial({wireframe: true, color: "red"});
let wheel = new THREE.Mesh(g, m);
wheel.rotation.order = "YXZ";
wheel.position.y = 2;
scene.add(wheel);
document.addEventListener("keydown", event => {
//console.log(event)
let val = 0.05;
let angleTurn = event.key == "ArrowRight" ? -val : event.key == "ArrowLeft" ? val : 0;
wheel.rotation.y = THREE.MathUtils.clamp(
wheel.rotation.y + angleTurn,
-Math.PI * 0.25,
Math.PI * 0.25
);
})
renderer.setAnimationLoop(() => {
wheel.rotation.x += 0.01;
renderer.render(scene, camera);
});
</script>
let leftWheel = car.parent.children[0].children[0].children[0].children[13];
let rightWheel = car.parent.children[0].children[0].children[0].children[14];
leftWheel.rotation.order = "YXZ";
rightWheel.rotation.order = "YXZ";
console.log(leftWheel.rotation.y);
document.addEventListener("keydown", (event) => {
console.log(event);
let val = 0.05;
let angleTurn = event.key == "d" ? -val : event.key == "a" ? val : 0;
event.key == "w"
? ((rightWheel.rotation.x += 0.05), (leftWheel.rotation.x += 0.05))
: event.key == "s"
? ((rightWheel.rotation.x -= 0.05), (leftWheel.rotation.x -= 0.05))
: 0;
leftWheel.rotation.y = THREE.MathUtils.clamp(
leftWheel.rotation.y + angleTurn,
-Math.PI * 0.25,
Math.PI * 0.25
);
rightWheel.rotation.y = THREE.MathUtils.clamp(
rightWheel.rotation.y + angleTurn,
-Math.PI * 0.25,
Math.PI * 0.25
);
});