milestone 7m update/refactor documentation website based on updated spec (+adoption levels)
This commit is contained in:
		
							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  | 
| 
						 | 
				
			
			@ -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 & 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’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’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>"src": "#cube"</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>"tag": "cubes geo"</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>"#": "#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">{
 | 
			
		||||
  "/":{
 | 
			
		||||
    "#":                 "#-penguin",
 | 
			
		||||
    "aria-description": "description of scene",
 | 
			
		||||
  },
 | 
			
		||||
  "/room/chair": {
 | 
			
		||||
    "href": "#penguin"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</code></pre>
 | 
			
		||||
 | 
			
		||||
<blockquote>
 | 
			
		||||
<p>This would mean: hide object(s) with name or <code>tag</code>-value ‘penguin’ 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['#'] = "#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 
 | 
			
		||||
</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  = "," / "="
 | 
			
		|||
</code></pre>
 | 
			
		||||
 | 
			
		||||
<blockquote>
 | 
			
		||||
<p>Example: <code>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</code></p>
 | 
			
		||||
<p>Example: <code>://foo.com/my3d.gltf#room1&prio=-5&t=0,100</code></p>
 | 
			
		||||
</blockquote>
 | 
			
		||||
 | 
			
		||||
<table>
 | 
			
		||||
| 
						 | 
				
			
			@ -448,12 +371,12 @@ sub-delims  = "," / "="
 | 
			
		|||
 | 
			
		||||
<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&rot=0,90,0&foo</code></td>
 | 
			
		||||
<td><code>room1&rot=0,90,0&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>"src": "#cube"</code>       | XR embed / teleport | custom property in 3D fileformats      |
 | 
			
		||||
| <code>tag</code>        | string   | <code>"tag": "cubes geo"</code>   | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats      |
 | 
			
		||||
| <code>#</code>          | string   | <code>"#": "#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">{
 | 
			
		||||
  "/":{
 | 
			
		||||
    "#":                 "#-penguin",
 | 
			
		||||
    "aria-description": "description of scene",
 | 
			
		||||
  },
 | 
			
		||||
  "/room/chair": {
 | 
			
		||||
    "href": "#penguin"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</code></pre>
 | 
			
		||||
 | 
			
		||||
<blockquote>
 | 
			
		||||
<p>This would mean: hide object(s) with name or <code>tag</code>-value ‘penguin’ 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['#'] = "#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 
 | 
			
		||||
</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>#<tag_or_objectname></code></td>
 | 
			
		||||
<td><code>xrf://#<tag_or_objectname></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 ‘play’ 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 ‘play’ 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&t=100,200                 │
 | 
			
		||||
  │    │      └ href: #room1&t=100,200                 │
 | 
			
		||||
  │    │                                                   │
 | 
			
		||||
  │    └── ◻ buttonB                                       │
 | 
			
		||||
  │           └ href: other.fbx                            │   <── 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&pos=0,0,0</code></p>
 | 
			
		||||
<p>Example URL:  <code>://foo/world.gltf#room1&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(’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&rot=90,0,0</code><br><code>://somefile.gltf#pos=1,1,0</code><br></td>
 | 
			
		||||
<td><code>#room1</code><br><code>#pos=room1&rot=90,0,0</code><br><code>://somefile.gltf#room1</code><br></td>
 | 
			
		||||
</tr>
 | 
			
		||||
</tbody>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<ol>
 | 
			
		||||
<li><p>clicking an outbound “external”- or “file URI” fully replaces the current scene and assumes <code>pos=0,0,0&rot=0,0,0</code> by default (unless specified)</p></li>
 | 
			
		||||
<li><p>clicking an outbound “external”- or “file URI” fully replaces the current scene and assumes <code>room2&rot=0,0,0</code> by default (unless specified)</p></li>
 | 
			
		||||
 | 
			
		||||
<li><p>relocation/reorientation should happen locally for local URI’s (<code>#pos=....</code>)</p></li>
 | 
			
		||||
<li><p>relocation/reorientation should happen locally for local URI’s (<code>#....</code>)</p></li>
 | 
			
		||||
 | 
			
		||||
<li><p>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.)</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’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’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’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’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&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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
											
										
									
								
							| 
						 | 
				
			
			@ -10,14 +10,15 @@
 | 
			
		|||
<workgroup>Jens & 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 & 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 <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 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 <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.</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>"src": "#cube"</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>"tag": "cubes geo"</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>"#": "#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 & 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&prio=-5&t=0,100</tt></t>
 | 
			
		||||
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#room1&prio=-5&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&rot=0,90,0&foo</tt></td>
 | 
			
		||||
<td><tt>room1&rot=0,90,0&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>"src": "#cube"</tt>       | XR embed / teleport | custom property in 3D fileformats      |
 | 
			
		||||
| <tt>tag</tt>        | string   | <tt>"tag": "cubes geo"</tt>   | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats      |
 | 
			
		||||
| <tt>#</tt>          | string   | <tt>"#": "#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>#<tag_or_objectname></tt></td>
 | 
			
		||||
<td><tt>xrf://#<tag_or_objectname></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&pos=0,0,0</tt></t>
 | 
			
		||||
<blockquote><t>Example URL:  <tt>://foo/world.gltf#room1&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>) <b>THEN</b> 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 <b>step 1 or 2</b> 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>) <b>THEN</b> 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 <b>step 1 or 2</b> 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 <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<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 <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.</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&rot=90,0,0</tt><br />
 | 
			
		||||
<tt>://somefile.gltf#pos=1,1,0</tt><br />
 | 
			
		||||
<td><tt>#room1</tt><br />
 | 
			
		||||
<tt>#pos=room1&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&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&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&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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
    ];
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue