janusweb 1.5.56 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.github/workflows/deploy.yml +71 -0
  2. package/Dockerfile +14 -0
  3. package/README.md +258 -19
  4. package/janusxr.com/.args +2 -0
  5. package/janusxr.com/.init.lua +30 -0
  6. package/media/assets/webui/apps/comms/voip.js +27 -25
  7. package/media/assets/webui/apps/editor/editor.js +16 -0
  8. package/media/assets/webui/apps/locomotion/locomotion-assets.json +3 -0
  9. package/media/assets/webui/apps/locomotion/teleport.mp3 +0 -0
  10. package/media/assets/webui/apps/locomotion/teleporter.js +75 -43
  11. package/media/assets/webui/apps/navigation/navigation.js +6 -1
  12. package/media/assets/webui/apps/xrfragment/level0-sidecarfile.js +308 -0
  13. package/media/assets/webui/apps/xrfragment/level2-hyperlink.js +265 -0
  14. package/media/assets/webui/apps/xrfragment/level7-engine-prefixes.export.js +93 -0
  15. package/media/assets/webui/apps/xrfragment/level7-engine-prefixes.import.js +229 -0
  16. package/media/assets/webui/apps/xrfragment/patch/metaquest-fix-flickering.js +15 -0
  17. package/media/assets/webui/apps/xrfragment/xrfragment.json +14 -0
  18. package/media/assets/webui/apps/xrmenu/images/teleport.png +0 -0
  19. package/media/assets/webui/apps/xrmenu/xrmenu-assets.json +2 -1
  20. package/media/assets/webui/apps/xrmenu/xrmenu.js +39 -15
  21. package/media/assets/webui/default.json +1 -0
  22. package/media/images/portal.svg +130 -0
  23. package/media/index.html +48 -1
  24. package/package.json +1 -1
  25. package/scripts/client.js +24 -0
  26. package/scripts/config.js +12 -1
  27. package/scripts/janusbase.js +14 -22
  28. package/scripts/janusghost.js +2 -2
  29. package/scripts/janusparagraph.js +195 -12
  30. package/scripts/janusplayer.js +9 -6
  31. package/scripts/room.js +91 -44
  32. package/scripts/sound.js +1 -1
  33. package/scripts/text.js +2 -1
  34. package/scripts/translators/paragraph/html-xml-rss.js +47 -0
  35. package/scripts/translators/peertube.js +89 -0
  36. package/scripts/translators/xrfragments.js +93 -0
  37. package/tests/room/paragraph.xml +47 -0
  38. package/utils/build.sh +1 -0
  39. package/utils/clean-build.sh +5 -0
  40. package/utils/dev-link.sh +75 -0
  41. package/utils/release.binary.sh +36 -0
  42. package/utils/release.docker.sh +11 -0
@@ -0,0 +1,71 @@
1
+ name: Build and Deploy to Pages
2
+
3
+ on:
4
+ push:
5
+ # Monitor all branches so we can catch '#deploy' in commit messages
6
+ branches: ["**"]
7
+ tags:
8
+ - "v*.*.*"
9
+
10
+ permissions: write-all
11
+
12
+ # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
13
+ concurrency:
14
+ group: "pages"
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ build-and-deploy:
19
+ # Run only on the master branch OR if the commit message contains '#deploy'
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - name: Checkout code
24
+ uses: actions/checkout@v4
25
+
26
+ - name: Setup Node.js
27
+ uses: actions/setup-node@v4
28
+ with:
29
+ node-version: '20' # Change to your preferred version
30
+ cache: 'npm' # Only works if you have a package-lock.json
31
+
32
+ - name: Install dependencies
33
+ # Only runs if package.json exists; avoids errors if it doesn't
34
+ run: |
35
+ if [ -f package.json ]; then
36
+ npm install
37
+ fi
38
+
39
+ - name: Run build script
40
+ run: |
41
+ chmod +x ./utils/build.sh
42
+ ./utils/build.sh
43
+ ./utils/release.binary.sh
44
+
45
+ - name: Create Release and Upload Assets
46
+ uses: softprops/action-gh-release@v3
47
+ with:
48
+ files: |
49
+ build/janusweb-*.tar.gz
50
+ build/*/janusxr.com
51
+ #env: # only needed when creating a release in other repo
52
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53
+
54
+ - name: Organize build artifacts
55
+ # Creates a clean 'www' folder and copies your build/sub/folders into it
56
+ run: |
57
+ mkdir -p www
58
+ cp -r build/*/* www/ 2>/dev/null || cp -r build/* www/
59
+
60
+ - name: Setup Pages
61
+ uses: actions/configure-pages@v4
62
+
63
+ - name: Upload artifact
64
+ uses: actions/upload-pages-artifact@v3
65
+ with:
66
+ path: 'www'
67
+
68
+ - name: Deploy to GitHub Pages
69
+ id: deployment
70
+ uses: actions/deploy-pages@v4
71
+
package/Dockerfile ADDED
@@ -0,0 +1,14 @@
1
+ FROM busybox:latest
2
+
3
+ ARG JANUSXR_VERSION="1.5.56"
4
+
5
+ WORKDIR /www
6
+ COPY build/$JANUSXR_VERSION/janusxr.com .
7
+
8
+ # assimilate the crossplatform binary into host architecture
9
+ # otherwise docker will complain with 'Exec format error'
10
+ RUN wget https://cosmo.zip/pub/cosmos/bin/assimilate && \
11
+ chmod +x assimilate && \
12
+ ./assimilate ./janusxr.com
13
+
14
+ CMD ["/www/janusxr.com"]
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center"><a href="https://web.janusvr.com" target="_blank"><img width="480" alt="JanusWeb" src="https://imgur.com/ejvyphR.jpg"></a></p>
2
2
 
3
- <p align="center"><b>A web framework for building social virtual reality experiences.</b></p>
3
+ <p align="center"><b>A web framework/browser for building rich virtual reality experiences.</b></p>
4
4
 
5
5
  <div align="center">
6
6
  <a href="https://janusvr.com">Site</a>
@@ -11,7 +11,9 @@
11
11
  &mdash;
12
12
  <a href="https://web.janusvr.com">Demo</a>
13
13
  &mdash;
14
- <a href="https://github.com/madjin/janus-guide">Docs</a>
14
+ <a href="https://coderofsalvation.github.io/janus-guide/">Docs</a>
15
+ &mdash;
16
+ <a href="https://discord.gg/7eyK2wE">Discord</a>
15
17
  </div>
16
18
 
17
19
 
@@ -39,20 +41,24 @@
39
41
 
40
42
  ## Features
41
43
 
44
+ - [Open Immersive Web-layer](https://madjin.github.io/janus-guide/#/home/about) for browsing XR experiences across the web
42
45
  - Build immersive 3D environments for desktop, mobile, and VR devices using HTML and JS
43
46
  - Rendering functionality provided by Three.js / WebGL
47
+ - Separately host WebXR experiences via ([JML](https://madjin.github.io/janus-guide/#/examples/markup) in) any textfile.
44
48
  - Oculus Rift, Vive, GearVR, Daydream, and Cardboard support via WebVR API
45
- - Realtime collaboration across all devices via built-in networking
49
+ - [Realtime collaboration](https://madjin.github.io/janus-guide/#/home/usecases) across all devices via built-in networking
46
50
  - Import Collada, OBJ, glTF, and other popular 3d file formats
47
51
  - 3D positional audio
48
52
  - Gamepad support via the HTML5 Gamepad API
49
53
  - Supports hand tracking peripherals like Leap Motion, Oculus Touch, and Vive controllers
50
54
  - Support for 2d, sbs3d/ou3d, and 360 degree video textures using HTML5 Video
51
55
  - Scriptable client enables many customized uses
56
+ - And [much more](https://madjin.github.io/janus-guide/#/home/toc)
57
+
52
58
 
53
59
  ## Using
54
60
 
55
- There are several different ways to use JanusWeb, depending on how much control you want to
61
+ There are [several different ways](https://madjin.github.io/janus-guide/#/home/usecases) to use JanusWeb, depending on how much control you want to
56
62
  have over the whole system.
57
63
 
58
64
  ### Use our viewer
@@ -64,10 +70,188 @@ You can even put your mark-up onto sites like PasteBin or PiratePad. Then just
64
70
  in our viewer by entering the URL into the navigation bar, and you can link directly to it, share
65
71
  on social media, or embed our viewer directly into other webpages, blog posts, or articles.
66
72
 
67
- See also **Using a specific version of JanusWeb** below.
73
+ ### Single-binary server+client
74
+
75
+ Use our all-in-one **janusxr.com** multi-platform binary file:
76
+ Run a **local-first** viewer locally on your desktop, raspberry pi (ARM64) or server.<br>
77
+
78
+ | executable | platforms |
79
+ |-|-|
80
+ | [janusxr.com](https://jbaicoianu.github.io/janusweb/janusxr.com) | <img src="https://i.imgur.com/v7cYVq1.png"/> |
81
+
82
+ Run `janusxr.com` from anywhere, or put it into a folder with your 3D models or JanusXR rooms:
83
+
84
+ ```
85
+ $ chmod +x janusxr.com # only for non-windows users
86
+
87
+ $ ./janusxr.com
88
+ I2026-01-19T15:41:10 (srvr) listen http://127.0.0.1:8080
89
+ I2026-01-19T15:41:10 (srvr) listen http://192.168.1.168:8080
90
+ Launching browser..
91
+ ```
92
+
93
+ A browser will popup, and connect to `https://janusxr.org` via Janusweb.<br>
94
+ Webbrowsers on the same network can access your node `https://192.168.1.168:8080`
95
+
96
+ > Optionally, you can expose this janusweb-node to the internet. Check [here](https://redbean.dev) for more commandline options.
97
+ </details>
98
+
99
+ <details>
100
+ <summary><b>Usecase:</b> 3D file viewer</summary>
101
+ <br>
102
+ Make sure `janusxr.com` is in a folder with your 3D models
103
+
104
+ ```
105
+ $ ls
106
+ janusxr.com
107
+ world1.glb
108
+ world2.glb
109
+ ```
110
+
111
+ Then make sure you rename `janusxr.com` to whatever you want to set as homepage:
112
+
113
+ ```
114
+ $ mv janusxr.com world1.com
115
+ $ ./world1.com
116
+ I2026-01-19T15:41:10 (srvr) listen http://127.0.0.1:8080
117
+ I2026-01-19T15:41:10 (srvr) listen http://192.168.1.168:8080
118
+ ✅ detected /world1.glb (setting as spatial home)
119
+ Launching browser..
120
+ ```
121
+ </details>
122
+
123
+ <details>
124
+ <summary><b>Usecase:</b> all-in-one JanusXR runtime</summary>
125
+ <br>
126
+ You can bundle all your XR experiences with the server/client binary.<br>
127
+ Just Make sure `janusxr.com` is in a folder with your JanusXR rooms or 3D models
128
+
129
+ ```
130
+ $ ls
131
+ janusxr.com
132
+ world1.html
133
+ world2.html
134
+ foo.glb
135
+ ```
136
+
137
+ Then make sure you rename `janusxr.com` to whatever you want to set as homepage:
138
+
139
+ ```
140
+ $ zip -r janusxr.com * # add janus files to janusxr.com
141
+ $ mv janusxr.com world1.com # hint homepage room (world1.html) sidecarfile
142
+ $ ./world1.com
143
+ ✅ detected /world1.html (setting as spatial home)
144
+ I2026-01-19T15:41:10 (srvr) listen http://127.0.0.1:8080
145
+ I2026-01-19T15:41:10 (srvr) listen http://192.168.1.168:8080
146
+ Launching browser..
147
+ ```
148
+
149
+ Profit! You can now send `world1.com` to a friend, and his browser will launch straight into world1.html
150
+
151
+ > NOTE: you can also point directly to a 3D model (`foo.com` would load `foo.glb`) or PDF-file etc!
152
+ </details>
153
+
154
+
155
+ <details>
156
+ <summary><b>Usecase:</b> run as a docker</summary>
157
+ <br>
158
+ You can run our docker-image as following:
159
+
160
+ ```
161
+ $ docker run -p 8080:8080 codeberg.org/coderofsalvation/janusxr:1.5.56
162
+ ```
163
+
164
+ Profit! You can now point your browser to `http://localhost:8080` or configure your reverseproxy for SSL certs/domain etc.<br>
165
+ Or optionally, serve your own XR experiences with it:
166
+
167
+ ```
168
+ $ ls
169
+ myworld1.xml myworld2.html myworld3.glb
170
+ $
171
+ $ docker run -p 8081:8080 -v $(pwd):/data codeberg.org/coderofsalvation/janusxr:1.5.56 /www/janusxr.com -D /data
172
+ ```
173
+
174
+ Profit! You can now use URLs like `http://localhost:8080/#janus.url=https://localhost:8080/myworld1.xml` e.g.<br>
175
+ Btw. you can build the docker image yourself too:
176
+
177
+ ```
178
+ $ utils/release.binary.sh # build the janusxr.com binary
179
+ $ docker build -t janusxr.com .
180
+ $ docker run -p 8080:8080 janusxr
181
+ ```
182
+
183
+ </summary>
184
+ </details>
185
+
186
+ <details>
187
+ <summary><b>Usecase:</b> serve all-in-one-binary in different docker/OCI container</summary>
188
+ <br>
189
+
190
+ Make sure to run you're in a folder with your JanusXR rooms or 3D models, and `janusxr.com`
191
+
192
+ ```
193
+ $ ls
194
+ janusxr.com
195
+
196
+ $ unzip janusxr.com # extract the viewer files
197
+
198
+ $ ls
199
+ janusxr.com
200
+ world1.html
201
+ world2.html
202
+ foo.glb
203
+
204
+ $ docker run -d -v ./:/www -p 8080:8080 --name janusweb busybox:latest /bin/httpd -f -h /www -p 8080
205
+ e7928798379e872983b7ec9b89237ebc
206
+
207
+ $ docker ps
208
+ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
209
+ 6711ed9739f3 docker.io/library/busybox:latest /bin/httpd -f -h ... 16 seconds ago Up 16 seconds 0.0.0.0:8080->8080/tcp janusweb
210
+ ```
211
+
212
+ Profit! You can now point your browser to `http://127.0.0.1:8080` or configure your reverseproxy for SSL certs/domain etc.
213
+
214
+ </details>
215
+
216
+ <details>
217
+ <summary><b>Usecase:</b> deploy janusweb as github/gitlab/codeforge webpage</summary>
218
+
219
+ <br>
220
+ *TODO* provide action-files
221
+ </details>
222
+
223
+ <details>
224
+ <summary><b>Usecase:</b> get the latest build files</summary>
225
+
226
+ <br>
227
+ Sometimes, developers just want the latest janusweb **files**.<br>
228
+ Good news, the executable is also a zip-file.<br>
229
+
230
+ ```
231
+ $ ls
232
+ janusxr.com
233
+ $ unzip janusxr.com
234
+ $ ls
235
+ index.html
236
+ janusweb.js
237
+ (...)
238
+
239
+ $ janusxr.com
240
+ I2026-01-19T15:41:10 (srvr) listen http://127.0.0.1:8080
241
+ I2026-01-19T15:41:10 (srvr) listen http://192.168.1.168:8080
242
+ Launching browser..
243
+
244
+ ( the webserver will prioritize the unzipped files )
245
+
246
+ $ zip janusxr.com index.html # you can even update the binary
247
+ ```
248
+
249
+ > Profit!
250
+
251
+ </details>
68
252
 
69
253
  ### Pull our scripts into your page
70
- Using the above method, all of your links would go through our servers. If you'd prefer to
254
+ Using the above method, all of your links would go through community CORS-proxies. If you'd prefer to
71
255
  link to your own servers, you can pull our JS into your page and use JanusWeb as a scriptable
72
256
  client via its API. This looks something like this:
73
257
 
@@ -91,13 +275,38 @@ client via its API. This looks something like this:
91
275
  ```
92
276
 
93
277
  The `elation.janusweb.init()` function can take a number of arguments, and returns a promise which
94
- receives an instance of the client. This client reference can be controlled via its API. See the
95
- sections on **Arguments** and **Scripting** below.
278
+ receives an instance of the client. This client reference can be controlled via its API:
96
279
 
97
- See also **Using a specific version of JanusWeb** below.
280
+ ```html
281
+ <html>
282
+ <head>
283
+ <title>My JanusVR Room</title>
284
+ </head>
285
+ <body>
286
+ <script src="https://web.janusvr.com/janusweb.js"></script>
287
+ <script>
288
+ elation.janusweb.init({url: document.location.href })
289
+ .then( (client)=> console.log("rendering this page's virtual twin") )
290
+ </script>
291
+
292
+ <!--
293
+ <fireboxroom>
294
+ <room use_local_asset="room1">
295
+ <object id="cube" pos="0 1 5" />
296
+ <text col="1 0 0" pos="0 2 4">my first room</text>
297
+ </room>
298
+ </fireboxroom>
299
+ -->
98
300
 
99
- ### Install from ZIPs
100
- (TODO - we will start shipping zip builds of JanusWeb once we release v1.0)
301
+ </body>
302
+ </html>
303
+ ```
304
+
305
+ > **NOTE**: you can also update the `janusxr.com` binary to your likings: (`unzip janusxr.com index.html && vi index.html && zip janusxr.com index.html` see 'get the latest build files' above)
306
+
307
+ See the sections on **Arguments** and **Scripting** below.
308
+
309
+ > See also **Using a specific version of JanusWeb** below.
101
310
 
102
311
  ### Install from NPM
103
312
  (TODO - we will start shipping official NPM packages of JanusWeb once we release v1.0)
@@ -126,7 +335,9 @@ JanusWeb supports several arguments at initialization time to control how it beh
126
335
  <table>
127
336
  <tr><th> Name </th><th> Description </th><th> Default </th></tr>
128
337
 
129
- <tr><td> autoload </td><td> Load URL by default or wait for script </td><td> true </td></tr>
338
+ <tr><td> autostart </td><td> call `elation.janusweb.init({..})` automatically or manually </td><td> true </td></tr>
339
+
340
+ <tr><td> autoload </td><td> Load URL by default or wait for script </td><td> true </td></tr>
130
341
 
131
342
  <tr><td> crosshair </td><td> Show player crosshair </td><td> true </td></tr>
132
343
 
@@ -142,10 +353,6 @@ JanusWeb supports several arguments at initialization time to control how it beh
142
353
 
143
354
  <tr><td> server </td><td> Presence server to connect to </td><td> wss://presence.janusvr.com:5567/</td></tr>
144
355
 
145
- <tr><td> shownavigation </td><td> Control visibility of navigation bar </td><td> true </td></tr>
146
-
147
- <tr><td> showchat </td><td> Control visibility of chat </td><td> true </td></tr>
148
-
149
356
  <tr><td> stats </td><td> Enable render performance stats </td><td> false </td></tr>
150
357
 
151
358
  <tr><td> url </td><td> Default page to load </td><td> (homepage) </td></tr>
@@ -160,12 +367,18 @@ JanusWeb supports several arguments at initialization time to control how it beh
160
367
  for Opus via WebAudio) </td><td> false </td></tr>
161
368
  </table>
162
369
 
370
+ > NOTE: see [client.js](https://github.com/jbaicoianu/janusweb/blob/master/scripts/client.js#L65) for the most up to date arguments
371
+
163
372
  ## Scripting
164
373
  After initializing the client, `elation.janusweb.init()` returns a Promise which provides a reference to the client.
165
374
  You can programatically control this client to do all sorts of things. For instance, we can make the client load a
166
375
  URL, wait for the world and all of its assets to load, and then take a screenshot of the world after a specified delay:
167
376
 
168
377
  ```javascript
378
+ <janus-viewer autostart="false"> <!-- disable autostart, we will -->
379
+ </janus-viewer> <!-- call elation.janusweb.init() -->
380
+
381
+ <script>
169
382
  var pageinfo = elation.utils.parseURL(document.location.href),
170
383
  urlargs = pageinfo.args || {},
171
384
  hashargs = pageinfo.hash || {};
@@ -173,11 +386,11 @@ var pageinfo = elation.utils.parseURL(document.location.href),
173
386
  var url = elation.utils.any(hashargs.url, urlargs.url, 'http://www.janusvr.com/index.html'),
174
387
  delay = elation.utils.any(hashargs.delay, urlargs.delay, 1000);
175
388
 
176
- elation.janusweb.init({
389
+ elation.janusweb.init({
177
390
  url: url,
178
391
  resolution: '1920x1080',
179
- showchat: false,
180
- shownavigation: false
392
+ uiconfig: "./media/assets/webui/default.json" // tweak ui here
393
+ // more options at https://github.com/jbaicoianu/janusweb/blob/master/scripts/client.js#L93
181
394
  }).then(function(client) {
182
395
  elation.events.add(client.janusweb.currentroom, 'room_load_complete', function() {
183
396
  setTimeout(function() {
@@ -188,7 +401,9 @@ elation.janusweb.init({
188
401
  });
189
402
  }, delay);
190
403
  });
404
+ elation.janusweb.init = function(){} // init only once
191
405
  });
406
+ </script>
192
407
 
193
408
  ```
194
409
 
@@ -209,6 +424,30 @@ If you need to load a specific version of JanusWeb, all previous versions are st
209
424
 
210
425
  JanusWeb versions follow the [Semantic Versioning 2.0.0](http://semver.org/) spec, which follows the format ```<major>.<minor>.<patch>``` - for example, at the time of writing (March 2017) the current stable release is **1.0.15**. So if you want to view this version, you could go to https://web.janusvr.com/1.0.15/ and if you wanted to pull this specific version into your page, you could do so with ```<script src="https://web.janusvr.com/1.0.15/janusweb.js"></script>```. We also support aliases for the most current version - for instance, https://web.janusvr.com/1.0/ will always refer to the most recent 1.0 release, https://web.janusvr.com/0.9/ the final 0.9 release, etc.
211
426
 
427
+ ## Ecosystem
428
+
429
+ Platforms using JanusXR + JanusWeb:
430
+
431
+ | | URL | source / docker |
432
+ |----|-----|------------|
433
+ | <img src="https://imgur.com/JMYi81Z.png"/><br><br> | [vesta.janusxr.org](https://vesta.janusxr.org) | |
434
+ | <img src="https://codeberg.org/coderofsalvation/xrforge/media/branch/master/xrforge.jpg"/><br><br> | [xrforge.isvery.ninja](https://xrforge.isvery.ninja) | [codeberg.org](https://codeberg.org/coderofsalvation/xrforge)
435
+
436
+ Visualisations of hyperlinked Janus clusters across the web:
437
+ * [augmentedperception.com](https://augmentedperception.com)
438
+ * [panopticon](https://panopticon.spyduck.net/)
439
+
440
+ Extra Tools / Components:
441
+ * [custom components](https://github.com/jbaicoianu/janus-custom-components)
442
+ * [janusxr-cli](https://github.com/coderofsalvation/janusxr-cli) swiss army CLI knife for room health/preservation #cli
443
+ * [corsanywhere](https://github.com/Rob--W/cors-anywhere) for hasslefree hopping clusters #stack
444
+ * [janus-gateway](https://janus.conf.meetecho.com/) webrtc/voip-layer [docs](https://janus.conf.meetecho.com/) #stack
445
+ * [janus-server](https://github.com/janusvr/janus-server) multiuser presence layer #stack
446
+
447
+ Reference:
448
+ * [quick scripting reference](https://github.com/jbaicoianu/janusweb/wiki/Scripting-Support-2.0)
449
+ * [janus guide](https://coderofsalvation.github.io/janus-guide/)
450
+
212
451
  ## Contributing
213
452
  JanusWeb is open source, and we welcome any contributions! Please do report bugs using GitHub Issues,
214
453
  and all pull requests will be considered. We could especially use help with documentation!
@@ -0,0 +1,2 @@
1
+ -D
2
+ .
@@ -0,0 +1,30 @@
1
+ HidePath("/usr/share/zoneinfo/")
2
+ HidePath("/usr/share/ssl/")
3
+ homepage = false
4
+ homepath = false
5
+ home = arg[-1]:gsub(".*/","")
6
+ :gsub(".com","")
7
+ ext = { "txt", "xml", "html", "pdf", "mp3", "yaml", "json", "xlsx", "png", "jpg", "glb", "gltf", "dae", "obj"}
8
+ for k,v in pairs(ext) do
9
+ file = string.format("%s.%s", home, v)
10
+ if( path.exists( file ) ) then homepath = "/" .. file; end
11
+ end
12
+
13
+ if( homepath ) then
14
+ print("✅ detected " .. homepath .. " (setting as spatial home)")
15
+ homepage = Slurp("/zip/index.html"):gsub("<janus%-viewer .-</janus%-viewer>","<janus-viewer src=\"" .. homepath .. "\"></janus-viewer>")
16
+
17
+ function OnHttpRequest()
18
+ path = GetPath()
19
+ if( homepage and path == "/" ) then
20
+ SetStatus(200)
21
+ SetHeader("Content-Type", "text/html; charset=utf-8")
22
+ SetHeader("Access-Control-Allow-Origin", "*")
23
+ Write(homepage)
24
+ else
25
+ Route()
26
+ end
27
+ end
28
+ end
29
+ LaunchBrowser()
30
+
@@ -681,35 +681,37 @@ console.log('[voip-remoteuser] got a remote voip user', data);
681
681
  this.audio = audio;
682
682
  this.appendChild(audio);
683
683
 
684
- audio.play()
685
- .then(() => {
686
- console.log('[voip-remoteuser] remote user audio playing', audio, this);
687
- this.hasaudio = true;
688
- });
684
+ room.getAudioNodes().then(() => {
685
+ audio.play()
686
+ .then(() => {
687
+ console.log('[voip-remoteuser] remote user audio playing', audio, this);
688
+ this.hasaudio = true;
689
+ });
689
690
 
690
- let listener = player.engine.systems.sound.getRealListener();
691
- let context = listener.context;
692
- let analyser = context.createAnalyser();
693
- let source = context.createMediaStreamSource(audio.srcObject);
694
- source.connect(analyser);
691
+ let listener = player.engine.systems.sound.getRealListener();
692
+ let context = listener.context;
693
+ let analyser = context.createAnalyser();
694
+ let source = context.createMediaStreamSource(audio.srcObject);
695
+ source.connect(analyser);
695
696
 
696
- analyser.fftSize = 32;
697
- this.analyser = analyser;
698
- this.audiobuffer = new Uint8Array(analyser.frequencyBinCount);
697
+ analyser.fftSize = 32;
698
+ this.analyser = analyser;
699
+ this.audiobuffer = new Uint8Array(analyser.frequencyBinCount);
699
700
 
700
- if (this.updateVolumeInterval) {
701
- clearInterval(this.updateVolumeInterval);
702
- this.updateVolumeInterval = false;
703
- }
704
- this.updateVolumeInterval = setInterval(() => {
705
- analyser.getByteFrequencyData(this.audiobuffer);
706
- let sum = 0;
707
- for (let i = 0; i < this.audiobuffer.length; i++) {
708
- sum += this.audiobuffer[i];
701
+ if (this.updateVolumeInterval) {
702
+ clearInterval(this.updateVolumeInterval);
703
+ this.updateVolumeInterval = false;
709
704
  }
710
- let avg = sum / this.audiobuffer.length;
711
- this.updateVolume(avg / 100);
712
- }, 20);
705
+ this.updateVolumeInterval = setInterval(() => {
706
+ analyser.getByteFrequencyData(this.audiobuffer);
707
+ let sum = 0;
708
+ for (let i = 0; i < this.audiobuffer.length; i++) {
709
+ sum += this.audiobuffer[i];
710
+ }
711
+ let avg = sum / this.audiobuffer.length;
712
+ this.updateVolume(avg / 100);
713
+ }, 20);
714
+ });
713
715
  }
714
716
 
715
717
  let remoteuser = janus.network.remoteplayers[this.id];
@@ -320,7 +320,23 @@ console.log('set translation snap', ev.data, ev);
320
320
  }
321
321
  handleExportClick(ev) {
322
322
  let exporter = new THREE.GLTFExporter();
323
+ let userDatas = new Map();
324
+ // Store and nullify userData objects for each object before serializing
325
+ room._target.objects['3d'].traverse(n => {
326
+ userDatas.set(n, n.userData);
327
+ n.userData = {};
328
+ elation.events.fire({element: this, type: 'webui_editor_export_node', data:{n,userData: userDatas.get(n)} })
329
+ });
330
+ elation.events.fire({element: this, type: 'webui_editor_export', data:{ scene: room._target.objects['3d']} })
331
+
323
332
  exporter.parse(room._target.objects['3d'], (data) => {
333
+ // Restore userData objects
334
+ room._target.objects['3d'].traverse(n => {
335
+ if (userDatas.has(n)) {
336
+ n.userData = userDatas.get(n);
337
+ }
338
+ });
339
+
324
340
  let filedata = new Blob([data], {type: 'model/gltf-binary'});
325
341
 
326
342
  var url = window.URL.createObjectURL(filedata);
@@ -0,0 +1,3 @@
1
+ [
2
+ { "assettype": "sound", "name": "button-teleport", "src": "./teleport.mp3" }
3
+ ]