feat/godot wip

This commit is contained in:
Leon van Kammen 2024-05-10 13:41:20 +02:00
parent 606133289d
commit dd2434a3ed
13 changed files with 405 additions and 362 deletions

3
.gitignore vendored
View File

@ -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

View File

@ -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&rsquo;s an ascii representation of a 3D scene-graph which contains 3D objects <code></code> and their metadata:</p> <p>Here&rsquo;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>

View File

@ -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 |
|----------|------|---------------| |----------|------|---------------|

View File

@ -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]

View File

@ -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 &lt;a target=&quot;_blank&quot; href=&quot;https://www.w3.org/html/wiki/Elements/iframe&quot;&gt;iframe&lt;/a&gt;.<br /> <t><tt>src</tt> is the 3D version of the &lt;a target=&quot;_blank&quot; href=&quot;https://www.w3.org/html/wiki/Elements/iframe&quot;&gt;iframe&lt;/a&gt;.<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>

View File

@ -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]

View File

@ -1 +0,0 @@
../assets/index.glb

View File

@ -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"]) )

View File

@ -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]

View File

@ -1 +0,0 @@
../../src/xrfragment/xrfragment.gd

233
example/godot/xrfragment.gd Normal file
View File

@ -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
View File

@ -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/.

View File

@ -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

View File

@ -0,0 +1 @@
../../example/godot/xrfragment.gd