Вложенность сущностей и наследование трансформаций

A-Frame строится на концепции сущностей (entities) и компонентов, где каждая сущность может содержать другие сущности, формируя иерархию. Вложенность играет ключевую роль для управления пространственными трансформациями, группировкой объектов и созданием сложных сцен.

Основные принципы вложенности

Любая сущность в A-Frame может быть родителем для других сущностей. Вложенные сущности наследуют преобразования своего родителя: позицию, поворот и масштаб. Это означает, что изменения трансформаций у родителя автоматически влияют на все дочерние объекты.

Пример структуры:

<a-entity position="0 1 0" rotation="0 45 0">
  <a-box position="1 0 0" color="red"></a-box>
  <a-sphere position="-1 0 0" color="blue"></a-sphere>
</a-entity>

В этом примере:

  • Родительская сущность имеет позицию (0,1,0) и поворот по оси Y на 45°.
  • Дочерние объекты (a-box и a-sphere) наследуют эти трансформации.
  • Фактическая позиция a-box в мировой системе координат рассчитывается как сумма позиции родителя и локальной позиции дочерней сущности, повернутой на угол родителя.

Наследование трансформаций

Наследование включает три основных компонента:

  1. Позиция: Локальная позиция дочерней сущности суммируется с позицией родителя с учётом поворота родителя.
  2. Поворот (rotation): Поворот дочерней сущности складывается с поворотом родителя. Порядок вращений имеет значение: в A-Frame используется система Euler angles, и трансформации применяются в порядке X → Y → Z.
  3. Масштаб (scale): Локальный масштаб умножается на масштаб родителя. Например, если родитель масштабирован по оси X в 2, а дочерняя сущность имеет масштаб 0.5, итоговый масштаб будет 1.
<a-entity position="0 1 0" rotation="0 90 0" scale="2 2 2">
  <a-box position="1 0 0" scale="0.5 0.5 0.5"></a-box>
</a-entity>

Итоговое положение коробки и её размеры рассчитываются с учётом позиции, вращения и масштаба родителя.

Управление сложными структурами

Вложенность позволяет строить модульные объекты, где каждая часть управляется локально, а изменения у родителя распространяются на всё дерево. Это удобно для:

  • Моделирования транспортных средств, роботов, персонажей.
  • Создания камер и источников света, закреплённых за объектами.
  • Анимации сложных структур, где движение одной сущности ведёт за собой дочерние объекты.

Пример иерархии робота:

<a-entity id="robot" position="0 0 0">
  <a-box id="torso" position="0 1 0" scale="1 2 0.5" color="gray">
    <a-sphere id="head" position="0 1.5 0" radius="0.5" color="lightgray"></a-sphere>
    <a-box id="left-arm" position="-1 0.5 0" scale="0.3 1 0.3" color="gray"></a-box>
    <a-box id="right-arm" position="1 0.5 0" scale="0.3 1 0.3" color="gray"></a-box>
  </a-box>
</a-entity>

В этой структуре:

  • Поворот или перемещение robot перемещает весь объект целиком.
  • Локальные трансформации отдельных частей (head, left-arm) применяются относительно torso.

Локальные и глобальные координаты

  • Локальные координаты задаются относительно родителя.
  • Глобальные координаты вычисляются системой сцены, учитывая все родительские трансформации.
  • Для доступа к глобальным координатам можно использовать метод object3D.getWorldPosition() из Three.js:
const box = document.querySelector('#left-arm');
const worldPos = new THREE.Vector3();
box.object3D.getWorldPosition(worldPos);
console.log(worldPos);

Динамическое управление

Сущности можно добавлять, удалять или менять трансформации во время выполнения, что делает вложенность мощным инструментом для интерактивных сцен:

const robot = document.querySelector('#robot');
const newLeg = document.createElement('a-box');
newLeg.setAttribute('position', '0 -1 0');
newLeg.setAttribute('scale', '0.3 1 0.3');
newLeg.setAttribute('color', 'gray');
robot.appendChild(newLeg);

Дочерние объекты автоматически наследуют трансформации родителя, что упрощает анимацию и синхронизацию движений.

Особенности взаимодействия с анимациями

  • Анимации дочерних сущностей происходят относительно родителя.
  • Если родитель движется, дочерние анимации комбинируются с родительской трансформацией.
  • Для независимой анимации можно временно перемещать объект в корень сцены или использовать world-space анимации через Three.js.

Рекомендации по построению сцен

  1. Разбивать сложные объекты на логические компоненты.
  2. Минимизировать количество уровней вложенности, чтобы избежать сложностей с вычислением трансформаций.
  3. Использовать именованные идентификаторы для дочерних объектов для удобного доступа через querySelector или object3D.getObjectByName.
  4. Визуализировать оси и размеры объектов при разработке с помощью вспомогательных компонентов axes-helper или grid-helper.

Вложенность сущностей в A-Frame обеспечивает гибкость в организации сцены, управлении трансформациями и построении сложных объектов, делая возможным создание интерактивных 3D-сцен с минимальной ручной настройкой каждой отдельной части.