(Three.js ) Как медленно вращать сетку, пока она не достигнет определенного значения

#javascript #three.js

#javascript #three.js

Вопрос:

Я только что перешел к трем.JS, и я столкнулся с проблемой. Я пытаюсь создать автомобиль, которым можно управлять с помощью клавиш со стрелками. До сих пор я заставлял ее двигаться вперед и назад, и колесики поворачиваются, когда вы нажимаете вверх (вперед) и вниз (назад). Итак, логично, что следующим шагом будет поворот. Однако именно здесь я обращаюсь к своей проблеме.

Я не могу понять, как сделать так, чтобы при нажатии клавиш со стрелками влево или вправо вращение колесиков медленно, постепенно увеличивалось, пока они не достигнут определенного значения, скажем, 45 для левого и -45 для правого.

У меня есть куб, вытянутый в форме преимущественно плоского прямоугольника, называемый шасси. У меня есть четыре колеса, Wheel_FL, FR, RL и RR. F означает передний, первый R означает задний, L означает левый, второй R означает правый. И Wheel_FL, и Wheel_FR имеют группу в качестве родительского элемента, который я буду использовать для поворота их влево или вправо, они действуют как стержень. Я не могу понять, как это сделать, я пытался искать ответ везде в течение последних нескольких дней, но безрезультатно. Если у кого-нибудь есть какие-либо идеи, пожалуйста, дайте мне знать! И если кому-то нужна дополнительная информация, пожалуйста, дайте мне знать!

Я также ищу способ затем, как только эта проблема с рулевым управлением будет устранена, повернуть само шасси таким образом, чтобы оно было реалистичным для поворота автомобиля.

Спасибо!

Если кому-то нужен пример, у меня есть один здесь.

Ответ №1:

Я могу помочь вам с первой частью вопроса:

Давайте назовем переменные: Wheel_FL, Wheel_FR, Group_FL, Group_FR; . Каждое колесо вложено в соответствующую группу с Group_FL.add(Wheel_FL);

Итак, чтобы вращать колеса, вы, вероятно, сделали бы Wheel_FL.rotation.x = spinAngle; или, возможно rotation.z , основываясь на ориентации вашего ресурса. Теперь, чтобы повернуть влево / вправо, вам нужно повернуть контейнер Group , чтобы он не мешал углу поворота: Group_FL.rotation.y = steerAngle;

Чтобы анимировать или изменять этот угол поворота, вы могли бы использовать MathUtils.lerp() функцию (lerp расшифровывается как линейная интерполяция), которая принимает переменную и направляет ее к цели.

 var Wheel_FL, Wheel_FR;
var Group_FL = new THREE.Group();
var Group_FR = new THREE.Group();
Group_FL.add(Wheel_FL);
Group_FR.add(Wheel_FR);

var spinAngle = 0;
var steerAngle = 0;
var steerAngleTarget = 0;

function update() {
    // Update wheel spin
    Wheel_FL.rotation.x  = spinAngle;
    Wheel_FR.rotation.x  = spinAngle;

    // Tween steering angle towards target
    steerAngle = MathUtils.lerp(steerAngle, steerAngleTarget, 0.1);

    // Rotate parent group around y-axis
    Group_FL.rotation.y = steerAngle;
    Group_FR.rotation.y = steerAngle;
}

function steerLeft() {
    steerAngleTarget = Math.PI / 4; // 45 deg in radians
}

function steerRight() {
    steerAngleTarget = - Math.PI / 4; // -45 deg in radians
}
  

Ниже я создал для вас рабочую демонстрацию. Используйте клавиши w-a-s-d для управления, ускорения и замедления:

 var camera, scene, renderer, clock, container;

container = document.getElementById( 'container' );

camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 100 );
camera.position.y = 10;
camera.position.z = 5;
camera.lookAt(0, 0, 0);

scene = new THREE.Scene();
scene.background = new THREE.Color( 0xeeeeee );
scene.fog = new THREE.Fog( 0xcccccc, 100, 1500 );

clock = new THREE.Clock();

var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x222222, 1.5 );
hemiLight.position.set( 1, 1, 1 );
scene.add( hemiLight );

var floor = new THREE.Mesh(new THREE.PlaneBufferGeometry(10, 10), new THREE.MeshBasicMaterial({color: 0x999999}));
floor.rotation.x = -Math.PI/2;
scene.add(floor);

renderer = new THREE.WebGLRenderer();
renderer.setSize( container.offsetWidth, container.offsetHeight );
container.appendChild( renderer.domElement );

window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener("keydown", onKeyPress);
window.addEventListener("keyup", onKeyRelease);

// Create wheels
var Wheel_FL = new THREE.Mesh(
    new THREE.CylinderBufferGeometry(1, 1, 1, 8),
  new THREE.MeshBasicMaterial({color: 0xffff00, wireframe: true})
);
var Wheel_FR = new THREE.Mesh(
    new THREE.CylinderBufferGeometry(1, 1, 1, 8),
  new THREE.MeshBasicMaterial({color: 0xffff00, wireframe: true})
);
var Group_FL = new THREE.Group();
var Group_FR = new THREE.Group();

// Set initial positions and rotations
Wheel_FL.position.y = 1;
Wheel_FR.position.y = 1;
Wheel_FL.rotation.z = Math.PI / 2;
Wheel_FR.rotation.z = Math.PI / 2;

// Add wheels to group, and position groups
Group_FL.add(Wheel_FL);
Group_FR.add(Wheel_FR);
Group_FL.position.x = -2;
Group_FR.position.x = 2;
scene.add(Group_FL);
scene.add(Group_FR);

var spinAngle = 0;
var steerAngle = 0;
var steerAngleTarget = 0;

// WASD to turn, accelerate, and decelerate
function onKeyPress(evt) {
    switch(evt.key) {
    case 'a':
        steerAngleTarget = Math.PI / 6; // 45 deg in radians
    break;
    case 'd':
        steerAngleTarget = - Math.PI / 6; // -45 deg in radians
    break;
    case 'w':
        spinAngle  = 0.01; // accelerate
    break;
    case 's':
        spinAngle -= 0.01; // decelerate
    break;
  }
}

// Returns wheels to center
function onKeyRelease() {
    steerAngleTarget = 0;
}

function onWindowResize() {
    camera.aspect = container.offsetWidth / container.offsetHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( container.offsetWidth, container.offsetHeight );
}

function update() {
  // Update wheel spin
  Wheel_FL.rotation.x -= spinAngle;
  Wheel_FR.rotation.x -= spinAngle;

  // Tween steering angle towards target
  steerAngle = THREE.MathUtils.lerp(steerAngle, steerAngleTarget, 0.1);

  // Rotate parent group around y-axis
  Group_FL.rotation.y = steerAngle;
  Group_FR.rotation.y = steerAngle;
    requestAnimationFrame( update );

    renderer.render(scene, camera);
}

update();  
 body, html {
  background-color: #fff;
  color: #222;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

#container {
  position: absolute;
  top: 0;
  width: 100%;
  bottom: 0px;
}  
 <script src="https://cdn.rawgit.com/mrdoob/three.js/dev/build/three.js"></script>
<div id="container">
</div>