Трансформация объектов (часть 1)
В предыдущем уроке мы настроили полноценную сборку проекта с three.js при помощи webpack, если вы это пропустили, то советую вернуться!
Теперь, когда у нас все готово, мы можем изучить функциональные возможности three.js. Сегодня мы рассмотрим как перемещать и масштабировать объекты...
Перед анимацией нашей сцены нам необходимо знать, как трансформировать объекты в нашей сцене. Мы уже сделали это с камерой, переместив ее назад с помощью строчки camera.position.z = 3.
Существует 4 свойства для преобразования объектов в нашей сцене:
- position (для перемещения)
- scale (для изменения размера)
- rotation (для вращения)
- quaternion (тоже для вращения, но об этом позже 😏)
Все классы, которые наследуются от класса Object3D, обладают такими свойствами, как PerspectiveCamera или Mesh, а также классы, которые мы еще не рассматривали.
Подготовка
Если у вас нет кода всего проекта, то вы можете найти его в репозитории.
Перемещение объектов
position обладает тремя основными свойствами- x, y и z. Это свойства необходимы для позиционирования чего-либо в трехмерном пространстве.
Направление каждой оси является произвольным, и может меняться в зависимости от окружающей среды. В three.js обычно считают, что ось yнаправлена вверх, ось z - назад, а ось x - вправо.
Что касается масштаба единицы измерения, то это зависит от вас. Это может быть 1 сантиметр, 1 метр или даже 1 километр. Я рекомендую вам адаптировать единицу к тому, что вы хотите построить.
Например, если вы собираетесь создать дом, то, вероятно, вам следует считать, что 1 единица - это 1 метр.
mesh.position.x = -1; mesh.position.y = -0.8; mesh.position.z = 0.4;
🤖 Обязательно меняйте положение куба до вызова метода render(...), иначе вы отрендерите сетку до ее перемещения.
Вы можете поиграть со свойством position и попытаться угадать, куда попадет куб (старайтесь, чтобы он находился на экране).
Свойство position - это экземпляр класса Vector3. Этот класс имеет не только свойства x, y и z, но еще и множество полезных методов.
Вы можете получить длину вектора:
console.log(mesh.position.length());
Вы можете получить расстояние от другого Vector3 (убедитесь, что используете этот код после создания камеры):
console.log(mesh.position.distanceTo(camera.position));
Можно нормализовать значение вектора (это означает, что вы уменьшите длину вектора до 1 единицы, но сохраните его направление):
console.log(mesh.position.normalize());
Для перемещения объекта, вместо того чтобы изменять x, y и z по отдельности, можно также использовать метод set(...):
mesh.position.set(-1, -0.8, 0.4);
Добавляем визуализацию осей
Прежде чем мы продолжим, хочу отметить, что знать, куда направлена каждая ось, сложно, особенно когда мы начинаем перемещать камеру.
Одним из хороших решений является использование three.js AxesHelper.
AxesHelper отобразит 3 линии, соответствующие осям x, y и z, каждая из которых начинается в центре сцены и идет в соответствующем направлении.
Чтобы создать AxesHelper, создайте объект и добавьте на сцену. В качестве единственного параметра можно указать длину, с которой нужно отрисовать оси. Мы будем использовать 3:
// Отрисовка осей координат const axesHelper = new THREE.AxesHelper(3); scene.add(axesHelper);
Вы должны увидеть зеленую и красную линии.
Зеленая линия соответствует оси y. Красная линия соответствует оси x, а синяя линия соответствует оси z, но мы ее не видим, потому что она идеально выровнена относительно камеры.
Мы не будем использовать AxesHelper в следующих уроках, но не стесняйтесь добавить его, если вам нужно понять куда смотрят оси.
Масштабирование объектов
scale также является объектом класса Vector3. По умолчанию x, y и z равны 1, что означает, что к объекту не применяется масштабирование. Если вы поставите значение 0,5, объект будет иметь половину своего размера по этой оси, а если вы поставите значение 2, он будет вдвое больше своего первоначального размера по этой оси.
Если вы измените эти значения, объект начнет масштабироваться соответствующим образом. Давайте закомментируем изменения положения и добавьте новые масштабы:
mesh.scale.x = 0.5; mesh.scale.y = 2; mesh.scale.z = 0.7;
🤖 При изменении масштаба можно использовать отрицательные значения, но в дальнейшем это может привести к ошибкам, поскольку оси не будут ориентированы в логическом направлении. Старайтесь избегать этого.
Поскольку scale это Vector3, мы можем использовать все ранее упомянутые методы этого класса.