利用3DMAX的IGame接口可以方便的导出自已的动画格式数据,而且你仍然可以同时继续调用原来的SDK函数来完成一些IGame接口不支持的操作。下面是调用IGame导出骨骼动画的大概步骤,为了让简化问题,这儿通过对3DMAX骨骼动画进行采样的方式来完成骨骼动画数据的采集,至于像TCB,Bezier这类的控制器数据的导出,原理一样,就是需要计算一下每个关键帧骨骼数据的相关插值参数。懂的TCB(Hermite插值算法)和Bezier的插值算法应该比较好理解。

首先利用插件向导建立一个导出插件的框架,完成一些必要的接口例程。然后重点来到真正导出数据的接口函数中:

Int DoExport( …)

{

//

// 转换坐标系为D3D坐标系

//

IGameConversionManager * cm = GetConversionManager();

cm->SetCoordSystem( IGameConversionManager::IGAME_D3D );

// 初始化IGame 场景接口

m_pIGame->InitialiseIGame();

// 我们导出网格时的第一帧,当然不一定是0帧,任何一帧都是可以的

m_pIGame->SetStaticFrame(  0  );

// 导出其它的各种数据,网格,材质,灯光,摄像机…

// 这儿就是我们现在关心的是骨骼数据导出的地方

ExportBones();

}

void ExportBones()

{

// 针对每一个Bone类型的Node

// 得到骨骼名称

TCHAR *value = pGameNode->GetName();

// 骨骼唯一的ID

int id = pGameNode->GetNodeID();

// 父骨骼的ID

IGameNode *parent = pGameNode->GetNodeParent();

int parentID = parent ? parent->GetNodeID() : -1;

// 得到骨骼控制器

IGameControl *pGameControl = pGameNode->GetIGameControl();

// 采样各个时刻的值, keys用来接收返回的采样值,m_sampleRate是采样的帧率,采样的

// 数据类型为IGAME_TM,代表骨骼矩阵,我们可以根据需要将其分解为缩放,旋转,平

// 移数据。m_bRelative代表骨骼矩阵是否需要乘以父骨骼矩阵,如果为FALSE的话,可以

// 直接用来变换蒙皮顶点,不需要再乘以父骨骼矩阵。

if ( pGameControl->GetFullSampledKeys( keys,

                     m_sampleRate,

IGAME_TM,

                     m_bRelative ) )

{

// 导出骨骼采样的各个帧的数据,共有三种类型:缩放,旋转,平移

// 由这三种类型的数据可以组建一个骨骼的变换矩阵

DumpSampleKeys( pDoc, keys, IGAME_POS, pGameNode );

DumpSampleKeys( pDoc, keys, IGAME_ROT, pGameNode );

DumpSampleKeys( pDoc, keys, IGAME_SCALE, pGameNode );

}
}

// 这儿是具体导出骨骼所有帧数据的地方

Void DumpSampleKeys( IGameKeyTab &keys,

            IGameControlType type,

             IGameNode *pGameNode )

{

// 在这儿我们将得到的各个骨骼矩阵数据进行分解,得到骨骼的旋转,缩放,平移

     // 三种类型数据分别保存。

GMatrix &matrix = keys[ k ].sampleKey.gval;

Matrix3 m = matrix.ExtractMatrix3();

AffineParts ap;

decomp_affine( m, &ap );

   // 将ap的内容保存为自已的格式

// …

}

至此我们就完成了骨骼动画数据的导出,是不是非常简单。下面将介绍如何利用导出的旋转,平移,缩放数据去重建3DMAX中的骨骼矩阵,在获得了骨骼在各个时刻的旋转、平移缩放三种数据后,我们就可以恢复出这三种数据所代表的骨骼变换。恢复方法见MAX的DOC中说明:

Matrix3 srtm, rtm, ptm, stm, ftm;

ptm.IdentityMatrix();

ptm.SetTrans(ap.t);

ap.q.MakeMatrix(rtm);

ap.u.MakeMatrix(srtm);

stm = ScaleMatrix(ap.k);

mat = Inverse(srtm) * stm * srtm * rtm * ftm * ptm;

(一般情况下你直接采用rtm * ptm也不会出错,因为人体骨骼一般不会有缩放的情况,怪物例外。

 )

这儿我们假定这个骨骼变换在导出时已经包含了父骨骼作用的影响(GetFullSampledKeys( keys, m_sampleRate, IGAME_TM, m_bRelative ) m_bRelative值为FALSE)。也就是说这个骨骼上的蒙皮顶点乘上这个骨骼矩阵就可以得到在该骨骼作用下的新的顶点,同理所有网格顶点都乘以它们所绑定到的骨骼上的骨骼矩阵就完成了网格(蒙皮)随着骨骼一起动画的目的。

在导出骨骼动画之前我们可以同时导出其网格的数据。记录获取这个网格的数据时刻是t0, 那么我们用这个to时刻的网格乘以各个时刻的骨骼矩阵是否就能将网格进行正确的蒙皮动画呢?如果你试一下就会发现结果是错误的。因为我们前面计算的骨骼矩阵不是针对to时刻的网格的。

前面计算的所有时刻的骨骼矩阵针对的都是同一个姿态的网格,然而这个姿态却不是我们t0时刻导出的网格。怎么办?我们需要将这个t0时刻的网格先变换到原始可以进行骨骼蒙皮的姿态即可。怎么做?

我们看看下面的公式:

(待求的可以进行蒙皮的网格数据) * (t0时刻骨骼矩阵) = (to时刻的网格数据)

现在我们手头有如下的数据,一是t0时刻网格的数据,二是可以得到t0时刻骨骼矩阵。

这样的话:

(待求的可以进行蒙皮的网格数据)=(to时刻的网格数据) * (t0时刻骨骼矩阵的 逆)

(待求的可以进行蒙皮的网格数据)*(各个时刻的骨骼矩阵),就实现了骨骼动画。

也即是 :

最终的蒙皮网格 = (待求的可以进行蒙皮的网格数据)* (各个时刻的骨骼矩阵) 

最终的蒙皮网格 = (to时刻的网格数据)*(t0时刻骨骼矩阵的 逆)* (各个时刻的骨骼矩阵) 

上面的公式就是我们进行骨骼动画时的公式。其中(t0时刻骨骼矩阵的 逆)我们可以称其为骨骼偏移矩阵或什么矩阵你认为能说明其作用的名字。

至此已经完成了3DMAX骨骼动画数据导出后的使用方法,在验证过程中有个需要注意的地方是,在用导出的旋转,缩放,平移等数据还原骨骼矩阵时,那个缩放的四元数要特别照顾一下,将(x, y, z, w)中的w值反转一下极性,也就是w = -w; 为什么这样呢,我猜想可能是因为MAX中的旋转方向和D3D中的不一致的原因。具体没有去验证。

转载于:https://www.cnblogs.com/Perit/archive/2011/01/25/1944964.html

3DMAX利用IGame导出骨骼动画概要相关推荐

  1. 探讨3DSMAX 中的CS骨骼动画插件

    3D 图形引擎中角色动画是一个重要的组成部分,它在虚拟现实.电子游戏,甚至是传统的动画制作中均扮演着极其重要的角色.如何实现一个良好的角色动画以引起越来越多的研究者的关注.目前的许多建模软件都可以快速 ...

  2. cocos2d-x 3.8.1的骨骼动画加载方法addArmatureFileInfo仍然存在问题

    提出如题所示的问题,心里非常别扭,但的确是事实.因此,Cocos Studio(我目前使用的是 2.3.2)在许多方面还有改进的地方,包括与之相对应的cocos2d-x中的代码操作部分. 问题 目前, ...

  3. Unity 骨骼动画模型变形

    目录 一.问题描述 二.问题截图 三.解决办法 检查办法1: 检查办法2: 一.问题描述 从Maya导出骨骼动画至Unity后,在播放动画时的某一帧发生形变.产生变形的原因,是由于模型权重问题导致骨骼 ...

  4. Cocos骨骼动画功能解密

    在游戏中,人物的各种动作是必不可少,一般实现人物动作的方式有两种,序列帧动画或骨骼动画.Cocos在更新到2.x版本之后,便没有了骨骼动画的功能,使得开发者非常困扰.终于在本次更新中,Cocos编辑器 ...

  5. 第六章:3ds max骨骼动画(下)

    动画是由一系列的静态图像的不断更新显示而产生的.一般情况下,1秒钟要显示24张图像,人就会感觉到连续的动态图像.一般情况下使用30帧就足够了.在3ds max可以设置这个FPS值.右下角"时 ...

  6. Unity3D - 【Animator】骨骼动画的实现

    利用Animator实现骨骼动画: 1> 确保人物能够正常移动.Camera能够正常跟随 2> 使用WSAD对人物不同运动状态进行切换与连接 3> LeftShift:加速.Spac ...

  7. 3dMax 骨骼动画导入到Unity

    3dMax做的骨骼动画导入到unity中的时候需要注意的事项: 在使用3dMax导出的时候一定要勾选3DMax 导出选项中的"烘焙动画",否则导出的动画在unity中无法正常动作.

  8. OGRE 3DMAX导出骨骼

    3DS MAX是一个强大通用的建模工具,能方便的制作骨骼动画.Ogre是一个开源的图形引擎,在骨骼动画方面支持Vertex blending,它也提供了对多种模型的导入,当然少不了3DS MAX模型. ...

  9. 利用Unity插件Anima2D创建2D骨骼动画

    利用Unity插件Anima2D创建2D骨骼动画 创建步骤 导入Anima2D插件 准备2D素材 配置2D骨骼 对2D角色应用IK(反向动力学) 利用Animation创建2D人物动画 创建步骤 导入 ...

最新文章

  1. codeforces B. Eight Point Sets 解题报告
  2. C++学习之路—继承与派生(四)拓展与总结
  3. 云计算概况及第一个Azure程序
  4. JS-数组和函数冒泡排序递归函数
  5. android 自动补全方法,# AndroidStudio代码块的自动补全
  6. 摆摊真的一个月能上万嘛
  7. 玩个锤子,李飞飞夫妇团队的最新研究
  8. (转载)C语言中strlen()返回值类型为无符号数
  9. 基于同一主机配置 Oracle 11g Data Guard
  10. SQLMAP使用教程(一)
  11. linux系统编程实训总结,linux实训总结与体会
  12. Github Emoji——Github表情大全
  13. 微信公众号开发(3)-实现关键词自动回复
  14. 苹果x微信语音十秒就断_原来苹果手机信号差是这个原因!教你4个方法,信号马上满格...
  15. ESP32/8266 WIFI模块连接Linux云服务器
  16. Vscode :代码缩进forward and backward
  17. Q Inventory System unity背包物品插件 使用笔记
  18. 关于onenote2016遇到的页面大片空白无法正常收缩的bug
  19. 【50个最受网友欢迎的HTML5资源下载列表】
  20. 深入理解Java中的容器

热门文章

  1. 用实际例子理解回调函数(Calback)
  2. 公式不懂也无妨,业务精通才是真正的算法工程师
  3. 如何清理和优化你的Mac:14个小技巧推荐给你!
  4. 网站统计中访客标识码有什么作用
  5. 三行代码,使用第三方网站统计访客数据
  6. oneDrive 5T网盘空间申请教程
  7. 如何在word中打印对勾和叉
  8. java项目----教务管理系统_基于Java的教务管理系统
  9. flutter 刷脸_传说哥教你如何假装架构师
  10. Android自定义控件--仿安全卫士中的一键加速【圆形进度条】