Difference between revisions of "Basic Concept"

From Ciliz|W4
 
(31 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
<languages />
 
== Scope ==
 
== Scope ==
 
+
<translate>
В статье описаны основные решения, используемые в W4 Game Engine, и их API.
+
<!--T:1-->
 +
В статье описаны основные решения, используемые в W4 Game Engine:
 +
* Координатная истема
 +
* Нодовая система
 +
* API основных классов
 +
</translate>
  
 
== Coordinate System ==
 
== Coordinate System ==
[[File:Concept 01.png|thumb|Координатная система]] Используется [https://en.wikipedia.org/wiki/Cartesian_coordinate_system#In_three_dimensions left-handed координатная система] и вращение производится против часовой стрелки, если смотреть в направлении оси.
+
[[File:Concept 01.png|thumb|<translate><!--T:2--> Координатная система</translate>]] <translate><!--T:3--> Используется [https://en.wikipedia.org/wiki/Cartesian_coordinate_system#In_three_dimensions left-handed координатная система] и вращение производится против часовой стрелки, если смотреть в направлении оси.</translate>
  
 
== Render Tree ==
 
== Render Tree ==
 +
<translate><!--T:4-->
 
Отображаемый на экране результат и зависимость трансформаций объектов друг от друга определяются деревом рендеринга, то есть набором объектов рендеринга. Особенности дерева рендеринга W4 Game Engine:
 
Отображаемый на экране результат и зависимость трансформаций объектов друг от друга определяются деревом рендеринга, то есть набором объектов рендеринга. Особенности дерева рендеринга W4 Game Engine:
 
* Минимальное дерево рендеринга состоит только из корневого узла.  
 
* Минимальное дерево рендеринга состоит только из корневого узла.  
 
* У каждого узла может быть ноль или более подузлов — «детей», но при этом у узла не может быть более одного “родителя“ (самый верхний узел - “корневой“ - родителя не имеет).  
 
* У каждого узла может быть ноль или более подузлов — «детей», но при этом у узла не может быть более одного “родителя“ (самый верхний узел - “корневой“ - родителя не имеет).  
 
* Для того чтобы объект отобразился на экране и/или пересчитал свои данные, необходимо чтобы он находился в дереве.  
 
* Для того чтобы объект отобразился на экране и/или пересчитал свои данные, необходимо чтобы он находился в дереве.  
* Иерархия встроенных типов узлов показана на схеме.
+
* Иерархия встроенных типов узлов показана на схеме.</translate>
  
[[File:Concept_02.png]]
+
[[File:Concept_02.png|<translate><!--T:5--> Иерархия типов</translate>|500 px]]
  
 +
<translate><!--T:6-->
 +
Назначение и интерфейсы узлов (классов) описаны в следующих параграфах.
 +
 +
<!--T:7-->
 
Примечания по использованию:
 
Примечания по использованию:
 
* При рисовании в несколько проходов, у каждого прохода создаётся своё дерево со своим корневым узлом.  
 
* При рисовании в несколько проходов, у каждого прохода создаётся своё дерево со своим корневым узлом.  
Line 21: Line 32:
 
* У узла, не имеющего родителя трансформации совпадают.  
 
* У узла, не имеющего родителя трансформации совпадают.  
 
* Можно временно отключить узел, при этом отключаются и все его “потомки“.  
 
* Можно временно отключить узел, при этом отключаются и все его “потомки“.  
 
+
</translate>
Интерфейсы узлов (классов) описаны далее.
 
 
=== Node ===
 
=== Node ===
Node - базовый класс любого узла (в том числе RootNode).
+
<translate><!--T:8--> Node - базовый класс любого узла (в том числе RootNode).</translate>
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Метод !! Описание
+
! Method !! Description
 
|-
 
|-
| <syntaxhighlight lang="c++">w4::sptr<render::RootNode> getRoot() const</syntaxhighlight> || Возвращает корневой узел дерева или nullptr при её отсутствии.
+
| <syntaxhighlight lang="c++">w4::sptr<render::RootNode> getRoot() const</syntaxhighlight> || <translate><!--T:9--> Возвращает корневой узел дерева или nullptr при её отсутствии</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">w4::sptr<Node> clone() const</syntaxhighlight> || Создаёт копию узла, но не имеющую “родителя“
+
| <syntaxhighlight lang="c++">w4::sptr<Node> clone() const</syntaxhighlight> || <translate><!--T:10--> Создаёт копию узла, но не имеющую “родителя“</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">w4::sptr<Node> getParent() const</syntaxhighlight> || Возвращает “родительский“ узел или nullptr при её отсутствии.
+
| <syntaxhighlight lang="c++">w4::sptr<Node> getParent() const</syntaxhighlight> || <translate><!--T:11--> Возвращает “родительский“ узел или nullptr при его отсутствии</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setEnabled(bool)</syntaxhighlight> || Включает/выключает узел и его “потомков“
+
| <syntaxhighlight lang="c++">void setEnabled(bool)</syntaxhighlight> || <translate><!--T:12--> Включает/выключает узел и его “потомков“</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">void addChild(w4::cref<Node>, bool preserveTransorm = true)
 
| <syntaxhighlight lang="c++">void addChild(w4::cref<Node>, bool preserveTransorm = true)
  
 
void addChild(const std::string&, w4::cref<Node>, bool preserveTransorm = true)
 
void addChild(const std::string&, w4::cref<Node>, bool preserveTransorm = true)
</syntaxhighlight> || Добавляет “детей“ к текущему узлу. Возможно задание имени для “ребёнка“.
+
</syntaxhighlight> || <translate><!--T:13-->
 +
Добавляет “детей“ к текущему узлу. Возможно задание имени для “ребёнка“.
 
'''Параметр "preserveTransform" определяет локальные(false) или глобальные(true) трансформации, которые сохраняются у “ребёнка“.'''
 
'''Параметр "preserveTransform" определяет локальные(false) или глобальные(true) трансформации, которые сохраняются у “ребёнка“.'''
  
Например, если дополнить код слева строками:
+
<!--T:14-->
 +
Например, если дополнить код слева строками:</translate>
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
childNode->setTranslation({1, 0, 0});
+
childNode->setLocalTranslation({1, 0, 0});
 
parentNode->addChild(childNode);
 
parentNode->addChild(childNode);
 
</syntaxhighlight>
 
</syntaxhighlight>
то узел childNode будет находиться в мировой позиции {1, 0, 0},  
+
<translate><!--T:15-->
 +
то узел childNode будет находиться в мировой позиции {1, 0, 0},
  
а если использовать следующие строки:
+
<!--T:16-->
 +
а если использовать следующие строки:</translate>
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
childNode->setTranslation({1, 0, 0});
+
childNode->setLocalTranslation({1, 0, 0});
 
parentNode->addChild(childNode, false);
 
parentNode->addChild(childNode, false);
 
</syntaxhighlight>
 
</syntaxhighlight>
  
то узел childNode будет сдвинут на 1 по оси X относительно родителя.
+
<translate><!--T:17--> то узел childNode будет сдвинут на 1 по оси X относительно родителя.</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">void removeChild(w4::cref<Node>)
 
| <syntaxhighlight lang="c++">void removeChild(w4::cref<Node>)
Line 62: Line 76:
 
void removeChild(const std::string&)
 
void removeChild(const std::string&)
  
void removeChild(const std::list<w4::sptr<Node>>&)</syntaxhighlight> || Отвязка “детей“ от узла по указателю, имени и списку.
+
void removeChild(const std::list<w4::sptr<Node>>&)</syntaxhighlight> || <translate><!--T:18--> Отвязка “детей“ от узла по указателю, имени и списку.</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">void traversal(const Callback&)
 
| <syntaxhighlight lang="c++">void traversal(const Callback&)
  
void traversal(const PredicateC & predicate, const Callback&)
+
void traversal(const PredicateC & predicate, const Callback&)
  
template<typename T> void traversalTyped(const std::function<void(w4::cref<T>)>&);</syntaxhighlight> || Выполнение функтора начиная с текущего узла и вниз по иерархии.  
+
template<typename T> void traversalTyped(const std::function<void(w4::cref<T>)>&);</syntaxhighlight> || <translate><!--T:19--> Выполнение функтора начиная с текущего узла и вниз по иерархии. </translate>
  
Callback имеет сигнатуру '''void(Node&) PredicateC - bool(w4::core::Node&)'''
+
<translate><!--T:20--> Callback имеет сигнатуру</translate> '''void(Node&) PredicateC - bool(w4::core::Node&)'''
  
Последний метод вызывается только для узлов, чей тип унаследован от T
+
<translate><!--T:21--> Последний метод вызывает функтор только для тех узлов, чей тип унаследован от T</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setWorldRotation(math::Rotator::cref, math::vec3::cref worldPt)</syntaxhighlight> || Установка поворота относительно точки в мировых координатах.
+
| <syntaxhighlight lang="c++">void setWorldRotation(math::Rotator::cref, math::vec3::cref worldPt)</syntaxhighlight> || <translate><!--T:22--> Установка поворота относительно точки в мировых координатах</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void rotateAroundPoint(const math::Rotator& rotator, const math::vec3& worldPt)</syntaxhighlight> || Вращение вокруг точки в мировых координатах.
+
| <syntaxhighlight lang="c++">void rotateAroundPoint(const math::Rotator& rotator, const math::vec3& worldPt)</syntaxhighlight> || <translate><!--T:23--> Вращение вокруг точки в мировых координатах</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">template<typename T> w4::sptr<T> as()
 
| <syntaxhighlight lang="c++">template<typename T> w4::sptr<T> as()
Line 84: Line 98:
 
template<typename T> T* asRaw()
 
template<typename T> T* asRaw()
  
template<typename T> const T* asRaw() const</syntaxhighlight> || Приведение типа узла (прим. указываемый тип не проверяется)
+
template<typename T> const T* asRaw() const</syntaxhighlight> || <translate><!--T:24--> Приведение типа узла (прим. указываемый тип не проверяется)</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">template<typename T> bool derived_from() const</syntaxhighlight> || Проверка, является ли класс узла потомком заданного класса
+
| <syntaxhighlight lang="c++">template<typename T> bool derived_from() const</syntaxhighlight> || <translate><!--T:25--> Проверка, является ли класс узла потомком заданного класса</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">template<typename T> w4::sptr<T> getChild(const std::string&)</syntaxhighlight> || Получение ”ребёнка” по имени с приведением типа (прим. указываемый тип не проверяется).
+
| <syntaxhighlight lang="c++">template<typename T> w4::sptr<T> getChild(const std::string&)</syntaxhighlight> || <translate><!--T:26--> Получение ”ребёнка” по имени с приведением типа (прим. указываемый тип не проверяется)</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">std::list<w4::sptr<Node>> getAllChildren() const</syntaxhighlight> || Получение списка всех узлов, находящихся ниже по иерархии (“дети“, “дети детей“…).
+
| <syntaxhighlight lang="c++">std::list<w4::sptr<Node>> getAllChildren() const</syntaxhighlight> || <translate><!--T:27--> Получение списка всех узлов, находящихся ниже по иерархии (“дети“, “дети детей“…)</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">std::list<w4::sptr<Node>> findChildren(std::string const&) const</syntaxhighlight> || Поиск “ребёнка“ по имени
+
| <syntaxhighlight lang="c++">std::list<w4::sptr<Node>> findChildren(std::string const&) const</syntaxhighlight> || <translate><!--T:28--> Поиск “ребёнка“ по имени</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">std::list<w4::sptr<Node>> findChildrenRecursive(std::string const&) const</syntaxhighlight> || Поиск вниз по иерархии по имени
+
| <syntaxhighlight lang="c++">std::list<w4::sptr<Node>> findChildrenRecursive(std::string const&) const</syntaxhighlight> || <translate><!--T:29--> Поиск вниз по иерархии по имени</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">math::vec3::cref getWorldTranslation() const
 
| <syntaxhighlight lang="c++">math::vec3::cref getWorldTranslation() const
Line 104: Line 118:
 
void setLocalTranslation(math::vec3::cref)
 
void setLocalTranslation(math::vec3::cref)
  
</syntaxhighlight> || Получение и установка позиции в мировых или локальных координатах
+
</syntaxhighlight> || <translate><!--T:30--> Получение и установка позиции в мировых или локальных координатах</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">math::vec3::cref getWorldScale() const
 
| <syntaxhighlight lang="c++">math::vec3::cref getWorldScale() const
Line 114: Line 128:
 
void setLocalScale(math::vec3::cref)
 
void setLocalScale(math::vec3::cref)
  
</syntaxhighlight> || Получение и установка масштаба в мировых или локальных координатах
+
</syntaxhighlight> || <translate><!--T:31--> Получение и установка масштаба в мировых или локальных координатах</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">math::vec3 getWorldUp() const
 
| <syntaxhighlight lang="c++">math::vec3 getWorldUp() const
Line 120: Line 134:
 
math::vec3 getWorldForward() const
 
math::vec3 getWorldForward() const
  
math::vec3 getWorldRight() const</syntaxhighlight> || Получение нормализованных векторов в направлениях вверх, вперёд и вправо пространства модели в мировых координатах
+
math::vec3 getWorldRight() const</syntaxhighlight> || <translate><!--T:32--> Получение нормализованных векторов в направлениях вверх, вперёд и вправо пространства модели в мировых координатах</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">math::Transform::cref getWorldTransform()    const
 
| <syntaxhighlight lang="c++">math::Transform::cref getWorldTransform()    const
Line 129: Line 143:
  
 
void setLocalTransform(math::Transform::cref)
 
void setLocalTransform(math::Transform::cref)
</syntaxhighlight> || Получение и установка трансформации в мировых или локальных координатах. Трансформация - сочетание позиции, поворота и масштаба
+
</syntaxhighlight> || <translate><!--T:33--> Получение и установка трансформации в мировых или локальных координатах. Трансформация - сочетание позиции, поворота и масштаба</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">math::Rotator::cref getWorldRotation() const
 
| <syntaxhighlight lang="c++">math::Rotator::cref getWorldRotation() const
Line 142: Line 156:
  
 
void rotateWorld(const math::Rotator&rotator)
 
void rotateWorld(const math::Rotator&rotator)
</syntaxhighlight> || Получение и установка поворота в мировых или локальных координатах. Методы rotateWorld/Local добавляют поворот к текущим значениям
+
</syntaxhighlight> || <translate><!--T:34--> Получение и установка поворота в мировых или локальных координатах. Методы rotateWorld/Local добавляют поворот к текущим значениям</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">const std::unordered_set<w4::sptr<Node>>& getChildren() const</syntaxhighlight> || Получение списка “детей“
+
| <syntaxhighlight lang="c++">const std::unordered_set<w4::sptr<Node>>& getChildren() const</syntaxhighlight> || <translate><!--T:35--> Получение списка “детей“</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">bool isEnabled() const</syntaxhighlight> || Возвращает, включен ли узел
+
| <syntaxhighlight lang="c++">bool isEnabled() const</syntaxhighlight> || <translate><!--T:36--> Возвращает, включен ли узел</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">bool hasParent() const</syntaxhighlight> || Возвращает имеет ли узел “родителя“
+
| <syntaxhighlight lang="c++">bool hasParent() const</syntaxhighlight> || <translate><!--T:37--> Возвращает имеет ли узел “родителя“</translate>
 
|-
 
|-
 
|}
 
|}
 
==== Hierarchy Example ====
 
==== Hierarchy Example ====
Возьмём реальные астрономические цифры и построим упрощённую модель солнечной системы. Так как используются космические расстояния, обозреть всю систему не представляется возможным (хотя ничего не мешает попробовать сделать модель более наглядной). В данном случае, модель взята не для визуализации, а для примера возможностей иерархии и вложенности трансформов.
+
<translate><!--T:38--> Возьмём реальные астрономические цифры и построим упрощённую модель солнечной системы. Так как используются космические расстояния, обозреть всю систему не представляется возможным (хотя ничего не мешает попробовать сделать модель более наглядной). В данном случае, модель взята не для визуализации, а для примера возможностей иерархии и вложенности трансформов.</translate>
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
 
#include "W4Framework.h"
 
#include "W4Framework.h"
Line 161: Line 175:
 
{
 
{
 
public:
 
public:
 +
<translate><!--T:39-->
 
//Немного данных о небесном теле:
 
//Немного данных о небесном теле:
 
// - имя
 
// - имя
Line 169: Line 184:
 
// - угол отклонения орбиты относительно плоскости обращения вокруг главного тела
 
// - угол отклонения орбиты относительно плоскости обращения вокруг главного тела
 
// - наклон оси
 
// - наклон оси
// - список спутников
+
// - список спутников</translate>
 
  Planet(const std::string& name, const color& planetColor, float planetRadius, float planetOrbit, float siderealPeriod, float eclipseAngle, float axisTilt, const std::vector<Planet>& moons)
 
  Planet(const std::string& name, const color& planetColor, float planetRadius, float planetOrbit, float siderealPeriod, float eclipseAngle, float axisTilt, const std::vector<Planet>& moons)
 
     : m_color(planetColor),
 
     : m_color(planetColor),
Line 193: Line 208:
 
     void onStart() override
 
     void onStart() override
 
     {
 
     {
         //на старте создаём солнечную систему
+
         //<translate><!--T:40--> на старте создаём солнечную систему</translate>
 
         createSolarSystem();
 
         createSolarSystem();
 
     }
 
     }
Line 205: Line 220:
 
         for(auto& rotation: m_rotations)
 
         for(auto& rotation: m_rotations)
 
         {
 
         {
             //вращаем тела вокруг их главных тел со скоростью 0.5 дня в секунду
+
             //<translate><!--T:41--> вращаем тела вокруг их главных тел со скоростью 0.5 дня в секунду</translate>
 
             rotation.first->rotateLocal(rotation.second * (dt / 2));
 
             rotation.first->rotateLocal(rotation.second * (dt / 2));
 
         }
 
         }
Line 214: Line 229:
 
     void createSolarSystem()
 
     void createSolarSystem()
 
     {
 
     {
         // вот она - Солнечная система!
+
         // <translate><!--T:42--> вот она - Солнечная система!</translate>
 
         const Planet solarSystem("Sun", color::yellow, 695500.f, 0.f, 345.39f, 0.f, 0.f, {
 
         const Planet solarSystem("Sun", color::yellow, 695500.f, 0.f, 345.39f, 0.f, 0.f, {
 
             {"Mercury", color::white,                        2439.7f,  57909050.f, .241f,  7.01f,    .0352f, {}},
 
             {"Mercury", color::white,                        2439.7f,  57909050.f, .241f,  7.01f,    .0352f, {}},
Line 248: Line 263:
 
         });
 
         });
  
         //Создаём Солнце
+
         //<translate><!--T:43--> Создаём Солнце</translate>
 
         auto sun = Mesh::create::sphere(solarSystem.m_radius, 10, 10);
 
         auto sun = Mesh::create::sphere(solarSystem.m_radius, 10, 10);
         //Добавляем его в корневой узел
+
         //<translate><!--T:44--> Добавляем его в корневой узел</translate>
 
         Render::getRoot()->addChild(sun);
 
         Render::getRoot()->addChild(sun);
  
         //Устанавливаем цвет для базового материала
+
         //<translate><!--T:45--> Устанавливаем цвет для базового материала</translate>
 
         sun->getMaterialInst()->setParam("baseColor", solarSystem.m_color);
 
         sun->getMaterialInst()->setParam("baseColor", solarSystem.m_color);
         //Создаём планеты
+
         //<translate><!--T:46--> Создаём планеты</translate>
 
         createMoons(sun, solarSystem);
 
         createMoons(sun, solarSystem);
         //Устанавливаем масштаб. Увы, расстояния такие, что с реальными расстояниями без лупы видно только Солнце... Но это пример.
+
         //<translate><!--T:47--> Устанавливаем масштаб. Увы, расстояния такие, что с реальными расстояниями без лупы видно только Солнце... Но это пример.</translate>
 
         sun->setLocalScale({1.e-7f, 1.e-7f, 1.e-7f});
 
         sun->setLocalScale({1.e-7f, 1.e-7f, 1.e-7f});
 
     }
 
     }
 
     void createMoons(cref<Node> planetNode, const Planet& planet)
 
     void createMoons(cref<Node> planetNode, const Planet& planet)
 
     {
 
     {
         //для каждого спутника
+
         //<translate><!--T:48--> для каждого спутника</translate>
 
         for(const auto& moon: planet.m_moons)
 
         for(const auto& moon: planet.m_moons)
 
         {
 
         {
             //для иллюстрации вложенности - создадим узел - орбиту, при вращении которого вокруг центра тело будет передвигаться по орбите
+
             //<translate><!--T:49--> для иллюстрации вложенности - создадим узел - орбиту, при вращении которого вокруг центра тело будет передвигаться по орбите</translate>
 
             auto orbitContainer = make::sptr<Node>();
 
             auto orbitContainer = make::sptr<Node>();
             //отклоняем орбиту от плоскости вращения главного тела
+
             //<translate><!--T:50--> отклоняем орбиту от плоскости вращения главного тела</translate>
 
             orbitContainer->setLocalRotation({(planet.m_axisTilt + moon.m_eclipseAngle) * DEG2RAD, 0, 0});
 
             orbitContainer->setLocalRotation({(planet.m_axisTilt + moon.m_eclipseAngle) * DEG2RAD, 0, 0});
             //создаём тело
+
             //<translate><!--T:51--> создаём тело</translate>
 
             auto moonNode = Mesh::create::sphere(moon.m_radius, 10, 10);
 
             auto moonNode = Mesh::create::sphere(moon.m_radius, 10, 10);
             //добавляем спутник как "ребёнка" орбиты
+
             //<translate><!--T:52--> добавляем спутник как "ребёнка" орбиты</translate>
 
             orbitContainer->addChild(moonNode);
 
             orbitContainer->addChild(moonNode);
             //устанавливаем позицию телав на орбите
+
             //<translate><!--T:53--> устанавливаем позицию тела на орбите</translate>
 
             moonNode->setLocalTranslation({moon.m_orbit, 0, 0});
 
             moonNode->setLocalTranslation({moon.m_orbit, 0, 0});
 
             moonNode->getMaterialInst()->setParam("baseColor", moon.m_color);
 
             moonNode->getMaterialInst()->setParam("baseColor", moon.m_color);
             //добавляем орбиту как "ребёнка" главного тела. Особое внимание на параметр false - он обозначает,  
+
             //<translate><!--T:54-->
 +
добавляем орбиту как "ребёнка" главного тела. Особое внимание на параметр false - он обозначает,  
 
             //что при чайлдинге сохраняются локальные трансформы. Таким образом, орбита окажется в той же позиции,  
 
             //что при чайлдинге сохраняются локальные трансформы. Таким образом, орбита окажется в той же позиции,  
             //что и планета и наклонена относительно его плоскости обращения
+
             //что и планета и наклонена относительно его плоскости обращения</translate>
 
             planetNode->addChild(orbitContainer, false);
 
             planetNode->addChild(orbitContainer, false);
             //рекурсивно создаём спутники
+
             //<translate><!--T:55--> рекурсивно создаём спутники</translate>
 
             createMoons(moonNode, moon);
 
             createMoons(moonNode, moon);
  
             //добавляем в список орбиты и кватернионы для их поворота в локальном пространстве (вычисляем из углов эйлера)
+
             //<translate><!--T:56--> добавляем в список орбиты и кватернионы для их поворота в локальном пространстве (вычисляем из углов эйлера)</translate>
 
             m_rotations.emplace_back(orbitContainer, Rotator(0, 0, 1 / moon.m_siderealPeriod));
 
             m_rotations.emplace_back(orbitContainer, Rotator(0, 0, 1 / moon.m_siderealPeriod));
 
         }
 
         }
Line 295: Line 311:
  
 
=== VisibleNode ===
 
=== VisibleNode ===
 +
<translate><!--T:57-->
 
Базовый класс для отображаемого узла.
 
Базовый класс для отображаемого узла.
  
 +
<!--T:58-->
 
Особенности:
 
Особенности:
 
* Все отображаемые узлы содержат вертексный буфер и состоят из одного и более элемента surface (который содержит индексный буфер).  
 
* Все отображаемые узлы содержат вертексный буфер и состоят из одного и более элемента surface (который содержит индексный буфер).  
 
* Каждому surface можно назначить свой материал.
 
* Каждому surface можно назначить свой материал.
Все отображаемые узлы имеют следующие дополнительные методы:
+
Все отображаемые узлы имеют следующие дополнительные методы:</translate>
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Метод !! Описание
+
! Method !! Description
 
|-
 
|-
| <syntaxhighlight lang="c++">const MaterialInstPtr& getMaterialInst(const std::string& surfaceName) const</syntaxhighlight> || Возвращает материал указанного surface
+
| <syntaxhighlight lang="c++">const MaterialInstPtr& getMaterialInst(const std::string& surfaceName) const</syntaxhighlight> || <translate><!--T:59--> Возвращает материал указанного surface</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">const MaterialInstPtr& getMaterialInst() const</syntaxhighlight> || Получает материал, установленный для всех surface. Если материалы surface отличаются - выдаёт ошибку в лог и возвращает какой-то материал.
+
| <syntaxhighlight lang="c++">const MaterialInstPtr& getMaterialInst() const</syntaxhighlight> || <translate><!--T:60--> Получает материал, установленный для всех surface. Если материалы surface отличаются - выдаёт ошибку в лог и возвращает какой-то материал.</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setMaterialInst(const MaterialInstPtr & m)</syntaxhighlight> || Устанавливает материал для всех surface
+
| <syntaxhighlight lang="c++">void setMaterialInst(const MaterialInstPtr & m)</syntaxhighlight> || <translate><!--T:61--> Устанавливает материал для всех surface</translate>
 
|}
 
|}
 
==== Mesh ====
 
==== Mesh ====
 +
<translate><!--T:62-->
 
Объект, отображающий геометрию.
 
Объект, отображающий геометрию.
  
Объекты типа Mesh в движке можно создать тремя путями:
+
<!--T:63-->
1. Загрузить из ресурсов (см. также [http://wiki.w4-dev.ciliz.com/index.php/Mesh_Converter Mesh Converter]):
+
Объекты типа Mesh в движке можно создать тремя путями:</translate>
 +
1. <translate><!--T:64--> Загрузить из ресурсов (см. также [http://wiki.w4-dev.ciliz.com/index.php/Mesh_Converter Mesh Converter]):</translate>
 
<syntaxhighlight lang="c++">teapot = Asset::load(Path("resources/teapot", "teapot.asset"))->getRoot()->getChild<Mesh>("Utah Teapot Quads");</syntaxhighlight>
 
<syntaxhighlight lang="c++">teapot = Asset::load(Path("resources/teapot", "teapot.asset"))->getRoot()->getChild<Mesh>("Utah Teapot Quads");</syntaxhighlight>
2. Вызвать встроенный генератор:
+
2. <translate><!--T:65--> Вызвать встроенный генератор:</translate>
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
auto sphere = Mesh::create::sphere(радиус, количество параллелей, количество меридианов);
+
auto sphere = Mesh::create::sphere<translate><!--T:66--> (радиус, количество параллелей, количество меридианов)</translate>;
auto box = Mesh::create::box({ширина, высота, глубина}); //box - параллелепипед, у которого каждая грань - surface
+
auto box = Mesh::create::box({width, height, depth}); //<translate><!--T:67--> box - параллелепипед, у которого каждая грань - surface</translate>
auto cube = Mesh::create::cube({ширина, высота, глубина});  
+
auto cube = Mesh::create::cube({width, height, depth});  
auto mappedCube = Mesh::create::mappedCube({ширина, высота, глубина}); //параллелепипед с uv координатами под развёртку
+
auto mappedCube = Mesh::create::mappedCube({width, height, depth}); //<translate><!--T:68--> параллелепипед с uv координатами под развёртку</translate>
auto plane1 = Mesh::create::plane({ширина, высота}, scaleUv); //плоскость по осям XY. scaleUv = false(по умолчанию) - UV от 0 до 1, true - от 0 до ширины/высоты
+
auto plane1 = Mesh::create::plane({width, height}, scaleUv); //<translate><!--T:69--> плоскость по осям XY. scaleUv = false(по умолчанию) - UV от 0 до 1, true - от 0 до ширины/высоты</translate>
auto plane2 = Mesh::create::plane({лево, низ}, {право, верх}, scaleUv; //то же самое
+
auto plane2 = Mesh::create::plane({left, down}, {right, up}, scaleUv; //<translate><!--T:70--> то же самое</translate>
auto cylinder = Mesh::create::cylinder(высота, радиус, количество секторов);
+
auto cylinder = Mesh::create::cylinder<translate><!--T:71--> (высота, радиус, количество секторов)</translate>;
auto cone = Mesh::create::cone(верхний радиус, нижний радиус, высота, количество секторов, количество сегментов по вертикали);
+
auto cone = Mesh::create::cone(<translate><!--T:72--> верхний радиус, нижний радиус, высота, количество секторов, количество сегментов по вертикали</translate>);
auto torus = Mesh::create::torus(радиус кольца, радиус "трубы", количество сегментов кольца, количество сегментов "трубы", угол дуги кольца(2*PI для замкнутого тора));
+
auto torus = Mesh::create::torus(<translate><!--T:73--> радиус кольца, радиус "трубы", количество сегментов кольца, количество сегментов "трубы", угол дуги кольца(2*PI для замкнутого тора)</translate>);
auto skybox = Mesh::create::skybox(); //Скайбокс. Единичный куб со сторонами, отображаемыми изнутри.
+
auto skybox = Mesh::create::skybox(); //<translate><!--T:74--> Скайбокс. Единичный куб со сторонами, отображаемыми изнутри.</translate>
 
</syntaxhighlight>
 
</syntaxhighlight>
3. Создать из кода:
+
3. <translate><!--T:75--> Создать из кода:</translate>
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
 
         auto indicesBuf = make::sptr<UserIndicesBuffer>("Floor indices");
 
         auto indicesBuf = make::sptr<UserIndicesBuffer>("Floor indices");
Line 338: Line 358:
  
 
         resources::MeshVertexDataBuilder vdb(verticesBuf, indicesBuf);
 
         resources::MeshVertexDataBuilder vdb(verticesBuf, indicesBuf);
         //позиция, UV, нормаль
+
         //<translate><!--T:76--> позиция, UV, нормаль</translate>
 
         vdb.addVertex({-width / 2 + offset, 0, height / 2}, {offset/width, 0.f}, {0, 1, 0});
 
         vdb.addVertex({-width / 2 + offset, 0, height / 2}, {offset/width, 0.f}, {0, 1, 0});
 
         vdb.addVertex({width / 2 - offset, 0, height / 2}, {1.f - offset/width, 0.f}, {0, 1, 0});
 
         vdb.addVertex({width / 2 - offset, 0, height / 2}, {1.f - offset/width, 0.f}, {0, 1, 0});
Line 365: Line 385:
  
 
==== SkinnedMesh ====
 
==== SkinnedMesh ====
 +
<translate><!--T:77-->
 
Объект, отображающий геометрию с анимацией.
 
Объект, отображающий геометрию с анимацией.
  
 +
<!--T:78-->
 
Особенности:
 
Особенности:
 
* можно загрузить только из файла;
 
* можно загрузить только из файла;
* представляет собой скелетную анимацию;
+
* представляет собой геометрию со скелетной анимацией;
* содержит в себе API для управления анимациями и позволяет проигрывать несколько анимаций с плавными переходами между ними.
+
* содержит в себе набор анимаций;
 +
* содержит в себе API для управления анимациями и позволяет проигрывать несколько анимаций с плавными переходами между ними.</translate>
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Метод !! Описание
+
! Method !! Description
 
|-
 
|-
| <syntaxhighlight lang="c++">w4::cref<core::Node> createSocket(const std::string& boneName)</syntaxhighlight>|| Создаёт точку крепления на кости с заданным именем. К этому узлу можно добавлять “детей“.
+
| <syntaxhighlight lang="c++">w4::cref<core::Node> createSocket(const std::string& boneName)</syntaxhighlight>|| <translate><!--T:79--> Создаёт узел для крепления на кости с заданным именем. К этому узлу можно добавлять “детей“</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">w4::cref<core::Node> getSocket(const std::string& boneName) const</syntaxhighlight>|| Возвращает точку крепления на кости с заданным именем
+
| <syntaxhighlight lang="c++">w4::cref<core::Node> getSocket(const std::string& boneName) const</syntaxhighlight>|| <translate><!--T:80--> Возвращает узел для крепления на кости с заданным именем</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">std::vector<std::string> getAvailableAnimations() const</syntaxhighlight>|| Возвращает список полученных анимация
+
| <syntaxhighlight lang="c++">std::vector<std::string> getAvailableAnimations() const</syntaxhighlight>|| <translate><!--T:81--> Возвращает список имеющихся анимаций</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">bool haveAnimation(const std::string& animationName) const</syntaxhighlight>|| Проверяет наличие анимации с заданным именем
+
| <syntaxhighlight lang="c++">bool haveAnimation(const std::string& animationName) const</syntaxhighlight>|| <translate><!--T:82--> Проверяет наличие анимации с заданным именем</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">size_t getAnimationIndex(const std::string& animationName) const</syntaxhighlight>|| Получение индекса анимации по её имени.
+
| <syntaxhighlight lang="c++">size_t getAnimationIndex(const std::string& animationName) const</syntaxhighlight>|| <translate><!--T:83--> Получение индекса анимации по её имени</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">const std::string& getAnimationName(size_t animationIndex) const</syntaxhighlight>|| Получение имени анимации по её индексу.
+
| <syntaxhighlight lang="c++">const std::string& getAnimationName(size_t animationIndex) const</syntaxhighlight>|| <translate><!--T:84--> Получение имени анимации по её индексу</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">void setAnimationStateChangedCallback(std::function<void(Animator&, Animator::State)>)
 
| <syntaxhighlight lang="c++">void setAnimationStateChangedCallback(std::function<void(Animator&, Animator::State)>)
  
void setAnimationStateChangedCallback(Animator::State, std::function<void(Animator&)>)</syntaxhighlight>|| Установить функтор, который вызовется по изменению состояния конкретной анимации. Метод имеет как вариант только для заданного состояния, так и для любого. Состояния анимаций:  
+
void setAnimationStateChangedCallback(Animator::State, std::function<void(Animator&)>)</syntaxhighlight>|| <translate><!--T:85--> Установить функтор, который вызовется по изменению состояния конкретной анимации. Метод имеет как вариант только для заданного состояния, так и для любого. Состояния анимаций:</translate>
  
  Animator::State::Idle(не проигрывается/закончилась),  
+
  Animator::State::Idle(<translate><!--T:86--> не проигрывается/закончилась</translate>),  
  
  Animator::State::Play(проигрывается),  
+
  Animator::State::Play(<translate><!--T:87--> проигрывается</translate>),  
  
  Animator::State::Pause(приостановлена)
+
  Animator::State::Pause(<translate><!--T:88--> приостановлена</translate>)
  
Пример:
+
<translate><!--T:89--> Пример:</translate>
 
<syntaxhighlight lang="c++">node->setAnimationStateChangedCallback(Animator::State::Idle, [](Animator& animator)
 
<syntaxhighlight lang="c++">node->setAnimationStateChangedCallback(Animator::State::Idle, [](Animator& animator)
 
{
 
{
Line 413: Line 436:
 
| <syntaxhighlight lang="c++">void play(const std::string& animationName, float duration = 0.f)
 
| <syntaxhighlight lang="c++">void play(const std::string& animationName, float duration = 0.f)
  
void play(size_t animationIndex = 0, float duration = 0.f)</syntaxhighlight>|| Проигрывание анимации по индексу или имени. Указывается длительность анимации, если она равна нулю - проигрывается анимация целиком.
+
void play(size_t animationIndex = 0, float duration = 0.f)</syntaxhighlight>|| <translate><!--T:90--> Проигрывание анимации по индексу или имени. Указывается длительность анимации, если она равна нулю - проигрывается анимация целиком</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">void play(std::initializer_list<std::pair<std::string, float>>, float duration = 0.f)
 
| <syntaxhighlight lang="c++">void play(std::initializer_list<std::pair<std::string, float>>, float duration = 0.f)
  
void play(std::initializer_list<std::pair<size_t, float>>, float duration = 0.f)</syntaxhighlight>|| Проигрывание списка анимаций с весами. Длительность, если равна нулю - равна анимации с максимальной длительностью.
+
void play(std::initializer_list<std::pair<size_t, float>>, float duration = 0.f)</syntaxhighlight>|| <translate><!--T:91--> Проигрывание списка анимаций с весами. Длительность, если равна нулю - равна анимации с максимальной длительностью</translate>
  
Пример:
+
<translate><!--T:92--> Пример:</translate>
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
 
skinned->play({{"run", .3f}, {"jump", .7f}});
 
skinned->play({{"run", .3f}, {"jump", .7f}});
 
</syntaxhighlight>
 
</syntaxhighlight>
 
|-
 
|-
| <syntaxhighlight lang="c++">void pause()</syntaxhighlight>|| Приостановить все активные анимации.
+
| <syntaxhighlight lang="c++">void pause()</syntaxhighlight>|| <translate><!--T:93--> Приостановить все активные анимации</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void resume()</syntaxhighlight>|| Возобновить проигрывание всех приостановленных анимаций.
+
| <syntaxhighlight lang="c++">void resume()</syntaxhighlight>|| <translate><!--T:94--> Возобновить проигрывание всех приостановленных анимаций</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void stop()</syntaxhighlight>|| Остановить проигрывание всех активных анимаций.
+
| <syntaxhighlight lang="c++">void stop()</syntaxhighlight>|| <translate><!--T:95--> Остановить проигрывание всех активных анимаций</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">bool isPlaying() const</syntaxhighlight>|| Проверяет, проигрывается ли сейчас любая анимация.
+
| <syntaxhighlight lang="c++">bool isPlaying() const</syntaxhighlight>|| <translate><!--T:96--> Проверяет, проигрывается ли сейчас любая анимация</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">Animator & getAnimator(size_t)
 
| <syntaxhighlight lang="c++">Animator & getAnimator(size_t)
Line 436: Line 459:
 
const Animator & getAnimator(size_t) const
 
const Animator & getAnimator(size_t) const
 
const Animator & getAnimator(const std::string&) const
 
const Animator & getAnimator(const std::string&) const
</syntaxhighlight>|| Получить объект аниматор по имени или индексу. API объекта Animator описан чуть ниже. Используется для управления анимациями с расширенными возможностями.
+
</syntaxhighlight>|| <translate><!--T:97--> Получить объект аниматор по имени или индексу. API объекта Animator описан чуть ниже. Используется для управления анимациями с расширенными возможностями.</translate>
  
'''Управление анимациями через API и SkinnedMesh не являются взаимоисключающими.''' Так, например, общеупотребительной является практика зацикливания анимаций:
+
<translate><!--T:98--> '''Управление анимациями через API и SkinnedMesh не являются взаимоисключающими.''' Так, например, общеупотребительной является практика зацикливания анимаций:</translate>
 
<syntaxhighlight lang="c++">m_skinned->getAnimator("dance").setIsLooped(true);</syntaxhighlight>
 
<syntaxhighlight lang="c++">m_skinned->getAnimator("dance").setIsLooped(true);</syntaxhighlight>
 
|}
 
|}
Line 444: Line 467:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Метод !! Описание
+
! Method !! Description
 
|-
 
|-
| <syntaxhighlight lang="c++">void play()</syntaxhighlight>|| Запуск воспроизведения анимации.  
+
| <syntaxhighlight lang="c++">void play()</syntaxhighlight>|| <translate><!--T:99-->
 +
Запуск воспроизведения анимации.  
  
'''В случае, если она уже проигрывается, она будет остановлена и запущена с начала.'''
+
<!--T:100-->
 +
'''В случае, если она уже проигрывается, она будет остановлена и запущена с начала'''</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void pause()</syntaxhighlight>|| Приостанавливает воспроизведение анимации.
+
| <syntaxhighlight lang="c++">void pause()</syntaxhighlight>|| <translate><!--T:101--> Приостанавливает воспроизведение анимации</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void resume()</syntaxhighlight>|| Возобновляет воспроизведение анимации.
+
| <syntaxhighlight lang="c++">void resume()</syntaxhighlight>|| <translate><!--T:102--> Возобновляет воспроизведение анимации</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void stop()</syntaxhighlight>|| Останавливает воспроизведение анимации.
+
| <syntaxhighlight lang="c++">void stop()</syntaxhighlight>|| <translate><!--T:103--> Останавливает воспроизведение анимации</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void seek(float targetTime)</syntaxhighlight>|| Устанавливает текущую позицию в анимации на заданное время. '''Значения автоматически обрезаются сверху и снизу до диапазона [0; длина анимации] или до диапазона, заданного методами setBeginTime/setEndTime'''
+
| <syntaxhighlight lang="c++">void seek(float targetTime)</syntaxhighlight>|| <translate><!--T:104--> Устанавливает текущую позицию в анимации на заданное время. '''Значения автоматически обрезаются сверху и снизу до диапазона [0; длина анимации] или до диапазона, заданного методами setBeginTime/setEndTime'''</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">bool isLooped() const</syntaxhighlight>|| Возвращает, включен ли для данной анимации режим циклическое воспроизведение.
+
| <syntaxhighlight lang="c++">bool isLooped() const</syntaxhighlight>|| <translate><!--T:105--> Возвращает, включен ли для данной анимации режим циклическое воспроизведение</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">float getSpeed() const</syntaxhighlight>|| Получает множитель скорости воспроизведения анимации (по умолчанию 1.0)
+
| <syntaxhighlight lang="c++">float getSpeed() const</syntaxhighlight>|| <translate><!--T:106--> Получает множитель скорости воспроизведения анимации (по умолчанию 1.0)</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">State getState() const</syntaxhighlight>|| Возвращает состояние анимации.
+
| <syntaxhighlight lang="c++">State getState() const</syntaxhighlight>|| <translate><!--T:107--> Возвращает состояние анимации</translate>
  
Состояния анимаций:
+
<translate><!--T:108--> Состояния анимаций:</translate>
  Animator::State::Idle(не проигрывается/закончилась),
+
  Animator::State::Idle <translate><!--T:109--> (не проигрывается/закончилась)</translate>,
  Animator::State::Play(проигрывается),
+
  Animator::State::Play <translate><!--T:110--> (проигрывается)</translate>,
  Animator::State::Pause(приостановлена)
+
  Animator::State::Pause <translate><!--T:111--> (приостановлена)</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setPlayType(PlayType)</syntaxhighlight>|| Устанавливает направление воспроизведения.  
+
| <syntaxhighlight lang="c++">void setPlayType(PlayType)</syntaxhighlight>|| <translate><!--T:112-->
 +
Устанавливает направление воспроизведения.  
  
Возможные значения параметра:
+
<!--T:113-->
  Animator::PlayType::Forward(вперёд),
+
Возможные значения параметра:</translate>
  Animator::PlayType::Backward(в обратном направлении)
+
  Animator::PlayType::<translate><!--T:114--> Forward (вперёд)</translate>,
 +
  Animator::PlayType::<translate><!--T:115--> Backward (в обратном направлении)</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">PlayType getPlayType() const</syntaxhighlight>|| Возвращает текущее направление проигрывания. Возможные значения см. в '''setPlayType'''
+
| <syntaxhighlight lang="c++">PlayType getPlayType() const</syntaxhighlight>|| <translate><!--T:116--> Возвращает текущее направление проигрывания. Возможные значения см. в '''setPlayType'''</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">float getCurrentTime() const</syntaxhighlight>|| Возвращает текущую позицию в анимации
+
| <syntaxhighlight lang="c++">float getCurrentTime() const</syntaxhighlight>|| <translate><!--T:117--> Возвращает текущую позицию в анимации</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setIsLooped(bool)</syntaxhighlight>|| Включает/выключает для данной анимации режим циклического воспроизведение.
+
| <syntaxhighlight lang="c++">void setIsLooped(bool)</syntaxhighlight>|| <translate><!--T:118--> Включает/выключает для данной анимации режим циклического воспроизведение</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setSpeed(float)</syntaxhighlight>|| Устанавливает множитель скорости воспроизведения анимации.
+
| <syntaxhighlight lang="c++">void setSpeed(float)</syntaxhighlight>|| <translate><!--T:119--> Устанавливает множитель скорости воспроизведения анимации</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setBeginTime(float)</syntaxhighlight>|| Устанавливает начальное время анимации. Нужно для частичного воспроизведения анимации.
+
| <syntaxhighlight lang="c++">void setBeginTime(float)</syntaxhighlight>|| <translate><!--T:120--> Устанавливает начальное время анимации. Нужно для частичного воспроизведения анимации</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setEndTime(float)</syntaxhighlight>|| Устанавливает конечное время анимации. Нужно для частичного воспроизведения анимации.
+
| <syntaxhighlight lang="c++">void setEndTime(float)</syntaxhighlight>|| <translate><!--T:121--> Устанавливает конечное время анимации. Нужно для частичного воспроизведения анимации</translate>
 
|-
 
|-
 
| <syntaxhighlight lang="c++">StateHandlerId setStateHandler(State state, StateHandler handler)
 
| <syntaxhighlight lang="c++">StateHandlerId setStateHandler(State state, StateHandler handler)
void resetStateHandler(StateHandlerId handler)</syntaxhighlight>|| Устанавливает и удаляет callback на смену состояния на заданное. Сигнатура '''callback - void(Animator&)'''
+
void resetStateHandler(StateHandlerId handler)</syntaxhighlight>|| <translate><!--T:122--> Устанавливает и удаляет callback на смену состояния на заданное. Сигнатура '''callback - void(Animator&)'''</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void setTimeHandler(float dt, TimeHandler handler)</syntaxhighlight>|| Устанавливает callback на прохождение заданной временной метки. Сигнатура '''callback - void(Animator&)'''
+
| <syntaxhighlight lang="c++">void setTimeHandler(float dt, TimeHandler handler)</syntaxhighlight>|| <translate><!--T:123--> Устанавливает callback на прохождение заданной временной метки. Сигнатура '''callback - void(Animator&)'''</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">float getFps() const</syntaxhighlight>|| Возвращает характеристику анимации - количество значений в секунду.
+
| <syntaxhighlight lang="c++">float getFps() const</syntaxhighlight>|| <translate><!--T:124--> Возвращает характеристику анимации - количество значений в секунду.</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">float getDuration() const</syntaxhighlight>|| Возвращает длительность анимации
+
| <syntaxhighlight lang="c++">float getDuration() const</syntaxhighlight>|| <translate><!--T:125--> Возвращает длительность анимации</translate>
 
|}
 
|}
  
 
==== ParticlesEmitter ====
 
==== ParticlesEmitter ====
Генератор частиц.
+
<translate>
 
+
<!--T:127-->
 
Особенности:
 
Особенности:
 
* ParticlesEmitter может быть загружен только из файла;  
 
* ParticlesEmitter может быть загружен только из файла;  
* Входным форматом файла является CoronaSDK (можно создать в любом онлайн-редакторе, например в http://www.effecthub.com/particle2dx, сохранить json с расширением part и убедиться, что путь к текстуре является путём от корня проекта).  
+
* Входным форматом файла является CoronaSDK (можно создать в любом онлайн-редакторе, например в http://www.effecthub.com/particle2dx, сохранить json с расширением part и текстуру и убедиться, что путь к текстуре является путём от корня проекта). </translate>
  
Важно понимать и учитывать, что в связи с ограниченными вычислительными и асинхронными возможностями технологии WebAssembly на текущий момент, система частиц отображается на плоскости, развёрнутой к камере.
+
<translate><!--T:128--> Важно понимать и учитывать, что в связи с ограниченными вычислительными и асинхронными возможностями технологии WebAssembly на текущий момент, система частиц отображается на плоскости, развёрнутой к камере.</translate>
  
 
'''API ParticlesEmitter:'''
 
'''API ParticlesEmitter:'''
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Метод !! Описание
+
! Method !! Description
 
|-
 
|-
| <syntaxhighlight lang="c++">void start()</syntaxhighlight> || Запуск генерации частиц
+
| <syntaxhighlight lang="c++">void start()</syntaxhighlight> || <translate><!--T:129--> Запуск генерации частиц</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void pause()</syntaxhighlight> || Приостановка генерации частиц. В этом случае обработка уже выпущенных частиц продолжается.
+
| <syntaxhighlight lang="c++">void pause()</syntaxhighlight> || <translate><!--T:130--> Приостановка генерации частиц. В этом случае обработка уже выпущенных частиц продолжается</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void resume()</syntaxhighlight> || Возобновление генерации частиц
+
| <syntaxhighlight lang="c++">void resume()</syntaxhighlight> || <translate><!--T:131--> Возобновление генерации частиц</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">void stop()</syntaxhighlight> || Остановка генерации частиц. Обработка всех частиц прекращается.
+
| <syntaxhighlight lang="c++">void stop()</syntaxhighlight> || <translate><!--T:132--> Остановка генерации частиц. Обработка всех частиц прекращается</translate>
 
|-
 
|-
| <syntaxhighlight lang="c++">State getState() const</syntaxhighlight> || Получение состояния.
+
| <syntaxhighlight lang="c++">State getState() const</syntaxhighlight> || <translate><!--T:133--> Получение состояния</translate>
  
Варианты:  
+
<translate><!--T:134--> Варианты:</translate>
 
  ParticlesEmitter::State::IDLE,  
 
  ParticlesEmitter::State::IDLE,  
 
  ParticlesEmitter::State::STARTED,  
 
  ParticlesEmitter::State::STARTED,  
Line 528: Line 555:
  
 
==== Billboard ====
 
==== Billboard ====
 +
<translate><!--T:135--> Плоскость заданного при создании размера, всегда ориентированная на камеру. Имеет методы '''getSize''' и '''setSize'''.</translate>
  
 
==== Plotter ====
 
==== Plotter ====
 +
<translate><!--T:136--> Реализация рисования линиями. Данные плоттера представляют собой информацию о точках (позиция и цвет) и набор индексов для их попарного соединения.</translate>
 +
 +
<translate><!--T:137--> Пример:</translate>
 +
<syntaxhighlight lang="c++">
 +
auto plotter1 = make::sptr<Plotter>("Plotter_1");
 +
const std::vector<uint32_t> indices = {1, 0};
 +
const std::vector<LinesVertexFormat> vertices = {{{-10, -10, 0}, {1, 0, 0,1}},
 +
                                                {{10, 10, 0}, {0, 1, 0, 1}}};
 +
plotter1->setLines(vertices, indices);
 +
</syntaxhighlight>                                               
 +
<translate><!--T:138--> Представленный выше пример создаст косую линию с цветом, переходящим из красного в зелёный.</translate>
 +
 +
<translate><!--T:139--> Как правило, для создания примитивов используются статические хелперы, возвращающие готовый объект, описанные в классе Plotter:</translate>
 +
<syntaxhighlight lang="c++">
 +
static w4::sptr<Plotter> build(std::vector<LinesVertexFormat> vertices, std::vector<uint32_t> indices);
 +
static w4::sptr<Plotter> buildFromSegments(std::vector<std::array<w4::math::vec3, 2>> segments, const w4::math::vec4& color);
 +
static w4::sptr<Plotter> buildFromPolyline(std::vector<w4::math::vec3> points, const w4::math::vec4& color);
 +
static w4::sptr<Plotter> buildSphere(float radius, size_t rings, size_t sectors, const w4::math::vec4& color);
 +
static w4::sptr<Plotter> buildOctahedron(std::array<w4::math::vec3, 8> vertices, const w4::math::vec4& color);
 +
static w4::sptr<Plotter> buildCube(std::array<w4::math::vec3, 2> inVertices, const w4::math::vec4& color);
 +
static w4::sptr<Plotter> buildCapsule(float radius, float height, size_t rings, size_t sectors, const w4::math::vec4& color);
 +
static w4::sptr<Plotter> buildMesh(w4::cref<Mesh>, w4::math::vec4::cref color);
 +
static w4::sptr<Plotter> buildMesh(w4::cref<SkinnedMesh>, w4::math::vec4::cref color);
 +
static w4::sptr<Plotter> buildRay(math::vec3::cref startPoint, math::vec3::cref directionPoint, const w4::math::vec4& color);
 +
</syntaxhighlight>
  
 
=== DataNode ===
 
=== DataNode ===
 
+
<translate><!--T:140--> В отличие от '''VisibleNode''', '''DataNode''' не отображается на экране. Далее описывается API унаследованных классов.</translate>
 
==== ArcBallNode ====
 
==== ArcBallNode ====
 +
<translate><!--T:141--> Аркболл для нижележащих объектов иерархии. Реализует контейнер, позволяющий вращать содержимое, как если бы оно находилось в шаре с инерцией.</translate>
 +
{| class="wikitable"
 +
|-
 +
! Method !! Description
 +
|-
 +
| <syntaxhighlight lang="c++">ArcBallNode(const std::string& name = core::Object::defaultName, float radius = 1.f)</syntaxhighlight> || <translate><!--T:142--> Конструктор, принимающий имя и радиус "шара"</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void setFriction(float v)</syntaxhighlight> || <translate><!--T:143--> Задать коэффициент затухания скорости. По умолчанию = 0.95</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void setSensitivity(float v)</syntaxhighlight> || <translate><!--T:144--> Задать множитель чувствительности к прикосновению. По умолчанию = 1</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void setRadius(float r)</syntaxhighlight> || <translate><!--T:145--> Задать радиус</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void setVelocity(const math::Rotator& v)</syntaxhighlight> || <translate><!--T:146--> Задать угловую скорость</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void enableUpdate(bool flag = true)
 +
void disableUpdate()</syntaxhighlight> || <translate><!--T:147--> Включить/отключить вращение аркболла. '''Не сбрасывает скорость, при включении - может продолжить вращаться (затухание скорости по времени)'''</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void enableInput(bool flag = true)
 +
void disableInput()</syntaxhighlight> || <translate><!--T:148--> Включение/выключение перехвата прикосновений аркболлом</translate>
 +
|}
  
 
==== Camera ====
 
==== Camera ====
 +
{| class="wikitable"
 +
|-
 +
! Method !! Description
 +
|-
 +
| <syntaxhighlight lang="c++">Camera(const std::string& name)
 +
Camera(const std::string& name, float fov, float aspect, float near, float far)</syntaxhighlight> || <translate><!--T:149--> Конструкторы перспективной камеры. Можно сразу указать FOV(угол обзора камеры по горизонтали), соотношение сторон и clip плоскости. '''FOV указывается в градусах'''</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">Camera(const std::string& name, const math::size& screen, float near, float far)</syntaxhighlight> || <translate><!--T:150--> Конструктор ортокамеры. Указываются размеры и clip плоскости камеры</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">float getFov() const
 +
void setFov(float v)</syntaxhighlight> || <translate><!--T:151--> Получить, установить FOV(угол обзора камеры по горизонтали). '''FOV указывается в градусах'''</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">float getAspect() const
 +
void setAspect(float v)</syntaxhighlight> || <translate><!--T:152--> Получить/установить соотношение сторон</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">float getNear() const
 +
void setNear(float v)</syntaxhighlight> || <translate><!--T:153--> Получить/установить near clip плоскость</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">float getFar() const
 +
void setFar(float v)</syntaxhighlight> || <translate><!--T:154--> Получить/установить far clip плоскость</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">bool getIsOrtho() const</syntaxhighlight> || <translate><!--T:155--> Получить является ли камера ортокамерой</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void setClearColor(const math::vec4& v)</syntaxhighlight> || <translate><!--T:156--> Задать значение цвета для очистки буфера цвета (фоновый цвет для камеры при отсутствии Background или Skybox)</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">ClearMask getClearMask() const
 +
void setClearMask(ClearMask v)</syntaxhighlight> || <translate><!--T:157--> Получить/установить ,битовую маску режима очистки экрана. Это значение будет применяться при рендеринге каждого кадра.</translate>
 +
 +
<translate><!--T:158-->
 +
Значение по умолчанию '''ClearMask::Color | ClearMask::Depth'''
 +
 +
<!--T:159-->
 +
Возможные значения:</translate>
 +
 +
None
 +
 +
<translate><!--T:160-->
 +
Color - очищать буфер цвета
 +
 +
<!--T:161-->
 +
Depth - очищать буфер глубины
 +
 +
<!--T:162-->
 +
Skybox - отрисовывать ли skybox
 +
 +
<!--T:163-->
 +
Background - отрисовывать ли background</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">bool hasSkybox() const
 +
w4::cref<Skybox> getSkybox() const</syntaxhighlight> || <translate><!--T:164--> Получить текущий объект skybox или nullptr при его отсутствии</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">bool hasBackground() const
 +
w4::cref<Background> getBackground() const</syntaxhighlight> || <translate><!--T:165--> Получить текущий объект background или nullptr при его отсутствии</translate>
 +
|}
 +
 +
===== Background =====
 +
<translate><!--T:166--> Background представляет собой ресурсовыгодный способ очистки буфера цвета чем-то, что сложнее одного цвета.</translate>
 +
 +
<translate><!--T:167-->
 +
Может использоваться двумя способами:
 +
# Вызовом метода '''void setTexture(w4::cref<resources::Texture> texture)'''. При вызове создастся материал по умолчанию (просто отображает текстуру).
 +
# Работа с материалами вручную через методы '''void setMaterial(w4::cref<resources::MaterialInst>)''' и '''w4::sptr<resources::MaterialInst> getMaterial()'''. '''Вертексный шейдер должен использовать нормализованное пространство координат (т.е. [-1; 1])'''</translate>
 +
 +
===== Skybox =====
 +
<translate><!--T:168--> В случае если необходимо чтобы фон смещался при движении камеры, можно использовать объект Skybox. Он также может использоваться двумя способами:</translate>
 +
 +
<translate><!--T:169--> 1. Вызовом метода '''void setCubemap(w4::cref<resources::Cubemap> texture)'''. При вызове создастся материал по умолчанию (просто отображает текстуру).</translate>
 +
 +
<translate><!--T:170--> Пример:</translate>
 +
<syntaxhighlight lang="c++">
 +
auto cubemap = Cubemap::get({"resources/textures/left.png",
 +
                            "resources/textures/right.png",
 +
                            "resources/textures/up.png",
 +
                            "resources/textures/down.png",
 +
                            "resources/textures/front.png",
 +
                            "resources/textures/back.png",
 +
                            });
 +
m_cam->setClearMask(ClearMask::Color | ClearMask::Depth | ClearMask::Skybox);
 +
m_cam->getSkybox()->setCubemap(cubemap);
 +
</syntaxhighlight>
 +
<translate><!--T:171--> 2. Работа с материалами вручную через методы '''void setMaterial(w4::cref<resources::MaterialInst>)''' и '''w4::sptr<resources::MaterialInst> getMaterial()'''. '''Вертексный шейдер должен использовать нормализованное пространство координат (т.е. [-1; 1])'''</translate>
  
 
==== PointLight ====
 
==== PointLight ====
 +
<translate><!--T:172--> Точечный источник освещения. Имеет следующий API:</translate>
 +
{| class="wikitable"
 +
|-
 +
! Method !! Description
 +
|-
 +
| <syntaxhighlight lang="c++">math::vec3 getColor() const
 +
void setColor(const math::vec3& c)</syntaxhighlight> || <translate><!--T:173--> Получить/установить цвет света</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">float getIntensity() const
 +
void setIntensity(float i)</syntaxhighlight> || <translate><!--T:174--> Получить/установить яркость источника света</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">core::LightDecayRate getDecayRate() const
 +
void setDecayRate(core::LightDecayRate)</syntaxhighlight> || <translate><!--T:175--> Получить/установить алгоритм затухания цвета</translate> (None, Linear, Quadratic, Cubic).
 +
|}
  
 
==== SpotLight ====
 
==== SpotLight ====
 +
<translate><!--T:176--> Направленный источник освещения в виде конуса с вершиной в точке излучения.</translate>
 +
{| class="wikitable"
 +
|-
 +
! Method !! Description
 +
|-
 +
| <syntaxhighlight lang="c++">float getAngle() const
 +
void setAngle(float r)</syntaxhighlight> || <translate><!--T:177--> Получить/установить верхний угол конуса</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">math::vec3 getColor() const
 +
void setColor(const math::vec3& c)</syntaxhighlight> || <translate><!--T:178--> Получить/установить цвет света</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">float getIntensity() const
 +
void setIntensity(float i)</syntaxhighlight> || <translate><!--T:179--> Получить/установить яркость источника света</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">core::LightDecayRate getDecayRate() const
 +
void setDecayRate(core::LightDecayRate)</syntaxhighlight> || <translate><!--T:180--> Получить/установить алгоритм затухания цвета</translate> (None, Linear, Quadratic, Cubic)
 +
|-
 +
| <syntaxhighlight lang="c++">float getDecayFactor() const
 +
void setDecayFactor(float f)</syntaxhighlight> || <translate><!--T:181--> Получить/установить степень затухания(“прозрачность“) цвета от 0 до 1(по умолчанию = 1)</translate>
 +
|}
  
 
==== Spline ====
 
==== Spline ====
 +
<translate><!--T:182--> Позволяет использовать траектории, импортированные из fbx (b-spline). </translate>
 +
 +
'''<translate><!--T:183--> Важно понимать, что в формате FBX Spline содержит только саму траекторию, но не вращения вокруг неё (spin).</translate>'''
 +
{| class="wikitable"
 +
|-
 +
! Method !! Description
 +
|-
 +
| <syntaxhighlight lang="c++">bool isRepeatable() const
 +
void setRepeatable(bool isRepeatable)</syntaxhighlight> || <translate><!--T:184--> Получить/установить режим повторяющегося “воспроизведения”</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void play(float splineTime, std::function<void(const math::Transform&)> updateHandler, std::function<void(bool)> completionHandler = [](bool){})</syntaxhighlight> || <translate><!--T:185--> Запуск “воспроизведения” сплайна</translate>
 +
 +
<translate><!--T:186--> splineTime - конечное время воспроизведения сплайна(для расчёта множителя скорости)</translate>
 +
 +
<translate><!--T:187--> updateHandler - метод, в который будут приходить Transform</translate>
 +
 +
<translate><!--T:188--> completionHandler - метод, который вызовется при завершении “воспроизведения” (если не задано повторение)</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void stop()</syntaxhighlight> || <translate><!--T:189--> Остановить “воспроизведение” преобразований</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">bool isPlaying() const</syntaxhighlight> || <translate><!--T:190--> Возвращает, идёт ли “воспроизведение” сплайна</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">bool isPaused() const
 +
void pause()</syntaxhighlight> || <translate><!--T:191--> Приостановка “воспроизведения” сплайна</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">float getDuration() const</syntaxhighlight> || <translate><!--T:192--> Возвращает длительность сплайна в секундах</translate>
 +
|-
 +
| <syntaxhighlight lang="c++">void setPosition(float pos)</syntaxhighlight> || <translate><!--T:193--> Устанавливает позицию в секундах</translate>
 +
|}

Latest revision as of 13:55, 19 June 2020

Other languages:
English • ‎русский

Scope

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

  • Координатная истема
  • Нодовая система
  • API основных классов

Coordinate System

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

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

Render Tree

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

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

Иерархия типов

Назначение и интерфейсы узлов (классов) описаны в следующих параграфах.

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

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

Node

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

Method Description
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->setLocalTranslation({1, 0, 0});
parentNode->addChild(childNode);

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

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

childNode->setLocalTranslation({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

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

#include "W4Framework.h"

W4_USE_UNSTRICT_INTERFACE

class Planet
{
public:
//Немного данных о небесном теле:
// - имя
// - цвет
// - радиус (км)
// - радиус орбиты (км)
// - период оборота вокруг главного тела (дней)
// - угол отклонения орбиты относительно плоскости обращения вокруг главного тела
// - наклон оси
// - список спутников
 Planet(const std::string& name, const color& planetColor, float planetRadius, float planetOrbit, float siderealPeriod, float eclipseAngle, float axisTilt, const std::vector<Planet>& moons)
    : m_color(planetColor),
      m_radius(planetRadius),
      m_orbit(planetOrbit),
      m_siderealPeriod(siderealPeriod),
      m_eclipseAngle(eclipseAngle),
      m_axisTilt(axisTilt),
      m_moons(moons)
 {}
 color m_color;
 float m_radius;
 float m_orbit;
 float m_siderealPeriod;
 float m_eclipseAngle;
 float m_axisTilt;
 std::vector<Planet> m_moons;
};

struct SolarDemo : public IGame
{
public:
    void onStart() override
    {
        //на старте создаём солнечную систему
        createSolarSystem();
    }

    void onMove(const event::Touch::Move& evt)
    {
    }

    void onUpdate(float dt) override
    {
        for(auto& rotation: m_rotations)
        {
            //вращаем тела вокруг их главных тел со скоростью 0.5 дня в секунду
            rotation.first->rotateLocal(rotation.second * (dt / 2));
        }
    }

private:

    void createSolarSystem()
    {
        // вот она - Солнечная система!
        const Planet solarSystem("Sun", color::yellow, 695500.f, 0.f, 345.39f, 0.f, 0.f, {
            {"Mercury", color::white,                        2439.7f,   57909050.f, .241f,   7.01f,    .0352f, {}},
            {"Venus",   color::magenta,                      6051.8f,  108208000.f, .615,    3.39f, 177.36f,   {}},
            {"Earth",   color::green,                        6378.f,   149598261.f, 1.f,     0.f,    23.44f,   {
                        {"Moon", color::gray, 1737.1f,  384399.f, 1.f, 0.f, 0.f, {}}
                }},
            {"Mars",    color::red,                          3393.5f,  227939100.f, 1.88f,   1.85f,  25.19f,   {
                        {"Phobos", color::gray, 11.2667f, 9377.2f, .317f,   1.093f, 0.f, {}},
                        {"Demos",  color::gray, 10.f,   23458.f, 1.2625f,   1.85f , 0.f, {}}
                }},
            {"Jupiter", color(1.f, .5f, 0.f, 1.f),          71400.f,   778547200.f, 11.86f,  1.31f,   3.13f,   {
                        {"Callisto", color::gray, 2410.3f, 1882709.f, 16.69f, .205f, 0.f, {}},
                        {"Europa",   color::gray, 1560.8f,  671034.f, 3.55f, .471f, 0.f,  {}},
                        {"Ganymede", color::gray, 2634.1f, 1070412.f, 7.15f, .204f, 0.f,  {}},
                        {"Io",       color::gray, 1818.f,   421700.f, 1.77f, .05f, 0.f,   {}}
                }},
            {"Saturn",  (color::yellow + color::white) / 2, 60000.f,  1433449370.f, 29.46f,  2.49f,  26.73f,   {
                        {"Dione",     color::gray, 560.f,   377415.f, 2.74f,      .028f, 0.f, {}},
                        {"Enceladus", color::gray, 251.4f,  238042.f, 1.370218f, 0.f, 0.f,    {}},
                        {"Tethys",    color::gray, 530.f,   294672.f, 1.887802f, 1.091f, 0.f, {}},
                        {"Titan",     color::gray, 2575.f, 1221865.f, 15.945f,    .306f, 0.f, {}}
                }},
            {"Uranus",  color::cyan,                        25600.f,  2876679082.f, 84.01f,  .77f,   97.77f,   {
                        {"Ariel",   color::gray, 578.9f,  191020.f, 2.520379f,  .26f,  0.f, {}},
                        {"Oberon",  color::gray, 761.4f,  583520.f, 13.463239f, .058f, 0.f, {}},
                        {"Titania", color::gray, 588.9f,  435910.f, 8.705872f,  .34f , 0.f, {}},
                        {"Umbriel", color::gray, 584.7f,  266300.f, 4.144177f,  .205f, 0.f, {}}
                }},
            {"Neptune", color::blue,                        24300.f,  4503443661.f, 164.79f, 1.77f,  28.32f,   {
                        {"Triton", color::gray, 1353.4, 4503443661.f, 164.79f, 1.77f, 0.f, {}}
                }}
        });

        //Создаём Солнце
        auto sun = Mesh::create::sphere(solarSystem.m_radius, 10, 10);
        //Добавляем его в корневой узел
        Render::getRoot()->addChild(sun);

        //Устанавливаем цвет для базового материала
        sun->getMaterialInst()->setParam("baseColor", solarSystem.m_color);
        //Создаём планеты
        createMoons(sun, solarSystem);
        //Устанавливаем масштаб. Увы, расстояния такие, что с реальными расстояниями без лупы видно только Солнце... Но это пример.
        sun->setLocalScale({1.e-7f, 1.e-7f, 1.e-7f});
    }
    void createMoons(cref<Node> planetNode, const Planet& planet)
    {
        //для каждого спутника
        for(const auto& moon: planet.m_moons)
        {
            //для иллюстрации вложенности - создадим узел - орбиту, при вращении которого вокруг центра тело будет передвигаться по орбите
            auto orbitContainer = make::sptr<Node>();
            //отклоняем орбиту от плоскости вращения главного тела
            orbitContainer->setLocalRotation({(planet.m_axisTilt + moon.m_eclipseAngle) * DEG2RAD, 0, 0});
            //создаём тело
            auto moonNode = Mesh::create::sphere(moon.m_radius, 10, 10);
            //добавляем спутник как "ребёнка" орбиты
            orbitContainer->addChild(moonNode);
            //устанавливаем позицию тела на орбите
            moonNode->setLocalTranslation({moon.m_orbit, 0, 0});
            moonNode->getMaterialInst()->setParam("baseColor", moon.m_color);
            //добавляем орбиту как "ребёнка" главного тела. Особое внимание на параметр false - он обозначает, 
            //что при чайлдинге сохраняются локальные трансформы. Таким образом, орбита окажется в той же позиции, 
            //что и планета и наклонена относительно его плоскости обращения
            planetNode->addChild(orbitContainer, false);
            //рекурсивно создаём спутники
            createMoons(moonNode, moon);

            //добавляем в список орбиты и кватернионы для их поворота в локальном пространстве (вычисляем из углов эйлера)
            m_rotations.emplace_back(orbitContainer, Rotator(0, 0, 1 / moon.m_siderealPeriod));
        }
    }

    std::vector<std::pair<sptr<Node>, Rotator>> m_rotations;
};

W4_RUN(SolarDemo)

VisibleNode

Базовый класс для отображаемого узла.

Особенности:

  • Все отображаемые узлы содержат вертексный буфер и состоят из одного и более элемента surface (который содержит индексный буфер).
  • Каждому surface можно назначить свой материал.

Все отображаемые узлы имеют следующие дополнительные методы:

Method Description
const MaterialInstPtr& getMaterialInst(const std::string& surfaceName) const
Возвращает материал указанного surface
const MaterialInstPtr& getMaterialInst() const
Получает материал, установленный для всех surface. Если материалы surface отличаются - выдаёт ошибку в лог и возвращает какой-то материал.
void setMaterialInst(const MaterialInstPtr & m)
Устанавливает материал для всех surface

Mesh

Объект, отображающий геометрию.

Объекты типа Mesh в движке можно создать тремя путями: 1. Загрузить из ресурсов (см. также Mesh Converter):

teapot = Asset::load(Path("resources/teapot", "teapot.asset"))->getRoot()->getChild<Mesh>("Utah Teapot Quads");

2. Вызвать встроенный генератор:

auto sphere = Mesh::create::sphere(радиус, количество параллелей, количество меридианов);
auto box = Mesh::create::box({width, height, depth}); //box - параллелепипед, у которого каждая грань - surface
auto cube = Mesh::create::cube({width, height, depth}); 
auto mappedCube = Mesh::create::mappedCube({width, height, depth}); //параллелепипед с uv координатами под развёртку
auto plane1 = Mesh::create::plane({width, height}, scaleUv); //плоскость по осям XY. scaleUv = false(по умолчанию) - UV от 0 до 1, true - от 0 до ширины/высоты
auto plane2 = Mesh::create::plane({left, down}, {right, up}, scaleUv; //то же самое
auto cylinder = Mesh::create::cylinder(высота, радиус, количество секторов);
auto cone = Mesh::create::cone(верхний радиус, нижний радиус, высота, количество секторов, количество сегментов по вертикали);
auto torus = Mesh::create::torus(радиус кольца, радиус "трубы", количество сегментов кольца, количество сегментов "трубы", угол дуги кольца(2*PI для замкнутого тора));
auto skybox = Mesh::create::skybox(); //Скайбокс. Единичный куб со сторонами, отображаемыми изнутри.

3. Создать из кода:

        auto indicesBuf = make::sptr<UserIndicesBuffer>("Floor indices");
        auto verticesBuf = make::sptr<UserVerticesBuffer<Mesh::VertexFormat>>("floor_" + std::to_string(width) + "x" + std::to_string(height) + "-" + std::to_string(offset));
        indicesBuf->setNeedExport(false);
        verticesBuf->setNeedExport(false);

        resources::MeshVertexDataBuilder vdb(verticesBuf, indicesBuf);
        //позиция, UV, нормаль
        vdb.addVertex({-width / 2 + offset, 0, height / 2}, {offset/width, 0.f}, {0, 1, 0});
        vdb.addVertex({width / 2 - offset, 0, height / 2}, {1.f - offset/width, 0.f}, {0, 1, 0});
        vdb.addVertex({-width / 2, 0, height / 2 - offset}, {0.f, offset/height}, {0, 1, 0});
        vdb.addVertex({width / 2, 0, height / 2 - offset}, {1.f, offset/height}, {0, 1, 0});

        vdb.addVertex({width / 2, 0, -height / 2 + offset}, {0.f, 1.f - offset/height}, {0, 1, 0});
        vdb.addVertex({-width / 2, 0, -height / 2 + offset}, {1.f, 1.f - offset/height}, {0, 1, 0});
        vdb.addVertex({width / 2 - offset, 0, -height / 2}, {offset/width, 1.f}, {0, 1, 0});
        vdb.addVertex({-width / 2 + offset, 0, -height / 2}, {1.f - offset/width, 1.f}, {0, 1, 0});

        vdb.addIndices({2, 1, 0,
                                2, 3, 1,
                                4, 3 ,2,
                                5, 4, 2,
                                5, 6, 4,
                                7, 6, 5});

        vdb.build();

        auto result = make::sptr<Mesh>(verticesBuf->getName(), verticesBuf);
        result->addComponent<Surface>("unnamed", indicesBuf);

        result->setMaterialInst(Material::getDefault()->createInstance());

SkinnedMesh

Объект, отображающий геометрию с анимацией.

Особенности:

  • можно загрузить только из файла;
  • представляет собой геометрию со скелетной анимацией;
  • содержит в себе набор анимаций;
  • содержит в себе API для управления анимациями и позволяет проигрывать несколько анимаций с плавными переходами между ними.
Method Description
w4::cref<core::Node> createSocket(const std::string& boneName)
Создаёт узел для крепления на кости с заданным именем. К этому узлу можно добавлять “детей“
w4::cref<core::Node> getSocket(const std::string& boneName) const
Возвращает узел для крепления на кости с заданным именем
std::vector<std::string> getAvailableAnimations() const
Возвращает список имеющихся анимаций
bool haveAnimation(const std::string& animationName) const
Проверяет наличие анимации с заданным именем
size_t getAnimationIndex(const std::string& animationName) const
Получение индекса анимации по её имени
const std::string& getAnimationName(size_t animationIndex) const
Получение имени анимации по её индексу
void setAnimationStateChangedCallback(std::function<void(Animator&, Animator::State)>)

void setAnimationStateChangedCallback(Animator::State, std::function<void(Animator&)>)
Установить функтор, который вызовется по изменению состояния конкретной анимации. Метод имеет как вариант только для заданного состояния, так и для любого. Состояния анимаций:
Animator::State::Idle(не проигрывается/закончилась), 
Animator::State::Play(проигрывается), 
Animator::State::Pause(приостановлена)

Пример:

node->setAnimationStateChangedCallback(Animator::State::Idle, [](Animator& animator)
{
    W4_LOG_DEBUG("Animator stopped:\n"
                 "\tName: %s,"
                 "\tSpeed: %f,"
                 "\tDuration: %f,"
                 "\tFps: %f",
                    animator.getName().c_str(),
                    animator.getSpeed(),
                    animator.getDuration(),
                    animator.getFps());
});
void play(const std::string& animationName, float duration = 0.f)

void play(size_t animationIndex = 0, float duration = 0.f)
Проигрывание анимации по индексу или имени. Указывается длительность анимации, если она равна нулю - проигрывается анимация целиком
void play(std::initializer_list<std::pair<std::string, float>>, float duration = 0.f)

void play(std::initializer_list<std::pair<size_t, float>>, float duration = 0.f)
Проигрывание списка анимаций с весами. Длительность, если равна нулю - равна анимации с максимальной длительностью

Пример:

skinned->play({{"run", .3f}, {"jump", .7f}});
void pause()
Приостановить все активные анимации
void resume()
Возобновить проигрывание всех приостановленных анимаций
void stop()
Остановить проигрывание всех активных анимаций
bool isPlaying() const
Проверяет, проигрывается ли сейчас любая анимация
Animator & getAnimator(size_t)
Animator & getAnimator(const std::string&)
const Animator & getAnimator(size_t) const
const Animator & getAnimator(const std::string&) const
Получить объект аниматор по имени или индексу. API объекта Animator описан чуть ниже. Используется для управления анимациями с расширенными возможностями.

Управление анимациями через API и SkinnedMesh не являются взаимоисключающими. Так, например, общеупотребительной является практика зацикливания анимаций:

m_skinned->getAnimator("dance").setIsLooped(true);
Animator API
Method Description
void play()
Запуск воспроизведения анимации.

В случае, если она уже проигрывается, она будет остановлена и запущена с начала

void pause()
Приостанавливает воспроизведение анимации
void resume()
Возобновляет воспроизведение анимации
void stop()
Останавливает воспроизведение анимации
void seek(float targetTime)
Устанавливает текущую позицию в анимации на заданное время. Значения автоматически обрезаются сверху и снизу до диапазона [0; длина анимации] или до диапазона, заданного методами setBeginTime/setEndTime
bool isLooped() const
Возвращает, включен ли для данной анимации режим циклическое воспроизведение
float getSpeed() const
Получает множитель скорости воспроизведения анимации (по умолчанию 1.0)
State getState() const
Возвращает состояние анимации

Состояния анимаций:

Animator::State::Idle (не проигрывается/закончилась),
Animator::State::Play (проигрывается),
Animator::State::Pause (приостановлена)
void setPlayType(PlayType)
Устанавливает направление воспроизведения.

Возможные значения параметра:

Animator::PlayType::Forward (вперёд),
Animator::PlayType::Backward (в обратном направлении)
PlayType getPlayType() const
Возвращает текущее направление проигрывания. Возможные значения см. в setPlayType
float getCurrentTime() const
Возвращает текущую позицию в анимации
void setIsLooped(bool)
Включает/выключает для данной анимации режим циклического воспроизведение
void setSpeed(float)
Устанавливает множитель скорости воспроизведения анимации
void setBeginTime(float)
Устанавливает начальное время анимации. Нужно для частичного воспроизведения анимации
void setEndTime(float)
Устанавливает конечное время анимации. Нужно для частичного воспроизведения анимации
StateHandlerId setStateHandler(State state, StateHandler handler)
void resetStateHandler(StateHandlerId handler)
Устанавливает и удаляет callback на смену состояния на заданное. Сигнатура callback - void(Animator&)
void setTimeHandler(float dt, TimeHandler handler)
Устанавливает callback на прохождение заданной временной метки. Сигнатура callback - void(Animator&)
float getFps() const
Возвращает характеристику анимации - количество значений в секунду.
float getDuration() const
Возвращает длительность анимации

ParticlesEmitter

Особенности:

  • ParticlesEmitter может быть загружен только из файла;
  • Входным форматом файла является CoronaSDK (можно создать в любом онлайн-редакторе, например в http://www.effecthub.com/particle2dx, сохранить json с расширением part и текстуру и убедиться, что путь к текстуре является путём от корня проекта).

Важно понимать и учитывать, что в связи с ограниченными вычислительными и асинхронными возможностями технологии WebAssembly на текущий момент, система частиц отображается на плоскости, развёрнутой к камере.

API ParticlesEmitter:

Method Description
void start()
Запуск генерации частиц
void pause()
Приостановка генерации частиц. В этом случае обработка уже выпущенных частиц продолжается
void resume()
Возобновление генерации частиц
void stop()
Остановка генерации частиц. Обработка всех частиц прекращается
State getState() const
Получение состояния

Варианты:

ParticlesEmitter::State::IDLE, 
ParticlesEmitter::State::STARTED, 
ParticlesEmitter::State::PAUSED

Billboard

Плоскость заданного при создании размера, всегда ориентированная на камеру. Имеет методы getSize и setSize.

Plotter

Реализация рисования линиями. Данные плоттера представляют собой информацию о точках (позиция и цвет) и набор индексов для их попарного соединения.

Пример:

auto plotter1 = make::sptr<Plotter>("Plotter_1");
const std::vector<uint32_t> indices = {1, 0};
const std::vector<LinesVertexFormat> vertices = {{{-10, -10, 0}, {1, 0, 0,1}},
                                                 {{10, 10, 0}, {0, 1, 0, 1}}};
plotter1->setLines(vertices, indices);

Представленный выше пример создаст косую линию с цветом, переходящим из красного в зелёный.

Как правило, для создания примитивов используются статические хелперы, возвращающие готовый объект, описанные в классе Plotter:

static w4::sptr<Plotter> build(std::vector<LinesVertexFormat> vertices, std::vector<uint32_t> indices);
static w4::sptr<Plotter> buildFromSegments(std::vector<std::array<w4::math::vec3, 2>> segments, const w4::math::vec4& color);
static w4::sptr<Plotter> buildFromPolyline(std::vector<w4::math::vec3> points, const w4::math::vec4& color);
static w4::sptr<Plotter> buildSphere(float radius, size_t rings, size_t sectors, const w4::math::vec4& color);
static w4::sptr<Plotter> buildOctahedron(std::array<w4::math::vec3, 8> vertices, const w4::math::vec4& color);
static w4::sptr<Plotter> buildCube(std::array<w4::math::vec3, 2> inVertices, const w4::math::vec4& color);
static w4::sptr<Plotter> buildCapsule(float radius, float height, size_t rings, size_t sectors, const w4::math::vec4& color);
static w4::sptr<Plotter> buildMesh(w4::cref<Mesh>, w4::math::vec4::cref color);
static w4::sptr<Plotter> buildMesh(w4::cref<SkinnedMesh>, w4::math::vec4::cref color);
static w4::sptr<Plotter> buildRay(math::vec3::cref startPoint, math::vec3::cref directionPoint, const w4::math::vec4& color);

DataNode

В отличие от VisibleNode, DataNode не отображается на экране. Далее описывается API унаследованных классов.

ArcBallNode

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

Method Description
ArcBallNode(const std::string& name = core::Object::defaultName, float radius = 1.f)
Конструктор, принимающий имя и радиус "шара"
void setFriction(float v)
Задать коэффициент затухания скорости. По умолчанию = 0.95
void setSensitivity(float v)
Задать множитель чувствительности к прикосновению. По умолчанию = 1
void setRadius(float r)
Задать радиус
void setVelocity(const math::Rotator& v)
Задать угловую скорость
void enableUpdate(bool flag = true)
void disableUpdate()
Включить/отключить вращение аркболла. Не сбрасывает скорость, при включении - может продолжить вращаться (затухание скорости по времени)
void enableInput(bool flag = true)
void disableInput()
Включение/выключение перехвата прикосновений аркболлом

Camera

Method Description
Camera(const std::string& name)
Camera(const std::string& name, float fov, float aspect, float near, float far)
Конструкторы перспективной камеры. Можно сразу указать FOV(угол обзора камеры по горизонтали), соотношение сторон и clip плоскости. FOV указывается в градусах
Camera(const std::string& name, const math::size& screen, float near, float far)
Конструктор ортокамеры. Указываются размеры и clip плоскости камеры
float getFov() const
void setFov(float v)
Получить, установить FOV(угол обзора камеры по горизонтали). FOV указывается в градусах
float getAspect() const
void setAspect(float v)
Получить/установить соотношение сторон
float getNear() const
void setNear(float v)
Получить/установить near clip плоскость
float getFar() const
void setFar(float v)
Получить/установить far clip плоскость
bool getIsOrtho() const
Получить является ли камера ортокамерой
void setClearColor(const math::vec4& v)
Задать значение цвета для очистки буфера цвета (фоновый цвет для камеры при отсутствии Background или Skybox)
ClearMask getClearMask() const
void setClearMask(ClearMask v)
Получить/установить ,битовую маску режима очистки экрана. Это значение будет применяться при рендеринге каждого кадра.

Значение по умолчанию ClearMask::Color | ClearMask::Depth

Возможные значения:

None

Color - очищать буфер цвета

Depth - очищать буфер глубины

Skybox - отрисовывать ли skybox

Background - отрисовывать ли background

bool hasSkybox() const
w4::cref<Skybox> getSkybox() const
Получить текущий объект skybox или nullptr при его отсутствии
bool hasBackground() const
w4::cref<Background> getBackground() const
Получить текущий объект background или nullptr при его отсутствии
Background

Background представляет собой ресурсовыгодный способ очистки буфера цвета чем-то, что сложнее одного цвета.

Может использоваться двумя способами:

  1. Вызовом метода void setTexture(w4::cref<resources::Texture> texture). При вызове создастся материал по умолчанию (просто отображает текстуру).
  2. Работа с материалами вручную через методы void setMaterial(w4::cref<resources::MaterialInst>) и w4::sptr<resources::MaterialInst> getMaterial(). Вертексный шейдер должен использовать нормализованное пространство координат (т.е. [-1; 1])
Skybox

В случае если необходимо чтобы фон смещался при движении камеры, можно использовать объект Skybox. Он также может использоваться двумя способами:

1. Вызовом метода void setCubemap(w4::cref<resources::Cubemap> texture). При вызове создастся материал по умолчанию (просто отображает текстуру).

Пример:

auto cubemap = Cubemap::get({"resources/textures/left.png",
                             "resources/textures/right.png",
                             "resources/textures/up.png",
                             "resources/textures/down.png",
                             "resources/textures/front.png",
                             "resources/textures/back.png",
                            });
m_cam->setClearMask(ClearMask::Color | ClearMask::Depth | ClearMask::Skybox);
m_cam->getSkybox()->setCubemap(cubemap);

2. Работа с материалами вручную через методы void setMaterial(w4::cref<resources::MaterialInst>) и w4::sptr<resources::MaterialInst> getMaterial(). Вертексный шейдер должен использовать нормализованное пространство координат (т.е. [-1; 1])

PointLight

Точечный источник освещения. Имеет следующий API:

Method Description
math::vec3 getColor() const
void setColor(const math::vec3& c)
Получить/установить цвет света
float getIntensity() const
void setIntensity(float i)
Получить/установить яркость источника света
core::LightDecayRate getDecayRate() const
void setDecayRate(core::LightDecayRate)
Получить/установить алгоритм затухания цвета (None, Linear, Quadratic, Cubic).

SpotLight

Направленный источник освещения в виде конуса с вершиной в точке излучения.

Method Description
float getAngle() const
void setAngle(float r)
Получить/установить верхний угол конуса
math::vec3 getColor() const
void setColor(const math::vec3& c)
Получить/установить цвет света
float getIntensity() const
void setIntensity(float i)
Получить/установить яркость источника света
core::LightDecayRate getDecayRate() const
void setDecayRate(core::LightDecayRate)
Получить/установить алгоритм затухания цвета (None, Linear, Quadratic, Cubic)
float getDecayFactor() const
void setDecayFactor(float f)
Получить/установить степень затухания(“прозрачность“) цвета от 0 до 1(по умолчанию = 1)

Spline

Позволяет использовать траектории, импортированные из fbx (b-spline).

Важно понимать, что в формате FBX Spline содержит только саму траекторию, но не вращения вокруг неё (spin).

Method Description
bool isRepeatable() const
void setRepeatable(bool isRepeatable)
Получить/установить режим повторяющегося “воспроизведения”
void play(float splineTime, std::function<void(const math::Transform&)> updateHandler, std::function<void(bool)> completionHandler = [](bool){})
Запуск “воспроизведения” сплайна

splineTime - конечное время воспроизведения сплайна(для расчёта множителя скорости)

updateHandler - метод, в который будут приходить Transform

completionHandler - метод, который вызовется при завершении “воспроизведения” (если не задано повторение)

void stop()
Остановить “воспроизведение” преобразований
bool isPlaying() const
Возвращает, идёт ли “воспроизведение” сплайна
bool isPaused() const
void pause()
Приостановка “воспроизведения” сплайна
float getDuration() const
Возвращает длительность сплайна в секундах
void setPosition(float pos)
Устанавливает позицию в секундах