Difference between revisions of "Mesh Converter"

From Ciliz|W4
 
(30 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
<languages />
 
== Scope ==
 
== Scope ==
 
<translate>
 
<translate>
Игровой движок W4 использует собственный формат хранения сцены. Следовательно, прежде чем использовать сторонний ассет, его необходимо преобразовать в наш формат. Сделать это можно с помощью инструмента Mesh Converter, который поставляется вместе с нашим SDK.
+
<!--T:1-->
 +
Игровой движок W4 использует собственный формат хранения ассетов. Следовательно, прежде чем использовать сторонний ассет, его необходимо преобразовать в наш формат. Сделать это можно с помощью инструмента Mesh Converter, который поставляется вместе с нашим SDK.
 
</translate>
 
</translate>
  
 
<translate>
 
<translate>
 +
<!--T:2-->
 
Mesh Converter позволяет преобразовывать ассеты из формата Autodesk FBX (.fbx). Другие форматы не поддерживаются.
 
Mesh Converter позволяет преобразовывать ассеты из формата Autodesk FBX (.fbx). Другие форматы не поддерживаются.
 
</translate>
 
</translate>
Line 10: Line 13:
 
== Technical limitations ==
 
== Technical limitations ==
 
<translate>
 
<translate>
Конвертер может преобразовать любой меш, но стоит помнить про ограничения движка, которые завязаны на ограничения WebGL. Оптимальное сочетания работоспособности и компактности решений достигается, если skinned mesh содержит не более 28 костей и/или 8 вершин на кость.
+
<!--T:3-->
 +
Конвертер может преобразовать любой fbx со следующими ограничениями:
 +
 
 +
<!--T:4-->
 +
1. В связи с аппаратными и программными особенностями некоторых популярных моделей устройств skinned mesh может содержать:
 +
* не более 28 костей
 +
* не более 8 вершин на кость
 
</translate>
 
</translate>
 +
 
== How to use ==
 
== How to use ==
 
<translate>
 
<translate>
 +
<!--T:5-->
 
Загрузка репозитория проекта описана в статье [[Quick Start]].
 
Загрузка репозитория проекта описана в статье [[Quick Start]].
 
Файл конвертера W4MeshConverter.bin находится в каталоге w4framework/tools .
 
Файл конвертера W4MeshConverter.bin находится в каталоге w4framework/tools .
Конвертация запускается из командной строки, как это описано на следующем примере.
+
Конвертация запускается из командной строки, как это описано на следующем примере и в разделе [http://wiki.w4-dev.ciliz.com/index.php/Mesh_Converter#Short_manual Short manual].
 
</translate>
 
</translate>
  
Line 22: Line 33:
 
==== Preparing ====
 
==== Preparing ====
 
<translate>
 
<translate>
Возьмем для примера Utah teapot.
+
<!--T:6-->
 +
Возьмем для примера [http://demo.w4-dev.ciliz.com/wiki-files/utah-teapot.fbx Utah teapot].
 
Если посмотрите файл с помощью утилиты [https://www.autodesk.com/products/fbx/fbx-review Autodesk FBX Review], увидите примерно то же, что на рисунке.
 
Если посмотрите файл с помощью утилиты [https://www.autodesk.com/products/fbx/fbx-review Autodesk FBX Review], увидите примерно то же, что на рисунке.
 
</translate>
 
</translate>
  
[[File:D1b94d56-cb70-428b-ac1c-65701c690238.png|500px]]
+
http://demo.w4-dev.ciliz.com/wiki-files/cb84552c-5001-4127-9d9d-1e93f9c96696.png
  
 
<translate>
 
<translate>
 +
<!--T:7-->
 
Обратите внимание на положение носика чайника при просмотре fbx, мы вернемся к этому чуть позже.
 
Обратите внимание на положение носика чайника при просмотре fbx, мы вернемся к этому чуть позже.
 
</translate>
 
</translate>
Line 34: Line 47:
 
==== Converting ====
 
==== Converting ====
 
<translate>
 
<translate>
 +
<!--T:8-->
 
Скопируем файл модели в директорию конвертера.
 
Скопируем файл модели в директорию конвертера.
  
 +
<!--T:9-->
 
Далее, для преобразования модели в формат нашего движка (asset) необходимо выполнить:
 
Далее, для преобразования модели в формат нашего движка (asset) необходимо выполнить:
 
</translate>
 
</translate>
Line 42: Line 57:
  
 
<translate>
 
<translate>
 +
<!--T:10-->
 
В результате появится директория teapot содержащая данные ассета.
 
В результате появится директория teapot содержащая данные ассета.
 
</translate>
 
</translate>
 
==== Adding to the project structure ====
 
==== Adding to the project structure ====
 
<translate>
 
<translate>
 +
<!--T:11-->
 
Для работы с ассетом необходимо скопировать его директорию (в нашем случае это teapot) в директорию resources проекта. Директория resources располагается на том же уровне структуры проекта, что и sources. Таким образом, структура проекта станет подобна следующей:
 
Для работы с ассетом необходимо скопировать его директорию (в нашем случае это teapot) в директорию resources проекта. Директория resources располагается на том же уровне структуры проекта, что и sources. Таким образом, структура проекта станет подобна следующей:
 
</translate>
 
</translate>
Line 68: Line 85:
 
==== Code example ====
 
==== Code example ====
 
<translate>
 
<translate>
 +
<!--T:12-->
 
Загрузка:
 
Загрузка:
 
</translate>
 
</translate>
  
 +
<syntaxhighlight lang="c++">
 
  auto asset = Asset::load(Path("resources/teapot", "teapot.asset"));
 
  auto asset = Asset::load(Path("resources/teapot", "teapot.asset"));
 +
</syntaxhighlight>
  
 
<translate>
 
<translate>
 +
<!--T:13-->
 
Добавление в Render (отображение на экране):
 
Добавление в Render (отображение на экране):
 
</translate>
 
</translate>
  
 +
<syntaxhighlight lang="c++">
 
  auto root = RootNode::make();
 
  auto root = RootNode::make();
 
  root->addChild(asset->getRoot());
 
  root->addChild(asset->getRoot());
 
  Render::instance().getPass(0)->setRoot(root);
 
  Render::instance().getPass(0)->setRoot(root);
 +
</syntaxhighlight>
  
 
<translate>
 
<translate>
 +
<!--T:14-->
 
Полный код примера:
 
Полный код примера:
 
</translate>
 
</translate>
  
 +
<syntaxhighlight lang="c++">
 
  #include "W4Framework.h"
 
  #include "W4Framework.h"
 
   
 
   
Line 110: Line 135:
 
   
 
   
 
  W4_RUN(AssetSample)
 
  W4_RUN(AssetSample)
 +
</syntaxhighlight>
  
 
==== Result ====
 
==== Result ====
 
<translate>
 
<translate>
 +
<!--T:15-->
 
В результате выполнения должен отобразиться тот же чайник, но с небольшим отличием.
 
В результате выполнения должен отобразиться тот же чайник, но с небольшим отличием.
 
</translate>
 
</translate>
  
[[File:1b952599-fc03-428f-96e8-ae86935b46d8.png|500px]]
+
http://demo.w4-dev.ciliz.com/wiki-files/3aa4d02a-5152-44d6-9168-13a155f1b049.png
  
 
<translate>
 
<translate>
Если сравнить рисунки, можно заметить, что нос чайника в FBX Review смотрит в одну сторону, а в результате выполнения программы в другую. Это происходит из-за различий в системах координат и поведении конвертера.
+
<!--T:16-->
 +
Если сравнить рисунки, можно заметить, что нос чайника в FBX Review смотрит в одну сторону, а в результате выполнения программы в другую. Это происходит из-за различий в системах координат.
 
</translate>
 
</translate>
  
 
<translate>
 
<translate>
Система координат FBX Scene Axis and Unit Conversion является правосторонней (с осью Y направленной верх), тогда как [[Система координат W4]] левосторонняя (ось Y также направлена верх).
+
<!--T:17-->
 +
Система координат FBX [https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_CC93340E_C4A1_49EE_B048_E898F856CFBF_htm Scene Axis and Unit Conversion] является правосторонней (с осью Y направленной верх), тогда как [[Система координат W4]] левосторонняя (ось Y также направлена верх).
 
</translate>
 
</translate>
  
 
=== Animated mesh Exmple ===
 
=== Animated mesh Exmple ===
Для анимированных мешей порядок работы не сильно отличается от вышеописанного.
+
<translate>
 +
<!--T:18-->
 +
Для анимированных мешей порядок работы не сильно отличается от описанного [http://wiki.w4-dev.ciliz.com/index.php/Mesh_Converter#Mesh_Exmple выше].
 +
</translate>
 
==== Preparing ====
 
==== Preparing ====
Анимированную модель можно найти в интернете. Возьмем, например, Hand_rigged.FBX (ссылка на ресурс).
+
<translate>
 +
<!--T:19-->
 +
Анимированную модель можно найти в интернете. Возьмем, например, [http://demo.w4-dev.ciliz.com/wiki-files/Hand_rigged.FBX Rigged Hand].
 
Просмотр с помощью [https://www.autodesk.com/products/fbx/fbx-review Autodesk FBX Review] покажет примерно следующее:
 
Просмотр с помощью [https://www.autodesk.com/products/fbx/fbx-review Autodesk FBX Review] покажет примерно следующее:
 +
</translate>
  
 
[[file:hand.mov|500px]]
 
[[file:hand.mov|500px]]
 +
 +
http://demo.w4-dev.ciliz.com/wiki-files/Hand.mov
  
 
==== Converting ====
 
==== Converting ====
 +
<translate>
 +
<!--T:20-->
 
Так же как в примере выше (с обычным мешем), скопируем модель в папку конвертера и преобразуем в формат W4 Engine:
 
Так же как в примере выше (с обычным мешем), скопируем модель в папку конвертера и преобразуем в формат W4 Engine:
 +
</translate>
  
 
  ./W4MeshConverter Hand_rigged.FBX hand
 
  ./W4MeshConverter Hand_rigged.FBX hand
  
 +
<translate>
 +
<!--T:21-->
 
В результате выполнения в текущей папке будет получена директория hand, содержащая данные ассета.
 
В результате выполнения в текущей папке будет получена директория hand, содержащая данные ассета.
 
+
</translate>
 
==== Adding to the project structure ====
 
==== Adding to the project structure ====
 +
<translate>
 +
<!--T:22-->
 
Скопируем полученный каталог ассета hand в каталог resources нашего проекта. Примерная структура проекта после этого:
 
Скопируем полученный каталог ассета hand в каталог resources нашего проекта. Примерная структура проекта после этого:
 +
</translate>
 +
 
  .
 
  .
 
  └── W4TemplateGame
 
  └── W4TemplateGame
Line 164: Line 210:
  
 
==== Code example ====
 
==== Code example ====
 +
<translate>
 +
<!--T:23-->
 
Загрузим asset и добавим его в дерево отрисовки:
 
Загрузим asset и добавим его в дерево отрисовки:
 +
</translate>
  
 +
<syntaxhighlight lang="c++">
 
  auto asset = Asset::load(Path("resources/hand", "hand.asset"));
 
  auto asset = Asset::load(Path("resources/hand", "hand.asset"));
 
  render::getRoot()->addChild(asset->getRoot());
 
  render::getRoot()->addChild(asset->getRoot());
 +
</syntaxhighlight>
  
 +
<translate>
 +
<!--T:24-->
 
Если мы попробуем сейчас собрать проект, то ничего не увидим. Потому что камера попала “внутрь” asset’a.
 
Если мы попробуем сейчас собрать проект, то ничего не увидим. Потому что камера попала “внутрь” asset’a.
  
 +
<!--T:25-->
 
Возьмем камеру и передвинем её подальше (возможно, придется задать другие значения, в зависимости от размера окна браузера, размера объекта и т.п.):
 
Возьмем камеру и передвинем её подальше (возможно, придется задать другие значения, в зависимости от размера окна браузера, размера объекта и т.п.):
 +
</translate>
  
 +
<syntaxhighlight lang="c++">
 
  auto cam = render::getScreenCamera();
 
  auto cam = render::getScreenCamera();
 
  cam->setWorldTranslation({0.f, 125.f, -300.f});
 
  cam->setWorldTranslation({0.f, 125.f, -300.f});
 
+
</syntaxhighlight>
 +
 
 +
<translate>
 +
<!--T:26-->
 
Если сейчас собрать проект, то на экране появится рука, но она не будет двигаться.
 
Если сейчас собрать проект, то на экране появится рука, но она не будет двигаться.
  
 +
<!--T:27-->
 
Чтобы она задвигалась, нужно запустить аниматор у соответствующего skinned mesh’a. Известно, что skinned mesh у нас один и у него одна анимация, поэтому в цикле пройдем по всему дереву asset’a и всем skinned mesh’ам в нём и будем проигрывать анимацию (в нашем примере - первую):
 
Чтобы она задвигалась, нужно запустить аниматор у соответствующего skinned mesh’a. Известно, что skinned mesh у нас один и у него одна анимация, поэтому в цикле пройдем по всему дереву asset’a и всем skinned mesh’ам в нём и будем проигрывать анимацию (в нашем примере - первую):
 +
</translate>
  
 +
<syntaxhighlight lang="c++">
 
  asset->getRoot()->traversal([&](Node& node)
 
  asset->getRoot()->traversal([&](Node& node)
 
  {
 
  {
Line 189: Line 251:
 
   }
 
   }
 
  });
 
  });
 +
</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:28-->
 
Полный код примера:
 
Полный код примера:
 +
</translate>
  
 +
<syntaxhighlight lang="c++">
 
  #include "W4Framework.h"
 
  #include "W4Framework.h"
 
   
 
   
Line 221: Line 289:
 
   
 
   
 
  W4_RUN(MeshAnimatedSample)
 
  W4_RUN(MeshAnimatedSample)
 +
</syntaxhighlight>
  
 
==== Result ====
 
==== Result ====
 +
<translate>
 +
<!--T:29-->
 
В результате выполнения вышеописанной программы отобразится следующая анимация:
 
В результате выполнения вышеописанной программы отобразится следующая анимация:
 +
</translate>
  
 
[[File:Hand engine.mov|500px]]
 
[[File:Hand engine.mov|500px]]
 +
 +
http://demo.w4-dev.ciliz.com/wiki-files/Hand_engine.mov
  
 
== Short manual ==
 
== Short manual ==
 
=== Basics ===
 
=== Basics ===
 
<translate>
 
<translate>
 +
<!--T:30-->
 
Конвертация utah-teapot.fbx в ассет с именем asset в текущей директории:
 
Конвертация utah-teapot.fbx в ассет с именем asset в текущей директории:
 
</translate>
 
</translate>
Line 236: Line 311:
  
 
<translate>
 
<translate>
 +
<!--T:31-->
 
Конвертация utah-teapot.fbx в ассет с именем teapot в текущей директории:
 
Конвертация utah-teapot.fbx в ассет с именем teapot в текущей директории:
 
</translate>
 
</translate>
Line 242: Line 318:
  
 
<translate>
 
<translate>
 +
<!--T:32-->
 
Конвертация utah-teapot.fbx в ассет с именем teapot, который будет сохранен в директории ~/some/dir:
 
Конвертация utah-teapot.fbx в ассет с именем teapot, который будет сохранен в директории ~/some/dir:
 
</translate>
 
</translate>
Line 249: Line 326:
 
=== Common keys ===
 
=== Common keys ===
 
<translate>
 
<translate>
 +
<!--T:33-->
 
Справка:
 
Справка:
 
</translate>
 
</translate>
Line 255: Line 333:
  
 
<translate>
 
<translate>
 +
<!--T:34-->
 
Вывод статистики сцены:
 
Вывод статистики сцены:
 
</translate>
 
</translate>
Line 261: Line 340:
  
 
<translate>
 
<translate>
 +
<!--T:35-->
 
Пример статистики:
 
Пример статистики:
 
</translate>
 
</translate>
Line 282: Line 362:
  
 
<translate>
 
<translate>
 +
<!--T:36-->
 
Управление размером (scale) на конвертации, где arg - значение, например (10, 1, 0.1):
 
Управление размером (scale) на конвертации, где arg - значение, например (10, 1, 0.1):
 
</translate>
 
</translate>
Line 288: Line 369:
  
 
<translate>
 
<translate>
Переворот UV.Y координаты:
+
<!--T:37-->
 +
Переворот вертикальной оси V текстурных координат, если флаг указан, то к текстурным координатам будет применено преобразование вида V = 1.0 - V:
 
</translate>
 
</translate>
  
Line 295: Line 377:
 
=== Setting limitations ===
 
=== Setting limitations ===
 
<translate>
 
<translate>
 +
<!--T:38-->
 
Для всех Mesh'ей могут быть заданы ограничения на максимальное количество вершин и индексов. Для Skinned Mesh'ей могут быть заданы ограничения на максимальное количество костей и максимальное количество костей на вершину.  
 
Для всех Mesh'ей могут быть заданы ограничения на максимальное количество вершин и индексов. Для Skinned Mesh'ей могут быть заданы ограничения на максимальное количество костей и максимальное количество костей на вершину.  
 
</translate>
 
</translate>
  
 
<translate>
 
<translate>
Модель, которая упирается в текущие ограничения, можно сконвертировать с помощью флага force, однако работоспособность данной модели не гарантируется:
+
<!--T:39-->
 +
Модель, которая не соответствует заданным ограничениям, можно принудительно сконвертировать с помощью флага force, однако работоспособность в таком случае не гарантируется:
 
</translate>
 
</translate>
  
Line 305: Line 389:
  
 
<translate>
 
<translate>
 +
<!--T:40-->
 
Установка ограничения на максимальное количество вершин на объект, где arg - значение, по умолчанию не задано:
 
Установка ограничения на максимальное количество вершин на объект, где arg - значение, по умолчанию не задано:
 
</translate>
 
</translate>
Line 311: Line 396:
  
 
<translate>
 
<translate>
 +
<!--T:41-->
 
Установка ограничения на максимальное количество индексов на объект, где arg - значение, по умолчанию не задано:
 
Установка ограничения на максимальное количество индексов на объект, где arg - значение, по умолчанию не задано:
 
</translate>
 
</translate>
Line 317: Line 403:
  
 
<translate>
 
<translate>
Установка ограничения на максимальное количество костей для Skinned Mesh, где arg - значение, по умолчанию 28:
+
<!--T:42-->
 +
Установка ограничения на максимальное количество костей для Skinned Mesh, где arg - значение, по умолчанию 28, при установке значения выше, чем значение по умолчанию, работоспособность не гарантируется:
 
</translate>
 
</translate>
  
Line 323: Line 410:
  
 
<translate>
 
<translate>
Установка ограничения на максимальное количество костей на вершину для Skinned Mesh, где arg - значение, по умолчанию 8:
+
<!--T:43-->
 +
Установка ограничения на максимальное количество костей на вершину для Skinned Mesh, где arg - значение, по умолчанию 8, при установке значения выше, чем значение по умолчанию, работоспособность не гарантируется:
 
</translate>
 
</translate>
  
 
  --max-bones-per-vertex arg
 
  --max-bones-per-vertex arg

Latest revision as of 09:32, 9 June 2020

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

Scope

Игровой движок W4 использует собственный формат хранения ассетов. Следовательно, прежде чем использовать сторонний ассет, его необходимо преобразовать в наш формат. Сделать это можно с помощью инструмента Mesh Converter, который поставляется вместе с нашим SDK.

Mesh Converter позволяет преобразовывать ассеты из формата Autodesk FBX (.fbx). Другие форматы не поддерживаются.

Technical limitations

Конвертер может преобразовать любой fbx со следующими ограничениями:

1. В связи с аппаратными и программными особенностями некоторых популярных моделей устройств skinned mesh может содержать:

  • не более 28 костей
  • не более 8 вершин на кость

How to use

Загрузка репозитория проекта описана в статье Quick Start. Файл конвертера W4MeshConverter.bin находится в каталоге w4framework/tools . Конвертация запускается из командной строки, как это описано на следующем примере и в разделе Short manual.

Mesh Exmple

Preparing

Возьмем для примера Utah teapot. Если посмотрите файл с помощью утилиты Autodesk FBX Review, увидите примерно то же, что на рисунке.

cb84552c-5001-4127-9d9d-1e93f9c96696.png

Обратите внимание на положение носика чайника при просмотре fbx, мы вернемся к этому чуть позже.

Converting

Скопируем файл модели в директорию конвертера.

Далее, для преобразования модели в формат нашего движка (asset) необходимо выполнить:

./W4MeshConverter utah-teapot.fbx teapot

В результате появится директория teapot содержащая данные ассета.

Adding to the project structure

Для работы с ассетом необходимо скопировать его директорию (в нашем случае это teapot) в директорию resources проекта. Директория resources располагается на том же уровне структуры проекта, что и sources. Таким образом, структура проекта станет подобна следующей:

.
└── W4TemplateGame
    ├── resources
    │   └── teapot
    │       ├── Animations
    │       ├── BoneInfo
    │       ├── Materials
    │       │   ├── defaultMaterial.matInst
    │       │   └── defaultSkinnedMaterial.matInst
    │       ├── Splines
    │       ├── teapot.asset
    │       └── VertexData
    │           ├── Utah Teapot Quads_0.ib
    │           └── Utah Teapot Quads.vb
    └── sources
        └── main.cpp

Code example

Загрузка:

 auto asset = Asset::load(Path("resources/teapot", "teapot.asset"));

Добавление в Render (отображение на экране):

 auto root = RootNode::make();
 root->addChild(asset->getRoot());
 Render::instance().getPass(0)->setRoot(root);

Полный код примера:

 #include "W4Framework.h"
 
 W4_USE_UNSTRICT_INTERFACE
 
 class AssetSample : public w4::IGame
 {
 public:
 
     AssetSample() = default;
     ~AssetSample() = default; 
 
     void onStart() override
     {
         auto cam = Render::instance().getScreenCamera();
         cam->setWorldTranslation({0.f, 0, -50.f});
 
         auto asset = Asset::load(Path("resources/teapot", "teapot.asset"));
 
         auto root =  RootNode::make();
         root->addChild(asset->getRoot());
         Render::instance().getPass(0)->setRoot(root);
     }
 };
 
 W4_RUN(AssetSample)

Result

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

3aa4d02a-5152-44d6-9168-13a155f1b049.png

Если сравнить рисунки, можно заметить, что нос чайника в FBX Review смотрит в одну сторону, а в результате выполнения программы в другую. Это происходит из-за различий в системах координат.

Система координат FBX Scene Axis and Unit Conversion является правосторонней (с осью Y направленной верх), тогда как Система координат W4 левосторонняя (ось Y также направлена верх).

Animated mesh Exmple

Для анимированных мешей порядок работы не сильно отличается от описанного выше.

Preparing

Анимированную модель можно найти в интернете. Возьмем, например, Rigged Hand. Просмотр с помощью Autodesk FBX Review покажет примерно следующее:

http://demo.w4-dev.ciliz.com/wiki-files/Hand.mov

Converting

Так же как в примере выше (с обычным мешем), скопируем модель в папку конвертера и преобразуем в формат W4 Engine:

./W4MeshConverter Hand_rigged.FBX hand

В результате выполнения в текущей папке будет получена директория hand, содержащая данные ассета.

Adding to the project structure

Скопируем полученный каталог ассета hand в каталог resources нашего проекта. Примерная структура проекта после этого:

.
└── W4TemplateGame
    ├── resources
    │   └── hand
    │       ├── Animations
    │       │   └── Take 001.ssa
    │       ├── BoneInfo
    │       │   ├── bone_main_hande.skeleton
    │       │   └── Hand_rigged.skin
    │       ├── hand.asset
    │       ├── Materials
    │       │   ├── defaultMaterial.matInst
    │       │   └── defaultSkinnedMaterial.matInst
    │       ├── Splines
    │       └── VertexData
    │           ├── Hand_rigged_0.ib
    │           └── Hand_rigged.vb
    └── sources
        └── main.cpp

Code example

Загрузим asset и добавим его в дерево отрисовки:

 auto asset = Asset::load(Path("resources/hand", "hand.asset"));
 render::getRoot()->addChild(asset->getRoot());

Если мы попробуем сейчас собрать проект, то ничего не увидим. Потому что камера попала “внутрь” asset’a.

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

 auto cam = render::getScreenCamera();
 cam->setWorldTranslation({0.f, 125.f, -300.f});

Если сейчас собрать проект, то на экране появится рука, но она не будет двигаться.

Чтобы она задвигалась, нужно запустить аниматор у соответствующего skinned mesh’a. Известно, что skinned mesh у нас один и у него одна анимация, поэтому в цикле пройдем по всему дереву asset’a и всем skinned mesh’ам в нём и будем проигрывать анимацию (в нашем примере - первую):

 asset->getRoot()->traversal([&](Node& node)
 {
   if(node.is<SkinnedMesh>())
   {
     auto skinned = node.as<SkinnedMesh>();
     skinned->getAnimator(0).setIsLooped(true);
     skinned->play(0);
   }
 });

Полный код примера:

 #include "W4Framework.h"
 
 W4_USE_UNSTRICT_INTERFACE
 
 class MeshAnimatedSample : public w4::IGame
 {
 public:
     MeshAnimatedSample() = default;
 
     void onStart() override
     {
         auto asset = Asset::load(Path("resources/hand", "hand.asset"));
         render::getRoot()->addChild(asset->getRoot());
 
         auto cam = render::getScreenCamera();
         cam->setWorldTranslation({0.f, 150.f, -300.f});
 
         asset->getRoot()->traversal([&](Node &node)
         {
             if (node.is<SkinnedMesh>())
             {
                 auto skinned = node.as<SkinnedMesh>();
                 skinned->getAnimator(0).setIsLooped(true);
                 skinned->play(0);
             }
         });
     }
 };
 
 W4_RUN(MeshAnimatedSample)

Result

В результате выполнения вышеописанной программы отобразится следующая анимация:

http://demo.w4-dev.ciliz.com/wiki-files/Hand_engine.mov

Short manual

Basics

Конвертация utah-teapot.fbx в ассет с именем asset в текущей директории:

./W4MeshConverter utah-teapot.fbx

Конвертация utah-teapot.fbx в ассет с именем teapot в текущей директории:

./W4MeshConverter utah-teapot.fbx teapot

Конвертация utah-teapot.fbx в ассет с именем teapot, который будет сохранен в директории ~/some/dir:

./W4MeshConverter utah-teapot.fbx teapot ~/some/dir 

Common keys

Справка:

-h, --help

Вывод статистики сцены:

-v, --verbose

Пример статистики:

(DEBUG) ==================== Scene statistics ====================
(DEBUG) Nodes: 2
(DEBUG) Geometries: 1
(DEBUG) Poses: 0
(DEBUG) Materials: 1
(DEBUG) Textures: 0
(DEBUG) ====================== Axis & Scale ======================
(DEBUG) Up: +Y, Front: +ParityOdd, System: RightHanded
(DEBUG) Scale: 1.000000
(DEBUG) ================ Mesh: Red_label ================
(DEBUG) Vertex count: 404
(DEBUG) Index count: 2118
(DEBUG) All polygons are triangles: 1
(DEBUG) ==========================================================
(DEBUG) create default material...
(DEBUG) create default skinned material...

Управление размером (scale) на конвертации, где arg - значение, например (10, 1, 0.1):

--scale arg

Переворот вертикальной оси V текстурных координат, если флаг указан, то к текстурным координатам будет применено преобразование вида V = 1.0 - V:

--uv-flip

Setting limitations

Для всех Mesh'ей могут быть заданы ограничения на максимальное количество вершин и индексов. Для Skinned Mesh'ей могут быть заданы ограничения на максимальное количество костей и максимальное количество костей на вершину.

Модель, которая не соответствует заданным ограничениям, можно принудительно сконвертировать с помощью флага force, однако работоспособность в таком случае не гарантируется:

-f, --force

Установка ограничения на максимальное количество вершин на объект, где arg - значение, по умолчанию не задано:

--max-vertex arg

Установка ограничения на максимальное количество индексов на объект, где arg - значение, по умолчанию не задано:

--max-index arg

Установка ограничения на максимальное количество костей для Skinned Mesh, где arg - значение, по умолчанию 28, при установке значения выше, чем значение по умолчанию, работоспособность не гарантируется:

--max-bones arg

Установка ограничения на максимальное количество костей на вершину для Skinned Mesh, где arg - значение, по умолчанию 8, при установке значения выше, чем значение по умолчанию, работоспособность не гарантируется:

--max-bones-per-vertex arg