跳到主要内容

展示三维空间

上一章回顾: 起步

  • 你学会了如何初始化环境。
  • 并且你书写了一段代码,虽然不知道这段代码干了什么,不过也顺利得完成了载入并展示一个 VR 的工作。
本章你可以学习到
  • 了解什么是 Work。
  • 了解 FiveProvider / FiveCanvas 组件是如何工作的。

准备工作

和上一章节一样,我们新建一个目录(src/1.displaying-work)以及对应的 html 文件 以及 jsxtsx 文件。

jsxtsx 文件可以先拷贝上一章节的内容。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="data:;base64,iVBORw0KGgo=">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>展示空间 | Display a work</title>
  <style>
    * { margin: 0; padding: 0; }
    html, body #app { width: 100%; height: 100%; overflow: hidden; }
  </style>
</head>
<body>
  <div id="app"></div>
  <script type="module" src="./index"></script>
</body>
</html>
import { useState, useEffect } from "react";
import { parseWork } from "@realsee/five";

/**
 * React Hook: 通过 work.json 的地址 获取 work 对象
 * @param url work.json 的数据地址
 * @returns work 对象,如果获取中,返回 null
 */
 function useFetchWork(url) {
  const [work, setWork] = useState(null);
  useEffect(() => {
    setWork(null);
    fetch(url)
      .then(response => response.text())
      .then(text => setWork(parseWork(text)));
  },[url]);
  return work;
}

export { useFetchWork };
src/1.displaying-work/useWindowDimensions.js
import { useState, useEffect } from "react";

/**
* 获取当前窗口的尺寸
*/
function getWindowDimensions() {
return { width: window.innerWidth, height: window.innerHeight };
}

/**
* React Hook: 获取当前窗口的尺寸
*/
function useWindowDimensions() {
const [size, setSize] = useState(getWindowDimensions);
useEffect(() => {
const listener = () => setSize(getWindowDimensions());
window.addEventListener("resize", listener, false);
return () => window.removeEventListener("resize", listener, false);
});
return size;
}

export { useWindowDimensions };
src/1.displaying-work/App.jsx
import React from "react";
import { createFiveProvider, FiveCanvas } from "@realsee/five/react";
import { useFetchWork } from "./useFetchWork";
import { useWindowDimensions } from "./useWindowDimensions";

/** work.json 的数据 URL */
const workURL = "https://vr-public.realsee-cdn.cn/release/static/image/release/five/work-sample/07bdc58f413bc5494f05c7cbb5cbdce4/work.json";

const FiveProvider = createFiveProvider();
const App = () => {
const work = useFetchWork(workURL);
const size = useWindowDimensions();
return work && <FiveProvider initialWork={work}>
<FiveCanvas {...size}/>
</FiveProvider>;
};

export { App };
src/1.displaying-work/index.jsx
import React from "react";
import ReactDOM from "react-dom";
import { App } from "./App";

ReactDOM.render(<App/>, document.querySelector("#app"));

export {};

启动服务 npm run dev。 并跳转到当前页面 "http://localhost:3000/src/1.displaying-work/index.html"。

信息

请查看你的控制台,端口号会因为你的配置以及当前端口占用情况变更,请已控制台输出的为准。 如果你使用其他开发构建工具,请按照自己的开发构建工具的要求启动服务。

什么是 Work

接下来停下写代码的双手,我们来理解一些概念,放心很简单。

Work 简介

我们将一个三维空间叫做一个 Work。 那么一个 Work 是通过 json 的结构体描述的,称之为 work.jsonWork 你可以通过如视开放平台接口获取。 也可以像本次示例一样将之静态化使用。

Five 提供了 parseWork 的方法,用于解析 work.json,然后便可以得到 work 对象。 将 work 对象传入 FiveProviderinitialWork 属性中就可以初始化场景。你在上一章也是这么做的。

work 的使用限制

你需要在如视开发者中心配置你的 安全域名 以及 work数据的 可用时间。 在生成环境中使用 Five SDK 对对此做校验来保护开发者以及如视的数据安全。

在以下情况不会校验上述限制,便于开发和测试:

  • 域名为 localhost
  • 域名为 ip 地址,如 127.0.0.1, 192.168.0.5, 172.30.2.0, 10.33.10.2 等
  • 在非 http 情况下访问,比如 file:// 协议下

work.json的数据样例及数据说明

你并不需要了解 work.json 的内容也可能很好的使用 Five SDK. 但是多了解一些,也不是坏事。

点击查看work.json
{
  "_signature": "LLzk2WHDbRfzQ5R+v82uVQqAGWMPfvgQ05hTwxgWKGeXbTPKtoQ8eI6FmCxJjtVjQW+wuZmZfxpzXePv4MGrWidG/05i5RRSELlPLEFZN3qYPykJLEIYhg3Wtvr8XkOI8wdeMgV82CP4Hyi84k/W2g+S+HcFs5oXfbfbFXPL/Gs=",
  "allow_hosts": [
    "*"
  ],
  "base_url": "https://vr-public.realsee-cdn.cn/release/auto3dhd/9380ce27b46cbc5ba8d47fcf0e4c9e4f/",
  "certificate": "-----BEGIN CERTIFICATE-----\nMIIEMzCCAhsCCQDYAS/7ATZRmTANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgMB0JlaWppbmcxEDAOBgNVBAcMB0JlaWppbmcxFDASBgNVBAoM\nC2xpYW5qaWEuY29tMRAwDgYDVQQLDAdSZWFsc2VlMREwDwYDVQQDDAhIYXJkd2Fy\nZTElMCMGCSqGSIb3DQEJARYWbml1aGFpcWluZ0BsaWFuamlhLmNvbTAeFw0yMTA5\nMTAwNTIwMDBaFw0zMTA5MDgwNTIwMDBaMIGmMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCAwHQmVpSmluZzEQMA4GA1UEBwwHQmVpSmluZzEQMA4GA1UECgwHUmVhbHNlZTEZ\nMBcGA1UECwwQUmVhbHNlZUFwcEdldHdheTEgMB4GA1UEAwwXYXBwLWdhdGV3YXku\ncmVhbHNlZS5jb20xJDAiBgkqhkiG9w0BCQEWFWRldmVsb3BlckByZWFsc2VlLmNv\nbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuv/y3Ezsy/wh3LCA8vomPbgI\nSO9iO5kyR+oAetklD+epMU6J/ZbvTDEomZxuS5iyyKGBupzAh2ZFLIy7tsE71Vx1\nIIvT7Kdyq66lMU4YzdrpKUcxv7oOQnO8DA1orKluNa4jkyXBywHKs/Q+20LVc+RD\ngKXqFGJUdo8mAxEScs0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAkMxsU4VLPd4J\n0rElBNBIyqPtvnlTs6VkhIK0l4oM58wtDKc1uG9UPSX5j29NguZM6LOe0jCsU2Vg\nEpUseMWQjx4o2yBg7MokQyjWc1zu6PppKhQ+RqHQy/biJ2zsIMpX3oMASXffvnW5\nn4Bjyo1JdDJiLm1fLvLlVVxQoraJD+rtpqWDEYixGVREUo5OIL5Y5dVjkHG2r9RQ\nQuu3yEiyr9gAW8yhz3YR6/sJ6boyGK8NC0v8Jih7NnCdT+9ML+3jn3P5F3TeXdSf\nVeYIm5oWAOTe3AjjKP8ARMb2RYACjg80/AcowD/dvRRjbwQmyucUNug2pXJynXpD\nNfx1IBmUmzSAT1Z5yNuY/f3VRBJvmIQ6Jpmef+g0/wUJpyS4SObguItyYlFPLqRH\nK1oKqNX/uV0GWWEQl6Lml986TzlHxc4ljtHBhjzlKYIYYZLWWipk4JiB8hxJcTK+\ncrgvclEQSxFlmAyoqxYFClrOOsPqZJdBhDTvoUWnnWuJLQt7DLHpyInp+S75Gg3o\n0zgHpt9m26B3YbjQGYMQlYmhl2VLQa+Ey0W8UZQXLcTvoRT4p+8crqr6cNNsxCyZ\nm08vBbEMIMvhBeLQvpM75oaMBmelegipFl2eelxVIHdGJWoyJSZQUdXN0uSidhZp\nI7AIgzhqK1Ku/IXK0OSXJonn+/9X/VI=\n-----END CERTIFICATE-----",
  "create_time": "2020-07-29T15:18:06+08:00",
  "expire_at": "2132653492169",
  "initial": {
    "flag_position": [
      -1.8683282713225706,
      -1.1184803014502747,
      -2.536637882840082
    ],
    "fov": 95,
    "heading": 0,
    "latitude": 0,
    "longitude": 5.58602282229265,
    "pano": 4,
    "pano_index": 4
  },
  "model": {
    "file_url": "model/auto3d-syVb5hzy8ZL1gZut_VvGDo.at3d",
    "material_base_url": "materials/",
    "material_textures": [
      "texture_0.jpg",
      "texture_1.jpg",
      "texture_2.jpg",
      "texture_3.jpg",
      "texture_4.jpg",
      "texture_5.jpg",
      "texture_6.jpg",
      "texture_7.jpg",
      "texture_8.jpg"
    ],
    "modify_time": "2020-07-29T15:37:17+08:00",
    "type": 0
  },
  "observers": [
    {
      "accessible_nodes": [
        1,
        2,
        3,
        4,
        6,
        7,
        8
      ],
      "floor_index": 0,
      "index": 0,
      "offset_point_count": 551,
      "position": [
        -2.9148900508880615,
        0,
        1.392490029335022
      ],
      "quaternion": {
        "w": 0.44238951628615497,
        "x": -0.0011834399273419546,
        "y": -0.8968221073969266,
        "z": -0.00045692663054024737
      },
      "standing_position": [
        -2.9148900508880615,
        -1.1193245547539874,
        1.392490029335022
      ],
      "visible_nodes": [
        1,
        2,
        3,
        4,
        6,
        7,
        8
      ]
    },
    {
      "accessible_nodes": [
        0,
        2,
        3,
        4
      ],
      "floor_index": 0,
      "index": 1,
      "offset_point_count": 1382,
      "position": [
        -1.780460000038147,
        -0.00217098998837173,
        4.450079917907715
      ],
      "quaternion": {
        "w": 0.46776604948048534,
        "x": -0.0011699393533674196,
        "y": -0.883851410579187,
        "z": -0.000490464139922521
      },
      "standing_position": [
        -1.780460000038147,
        -1.1214462854241507,
        4.450079917907715
      ],
      "visible_nodes": [
        0,
        2,
        3,
        4
      ]
    },
    {
      "accessible_nodes": [
        0,
        1,
        3,
        4
      ],
      "floor_index": 0,
      "index": 2,
      "offset_point_count": 378,
      "position": [
        -1.3428200483322144,
        -0.0028426700737327337,
        6.358610153198242
      ],
      "quaternion": {
        "w": 0.6069850728938949,
        "x": -0.001073151580086956,
        "y": -0.7947122170838032,
        "z": -0.0006765059598702671
      },
      "standing_position": [
        -1.3428200483322144,
        -1.1225737228916606,
        6.358610153198242
      ],
      "visible_nodes": [
        0,
        1,
        3,
        4
      ]
    },
    {
      "accessible_nodes": [
        0,
        1,
        2,
        4,
        6,
        7,
        8
      ],
      "floor_index": 0,
      "index": 3,
      "offset_point_count": 0,
      "position": [
        -2.554189920425415,
        -0.005082080140709877,
        6.343259811401367
      ],
      "quaternion": {
        "w": -0.030997155509175898,
        "x": -0.0033666821765646494,
        "y": -0.9994984128781037,
        "z": -0.005546881036692224
      },
      "standing_position": [
        -2.554189920425415,
        -1.1224907918710612,
        6.343259811401367
      ],
      "visible_nodes": [
        0,
        1,
        2,
        4,
        6,
        7,
        8
      ]
    },
    {
      "accessible_nodes": [
        0,
        1,
        2,
        3,
        5,
        6,
        7,
        8,
        9,
        10,
        11
      ],
      "floor_index": 0,
      "index": 4,
      "offset_point_count": 941,
      "position": [
        -2.91471004486084,
        -0.0003035110130440444,
        0.06049229949712753
      ],
      "quaternion": {
        "w": 0.0513025987418296,
        "x": -0.0012676475973127641,
        "y": -0.9986823460816978,
        "z": 0.00004879134915086605
      },
      "standing_position": [
        -2.91471004486084,
        -1.1184803014502747,
        0.06049229949712753
      ],
      "visible_nodes": [
        0,
        1,
        2,
        3,
        5,
        6,
        7,
        8,
        9,
        10,
        11
      ]
    },
    {
      "accessible_nodes": [
        4,
        6,
        9,
        10
      ],
      "floor_index": 0,
      "index": 5,
      "offset_point_count": 863,
      "position": [
        -1.0017000436782837,
        -0.005517140030860901,
        -1.6075899600982666
      ],
      "quaternion": {
        "w": -0.0344319061946854,
        "x": -0.001258810265919515,
        "y": -0.9994062434209862,
        "z": 0.0001571970577815824
      },
      "standing_position": [
        -1.0017000436782837,
        -1.1178040247150276,
        -1.6075899600982666
      ],
      "visible_nodes": [
        4,
        6,
        9,
        10
      ]
    },
    {
      "accessible_nodes": [
        0,
        3,
        4,
        5,
        7,
        8
      ],
      "floor_index": 0,
      "index": 6,
      "offset_point_count": 1322,
      "position": [
        -2.846139907836914,
        -0.001211759983561933,
        -3.169840097427368
      ],
      "quaternion": {
        "w": 0.32066123052403445,
        "x": -0.0012332355032137405,
        "y": -0.9471930957831524,
        "z": -0.00029739399948980815
      },
      "standing_position": [
        -2.846139907836914,
        -1.1164889512469,
        -3.169840097427368
      ],
      "visible_nodes": [
        0,
        3,
        4,
        5,
        7,
        8
      ]
    },
    {
      "accessible_nodes": [
        0,
        3,
        4,
        6,
        8
      ],
      "floor_index": 0,
      "index": 7,
      "offset_point_count": 2356,
      "position": [
        -3.0448501110076904,
        -0.0010134399635717273,
        -4.505109786987305
      ],
      "quaternion": {
        "w": 0.49087982982843503,
        "x": -0.001156616652291604,
        "y": -0.8712263733357108,
        "z": -0.0005211039435373182
      },
      "standing_position": [
        -3.0448501110076904,
        -1.11562920091362,
        -4.505109786987305
      ],
      "visible_nodes": [
        0,
        3,
        4,
        6,
        8
      ]
    },
    {
      "accessible_nodes": [
        0,
        3,
        4,
        6,
        7
      ],
      "floor_index": 0,
      "index": 8,
      "offset_point_count": 234,
      "position": [
        -2.9152801036834717,
        -0.01438829954713583,
        -6.370659828186035
      ],
      "quaternion": {
        "w": -0.30469427695314993,
        "x": 0.0033588028429806095,
        "y": -0.952412964681632,
        "z": -0.007724194714338225
      },
      "standing_position": [
        -2.9152801036834717,
        -1.1144715989725875,
        -6.370659828186035
      ],
      "visible_nodes": [
        0,
        3,
        4,
        6,
        7
      ]
    },
    {
      "accessible_nodes": [
        4,
        5,
        10,
        11,
        12,
        13
      ],
      "floor_index": 0,
      "index": 9,
      "offset_point_count": 4886,
      "position": [
        -4.0423102378845215,
        0.003333129920065403,
        -0.03953389823436737
      ],
      "quaternion": {
        "w": -0.18957592794754674,
        "x": 0.010895134657991246,
        "y": -0.9818002618819436,
        "z": -0.0032427031038127978
      },
      "standing_position": [
        -4.0423102378845215,
        -1.118231507556375,
        -0.03953389823436737
      ],
      "visible_nodes": [
        4,
        5,
        10,
        11,
        12,
        13
      ]
    },
    {
      "accessible_nodes": [
        4,
        5,
        9,
        11
      ],
      "floor_index": 0,
      "index": 10,
      "offset_point_count": 1773,
      "position": [
        -4.850550174713135,
        0.004613489843904972,
        0.1713390052318573
      ],
      "quaternion": {
        "w": 0.12768161943121548,
        "x": -0.0012676586552423492,
        "y": -0.9918143930048722,
        "z": -0.00004849317962342722
      },
      "standing_position": [
        -4.850550174713135,
        -1.1182253683511887,
        0.1713390052318573
      ],
      "visible_nodes": [
        4,
        5,
        9,
        11
      ]
    },
    {
      "accessible_nodes": [
        4,
        9,
        10
      ],
      "floor_index": 0,
      "index": 11,
      "offset_point_count": 654,
      "position": [
        -5.53085994720459,
        -0.013371099717915058,
        -0.143778994679451
      ],
      "quaternion": {
        "w": -0.0030183054753861976,
        "x": -0.00047414000140664293,
        "y": -0.9999897553992034,
        "z": -0.0033406236879980804
      },
      "standing_position": [
        -5.53085994720459,
        -1.1179010210789888,
        -0.143778994679451
      ],
      "visible_nodes": [
        4,
        9,
        10
      ]
    },
    {
      "accessible_nodes": [
        9,
        13
      ],
      "floor_index": 0,
      "index": 12,
      "offset_point_count": 1237,
      "position": [
        -4.178860187530518,
        -0.013643399812281132,
        1.3469799757003784
      ],
      "quaternion": {
        "w": 0.06683888675991313,
        "x": -0.0047767000805582485,
        "y": -0.9977055393311836,
        "z": -0.00966420424898995
      },
      "standing_position": [
        -4.178860187530518,
        -1.1190794461899993,
        1.3469799757003784
      ],
      "visible_nodes": [
        9,
        13
      ]
    },
    {
      "accessible_nodes": [
        9,
        12
      ],
      "floor_index": 0,
      "index": 13,
      "offset_point_count": 466,
      "position": [
        -4.963950157165527,
        -0.005961719900369644,
        3.710700035095215
      ],
      "quaternion": {
        "w": -0.19462188396064967,
        "x": 0.004454742146828046,
        "y": -0.9807853643462634,
        "z": -0.012749200565824454
      },
      "standing_position": [
        -4.963950157165527,
        -1.12043610464341,
        3.710700035095215
      ],
      "visible_nodes": [
        9,
        12
      ]
    }
  ],
  "panorama": {
    "count": 14,
    "list": [
      {
        "back": "images/cube_2048/0/9bf403506f2bc22eea0a81cdb09a8e22/0_b.jpg",
        "down": "images/cube_2048/0/9bf403506f2bc22eea0a81cdb09a8e22/0_d.jpg",
        "front": "images/cube_2048/0/9bf403506f2bc22eea0a81cdb09a8e22/0_f.jpg",
        "index": 0,
        "left": "images/cube_2048/0/9bf403506f2bc22eea0a81cdb09a8e22/0_l.jpg",
        "right": "images/cube_2048/0/9bf403506f2bc22eea0a81cdb09a8e22/0_r.jpg",
        "up": "images/cube_2048/0/9bf403506f2bc22eea0a81cdb09a8e22/0_u.jpg"
      },
      {
        "back": "images/cube_2048/1/cb8db51bc30afdd40cf6e4f3f7341c40/1_b.jpg",
        "down": "images/cube_2048/1/cb8db51bc30afdd40cf6e4f3f7341c40/1_d.jpg",
        "front": "images/cube_2048/1/cb8db51bc30afdd40cf6e4f3f7341c40/1_f.jpg",
        "index": 1,
        "left": "images/cube_2048/1/cb8db51bc30afdd40cf6e4f3f7341c40/1_l.jpg",
        "right": "images/cube_2048/1/cb8db51bc30afdd40cf6e4f3f7341c40/1_r.jpg",
        "up": "images/cube_2048/1/cb8db51bc30afdd40cf6e4f3f7341c40/1_u.jpg"
      },
      {
        "back": "images/cube_2048/2/67cdadb9caa0f844f56fee0aac7bb56d/2_b.jpg",
        "down": "images/cube_2048/2/67cdadb9caa0f844f56fee0aac7bb56d/2_d.jpg",
        "front": "images/cube_2048/2/67cdadb9caa0f844f56fee0aac7bb56d/2_f.jpg",
        "index": 2,
        "left": "images/cube_2048/2/67cdadb9caa0f844f56fee0aac7bb56d/2_l.jpg",
        "right": "images/cube_2048/2/67cdadb9caa0f844f56fee0aac7bb56d/2_r.jpg",
        "up": "images/cube_2048/2/67cdadb9caa0f844f56fee0aac7bb56d/2_u.jpg"
      },
      {
        "back": "images/cube_2048/3/791c38edaf6bbcc16e19682543745e9b/3_b.jpg",
        "down": "images/cube_2048/3/791c38edaf6bbcc16e19682543745e9b/3_d.jpg",
        "front": "images/cube_2048/3/791c38edaf6bbcc16e19682543745e9b/3_f.jpg",
        "index": 3,
        "left": "images/cube_2048/3/791c38edaf6bbcc16e19682543745e9b/3_l.jpg",
        "right": "images/cube_2048/3/791c38edaf6bbcc16e19682543745e9b/3_r.jpg",
        "up": "images/cube_2048/3/791c38edaf6bbcc16e19682543745e9b/3_u.jpg"
      },
      {
        "back": "images/cube_2048/4/ee318d536c51ef3de38c4aa059d65ef0/4_b.jpg",
        "down": "images/cube_2048/4/ee318d536c51ef3de38c4aa059d65ef0/4_d.jpg",
        "front": "images/cube_2048/4/ee318d536c51ef3de38c4aa059d65ef0/4_f.jpg",
        "index": 4,
        "left": "images/cube_2048/4/ee318d536c51ef3de38c4aa059d65ef0/4_l.jpg",
        "right": "images/cube_2048/4/ee318d536c51ef3de38c4aa059d65ef0/4_r.jpg",
        "up": "images/cube_2048/4/ee318d536c51ef3de38c4aa059d65ef0/4_u.jpg"
      },
      {
        "back": "images/cube_2048/5/b19d98dc23ec04d86df755dd1a15fdb3/5_b.jpg",
        "down": "images/cube_2048/5/b19d98dc23ec04d86df755dd1a15fdb3/5_d.jpg",
        "front": "images/cube_2048/5/b19d98dc23ec04d86df755dd1a15fdb3/5_f.jpg",
        "index": 5,
        "left": "images/cube_2048/5/b19d98dc23ec04d86df755dd1a15fdb3/5_l.jpg",
        "right": "images/cube_2048/5/b19d98dc23ec04d86df755dd1a15fdb3/5_r.jpg",
        "up": "images/cube_2048/5/b19d98dc23ec04d86df755dd1a15fdb3/5_u.jpg"
      },
      {
        "back": "images/cube_2048/6/b8f425e5f8943c38ad1386ab391b54bc/6_b.jpg",
        "down": "images/cube_2048/6/b8f425e5f8943c38ad1386ab391b54bc/6_d.jpg",
        "front": "images/cube_2048/6/b8f425e5f8943c38ad1386ab391b54bc/6_f.jpg",
        "index": 6,
        "left": "images/cube_2048/6/b8f425e5f8943c38ad1386ab391b54bc/6_l.jpg",
        "right": "images/cube_2048/6/b8f425e5f8943c38ad1386ab391b54bc/6_r.jpg",
        "up": "images/cube_2048/6/b8f425e5f8943c38ad1386ab391b54bc/6_u.jpg"
      },
      {
        "back": "images/cube_2048/7/a05b06a01171babb1aceb5aad8406ab8/7_b.jpg",
        "down": "images/cube_2048/7/a05b06a01171babb1aceb5aad8406ab8/7_d.jpg",
        "front": "images/cube_2048/7/a05b06a01171babb1aceb5aad8406ab8/7_f.jpg",
        "index": 7,
        "left": "images/cube_2048/7/a05b06a01171babb1aceb5aad8406ab8/7_l.jpg",
        "right": "images/cube_2048/7/a05b06a01171babb1aceb5aad8406ab8/7_r.jpg",
        "up": "images/cube_2048/7/a05b06a01171babb1aceb5aad8406ab8/7_u.jpg"
      },
      {
        "back": "images/cube_2048/8/2cd717b9c97f48ae79511855cc7e5138/8_b.jpg",
        "down": "images/cube_2048/8/2cd717b9c97f48ae79511855cc7e5138/8_d.jpg",
        "front": "images/cube_2048/8/2cd717b9c97f48ae79511855cc7e5138/8_f.jpg",
        "index": 8,
        "left": "images/cube_2048/8/2cd717b9c97f48ae79511855cc7e5138/8_l.jpg",
        "right": "images/cube_2048/8/2cd717b9c97f48ae79511855cc7e5138/8_r.jpg",
        "up": "images/cube_2048/8/2cd717b9c97f48ae79511855cc7e5138/8_u.jpg"
      },
      {
        "back": "images/cube_2048/9/0b634fe985df7011472b81c75babfd95/9_b.jpg",
        "down": "images/cube_2048/9/0b634fe985df7011472b81c75babfd95/9_d.jpg",
        "front": "images/cube_2048/9/0b634fe985df7011472b81c75babfd95/9_f.jpg",
        "index": 9,
        "left": "images/cube_2048/9/0b634fe985df7011472b81c75babfd95/9_l.jpg",
        "right": "images/cube_2048/9/0b634fe985df7011472b81c75babfd95/9_r.jpg",
        "up": "images/cube_2048/9/0b634fe985df7011472b81c75babfd95/9_u.jpg"
      },
      {
        "back": "images/cube_2048/10/40c1a6463b8c7462aadfca2a5f80f685/10_b.jpg",
        "down": "images/cube_2048/10/40c1a6463b8c7462aadfca2a5f80f685/10_d.jpg",
        "front": "images/cube_2048/10/40c1a6463b8c7462aadfca2a5f80f685/10_f.jpg",
        "index": 10,
        "left": "images/cube_2048/10/40c1a6463b8c7462aadfca2a5f80f685/10_l.jpg",
        "right": "images/cube_2048/10/40c1a6463b8c7462aadfca2a5f80f685/10_r.jpg",
        "up": "images/cube_2048/10/40c1a6463b8c7462aadfca2a5f80f685/10_u.jpg"
      },
      {
        "back": "images/cube_2048/11/9663b7885a119f2f06da06212986bc9b/11_b.jpg",
        "down": "images/cube_2048/11/9663b7885a119f2f06da06212986bc9b/11_d.jpg",
        "front": "images/cube_2048/11/9663b7885a119f2f06da06212986bc9b/11_f.jpg",
        "index": 11,
        "left": "images/cube_2048/11/9663b7885a119f2f06da06212986bc9b/11_l.jpg",
        "right": "images/cube_2048/11/9663b7885a119f2f06da06212986bc9b/11_r.jpg",
        "up": "images/cube_2048/11/9663b7885a119f2f06da06212986bc9b/11_u.jpg"
      },
      {
        "back": "images/cube_2048/12/01f84f2edd8642d0bf5e4874d01a28ac/12_b.jpg",
        "down": "images/cube_2048/12/01f84f2edd8642d0bf5e4874d01a28ac/12_d.jpg",
        "front": "images/cube_2048/12/01f84f2edd8642d0bf5e4874d01a28ac/12_f.jpg",
        "index": 12,
        "left": "images/cube_2048/12/01f84f2edd8642d0bf5e4874d01a28ac/12_l.jpg",
        "right": "images/cube_2048/12/01f84f2edd8642d0bf5e4874d01a28ac/12_r.jpg",
        "up": "images/cube_2048/12/01f84f2edd8642d0bf5e4874d01a28ac/12_u.jpg"
      },
      {
        "back": "images/cube_2048/13/e9ce1249af9000a33d566c653560c3d6/13_b.jpg",
        "down": "images/cube_2048/13/e9ce1249af9000a33d566c653560c3d6/13_d.jpg",
        "front": "images/cube_2048/13/e9ce1249af9000a33d566c653560c3d6/13_f.jpg",
        "index": 13,
        "left": "images/cube_2048/13/e9ce1249af9000a33d566c653560c3d6/13_l.jpg",
        "right": "images/cube_2048/13/e9ce1249af9000a33d566c653560c3d6/13_r.jpg",
        "up": "images/cube_2048/13/e9ce1249af9000a33d566c653560c3d6/13_u.jpg"
      }
    ]
  },
  "picture_url": "https://vr-public.realsee-cdn.cn/release/auto3dhd/9380ce27b46cbc5ba8d47fcf0e4c9e4f/screenshot/1596005211_4/pc0_3aoiit6zp.jpg",
  "title_picture_url": "https://vr-public.realsee-cdn.cn/release/auto3dhd/9380ce27b46cbc5ba8d47fcf0e4c9e4f/screenshot/1596005211_4/pc1_iQLf2N6a6_1.jpg",
  "vr_code": "8054djM0oR6ky3Ey8e"
}
  • _signature / certificate: work 内容的数字签名

  • expire_at: work 的过期时间

  • allow_hosts: work 的安全域名

  • initial: 初始化数据,是一个 State 数据。描述 Work 被加载初始状态的位姿,也叫做VR的初始视角

    • mode: 模态
    • pano_index: 初始化点位
    • longitude: 相机的水平角
    • latitude: 相机的偏航角
    • fov: 相机垂直方向的可视角度
  • model: 三维模型

    • file_url: 三维模型的资源地址,文件为 .at3d 为如视定制的模型格式
    • material_textures: 三维模型的贴图资源地址
  • panorama: 全景彩色信息

    • list:
      • up / down / left / right / front / back: 全景彩色信息以 cubemap 方式存储和使用。
  • observers: 采集点信息

    • visible_nodes: 采集点之间的可见性列表
    • accessible_nodes: 采集点之间的连通性列表
    • quaternion: 采集点与模型坐标的旋转偏移量
    • standing_position: 采集点地面坐标
    • position: 采集点坐标
    • floor_index: 采集点楼层

Work 对象

相比上面的 work.json, 你可能更常用到的是 Work 对象,他是 parseWork 函数的产物。 Work 对象 相比 work.json 会做很好的序列化,你可以在 Five API 文档 中查看详细说明。

了解 FiveProvider 及 FiveCanvas

FiveProvider 及 FiveCanvas 的由来

FiveProvider / FiveCanvas 是通过 React Context API 的思路开发的。 我们可以认为 FiveProvider 创建了一个三维空间实例。而 FiveCanvas 是对应显示到 DOM 结构中的画布(cnavas)。在 FiveProvider 内的子组件均可以通过 context 获取到 FiveProvider 上提供的方法来获取三维空间的信息或者控制三维空间,我们还开发了一系列的 hooks, 便于你更方便的完成上述事情。

这样的文字描述可能不好理解,那么我们动手做一些看看。

添加模态控制按钮

我们这次完成的工作是添加模态控制按钮,Five 内置了多种模态,默认状态展示的是 全景态,就和上一章最终得到的结果一样,我们还可以展示 模型态 来查看三维空间的宏观状态。切换我们会用到 Five SDK 提供的 useCurrentState 的 React hooks。关于 模态State, useCurrentState 等会在下一章详细学习到,而本章我们要做的事情是:

  • 编写一个 React 组件。
  • 将组件安插为 FiveProvider 的子组件。
  • 通过 Five 提供的 api 控制三维空间。

安装 ui 组件

为了减少示例代码复杂度,这边使用 material-UI 作为 UI 组件库, 你也可以使用 Ant Design Fluent UI 等。

npm install @mui/material @mui/icons-material @emotion/react @emotion/styled

接下来开始编写代码

  1. 添加一个 ModeController 文件,用于编写组件。
  2. 首先在头部从 @realsee/five 引用 Five Mode
  3. Mode 是模态的类型声明。
  4. Five.Mode[string] 是模态的枚举。
  5. 首先在头部从 @realsee/five/react 引用 useFiveCurrentState
  6. 书写 ModeController 组件。
  7. 通过 material-UI 组件,添加界面。
  8. 通过 useFiveCurrentState 可以获取/设置 三维空间的模态(mode)。
import React from "react";
import { Five } from "@realsee/five";
import { useFiveCurrentState } from "@realsee/five/react";
import BottomNavigation from "@mui/material/BottomNavigation";
import BottomNavigationAction from "@mui/material/BottomNavigationAction";
import Paper from "@mui/material/Paper";
import DirectionsWalkIcon from "@mui/icons-material/DirectionsWalk";
import ViewInArIcon from "@mui/icons-material/ViewInAr";

/**
 * React Component: 模态控制
 */
const ModeController = () => {
  const [state, setState] = useFiveCurrentState();
  return <Paper sx={{ position: "fixed", bottom: 0, left: 0, right: 0 }}>
    <BottomNavigation
      showLabels
      value={state.mode}
      onChange={(_, newValue) => {
        setState({ mode: newValue });
      }}
    >
      <BottomNavigationAction label="全景漫游" icon={<DirectionsWalkIcon/>} value={Five.Mode.Panorama}/>
      <BottomNavigationAction label="空间总览" icon={<ViewInArIcon/>} value={Five.Mode.Floorplan}/>
    </BottomNavigation>
  </Paper>;
}

export { ModeController };

使用模态控制按钮组件

接下来将 ModeController 组件插入到 App 文件的 FiveProvider 中。

import React from "react";
import { createFiveProvider, FiveCanvas } from "@realsee/five/react";
import { useFetchWork } from "./useFetchWork";
import { useWindowDimensions } from "./useWindowDimensions";
// highlight-start
import { ModeController } from "./ModeController";
// highlight-end

/** work.json 的数据 URL */
const workURL = "https://vr-public.realsee-cdn.cn/release/static/image/release/five/work-sample/07bdc58f413bc5494f05c7cbb5cbdce4/work.json";

const FiveProvider = createFiveProvider();
const App = () => {
  const work = useFetchWork(workURL);
  const size = useWindowDimensions();
  return work && <FiveProvider initialWork={work}>
    <FiveCanvas {...size}/>
    // highlight-start
    <ModeController/>
    // highlight-end
  </FiveProvider>;
};

export { App };

回到你的浏览器查看,会发现你的页面底部出现了控制条,点击不同的按钮 全景漫游 空间总览 可以让三维空间改变状态。

真不错 🥳 !

下一章节你会学到

下一章节你会学到
  • 了解什么是 State
  • 如何改变三维空间观察的方向 / 位置。
  • 了解刚才的代码,比如 useCurrentState 及其他响应的是如何工作的。
  • 通过 State 完成了自动环视的功能。