状态控制
Five 引入了 State 的概念,以便于理解当前三维空间的状态。您可以通过 five.state
来获取当前状态或调用 five.setState()
对状态进行修改:
// 获取当前的模态
five.state.mode;
// 全景点位游走
five.setState({ panoIndex: 0 });
// 切换当前的模态至 "Floorplan" 空间总览模态
five.setState({ mode: Five.Mode.Floorplan });
这里提供一个示例,展示当前 Five 实例的状态值:
数据结构
State 是 Five 渲染引擎用于描述当前三维空间状态的数据结构。它包含了当前空间渲染的 模态、所处的 采集点位、相机方向 及 相机可视角度 等信息。 其数据结构声明如下:
interface State {
mode: Mode /* 视图模态 */;
panoIndex: number /* 采集点位 或 全景点位 */;
longitude: number /* 相机俯仰角 */;
latitude: number /* 相机偏航角 */;
fov: number /* 相机可视角度(垂直) */;
offset: THREE.Vector3 /* 相机位置坐标 */;
}
视图模态
Five 内置五种视图渲染 模态,可以通过 Five.Mode
获得,其枚举定义:
Panorama
:全景游走模态 可以在采集点间进行全景游走,适合查看采集点位的全景信息。你可以点击屏幕或地面"引导圈"切换采集点位,还可以旋转、双指放大或鼠标滚轮等操作选择合适的视角。Floorplan
:空间总览模态 视图以模型为中心,手势操作可以旋转/放大模型/切换楼层,适合查看模型的整体效果。Topview
:户型图模态 视图以模型为中心,垂直俯视模型,手势操作可以平移/放大模型/切换楼层,适合查看模型平面结构。Model
:模型游走模态 视图将在模型中自由游走,手势操作可以旋转/放大视角/位移,适合查看模型的细节,做一些定位操作。VRPanorama
:VR 眼镜模态 可以使用 Cardboard 眼镜 或者他的第三方衍生产品,实现 VR 虚拟显示效果。
每个 视图模态 在不同场景的作用是不同的,其中 Panorama 和 Floorplan 是最常用的,正常情况下仅需关注这两个模态即可。没有特殊设置,five.load()
渲染的默认模态就是 Panorama。
你可以点击以上示例中上角的按钮进行模态切换,以对比不同的视图模态所带来的视觉体验。
采集点位
采集点位 panoIndex
是指在 Panorama
模态下可以落脚的位置,一般也被叫做 全景点位。其位置信息在 Work 数据 work[observers]
和 work[panorama]
字段中体现。
如何理解采集点位
其实,完整的实景三维空间信息是从采集的点位信息经过算法加工而来的。比如下面的 如视 VR App 相机采集视频教程——在空间中选择位置(即点位),然后拍摄全景图片、收集深度等空间数据,接着基于这些数据通过如视云服务器执行三维重建技术算法,最后生成供终端渲染用的 Work 数据。
通常我们所说的 全景游走 其本质是在 Panorama
模态下更改采集点位位置。
相机描述
Five 是基于 Three.js 实现的,其三维建模体系与 Three.js 完全一致,均有场景、渲染器、相机等概念。前面我们提到的缩放、移动、旋转等交互效果并没有实时修改模型在三维空间中的位置信息。其实,我们是通过调整相机的位置信息来实现的。
Five 中的摄像机使用 透视相机(PerspectiveCamera)来进行投影。这一投影模式被用来模拟人眼所看到的景象,它是 3D 场景的渲染中使用得最普遍的投影模式。

longitude
& latitude
透视相机 的概念复杂、参数多,如上图一(左)所示——如果直接通过修改这些参数并不方面理解。
Five 使用类似 经纬度 的方式描述相机位置,即相机的水平角 longitude
和 相机的偏航角 latitude
,且单位为 弧度。
比如,我们将整个模型场景为一个右手笛卡尔坐标系, XZ
平面平行于地面, Y
轴垂直于地面,如图一(右)。
初始相机方向为原点看向 Z 轴负方向,可以通过调整经纬度值来影响相机信息:
- 增加
longitude
:相机向左旋转。 - 减少
longitude
:相机向右旋转。 - 增加
latitude
:相机向下旋转。 - 减少
latitude
:相机向上旋转。
fov
相机垂直方向的 可视角度,即如图一(左)中 fovy
值。直观的效果是增加 fov
值显示的模型越小,减少 fov
值显示的模型越大。
offset
当前相机的在三维空间中坐标位置,不建议直接修改此值。
设置状态
前文已提到,可以通过 five.state
获取当前状态,通过 five.setState()
方法设置状态。
比如,在 Panorama 模态下切换到采集点位 0
:
five.setState({ panoIndex: 0 });
比如,将 latitude
设置为 0
来平视空间:
five.setState({ latitude: 0 });
当然,你也可以批量修改状态:
five.setState({
latitude: 0,
panoIndex: 0,
mode: Five.Mode.Panorama,
});
相信你已经通过 five.setState()
方法修改过 Five 实例的当前状态了,细心的你会发现 five.setState()
并不是马上修改当前状态值,而是附带动画渐进式地更新到目标状态。如果你想禁用掉动画过渡,可以设置第二个参数 immediately
为 true
来马上达到目标状态:
five.setState(state, true);
state
与 currentState
的区别
除了 five.state
属性外 Five 还提供了 five.getCurrentState()
方法来获取当前的状态。
静态场景下,两种方式获取的值是相同的,区别是:
- currentState 是当前状态,就是画面中渲染的状态,目前展示的状态。
- state 是目标状态或者说下一时间的稳定状态。
当 setState 被调用后,state 当即会变成 setState 的值,而 currentState 则不会马上改变,他会在动画过渡的过程中逐步逼近 state 并最终变成和 state 一样的值。当你的动画时间未结束时调用 five.getCurrentState()
大概率会和 five.state
拿到的值不一致。