M3G教程:进阶篇(六)动画
?
????? M3G中动画的数据结构如下:

【载入World节点】
????? 通过M3G Viewer查看M3G Converter转换的m3g文件,我们会发现m3g文件中camera并没有在world树下,而是和world树是平级的。因为JSR184要求渲染时所有模型信息必须放到world树下,所以我们要先获取World节点,方法有两种:
????? ①遍历该Object3D数组,并比较每个元素的userid如果正是World节点的useid将该元素取出;
????? ②遍历该Object3D数组,并比较每个元素是不是World类的实例,那么既然World节点是场景的根节点,那么在该Object3D数组中也应该只有一个World类的实例对象。
????? 第一种必需通过查看文件中world节点的userId来获取,第二种比较容易操作,代码如下:
????? 在JSR184中,使用AnimationTrack、AnimationController和KeyframeSquence三个类来实现关键帧动画:
AnimationTrack:是一个集合类(Composition),用来将AnimationController、KeyframeSquence和一个特定属性(Target Property)捆绑起来,这种结构也使得同一个AnimationController和KeyframeSquence可以被不同的关键帧动画复用。在每一个Object3D对象中,通过addAnimationTrack和removeAnimationTrack方法,管理一组AnimationTrack序列;当使用animate方法,计算该Object3D对象关键帧动画时,所有在序列中的AnimationTrack都会被依次计算,此外若该Object3D对象有到其他Object3D的引用,则所有引用的Object3D的animate方法也会被依次执行。
AnimationController:通过指定采样点和采样速度,实现从WorldTime到SquenceTime的映射,从而控制动画的播放效果,如:暂停,继续,快进、倒退等。
????? AnimationController有一个激活时间段属性(通过setActiveInterval(int,int)实现),通过指定最小及最大的world time值来控制这个AnimationController在这个时间段是激活状态的。如果AnimationController是在某时间是非激活状态,则系统在动画计算时直接将其忽略。
????? 另外,AnimationController有一个weight属性,因为系统对对象某属性进行计算时会将与此属性相关的所有动画计算的结果进行合并,而weight则表示这个AnimationController在这个计算中所占的比重,确切的说,对于一个标量属性P的计算是这样的:P = sum [ wi Pi ] 。
????? AnimationController将传入Object3D.animate()方法的world time值与sequence time值进行映射,sequence time主要用于对关键帧动画数据进行抽样。sequence time会在每次调用对象的animate()方法时计算得出,而不是store it internally,这是为了避免误差的累积及由此产生的一系列状况。这种设计简化了动画系统,使动画系统能够无状态化(相对于状态机),并且效率更高。
????? 从world time到sequence time的映射由AnimationController中的三个常量及传入animate()方法的world time进行计算得到的。公式如下:
?????
????? 其中的参考值t[sref]及t[wref]是通过setPosition()方法指定,而速度speed则是由setSpeed()方法指定(注意改变速度会影响到t[sref]及t[wref]值)。
????? 注意:虽然API及文档中并没有明确的说明这里的时间单位使用毫秒,但我们强烈建议你使用这个默认的时间单位。当然,如果确实需要使用特有有时间单位,动画系统还是支持的。
KeyframeSquence:用来保存所有的关键帧的值,同时指定关键帧循环的方式,以及计算时的插值方法。
????? 无论在立即模式还是保留模式下,都是通过调用Object3D对象的animate()方法实现将对象动画数据的计算。根据使用情形,我们既可以调用World.animate(),也可以调用相应Object3D对象的animate()方法。
【示例】
以下代码实现一个灯光在红色与绿色之间转换,并沿着一条曲线路径进行移动:
?? 初始化时:
?
其中pogoroo.m3g的节点树关系如下:
效果如下:
?