Добавление целей морфинга
В этой статье описывается, как работать в 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.
- Добавьте импортированный файл в сцену.
- Сохраните мир.
Каждая форма смешивания меша является целью морфинга. Вам нужно включить цели морфинга для поверхности меша и задать параметры для этих целей, чтобы управлять анимацией цели морфинга. В следующем примере показано, как создавать цели морфинга и задавать параметры из кода:
#pragma once
#include <UnigineComponentSystem.h>
#include <UnigineWorld.h>
#include <UnigineGame.h>
class Morph :
public Unigine::ComponentBase
{
public:
// declare constructor and destructor for the Morph class
COMPONENT_DEFINE(Morph, Unigine::ComponentBase);
// declare methods to be called at the corresponding stages of the execution sequence
COMPONENT_INIT(init);
COMPONENT_UPDATE(update);
private:
Unigine::ObjectMeshSkinnedPtr mesh;
protected:
// world main loop
void init();
void update();
};
#include "Morph.h"
REGISTER_COMPONENT(Morph); // macro for component registration by the Component System
using namespace Unigine;
using namespace Math;
void Morph::init()
{
// get the node and cast it to a skinned mesh
mesh = static_ptr_cast<ObjectMeshSkinned>(node);
// enable targets of the surface
mesh->setSurfaceTargetEnabled(0, 1, true);
mesh->setSurfaceTargetEnabled(0, 2, true);
}
void Morph::update()
{
float time = Game::getTime() * 2.0f;
// calculate weights of targets
float k0 = Unigine::Math::sin(time * 3.0f) + 0.75f;
float k1 = Unigine::Math::cos(time * 3.0f) + 0.75f;
// set targets with parameters
mesh->setSurfaceTargetWeight(0, 0, 1.0f - k0 - k1);
mesh->setSurfaceTargetWeight(0, 1, k0);
mesh->setSurfaceTargetWeight(0, 2, k1);
}
Приведенный выше код получает ноду, которая ссылается на файл FBX, и задает параметры для целей морфинга. Давайте проясним основные моменты:
-
Меш был получен путем приведения ноды, которая ссылается на ассет FBX, к ObjectMeshSkinned. Приводиться будет та нода, на которую назначен компонент. Также можно добавить проверку того, что нода, на которую назначен компонент, является ObjectMeshSkinned, перед ее приведением:
//check if the node to which the component is assigned is MeshSkinned if (node->getType() != Node::OBJECT_MESH_SKINNED) return; // get the node and cast it to a skinned mesh mesh = static_ptr_cast<ObjectMeshSkinned>(node);
- Функция setSurfaceTargetEnabled() задает цель для указанной поверхности меша.
-
Посредством функции setSurfaceTargetWeight() задаются веса для целей морфинга. Каждая цель имеет свой целевой вес. Веса влияют на координаты меша: координаты умножаются на их веса. Таким образом, все включенные целевые объекты умножаются на их веса и создается новый меш:
final_xyz = target_0_xyz * weight_0 + target_1_xyz * weight_1 + ... -
Для объекта включены три целевых объекта и используются функции sin() и cos() для смешивания анимации этих целевых объектов следующим образом:
-
Вычитаем воздействие двух других целей морфинга из позы привязки (bind pose), чтобы получить нормализованный вес для смешивания.
mesh->setSurfaceTargetWeight(0, 0, 1.0f - k0 - k1);
-
Вес первого целевого объекта изменяется при помощи функции sin().
mesh->setSurfaceTargetWeight(0, 1, k0);
-
Вес второго целевого объекта изменяется при помощи функции cos().
mesh->setSurfaceTargetWeight(0, 2, k1);
-
После назначения компонента на меш результат выглядит следующим образом: