Basic Concept

From Ciliz|W4

Scope

В статье описаны основные решения, используемые в W4 Game Engine, и их API.

Coordinate System

Координатная система

Используется left-handed координатная система и вращение производится против часовой стрелки, если смотреть в направлении оси.

Render Tree

Отображаемый на экране результат и зависимость трансформаций объектов друг от друга определяются деревом рендеринга, то есть набором объектов рендеринга. Особенности дерева рендеринга W4 Game Engine:

  • Минимальное дерево рендеринга состоит только из корневого узла.
  • У каждого узла может быть ноль или более подузлов — «детей», но при этом у узла не может быть более одного “родителя“ (самый верхний узел - “корневой“ - родителя не имеет).
  • Для того чтобы объект отобразился на экране и/или пересчитал свои данные, необходимо чтобы он находился в дереве.
  • Иерархия встроенных типов узлов показана на схеме.

Concept 02.png

Примечания по использованию:

  • При рисовании в несколько проходов, у каждого прохода создаётся своё дерево со своим корневым узлом.
  • У каждого узла можно узнать локальные трансформации (то есть трансформации относительно “родителя“) и мировые, а также задать их.
  • При задании мировых координат узла пересчитываются его локальные координаты, при задании локальных - мировые.
  • У узла, не имеющего родителя трансформации совпадают.
  • Можно временно отключить узел, при этом отключаются и все его “потомки“.

Интерфейсы узлов (классов) описаны далее.

Node

Node - базовый класс любого узла (в том числе RootNode).

Метод Описание
w4::sptr<render::RootNode> getRoot() const
Возвращает корневой узел дерева или nullptr при её отсутствии.
w4::sptr<Node> clone() const
Создаёт копию узла, но не имеющую “родителя“
w4::sptr<Node> getParent() const
Возвращает “родительский“ узел или nullptr при её отсутствии.
void setEnabled(bool)
Включает/выключает узел и его “потомков“
void addChild(w4::cref<Node>, bool preserveTransorm = true)

void addChild(const std::string&, w4::cref<Node>, bool preserveTransorm = true)
Добавляет “детей“ к текущему узлу. Возможно задание имени для “ребёнка“.

Параметр "preserveTransform" определяет локальные(false) или глобальные(true) трансформации, которые сохраняются у “ребёнка“.

Например, если дополнить код слева строками:

childNode->setTranslation({1, 0, 0});
parentNode->addChild(childNode);

то узел childNode будет находиться в мировой позиции {1, 0, 0},

а если использовать следующие строки:

childNode->setTranslation({1, 0, 0});
parentNode->addChild(childNode, false);

то узел childNode будет сдвинут на 1 по оси X относительно родителя.

void removeChild(w4::cref<Node>)

void removeChild(const std::string&)

void removeChild(const std::list<w4::sptr<Node>>&)
Отвязка “детей“ от узла по указателю, имени и списку.
void traversal(const Callback&)

 void traversal(const PredicateC & predicate, const Callback&)

template<typename T> void traversalTyped(const std::function<void(w4::cref<T>)>&);
Выполнение функтора начиная с текущего узла и вниз по иерархии.

Callback имеет сигнатуру void(Node&) PredicateC - bool(w4::core::Node&)

Последний метод вызывается только для узлов, чей тип унаследован от T

void setWorldRotation(math::Rotator::cref, math::vec3::cref worldPt)
Установка поворота относительно точки в мировых координатах.
void rotateAroundPoint(const math::Rotator& rotator, const math::vec3& worldPt)
Вращение вокруг точки в мировых координатах.
template<typename T> w4::sptr<T> as()

template<typename T> w4::sptr<const T> as()   const

template<typename T> T* asRaw()

template<typename T> const T* asRaw() const
Приведение типа узла (прим. указываемый тип не проверяется)
template<typename T> bool derived_from() const
Проверка, является ли класс узла потомком заданного класса
template<typename T> w4::sptr<T> getChild(const std::string&)
Получение ”ребёнка” по имени с приведением типа (прим. указываемый тип не проверяется).
std::list<w4::sptr<Node>> getAllChildren() const
Получение списка всех узлов, находящихся ниже по иерархии (“дети“, “дети детей“…).
std::list<w4::sptr<Node>> findChildren(std::string const&) const
Поиск “ребёнка“ по имени
std::list<w4::sptr<Node>> findChildrenRecursive(std::string const&) const
Поиск вниз по иерархии по имени
math::vec3::cref getWorldTranslation() const

void setWorldTranslation(math::vec3::cref)

math::vec3::cref getLocalTranslation() const

void setLocalTranslation(math::vec3::cref)
Получение и установка позиции в мировых или локальных координатах
math::vec3::cref getWorldScale() const

void setWorldScale(math::vec3::cref)

math::vec3::cref getLocalScale() const

void setLocalScale(math::vec3::cref)
Получение и установка масштаба в мировых или локальных координатах
math::vec3 getWorldUp() const

math::vec3 getWorldForward() const

math::vec3 getWorldRight() const
Получение нормализованных векторов в направлениях вверх, вперёд и вправо пространства модели в мировых координатах
math::Transform::cref getWorldTransform()     const

void setWorldTransform(math::Transform::cref)

math::Transform::cref getLocalTransform() const

void setLocalTransform(math::Transform::cref)
Получение и установка трансформации в мировых или локальных координатах. Трансформация - сочетание позиции, поворота и масштаба
math::Rotator::cref getWorldRotation() const

void setWorldRotation(math::Rotator::cref)

math::Rotator::cref getLocalRotation() const

void setLocalRotation(math::Rotator::cref)

void rotateLocal(const math::Rotator&rotator)

void rotateWorld(const math::Rotator&rotator)
Получение и установка поворота в мировых или локальных координатах. Методы rotateWorld/Local добавляют поворот к текущим значениям
const std::unordered_set<w4::sptr<Node>>& getChildren() const
Получение списка “детей“
bool isEnabled() const
Возвращает, включен ли узел
bool hasParent() const
Возвращает имеет ли узел “родителя“

Hierarchy Example

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

VisibleNode

Mesh

SkinnedMesh

Animator API

ParticlesEmitter

Billboard

Plotter

DataNode

ArcBallNode

Camera

PointLight

SpotLight

Spline