我的订单|我的收藏|我的商城|帮助中心|返回首页
虚拟现实新闻>VR>行业资讯>培训教程

VRML2.0教程5:变换节点

文章来源:第三维度 作者: 发布时间:2012年04月17日 点击数: 字号:

    来源:第三维度
    作者:施寅,周葆芳,赵志勇

    选自《VRML2.0使用速成》第5章 第二节

    一、准备工作
   
    首先, 找一个你最喜欢的文本编辑器, 用它新建一个VRML 文件, 这个文件除了文件头和一个空的分组节点外不包含任何东西:

    # VRML V2 .0 utf8 Group {}

    然后保存这个新文件并给它取个名(如temple .wrl ) , 用你的VRML 浏览器打开这个文件看看它是否是个合法的VRML 文件。由于还没对场景做任何实际工作, 从浏览器窗口看到的将是一个空旷的场景。如果浏览器报告说你的文件有错, 那么就请你仔细检查一下,是哪里敲错了, 特别要注意大小写———文件头中“V2 .0”的“V”一定要大写。

    现在让我们回到文本编辑器, 为你的新场景加一些东西。先在文件的顶部(文件头后)加一个WorldInfo(场景信息)节点, 虽然你可以把WorldInfo 节点加到分组节点Group中作为一个子节点, 但从逻辑上看,WorldInfo 包含的是说明整个场景的信息, 最好把它独立放在文件开头处。WorldInfo 节点的title 域给出了场景的标题, 浏览器一般把这一信息显示在窗口顶部的标题栏中。另外一个域是info 域, 它的值是说明性字符串, 浏览器一般把它同注释句一样忽略掉。不同的是, 注释句对有的服务器来说是不予传输的, 而WorldInfo 节点的info 域一定会传输给浏览器, 因此, 一些重要的说明信息应放在World-Info 节点中, 而不要写成注释语句。

    [例1] 使用WorldInfo 节点。

    # VRML 2 .0 utf8 WorldInfo {

    title "temple" info "VRML model of an Aztec temple ."

    }

   Group {

    }

    注意: info 域是一个多值域( 取MFSt ring 类型值) , 所以它可以是多个字符串, 这些字符串一定要用一对方括号括起来。关于域的取值类型请参看附录C“域类型说明”。如果一个文件中含有多个WorldInfo 节点, 则只有第一个起作用, 别的都将被忽略。因此, 你可以在每个VRML 文件中都包含WorldInfo 节点, 甚至这个文件将用内联方式引入到一个大的场景中也可以, 但只有顶层文件中的第一个WorldInfo 节点会被用到。

    你可以用NavigationInfo(导航信息) 节点来告诉浏览器, 你想以怎样的方式来观察你的场景。这两种信息节点都是既能出现在VRML 文件的顶层, 又能作为子节点出现在任何一种分组节点中。如果你没有指定任何导航信息, 浏览器将取缺省的NavigationInfo节点值, 它是一种在大多数情况下对大多数文件都适用的观察方式。

    现在, 基本的文件框架已经有了, 在你开始建造神庙之前, 你需要更进一步了解VRML 中的变换和几何造型。

    二、变换节点

    Transform( 变换)节点包含多个域, 它们共同定义一个变换。VRML 中提供了多种变换, 像平移、绕一个给定点旋转和关于给定点变比等。利用变换, 你能在VRML 场景中随意移动物体、改变方向、缩放物体尺寸等。

    1. 平移变换

    在上一章中学习了用translation 域指定x , y, z 方向上平移量来移动一个Transform子节点。这些平移量, 如同VRML 中所有的距离, 都是以米为单位的。如果你只是在自己的一个场景中用到单位, 你可以不去理会它是米还是别的。但是, 如果你的场景要和别人的场景相连, 就最好使用这个标准单位, 免得连接时出现单位不一致的问题。

    注意: 阿兹特克场景中用的单位都是英尺。为了不改变文件中各处的距离单位, 本书提供的取自阿兹特克场景的所有例子的单位都用英尺。

    2. 旋转变换

    Transform 节点中的rotation 域用来使其子节点绕指定轴旋转一个角度, 其角度由指定的弧度给出。域值包含四个数, 前三个数指定一个三维空间中的点, 旋转轴就是过坐标原点和这个点的连线, 最后一个数是绕这根轴旋转的弧度。例如, 为了让chacmool 躺在地上, 你可以使它绕x 轴旋转1 .57 弧度( 大约90°)。

    [例2] 旋转一个物体。

    Transform { rotation 1 0 0 1 .57
    children [
   Inline { url "chacmool .wrl"}
    ]
    }

    定义转轴时你不一定要把它定义成单位向量, 你可以取任何长度值。

    rotation 50 0 0 1 .57

    因为就旋转轴的定义而言, 关键的是它的方向, 而不是长短, 当然以单位向量的形式给出更好一些。

    如果沿定义转轴的那点往坐标原点方向看, 正的弧度值是沿逆时针方向旋转, 负的弧度值是沿顺时针方向旋转。你可以通过右手法则来记住它, 把右手伸出来, 大拇指伸直并指向右, 握起其余四指, 弯曲的四指旋转方向是向你的。如果你想像把右手放在转轴定义点处, 并让拇指指向表示从坐标原点向该处出发的方向, 那么此时其余四指的旋转方向就是正旋转方向。图1 所示的就是三个坐标轴方向上的右手法则, 它也适用于绕其它任意轴的旋转。

VRML2.0教程5:变换节点右手法则
图1 右手法则

    如果你想绕多个坐标轴旋转的话, 必须通过用多个相关联的变换并指定每个变换的坐标轴来实现。你不能在一个变换中指定多个旋转。

    注意: 当要转动的物体不在坐标原点时要特别小心。旋转这类物体时, 它还要在空间发生位置移动。如果你只想旋转它, 你就得先把它平移到坐标原点再转动它, 最后再平移到原来位置。

    3. 比例变换

    你可以拉伸或压缩Transform 节点的子节点。Transform 节点的scale 域的三个数分别定义了比例变换在x、y、z 轴三个方向上所做的变化, 所以用( 1 , 1 , 1) 来作为比例系数是不起作用的。取0 作为比例系数会使物体在那个方向上无限小, 所以使用0 值是不恰当的。

    注意: 必须注意你要比例变换的物体不在坐标原点的情况。比例变换通常是相对于坐标原点而言的, 而不是相对于物体的中心, 知道这一点至关重要。实际应用时你必须先把物体平移到坐标原点, 缩放后再平移回去。

    4. 综合变换

    Transform 节点有多个定义不同变换的域, 从前面的例子中你已经看到它们了, 把它们综合起来就可以表示一个复杂的变换。一般来说, 可以把综合变换看成是一个简单平移变换加一个简单旋转变换再加一个简单比例变换的叠加。

    下面是一个Transform 节点的例子, 每个域都填上了值, chacmool 模型被用为子节点。

    [例3] 综合变换。

    Trnsform { translation 2 2 .5 0

     rotation 0 0 1 1 .57
     scale 1 .7 1 0 .7
     children [
     Inline { url "chacmool .wrl"}
    ]
    }

    如果空出某个域, 浏览器将使用它的缺省值, 关于具体各个域的缺省值请参看附录B“节点说明”部分。

    上面例子执行的结果是: chacmool 在两个坐标轴( x 轴和z 轴)方向上相对原点进行了大小不同的比例变换, 接着绕z 轴旋转了90°, 然后以相对于原点的一段距离进行了平移。如图2 所示的变换前后的两个位置,变换前chacmool 躺在坐标原点处, 经过比例、旋转和平移变换后直立在一个新的位置上。

VRML2.0教程5:变换节点变换后的chacmool
图2 变换后的chacmool

     5. 变换的顺序

    当你同时使用多种变换时, 要牢记以下几点:

    (1 ) 一系列变换其顺序不同最后的效果亦不同, 一个旋转变换跟在一个平移变换后与这个平移变换跟在旋转变换后比较, 其产生的效果是迥然不同的。图3 和图4 显示了这种不同的结果。

    (2 ) 最近一个父节点的变换首先产生作用, 然后更上面一层的父节点的变换产生作用, 如此往上一层接着一层进行, 详细见第四章“变换的累加”一节。

    (3 ) 在一个变换节点中的各种变换的执行次序是固定的———首先是比例变换, 其次是旋转变换, 最后是平移变换。如果你希望以不同的顺序执行这些变换, 就必须以嵌套变换的方式来实现。

    如果你想对综合型变换的作用有一个直观感觉, 最好的办法是把它们写成一串嵌套图5 先平移后旋转变换的形式, 一点一点地改变它们的值和次序来观察有什么不同的效果。

    如果你在实际开发时遇到物体位置放错了或旋转错了等问题, 那么可以把Transform节点中的每个变换(平移、旋转、比例变换) 分离出来分别作为几个Transform 的节点, 并尝试改变它们的顺序, 这样就能很容易地找出错误所在。

    图3 所示是chacmool 先旋转后平移的情况。

VRML2.0教程5:变换节点先旋转后平移
图3 先旋转后平移

    [例3] 先旋转后平移。

    Transform { translation 6 5 .3 0 rotation 0 1 0 1 .8
    children [
    Inline { url "chacmool .wrl"}
    ]
   }

    图4  所示是chacmool 先平移后做旋转的情况。

VRML2.0教程5:变换节点先平移后旋转

    [例5] 先平移后旋转。

    Transfrom { rotation 0 1 0 1 .8
    children [
    Transform {
    Translation 6 5 .3 0
    children [
    Inline { url "chacmool .wrl"}
    ]
    }
    ]
    }

  • 暂无资料
  • 暂无资料
  • 暂无资料
  • 暂无资料
  • 暂无资料