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. Linux bridge-utils tunctl 使用

    网络 brctl是Linux下用来管理以太网桥.在内核中建立.维护.检查网桥配置的命令 STP - Spanning Tree Protocol(生成树协议)逻辑上断开环路.防止二层网络的广播风暴的产 ...

  2. MCE----Machine-check exception

    http://en.wikipedia.org/wiki/Machine_Check_Exception Machine-check exception From Wikipedia, the fre ...

  3. Intel的东进与ARM的西征(4)--理想的星空,苹果处理器之野望

    http://www.36kr.com/p/200031.html “人生五十年,如梦亦如幻.有生斯有死,壮士何所憾?”之所以没有遗憾,是因为有了理想. 公元 1582 年,日本战国时期最著名的霸主, ...

  4. poj1703 Find them,Catch them 【并查集】

    做过一些的带权并查集,再来做所谓的"种类并查集",发现好像就顿悟了. 种类并查集与带权并查集实质上的区别并不大. 关键的区别就是种类并查集仅仅是带权并查集再弄个%取余操作而已.然后 ...

  5. Objective C运行时(runtime)技术总结,好强大的runtime

    前言:          Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表.属性列表.变量列表,修改方法.属性,增加方法,属性等等,本文对相 ...

  6. [转载]php中深拷贝浅拷贝

    转自:http://cnn237111.blog.51cto.com/2359144/1283163 PHP中提供了一种对象复制的操作,clone.语法颇为简单: $a = clone $b; 1.浅 ...

  7. 【Web前端】清除浮动&amp;css中文字体

    清理浮动有非常多种方式,像使用 br 标签自带的 clear 属,使用元素的 overflow.使用空标签来设置 clear:both 等等.但考虑到兼容问题和语义化的问题,一般我们都会使用例如以下代 ...

  8. 使用GitLab CI + Capistrano部署CakePHP应用程序

    使用GitLab CI + Capistrano部署CakePHP应用程序 摘要:本文描述了如使用GitLab CI + Capistrano部署CakePHP应用程序. 目录 1. 问题2. 解决方 ...

  9. Android图表AChartEngine

    很多时候项目中我们需要对一些统计数据进行绘制表格,更多直观查看报表分析结果.基本有以下几种方法: 1:可以进行android api进行draw这样的话,效率比较低 2:使用开源绘表引擎,这样效率比较 ...

  10. UICollectionViewController xcode6.1 自定义Cell

    本文转载至 http://blog.csdn.net/daleiwang/article/details/40423219 UICollectionViewContAutolayoutstoryboa ...