@realsee/five v6.2.1
Five.js
贝壳如视三维渲染框架
什么是Five
Five是 贝壳如视(realsee.com) 提供的在浏览器中运行的三维空间渲染 Javascript SDK。您可以通过如视开发者中心的数据服务,并结合Five,制作丰富多彩的三维空间应用。
并且Five提供了一系列的方法、事件、生命周期函数。您可以方便地基于Five进行二次开发,并结合到您自身的项目中,为您的项目添砖加瓦。
Five通过 TypeScript 编写,保证开发的质量以及编程体验,推荐通过 Visual Studio Code、WebStorm 等现代源代码编辑器,您将可以体验到友好的代码提示以及自动补全。
Five还提供了完善的 React Hooks API ,可以方便的通过 React 开发复杂的响应式数据应用。当然直接使用Five开发也是没有问题的。
安装Five
Five提供通过 npm 的方式安装。Five基于 Three.js, 所以同时您需要安装相关依赖。
目前依赖的three版本为 115 ~ 117 的版本
npm install @realsee/five three@0.117.1
如果您使用React Hooks API,那么也请同时安装React的相关依赖。
npm install @realsee/five three@0.117.1 react react-dom @types/react @types/react-dom
接下来便可以在您的项目使用Five了。
import { Five } from "@realsee/five";
// 如果您使用 React Hoos API
import { useFiveState } from "@realsee/five/react";
浏览器兼容性
Safari | Safari on iOS | Chrome | Chrome for Android | Edge | Firefox |
---|---|---|---|---|---|
>= 9 | >= 9 | >= 49 | >= 93 | >= 13 | >= 45 |
快速上手
Five提供了快速上手体验的项目生成工具,您可以通过他熟悉Five的功能以及尝试基于Five开发功能。
- 先创建一个文件夹
five-quick-start
, 作为项目根目录并且使用npm init
命令初始化一个工程。
mkdir five-quick-start && cd five-quick-start && npm init -y
- 安装Five
npm install @realsee/five
- 通过Five的内置的
five-quick-start-init
脚本来快速补完当前项目
npx five-quick-start-init
项目的文件结构如下
.
├── README.md
├── assets 静态文件(测试数据)
│ ├── data0.json
│ └── data1.json
├── index.html 页面模版
├── index.tsx 逻辑代码
├── package.json npm 包管理描述
├── tsconfig.json typescript 配置
├── webpack.config.js webpack 开发环境配置
└── webpack.production.js webpack 生产配置
通npm script运行测试环境
npm run dev
默认将会在 port: 3000
开启 webpack dev server
。您也可以在 webpack.config.js
中修改配置。
- 现在可以打来浏览器
http://0.0.0.0:3000
来看看项目初始化的效果了。您可以修改代码来体验一下如何使用Five来二次开发。
如何使用Five
Five的简单使用样例:
import { Five } from "@realsee/five";
// 构造函数的具体参数见文档
const five = new Five();
// 将渲染视图的 canvas 添加到 DOM 中
five.appendTo(document.getElementById('app')!);
// 如果显示区域需要变动,在变动时请调用 refresh 重置显示参数
window.addEventListener('resize', () => five.refresh());
// 获取三维空间的 Work 数据,加载进来
// Work 数据可以通过如视开发者中心获取
fetch(`./work.json`)
.then(res => res.json())
.then(work => five.load(work));
其他的 Five API 待补充
在React框架中使用Five
在React框架中使用Five的简单使用样例:
import * as React from "react";
import * as ReactDOM from "react-dom";
import {Five, Work, parseWork} from "@realsee/five";
import {createFiveProvider, FiveCanvas} from "@realsee/five/react";
// 创建 Provider, 参数与 new Five 参数类似
// 构造函数的具体参数见文档
const FiveProvider = createFiveProvider();
const App: React.FC = () => {
// 声明 State: Work
const [work, setWork] = React.useState<Work | null>(null);
// 声明 State: Size<{width, height}>
const [size, setSize] = React.useState({
width: window.innerWidth,
height: window.innerHeight
})
// 获取三维空间的 Work 数据,加载进来
const loadWork = React.useCallback((url: string) => {
fetch(url)
.then(res => res.json())
.then(data => setWork(parseWork(data)));
}, []);
React.useEffect(() => {
loadWork("./data0.json");
}, []);
// 如果显示区域需要变动,在变动时请调用 FiveCanvas 的 size
React.useEffect(() => {
const onResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
}
window.addEventListener("resize", onResize, false);
return () => window.removeEventListener("resize", onResize, false);
});
if (work) {
{/*
在 FiveProvider 内承载一个 Five 实例,
在他内部的组件可以使用 Five React Hook API 来获取/设置/操作 他
一个页面中也可以有多个 FiveProvider
*/}
return <FiveProvider initialWork={work}>
{/*
将渲染视图的 canvas 添加到 DOM 中
FiveCanvas 需要出现在 FiveProvider 内,他将渲染 FiveProvider 的视图
这样的设计可以实现不同的 DOM 层级结构
在 FiveProvider 内的其他组件也可以使用 Five React Hook API 来获取/设置/操作 他外部的 FiveProvider
*/}
<FiveCanvas width={size.width} height={size.height}/>
</FiveProvider>
}
return null;
}
ReactDOM.render(<App></App>, document.getElementById("app"));
其他的Five React Hook API文档建设中...
Five API文档
欢迎查看 Five API 文档 。
该文档由 TypeDoc 生成,您可以详细查看 api 使用方式,调用参数,数据结构。
相关名词解释
什么是Work
Work是如视开发者中心 提供的对于一个三维空间的描述。 是通过如视硬件设备(如视扫描仪 、如视Lite全景相机 、如视VR App )扫描并处理之后用于三维空间展示的数据。
Work以JSON
作为数据格式Five框架可以解析Work数据并展示。一个Five实例每次可以载入并展示一个Work。并且也可以在不同的Work之间动态切换。
Work的数据样例如下
{
"initial": {
"mode": "Panorama",
"pano_index": 6,
"longitude": 2.6869287662553916,
"latitude": 0,
"fov": 95
},
"model": {
"file_url": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/model\/auto3d-DJaa08PIzN4JYluXQ1j2VS.at3d",
"material_textures": [
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_0.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_1.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_2.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_3.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_4.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_5.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_6.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_7.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_8.jpg",
"https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/materials\/texture_9.jpg"
]
},
"panorama": {
"list": [
{
"up": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/0\/2257f0f0b29d5b00ff01934ce51aaa35\/0_u.jpg",
"down": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/0\/2257f0f0b29d5b00ff01934ce51aaa35\/0_d.jpg",
"left": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/0\/2257f0f0b29d5b00ff01934ce51aaa35\/0_l.jpg",
"right": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/0\/2257f0f0b29d5b00ff01934ce51aaa35\/0_r.jpg",
"front": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/0\/2257f0f0b29d5b00ff01934ce51aaa35\/0_f.jpg",
"back": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/0\/2257f0f0b29d5b00ff01934ce51aaa35\/0_b.jpg"
},
{
"up": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/1\/ecb554bb1c122fa90186d176ccfecde4\/1_u.jpg",
"down": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/1\/ecb554bb1c122fa90186d176ccfecde4\/1_d.jpg",
"left": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/1\/ecb554bb1c122fa90186d176ccfecde4\/1_l.jpg",
"right": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/1\/ecb554bb1c122fa90186d176ccfecde4\/1_r.jpg",
"front": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/1\/ecb554bb1c122fa90186d176ccfecde4\/1_f.jpg",
"back": "https:\/\/vrlab-public.ljcdn.com\/release\/auto3dhd\/a62e1ebf7d013f7df117551a14af79fc\/images\/cube_2048\/1\/ecb554bb1c122fa90186d176ccfecde4\/1_b.jpg"
}
],
},
"observers": [
{
"visible_nodes": [ 1 ],
"accessible_nodes": [ 1 ],
"quaternion": {
"w": 0.45076583925142194,
"x": 0.010070951976936936,
"y": -0.8925839597148215,
"z": -0.0016154299986102319
},
"standing_position": [
-6.956049919128418,
-1.3924440682333898,
1.6591600179672241
],
"position": [
-6.956049919128418,
-0.10312400013208389,
1.6591600179672241
],
"floor_index": 0
},
{
"visible_nodes": [ 0 ],
"accessible_nodes": [ 0 ],
"index": 1,
"quaternion": {
"w": -0.9884643083591809,
"x": -0.0038900979633806664,
"y": 0.1512670435365699,
"z": -0.006439990839033269
},
"standing_position": [
-6.176340103149414,
-1.380554749576384,
2.179759979248047
],
"position": [
-6.176340103149414,
-0.10025200247764587,
2.179759979248047
],
"floor_index": 0,
}
]
}
Work 的数据说明
initial
: 初始化数据,是一个State
数据。描述Work被加载初始状态的位姿,也叫做VR的初始视角- mode: 模态
- pano_index: 初始化点位
- longitude: 相机的水平角
- latitude: 相机的偏航角
- fov: 相机垂直方向的可视角度
model
: 三维模型- file_url: 三维模型的资源地址,文件为
.at3d
为如视定制的模型格式 - material_textures: 三维模型的贴图资源地址
- file_url: 三维模型的资源地址,文件为
panorama
: 全景彩色信息- list:
- up / down / left / right / front / back: 全景彩色信息以 cubemap 方式存储和使用。
- list:
observers
: 采集点信息- visible_nodes: 采集点之间的可见性列表
- accessible_nodes: 采集点之间的连通性列表
- quaternion: 采集点与模型坐标的旋转偏移量
- standing_position: 采集点地面坐标
- position: 采集点坐标
- floor_index: 采集点楼层
什么是 Five State
State是Five框架用于描述状态的数据结构。他包含了模态、位于的采集点位、相机的方向、相机可视角度的信息。 您可以使用State来操作Five或者获取Five当前的状态。
interface State {
"mode": Five.Mode,
"panoIndex": number,
"longitude": number,
"latitude": number,
"fov": number,
"distanace": number,
"offset": THREE.Vector3,
}
State的数据描述
mode
: 当前的模态 Five 常用有 5 种模态,可以使用Five.Mode
获得- Panorama: 全景游走模态,该模态下视图将在采集点间游走,手势操作可以旋转/放大视角/切换采集点,适合查看采集的全景信息。
- Floorplan: 空间总览模态, 该模态下视图以模型为中心,手势操作可以旋转/放大模型/切换楼层,适合查看模型的整体效果。
- Topview: 户型图模态,该模态下视图以模型为中心,垂直俯视模型,手势操作可以平移/放大模型/切换楼层,适合查看模型平面结构。
- Model: 模型游走模态,该模态下视图将在模型中自由游走,手势操作可以旋转/放大视角/位移,适合查看模型的细节,做一些定位操作。
- Mapview: 地图模态, 该模态下视图将类似三维地图,手势操作可以旋转/放大视角/位移,适合查看模型的细节。适合展示小区,工厂等较大的模型。
- VRPanorama: VR 眼镜模态,该模态下可以使用 Cardboard 眼镜 或者他的第三方衍生产品,实现 VR 虚拟显示效果。
- XRPanorama: XR 眼镜模态,该模态下可以使用头戴显示设备比如 Pico, Meta Quest 等,实现沉浸式体验。
panoIndex
: 采集点位longitude
/latitude
: 相机的水平角 / 相机的偏航角(弧度),我们使用类似经纬度的方式描述相机位置。fov
: 相机垂直方向的可视角度 (角度)distance
: 相机距 offset 的距离offset
: 相机看向的目标
模型坐标的转换说明
目前涉及到的模型类型 at3d / domez / 3d-tile(b3dm, pnts, glb)
枚举说明
world
: five.scene 场景下的坐标。属于 view 下的绝对坐标。坐标的上方向是 Y 轴,单位米。local
: 单个模型的相对坐标。坐标的上方向是 Y 轴,单位米。 单个模型受到work.transform
的影响会产生一定的位姿变化进行项目拼接(比如沙盘项目)。这种情况下,会与world
有一定偏转。enu
: 模型描述坐标(East-North-Up)。坐标的上方向是 Z 轴,单位米。需要在算法模型输入/输出时使用这个坐标系。ecef
: 模型在地球的坐标系(Earth-centered, Earth-fixed)。坐标的上方向是 Z 轴并且固定是北,单位米。lla
: 模型在地球的经纬高度 (Latitude-Longitude-Altitude)。 经纬度单位是弧度,高度单位是米。
数据来源
转换:
local
与world
的转换依赖work.transform
local
与enu
的转换是固定的 yUp 转 zUpenu
与ecef
依赖tileset.json
中rootMeta.coordinate.pose_ecef_to_enu
/rootMeta.coordinate.pose_enu_to_ecef
。 如果缺损,则使用a=6378137.0;invf=298.257223563
的椭球近似计算lla
通过a=6378137.0;invf=298.257223563
的椭球近似计算
椭球近似计算: (enu
+ lla
) 与 ecef
可以相互推导。
转换关系
- 在 five 环境下,通过 viewLayer 对象,即 five.modelsnumber.viewLayernumber.scene 转化。提供对应方法。
localToWorld(vector: THREE.Vector3): THREE.Vector3
worldToLocal(vector: THREE.Vector3): THREE.Vector3
localToEnu(vector: THREE.Vector3): THREE.Vector3
enuToLocal(vector: THREE.Vector3): THREE.Vector3
localToEcef(vector: THREE.Vector3): THREE.Vector3
ecefToLocal(vector: THREE.Vector3): THREE.Vector3
localToLla(vector: THREE.Vector3): THREE.Vector3
llaToLocal(vector: THREE.Vector3): THREE.Vector3
worldToEnu(vector: THREE.Vector3): THREE.Vector3
enuToWorld(vector: THREE.Vector3): THREE.Vector3
worldToEcef(vector: THREE.Vector3): THREE.Vector3
ecefToWorld(vector: THREE.Vector3): THREE.Vector3
worldToLla(vector: THREE.Vector3): THREE.Vector3
llaToWorld(vector: THREE.Vector3): THREE.Vector3
这些函数均为直接修改传入 vector
。 如果要保持原先的数据,请实现 vector.clone()
。
位置拾取
通过 intersectRaycaster
方法得到的 Intersection
在 world
坐标系下, 并返回对应的 model
与 viewLayer
。
与算法数据对接
目前约定为,算法的模型输入输出均使用 enu
坐标系。
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
11 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago