Skip to main content

状态控制

Five 引入了 State 的概念,以便于理解当前三维空间的状态。您可以通过 five.state 来获取当前状态或调用 five.setState() 对状态进行修改:

// 获取当前的模态
five.state.mode

// 全景点位游走
five.setState({ panoIndex: 0 })

// 切换当前的模态至 "Floorplan" 空间总览模态
five.setState({ mode: Five.Mode.Floorplan })

这里提供一个示例,展示当前 Five 实例的状态值:

数据结构

StateFive 渲染引擎用于描述当前三维空间状态的数据结构。它包含了当前空间渲染的 模态、所处的 采集点位相机方向相机可视角度 等信息。 其数据结构声明如下:

interface State {
"mode": Mode, /* 视图模态 */
"panoIndex": number, /* 采集点位 或 全景点位 */
"longitude": number, /* 相机俯仰角 */
"latitude": number, /* 相机偏航角 */
"fov": number, /* 相机可视角度(垂直) */
"offset": THREE.Vector3, /* 相机位置坐标 */
}

视图模态

Five 内置五种视图渲染 模态,可以通过 Five.Mode 获得,其枚举定义:

  • Panorama全景游走模态 可以在采集点间进行全景游走,适合查看采集点位的全景信息。你可以点击屏幕或地面"引导圈"切换采集点位,还可以旋转、双指放大或鼠标滚轮等操作选择合适的视角。
  • Floorplan空间总览模态 视图以模型为中心,手势操作可以旋转/放大模型/切换楼层,适合查看模型的整体效果
  • Topview户型图模态 视图以模型为中心,垂直俯视模型,手势操作可以平移/放大模型/切换楼层,适合查看模型平面结构
  • Model模型游走模态 视图将在模型中自由游走,手势操作可以旋转/放大视角/位移,适合查看模型的细节,做一些定位操作
  • VRPanoramaVR 眼镜模态 可以使用 Cardboard 眼镜 或者他的第三方衍生产品,实现 VR 虚拟显示效果。

每个 视图模态 在不同场景的作用是不同的,其中 PanoramaFloorplan 是最常用的,正常情况下仅需关注这两个模态即可。没有特殊设置,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() 并不是马上修改当前状态值,而是附带动画渐进式地更新到目标状态。如果你想禁用掉动画过渡,可以设置第二个参数 immediatelytrue 来马上达到目标状态:

five.setState(state, true)

statecurrentState 的区别

除了 five.state 属性外 Five 还提供了 five.getCurrentState() 方法来获取当前的状态。 静态场景下,两种方式获取的值是相同的,区别是:

  • currentState 是当前状态,就是画面中渲染的状态,目前展示的状态。
  • state 是目标状态或者说下一时间的稳定状态。
可以这样简单理解:

setState 被调用后,state 当即会变成 setState 的值,而 currentState 则不会马上改变,他会在动画过度的过程中逐步逼近 state 并最终变成和 state 一样的值。当你的动画时间未结束时调用 five.getCurrentState() 大概率会和 five.state 拿到的值不一致。