Extensible 3D (X3D)
Part 1: Architecture and base components

23 Navigation component

--- X3D separator bar ---

cube 23.1 Introduction

23.1.1 Name

The name of this component is "Navigation". This name shall be used when referring to this component in the COMPONENT statement (see 7.2.5.4 Component statement).

23.1.2 Overview

This clause describes the Navigation component of this part of ISO/IEC 19775. Table 23.1 provides links to the major topics in this clause.

Table 23.1 — Topics

cube 23.2 概述

23.2.1 导航概述

导航(navigation)是指用户通过一个或多个输入设备和 X3D 浏览器交互以改变当前呈现的视图的能力。并不是所有的概貌(profiles)都要求支持导航。

可以认为每个 X3D 场景中都包含一个 视点(viewpoint),场景中的视点都将通过这个视点呈现给观测者。导航允许用户改变这个视点相对场景的位置和方向,因此用户可以在场景中移动并检视场景中的对象。

NavigationInfo 节点(参见 23.3.4 NavigationInfo)指定了希望的导航行为的特性,但实际的用户界面是基于浏览器的。Viewpoint 节点(参见 23.3.5 Viewpoint)指定了场景中的关键位置和方向,用户可以通过 SAI 服务或浏览器特定的用户界面转换到这些点。

23.2.2 导航范例模式

浏览器可以允许用户使用一种导航范例模式来修改观测器在虚拟场景中的位置和方向。基于虚拟场景的种类和用户希望完成的任务,可能存在多种不同的导航范例模式。举例来说,行走范例模式将适用于建筑漫游的应用,飞行范例模式可能适用于星际空间探索的应用。当场景中包含一个或多个对象时,如果用户希望从不同的角度和距离观察这些对象时,可以用使用 X3D 中常用的检视模式。

NavigationInfo 节点有一个 type(类型)域用来指定适用于此场景的导航范例模式。提供完成此导航的实际用户界面将是基于浏览器的。细节见 23.3.4 NavigationInfo

23.2.3 观察模式

浏览器控制观测者在场景中的位置和方向,这些控制将基于用户输入(使用浏览器提供的导航范例模式)和当前绑定的 Viewpoint 节点(以及其坐标系)。X3D 场景作者可以在场景中放置任意数量的视点,这些视点可以是场景中重要的用户希望查看的地方。每一个视点将由一个 Viewpoint 节点描述。Viewpoint 将存在其父层级的坐标系中,视点设置的改变或这个坐标系的改变都会影响到浏览器呈现场景的视图。一次将只有一个视点被绑定。Viewpoint 节点运作的细节见 7.2.2 可绑定子节点(Bindable children nodes)23.3.5 Viewpoint

导航执行是相对 Viewpoint 节点的定位的,但并不影响 Viewpoint 节点的位置和方向值。观测者的位置可以使用 ProximitySensor 节点(见 22.4.1 ProximitySensor)查出。

23.2.4 碰撞检测和地形随动

在需要碰撞检测的概貌中,NavigationInfo 类型 WALK、FLY、NONE 将严格检测以阻止导航或/和调节视点位置时用户替身和场景中其它对象间的发生碰撞。然而 NavigationInfo 类型 ANY、EXAMINE 则可以在导航时临时禁止碰撞检测,但这种类型下一般场景操作时不应禁止碰撞检测。不同的导航类型的的细节见 23.3.4 NavigationInfo

Collision 节点可以用来在观测者和对象碰撞时产生事件,并可以指定某些物体不参与碰撞检测。对象之间碰撞在规格中不规定。

NavigationInfo 节点可以用来指定包含浏览器导航范例模式的参数。这些参数将决定观测者替身的尺寸和形状,以决定替身和对象在多近距离之内将考虑为发生碰撞。也用来把替身维持在一个高于地面的一定距离的高度上,以执行 地形随动(terrain following)。还将决定观测者前面的物体低于多少高度时,观测者将自动跨上去而避免碰撞。

cube 23.3 节点参考

23.3.1 Billboard(布告牌)

Billboard : X3DGroupingNode {
  MFNode  [in]     addChildren             [X3DChildNode]
  MFNode  [in]     removeChildren          [X3DChildNode]
  SFVec3f [in,out] axisOfRotation 0 1 0    (-∞,∞)
  MFNode  [in,out] children       []       [X3DChildNode]
  SFNode  [in,out] metadata       NULL     [X3DMetadataObject]
  SFVec3f []       bboxCenter     0 0 0    (-∞,∞)
  SFVec3f []       bboxSize       -1 -1 -1 [0,∞) or −1 −1 −1
}

Billboard(布告牌)节点是一个组节点,这个组节点将不断地修改自身的坐标系以使其局部 Z 轴将始终指向观测者。Billboard 的子节点可以是任何的子节点类型。

axisOfRotation(旋转轴)域指定了将在哪个轴上执行旋转。此轴将定义在局部坐标系中。

axisOfRotation 域不为 (0, 0, 0) 时,以下的步骤描述了如何把一个布告牌旋转以使其面对观测者:

  1. 计算从 Billboard 节点原点到观测者位置的矢量。此矢量称为“布告牌至观测者”(billboard-to-viewer) 矢量。
  2. 计算由 axisOfRotation 和“布告牌至观测者”矢量定义的平面。
  3. axisOfRotation 为轴,把布告牌的局部 Z 轴旋转到上一步(b)计算出的平面中。

当 axisOfRotation 域被设置为 (0, 0, 0) 时表示特殊的 对齐观测者(viewer-alignment)的案例。在这种情况下, 对象将旋转以保持布告牌的局部 Y 轴始终平行于观测者的 Y 轴。设置 axisOfRotation 为 (0, 0, 0) 时将区别处理这种特殊情况。以下的步骤描述了如何把布告牌的 Y 轴和观测者的 Y 轴对齐:

  1. 计算“布告牌至观测者”矢量。
  2. 旋转布告牌的 Z 轴,使其和“布告牌至观测者”矢量共线并指向观测者的位置。
  3. 旋转布告牌的 Y 轴以使其和观测者的 Y 轴平行且方向相同。

如果 axisOfRotation 和“布告牌至观测者”矢量重合时将不能建立上述平面,则旋转的结果未定义。例如,如果 axisOfRotation 设置为 (0,1,0)(即 Y 轴)时观测者从 Y 轴上方飞过且沿 Y 轴向下看时,结果是未定义的。

Billboard 节点的多个实例(DEF/USE)将需要按这种方式运作:每个实例都在各自的坐标系中转动以面向观测者。

10.2.1 组和子节点类型 Grouping and children node types 中提供了关于 children 域、addChildren 域、removeChildren 域的描述。

bboxCenter 域和 bboxSize 域指定了一个包裹 Billboard 节点的子节点的边界盒。这是一个可以用作优化目的的提示。如果指定的边界盒在某一时间中比其子节点的实际边界盒小,则结果不确定。缺省的 bboxSize 值 (-1, -1, -1) 意味着没有指定边界盒,如果需要,边界盒将由浏览器计算。关于 bboxCenter 域和 bboxSize 域的详细描述包括在 10.2.2 边界盒 Bounding boxes 中。

23.3.2 Collision(碰撞)

Collision : X3DGroupingNode, X3DSensorNode {
  MFNode  [in]     addChildren             [X3DChildNode]
  MFNode  [in]     removeChildren          [X3DChildNode]
  SFBool  [in,out] enabled
  MFNode  [in,out] children       []       [X3DChildNode]
  SFNode  [in,out] metadata       NULL     [X3DMetadataObject]
  SFTime  [out]    collideTime
  SFBool  [out]    isActive
  SFVec3f []       bboxCenter     0 0 0    (-∞,∞)
  SFVec3f []       bboxSize       -1 -1 -1 [0,∞) or −1 −1 −1
  SFNode  []       proxy          NULL     [X3DChildNode]
}

Collision(碰撞)节点是一个组节点,用以指定其子(及其后代)的碰撞检测属性,还用以指定在检测碰撞时用以替代其子的代理对象,Collision 节点在 Collision 的几何体或代理和替身发生碰撞时将发送事件。缺省情况下,除了 IndexedLineSetPointSet 外的场景中的所有的几何体节点都可以和观测者发生碰撞。浏览器应检测替身(见 23.3.4 NavigationInfo)和场景中几何体的碰撞并阻止替身“进入”几何体。碰撞检测的一般信息见 23.2.4 碰撞检测和地形随动

如果在 X3D 文件中没有指定 Collision 节点,浏览器应在导航时检测替身和所有对象之间的碰撞。

10.2.1 组和子节点类型 Grouping and children node types 中提供了关于 children 域、addChildren 域、removeChildren 域的描述。

Collision 节点的 collide(碰撞)域用来激活或禁止碰撞检测。如果 collide 被设置为 FALSE,Collision 节点的子及其后来即使任被绘制出来也不进行碰撞检测,不进行碰撞检测的还包括其后代的 collide 设置为 TRUE Collision 节点(即设置 collideFALSE 将关闭所有下级的节点的碰撞检测)。

collide 域设置为 TRUE 的 Collision 节点将检测和其后代几何体(或代理)最近的碰撞。当检测到碰撞时,被碰撞到的 Collision 节点通过其 collideTime 域发送碰撞的时间。如果一个 Collision 节点包含的子、后代、或代理(见下文)也有 Collision 节点,则所有的 Collision 节点同时检测到碰撞发生时,将同时发送 collideTime 事件。在 Collision 从 X3D 文件中被读取或被插入到当前的变换层级中时,如果此时替身和可碰撞几何体发生碰撞,则应生成 collideTime 事件。

bboxCenter 域和 bboxSize 域指定了一个包裹 Collision 节点的子节点的边界盒。这是一个可以用作优化目的的提示。如果指定的边界盒在某一时间中比其子节点的实际边界盒小,则结果不确定。缺省的 bboxSize 值 (-1, -1, -1) 意味着没有指定边界盒,如果需要,边界盒将由浏览器计算。关于 bboxCenter 域和 bboxSize 域的详细描述包括在 10.2.2 边界盒 Bounding boxes 中。

proxy(代理)域中定义了碰撞代理,碰撞代理可以是 10.2.1 组和子节点类型 Grouping and children node types 中描述的任何合法子节点,碰撞代理将替代 Collision 节点的子来进行碰撞检测。此代理只用于碰撞检测;而并不被绘制出来。

如果 collide 域值为 TRUEproxy 域为 non-NULL(非空proxy 域将定义执行碰撞检测用的场景。如果 proxy 值为 NULL(空),碰撞检测将根据 Collision 节点的 children 来执行。

如果指定了 proxy,在碰撞检测时将忽略 Collision 节点的任何子及其后代。如果 children 为空、collideTRUE、且指定了 proxy,碰撞检测将根据代理执行带不显示任何物体。这种方法将支持不可见的碰撞对象。

替身(见 23.3.4 NavigationInfo)和可碰撞 Collision 节点的子或代理发生接触时,collideTime(碰撞时间)域生成事件。理想的执行将计算确切的碰撞时间。执行时可通过对用户和可碰撞对象的采样来逼近理想状态。NavigationInfo 节点中包含了控制替身尺寸参数的额外信息。

23.3.3 LOD(细节层次)

LOD : X3DGroupingNode {
  MFNode  [in]     addChildren             [X3DChildNode]
  MFNode  [in]     removeChildren          [X3DChildNode]
  MFNode  [in,out] children       []       [X3DChildNode]
  SFNode  [in,out] metadata       NULL     [X3DMetadataObject]
  SFVec3f []       bboxCenter     0 0 0    (-∞,∞)
  SFVec3f []       bboxSize       -1 -1 -1 [0,∞) or −1 −1 −1
  SFVec3f []       center         0 0 0    (-∞,∞)
  MFFloat []       range          []       [0,∞) or -1 
}

LOD(细节层次)节点为一个给定的对象指定了不同层次的细节度(levels of detail)或复杂度,根据用户和对象之间的距离,LOD 节点将提示浏览器提示以从这些不同的层次中选择一个对象的适当版本。其 children 域包含了一个用来表示同一个对象或一个对象的不同细节层次的节点的列表,这些节点将按照最高层到最低层的顺序在列表中排出。range(范围)域指定了理想化的在不同层次间切换时的距离。然而浏览器为了提供更好的性能也允许忽略层次切换的距离。10.2.1 组和子节点类型 Grouping and children node types 中包含了可用作 children 域中值的合法的节点类型。

center 域是一个局部坐标系中的偏移,用来指定距离计算时 LOD 节点的中心。

children 域中的节点的数量应比 range 域中的值的数量多一个(例如 N 个 range 值对应 N+1 children 节点)。range 域包含了应大于 0 的单调渐增的值。为了计算应显示哪个层次,首先将把观测者的位置变换到 LOD 节点的局部坐标系(并包括任何的缩放变换)中,并计算这个位置和 LOD 节点的 center 中心点之间的距离。然后 LOD 节点将按照步长函数 function L(d) 对给定的 d(这里 d 代表观测者位置到 LOD 节点中心的距离)计算出将被选定的层次。

如设有 n 个范围值,并以 R0R1R2、...、Rn-1 把区间 (0, +infinity) 划分为 (0, R0)、[R0R1)... 、 [Rn-1, +infinity) 这样的 n+1 个子区间。同时设 n 个层次 L0L1L2、...、Ln-1 为阶梯函数 L(d) 的值。则对于给定的距离 d,层次 L(d), 将按以下定义:

    L(d) = L0,   if d < R0,
         = Li+1, if Ri ≤ d < Ri+1, for −1 < i < n−1,
         = Ln−1, if d ≥ Rn−1.

children 域中的第 L(d)th 个节点将显示出来。

指定过少的层次将导致最后一个级别被重复用作为最低级细节层次。如果指定的层次数比范围值多,多余的层次将被忽略。空的范围域将不遵守这个规则。这种情况下将用作为一个提示,浏览器可以自动选择层次以维持一个恒定的帧数率。range 域中的每个值应大于前一个值。

LOD 节点在场景图中将由上而下的计算。只有当前选定的 children 节点的后代才被渲染。不管 LOD 节点的哪个 level 被激活,LOD 之下的所有子节点都持续接受和发送事件。例如,如果一个 LOD 节点的非活动层次中包含一个 TimeSensor 节点,则这个 TimeSensor 不管 LOD 的选择状态如何都将发送事件。

bboxCenter 域和 bboxSize 域指定了一个包裹 LOD 节点的子节点的边界盒。这是一个可以用作优化目的的提示。如果指定的边界盒在某一时间中比其子节点的实际边界盒小,则结果不确定。缺省的 bboxSize 值 (-1, -1, -1) 意味着没有指定边界盒,如果需要,边界盒将由浏览器计算。关于 bboxCenter 域和 bboxSize 域的详细描述包括在 10.2.2 边界盒 Bounding boxes 中。

23.3.4 NavigationInfo(导航信息)

NavigationInfo : X3DBindableNode {
  SFBool   [in]     set_bind
  MFFloat  [in,out] avatarSize      [0.25 1.6 0.75] [0,∞)
  SFBool   [in,out] headlight       TRUE
  SFNode   [in,out] metadata        NULL            [X3DMetadataObject]
  SFFloat  [in,out] speed           1.0             [0,∞)
  MFString [in,out] transitionType  [LINEAR]        ["TELEPORT"
                                                     "LINEAR"
                                                     "ANIMATE"]
  MFString [in,out] type            ["EXAMINE" "ANY"]
  SFFloat  [in,out] visibilityLimit 0.0             [0,∞)
  SFTime   [out]    bindTime
  SFBool   [out]    isBound
}

NavigationInfo(导航信息)节点包含了描述观测者替身和观测模式物理特性的信息。NavigationInfo 节点是可绑定子节点(见 7.2.2 可绑定子节点 Bindable children nodes),因此浏览器中将有一个 NavigationInfo 节点堆栈,堆栈中最顶端的 NavigationInfo 节点就是当前绑定的 NavigationInfo 节点。当前的 NavigationInfo 节点被看作当前 Viewpoint 节点的子,而不管其最初在 X3D 文件中的位置。一旦更换了当前的 Viewpoint 节点,浏览器应把当前的 Viewpoint 节点重新设为当前的 NavigationInfo 节点的夫。

如果向一个 NavigationInfo 节点的 set_bind 域发送 TRUE 值,就可以把这个节点推到 NavigationInfo 节点堆栈顶部。当一个 NavigationInfo 节点被绑定时,浏览器应使用此 NavigationInfo 节点的域来设置其用户界面的导航控制,此 NavigationInfo 节点从概念上说将重新变为当前绑定的 Viewpoint 节点的子。随后的针对当前 Viewpoint 节点坐标系的缩放变换(例如对任何其祖先变换的缩放)将自动改变节点值在浏览器中使用的效果(见下文)。发送到其 set_bind 域的 FALSE 值将把这个 NavigationInfo 节点从堆栈顶部移去,结果将生成一个 isBound FALSE 事件,同时把堆栈中的下一项弹出并使其成为当前 Viewpoint 节点的子。绑定堆栈的更多细节见 7.2.2 可绑定子节点 Bindable children nodes

type(类型)域指定了一个排序的导航范例模式的列表,这个列表将用来指定一系列导航类型以及初始的导航类型。当前绑定的 NavigationInfo 节点的导航类型将决定将决定浏览器用户界面的功能。例如,如果当前绑定的 NavigationInfo 节点的 type 值为 "WALK",浏览器应呈现一种 WALK 用户导航界面模式(WALK(行走模式)的描述见下文)。浏览器至少应 能识别以下的导航类型:"ANY"、"WALK"、"EXAMINE"、"FLY"、"LOOKAT"、"NONE",并按 表 23.2 中的规定支持这些导航类型。

如果当前绑定的 NavigationInfo 的 type 的列表中没有出现 "ANY"(任意),则浏览器的用户导航界面将被严格限制为列表中指定的可识别导航类型。这种情况下,浏览器呈现的用户界面应不允许用户把导航类型更改为列表中未指定的类型的。然而如果 type 域中的任一值为 "ANY",则浏览器就可以提供任何类型的导航界面,并允许用户动态地改变导航类型。列表中第一个可识别的类型应设为浏览器用户界面最初呈现的导航类型。

ANY 导航指定浏览器可以选择最适合场景内容的导航范例模式,并提供一个允许用户动态改变导航范例模式的用户界面。如果当前绑定的 NavigationInfo 的 type 值为 "ANY" 且由 Anchor 节点(见 9.4.1 Anchor)或 loadURL() 脚本方法(见 2.[I19775-2])触发了一个 Viewpoint 转换(见 23.3.5 Viewpoint),则结果未定义。

WALK(行走)导航将用于步行方式探索虚拟场景,或用于乘坐行驶或悬浮在地面上的交通工具来探索虚拟场景。强烈推荐 WALK 导航把向上矢量定义为 +Y 方向并提供某种形式地形随动和重力,以能产生一种行走或驾驶的感觉。如果被绑定的 NavigationInfo 的 type 为 "WALK",则浏览器应严格地支持碰撞检测。(见 23.3.2 Collision)。

FLY(飞行)导航和 WALK 相似,除了地形随动和重力可以被禁止或忽略。仍然应需要某种形式的“向上”的概念。如果被绑定的 NavigationInfo 的 type 为 "FLY",则浏览器应严格地支持碰撞检测。(见 23.3.2 Collision)。

LOOKAT(注视)导航通过航行到一个特定对象来探索场景。通过 LOOKAT 选定一个对象将:

  1. 把视点直接移动到离选定对象的边界盒中心的某个方便查看此对象的距离,并把视点方向设置为对准此对象的近似“中心”;
  2. 把当前绑定的 Viewpoint 节点的旋转中心设置到选定的对象的近似“中心”。

EXAMINE(检视)导航用于查看单个对象。EXAMINE 应提供使用户视点围绕旋转中心旋转的功能,以回应用户的动作。使视点绕对象移动并决定视点方向的旋转中心将在当前绑定的 Viewpoint 节点(见 23.3.5 Viewpoint)中指定。浏览器应严格支持碰撞检测(见 Collision)并应在 EXAMINE 操作时能触发退出(exit)和进入(enter)事件。

EXAMINE 结合的 LOOKAT 导航将用于导航到特定对象并能便捷地导航到不同方向以检视对象,并以此方式探索场景。如果内容中同时指定了 LOOKAT 类型和 EXAMINE 类型,任何 LOOKAT 操作应改变后续的 EXAMINE 操作的旋转中心。

NONE(无)导航将禁止或去除任何特定浏览器的用户导航界面,以限制用户只能使用场景中提供的导航机制,例如只能使用 Anchor 节点或包含 loadURL()的脚本。

如果 NavigationInfo 类型为 "WALK"、"FLY"、"EXAMINE"、"NONE"或是这些类型的组合(例如,"ANY" 不在列表中),则由 Anchor 节点(见 9.4.1 Anchor)或 loadURL()脚本方法(见 2.[I19775-2])触发的 Viewpoint 转换(见 23.3.5 Viewpoint)应执行由旧 Viewpoint 跳转到新的 Viewpoint 的转换效果,此时将触发退出和进入事件,除此外跳转执行将不再触发其它事件。

浏览器可以建立浏览器特定的导航类型扩展。推荐在扩展的 type 名称中包括一个唯一的后缀(例如 HELICOPTER_mydomain.com)以防止冲突。对于扩展导航类型,由 Anchor 节点(见 9.4.1 Anchor)或 loadURL()脚本方法(见 2.[I19775-2])触发的 Viewpoint 转换方式未定义。如果浏览器一种类型都不能识别,则使用缺省的 "ANY"。这些字符串值是大小写敏感的("any" 和 "ANY" 是)不同的)。

transitionType(转换类型)域指定了一个排序的转换范例模式的列表,这个列表决定了当一个新的 Viewpoint 节点被绑定时浏览器将以何种方式移动观测者。浏览器至少应识别并支持以下的转换导航类型:"TELEPORT"、"LINEAR"、"ANIMATE"。对于 "TELEPORT(空间传输)",应立即转换转换到新位置,转换过程将不插入位置过渡。对于值 "LINEAR(线性)",浏览器应在位置和方向值上执行一个线性插值。对于值 "ANIMATE(动画)",浏览器应执行一个浏览器特定的动画效果。如果值没能被识别出来或此域为空,则应使用缺省的 "ANIMATE" 值。这个域将应用于任何位置和方向之间的视点转换,包括 Viewpoint 绑定和 LOOKAT 导航类型下的转换。

speed(速度)域以米/每秒为单位用户在场景中漫游的速度。由于浏览器也可以提供把漫游速度加快或减慢的机制,所以此域指定的是缺省的速度,也就是 NavigationInfo 节点刚被绑定时观测者的平均速度。如果 NavigationInfo 的 type 值为 EXAMINE,则 speed 应不影响视图的旋转速度。当前绑定 Viewpoint 节点(见上文)变换层级中的缩放将缩放 speed 速度值;父平移和旋转变换对 speed 速度值没有影响。速度值应为非负值。0 速度值表示替身的位置是固定的,但替身的方向和视野仍然可以改变。。如果导航 type 值为 "NONE",则 speed 域不产生效果。

avatarSize(替身尺寸)域 为碰撞检测和地形随动的目的指定了用户在场景中的物理尺寸。这是一个用来指定多个尺寸的多值域。第一个值应为任何碰撞检测体(由 Collision 节点指定)和用户位置之间检测为碰撞前的允许距离。第二个值为浏览器应把观测器维持在地形之上的高度。第三个值为浏览者可以跨越过的最高的对象的高度。这允许设定所有浏览器中观测者可以攀登的楼梯尺寸。当前绑定 Viewpoint 节点的变换层级的缩放将缩放 avatarSize 值。平移和旋转对 avatarSize 值没有影响。

为了地形随动的目的,浏览器应维持一个向下(down)的方向(下矢量),因为重力是以向下失量的方式应用的。这个下矢量应顺着当前绑定 Viewpoint 节点局部坐标系(例如 Viewpoint 节点的祖先的变换的累积,但不包括此 Viewpoint 节点的 orientation 域)的-Y 轴。

超出可视范围限制(visibilityLimit)的几何体将不被渲染。0.0 值表示一个无限远的可视范围限制。visibilityLimit 域限制为大于或等于 0。

speedavatarSizevisibilityLimit 值都能由应用到当前绑定的 Viewpoint 节点的变换来缩放。如果没有当前绑定的 Viewpoint 节点,这些值将被解释为位于世界坐标系(world coordinate system)中。这将允许这些值在绑定到一个应用了缩放变换的 Viewpoint 节点进行自动调节,而不再需要绑定到一个新的 NavigationInfo 节点以进行调节。如果应用到 Viewpoint 节点的缩放是非一致缩放,则结果未定义。

headlight(头灯)域指定浏览器是否应打开头灯。头灯是一个一直指向用户观看方向的定向灯光。把这个域设置为 TRUE 将允许浏览器提供一盏头灯,也可能可以通过用户界面来打开或关闭头灯。支持预渲染光照计算(例如 辐射度方案)可以关闭头灯。头灯的参数应为 intensity = 1、color = (1 1 1)、ambientIntensity = 0.0、direction = (0 0 −1)。

推荐把近端裁切平面设置为 avatarSize 域中指定的碰撞半径的一半(把近端平面设置为此值 可以防止恰好位于碰撞检测容积外侧对象的过渡裁切,也为内容作者提供了一个碰撞检测容积内用来放置保持和观测者相对固定的几何体的的范围)这样几何体应不被 碰撞检测容积之外的几何体阻碍。

23.3.5 Viewpoint(视点)

Viewpoint : X3DBindableNode { 
  SFBool     [in]     set_bind
  SFVec3f    [in,out] centerOfRotation 0 0 0   (-∞,∞)
  SFString   [in,out] description      ""
  SFFloat    [in,out] fieldOfView      π/4     (0,π)
  SFBool     [in,out] jump             TRUE
  SFNode     [in,out] metadata         NULL    [X3DMetadataObject]
  SFRotation [in,out] orientation      0 0 1 0 [-1,1],(-∞,∞)
  SFVec3f    [in,out] position         0 0 10  (-∞,∞)
  SFTime     [out]    bindTime
  SFBool     [out]    isBound
}

Viewpoint(视点)节点定义了一个在局部坐标系中指定的位置,用户可以在此位置观看场景。Viewpoint 节点是可绑定子节点(见 7.2.2 可绑定子节点 Bindable children nodes),因此浏览器中将有一个 Viewpoint 节点堆栈,堆栈中最顶端的  Viewpoint 节点就是当前活动的 Viewpoint 节点。如果向其 set_bind 域发送 TRUE 值,就可以把这个 Viewpoint 节点推到堆栈顶部并激活。从概念上看,当一个 Viewpoint 节点位于堆栈顶端时,用户视图重新成为此 Viewpoint 节点的子。此 Viewpoint 节点坐标系的所有后来的改变都将使用户视图改变(例如改变 Viewpoint 节点 position 域和 orientation 域,或改变此 Viewpoint 节点的祖先变换节点)。发送到其 set_bind 域的 FALSE 值,就可以把这个 Viewpoint 节点从堆栈顶部移去,并生成一个 isBound FALSE 事件和一个 bindTime 事件。如果移去的 Viewpoint 节点位于视点堆栈的顶端,则用户视图重新成为堆栈中下个项的子。绑定堆栈的更多细节见 7.2.2 可绑定子节点 Bindable children nodes。当一个 Viewpoint 节点被移到堆栈顶端时,原来在堆栈顶端的 Viewpoint 节点会在堆栈中向下压并发送一个 isBound FALSE 事件。

通过对绑定用户到一个 Viewpoint 节点并对此 Viewpoint 节点或其上层变换施加动画,作者能够自动地移动用户视图。即使 Viewpoint 节点或其祖先变换正进行动画,浏览器也应允许对用户视图进行相对此 Viewpoint 节点(及其上层变换)定义的坐标系的导航。

当 Viewpoint 节点被绑定或解除绑定时,bindTime 域发送此刻的时间。这可能发生在:

  1. 载入过程中;
  2. 一个 set_bind 事件被发送到 Viewpoint 节点;
  3. 通过以下描述的界面把浏览器绑定到 Viewpoint 节点。

Viewpoint 节点的 position 域和 orientation 域指定了在局部坐标系中的相对位置。Position 是相对坐标系原点 (0,0,0) 的位置,同时 orientation 指定了一个相对缺省方向的相对旋转。在缺省位置和方向下,+X 轴为右方向,+Y 轴为上方向,观测者在 Z 轴上沿 -Z 轴方向看向原点。Viewpoint 节点受变换层级的影响。

需要定义下矢量(例如地形随动)的导航类型(见 23.3.4 NavigationInfo)应使用当前绑定的 Viewpoint 节点的局部坐标系的 -Y 轴作为其下矢量。同样地,需要定义上矢量的导航类型应使用当前绑定的 Viewpoint 节点的局部坐标系的 +Y 轴作为其上矢量。Viewpoint 节点的 orientation 域并不影响下矢量或上矢量的定义。这允许作者把观看方向和重力方向分离开。

jump 域指定了用户视图是否 “跳转(jumps)” 到当前绑定的 Viewpoint 节点位置和方向,或不进行转换。跳转是瞬间的不连续的,跳转开始和结束之间将不执行碰撞检测和 ProximitySensor 节点的检测。如果用户在跳转前的位置在一个 ProximitySensor 中,则此传感器的 exitTime 应发送和绑定域相同的时间戳。同样,如果用户在跳转后的位置在一个 ProximitySensor 中,则此传感器的 enterTime 应发送和绑定域相同的时间戳。不管 jump 域在绑定时间的值如何,用户视图和当前 Viewpoint 节点的相对视图变换应被和当前的 Viewpoint 节点一起存储,以便后面反向跳转(un-jumping)时使用(即把 jump TRUE 的 Viewpoint 节点从 Viewpoint 节点绑定堆栈移除)。以下描述了绑定堆栈的规则(见 7.2.2 可绑定子节点 Bindable children nodes)以及特定于 Viewpoint 节点的绑定堆栈规则(以黑体显示):

  1. 在读取时,第一个遇到的 Viewpoint 节点将被弹到 Viewpoint 节点堆栈的顶端,从而被绑定。如果一个 Viewpoint 节点的名称是正在读取的 URL 中指定的,此名称的 Viewpoint 节点就被当作最先遇到的 Viewpoint 节点。node. Nodes contained within Inline 节点(见 9.4.2 Inline)中包含的节点,或传输到 Browser.createX3DFromString() 方法的字符串中的节点,或传输到 Browser.createX3DFromURL() 方法中的 X3D 文件中的节点(参见 2.[I19775-2]),都不算做最先遇到的 Viewpoint 节点。原型实例中的第一个节点可以算作第一个遇到的 Viewpoint 节点。第一个遇到的 Viewpoint 节点发送一个 isBound TRUE 事件。
  2. 当一个 Viewpoint 节点接受到一个 set_bind TRUE 事件时,
    1. 如果节点不在堆栈顶端:从当前堆栈顶端的 Viewpoint 节点到当前用户视图的相对变换将被和当前的 Viewpoint 节点一起存储. 当前的堆栈顶端的节点发送一个 isBound FALSE 事件。新的节点被移到堆栈顶端,并变为当前绑定的 Viewpoint 节点。新的 Viewpoint 节点(堆栈顶端的)发送一个 isBound TRUE 事件。如果新的 Viewpoint 节点的 jumpTRUE,则用户视图将立即“跳转”匹配新的 Viewpoint 节点 position 域和 orientation 域的视图。
    2. 如果节点已经在堆栈顶,则事件不发生影响。
  3. 当堆栈中的一个 Viewpoint 节点接受到一个 set_bind FALSE 事件时,它将被从堆栈中移除。如果其位于堆栈顶端,
    1. 这个节点发送一个 isBound FALSE 事件,
    2. t堆栈中的下一个节点变为当前绑定的 Viewpoint 节点(例如弹到堆栈顶)同时发送一个 isBound TRUE 事件,
    3. 如果其 jump 域值为 TRUE,则用户视图将立即“跳转”到堆栈中 已经附加 存储的相对变换的下一个 Viewpoint 节点的 positionorientation
  4. 不在堆栈中的节点将忽略接受到的 set_bind FALSE 事件,同时也不会发送 isBound 事件。
  5. 当堆栈顶的节点被另一个节点替代时,两个节点同时(例如有一个相同的时间辍)分别发送 isBound TRUEFALSE 事件。
  6. 如果删除绑定的节点,则产生与其接收到 set_bind FALSE 事件时相同的行为(参见以上 f 条)。

在 Viewpoint 节点被绑定后,jump 域也可以改变。以上描述的规则仍然适用。如果一个 Viewpoint 节点被绑定时 jumpTRUE,但在 set_bind FALSE 发送前 jump 变为 FALSE,则此 Viewpoint 节点在解除绑定时不执行反向跳转(un-jump)。如果如果一个 Viewpoint 节点被绑定时 jumpFALSE,但在 set_bind FALSE 发送前 jump 变为 TRUE,则此 Viewpoint 节点在解除绑定时执行反向跳转

注意另外有两种机制将导致 Viewpoint 节点的新绑定:

  1. Anchor 节点的 url 域指定了一个 "#ViewpointName"。
  2. 脚本调用 loadURL() 方法并在 URL 自变量中指定了一个 "#ViewpointName"。

当绑定到新的 Viewpoint 时,这两种机制下都不考虑指定的 Viewpoint 节点(#ViewpointName)的 jump 域的值,而假定 jump 值为 TRUE。观测者转换到新绑定 Viewpoint 时的行为将由当前绑定的 NavigationInfo 节点的 type 域的值来决定。(见 23.3.4 NavigationInfo)。

fieldOfView(视野)域以弧度值指定了从此视点观察时首选的最小视角。较小的视野对应长焦镜头;较大的视野对应广角镜头。视野值应大于或等于 0 且小于 πfieldOfView 的值表示对应特定视图在任意轴上的最小观测角度。例如,浏览器的矩形观测投影应按一下关系设定:

   display width    tan(FOVhorizontal/2)
   -------------- = -----------------
   display height   tan(FOVvertical/2)

这里较小的显示宽度或显示高度决定了哪个角度将等于 fieldOfView(较大的角度将使用以上的关系计算)。较大的角度应不超出 π ,且可能会强制较小的角度小于 fieldOfView 以维持屏幕的宽高比。

description(描述)域指定了 Viewpoint 节点的文本化描述。这可能用于浏览器的特定界面。如果一个 Viewpoint 的 description 域为空,将推荐浏览器的特定界面中不出现这个 Viewpoint。

centerOfRotation(旋转中心)域指定了 EXAMINE 模式下旋转用户视点时所围绕的中心。如果浏览器在 EXAMINE 模式下没有提供围绕某个对象旋转的能力,或在允许的导航模式中没有列出 LOOKAT 模式,这个域将被忽略掉。更多信息见 23.3.4 NavigationInfo22.4.1 ProximitySensor

URL 后缀 ".../scene.wrl#ViewpointName" 指定了载入 "scene.wrl" 时由 DEF ViewpointName Viewpoint {...}定义的用户的初始视图,而通常初始视图是由 X3D 文件中的第一个 Viewpoint 节点定义的。这时将不以 X3D 文件中第一个 Viewpoint 节点为初始用户视图,set_bind TRUE 消息将被发送到名为 "ViewpointName" 的 Viewpoint 节点。如果没有发现名为 "ViewpointName" 的 Viewpoint 节点,浏览器应使用 X3D 文件中发现的第一个 Viewpoint 节点(正如一般的缺省行为)。URL 后缀 "#ViewpointName" (例如没有指定文件名)将指定一个当前 X3D 文件中的视点。如果此 URL 被载入(例如通过 Anchor 节点的 url 域或用一个 Script 节点调用 loadURL() 方法),名为 "ViewpointName" 的 Viewpoint 节点将被绑定(set_bind TRUE 事件将被发送到此 Viewpoint 节点)。

cube 23.4 支持级别

The Navigation component provides two levels of support as specified in Table 23.2.

Table 23.2Navigation component support levels

Level Prerequisites Nodes Support
1 Core 1
Shape 1

NavigationInfo avatarSize optionally supported.
speed optionally supported.
type support for at least "ANY", "FLY", "EXAMINE", and "NONE".
visibilityLimit optionally supported.
Viewpoint fieldOfView optionally supported.
description optionally supported.
2 Core 1
Grouping 1
Shape 1
Environmental sensor 2
All Level 1 Navigation nodes All fields fully supported.
    NavigationInfo type support for at least "ANY", "FLY", "EXAMINE", "WALK", "LOOKAT", and "NONE".

All other fields fully supported.

  Billboard All fields fully supported.
Collision All fields fully supported.
LOD All fields fully supported.
--- X3D separator bar ---