十、X3D的动画效果
由于X3D的动画涉及到时间触发器、插值器、事件和路由等概念,因此在本节中,我们先来看一个简单的示例,然后一步一步深入下去。
一、 一个简单的示例
示例的结果如下图所示:

说明:预览后,球来回移动。
二、 相关概念的理解
在X3D中,动画的产生涉及到时间触发器、插值器、事件和路由的概念,下面来说明:
1、 时间触发器TimeSensor
触发器或者叫做传感器,是用来产生不同类型的事件。时间触发器TimeSensor是根据时间来不断产生事件,它有许多属性,通常把用于输入的属性称为域,或称为输入事件,而把输出的属性称为产生的事件,或称为输出事件。时间触发器TimeSensor的主要域有:
cycleInterval -- 每个周期的长度,以秒为单位,取值大于0。需要说明的是:如果cycleInterval < 0.01 秒,TimeSensor 可能不起作用。
enabled --若为True,当条件成立时产生时间相关事件;若为False,在任何条件下都不会产生时间相关事件。
loop -- 表明时间传感器是无限循环,还是在一个周期后被终止。
startTime -- 开始产生事件的时间。
stopTime -- 终止产生事件的时间。其值若小于等于起始时间,则被忽略。
pauseTime -- 暂停时间。若当现在时间>= pauseTime,isPaused 值变为True,暂停。
resumeTime -- 恢复时间。当resumeTime <= 现在时间,isPaused值变为False,再次激活。
而事件主要有:
isActive -- 表明时间传感器当前是否在运行。若在运行,则返回True;若处于停止状态,则返回False。
isPaused -- 表明时间传感器当前是否在暂停。
cycleTime -- 在每个周期开始时,返回当前时间。
fraction_changed -- 当前周期的完成比。从0(周期开始)到1(周期结束)。
time -- 从格林威治时间1970年1月1日子时(午夜12点)至今所经过的秒数。
2、 插值器
计算机动画按生成的方法可以分为逐帧动画、关键帧动画和造型动画等几大类。在关键帧动画设计中,通常需要我们指定关键帧,而中间帧往往由计算机自动生成。X3D中的插值器就起到设定关键帧并自动生成中间帧的作用。它主要有颜色插值器节点(ColorInterpolator)、坐标插值器节点(CoordinateInterpolator)、法向量插值器节点(NormalInterpolator)、方向插值器节点(OrientationInterpolator)、位置插值器节点(PositionInterpolator) 和比例插值器节点(ScalarInterpolator)。除此之处,X3D还提供比较专业的插值器,如NURBS曲线系列插值器等。
3、 事件
事件(Events)是在 X3D 运行时环境中产生行为的主要方法,这种方法用来改变域的输入值或接受域的输出值,分别又称为发送到输入域的事件和输出域发送的事件。
4、 路由
路由(Route)声明允许我们在把一个节点的输出事件连接到另一个节点的输入事件上,这样可以执行复杂的行为,而不需要使用程序命令。在路由中,一个输出事件发生,相应目的的输入事件就会接受到通知,同时可以对输入事件变动做出相应的处理。这个处理可以改变节点的状态,产生额外的事件,或者改变场景图的结构。
Route(路由)不是节点,它是一个语句。ROUTE 语句是建立指定节点的域之间通道的语法构件。ROUTE 语句可以出现在 X3D 文件的最上层,或者也可以出现在节点中任何可以使用域的地方。ROUTE 语句应该放置在路由的源节点和目的节点定义之后,而不能放置在源节点中或目的节点中。
三、 理解前面的示例代码
上述代码中,我们产生定义了一个名为TIME的时间触发器。之所以给它定义一个名称,是由于在ROUTE语句中要使用它。然后定义了一个名为INPO的位置插值器。由于球的位置需要不断变化,因此我们将Transform作为Shape的父节点。最后两个Route语句是理解的关键。
第一个Route语句:![]()
是建立TIME中的fraction_changed和INPO的set_fraction的事件关联。
第二个Route语句:![]()
是建立INPO的set_fraction和BALL的translation的事件关联。
这样,当TIME中的fraction_changed变化时引起位置插值器set_fraction值的变化,当输入一个key 值,位置插值器就输出一个keyValue,由于位置插值器的keyValue值是一个坐标值,因此作为Transform节点的translation域的输入值,从而使球的位置自动改变。由于时间触发器的loop设为True,这样不断有事件产生,从而球的位置不断变化,球就动起来了。
需要说明的是,由于我们要使用时间触发器的fraction_changed事件,而fraction_changed值的变化是0到1之间,因此我们在指定插值器的key时也应是0到1之间的序列值,并且每一个序列值要插值器的keyValue相对应,不能多也不能少。
四、 动画示例
有了上述的理解,对于X3D的其他动画也就简单了。
示例1:旋转动画(见40.x3d,40.x3dv,40.wrl)

说明:由于将时间触发器的cycleInterval设为10秒,所以旋转的速度稍慢一些。
示例2:颜色动画(见41.x3d,41.x3dv,41.wrl)
结果如下所示:

类似的还可以使用其他的插值器进行动画,这里不再介绍。


