Skip to main content
Documentation

Displaying a 3D Space

Parse, load, and display Realsee work data with Five SDK in vanilla JavaScript or TypeScript.

Recap of the previous chapter: Getting Started

- You learned how to set up your environment.

- And you wrote some code that, although you didn't yet know what it did, successfully rendered a 3D space on screen.

What you will learn in this chapter

  • Understanding what a Work is.
  • Understanding how parseWork(json) and five.load(work) work.

Preparation

As in the previous chapter, create a new directory (src/1.displaying-work) along with the corresponding html file and the js or ts file.

You can start by copying the contents of the previous chapter into your jsx or tsx file.

<!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 { Five, parseWork } from "@realsee/five";

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

const five = new Five();

five.appendTo(document.querySelector("#app"));

fetch(workURL)
  .then((res) => res.json())
  .then((json) => {
    const work = parseWork(json);
    five.load(work);
  });

window.addEventListener("resize", () => five.refresh(), false);

export {};

Start the dev server with npm run dev and navigate to the current page at " \<http://localhost:3000/src/1.displaying-work.index.html\> ".

Tip

Check your console — the port number may change depending on your configuration and which ports are currently in use, so rely on the console output. If you use another build tool, start the server according to that tool's requirements.

What is a Work

Now put down your keyboard for a moment — let's understand a few concepts. Don't worry, it's simple.

Introducing Work

We call a 3D space a Work. A Work is described by a JSON structure called work.json. You can obtain a Work through Realsee OpenAPI (see the API reference) or, as in this example, use it as a static file.

Five SDK provides the parseWork method to parse work.json and produce a Work object. Passing the Work object into the load method initializes the scene. This is exactly what you did in the previous chapter.

Usage restrictions for a Work

A production Work can include domain and availability restrictions in its allow_hosts and expire_at fields. Five SDK enforces the values supplied with the Work data.

The restrictions above are not validated in the following cases, to make development and testing easier:

  • The domain is localhost.
  • The domain is an IP address, such as 127.0.0.1, 192.168.0.5, 172.30.2.0, 10.33.10.2, and so on.
  • The page is accessed over a non-HTTP protocol, such as the file:// protocol.

Sample data and field descriptions for work.json

You don't need to understand the contents of work.json to use Five SDK effectively.

That said, a little extra knowledge never hurts.

Click to view 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: digital signature of the Work content
  • expire_at: expiration time of the Work
  • allow_hosts: secure domains of the Work
  • initial: initialization data, which is a piece of State data. It describes the pose of the initial state in which the Work is loaded, also known as the VR initial viewpoint
    • mode: display mode
    • pano_index: initial capture point
    • longitude: the camera's horizontal angle
    • latitude: the camera's vertical angle (pitch)
    • fov: the camera's vertical field of view
  • model: the 3D model
    • file_url: the resource URL of the 3D model; the .at3d file is Realsee's custom model format
    • material_textures: the resource URLs of the 3D model's textures
  • panorama: panorama color information
    • list:
      • up / down / left / right / front / back: panorama color information is stored and used as a cubemap.
  • observers: capture point information
    • visible_nodes: the inter-point visibility list
    • accessible_nodes: the inter-point connectivity list
    • quaternion: the rotation offset between the capture point and the model coordinates
    • standing_position: the ground coordinates of the capture point
    • position: the coordinates of the capture point
    • floor_index: the floor of the capture point

The Work object

Compared with the work.json above, the object you will more commonly work with is the Work object, which is the output of the parseWork function. The Work object is more nicely serialized than work.json. See the Five SDK API documentation for full details.

Multiple display modes

Five SDK ships with several built-in display modes. By default it displays the panorama mode — the same result you ended up with in the previous chapter. We can also display the model mode to view the 3D space from a macro perspective. To switch between them we'll use the state property, the setState() method, and the stateChange event provided by the Five SDK. The detailed State content will be covered in the next chapter; for now, let's simply implement a mode-switching button.

Adding UI buttons

To keep the example code simple, we use Bootstrap as the UI library.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link rel="icon" href="data:;base64,iVBORw0KGgo=" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Displaying work</title>
    <!-- highlight-start -->
    <!-- Add the Bootstrap UI styles -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      crossorigin="anonymous"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"
      rel="stylesheet"
    />
    <style>
      html,
      body,
      #app {
        width: 100%;
        height: 100%;
        overflow: hidden;
      }
    </style>
    <!-- highlight-end -->
  </head>
  <body>
    <div id="app"></div>
    <!-- highlight-start -->
    <!-- Mode switching -->
    <nav class="navbar fixed-bottom navbar-light bg-light">
      <div class="container-fluid justify-content-center">
        <div class="btn-group">
          <a href="javascript:;" class="btn btn-primary active js-Panorama"
            >Panorama walkthrough</a
          >
          <a href="javascript:;" class="btn btn-primary js-Floorplan"
            >Space overview</a
          >
        </div>
      </div>
    </nav>
    <!-- highlight-end -->
    <script type="module" src="./index"></script>
  </body>
</html>

Using the setState method and the stateChange event

  • five.setState({ mode }) lets Five SDK switch between different display modes.
  • five.state.mode lets you read which display mode Five SDK is currently in.
  • The stateChange event lets you listen for changes to state, which of course includes state.mode.
import { Five, parseWork } from "@realsee/five";

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

const five = new Five();

five.appendTo(document.querySelector("#app"));

fetch(workURL)
  .then((res) => res.json())
  .then((json) => {
    const work = parseWork(json);
    five.load(work);
  });

window.addEventListener("resize", () => five.refresh(), false);

// highlight-start
{
  // === Mode switching ===
  const buttons = {
    Panorama: document.querySelector(".js-Panorama"),
    Floorplan: document.querySelector(".js-Floorplan"),
  };

  for (const [modeName, element] of Object.entries(buttons)) {
    element.addEventListener(
      "click",
      () => {
        five.setState({ mode: modeName });
      },
      false
    );
  }

  five.on("stateChange", (state) => {
    for (const [modeName, element] of Object.entries(buttons)) {
      if (modeName === state.mode) {
        element.classList.add("active");
      } else {
        element.classList.remove("active");
      }
    }
  });
}
// highlight-end

export {};

Go back to your browser and you'll see a control bar at the bottom of the page. Click the different buttons — Panorama walkthrough and Space overview — to change the state of the 3D space.

Awesome 🥳!

What you will learn in the next chapter

What you will learn in the next chapter

  • Understanding what State is.
  • How to change the direction / position from which the 3D space is observed.
  • Understanding how the code you just wrote works, such as setState and stateChange.
  • Implementing an automatic look-around feature using State.