This page has been translated automatically.
视频教程
界面
要领
高级
实用建议
专业(SIM)
UnigineEditor
界面概述
资源工作流程
版本控制
设置和首选项
项目开发
调整节点参数
Setting Up Materials
设置属性
照明
Sandworm
使用编辑器工具执行特定任务
如何擴展編輯器功能
嵌入式节点类型
Nodes
Objects
Effects
Decals
光源
Geodetics
World Nodes
Sound Objects
Pathfinding Objects
Players
编程
基本原理
搭建开发环境
使用范例
C++
C#
UnigineScript
UUSL (Unified UNIGINE Shader Language)
Plugins
File Formats
材质和着色器
Rebuilding the Engine Tools
GUI
VR Development
双精度坐标
应用程序接口
Animations-Related Classes
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
VR-Related Classes
创建内容
内容优化
材质
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Tutorials
注意! 这个版本的文档是过时的,因为它描述了一个较老的SDK版本!请切换到最新SDK版本的文档。
注意! 这个版本的文档描述了一个不再受支持的旧SDK版本!请升级到最新的SDK版本。

Adding Morph Targets(添加变形目标)

本文描述了如何使用 morph target(变形目标)动画,在UNIGINE中也称为blend shapes(混合形状)。通常,变形目标是用来改变人物的面部表情。

这篇文章展示了如何从Autodesk Maya导出带有morph目标的网格,然后将其添加到UNIGINE。

本教程中使用的模型是分布在CC0 1.0 Universal下的SpotKeenan Crane

需求#

  • 假设您已经有一个混合形状的3D模型准备导出,并且该模型在UNIGINE设置的限制范围内。
  • 假设您已经创造了一个世界。

另请参阅#

步骤1。从玛雅导出一个网格与混合形状#

本节展示了从Autodesk Maya导出FBX格式的混合形状网格的方法。它包含一个小牛的示例网格,它有2个混合形状(变形目标)。

要导出具有混合形状的网格,请执行以下操作:

  1. Autodesk Maya中,选择要导出的混合形状网格。

  2. 在主菜单中,单击File -> Export Selection...

  3. Export Selection窗口中,选择一个文件夹来保存网格,并为FBX文件指定一个名称。在“Files of type”下拉列表中选择“FBX export”。
  4. 在带有导出选项的File Type Specific Options选项卡中,指定参数以导出网格。
  5. Deformed Models选项卡中,选中Blend Shapes复选框以导出混合形状。
  6. 单击Export Selection

现在您有了FBX格式的网格,可以很容易地添加到您的项目中。

步骤2。在世界中添加网格#

本节将展示如何添加导出的网格动画世界,建立变形目标。

将导出的网格添加到世界中:

  1. 启用 Import Morph Targets 选项并导入.fbx文件。

  2. 将导入的文件添加到场景中。
  3. 保存世界。

网格的每个混合形状都是一个目标。您需要为网格的表面创建变形目标,并为这些目标设置参数来控制变形目标动画。下面的例子展示了如何从代码中创建变形目标和设置参数:

AppWorldLogic.h:

源代码 (C++)
#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:

源代码 (C++)
#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来获得的。节点是,通过其名称从World获得
  • setNumTargets()函数集的数量目标的表面网格。导出的网格在上面的例子中有2个目标(混合形状)。
  • 通过使用setTarget()函数,每个创建的变形目标的所有参数都在update()函数中设置。每个目标都有其目标权重。权重对网格的坐标有影响:坐标乘以它们的权重。因此,所有启用的目标都乘以它们的权重,并创建新的网格:

    final_xyz = target_0_xyz * weight_0 + target_1_xyz * weight_1 + ...
  • 因为在上面给出的代码sin()cos()函数用于动画混合不同的目标,创建目标:

    • 源代码 (C++)
      mesh->setTarget(0, 1, 0, 1.0f, 0);

      这个目标是没有任何插值的绑定姿势

    • 源代码 (C++)
      mesh->setTarget(1, 1, 0, -k0, 0);
      mesh->setTarget(2, 1, 0, -k1, 0);

      这些目标用于插值两种动画混合。

    • 源代码 (C++)
      mesh->setTarget(3, 1, 1, k0, 0);

      这个目标用于第一个动画混合,它使用sin()函数进行插值。

    • 源代码 (C++)
      mesh->setTarget(4, 1, 2, k1, 0);

      这个目标用于第二个动画混合,它使用cos()函数进行插值。

分配材质网后,结果如下:

最新更新: 2023-12-19
Build: ()