Добавление целей морфинга
В этой статье описывается, как работать в UNIGINE с анимацией morph target (целей морфинга), также известной как blend shapes (формы смешивания). Обычно цели морфинга используются для изменения выражений лиц персонажей.
В статье показано, как экспортировать меш с целями морфинга из Autodesk Maya, а затем добавить его в UNIGINE.
Модель, используемая в этом руководстве, - Spot от Keenan Crane, распространяемая под CC0 1.0 Universal.
Требования#
- Предполагается, что у вас уже есть 3D-модель со смешанными формами, готовая к экспорту, и эта модель учитывает ограничения, установленные в UNIGINE.
- Предполагается, что у вас уже есть созданный мир.
Смотрите также#
- Описание функций класса ObjectMeshSkinned
Шаг 1. Экспорт меша с формами смешивания из Maya#
В этом разделе показан способ экспорта мешей с формами смешивания в формате FBX из Autodesk Maya. Он содержит в качестве примера меш теленка, у которого есть 2 формы смешивания (цели морфинга).
Чтобы экспортировать меш с формами смешивания, выполните следующее:
-
В Autodesk Maya выберите меш с формами смешивания для экспорта.
В главном меню выберите File -> Export Selection...
- В окне Export Selection выберите папку для сохранения меша и укажите имя для файла FBX. В раскрывающемся списке Files of type выберите FBX export.
- На вкладке File Type Specific Options с параметрами экспорта укажите параметры для экспорта меша.
- На вкладке Deformed Models установите флажок Blend Shapes, чтобы экспортировать формы смешивания.
- Нажмите Export Selection.
Теперь у вас есть меш в формате FBX, который можно легко добавить в проект.
Шаг 2. Добавление меша в мир#
В этом разделе показано, как добавить экспортированный меш в мир и настроить анимацию целей морфинга.
Чтобы добавить экспортированный меш в мир:
-
Импортируйте файл .fbx с включенной опцией Import Morph Targets.
- Добавьте импортированный файл в сцену.
- Сохраните мир.
Каждая форма смешивания меша является целью морфинга. Вам нужно создать цели морфинга для поверхности меша и задать параметры для этих целей, чтобы управлять анимацией цели морфинга. В следующем примере показано, как создавать цели морфинга и задавать параметры из кода:
AppWorldLogic.h:
#ifndef __APP_WORLD_LOGIC_H__
#define __APP_WORLD_LOGIC_H__
#include <UnigineLogic.h>
#include <UnigineStreams.h>
#include <UnigineObjects.h>
#include <UnigineGame.h>
#include <UnigineMathLib.h>
using namespace Unigine;
class AppWorldLogic : public Unigine::WorldLogic
{
public:
AppWorldLogic();
~AppWorldLogic() override;
int init() override;
int update() override;
int postUpdate() override;
int updatePhysics() override;
int shutdown() override;
int save(const Unigine::StreamPtr &stream) override;
int restore(const Unigine::StreamPtr &stream) override;
private:
ObjectMeshSkinnedPtr mesh;
};
#endif // __APP_WORLD_LOGIC_H__
AppWorldLogic.cpp:
#include "AppWorldLogic.h"
#include <UnigineWorld.h>
int AppWorldLogic::init()
{
// get the node that refers to the exported FBX file and cast it to a skinned mesh
mesh = static_ptr_cast<ObjectMeshSkinned>(World::getNodeByName("spot_the_cow"));
// set the number of morph targets
mesh->setNumTargets(5, 0);
return 1;
}
int AppWorldLogic::update()
{
float time = Game::getTime() * 2.0f;
// calculate weights of targets
float k0 = sin(time * 3.0f) + 0.75f;
float k1 = cos(time * 3.0f) + 0.75f;
// set targets with parameters
mesh->setTarget(0, 1, 0, 1.0f, 0);
mesh->setTarget(1, 1, 0, -k0, 0);
mesh->setTarget(2, 1, 0, -k1, 0);
mesh->setTarget(3, 1, 1, k0, 0);
mesh->setTarget(4, 1, 2, k1, 0);
return 1;
}
int AppWorldLogic::shutdown()
{
mesh.clear();
return 1;
}
Приведенный выше код получает ноду, которая ссылается на файл FBX, и задает параметры для целей морфинга. Давайте проясним основные моменты:
- Экспортированный меш был получен путем приведения ноды, которая ссылается на ассет FBX, к ObjectMeshSkinned. Ноду получаем из мира по ее названию.
- Функция setNumTargets() задает количество целей для поверхности меша. Экспортированный меш в приведенном выше примере имеет 2 цели (формы смешивания).
-
При использовании функции setTarget() все параметры для каждой созданной цели морфинга задаются в функции update(). Каждая цель имеет свой целевой вес. Веса влияют на координаты меша: координаты умножаются на их веса. Таким образом, все включенные целевые объекты умножаются на их веса и создается новый меш:
final_xyz = target_0_xyz * weight_0 + target_1_xyz * weight_1 + ... -
Поскольку в приведенном выше коде функции sin() и cos() используются для смешивания анимации различных целевых объектов, создаются пять целевых объектов:
-
mesh->setTarget(0, 1, 0, 1.0f, 0);
Эта цель - для позы привязки (bind pose) без какой-либо интерполяции.
-
mesh->setTarget(1, 1, 0, -k0, 0); mesh->setTarget(2, 1, 0, -k1, 0);
Эти целевые объекты используются для интерполяции при смешивании двух анимаций.
-
mesh->setTarget(3, 1, 1, k0, 0);
Этот целевой объект используется для первого смешивания анимации, которое использует функцию sin() для интерполяции.
-
mesh->setTarget(4, 1, 2, k1, 0);
Этот целевой объект используется для второго смешивания анимации, которое использует функцию cos() для интерполяции.
-
После назначения материала мешу результат выглядит следующим образом: