milestone 7m update/refactor documentation website based on updated spec (+adoption levels)

This commit is contained in:
Leon van Kammen 2025-09-01 17:47:16 +02:00
parent be9a356ed7
commit 281358e910
7 changed files with 914 additions and 905 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -80,13 +80,14 @@ value: draft-XRFRAGMENTS-leonvankammen-00
<h1 class="special" id="abstract">Abstract</h1>
<p>This draft is a specification for interactive URI-controllable 3D files, enabling <a href="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.<br>
<p>An open specification for hyperlinking &amp; deeplinking 3D fileformats.
This draft is a specification for interactive URI-controllable 3D files, enabling <a href="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.<br>
The specification uses <a href="https://www.w3.org/TR/media-frags/">W3C Media Fragments</a> and <a href="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</a> to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.<br>
XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like <a href="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a>.<br>
XR Fragments views spatial webs thru the lens of 3D scene URI&rsquo;s, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).</p>
XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like <a href="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a>.<br>
XR Fragments views XR experiences thru the lens of 3D object URI&rsquo;s, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).</p>
<blockquote>
<p>XR Fragments is a <b>Meta scene format</b> which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.<br>
<p>XR Fragments is a <b>heuristical 3D format</b> which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.<br>
These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing <b>higher interop</b> between fileformats, 3D editors, viewers and game-engines.</p>
<p>Almost every idea in this document is demonstrated at <a href="https://xrfragment.org">https://xrfragment.org</a></p>
@ -206,19 +207,12 @@ Instead of forcing authors to combine 3D/2D objects programmatically (publishing
<tbody>
<tr>
<td><code>#pos</code></td>
<td><code>#......</code></td>
<td>vector3</td>
<td><code>#pos=0.5,0,0</code> <code>#pos=room</code> <code>#pos=cam2</code></td>
<td><code>#room1</code> <code>#room2</code> <code>#cam2</code></td>
<td>positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera</td>
</tr>
<tr>
<td><code>#rot</code></td>
<td>vector3</td>
<td><code>#rot=0,90,0</code></td>
<td>rotates camera to xyz-coord 0.5,0,0</td>
</tr>
<tr>
<td><a href="https://www.w3.org/TR/media-frags/">Media Fragments</a></td>
<td><a href="#media%20fragments%20and%20datatypes">media fragment</a></td>
@ -251,83 +245,12 @@ Instead of forcing authors to combine 3D/2D objects programmatically (publishing
<td>XR teleport</td>
<td>custom property in 3D fileformats</td>
</tr>
<tr>
<td><code>src</code></td>
<td>string</td>
<td><code>&quot;src&quot;: &quot;#cube&quot;</code></td>
<td>XR embed / teleport</td>
<td>custom property in 3D fileformats</td>
</tr>
<tr>
<td><code>tag</code></td>
<td>string</td>
<td><code>&quot;tag&quot;: &quot;cubes geo&quot;</code></td>
<td>tag object (for filter-use / XRWG highlighting)</td>
<td>custom property in 3D fileformats</td>
</tr>
<tr>
<td><code>#</code></td>
<td>string</td>
<td><code>&quot;#&quot;: &quot;#mypreset</code></td>
<td>trigger default fragment on load</td>
<td>custom property in 3D fileformats</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Supported popular compatible 3D fileformats: <code>.gltf</code>, <code>.obj</code>, <code>.fbx</code>, <code>.usdz</code>, <code>.json</code> (THREE.js), <code>.dae</code> and so on.</p>
</blockquote>
<h1 id="hfl-hypermediatic-feedback-loop-for-xr-browsers">HFL (Hypermediatic Feedback Loop) for XR Browsers</h1>
<h2 id="sidecar-file">Sidecar-file</h2>
<blockquote>
<p>NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a <code>.glb</code> e.g.).</p>
</blockquote>
<p>For developers, sidecar-file can allow for defining <strong>explicit</strong> XR Fragments metadata, outside of the 3D file.<br>
This can be done via a JSON-pointers <a href="https://www.rfc-editor.org/rfc/rfc6901">RFC6901</a> in a JSON <a href="https://en.wikipedia.org/wiki/Sidecar_file">sidecar-file</a>:</p>
<ul>
<li>experience.glb</li>
<li>experience.json</li>
</ul>
<pre><code class="language-json">{
&quot;/&quot;:{
&quot;#&quot;: &quot;#-penguin&quot;,
&quot;aria-description&quot;: &quot;description of scene&quot;,
},
&quot;/room/chair&quot;: {
&quot;href&quot;: &quot;#penguin&quot;
}
}
</code></pre>
<blockquote>
<p>This would mean: hide object(s) with name or <code>tag</code>-value &lsquo;penguin&rsquo; upon scene-load, and show it when the user clicks the chair</p>
</blockquote>
<p>So after loading <code>experience.glb</code> the existence of <code>experience.json</code> is detected, to apply the explicit metadata.<br>
The sidecar will define (or <strong>override</strong> already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).</p>
<blockquote>
<p>In THREE.js-code this would boil down to:</p>
</blockquote>
<pre><code class="language-javascript"> scene.userData['#'] = &quot;#chair&amp;penguin&quot;
scene.userData['aria-description'] = &quot;description of scene&quot;
scene.getObjectByName(&quot;room&quot;).getObjectByName(&quot;chair&quot;).userData.href = &quot;#penguin&quot;
// now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene
</code></pre>
<h1 id="hypermediatic-feedbackloop-for-xr-browsers">Hypermediatic FeedbackLoop for XR browsers</h1>
<p><code>href</code> metadata traditionally implies <strong>click</strong> AND <strong>navigate</strong>, however XR Fragments adds stateless <strong>click</strong> (<code>xrf://#....</code>) or <strong>navigate</strong> (<code>xrf://#pos=...</code>)
<p><code>href</code> metadata traditionally implies <strong>click</strong> AND <strong>navigate</strong>, however XR Fragments adds stateless <strong>click</strong> (<code>xrf://#....</code>) or <strong>navigate</strong> (<code>xrf://#...</code>)
as well (which allows many extra interactions which otherwise need a scripting language). This is known as <strong>hashbus</strong>-only events (see image above).</p>
<blockquote>
@ -338,7 +261,7 @@ The sidecar will define (or <strong>override</strong> already existing) extras,
<ul>
<li><a href="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).</li>
<li>allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the <code>xrf://</code> hashbus</li>
<li>allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the <code>xrf://</code> hashbus (<code>xrf://#person=walk</code> to trigger <code>walk</code>-animation for object <code>person</code>)</li>
<li>collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus</li>
<li>completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources)</li>
</ul>
@ -435,7 +358,7 @@ sub-delims = &quot;,&quot; / &quot;=&quot;
</code></pre>
<blockquote>
<p>Example: <code>://foo.com/my3d.gltf#pos=1,0,0&amp;prio=-5&amp;t=0,100</code></p>
<p>Example: <code>://foo.com/my3d.gltf#room1&amp;prio=-5&amp;t=0,100</code></p>
</blockquote>
<table>
@ -448,12 +371,12 @@ sub-delims = &quot;,&quot; / &quot;=&quot;
<tbody>
<tr>
<td><code>pos=1,2,3</code></td>
<td><code>room1</code></td>
<td>vector/coordinate argument e.g.</td>
</tr>
<tr>
<td><code>pos=1,2,3&amp;rot=0,90,0&amp;foo</code></td>
<td><code>room1&amp;rot=0,90,0&amp;cam1</code></td>
<td>combinators</td>
</tr>
</tbody>
@ -505,8 +428,72 @@ For example, to render a portal with a preview-version of the scene, create an 3
<p>It also allows <strong>sourceportation</strong>, which basically means the enduser can teleport to the original XR Document of an <code>src</code> embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it.</p>
</blockquote>
<hr>
<h1 id="non-normative">non-normative</h1>
<p>The following below is non-normative heuristics which are not part officially part of the spec.</p>
<h1 id="additional-explicit-metadata">additional <strong>explicit</strong> metadata</h1>
<p>| <code>#rot</code> | vector3 | <code>#rot=0,90,0</code> | rotates camera to xyz-coord 0.5,0,0 |
| <code>src</code> | string | <code>&quot;src&quot;: &quot;#cube&quot;</code> | XR embed / teleport | custom property in 3D fileformats |
| <code>tag</code> | string | <code>&quot;tag&quot;: &quot;cubes geo&quot;</code> | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats |
| <code>#</code> | string | <code>&quot;#&quot;: &quot;#mypreset</code> | trigger default fragment on load | custom property in 3D fileformats |</p>
<blockquote>
<p>Supported popular compatible 3D fileformats: <code>.gltf</code>, <code>.obj</code>, <code>.fbx</code>, <code>.usdz</code>, <code>.json</code> (THREE.js), <code>.dae</code> and so on.</p>
</blockquote>
<h2 id="sidecar-file">Sidecar-file</h2>
<blockquote>
<p>NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a <code>.glb</code> e.g.).</p>
</blockquote>
<p>For developers, sidecar-file can allow for defining <strong>explicit</strong> XR Fragments metadata, outside of the 3D file.<br>
This can be done via a JSON-pointers <a href="https://www.rfc-editor.org/rfc/rfc6901">RFC6901</a> in a JSON <a href="https://en.wikipedia.org/wiki/Sidecar_file">sidecar-file</a>:</p>
<ul>
<li>experience.glb</li>
<li>experience.json</li>
</ul>
<pre><code class="language-json">{
&quot;/&quot;:{
&quot;#&quot;: &quot;#-penguin&quot;,
&quot;aria-description&quot;: &quot;description of scene&quot;,
},
&quot;/room/chair&quot;: {
&quot;href&quot;: &quot;#penguin&quot;
}
}
</code></pre>
<blockquote>
<p>This would mean: hide object(s) with name or <code>tag</code>-value &lsquo;penguin&rsquo; upon scene-load, and show it when the user clicks the chair</p>
</blockquote>
<p>So after loading <code>experience.glb</code> the existence of <code>experience.json</code> is detected, to apply the explicit metadata.<br>
The sidecar will define (or <strong>override</strong> already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).</p>
<blockquote>
<p>In THREE.js-code this would boil down to:</p>
</blockquote>
<pre><code class="language-javascript"> scene.userData['#'] = &quot;#chair&amp;penguin&quot;
scene.userData['aria-description'] = &quot;description of scene&quot;
scene.getObjectByName(&quot;room&quot;).getObjectByName(&quot;chair&quot;).userData.href = &quot;#penguin&quot;
// now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene
</code></pre>
<h2 id="level2-implicit-uri-fragments">Level2: Implicit URI Fragments</h2>
<blockquote>
<p>Warning: non-normative</p>
</blockquote>
<p>These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser:</p>
<table>
@ -531,7 +518,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
<tr>
<td><strong>FOCUS</strong></td>
<td><code>#&lt;tag_or_objectname&gt;</code></td>
<td><code>xrf://#&lt;tag_or_objectname&gt;</code></td>
<td>string</td>
<td><code>#person</code></td>
<td>(and show) object(s) with <code>tag: person</code> or name <code>person</code> (XRWG lookup)</td>
@ -582,7 +569,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
<h2 id="media-fragments-and-datatypes">media fragments and datatypes</h2>
<blockquote>
<p>NOTE: below the word &lsquo;play&rsquo; applies to 3D animations embedded in the 3D scene(file) <strong>but also</strong> media defined in <code>src</code>-metadata like audio/video-files (mp3/mp4 e.g.)</p>
<p>Warning: <strong>non-normative</strong> (below the word &lsquo;play&rsquo; applies to 3D animations embedded in the 3D scene(file) <strong>but also</strong> media defined in <code>src</code>-metadata like audio/video-files (mp3/mp4 e.g.))</p>
</blockquote>
<table>
@ -787,7 +774,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
│ index.gltf │
│ │ │
│ ├── ◻ buttonA │
│ │ └ href: #pos=1,0,1&amp;t=100,200 │
│ │ └ href: #room1&amp;t=100,200 │
│ │ │
│ └── ◻ buttonB │
│ └ href: other.fbx │ &lt;── file─agnostic (can be .gltf .obj etc)
@ -797,26 +784,35 @@ For example, to render a portal with a preview-version of the scene, create an 3
</code></pre>
<p>An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the <code>buttonA</code> and <code>buttonB</code>.<br>
In case of <code>buttonA</code> the end-user will be teleported to another location and time in the <strong>current loaded scene</strong>, but <code>buttonB</code> will <strong>replace the current scene</strong> with a new one, like <code>other.fbx</code>, and assume <code>pos=0,0,0</code>.</p>
In case of <code>buttonA</code> the end-user will be teleported to another location and time in the <strong>current loaded scene</strong>, but <code>buttonB</code> will <strong>replace the current scene</strong> with a new one, like <code>other.fbx</code>, and assume camera coordinate <code>0,0,0</code></p>
<h1 id="top-level-url-processing">Top-level URL processing</h1>
<blockquote>
<p>Example URL: <code>://foo/world.gltf#cube&amp;pos=0,0,0</code></p>
<p>Example URL: <code>://foo/world.gltf#room1&amp;t=10</code></p>
</blockquote>
<p>The URL-processing-flow for hypermedia browsers goes like this:</p>
<ol>
<li>IF a <code>#cube</code> matches a custom property-key (of an object) in the 3D file/scene (<code>#cube</code>: <code>#......</code>) <b>THEN</b> execute that predefined_view.</li>
<li>IF scene operators (<code>pos</code>) and/or animation operator (<code>t</code>) are present in the URL then (re)position the camera and/or animation-range accordingly.</li>
<li>IF no camera-position has been set in <b>step 1 or 2</b> update the top-level URL with <code>#pos=0,0,0</code> (<a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]">example</a>)</li>
<li>IF a <code>#room1</code> matches a custom property-key (of an object) in the 3D file/scene (<code>#room1</code>: <code>#......</code>) <b>THEN</b> execute that predefined_view.</li>
<li>IF scene operators and/or animation operator (<code>t</code>) are present in the URL then (re)position the camera (to <code>room1</code>) and/or animation-range (<code>10</code>) accordingly.</li>
<li>IF no camera-position has been set in <b>step 1 or 2</b> assume <code>0,0,0</code> as camera coordinate (XR: add user-height) (<a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]">example</a>)</li>
</ol>
<p><strong>Non-normative / Deprecated</strong>:</p>
<ol start="4">
<li>IF a <code>#cube</code> matches the name (of an object) in the 3D file/scene then draw a line from the enduser(&rsquo;s heart) to that object (to highlight it).</li>
<li>IF a <code>#cube</code> matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).</li>
</ol>
<h1 id="embedding-xr-content-using-src">Embedding XR content using src</h1>
<blockquote>
<p>NOTE: only adviced for local-first experiences (where resources can be cached).</p>
</blockquote>
<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, and follows similar logic like the previous chapter, except that it does not modify the camera.</p>
@ -914,15 +910,15 @@ Resizing will be happen accordingly to its placeholder object <code>aquariumcube
<tr>
<td><code>href</code></td>
<td>string (uri or predefined view)</td>
<td><code>#pos=1,1,0</code><br><code>#pos=1,1,0&amp;rot=90,0,0</code><br><code>://somefile.gltf#pos=1,1,0</code><br></td>
<td><code>#room1</code><br><code>#pos=room1&amp;rot=90,0,0</code><br><code>://somefile.gltf#room1</code><br></td>
</tr>
</tbody>
</table>
<ol>
<li><p>clicking an outbound &ldquo;external&rdquo;- or &ldquo;file URI&rdquo; fully replaces the current scene and assumes <code>pos=0,0,0&amp;rot=0,0,0</code> by default (unless specified)</p></li>
<li><p>clicking an outbound &ldquo;external&rdquo;- or &ldquo;file URI&rdquo; fully replaces the current scene and assumes <code>room2&amp;rot=0,0,0</code> by default (unless specified)</p></li>
<li><p>relocation/reorientation should happen locally for local URI&rsquo;s (<code>#pos=....</code>)</p></li>
<li><p>relocation/reorientation should happen locally for local URI&rsquo;s (<code>#....</code>)</p></li>
<li><p>navigation should not happen &ldquo;immediately&rdquo; when user is more than 5 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)</p></li>
@ -934,9 +930,9 @@ Resizing will be happen accordingly to its placeholder object <code>aquariumcube
<li><p>ignore previous rule in special cases, like clicking an <code>href</code> using camera-portal collision (the back-button could cause a teleport-loop if the previous position is too close)</p></li>
<li><p>href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also contain an href), however only 1 href can be executed at the same time.</p></li>
<li><p>href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time.</p></li>
<li><p>the end-user navigator back/forward buttons should repeat a back/forward action until a <code>pos=...</code> primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)</p></li>
<li><p>the end-user navigator back/forward buttons should repeat a back/forward action until a <code>#...</code> primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)</p></li>
</ol>
<p><a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js">» example implementation</a><br>
@ -1552,16 +1548,16 @@ Spec:<br><Br></p>
<li>the textlog contains <code>aria-descriptions</code>, and its narration (Screenreader e.g.) can be skipped (via 2-button navigation)</li>
<li>The <code>back</code> command should navigate back to the previous URL (alias for browser-backbutton)</li>
<li>The <code>forward</code> command should navigate back to the next URL (alias for browser-nextbutton)</li>
<li>A destination is a 3D node containing an <code>href</code> with a <code>pos=</code> XR fragment</li>
<li>A destination is a 3D node containing an <code>href</code> with a <code>#...</code> XR fragment (which matches a 3d object name)</li>
<li>The <code>go</code> command should list all possible destinations</li>
<li>The <code>go left</code> command should move the camera around 0.3 meters to the left</li>
<li>The <code>go right</code> command should move the camera around 0.3 meters to the right</li>
<li>The <code>go forward</code> command should move the camera 0.3 meters forward (direction of current rotation).</li>
<li>The <code>rotate left</code> command should rotate the camera 0.3 to the left</li>
<li>The <code>rotate left</code> command should rotate the camera 0.3 to the right</li>
<li>The (dynamic) <code>go abc</code> command should navigate to <code>#pos=scene2</code> in case there&rsquo;s a 3D node with name <code>abc</code> and <code>href</code> value <code>#pos=scene2</code></li>
<li>The <code>look</code> command should give an (contextual) 3D-to-text transcript, by scanning the <code>aria-description</code> values of the current <code>pos=</code> value (including its children)</li>
<li>The <code>do</code> command should list all possible <code>href</code> values which don&rsquo;t contain an <code>pos=</code> XR Fragment</li>
<li>The (dynamic) <code>go abc</code> command should navigate to <code>#scene2</code> in case there&rsquo;s a 3D node with name <code>abc</code> and <code>href</code> value <code>#scene2</code></li>
<li>The <code>look</code> command should give an (contextual) 3D-to-text transcript, by scanning the <code>aria-description</code> values of the current <code>#...</code> (3D object) value (including its children)</li>
<li>The <code>do</code> command should list all possible <code>href</code> values which don&rsquo;t contain an <code>#...</code> XR Fragment</li>
<li>The (dynamic) <code>do abc</code> command should navigate/execute <code>https://.../...</code> in case a 3D node exist with name <code>abc</code> and <code>href</code> value <code>https://.../...</code></li>
</ol>
@ -1783,7 +1779,7 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
<tr>
<td>XR fragment</td>
<td>URI Fragment with spatial hints like <code>#pos=0,0,0&amp;t=1,100</code> e.g.</td>
<td>URI Fragment with spatial hints (which match the name of a 3D object-, camera-, animation-object)</td>
</tr>
<tr>

View file

@ -93,12 +93,13 @@ value: draft-XRFRAGMENTS-leonvankammen-00
.# Abstract
An open specification for hyperlinking & deeplinking 3D fileformats.
This draft is a specification for interactive URI-controllable 3D files, enabling [hypermediatic](https://github.com/coderofsalvation/hypermediatic) navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.<br>
The specification uses [W3C Media Fragments](https://www.w3.org/TR/media-frags/) and [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.<br>
XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like [URI Fragments](https://en.wikipedia.org/wiki/URI_fragment).<br>
XR Fragments views spatial webs thru the lens of 3D scene URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).
XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like [URI Fragments](https://en.wikipedia.org/wiki/URI_fragment).<br>
XR Fragments views XR experiences thru the lens of 3D object URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).
> XR Fragments is a <b>Meta scene format</b> which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.<br>
> XR Fragments is a <b>heuristical 3D format</b> which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.<br>
These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing <b>higher interop</b> between fileformats, 3D editors, viewers and game-engines.
> Almost every idea in this document is demonstrated at [https://xrfragment.org](https://xrfragment.org)
@ -201,10 +202,10 @@ XR Fragments utilizes URLs:
| fragment | type | example | info |
|-------------------|------------|--------------------|----------------------------------------------------------------------|
| `#pos` | vector3 | `#pos=0.5,0,0` `#pos=room` `#pos=cam2` | positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera |
| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 |
| `#......` | vector3 | `#room1` `#room2` `#cam2` | positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera |
| [Media Fragments](https://www.w3.org/TR/media-frags/) | [media fragment](#media%20fragments%20and%20datatypes) | `#t=0,2&loop` | play (and loop) 3D animation from 0 seconds till 2 seconds|
# List of **explicit* metadata
These are the possible 'extras' for 3D nodes and sidecar-files
@ -212,6 +213,109 @@ These are the possible 'extras' for 3D nodes and sidecar-files
| key | type | example (JSON) | function | existing compatibility |
|--------------|----------|------------------------|---------------------|----------------------------------------|
| `href` | string | `"href": "b.gltf"` | XR teleport | custom property in 3D fileformats |
# HFL (Hypermediatic Feedback Loop) for XR Browsers
`href` metadata traditionally implies **click** AND **navigate**, however XR Fragments adds stateless **click** (`xrf://#....`) or **navigate** (`xrf://#...`)
as well (which allows many extra interactions which otherwise need a scripting language). This is known as **hashbus**-only events (see image above).
> Being able to use the same URI Fragment DSL for navigation (`href: #foo`) as well as interactions (`href: xrf://#bar`) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.
This opens up the following benefits for traditional & future webbrowsers:
* [hypermediatic](https://github.com/coderofsalvation/hypermediatic) loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).
* allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the `xrf://` hashbus (`xrf://#person=walk` to trigger `walk`-animation for object `person`)
* collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus
* completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources)
XR Fragments itself are [hypermediatic](https://github.com/coderofsalvation/hypermediatic) and HTML-agnostic, though pseudo-XR Fragment browsers **can** be implemented on top of HTML/Javascript.
| principle | XR 4D URL | HTML 2D URL |
|-----------------------------|-------------------------------------------------|---------------------------------------|
| the XRWG | wordgraph (collapses 3D scene to tags) | Ctrl-F (find) |
| the hashbus | hashtags alter camera/scene/object-projections | hashtags alter document positions |
| src metadata | renders content and offers sourceportation | renders content |
| href metadata | teleports to other XR document | jumps to other HTML document |
| href metadata | triggers predefined view | Media fragments |
| href metadata | triggers camera/scene/object/projections | n/a |
| href metadata | draws visible connection(s) for XRWG 'tag' | n/a |
| href metadata | filters certain (in)visible objects | n/a |
| href metadata | href="xrf://#-foo&bar" | href="javascript:hideFooAndShowBar()` |
| | (this does not update topLevel URI) | (this is non-standard, non-hypermediatic) |
> An important aspect of HFL is that URI Fragments can be triggered without updating the top-level URI (default href-behaviour) thru their own 'bus' (`xrf://#.....`). This decoupling between navigation and interaction prevents non-standard things like (`href`:`javascript:dosomething()`).
# Conventions and Definitions
See appendix below in case certain terms are not clear.
## XR Fragment URL Grammar
For typical HTTP-like browsers/applications:
```
reserved = gen-delims / sub-delims
gen-delims = "#" / "&"
sub-delims = "," / "="
```
> Example: `://foo.com/my3d.gltf#room1&prio=-5&t=0,100`
| Demo | Explanation |
|-------------------------------|---------------------------------|
| `room1` | vector/coordinate argument e.g. |
| `room1&rot=0,90,0&cam1` | combinators |
> this is already implemented in all browsers
Pseudo (non-native) browser-implementations (supporting XR Fragments using HTML+JS e.g.) can use the `?` search-operator to address outbound content.<br>
In other words, the URL updates to: `https://me.com?https://me.com/other.glb` when navigating to `https://me.com/other.glb` from inside a `https://me.com` WebXR experience e.g.<br>
That way, if the link gets shared, the XR Fragments implementation at `https://me.com` can load the latter (and still indicates which XR Fragments entrypoint-experience/client was used).
# Spatial Referencing 3D
XR Fragments assume the following objectname-to-URIFragment mapping:
```
my.io/scene.fbx
+─────────────────────────────+
│ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor)
│ +─────────────────────────+ │
│ │ building │ │ src: http://my.io/scene.fbx#building (includes mainobject,floor)
│ │ +─────────────────────+ │ │
│ │ │ mainobject │ │ │ src: http://my.io/scene.fbx#mainobject (includes floor)
│ │ │ +─────────────────+ │ │ │
│ │ │ │ floor │ │ │ │ src: http://my.io/scene.fbx#floor (just floor object)
│ │ │ │ │ │ │ │
│ │ │ +─────────────────+ │ │ │
│ │ +─────────────────────+ │ │
│ +─────────────────────────+ │
+─────────────────────────────+
```
> Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).
Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.<br>
For example, to render a portal with a preview-version of the scene, create an 3D object with:
* href: `https://scene.fbx`
* src: `https://otherworld.gltf#mainobject`
> It also allows **sourceportation**, which basically means the enduser can teleport to the original XR Document of an `src` embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it.
---
# non-normative
The following below is non-normative heuristics which are not part officially part of the spec.
# additional **explicit** metadata
| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 |
| `src` | string | `"src": "#cube"` | XR embed / teleport | custom property in 3D fileformats |
| `tag` | string | `"tag": "cubes geo"` | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats |
| `#` | string | `"#": "#mypreset` | trigger default fragment on load | custom property in 3D fileformats |
@ -259,106 +363,16 @@ The sidecar will define (or **override** already existing) extras, which can be
# Hypermediatic FeedbackLoop for XR browsers
`href` metadata traditionally implies **click** AND **navigate**, however XR Fragments adds stateless **click** (`xrf://#....`) or **navigate** (`xrf://#pos=...`)
as well (which allows many extra interactions which otherwise need a scripting language). This is known as **hashbus**-only events (see image above).
> Being able to use the same URI Fragment DSL for navigation (`href: #foo`) as well as interactions (`href: xrf://#bar`) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.
This opens up the following benefits for traditional & future webbrowsers:
* [hypermediatic](https://github.com/coderofsalvation/hypermediatic) loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).
* allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the `xrf://` hashbus
* collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus
* completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources)
XR Fragments itself are [hypermediatic](https://github.com/coderofsalvation/hypermediatic) and HTML-agnostic, though pseudo-XR Fragment browsers **can** be implemented on top of HTML/Javascript.
| principle | XR 4D URL | HTML 2D URL |
|-----------------------------|-------------------------------------------------|---------------------------------------|
| the XRWG | wordgraph (collapses 3D scene to tags) | Ctrl-F (find) |
| the hashbus | hashtags alter camera/scene/object-projections | hashtags alter document positions |
| src metadata | renders content and offers sourceportation | renders content |
| href metadata | teleports to other XR document | jumps to other HTML document |
| href metadata | triggers predefined view | Media fragments |
| href metadata | triggers camera/scene/object/projections | n/a |
| href metadata | draws visible connection(s) for XRWG 'tag' | n/a |
| href metadata | filters certain (in)visible objects | n/a |
| href metadata | href="xrf://#-foo&bar" | href="javascript:hideFooAndShowBar()` |
| | (this does not update topLevel URI) | (this is non-standard, non-hypermediatic) |
> An important aspect of HFL is that URI Fragments can be triggered without updating the top-level URI (default href-behaviour) thru their own 'bus' (`xrf://#.....`). This decoupling between navigation and interaction prevents non-standard things like (`href`:`javascript:dosomething()`).
# Conventions and Definitions
See appendix below in case certain terms are not clear.
## XR Fragment URL Grammar
For typical HTTP-like browsers/applications:
```
reserved = gen-delims / sub-delims
gen-delims = "#" / "&"
sub-delims = "," / "="
```
> Example: `://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100`
| Demo | Explanation |
|-------------------------------|---------------------------------|
| `pos=1,2,3` | vector/coordinate argument e.g. |
| `pos=1,2,3&rot=0,90,0&foo` | combinators |
> this is already implemented in all browsers
Pseudo (non-native) browser-implementations (supporting XR Fragments using HTML+JS e.g.) can use the `?` search-operator to address outbound content.<br>
In other words, the URL updates to: `https://me.com?https://me.com/other.glb` when navigating to `https://me.com/other.glb` from inside a `https://me.com` WebXR experience e.g.<br>
That way, if the link gets shared, the XR Fragments implementation at `https://me.com` can load the latter (and still indicates which XR Fragments entrypoint-experience/client was used).
# Spatial Referencing 3D
XR Fragments assume the following objectname-to-URIFragment mapping:
```
my.io/scene.fbx
+─────────────────────────────+
│ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor)
│ +─────────────────────────+ │
│ │ building │ │ src: http://my.io/scene.fbx#building (includes mainobject,floor)
│ │ +─────────────────────+ │ │
│ │ │ mainobject │ │ │ src: http://my.io/scene.fbx#mainobject (includes floor)
│ │ │ +─────────────────+ │ │ │
│ │ │ │ floor │ │ │ │ src: http://my.io/scene.fbx#floor (just floor object)
│ │ │ │ │ │ │ │
│ │ │ +─────────────────+ │ │ │
│ │ +─────────────────────+ │ │
│ +─────────────────────────+ │
+─────────────────────────────+
```
> Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).
Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.<br>
For example, to render a portal with a preview-version of the scene, create an 3D object with:
* href: `https://scene.fbx`
* src: `https://otherworld.gltf#mainobject`
> It also allows **sourceportation**, which basically means the enduser can teleport to the original XR Document of an `src` embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it.
## Level2: Implicit URI Fragments
> Warning: non-normative
These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser:
| |fragment | type | example | info |
|------|------------------|----------|-------------------|-------------------------------------------------------------------------------|
| **PRESET** | `#<preset>` | string | `#cubes` | evaluates preset (`#foo&bar`) when a scene contains extra (`#cubes: #foo&bar` e.g.) while URL-browserbar reflects `#cubes`. Only works when metadata-key starts with `#` |
| **FOCUS** | `#<tag_or_objectname>` | string | `#person` | (and show) object(s) with `tag: person` or name `person` (XRWG lookup) |
| **FOCUS** | `xrf://#<tag_or_objectname>` | string | `#person` | (and show) object(s) with `tag: person` or name `person` (XRWG lookup) |
| **FILTERS** | `#[!][-]<tag_or_objectname>[*]` | string | `#person` (`#-person`) | will reset (`!`), show/focus or hide (`-`) focus object(s) with `tag: person` or name `person` by looking up XRWG (`*`=including children) |
| **MATERIALUPDATE** | `#<tag_or_objectname>[*]=<materialname>` | string=string | `#car=metallic`| sets material of car to material with name `metallic` (`*`=including children)|
| | | | `#soldout*=halfopacity`| set material of objects tagged with `product` to material with name `metallic` |
@ -367,7 +381,7 @@ These fragments are derived from objectnames (or their extras) within a 3D scene
## media fragments and datatypes
> NOTE: below the word 'play' applies to 3D animations embedded in the 3D scene(file) **but also** media defined in `src`-metadata like audio/video-files (mp3/mp4 e.g.)
> Warning: **non-normative** (below the word 'play' applies to 3D animations embedded in the 3D scene(file) **but also** media defined in `src`-metadata like audio/video-files (mp3/mp4 e.g.))
| type | syntax | example | info |
|-------------------------------|-----------------------------------|-----------------|----------------------|
@ -456,7 +470,7 @@ Here's an ascii representation of a 3D scene-graph which contains 3D objects `
│ index.gltf │
│ │ │
│ ├── ◻ buttonA │
│ │ └ href: #pos=1,0,1&t=100,200 │
│ │ └ href: #room1&t=100,200 │
│ │ │
│ └── ◻ buttonB │
│ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc)
@ -466,23 +480,27 @@ Here's an ascii representation of a 3D scene-graph which contains 3D objects `
```
An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the `buttonA` and `buttonB`.<br>
In case of `buttonA` the end-user will be teleported to another location and time in the **current loaded scene**, but `buttonB` will **replace the current scene** with a new one, like `other.fbx`, and assume `pos=0,0,0`.
In case of `buttonA` the end-user will be teleported to another location and time in the **current loaded scene**, but `buttonB` will **replace the current scene** with a new one, like `other.fbx`, and assume camera coordinate `0,0,0`
# Top-level URL processing
> Example URL: `://foo/world.gltf#cube&pos=0,0,0`
> Example URL: `://foo/world.gltf#room1&t=10`
The URL-processing-flow for hypermedia browsers goes like this:
1. IF a `#cube` matches a custom property-key (of an object) in the 3D file/scene (`#cube`: `#......`) <b>THEN</b> execute that predefined_view.
2. IF scene operators (`pos`) and/or animation operator (`t`) are present in the URL then (re)position the camera and/or animation-range accordingly.
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/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]))
1. IF a `#room1` matches a custom property-key (of an object) in the 3D file/scene (`#room1`: `#......`) <b>THEN</b> execute that predefined_view.
2. IF scene operators and/or animation operator (`t`) are present in the URL then (re)position the camera (to `room1`) and/or animation-range (`10`) accordingly.
3. IF no camera-position has been set in <b>step 1 or 2</b> assume `0,0,0` as camera coordinate (XR: add user-height) ([example](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]))
**Non-normative / Deprecated**:
4. IF a `#cube` matches the name (of an object) in the 3D file/scene then draw a line from the enduser('s heart) to that object (to highlight it).
5. IF a `#cube` matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).
# Embedding XR content using src
> NOTE: only adviced for local-first experiences (where resources can be cached).
`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, and follows similar logic like the previous chapter, except that it does not modify the camera.
@ -551,11 +569,11 @@ navigation, portals & mutations
| fragment | type | example value |
|----------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------|
|`href` | string (uri or predefined view) | `#pos=1,1,0`<br>`#pos=1,1,0&rot=90,0,0`<br>`://somefile.gltf#pos=1,1,0`<br> |
|`href` | string (uri or predefined view) | `#room1`<br>`#pos=room1&rot=90,0,0`<br>`://somefile.gltf#room1`<br> |
1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes `pos=0,0,0&rot=0,0,0` by default (unless specified)
1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes `room2&rot=0,0,0` by default (unless specified)
2. relocation/reorientation should happen locally for local URI's (`#pos=....`)
2. relocation/reorientation should happen locally for local URI's (`#....`)
3. navigation should not happen ''immediately'' when user is more than 5 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)
@ -567,9 +585,9 @@ navigation, portals & mutations
7. ignore previous rule in special cases, like clicking an `href` using camera-portal collision (the back-button could cause a teleport-loop if the previous position is too close)
8. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also contain an href), however only 1 href can be executed at the same time.
8. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time.
9. the end-user navigator back/forward buttons should repeat a back/forward action until a `pos=...` primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)
9. the end-user navigator back/forward buttons should repeat a back/forward action until a `#...` primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)
[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js)<br>
[» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/href.gltf#L192)<br>
@ -1000,19 +1018,18 @@ Spec:<br><Br>
4. the textlog contains `aria-descriptions`, and its narration (Screenreader e.g.) can be skipped (via 2-button navigation)
5. The `back` command should navigate back to the previous URL (alias for browser-backbutton)
6. The `forward` command should navigate back to the next URL (alias for browser-nextbutton)
7. A destination is a 3D node containing an `href` with a `pos=` XR fragment
7. A destination is a 3D node containing an `href` with a `#...` XR fragment (which matches a 3d object name)
8. The `go` command should list all possible destinations
9. The `go left` command should move the camera around 0.3 meters to the left
10. The `go right` command should move the camera around 0.3 meters to the right
11. The `go forward` command should move the camera 0.3 meters forward (direction of current rotation).
12. The `rotate left` command should rotate the camera 0.3 to the left
13. The `rotate left` command should rotate the camera 0.3 to the right
14. The (dynamic) `go abc` command should navigate to `#pos=scene2` in case there's a 3D node with name `abc` and `href` value `#pos=scene2`
15. The `look` command should give an (contextual) 3D-to-text transcript, by scanning the `aria-description` values of the current `pos=` value (including its children)
16. The `do` command should list all possible `href` values which don't contain an `pos=` XR Fragment
14. The (dynamic) `go abc` command should navigate to `#scene2` in case there's a 3D node with name `abc` and `href` value `#scene2`
15. The `look` command should give an (contextual) 3D-to-text transcript, by scanning the `aria-description` values of the current `#...` (3D object) value (including its children)
16. The `do` command should list all possible `href` values which don't contain an `#...` XR Fragment
17. The (dynamic) `do abc` command should navigate/execute `https://.../...` in case a 3D node exist with name `abc` and `href` value `https://.../...`
## Two-button navigation
For specific user-profiles, gyroscope/mouse/keyboard/audio/visuals will not be available.<br>
@ -1154,7 +1171,7 @@ This document has no IANA actions.
|URL | something somewhere via someprotocol (`http://me.com/foo.glb`) |
|URN | something at some domain (`me.com/foo.glb`) |
|metadata | custom properties of text, 3D Scene or Object(nodes), relevant to machines and a human minority (academics/developers) |
|XR fragment | URI Fragment with spatial hints like `#pos=0,0,0&t=1,100` e.g. |
|XR fragment | URI Fragment with spatial hints (which match the name of a 3D object-, camera-, animation-object) |
|the XRWG | wordgraph (collapses 3D scene to tags) |
|the hashbus | hashtags map to camera/scene-projections |
|spacetime hashtags | positions camera, triggers scene-preset/time |

File diff suppressed because it is too large Load diff

View file

@ -10,14 +10,15 @@
<workgroup>Jens &amp; Leon Internet Engineering Task Force</workgroup>
<abstract>
<t>This draft is a specification for interactive URI-controllable 3D files, enabling <eref target="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.<br />
<t>An open specification for hyperlinking &amp; deeplinking 3D fileformats.
This draft is a specification for interactive URI-controllable 3D files, enabling <eref target="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.<br />
The specification uses <eref target="https://www.w3.org/TR/media-frags/">W3C Media Fragments</eref> and <eref target="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</eref> to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.<br />
XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like <eref target="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref>.<br />
XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like <eref target="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref>.<br />
XR Fragments views spatial webs thru the lens of 3D scene URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).</t>
<t>XR Fragments is a &lt;b&gt;Meta scene format&lt;/b&gt; which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.<br />
XR Fragments views XR experiences thru the lens of 3D object URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).</t>
<t>XR Fragments is a &lt;b&gt;heuristical 3D format&lt;/b&gt; which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.<br />
These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing &lt;b&gt;higher interop&lt;/b&gt; between fileformats, 3D editors, viewers and game-engines.</t>
<t>Almost every idea in this document is demonstrated at <eref target="https://xrfragment.org">https://xrfragment.org</eref></t>
@ -133,19 +134,12 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec
<tbody>
<tr>
<td><tt>#pos</tt></td>
<td><tt>#......</tt></td>
<td>vector3</td>
<td><tt>#pos=0.5,0,0</tt> <tt>#pos=room</tt> <tt>#pos=cam2</tt></td>
<td><tt>#room1</tt> <tt>#room2</tt> <tt>#cam2</tt></td>
<td>positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera</td>
</tr>
<tr>
<td><tt>#rot</tt></td>
<td>vector3</td>
<td><tt>#rot=0,90,0</tt></td>
<td>rotates camera to xyz-coord 0.5,0,0</td>
</tr>
<tr>
<td><eref target="https://www.w3.org/TR/media-frags/">Media Fragments</eref></td>
<td><eref target="#media%20fragments%20and%20datatypes">media fragment</eref></td>
@ -176,80 +170,18 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec
<td>XR teleport</td>
<td>custom property in 3D fileformats</td>
</tr>
<tr>
<td><tt>src</tt></td>
<td>string</td>
<td><tt>&quot;src&quot;: &quot;#cube&quot;</tt></td>
<td>XR embed / teleport</td>
<td>custom property in 3D fileformats</td>
</tr>
<tr>
<td><tt>tag</tt></td>
<td>string</td>
<td><tt>&quot;tag&quot;: &quot;cubes geo&quot;</tt></td>
<td>tag object (for filter-use / XRWG highlighting)</td>
<td>custom property in 3D fileformats</td>
</tr>
<tr>
<td><tt>#</tt></td>
<td>string</td>
<td><tt>&quot;#&quot;: &quot;#mypreset</tt></td>
<td>trigger default fragment on load</td>
<td>custom property in 3D fileformats</td>
</tr>
</tbody>
</table><blockquote><t>Supported popular compatible 3D fileformats: <tt>.gltf</tt>, <tt>.obj</tt>, <tt>.fbx</tt>, <tt>.usdz</tt>, <tt>.json</tt> (THREE.js), <tt>.dae</tt> and so on.</t>
</blockquote>
<section anchor="sidecar-file"><name>Sidecar-file</name>
<blockquote><t>NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a <tt>.glb</tt> e.g.).</t>
</blockquote><t>For developers, sidecar-file can allow for defining <strong>explicit</strong> XR Fragments metadata, outside of the 3D file.<br />
</table></section>
This can be done via a JSON-pointers <eref target="https://www.rfc-editor.org/rfc/rfc6901">RFC6901</eref> in a JSON <eref target="https://en.wikipedia.org/wiki/Sidecar_file">sidecar-file</eref>:</t>
<ul spacing="compact">
<li>experience.glb</li>
<li>experience.json</li>
</ul>
<sourcecode type="json"><![CDATA[{
"/":{
"#": "#-penguin",
"aria-description": "description of scene",
},
"/room/chair": {
"href": "#penguin"
}
}
]]>
</sourcecode>
<blockquote><t>This would mean: hide object(s) with name or <tt>tag</tt>-value 'penguin' upon scene-load, and show it when the user clicks the chair</t>
</blockquote><t>So after loading <tt>experience.glb</tt> the existence of <tt>experience.json</tt> is detected, to apply the explicit metadata.<br />
The sidecar will define (or <strong>override</strong> already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).</t>
<blockquote><t>In THREE.js-code this would boil down to:</t>
</blockquote>
<sourcecode type="javascript"><![CDATA[ scene.userData['#'] = "#chair&penguin"
scene.userData['aria-description'] = "description of scene"
scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin"
// now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene
]]>
</sourcecode>
</section>
</section>
<section anchor="hypermediatic-feedbackloop-for-xr-browsers"><name>Hypermediatic FeedbackLoop for XR browsers</name>
<t><tt>href</tt> metadata traditionally implies <strong>click</strong> AND <strong>navigate</strong>, however XR Fragments adds stateless <strong>click</strong> (<tt>xrf://#....</tt>) or <strong>navigate</strong> (<tt>xrf://#pos=...</tt>)
<section anchor="hfl-hypermediatic-feedback-loop-for-xr-browsers"><name>HFL (Hypermediatic Feedback Loop) for XR Browsers</name>
<t><tt>href</tt> metadata traditionally implies <strong>click</strong> AND <strong>navigate</strong>, however XR Fragments adds stateless <strong>click</strong> (<tt>xrf://#....</tt>) or <strong>navigate</strong> (<tt>xrf://#...</tt>)
as well (which allows many extra interactions which otherwise need a scripting language). This is known as <strong>hashbus</strong>-only events (see image above).</t>
<blockquote><t>Being able to use the same URI Fragment DSL for navigation (<tt>href: #foo</tt>) as well as interactions (<tt>href: xrf://#bar</tt>) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.</t>
</blockquote><t>This opens up the following benefits for traditional &amp; future webbrowsers:</t>
<ul spacing="compact">
<li><eref target="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).</li>
<li>allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the <tt>xrf://</tt> hashbus</li>
<li>allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the <tt>xrf://</tt> hashbus (<tt>xrf://#person=walk</tt> to trigger <tt>walk</tt>-animation for object <tt>person</tt>)</li>
<li>collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus</li>
<li>completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources)</li>
</ul>
@ -338,7 +270,7 @@ gen-delims = "#" / "&"
sub-delims = "," / "="
]]>
</artwork>
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#pos=1,0,0&amp;prio=-5&amp;t=0,100</tt></t>
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#room1&amp;prio=-5&amp;t=0,100</tt></t>
</blockquote><table>
<thead>
<tr>
@ -349,12 +281,12 @@ sub-delims = "," / "="
<tbody>
<tr>
<td><tt>pos=1,2,3</tt></td>
<td><tt>room1</tt></td>
<td>vector/coordinate argument e.g.</td>
</tr>
<tr>
<td><tt>pos=1,2,3&amp;rot=0,90,0&amp;foo</tt></td>
<td><tt>room1&amp;rot=0,90,0&amp;cam1</tt></td>
<td>combinators</td>
</tr>
</tbody>
@ -398,9 +330,59 @@ For example, to render a portal with a preview-version of the scene, create an 3
<li>src: <tt>https://otherworld.gltf#mainobject</tt></li>
</ul>
<blockquote><t>It also allows <strong>sourceportation</strong>, which basically means the enduser can teleport to the original XR Document of an <tt>src</tt> embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it.</t>
</blockquote></section>
<section anchor="non-normative"><name>non-normative</name>
<t>The following below is non-normative heuristics which are not part officially part of the spec.</t>
</section>
<section anchor="additional-explicit-metadata"><name>additional <strong>explicit</strong> metadata</name>
<t>| <tt>#rot</tt> | vector3 | <tt>#rot=0,90,0</tt> | rotates camera to xyz-coord 0.5,0,0 |
| <tt>src</tt> | string | <tt>&quot;src&quot;: &quot;#cube&quot;</tt> | XR embed / teleport | custom property in 3D fileformats |
| <tt>tag</tt> | string | <tt>&quot;tag&quot;: &quot;cubes geo&quot;</tt> | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats |
| <tt>#</tt> | string | <tt>&quot;#&quot;: &quot;#mypreset</tt> | trigger default fragment on load | custom property in 3D fileformats |</t>
<blockquote><t>Supported popular compatible 3D fileformats: <tt>.gltf</tt>, <tt>.obj</tt>, <tt>.fbx</tt>, <tt>.usdz</tt>, <tt>.json</tt> (THREE.js), <tt>.dae</tt> and so on.</t>
</blockquote>
<section anchor="sidecar-file"><name>Sidecar-file</name>
<blockquote><t>NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a <tt>.glb</tt> e.g.).</t>
</blockquote><t>For developers, sidecar-file can allow for defining <strong>explicit</strong> XR Fragments metadata, outside of the 3D file.<br />
This can be done via a JSON-pointers <eref target="https://www.rfc-editor.org/rfc/rfc6901">RFC6901</eref> in a JSON <eref target="https://en.wikipedia.org/wiki/Sidecar_file">sidecar-file</eref>:</t>
<ul spacing="compact">
<li>experience.glb</li>
<li>experience.json</li>
</ul>
<sourcecode type="json"><![CDATA[{
"/":{
"#": "#-penguin",
"aria-description": "description of scene",
},
"/room/chair": {
"href": "#penguin"
}
}
]]>
</sourcecode>
<blockquote><t>This would mean: hide object(s) with name or <tt>tag</tt>-value 'penguin' upon scene-load, and show it when the user clicks the chair</t>
</blockquote><t>So after loading <tt>experience.glb</tt> the existence of <tt>experience.json</tt> is detected, to apply the explicit metadata.<br />
The sidecar will define (or <strong>override</strong> already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).</t>
<blockquote><t>In THREE.js-code this would boil down to:</t>
</blockquote>
<sourcecode type="javascript"><![CDATA[ scene.userData['#'] = "#chair&penguin"
scene.userData['aria-description'] = "description of scene"
scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin"
// now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene
]]>
</sourcecode>
</section>
<section anchor="level2-implicit-uri-fragments"><name>Level2: Implicit URI Fragments</name>
<t>These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser:</t>
<blockquote><t>Warning: non-normative</t>
</blockquote><t>These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser:</t>
<table>
<thead>
<tr>
@ -423,7 +405,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
<tr>
<td><strong>FOCUS</strong></td>
<td><tt>#&lt;tag_or_objectname&gt;</tt></td>
<td><tt>xrf://#&lt;tag_or_objectname&gt;</tt></td>
<td>string</td>
<td><tt>#person</tt></td>
<td>(and show) object(s) with <tt>tag: person</tt> or name <tt>person</tt> (XRWG lookup)</td>
@ -472,7 +454,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
</table></section>
<section anchor="media-fragments-and-datatypes"><name>media fragments and datatypes</name>
<blockquote><t>NOTE: below the word 'play' applies to 3D animations embedded in the 3D scene(file) <strong>but also</strong> media defined in <tt>src</tt>-metadata like audio/video-files (mp3/mp4 e.g.)</t>
<blockquote><t>Warning: <strong>non-normative</strong> (below the word 'play' applies to 3D animations embedded in the 3D scene(file) <strong>but also</strong> media defined in <tt>src</tt>-metadata like audio/video-files (mp3/mp4 e.g.))</t>
</blockquote><table>
<thead>
<tr>
@ -670,7 +652,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
│ index.gltf │
│ │ │
│ ├── ◻ buttonA │
│ │ └ href: #pos=1,0,1&t=100,200 │
│ │ └ href: #room1&t=100,200 │
│ │ │
│ └── ◻ buttonB │
│ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc)
@ -681,24 +663,29 @@ For example, to render a portal with a preview-version of the scene, create an 3
</artwork>
<t>An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the <tt>buttonA</tt> and <tt>buttonB</tt>.<br />
In case of <tt>buttonA</tt> the end-user will be teleported to another location and time in the <strong>current loaded scene</strong>, but <tt>buttonB</tt> will <strong>replace the current scene</strong> with a new one, like <tt>other.fbx</tt>, and assume <tt>pos=0,0,0</tt>.</t>
In case of <tt>buttonA</tt> the end-user will be teleported to another location and time in the <strong>current loaded scene</strong>, but <tt>buttonB</tt> will <strong>replace the current scene</strong> with a new one, like <tt>other.fbx</tt>, and assume camera coordinate <tt>0,0,0</tt></t>
</section>
<section anchor="top-level-url-processing"><name>Top-level URL processing</name>
<blockquote><t>Example URL: <tt>://foo/world.gltf#cube&amp;pos=0,0,0</tt></t>
<blockquote><t>Example URL: <tt>://foo/world.gltf#room1&amp;t=10</tt></t>
</blockquote><t>The URL-processing-flow for hypermedia browsers goes like this:</t>
<ol spacing="compact">
<li>IF a <tt>#cube</tt> matches a custom property-key (of an object) in the 3D file/scene (<tt>#cube</tt>: <tt>#......</tt>) &lt;b&gt;THEN&lt;/b&gt; execute that predefined_view.</li>
<li>IF scene operators (<tt>pos</tt>) and/or animation operator (<tt>t</tt>) are present in the URL then (re)position the camera and/or animation-range accordingly.</li>
<li>IF no camera-position has been set in &lt;b&gt;step 1 or 2&lt;/b&gt; update the top-level URL with <tt>#pos=0,0,0</tt> (<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]">example</eref>)</li>
<li>IF a <tt>#room1</tt> matches a custom property-key (of an object) in the 3D file/scene (<tt>#room1</tt>: <tt>#......</tt>) &lt;b&gt;THEN&lt;/b&gt; execute that predefined_view.</li>
<li>IF scene operators and/or animation operator (<tt>t</tt>) are present in the URL then (re)position the camera (to <tt>room1</tt>) and/or animation-range (<tt>10</tt>) accordingly.</li>
<li>IF no camera-position has been set in &lt;b&gt;step 1 or 2&lt;/b&gt; assume <tt>0,0,0</tt> as camera coordinate (XR: add user-height) (<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]">example</eref>)</li>
</ol>
<t><strong>Non-normative / Deprecated</strong>:</t>
<ol spacing="compact" start="4">
<li>IF a <tt>#cube</tt> matches the name (of an object) in the 3D file/scene then draw a line from the enduser('s heart) to that object (to highlight it).</li>
<li>IF a <tt>#cube</tt> matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).</li>
</ol>
</section>
<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 />
<blockquote><t>NOTE: only adviced for local-first experiences (where resources can be cached).</t>
</blockquote><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, and follows similar logic like the previous chapter, except that it does not modify the camera.</t>
<table>
@ -800,17 +787,17 @@ Resizing will be happen accordingly to its placeholder object <tt>aquariumcube</
<tr>
<td><tt>href</tt></td>
<td>string (uri or predefined view)</td>
<td><tt>#pos=1,1,0</tt><br />
<tt>#pos=1,1,0&amp;rot=90,0,0</tt><br />
<tt>://somefile.gltf#pos=1,1,0</tt><br />
<td><tt>#room1</tt><br />
<tt>#pos=room1&amp;rot=90,0,0</tt><br />
<tt>://somefile.gltf#room1</tt><br />
</td>
</tr>
</tbody>
</table>
<ol>
<li><t>clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes <tt>pos=0,0,0&amp;rot=0,0,0</tt> by default (unless specified)</t>
<li><t>clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes <tt>room2&amp;rot=0,0,0</tt> by default (unless specified)</t>
</li>
<li><t>relocation/reorientation should happen locally for local URI's (<tt>#pos=....</tt>)</t>
<li><t>relocation/reorientation should happen locally for local URI's (<tt>#....</tt>)</t>
</li>
<li><t>navigation should not happen ''immediately'' when user is more than 5 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)</t>
</li>
@ -822,9 +809,9 @@ Resizing will be happen accordingly to its placeholder object <tt>aquariumcube</
</li>
<li><t>ignore previous rule in special cases, like clicking an <tt>href</tt> using camera-portal collision (the back-button could cause a teleport-loop if the previous position is too close)</t>
</li>
<li><t>href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also contain an href), however only 1 href can be executed at the same time.</t>
<li><t>href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time.</t>
</li>
<li><t>the end-user navigator back/forward buttons should repeat a back/forward action until a <tt>pos=...</tt> primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)</t>
<li><t>the end-user navigator back/forward buttons should repeat a back/forward action until a <tt>#...</tt> primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)</t>
</li>
</ol>
<t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js">» example implementation</eref><br />
@ -1379,16 +1366,16 @@ Spec:<br />
<li>the textlog contains <tt>aria-descriptions</tt>, and its narration (Screenreader e.g.) can be skipped (via 2-button navigation)</li>
<li>The <tt>back</tt> command should navigate back to the previous URL (alias for browser-backbutton)</li>
<li>The <tt>forward</tt> command should navigate back to the next URL (alias for browser-nextbutton)</li>
<li>A destination is a 3D node containing an <tt>href</tt> with a <tt>pos=</tt> XR fragment</li>
<li>A destination is a 3D node containing an <tt>href</tt> with a <tt>#...</tt> XR fragment (which matches a 3d object name)</li>
<li>The <tt>go</tt> command should list all possible destinations</li>
<li>The <tt>go left</tt> command should move the camera around 0.3 meters to the left</li>
<li>The <tt>go right</tt> command should move the camera around 0.3 meters to the right</li>
<li>The <tt>go forward</tt> command should move the camera 0.3 meters forward (direction of current rotation).</li>
<li>The <tt>rotate left</tt> command should rotate the camera 0.3 to the left</li>
<li>The <tt>rotate left</tt> command should rotate the camera 0.3 to the right</li>
<li>The (dynamic) <tt>go abc</tt> command should navigate to <tt>#pos=scene2</tt> in case there's a 3D node with name <tt>abc</tt> and <tt>href</tt> value <tt>#pos=scene2</tt></li>
<li>The <tt>look</tt> command should give an (contextual) 3D-to-text transcript, by scanning the <tt>aria-description</tt> values of the current <tt>pos=</tt> value (including its children)</li>
<li>The <tt>do</tt> command should list all possible <tt>href</tt> values which don't contain an <tt>pos=</tt> XR Fragment</li>
<li>The (dynamic) <tt>go abc</tt> command should navigate to <tt>#scene2</tt> in case there's a 3D node with name <tt>abc</tt> and <tt>href</tt> value <tt>#scene2</tt></li>
<li>The <tt>look</tt> command should give an (contextual) 3D-to-text transcript, by scanning the <tt>aria-description</tt> values of the current <tt>#...</tt> (3D object) value (including its children)</li>
<li>The <tt>do</tt> command should list all possible <tt>href</tt> values which don't contain an <tt>#...</tt> XR Fragment</li>
<li>The (dynamic) <tt>do abc</tt> command should navigate/execute <tt>https://.../...</tt> in case a 3D node exist with name <tt>abc</tt> and <tt>href</tt> value <tt>https://.../...</tt></li>
</ol>
@ -1601,7 +1588,7 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
<tr>
<td>XR fragment</td>
<td>URI Fragment with spatial hints like <tt>#pos=0,0,0&amp;t=1,100</tt> e.g.</td>
<td>URI Fragment with spatial hints (which match the name of a 3D object-, camera-, animation-object)</td>
</tr>
<tr>

View file

@ -3,7 +3,7 @@
Internet Engineering Task Force L.R. van Kammen
Internet-Draft 27 September 2024
Internet-Draft 1 September 2025
Intended status: Informational
@ -38,11 +38,11 @@ Status of This Memo
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 31 March 2025.
This Internet-Draft will expire on 5 March 2026.
Copyright Notice
Copyright (c) 2024 IETF Trust and the persons identified as the
Copyright (c) 2025 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
@ -53,9 +53,9 @@ Copyright Notice
van Kammen Expires 31 March 2025 [Page 1]
van Kammen Expires 5 March 2026 [Page 1]
Internet-Draft XR Macros September 2024
Internet-Draft XR Macros September 2025
extracted from this document must include Revised BSD License text as
@ -109,9 +109,9 @@ Table of Contents
van Kammen Expires 31 March 2025 [Page 2]
van Kammen Expires 5 March 2026 [Page 2]
Internet-Draft XR Macros September 2024
Internet-Draft XR Macros September 2025
3. Metadata-values can contain the | symbol to 🎲 roundrobin variable
@ -165,9 +165,9 @@ Internet-Draft XR Macros September 2024
van Kammen Expires 31 March 2025 [Page 3]
van Kammen Expires 5 March 2026 [Page 3]
Internet-Draft XR Macros September 2024
Internet-Draft XR Macros September 2025
+=========+======+===================+=================+=============+
@ -221,9 +221,9 @@ Internet-Draft XR Macros September 2024
van Kammen Expires 31 March 2025 [Page 4]
van Kammen Expires 5 March 2026 [Page 4]
Internet-Draft XR Macros September 2024
Internet-Draft XR Macros September 2025
Table 3
@ -277,9 +277,9 @@ Internet-Draft XR Macros September 2024
van Kammen Expires 31 March 2025 [Page 5]
van Kammen Expires 5 March 2026 [Page 5]
Internet-Draft XR Macros September 2024
Internet-Draft XR Macros September 2025
4.5. Usecase: present context menu with options
@ -333,9 +333,9 @@ click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
van Kammen Expires 31 March 2025 [Page 6]
van Kammen Expires 5 March 2026 [Page 6]
Internet-Draft XR Macros September 2024
Internet-Draft XR Macros September 2025
| Note that only macro's can trigger roundrobin values or
@ -389,4 +389,4 @@ Internet-Draft XR Macros September 2024
van Kammen Expires 31 March 2025 [Page 7]
van Kammen Expires 5 March 2026 [Page 7]

View file

@ -1,6 +1,14 @@
{ pkgs ? import <nixpkgs> {} }:
{ pkgs ? import <nixos-unstable> {} } :
{
pkgs.mkShell {
pkgs = import (builtins.fetchGit {
name = "nixos-23.05";
url = "https://github.com/nixos/nixpkgs/";
ref = "refs/heads/nixos-unstable";
rev = "ef99fa5c5ed624460217c31ac4271cfb5cb2502c";
});
foo = pkgs.mkShell {
# nativeBuildInputs is usually what you want -- tools you need to run
nativeBuildInputs = with pkgs.buildPackages; [
@ -11,4 +19,5 @@
imagemagick
];
};
}