- VRML虚拟现实应用技术
- 张德丰 周灵编著
- 2975字
- 2020-08-26 16:23:17
1.6.4 VRML的节点和域
节点是VRML文件中最基本的单位,节点是VRML的精髓与核心。每个节点还包含子节点和描述节点属性的“域名”或“域值”,在高级语言中称为变量、数组等,在数据库中常称为字段。
单一节点的语法定义如下:
节点名{ 域名 域值 #域值类型说明 ... .... }
节点由节点名、一对花括号组成,花括号内又包括节点的域名、域值及域值类型说明等。
下面以锥体节点Cone为例来加以说明。
Cone{ 外 #Cone节点(注释) bottomRadius 1.0 #field SFFloat单值浮点域 height 2.0 #field SFFloat单值浮点域 side TRUE #field SFFloat单值浮点域 bottom TRUE #field SFBool单值布尔域 }
其中,“#”为注释语句。
节点的作用是描述空间造型(对象)及其属性。“节点”可以理解为高级语言中的函数、子程序、结构体及可视化编程语言中的类和对象等。
VRML节点的层次关系分为父节点和子节点。父节点即根节点。在一个嵌套节点中,最顶层的节点就是父节点,由它派生的节点称为子节点。例如,Group编组节点中,有一个域children[],children就是子节点,而Group就是父节点,如图1-9所示。
图1-9 节点层次关系图
1.节点的域名和域值
节点中包括“域”、“域值”或子节点。根据语法结构的要求,节点之间可以并列或层层嵌套使用。不同作用的节点有着不同的语法结构,父节点包括“域”、“域值”或子节点,子节点中也包含“域”、“域值”等。
域分为两种:一种称为“域”;另一种称为“暴露域”。“域”相当于高级语言中的普通变量,而“暴露域”相当于C语言中的外部变量,相当于可视编程语言VC++中的公共变量或公共函数。
域包含有各种类型的数据,可以是单值的或多值的。“域”可理解为高级语言中的“变量”、“数组”及C语言中的“结构体变量”或数据库中的“字段”等。
每一个节点都是由一个域多个域组成的,域即“属性”,描述空间造型尺寸。每个域有相应的“域值”,这些域值指定了一个场景的尺寸、大小和颜色等特征。“域值”相当于高级语言中的变量取值或取值范围,也相当于数据库中的字段取值。
同一节点中的域遵循如下规则。
● 同一节点中的各个域之间无先后次序之分。
● 同一节点中的各个域均有自己相应的默认值。
● 不同的域对应不同的域值类型。
域名:域的标识符叫域名。在节点作用域的范围内,域名是唯一的,也是VRML的保留字或关键字。
常见的两类域名的域值类型前缀如下。
● 单值类型的域名,以“SF”开始,只包含单值。单值可以是一个独立的数,也可以是一个向量、颜色的几个数等,甚至可以是图像数据。
● 还有一种多值域名以“MF”开始,它包含多个值,所以称为多值域名。
在VRML文件中,表示多域值的方法是:整个用方括号括起来的一系列用逗号和空格间隔开的单值。如果一个多值域不包含任何值,则只标出方括号“[]”。如果一个多值域恰好只包含一个数,可以不写括号,直接写该值。
例如,以“MF”开始的多域值的表示如下:
skyColor[ 0.2 1.0 1.0 0.6 0.8 1.0 1.0 0.2 0.5 ]
在VRML文件中,各个节点语法的各种“域值类型”详细说明为:单值域类型名用“SF”表示,多值域名称用“MF”表示。
1)SFBool
SFBool域是一个单值布尔量,常用于开启或关闭一个节点的性质特征。SFBool域输出事件的默认值为TRUE(真),否则为FALSE(假)。
2)SFFlot和MFFlot
SFFlot域是单值单精度浮点数,含有一个ANSIC格式的单精度浮点数。SFFlot域输出事件的初始值是0.0。
MFFlot域是多值单精度浮点数,含有零个域多个ANSIC格式的单精度浮点数。MFFlot域输出事件的初始值是[]。
3)SFInt32和MFInt32
SFInt32域是一个单值含有32位的整数。一个SFInt32值由一个十进制或十六进制格式(以OX开头)的整数构成。SFInt32域输出事件的初始值为0。
MFInt32域是一个多值域,由任意数量的以逗号或空格分隔的整数组成。MFInt32域输出事件的初始值为[]。
4)SFString和MFString
SFString域包含一个字符串。SFString的域值含有双引号括起来的字符串。任何字符都可在引号中出现。为了在字符中使用双引号,在它之前加一个反斜杆“\”,为了在字符串中使用反斜杆,可连续使用两个反斜杆“\\”。SFString域输出事件的初始值为“”。
MFString域是一个含有零个或多个单值的多值域,每个单值都和SFString值的格式相同。MFString域输出事件的初始值为[]。
5)SFVect2f和MFVec2f
SFVect2f域定义了一个二维向量。SFVect2f的域值由两个分隔的浮点数组成。SFVect2f域输出事件的初始值为(0 0)。
MFVec2f域是一个包含任意数量的二维向量的多值域。MFVec2f域输出事件的初始值为[]。
6)SFVec3f和MFVec3f
SFVec3f域定义了一个三维向量空间。一个SFVec3f域值包含有3个浮点数,数与数之间用空格分隔。该值表示从原点到给定点的向量。SFVec3f域输出事件的初始值为(0 0 0)。
MFVec3f域是一个包含任意数量的三维向量的多值域。MFVec3f域输出事件的初始值为[]。
7)SFTime和MFTime
SFTime域含有一个单独的时间值。每个时间值是一个ANSIC格式的双精度浮点数,表示从1970年1月1日(GMT,格林尼治平均时)子夜开始计时,延续当前时间的秒数。SFTime域输出事件的初始值为-1。
MFTime域包含任意数量的时间值。
8)SFRotation和MFRotation
SFRotation域规定了一个绕任意轴的任意角度的旋转。SFRotation的域值含有4个浮点数,各数之间用空格分隔,前3个数表示旋转轴,第4个数表示围绕该轴旋转多少弧度。SFRotation域输出事件的初始值为(0 0 1 0)。
MFRotation域可包含任意数量的这类旋转值。MFRotation域输出事件的初始值为[]。
9)SFImage
SFImage域含有非压缩的二维彩色图像或灰度图像。SFImage域首先列出3个整数值,前两个整数表示图像的宽度和高度,第三个整数表示构成图像格式的元素个数,随后按“宽度×高度”的格式列出一组十六进制数,数与数之间用空格或逗号分隔,每一个十六进制数表示图像中一个单独的像素,像素的排列按从左到右、从下到上的顺序。第一个十六进制数描述一个图像左下角的像素,最后一个则描述右上角的像素。SFImage域输出事件的初始值为(0 0 0)。
10)SFColor和MFColor
SFColor域是只有一个颜色的单值域。SFColor的域值由一组3 个浮点数组成,每个数都在0.1~1.0范围内,分别表示构成颜色的红、绿、蓝3个分量。SFColor域输出事件的初始值是(0 0 0)。
MFColor域是一个多值域,包含任意数量的RGB颜色值。MFColor域输出事件的初始值是[]。
11)SFNode和MFNode
SFNode域含有一个单节点,必须按标准节点语法写成。一个SFNode域允许包含一个关键字,表示不包含任何节点。SFNode域输出事件的初始值为NULL。
MFNode域包含任意数量的节点。MFNode域输出事件的初始值为[]。在编写VRML文件、节点和域时,特别要注意大小写,因为VRML源文件对大小写很敏感,即VRML源文件要严格区分大小写。
2.节点名的重定义和重用
在VRML虚拟空间的场景中,为了减少VRML源代码的编写量,提高VRML编程效率,对重复的造型或多个同样的造型在场景中多次出现时,可通过定义这个造型节点,然后再重复调用该定义的节点。
1)重定义节点:DEF
在VRML中,使用DEF命令可为空间的造型重新定义节点,以便在以后的节点重用或调用时引用,从而使程序编写简练,减少程序代码的重复和冗余,而且具有层次清晰、结构合理的软件工程设计的风格。
重定义节点的语法定义如下:
DEF 节点名 节点类型 {}
其中,DEF是重定义节点的VRML关键字,节点名可以由任何字母和数字及下划线组成,但不要使用与VRML保留字或关键字相重复的节点名。
在VRML中,对节点名的规定是:节点名区分大小写,命名不能以数字开头,不能带有非印刷的ASCII字符,不能包括单引号、双引号、数字运算或英镑符号等。
2)重用节点:USE
当重定义一个节点名之后,便可在VRML源程序中重复使用该节点名,即可以一次或多次调用该节点名。
重用节点的语法定义如下:
USE 节点名
其中,USE是VRML的保留字,节点名就是前面用DEF重定义的节点名。
节点重新定义和重复引用的文件结构形式如下:
VRML V2.0 utf8 #VRML文件在第一行必须有的头文件 节点名{ #VRML中各种类型的"节点" 域 域值 ... ... } DEF 节点1 节点类型{ #定义节点 域 域值 #相应"节点"的"域"和"域值" ... ... } USE 节点名1 #重用节点语法