feat/godot wip
This commit is contained in:
parent
606133289d
commit
dd2434a3ed
|
@ -4,4 +4,5 @@ tags
|
||||||
example/assets/*.blend*
|
example/assets/*.blend*
|
||||||
2wa.gitlab.io/*
|
2wa.gitlab.io/*
|
||||||
src/3rd/js/aframe/build/aframe
|
src/3rd/js/aframe/build/aframe
|
||||||
|
example/godot/addons
|
||||||
|
example/godot/dist
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
@ -720,7 +720,11 @@ For example, to render a portal with a preview-version of the scene, create an 3
|
||||||
<li>set the position of the camera accordingly to the vector3 values of <code>#pos</code></li>
|
<li>set the position of the camera accordingly to the vector3 values of <code>#pos</code></li>
|
||||||
<li><code>rot</code> sets the rotation of the camera (only for non-VR/AR headsets)</li>
|
<li><code>rot</code> sets the rotation of the camera (only for non-VR/AR headsets)</li>
|
||||||
<li>mediafragment <code>t</code> in the top-URL sets the playbackspeed and animation-range of the global scene animation</li>
|
<li>mediafragment <code>t</code> in the top-URL sets the playbackspeed and animation-range of the global scene animation</li>
|
||||||
<li>after scene load: in case an <code>href</code> does not mention any <code>pos</code>-coordinate, <code>pos=0,0,0</code> will be assumed</li>
|
<li>before scene load: the scene is cleared</li>
|
||||||
|
<li>after scene load: in case the scene (rootnode) contains an <code>#</code> default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)</li>
|
||||||
|
<li>after scene load: in case the scene (rootnode) contains an <code>#</code> default view with a fragment value: execute positional fragment via the hashbus + update top-level URL</li>
|
||||||
|
<li>in case of no default <code>#</code> view on the scene (rootnode), default player(rig) position <code>0,0,0</code> is assumed.</li>
|
||||||
|
<li>in case a <code>href</code> does not mention any <code>pos</code>-coordinate, the current position will be assumed</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>Here’s an ascii representation of a 3D scene-graph which contains 3D objects <code>◻</code> and their metadata:</p>
|
<p>Here’s an ascii representation of a 3D scene-graph which contains 3D objects <code>◻</code> and their metadata:</p>
|
||||||
|
@ -761,7 +765,7 @@ In case of <code>buttonA</code> the end-user will be teleported to another locat
|
||||||
<h1 id="embedding-xr-content-using-src">Embedding XR content using src</h1>
|
<h1 id="embedding-xr-content-using-src">Embedding XR content using src</h1>
|
||||||
|
|
||||||
<p><code>src</code> is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br>
|
<p><code>src</code> is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br>
|
||||||
It instances content (in objects) in the current scene/asset.</p>
|
It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.</p>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
|
|
@ -383,10 +383,14 @@ Example URI's:
|
||||||
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/5)<br>
|
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/5)<br>
|
||||||
|
|
||||||
1. the Y-coordinate of `pos` identifies the floorposition. This means that desktop-projections usually need to add 1.5m (average person height) on top (which is done automatically by VR/AR headsets).
|
1. the Y-coordinate of `pos` identifies the floorposition. This means that desktop-projections usually need to add 1.5m (average person height) on top (which is done automatically by VR/AR headsets).
|
||||||
1. set the position of the camera accordingly to the vector3 values of `#pos`
|
2. set the position of the camera accordingly to the vector3 values of `#pos`
|
||||||
1. `rot` sets the rotation of the camera (only for non-VR/AR headsets)
|
3. `rot` sets the rotation of the camera (only for non-VR/AR headsets)
|
||||||
1. mediafragment `t` in the top-URL sets the playbackspeed and animation-range of the global scene animation
|
4. mediafragment `t` in the top-URL sets the playbackspeed and animation-range of the global scene animation
|
||||||
1. after scene load: in case an `href` does not mention any `pos`-coordinate, `pos=0,0,0` will be assumed
|
5. before scene load: the scene is cleared
|
||||||
|
6. after scene load: in case the scene (rootnode) contains an `#` default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)
|
||||||
|
7. after scene load: in case the scene (rootnode) contains an `#` default view with a fragment value: execute positional fragment via the hashbus + update top-level URL
|
||||||
|
8. in case of no default `#` view on the scene (rootnode), default player(rig) position `0,0,0` is assumed.
|
||||||
|
9. in case a `href` does not mention any `pos`-coordinate, the current position will be assumed
|
||||||
|
|
||||||
Here's an ascii representation of a 3D scene-graph which contains 3D objects `◻` and their metadata:
|
Here's an ascii representation of a 3D scene-graph which contains 3D objects `◻` and their metadata:
|
||||||
|
|
||||||
|
@ -424,7 +428,7 @@ The URL-processing-flow for hypermedia browsers goes like this:
|
||||||
# Embedding XR content using src
|
# Embedding XR content using src
|
||||||
|
|
||||||
`src` is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br>
|
`src` is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br>
|
||||||
It instances content (in objects) in the current scene/asset.
|
It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.
|
||||||
|
|
||||||
| fragment | type | example value |
|
| fragment | type | example value |
|
||||||
|----------|------|---------------|
|
|----------|------|---------------|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
|
|
||||||
Jens & Leon Internet Engineering Task Force L.R. van Kammen
|
Jens & Leon Internet Engineering Task Force L.R. van Kammen
|
||||||
Internet-Draft 25 April 2024
|
Internet-Draft 9 May 2024
|
||||||
Intended status: Informational
|
Intended status: Informational
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,16 +46,16 @@ Status of This Memo
|
||||||
time. It is inappropriate to use Internet-Drafts as reference
|
time. It is inappropriate to use Internet-Drafts as reference
|
||||||
material or to cite them other than as "work in progress."
|
material or to cite them other than as "work in progress."
|
||||||
|
|
||||||
This Internet-Draft will expire on 27 October 2024.
|
This Internet-Draft will expire on 10 November 2024.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 1]
|
van Kammen Expires 10 November 2024 [Page 1]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
Copyright Notice
|
Copyright Notice
|
||||||
|
@ -109,9 +109,9 @@ Table of Contents
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 2]
|
van Kammen Expires 10 November 2024 [Page 2]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
21. Additional scene metadata . . . . . . . . . . . . . . . . . . 35
|
21. Additional scene metadata . . . . . . . . . . . . . . . . . . 35
|
||||||
|
@ -165,9 +165,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 3]
|
van Kammen Expires 10 November 2024 [Page 3]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
XR Fragments tries to seek to connect the world of text (semantical
|
XR Fragments tries to seek to connect the world of text (semantical
|
||||||
|
@ -221,9 +221,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 4]
|
van Kammen Expires 10 November 2024 [Page 4]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
||||||
|
@ -277,9 +277,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 5]
|
van Kammen Expires 10 November 2024 [Page 5]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
* allowing 3D assets/nodes to publish XR Fragments to themselves/
|
* allowing 3D assets/nodes to publish XR Fragments to themselves/
|
||||||
|
@ -333,9 +333,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 6]
|
van Kammen Expires 10 November 2024 [Page 6]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
+=========+======================+=====================================+
|
+=========+======================+=====================================+
|
||||||
|
@ -389,9 +389,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 7]
|
van Kammen Expires 10 November 2024 [Page 7]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
4. Conventions and Definitions
|
4. Conventions and Definitions
|
||||||
|
@ -445,9 +445,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 8]
|
van Kammen Expires 10 November 2024 [Page 8]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
my.io/scene.fbx
|
my.io/scene.fbx
|
||||||
|
@ -501,9 +501,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 9]
|
van Kammen Expires 10 November 2024 [Page 9]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
|Media Fragments |media fragment |#t=0,2&loop |play (and |
|
|Media Fragments |media fragment |#t=0,2&loop |play (and |
|
||||||
|
@ -557,9 +557,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 10]
|
van Kammen Expires 10 November 2024 [Page 10]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
6.2. Fragment-to-metadata mapping
|
6.2. Fragment-to-metadata mapping
|
||||||
|
@ -613,9 +613,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 11]
|
van Kammen Expires 10 November 2024 [Page 11]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
| | | | |metadata (bar:#t=0 |
|
| | | | |metadata (bar:#t=0 |
|
||||||
|
@ -669,9 +669,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 12]
|
van Kammen Expires 10 November 2024 [Page 12]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
| temporal | s=x | 1 | set playback |
|
| temporal | s=x | 1 | set playback |
|
||||||
|
@ -725,9 +725,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 13]
|
van Kammen Expires 10 November 2024 [Page 13]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
| | | | uv |
|
| | | | uv |
|
||||||
|
@ -781,9 +781,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 14]
|
van Kammen Expires 10 November 2024 [Page 14]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
+──────────────────────────────────────────────────────────+
|
+──────────────────────────────────────────────────────────+
|
||||||
|
@ -837,9 +837,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 15]
|
van Kammen Expires 10 November 2024 [Page 15]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
1. the Y-coordinate of pos identifies the floorposition. This means
|
1. the Y-coordinate of pos identifies the floorposition. This means
|
||||||
|
@ -850,8 +850,17 @@ Internet-Draft XR Fragments April 2024
|
||||||
3. rot sets the rotation of the camera (only for non-VR/AR headsets)
|
3. rot sets the rotation of the camera (only for non-VR/AR headsets)
|
||||||
4. mediafragment t in the top-URL sets the playbackspeed and
|
4. mediafragment t in the top-URL sets the playbackspeed and
|
||||||
animation-range of the global scene animation
|
animation-range of the global scene animation
|
||||||
5. after scene load: in case an href does not mention any pos-
|
5. before scene load: the scene is cleared
|
||||||
coordinate, pos=0,0,0 will be assumed
|
6. after scene load: in case the scene (rootnode) contains an #
|
||||||
|
default view with a fragment value: execute non-positional
|
||||||
|
fragments via the hashbus (no top-level URL change)
|
||||||
|
7. after scene load: in case the scene (rootnode) contains an #
|
||||||
|
default view with a fragment value: execute positional fragment
|
||||||
|
via the hashbus + update top-level URL
|
||||||
|
8. in case of no default # view on the scene (rootnode), default
|
||||||
|
player(rig) position 0,0,0 is assumed.
|
||||||
|
9. in case a href does not mention any pos-coordinate, the current
|
||||||
|
position will be assumed
|
||||||
|
|
||||||
Here's an ascii representation of a 3D scene-graph which contains 3D
|
Here's an ascii representation of a 3D scene-graph which contains 3D
|
||||||
objects ◻ and their metadata:
|
objects ◻ and their metadata:
|
||||||
|
@ -881,23 +890,20 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
The URL-processing-flow for hypermedia browsers goes like this:
|
The URL-processing-flow for hypermedia browsers goes like this:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
van Kammen Expires 10 November 2024 [Page 16]
|
||||||
|
|
||||||
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
1. IF a #cube matches a custom property-key (of an object) in the 3D
|
1. IF a #cube matches a custom property-key (of an object) in the 3D
|
||||||
file/scene (#cube: #......) <b>THEN</b> execute that
|
file/scene (#cube: #......) <b>THEN</b> execute that
|
||||||
predefined_view.
|
predefined_view.
|
||||||
2. IF scene operators (pos) and/or animation operator (t) are
|
2. IF scene operators (pos) and/or animation operator (t) are
|
||||||
present in the URL then (re)position the camera and/or animation-
|
present in the URL then (re)position the camera and/or animation-
|
||||||
range accordingly.
|
range accordingly.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 16]
|
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
|
||||||
|
|
||||||
|
|
||||||
3. IF no camera-position has been set in <b>step 1 or 2</b> update
|
3. IF no camera-position has been set in <b>step 1 or 2</b> update
|
||||||
the top-level URL with #pos=0,0,0 (example (https://github.com/co
|
the top-level URL with #pos=0,0,0 (example (https://github.com/co
|
||||||
derofsalvation/xrfragment/blob/main/src/3rd/js/three/
|
derofsalvation/xrfragment/blob/main/src/3rd/js/three/
|
||||||
|
@ -912,7 +918,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
src is the 3D version of the <a target="_blank"
|
src is the 3D version of the <a target="_blank"
|
||||||
href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.
|
href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.
|
||||||
It instances content (in objects) in the current scene/asset.
|
It instances content (in objects) in the current scene/asset, and
|
||||||
|
follows similar logic like the previous chapter, except that it does
|
||||||
|
not modify the camera.
|
||||||
|
|
||||||
+========+========+===================================================+
|
+========+========+===================================================+
|
||||||
|fragment|type |example value |
|
|fragment|type |example value |
|
||||||
|
@ -941,17 +949,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
van Kammen Expires 10 November 2024 [Page 17]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 17]
|
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
+────────────────────────────────────────────────────────+ +─────────────────────────+
|
+────────────────────────────────────────────────────────+ +─────────────────────────+
|
||||||
|
@ -1005,9 +1005,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 18]
|
van Kammen Expires 10 November 2024 [Page 18]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
6. <b>external</b> src values should be served with appropriate
|
6. <b>external</b> src values should be served with appropriate
|
||||||
|
@ -1061,9 +1061,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 19]
|
van Kammen Expires 10 November 2024 [Page 19]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
+==========+==================+============================+
|
+==========+==================+============================+
|
||||||
|
@ -1117,9 +1117,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 20]
|
van Kammen Expires 10 November 2024 [Page 20]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
» example implementation
|
» example implementation
|
||||||
|
@ -1173,9 +1173,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 21]
|
van Kammen Expires 10 November 2024 [Page 21]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
* calculate the <b>bounding box</b> of the instanced scene, and
|
* calculate the <b>bounding box</b> of the instanced scene, and
|
||||||
|
@ -1229,9 +1229,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 22]
|
van Kammen Expires 10 November 2024 [Page 22]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
14. XR audio/video integration
|
14. XR audio/video integration
|
||||||
|
@ -1285,9 +1285,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 23]
|
van Kammen Expires 10 November 2024 [Page 23]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
15.1. including/excluding
|
15.1. including/excluding
|
||||||
|
@ -1341,9 +1341,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 24]
|
van Kammen Expires 10 November 2024 [Page 24]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
2. detect object id's & properties foo=1 and foo (reference regex=
|
2. detect object id's & properties foo=1 and foo (reference regex=
|
||||||
|
@ -1397,9 +1397,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 25]
|
van Kammen Expires 10 November 2024 [Page 25]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
| The XR Fragments does this by collapsing space into a *Word Graph*
|
| The XR Fragments does this by collapsing space into a *Word Graph*
|
||||||
|
@ -1453,9 +1453,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 26]
|
van Kammen Expires 10 November 2024 [Page 26]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
|
http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
|
||||||
|
@ -1509,9 +1509,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 27]
|
van Kammen Expires 10 November 2024 [Page 27]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
As seen above, the XRWG can expand bibs
|
As seen above, the XRWG can expand bibs
|
||||||
|
@ -1565,9 +1565,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 28]
|
van Kammen Expires 10 November 2024 [Page 28]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
12. Default font (unless specified otherwise) is a modern monospace
|
12. Default font (unless specified otherwise) is a modern monospace
|
||||||
|
@ -1621,9 +1621,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 29]
|
van Kammen Expires 10 November 2024 [Page 29]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
* lines beginning with @ will not be rendered verbatim by default
|
* lines beginning with @ will not be rendered verbatim by default
|
||||||
|
@ -1677,9 +1677,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 30]
|
van Kammen Expires 10 November 2024 [Page 30]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
+--------------------------------------------------------------+ +------------------------+
|
+--------------------------------------------------------------+ +------------------------+
|
||||||
|
@ -1733,9 +1733,9 @@ xrtext = {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 31]
|
van Kammen Expires 10 November 2024 [Page 31]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
// bibtex: ↓@ ↓<tag|tag{phrase,|{ruler}> ↓property ↓end
|
// bibtex: ↓@ ↓<tag|tag{phrase,|{ruler}> ↓property ↓end
|
||||||
|
@ -1789,9 +1789,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 32]
|
van Kammen Expires 10 November 2024 [Page 32]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
str = `
|
str = `
|
||||||
|
@ -1845,9 +1845,9 @@ console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back to
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 33]
|
van Kammen Expires 10 November 2024 [Page 33]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
2. mirroring files on another protocol using (HTTP) errorcode tags
|
2. mirroring files on another protocol using (HTTP) errorcode tags
|
||||||
|
@ -1901,9 +1901,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 34]
|
van Kammen Expires 10 November 2024 [Page 34]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
* href: university.edu/projects.gltf#math&-theme math
|
* href: university.edu/projects.gltf#math&-theme math
|
||||||
|
@ -1957,9 +1957,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 35]
|
van Kammen Expires 10 November 2024 [Page 35]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
* BibTex (https://bibtex.eu/fields) when known bibtex-keys exist
|
* BibTex (https://bibtex.eu/fields) when known bibtex-keys exist
|
||||||
|
@ -2013,9 +2013,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 36]
|
van Kammen Expires 10 November 2024 [Page 36]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
22. Accessibility interface
|
22. Accessibility interface
|
||||||
|
@ -2069,9 +2069,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 37]
|
van Kammen Expires 10 November 2024 [Page 37]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
(javascript) which can change URN too.
|
(javascript) which can change URN too.
|
||||||
|
@ -2125,9 +2125,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 38]
|
van Kammen Expires 10 November 2024 [Page 38]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
* visual-meta.info (https://visual-meta.info)
|
* visual-meta.info (https://visual-meta.info)
|
||||||
|
@ -2181,9 +2181,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 39]
|
van Kammen Expires 10 November 2024 [Page 39]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
| hashtags | time |
|
| hashtags | time |
|
||||||
|
@ -2237,9 +2237,9 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 40]
|
van Kammen Expires 10 November 2024 [Page 40]
|
||||||
|
|
||||||
Internet-Draft XR Fragments April 2024
|
Internet-Draft XR Fragments May 2024
|
||||||
|
|
||||||
|
|
||||||
+-----------------+---------------------------------------------+
|
+-----------------+---------------------------------------------+
|
||||||
|
@ -2293,4 +2293,4 @@ Internet-Draft XR Fragments April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 41]
|
van Kammen Expires 10 November 2024 [Page 41]
|
||||||
|
|
|
@ -612,7 +612,11 @@ For example, to render a portal with a preview-version of the scene, create an 3
|
||||||
<li>set the position of the camera accordingly to the vector3 values of <tt>#pos</tt></li>
|
<li>set the position of the camera accordingly to the vector3 values of <tt>#pos</tt></li>
|
||||||
<li><tt>rot</tt> sets the rotation of the camera (only for non-VR/AR headsets)</li>
|
<li><tt>rot</tt> sets the rotation of the camera (only for non-VR/AR headsets)</li>
|
||||||
<li>mediafragment <tt>t</tt> in the top-URL sets the playbackspeed and animation-range of the global scene animation</li>
|
<li>mediafragment <tt>t</tt> in the top-URL sets the playbackspeed and animation-range of the global scene animation</li>
|
||||||
<li>after scene load: in case an <tt>href</tt> does not mention any <tt>pos</tt>-coordinate, <tt>pos=0,0,0</tt> will be assumed</li>
|
<li>before scene load: the scene is cleared</li>
|
||||||
|
<li>after scene load: in case the scene (rootnode) contains an <tt>#</tt> default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)</li>
|
||||||
|
<li>after scene load: in case the scene (rootnode) contains an <tt>#</tt> default view with a fragment value: execute positional fragment via the hashbus + update top-level URL</li>
|
||||||
|
<li>in case of no default <tt>#</tt> view on the scene (rootnode), default player(rig) position <tt>0,0,0</tt> is assumed.</li>
|
||||||
|
<li>in case a <tt>href</tt> does not mention any <tt>pos</tt>-coordinate, the current position will be assumed</li>
|
||||||
</ol>
|
</ol>
|
||||||
<t>Here's an ascii representation of a 3D scene-graph which contains 3D objects <tt>◻</tt> and their metadata:</t>
|
<t>Here's an ascii representation of a 3D scene-graph which contains 3D objects <tt>◻</tt> and their metadata:</t>
|
||||||
|
|
||||||
|
@ -651,7 +655,7 @@ In case of <tt>buttonA</tt> the end-user will be teleported to another location
|
||||||
<section anchor="embedding-xr-content-using-src"><name>Embedding XR content using src</name>
|
<section anchor="embedding-xr-content-using-src"><name>Embedding XR content using src</name>
|
||||||
<t><tt>src</tt> is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br />
|
<t><tt>src</tt> is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br />
|
||||||
|
|
||||||
It instances content (in objects) in the current scene/asset.</t>
|
It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.</t>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
|
|
||||||
Internet Engineering Task Force L.R. van Kammen
|
Internet Engineering Task Force L.R. van Kammen
|
||||||
Internet-Draft 25 April 2024
|
Internet-Draft 9 May 2024
|
||||||
Intended status: Informational
|
Intended status: Informational
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ Status of This Memo
|
||||||
time. It is inappropriate to use Internet-Drafts as reference
|
time. It is inappropriate to use Internet-Drafts as reference
|
||||||
material or to cite them other than as "work in progress."
|
material or to cite them other than as "work in progress."
|
||||||
|
|
||||||
This Internet-Draft will expire on 27 October 2024.
|
This Internet-Draft will expire on 10 November 2024.
|
||||||
|
|
||||||
Copyright Notice
|
Copyright Notice
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ Copyright Notice
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 1]
|
van Kammen Expires 10 November 2024 [Page 1]
|
||||||
|
|
||||||
Internet-Draft XR Macros April 2024
|
Internet-Draft XR Macros May 2024
|
||||||
|
|
||||||
|
|
||||||
extracted from this document must include Revised BSD License text as
|
extracted from this document must include Revised BSD License text as
|
||||||
|
@ -109,9 +109,9 @@ Table of Contents
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 2]
|
van Kammen Expires 10 November 2024 [Page 2]
|
||||||
|
|
||||||
Internet-Draft XR Macros April 2024
|
Internet-Draft XR Macros May 2024
|
||||||
|
|
||||||
|
|
||||||
3. Metadata-values can contain the | symbol to 🎲 roundrobin variable
|
3. Metadata-values can contain the | symbol to 🎲 roundrobin variable
|
||||||
|
@ -165,9 +165,9 @@ Internet-Draft XR Macros April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 3]
|
van Kammen Expires 10 November 2024 [Page 3]
|
||||||
|
|
||||||
Internet-Draft XR Macros April 2024
|
Internet-Draft XR Macros May 2024
|
||||||
|
|
||||||
|
|
||||||
+=========+======+===================+=================+=============+
|
+=========+======+===================+=================+=============+
|
||||||
|
@ -221,9 +221,9 @@ Internet-Draft XR Macros April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 4]
|
van Kammen Expires 10 November 2024 [Page 4]
|
||||||
|
|
||||||
Internet-Draft XR Macros April 2024
|
Internet-Draft XR Macros May 2024
|
||||||
|
|
||||||
|
|
||||||
Table 3
|
Table 3
|
||||||
|
@ -277,9 +277,9 @@ Internet-Draft XR Macros April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 5]
|
van Kammen Expires 10 November 2024 [Page 5]
|
||||||
|
|
||||||
Internet-Draft XR Macros April 2024
|
Internet-Draft XR Macros May 2024
|
||||||
|
|
||||||
|
|
||||||
4.5. Usecase: present context menu with options
|
4.5. Usecase: present context menu with options
|
||||||
|
@ -333,9 +333,9 @@ click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 6]
|
van Kammen Expires 10 November 2024 [Page 6]
|
||||||
|
|
||||||
Internet-Draft XR Macros April 2024
|
Internet-Draft XR Macros May 2024
|
||||||
|
|
||||||
|
|
||||||
| Note that only macro's can trigger roundrobin values or
|
| Note that only macro's can trigger roundrobin values or
|
||||||
|
@ -389,4 +389,4 @@ Internet-Draft XR Macros April 2024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
van Kammen Expires 27 October 2024 [Page 7]
|
van Kammen Expires 10 November 2024 [Page 7]
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../assets/index.glb
|
|
|
@ -1,14 +1,32 @@
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
var xr_interface: XRInterface
|
var xr_interface: XRInterface
|
||||||
|
var xrf
|
||||||
|
var scene
|
||||||
|
var player:CharacterBody3D
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
# Import MyClass
|
xrf = preload("res://xrfragment.gd").new()
|
||||||
const XRF = preload("res://xrfragment.gd")
|
|
||||||
var xrf = XRF.new()
|
|
||||||
add_child(xrf)
|
add_child(xrf)
|
||||||
print( xrf.parseURL("https://foo.com/?foo#flop=bar&fap=fop") )
|
xrf.to("https://xrfragment.org/index.glb", _onXRF )
|
||||||
print( xrf.parseURL("https://foo.com/flop.html?foo#flop=bar&fap=fop") )
|
player = find_child("PlayerBody")
|
||||||
xrf.load("https://xrfragment.org/index.glb")
|
player.enabled = false # optional: turn off gravity
|
||||||
|
|
||||||
|
func _onXRF(event:String,data ):
|
||||||
|
if event == "scene_loaded":
|
||||||
|
scene = data
|
||||||
|
setPredefinedSceneView()
|
||||||
|
|
||||||
|
func _input(event):
|
||||||
|
if event is InputEventMouseMotion:
|
||||||
|
var mouse_sens = 0.2
|
||||||
|
var cam = find_child("XRCamera3D")
|
||||||
|
cam.rotate_y(deg_to_rad(-event.relative.x*mouse_sens))
|
||||||
|
|
||||||
|
# info: https://xrfragment.org/#predefined_view
|
||||||
|
# spec: 6-8 @ https://xrfragment.org/doc/RFC_XR_Fragments.html#navigating-3d
|
||||||
|
func setPredefinedSceneView():
|
||||||
|
var XRF = scene.get_meta("XRF")
|
||||||
|
if XRF && XRF.has("#") && XRF["#"]["fragment"]["pos"]:
|
||||||
|
player.teleport( xrf.posToTransform3D(XRF["#"]["fragment"]["pos"]) )
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ XRToolsUserSettings="*res://addons/godot-xr-tools/user_settings/user_settings.gd
|
||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg")
|
enabled=PackedStringArray()
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../../src/xrfragment/xrfragment.gd
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
# https://xrfragment.org"
|
||||||
|
# SPDX-License-Identifier: MPL-2.0"
|
||||||
|
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
class_name XRF
|
||||||
|
|
||||||
|
var scene
|
||||||
|
var isModelLoading = false
|
||||||
|
var metadata
|
||||||
|
var callback: Callable;
|
||||||
|
var Type = {
|
||||||
|
"isColor": "^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$",
|
||||||
|
"isInt": "^[0-9]+$",
|
||||||
|
"isFloat": "^[0-9]+%.[0-9]+$",
|
||||||
|
"isVector": "([,]+|%w)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready():
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta):
|
||||||
|
pass
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# URI Related functions
|
||||||
|
####################################################################################################
|
||||||
|
|
||||||
|
func parseURL(url: String) -> Dictionary:
|
||||||
|
var URI = {}
|
||||||
|
|
||||||
|
# Split URL by '://' to get protocol and the rest of the URL
|
||||||
|
var parts = url.split("://")
|
||||||
|
if parts.size() > 1:
|
||||||
|
URI["protocol"] = parts[0]
|
||||||
|
url = parts[1]
|
||||||
|
else:
|
||||||
|
URI["protocol"] = "http" # Default to http if protocol is missing
|
||||||
|
|
||||||
|
# Split URL by '/' to separate domain, path, and file
|
||||||
|
parts = url.split("/")
|
||||||
|
URI["domain"] = parts[0]
|
||||||
|
if parts.size() > 1:
|
||||||
|
var path_and_file = parts[1]
|
||||||
|
var path_and_file_parts = path_and_file.split("/")
|
||||||
|
if path_and_file_parts.size() > 1:
|
||||||
|
URI["path"] = path_and_file_parts
|
||||||
|
var file = path_and_file_parts.pop_back()
|
||||||
|
URI["path"] = path_and_file_parts.join("/")
|
||||||
|
else:
|
||||||
|
URI["path"] = path_and_file
|
||||||
|
|
||||||
|
# Check if there's a query string
|
||||||
|
if url.find("?") != -1:
|
||||||
|
parts = url.split("?")
|
||||||
|
URI["path"] = parts[0]
|
||||||
|
var args = parts[1]
|
||||||
|
if args.find("#"):
|
||||||
|
args = args.split("#")[0]
|
||||||
|
URI["query"] = parseArgs(args)
|
||||||
|
else:
|
||||||
|
URI["query"] = {}
|
||||||
|
|
||||||
|
# Check if there's a fragment
|
||||||
|
if url.find("#") != -1:
|
||||||
|
parts = url.split("#")
|
||||||
|
URI["fragment"] = parseArgs(parts[1])
|
||||||
|
else:
|
||||||
|
URI["fragment"] = {}
|
||||||
|
|
||||||
|
return URI
|
||||||
|
|
||||||
|
func parseArgs(fragment: String) -> Dictionary:
|
||||||
|
var ARG = {}
|
||||||
|
|
||||||
|
# Split fragment by '&' to separate items
|
||||||
|
var items = fragment.split("&")
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
# Split item by '=' to separate key and value
|
||||||
|
var key_value = item.split("=")
|
||||||
|
if key_value.size() > 1:
|
||||||
|
ARG[key_value[0]] = guess_type(key_value[1])
|
||||||
|
else:
|
||||||
|
ARG[key_value[0]] = ""
|
||||||
|
|
||||||
|
return ARG
|
||||||
|
|
||||||
|
func guess_type(str: String) -> Dictionary:
|
||||||
|
var v = {
|
||||||
|
"string": str,
|
||||||
|
"x": null,
|
||||||
|
"y": null,
|
||||||
|
"color":null,
|
||||||
|
"float": null,
|
||||||
|
"int": null
|
||||||
|
}
|
||||||
|
var parts = str.split(",")
|
||||||
|
if parts.size() > 1:
|
||||||
|
v.x = parts[0].to_int()
|
||||||
|
v.y = parts[1].to_int()
|
||||||
|
if parts.size() > 2:
|
||||||
|
v.z = parts[2].to_int()
|
||||||
|
if str.match(Type.isColor):
|
||||||
|
v.color = str
|
||||||
|
if str.match(Type.isFloat):
|
||||||
|
v.float = str.to_float()
|
||||||
|
if str.match(Type.isInt):
|
||||||
|
v.int = str.to_int()
|
||||||
|
return v
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# Model Related functions
|
||||||
|
####################################################################################################
|
||||||
|
|
||||||
|
# Download model by HTTP and run `downloadModelSuccess` if OK
|
||||||
|
func to(url, f:Callable ):
|
||||||
|
print("loading "+url)
|
||||||
|
callback = f
|
||||||
|
var http_request = HTTPRequest.new()
|
||||||
|
add_child(http_request)
|
||||||
|
http_request.request_completed.connect(downloadModelSuccess)
|
||||||
|
|
||||||
|
var error = http_request.request(url)
|
||||||
|
if error != OK:
|
||||||
|
push_error("An error occurred in the HTTP request.")
|
||||||
|
|
||||||
|
func downloadModelSuccess(result, response_code, headers, body):
|
||||||
|
# TODO: here different parsing functions should be called
|
||||||
|
# based on the filetype (glb,gltf,ade,obj e.g.)
|
||||||
|
loadModelFromBufferByGLTFDocument(body)
|
||||||
|
_parseXRFMetadata(scene)
|
||||||
|
traverse( scene, _parseXRFMetadata )
|
||||||
|
# setup actions & embeds
|
||||||
|
traverse( scene, init_href )
|
||||||
|
traverse( scene, init_src )
|
||||||
|
callback.call("scene_loaded", scene)
|
||||||
|
|
||||||
|
func loadModelFromBufferByGLTFDocument(body):
|
||||||
|
print("loadModelFromBuffer")
|
||||||
|
var doc = GLTFDocument.new()
|
||||||
|
var state = GLTFState.new()
|
||||||
|
#state.set_handle_binary_image(GLTFState.HANDLE_BINARY_EMBED_AS_BASISU) # Fixed in new Godot version (4.3 as I see) https://github.com/godotengine/godot/blob/17e7f85c06366b427e5068c5b3e2940e27ff5f1d/scene/resources/portable_compressed_texture.cpp#L116
|
||||||
|
var error = doc.append_from_buffer(body, "", state)
|
||||||
|
if error == OK:
|
||||||
|
scene = doc.generate_scene(state)
|
||||||
|
metadata = _parseMetadata(state,scene)
|
||||||
|
add_child(scene)
|
||||||
|
print("model added")
|
||||||
|
else:
|
||||||
|
print("Couldn't load glTF scene (error code: %s). Are you connected to internet?" % error_string(error))
|
||||||
|
|
||||||
|
func _parseXRFMetadata(node:Node):
|
||||||
|
if node.has_meta("extras"):
|
||||||
|
var extras = node.get_meta("extras")
|
||||||
|
var XRF = {}
|
||||||
|
for i in extras:
|
||||||
|
if typeof(extras[i]) == TYPE_STRING:
|
||||||
|
XRF[ i ] = parseURL( extras[i] )
|
||||||
|
node.set_meta("XRF", XRF)
|
||||||
|
|
||||||
|
func traverse(node, f:Callable ):
|
||||||
|
for N in node.get_children():
|
||||||
|
if N.get_child_count() > 0:
|
||||||
|
f.call(N)
|
||||||
|
self.traverse(N,f)
|
||||||
|
else:
|
||||||
|
f.call(N)
|
||||||
|
|
||||||
|
func _parseMetadata(state: GLTFState, scene: Node) -> Error:
|
||||||
|
#var meta = new Dictionary()
|
||||||
|
|
||||||
|
# Add metadata to materials
|
||||||
|
var materials_json : Array = state.json.get("materials", [])
|
||||||
|
var materials : Array[Material] = state.get_materials()
|
||||||
|
for i in materials_json.size():
|
||||||
|
if materials_json[i].has("extras"):
|
||||||
|
materials[i].set_meta("extras", materials_json[i]["extras"])
|
||||||
|
|
||||||
|
# Add metadata to ImporterMeshes
|
||||||
|
var meshes_json : Array = state.json.get("meshes", [])
|
||||||
|
var meshes : Array[GLTFMesh] = state.get_meshes()
|
||||||
|
for i in meshes_json.size():
|
||||||
|
if meshes_json[i].has("extras"):
|
||||||
|
meshes[i].mesh.set_meta("extras", meshes_json[i]["extras"])
|
||||||
|
|
||||||
|
# Add metadata to scene
|
||||||
|
var scenes_json : Array = state.json.get("scenes", [])
|
||||||
|
if scenes_json[0].has("extras"):
|
||||||
|
scene.set_meta("extras", scenes_json[0]["extras"])
|
||||||
|
|
||||||
|
# Add metadata to nodes
|
||||||
|
var nodes_json : Array = state.json.get("nodes", [])
|
||||||
|
for i in nodes_json.size():
|
||||||
|
if nodes_json[i].has("extras"):
|
||||||
|
var name = nodes_json[i]["name"].replace(".","_")
|
||||||
|
var node = scene.find_child(name) #state.get_scene_node(i)
|
||||||
|
if node:
|
||||||
|
node.set_meta( "extras", nodes_json[i]["extras"] )
|
||||||
|
else:
|
||||||
|
print(name+" could not be found")
|
||||||
|
return OK
|
||||||
|
|
||||||
|
func posToTransform3D(v:Dictionary):
|
||||||
|
var pos = Vector3()
|
||||||
|
if !v.x:
|
||||||
|
var node:Node3D = scene.find_child(v.string)
|
||||||
|
pos.x = node.position.x
|
||||||
|
pos.y = node.position.y
|
||||||
|
pos.z = node.position.z
|
||||||
|
else:
|
||||||
|
pos.x = v.x
|
||||||
|
pos.y = v.y
|
||||||
|
pos.z = v.z
|
||||||
|
var transform = Transform3D()
|
||||||
|
transform.origin = pos
|
||||||
|
return transform
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# The XR Fragments
|
||||||
|
# spec: https://xrfragment.org/doc/RFC_XR_Fragments.html
|
||||||
|
####################################################################################################
|
||||||
|
|
||||||
|
func init_href(node:Node):
|
||||||
|
null
|
||||||
|
|
||||||
|
func init_src(node:Node):
|
||||||
|
null
|
||||||
|
|
7
make
7
make
|
@ -27,9 +27,10 @@ install(){
|
||||||
}
|
}
|
||||||
|
|
||||||
godot(){
|
godot(){
|
||||||
test -d src/xrfragment/godot/addons || mkdir src/xrfragment/godot/addons
|
DIR_GODOT=example/godot
|
||||||
test -d src/xrfragment/godot/addons/godot-xr-tools || {
|
test -d $DIR_GODOT/addons || mkdir -p $DIR_GODOT/addons
|
||||||
cd src/xrfragment/godot
|
test -d $DIR_GODOT/addons/godot-xr-tools || {
|
||||||
|
cd $DIR_GODOT
|
||||||
wget "https://github.com/GodotVR/godot-xr-tools/releases/download/4.3.1/godot-xr-tools.zip"
|
wget "https://github.com/GodotVR/godot-xr-tools/releases/download/4.3.1/godot-xr-tools.zip"
|
||||||
unzip godot-xr-tools.zip
|
unzip godot-xr-tools.zip
|
||||||
mv godot-xr-tools/addons/godot-xr-tools addons/.
|
mv godot-xr-tools/addons/godot-xr-tools addons/.
|
||||||
|
|
|
@ -1,221 +0,0 @@
|
||||||
extends Node
|
|
||||||
|
|
||||||
class_name XRF
|
|
||||||
|
|
||||||
var rootScene
|
|
||||||
var isModelLoading = false
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
|
||||||
func _ready():
|
|
||||||
pass # Replace with function body.
|
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
func _process(delta):
|
|
||||||
pass
|
|
||||||
|
|
||||||
####################################################################################################
|
|
||||||
# URI Related functions
|
|
||||||
####################################################################################################
|
|
||||||
|
|
||||||
func parseURL(url: String) -> Dictionary:
|
|
||||||
var URI = {}
|
|
||||||
|
|
||||||
# Split URL by '://' to get protocol and the rest of the URL
|
|
||||||
var parts = url.split("://")
|
|
||||||
if parts.size() > 1:
|
|
||||||
URI["protocol"] = parts[0]
|
|
||||||
url = parts[1]
|
|
||||||
else:
|
|
||||||
URI["protocol"] = "http" # Default to http if protocol is missing
|
|
||||||
|
|
||||||
# Split URL by '/' to separate domain, path, and file
|
|
||||||
parts = url.split("/")
|
|
||||||
URI["domain"] = parts[0]
|
|
||||||
if parts.size() > 1:
|
|
||||||
var path_and_file = parts[1]
|
|
||||||
var path_and_file_parts = path_and_file.split("/")
|
|
||||||
if path_and_file_parts.size() > 1:
|
|
||||||
URI["path"] = path_and_file_parts
|
|
||||||
var file = path_and_file_parts.pop_back()
|
|
||||||
URI["path"] = path_and_file_parts.join("/")
|
|
||||||
else:
|
|
||||||
URI["path"] = path_and_file
|
|
||||||
|
|
||||||
# Check if there's a query string
|
|
||||||
if url.find("?") != -1:
|
|
||||||
parts = url.split("?")
|
|
||||||
URI["path"] = parts[0]
|
|
||||||
var args = parts[1]
|
|
||||||
if args.find("#"):
|
|
||||||
args = args.split("#")[0]
|
|
||||||
URI["query"] = parseArgs(args)
|
|
||||||
else:
|
|
||||||
URI["query"] = {}
|
|
||||||
|
|
||||||
# Check if there's a fragment
|
|
||||||
if url.find("#") != -1:
|
|
||||||
parts = url.split("#")
|
|
||||||
URI["fragment"] = parseArgs(parts[1])
|
|
||||||
else:
|
|
||||||
URI["fragment"] = {}
|
|
||||||
|
|
||||||
return URI
|
|
||||||
|
|
||||||
func parseArgs(fragment: String) -> Dictionary:
|
|
||||||
var ARG = {}
|
|
||||||
|
|
||||||
# Split fragment by '&' to separate items
|
|
||||||
var items = fragment.split("&")
|
|
||||||
|
|
||||||
for item in items:
|
|
||||||
# Split item by '=' to separate key and value
|
|
||||||
var key_value = item.split("=")
|
|
||||||
if key_value.size() > 1:
|
|
||||||
ARG[key_value[0]] = key_value[1]
|
|
||||||
else:
|
|
||||||
ARG[key_value[0]] = ""
|
|
||||||
|
|
||||||
return ARG
|
|
||||||
|
|
||||||
####################################################################################################
|
|
||||||
# Model Related functions
|
|
||||||
####################################################################################################
|
|
||||||
|
|
||||||
# Download model by HTTP and run `downloadModelSuccess` if OK
|
|
||||||
func load(url):
|
|
||||||
print("loading "+url)
|
|
||||||
var http_request = HTTPRequest.new()
|
|
||||||
add_child(http_request)
|
|
||||||
http_request.request_completed.connect(downloadModelSuccess)
|
|
||||||
|
|
||||||
var error = http_request.request(url)
|
|
||||||
if error != OK:
|
|
||||||
push_error("An error occurred in the HTTP request.")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func placeModelToEditorScene(model):
|
|
||||||
add_child(model)
|
|
||||||
#model.translate(Vector3(0.0, 0.0, -1.0))
|
|
||||||
print("model added")
|
|
||||||
|
|
||||||
func downloadModelSuccess(result, response_code, headers, body):
|
|
||||||
# TODO: here different parsing functions should be called
|
|
||||||
# based on the filetype (glb,gltf,ade,obj e.g.)
|
|
||||||
loadModelFromBufferByGLTFDocument(body)
|
|
||||||
|
|
||||||
func loadModelFromBufferByGLTFDocument(body):
|
|
||||||
print("loadModelFromBuffer")
|
|
||||||
var doc = GLTFDocument.new()
|
|
||||||
var state = GLTFState.new()
|
|
||||||
#state.set_handle_binary_image(GLTFState.HANDLE_BINARY_EMBED_AS_BASISU) # Fixed in new Godot version (4.3 as I see) https://github.com/godotengine/godot/blob/17e7f85c06366b427e5068c5b3e2940e27ff5f1d/scene/resources/portable_compressed_texture.cpp#L116
|
|
||||||
|
|
||||||
var error = doc.append_from_buffer(body, "", state)
|
|
||||||
if error == OK:
|
|
||||||
#var glb_importer_model: GLTFMesh = state.get_meshes()[0]
|
|
||||||
#var glb_importer_model_mesh: ImporterMesh = glb_importer_model.get_mesh()
|
|
||||||
var scene = doc.generate_scene(state)
|
|
||||||
scene.set_meta("json",state.json)
|
|
||||||
#var ok:Error = _parseExtras(state)
|
|
||||||
traverse(scene, evalNode)
|
|
||||||
self.placeModelToEditorScene(scene)
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("Couldn't load glTF scene (error code: %s)." % error_string(error))
|
|
||||||
|
|
||||||
func evalNode(node:Node):
|
|
||||||
print(node.name)
|
|
||||||
#if node.has_meta("extras"):
|
|
||||||
# print(node.get_meta("extras",""))
|
|
||||||
|
|
||||||
func traverse(node, f:Callable ):
|
|
||||||
for N in node.get_children():
|
|
||||||
if N.get_child_count() > 0:
|
|
||||||
f.call(N)
|
|
||||||
self.traverse(N,f)
|
|
||||||
else:
|
|
||||||
f.call(N)
|
|
||||||
|
|
||||||
func _parseExtras(state: GLTFState) -> Error:
|
|
||||||
print( state.json.keys() )
|
|
||||||
|
|
||||||
# Add metadata to materials
|
|
||||||
var materials_json : Array = state.json.get("materials", [])
|
|
||||||
var materials : Array[Material] = state.get_materials()
|
|
||||||
for i in materials_json.size():
|
|
||||||
if materials_json[i].has("extras"):
|
|
||||||
materials[i].set_meta("extras", materials_json[i]["extras"])
|
|
||||||
|
|
||||||
# Add metadata to ImporterMeshes
|
|
||||||
var meshes_json : Array = state.json.get("meshes", [])
|
|
||||||
var meshes : Array[GLTFMesh] = state.get_meshes()
|
|
||||||
for i in meshes_json.size():
|
|
||||||
if meshes_json[i].has("extras"):
|
|
||||||
meshes[i].mesh.set_meta("extras", meshes_json[i]["extras"])
|
|
||||||
|
|
||||||
# Add metadata to nodes
|
|
||||||
var nodes_json : Array = state.json.get("nodes", [])
|
|
||||||
for i in nodes_json.size():
|
|
||||||
var node = state.get_scene_node(i)
|
|
||||||
if !node:
|
|
||||||
continue
|
|
||||||
if nodes_json[i].has("extras"):
|
|
||||||
# Handle special case
|
|
||||||
if node is ImporterMeshInstance3D:
|
|
||||||
# ImporterMeshInstance3D nodes will be converted later to either
|
|
||||||
# MeshInstance3D or StaticBody3D and metadata will be lost
|
|
||||||
# A sibling is created preserving the metadata. It can be later
|
|
||||||
# merged back in using a EditorScenePostImport script
|
|
||||||
var metadata_node = Node.new()
|
|
||||||
metadata_node.set_meta("extras", nodes_json[i]["extras"])
|
|
||||||
|
|
||||||
# Meshes are also ImporterMeshes that will be later converted either
|
|
||||||
# to ArrayMesh or some form of collision shape.
|
|
||||||
# We'll save it as another metadata item. If the mesh is reused we'll
|
|
||||||
# have duplicated info but at least it will always be accurate
|
|
||||||
if node.mesh and node.mesh.has_meta("extras"):
|
|
||||||
metadata_node.set_meta("mesh_extras", node.mesh.get_meta("extras"))
|
|
||||||
|
|
||||||
# Well add it as sibling so metadata node always follows the actual metadata owner
|
|
||||||
node.add_sibling(metadata_node)
|
|
||||||
# Make sure owner is set otherwise it won't get serialized to disk
|
|
||||||
metadata_node.owner = node.owner
|
|
||||||
# Add a suffix to the generated name so it's easy to find
|
|
||||||
metadata_node.name += "_meta"
|
|
||||||
# In all other cases just set_meta
|
|
||||||
else:
|
|
||||||
node.set_meta("extras", nodes_json[i]["extras"])
|
|
||||||
|
|
||||||
## now we merge extras to the scene
|
|
||||||
#var verbose_output = []
|
|
||||||
#var nodes : Array[Node] = scene.find_children("*" + "_meta", "Node")
|
|
||||||
#verbose_output.append_array(["Metadata nodes:", nodes])
|
|
||||||
#for node in nodes:
|
|
||||||
#var extras = node.get_meta("extras")
|
|
||||||
#if !extras:
|
|
||||||
#verbose_output.append("Node %s contains no 'extras' metadata" % node)
|
|
||||||
#continue
|
|
||||||
#var parent = node.get_parent()
|
|
||||||
#if !parent:
|
|
||||||
#verbose_output.append("Node %s has no parent" % node)
|
|
||||||
#continue
|
|
||||||
#var idx_original = node.get_index() - 1
|
|
||||||
#if idx_original < 0 or parent.get_child_count() <= idx_original:
|
|
||||||
#verbose_output.append("Original node index %s is out of bounds. Parent child count: %s" % [idx_original, parent.get_child_count()])
|
|
||||||
#continue
|
|
||||||
#var original = node.get_parent().get_child(idx_original)
|
|
||||||
#if original:
|
|
||||||
#verbose_output.append("Setting extras metadata for %s" % original)
|
|
||||||
#original.set_meta("extras", extras)
|
|
||||||
#if node.has_meta("mesh_extras"):
|
|
||||||
#if original is MeshInstance3D and original.mesh:
|
|
||||||
#verbose_output.append("Setting extras metadata for mesh %s" % original.mesh)
|
|
||||||
#original.mesh.set_meta("extras", node.get_meta("mesh_extras"))
|
|
||||||
#else:
|
|
||||||
#verbose_output.append("Metadata node %s has 'mesh_extras' but original %s has no mesh, preserving as 'mesh_extras'" % [node, original])
|
|
||||||
#original.set_meta("mesh_extras", node.get_meta("mesh_extras"))
|
|
||||||
#else:
|
|
||||||
#verbose_output.append("Original node not found for %s" % node)
|
|
||||||
#node.queue_free()
|
|
||||||
return OK
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../example/godot/xrfragment.gd
|
Loading…
Reference in New Issue