3Sixty Studio Docs

Docs Reference

Project files & format

A 3Sixty Studio project is a plain folder. Knowing its layout helps with backups, moving projects between devices, hosting, and advanced edits. This page is a reference; you never need to edit these files by hand to use the app.

Folder layout

My Project/
├── index.html                  the tour player (rebuilt on every Run and Export)
├── WTMProject.wtm              all tour data, in JSON
├── panoramas/                  360° photos
├── images/                     Image Assets (icons, map, pins, textures)
├── videos/                     MP4 files
├── audios/                     audio clips
├── pdf/                        PDF documents
├── models/                     GLB models
├── customhtml/                 Custom HTML pages
├── js/                         player scripts, incl. 3D helpers added when needed
└── index.before-upgrade.html   backup, only after a template upgrade

Media folders are created when you first open the matching section. The files js/3sixty-gltfloader.js (GLB loader) and js/3sixty-bvh.js (fast collision checks) are copied in by the build when a project has GLB models or 3D scenes.

WTMProject.wtm

WTMProject.wtm is a JSON file (pretty-printed with two spaces) and is the single source of truth for the tour. index.html is regenerated from it. The format is compatible with the older 3Sixty desktop app, in both directions.

{
  "title": "Seaside Hotel",
  "panoramas": [
    {
      "panofile": "lobby.jpg",
      "hotspots": [
        {
          "hotspotid": "ab12cd34ef",
          "title": "To the terrace",
          "position": "212.4818,-35.0021,-335.6620",
          "icon": "arrow.png",
          "scale": 1.5,
          "actions": [ { "type": 0, "target": "terrace.jpg" } ],
          "url": "https://example.com/book",
          "js": "console.log('clicked');"
        }
      ]
    },
    { "panofile": "terrace.jpg", "hotspots": [] }
  ],
  "threedeescenes": [],
  "tourmap": {
    "image": "images/floorplan.png",
    "scale": 0.75,
    "anchor": "center",
    "hotspots": [
      { "image": "images/pin.png", "posX": 42.5, "posY": 61.0,
        "actions": [], "destpano": "lobby.jpg" }
    ]
  },
  "settings": {
    "description": "A virtual walk through the Seaside Hotel.",
    "loadingtext": "Loading...",
    "firstpanorama": "lobby.jpg",
    "panolistmenu": 1,
    "panodraginverted": false,
    "scene3ddraginverted": false,
    "mouselook": true
  }
}

Top level

FieldTypeDescription
titlestringPage title of the tour.
panoramasarrayOne entry per panorama: panofile (file name in panoramas/) and its hotspots.
threedeescenesarray3D scenes. See 3D scene.
tourmapobject or ""The tour map, or an empty string when there is none.
settingsobjectSee Settings.

Hotspot

FieldTypeDescription
hotspotidstringRandom 10-character ID.
titlestringName shown in the editor. Defaults to "Untitled".
positionstring"x,y,z": a point at radius 400 inside the panorama sphere (radius 500).
iconstringFile name in images/. Default default.png.
scalenumberIcon size, 0.25–4. Omitted when 1.
actionsarray{ "type": <code>, "target": "…" } entries. See action codes.
urlstringOptional. The Open URL action.
jsstringOptional. The Execute JavaScript code action.

Action codes

CodeActionTarget format
0Open Panoramalobby.jpg
1Show Imageimages/photo.png
2Play a Videovideos/clip.mp4
3Play an Audioaudios/voice.mp3
4Open a PDF filepdf/brochure.pdf
5Open 3D Scene3dscene:<scene id>
6Open URLA web address. On hotspots it is stored in url; on 3D objects in actions.
7Execute JavaScript codeCode. On hotspots it is stored in js; on 3D objects in actions.
8Show Iframehttps://… or customhtml/page.html

Tour map

FieldTypeDescription
imagestringMap image path, e.g. images/floorplan.png.
scalenumberShare of the screen the map may use, 0.1–1. Default 0.75.
anchorstringcenter for new maps. Missing means topleft (older maps).
hotspots[].imagestringPin image path.
hotspots[].posX, posYnumberPin position in percent (0–100) of the map image.
hotspots[].destpanostringPanorama the pin opens.

Settings

FieldTypeDescription
descriptionstringMeta description.
loadingtextstringLoading screen text. Default "Loading...".
firstpanoramastringMain panorama file name.
panolistmenu1 / 0Show Panorama List.
panodraginvertedbooleanInverted drag in panoramas.
scene3ddraginvertedbooleanInverted drag in 3D scenes.
mouselookbooleanEnable Mouse Look.

3D scene

{
  "id": "3dscene_Ab3dE9xY",
  "name": "Gallery",
  "cameraPos": { "x": 0, "y": 1.6, "z": 5 },
  "cameraYaw": 0,
  "cameraPitch": 0,
  "objects": [
    {
      "id": "obj_1767225600000_cube",
      "type": "cube", "name": "Door",
      "posX": 0, "posY": 1, "posZ": -4,
      "rotX": 0, "rotY": 0, "rotZ": 0,
      "scaleX": 1, "scaleY": 1, "scaleZ": 1,
      "materialType": "texture", "color": 16777215, "texture": "door.png",
      "opacity": 1, "width": 1, "height": 2, "depth": 0.1,
      "actions": [ { "type": 0, "target": "lobby.jpg" } ],
      "isTrigger": false,
      "animation": {
        "duration": 2.0, "loop": true,
        "keyframes": [
          { "t": 0, "posX": 0, "posY": 1, "posZ": -4, "rotX": 0, "rotY": 0, "rotZ": 0,
            "scaleX": 1, "scaleY": 1, "scaleZ": 1, "ease": "easeInOut" },
          { "t": 1, "posX": 0, "posY": 1, "posZ": -4, "rotX": 0, "rotY": 90, "rotZ": 0,
            "scaleX": 1, "scaleY": 1, "scaleZ": 1, "ease": "easeInOut" }
        ]
      }
    }
  ],
  "environment": {
    "skyboxType": "panorama",
    "skyboxPanorama": "terrace.jpg",
    "lights": {
      "ambient": true, "hemisphere": true, "directional": true,
      "ambientIntensity": 1.0, "hemisphereIntensity": 0.9, "directionalIntensity": 1.0,
      "directionalAzimuth": 38.66, "directionalElevation": 49.51
    }
  }
}
  • cameraPos, cameraYaw, cameraPitch: the spawn point (eye position, angles in degrees).
  • type: cube, sphere, plane or model (model holds a file name from models/).
  • color: an integer RGB value (16777215 = 0xFFFFFF, white). materialType is color or texture; texture is a file name from images/.
  • animation.keyframes[].ease: linear, easeIn, easeOut or easeInOut.
  • environment.skyboxType: none, color (with skyboxColor like #111122) or panorama (with skyboxPanorama).

index.html and build markers

index.html is a copy of the app's tour template. On every Run and Export, 3Sixty Studio replaces the content between pairs of comment markers with freshly generated code and leaves everything else alone:

MarkersFilled with
<!--projecttitle--> … <!--projecttitle-end-->The <title> tag
<!--projectdescription--> … -end-->The meta description
<!--loadingtext--> … -end-->The loading text
/*initfunction*/ … /*initfunction-end*/The first panorama to load
/*panoramas*/ … /*panoramas-end*/Hotspots and their actions, per panorama
/*customjs*/ … /*customjs-end*/Tour UI (toolbar, pop-ups), controls, tour map, panorama list, Mouse Look
/*threedeescenes-data*/ … -end*/3D scene data and the first-person runtime