http://blog.csdn.net/bugrunner/article/details/7229416

6. 加载Camera和Light

在FBX模型中除了几何数据外较为常用的信息可能就是Camera和Light,虽然在游戏中一般不直接从模型中得到这两部分信息,而是由引擎来提供,但是FBX中提供了对这些信息保存的支持。其实单纯加载这两部分的信息很简单,就像之前介绍的在整个Scene Graph中对每个Node遍历过程中,判断得到当前结点是Camera或Light时调用相应的ProcessCamera或ProcessLight来完成相关的处理操作即可。

如果对于当前结点判断得到其是一个Camera结点,那么可以直接调用GetCamera来得到一个KFbxCamera类型的指针,之后就可以通过该指针来完成Camera属性的获取。

[cpp] view
plain
 copy

  1. void ProcessCamera(KFbxNode* pNode)
  2. {
  3. KFbxCamera* pCamera = pNode->GetCamera();
  4. // 调用相应的接口获取Camera的属性即可
  5. }

对于Light结点的处理与Camera类似。至于Camera与Light结点所具有的属性可以直接在SDK中看kfbxcamera与kfbxlight的类型定义即可。

[cpp] view
plain
 copy

  1. void ProcessLight(KFbxNode* pNode)
  2. {
  3. KFbxLight* pLight = pNode->GetLight();
  4. // 调用相应的接口获取Light的属性即可
  5. }

7. 加载动画

动画信息是模型数据中非常重要的一部分,也是一个渲染或游戏引擎最基本的需求之一。FBX对Animation的良好支持也成为其与.obj等静态模型最主要区别之一,而且最新的SDK中也提供了对Animation很丰富与简便的操作接口,包括自定义写入与读出等。接下来介绍一下如何使用FBX SDK来加载FBX中存储的动画信息。

7.1 动画数据读取

在FBX中实现对于动画数据的存储主要通过以下三个对象层来实现:Animaiton Stack、 Animation Layer、Animation Node,其层次关系为

Animation Stack -> Animation Layer -> Animation Node,图示化结构为(图片来自于FBX SDKRef):

其中的Animation Stack为FBX动画管理的最高层,其中包含着与之相关联的Animation Layer等;每个Animation Stack对应着一套动作过程。每个Stack中包含一个或多个Animation Layer(当用来做blend时就需要多个Layer,但一般是一个)。在每个Layer中又通过一个KFbxAnimCurveNode的结点使Layer与具体的动画数据发生关系。一般情况下可以根据自己的需要情况或引擎的动画实现方式来读取FBX中的动画数据,例如本人在实现时从FBX中读取数据的方法就可以抽像化为如下图所示的结构:

其中对每个Node判断其是否有对应的动画数据,若有则读取其Curve中的数据并存储以供渲染更新使用,代码如下所述:

[cpp] view
plain
 copy

  1. void LoadNodeCurve(KFbxAnimLayer* pAnimationLayer , KFbxNode* pNode , StackTimeSpan& timeSpan)
  2. {
  3. KTime       keyTimer;
  4. unsigned long millseconds;
  5. for(UINT i = 0 ; i < timeSpan.mKeyNums ; ++i)
  6. {
  7. millseconds = timeSpan.mStart + (float)i * timeSpan.mStep;
  8. keyTimer.SetMilliSeconds(millseconds);
  9. // 计算得到当前结点在当前时刻下所对应的空间局部和全局矩阵
  10. // 局部矩阵对于Skeleton是必需的,因需要使用它来计算父子Skeleton之间的空间关系
  11. KFbxXMatrix curveKeyLocalMatrix  = pNode->EvaluateLocalTransform(keyTimer);
  12. KFbxXMatrix curveKeyGlobalMatrix = pNode->EvaluateGlobalTransform(keyTimer);
  13. }
  14. }

代码中的timeSpan是一个自定义的结构,其中包含了整个FBX对象动画信息的相关数据,比如帧数、起始时间、帧间时差等;在读取时需将其中的信息转换为一个KTime类型的对象(keyTimer)以供FBX SDK的API使用。上述操作加载了动画数据中直接相关的空间Matrix信息,这是普通模型对象的基本动画信息。但是对于Camera或Light等对象而言,动画不仅包含着位置或空间信息的变化而且还包含着一些其它的属性变化如Camera的FOV,Light的Direction,Color等,这些信息也导出FBX时被存储到了FBX中。而这些信息的获取就是通过KFbxCurveNode来实现,其关联具体的Curve到相应的Property上,进而从中获得对应的动画信息。比如我们熟悉的Camera实现中有一个常用的属性PixelAspectRatio,用来描述视口Width与Height之间的比值,对于某些动画效果这个Ratio可能是时变的,因而在建模时就会将该信息同样以动画的信息进行存储,现在我们想要得到这一部分动画数据。通过查看kfbxcamera.h可以发现在KFbxCamera的定义中含有

KFbxTypedProperty<fbxDouble1> PixelAspectRatio

的一个成员变量,这即是PixelAspcetRatio动画数据所存储的位置;而在ProcessCamera时已经由当前Node的指针得到了Camera对应的指针,之后该部分读取代码基本上如下所述:

[cpp] view
plain
 copy

  1. void LoadCameraCurve(KFbxAnimLayer* pAnimationLayer , KFbxCamera* pCamera , StackTimeSpan& timeSpan)
  2. {
  3. if(pCamera == NULL)
  4. {
  5. return;
  6. }
  7. // 通过FBX的属性对象而获取其所对应的Animation Curve
  8. KFbxAnimCurve* pCameraAttriAnimCurve = pCamera->PixelAspectRatio.GetCurve<KFbxAnimCurve>(pAnimationLayer);
  9. // 判断当前的属性是否含有可变的Animation值
  10. if(pCameraAttriAnimCurve)
  11. {
  12. KTime         keyTimer;
  13. unsigned long millseconds;
  14. for(UINT i = 0 ; i < timeSpan.mKeyNums ; ++i)
  15. {
  16. millseconds = timeSpan.mStart + (float)i * timeSpan.mStep;
  17. keyTimer.SetMilliSeconds(millseconds);
  18. // 计算Camera的某属性在当前时刻所对应的值
  19. pCameraAttriAnimCurve->Evaluate(keyTimer);
  20. }
  21. }
  22. }

上述代码通过PixelAspectRatio的属性对象加载了其不同时刻下的动画值,其它的属性的动画读取也可以用类似的操作实现。

7.2 动画驱动

加载了上述的动画数据以后,即可以使用其来驱动模型中的直接动画相关部分,如Camera、Light、Skeleton等。由之前的代码可知,在加载动画数据时我们使用了当前Node的指针,因而就可以用它在加载动画时存储其它的一些额外信息使这些动画数据与对应的Camera、Light、Skeleton等部件进行关联(比如Node的指针,或是Node的Name等),从而可以从动画管理器中随时查得到某结点在指定时刻位置上的动画数据。该部分可以根据具体的实现采取适宜的操作即可完成。

最后,带有动画驱动的Skeleton渲染效果如下列图所示(Camera,Light的动画效果木有绘出):

 

 

基于FBX SDK的FBX模型解析与加载 -(三)的更多相关文章

  1. 基于FBX SDK的FBX模型解析与加载 -(一)

    http://blog.csdn.net/bugrunner/article/details/7210511 1. 简介 FBX是Autodesk的一个用于跨平台的免费三维数据交换的格式(最早不是由A ...

  2. 基于FBX SDK的FBX模型解析与加载 -(四)

    8. 骨骼蒙皮动画 骨骼蒙皮动画是当前游戏引擎中最常用的一种动画方式,关于其基本原理网络上的资料较多,关于到涉及的其它较复杂操作,如插值.融合等在这里也就先不再讨论了,而且其实现方式也与具体引擎的动作 ...

  3. 基于FBX SDK的FBX模型解析与加载 -(二)

    http://blog.csdn.net/bugrunner/article/details/7211515 5. 加载材质 Material是一个模型渲染时必不可少的部分,当然,这些信息也被存到了F ...

  4. 全面解析Pytorch框架下模型存储,加载以及冻结

    最近在做试验中遇到了一些深度网络模型加载以及存储的问题,因此整理了一份比较全面的在 PyTorch 框架下有关模型的问题.首先咱们先定义一个网络来进行后续的分析: 1.本文通用的网络模型 import ...

  5. tensorflow 模型保存与加载 和TensorFlow serving + grpc + docker项目部署

    TensorFlow 模型保存与加载 TensorFlow中总共有两种保存和加载模型的方法.第一种是利用 tf.train.Saver() 来保存,第二种就是利用 SavedModel 来保存模型,接 ...

  6. 一款基于jquery带百分比的响应式进度加载条

    今天要给大家带来一款基于jquery带百分比的响应式进度加载条.这款加载条非常漂亮,而且带有进度的百度比,且在不同的百分比用的是不同的颜色.而且这款加载条采用了响应式设计,在不同的分辨率的显示器下完美 ...

  7. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

  8. tensorflow实现线性回归、以及模型保存与加载

    内容:包含tensorflow变量作用域.tensorboard收集.模型保存与加载.自定义命令行参数 1.知识点 """ 1.训练过程: 1.准备好特征和目标值 2.建 ...

  9. [PyTorch 学习笔记] 7.1 模型保存与加载

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson7/model_save.py https://githu ...

随机推荐

  1. hdu3076ssworld VS DDD 概率dp

    //ssworld VS DDD 两个人有血量值 hp1 , hp2  //两人掷骰子得到每一点的概率已知 //ssword赢的概率 //dp[i][j]  表示有第一个人血量为i.第二个人的血量为j ...

  2. 【转载】C#相等性比较

    本文阐述C#中相等性比较,其中主要集中在下面两个方面 ==和!=运算符,什么时候它们可以用于相等性比较,什么时候它们不适用,如果不使用,那么它们的替代方式是什么? 什么时候,需要自定一个类型的相等性比 ...

  3. 【转载】细聊分布式ID生成方法

    一.需求缘起 几乎所有的业务系统,都有生成一个记录标识的需求,例如: (1)消息标识:message-id (2)订单标识:order-id (3)帖子标识:tiezi-id 这个记录标识往往就是数据 ...

  4. Network Booting

    http://en.wikipedia.org/wiki/Network_booting Network booting Network booting is the process of booti ...

  5. js操作文件 HTML5版

    js操作文件 HTML5版,有需要的朋友可以参考下. <!DOCTYPE html> <html> <head> <title>JSFileReader ...

  6. JAVA学习第十九课(java程序的异常处理 (二))

    异常处理的捕捉形式: 这是能够对异常进行针对性处理的方式 六.try.catch的理解 详细格式: try { //须要被检測异常的代码 } catch(异常类 变量)//改变量用于接受发生异常的对象 ...

  7. SpringCloud遇到的坑

    1. 今天使用Feign 调用其他项目,结果一直跳转到断路器,跟踪发现是接口响应时间较长,解决方案 解决:# 在 Feign 模块中,单独设置这个超时时间不行,还要额外设置 Ribbon 的超时时间, ...

  8. All the best open source and Software as a Service (SaaS) tools in one place 工具 工欲善其事必先利其器

    Open Source & SaaS Tools | StackShare https://stackshare.io/categories AfterShip/SaaS: List of S ...

  9. 在无代码文件的aspx文件中添加类、函数和字段的方法

    大家都知道,在开始WebForm程序时,一个WebForm由.cs代码文件与.aspx页面文件组成.在aspx文件中可以嵌入C#代码,但无法在aspx的嵌入C#代码中定义类,函数和字段等.这样,就限制 ...

  10. bzoj3462: DZY Loves Math II

    状态很差脑子不清醒了,柿子一直在推错.... ... 不难发现这个题实际上是一个完全背包 问题在于n太大了,相应的有质数的数量不会超过7个 假设要求sigema(1~plen)i pi*ci=n 的方 ...