<!-- for annotated version see: https://raw.githubusercontent.com/ietf-tools/rfcxml-templates-and-schemas/main/draft-rfcxml-general-template-annotated-00.xml -->
<p>An open specification for hyperlinking & deeplinking 3D fileformats.
This draft is a specification for interactive URI-controllable 3D files, enabling <ahref="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.<br>
XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like <ahref="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a>.<br></p>
<li>addressibility and <ahref="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> navigation of 3D scenes/objects: <ahref="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a> using src/href spatial metadata</li>
<p>XR Fragments views XR experiences through the lens of 3D deeplinked URI’s, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).
To aid adoption, the standard comprises of various (optional) support-levels, which incorporate existing standards like <ahref="https://www.w3.org/TR/media-frags/">W3C Media Fragments</a> and <ahref="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></p>
<p>XR Fragments is in a sense, a <b>heuristical 3D format</b> or meta-format, 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><code>href</code> metadata traditionally implies <strong>click</strong> AND <strong>navigate</strong>, however XR Fragments adds stateless <strong>click</strong> (<code>xrf://....</code>) via the <code>xrf://</code> scheme, which does not change the top-level URL-adress (of the browser).
This allows for many extra interactions via URLs, which otherwise needs a scripting language.
These are called <strong>hashbus</strong>-only events/</p>
<p>Being able to use the same URI Fragment DSL for navigation (<code>href: #foo</code>) as well as interactions (<code>href: xrf://#foo</code>) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.</p>
<li><ahref="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).</li>
<li>potentially 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>potentially collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus</li>
<p>XR Fragments itself are <ahref="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> and HTML-agnostic, though pseudo-XR Fragment browsers <strong>can</strong> be implemented on top of HTML/Javascript.</p>
<p>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’ (<code>xrf://#.....</code>). This decoupling between navigation and interaction prevents non-standard things like (<code>href</code>:<code>javascript:dosomething()</code>).</p>
<p>Pseudo (non-native) browser-implementations (supporting XR Fragments using HTML+JS e.g.) can use the <code>?</code> search-operator to address outbound content.<br>
In other words, the URL updates to: <code>https://me.com?https://me.com/other.glb</code> when navigating to <code>https://me.com/other.glb</code> from inside a <code>https://me.com</code> WebXR experience e.g.<br>
That way, if the link gets shared, the XR Fragments implementation at <code>https://me.com</code> can load the latter (and still indicates which XR Fragments entrypoint-experience/client was used).</p>
<p>Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).</p>
</blockquote>
<p>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:</p>
<ul>
<li>href: <code>https://scene.fbx</code></li>
</ul>
<blockquote>
<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>
<p>NOTE: Linux’s <code>setfattr/getfattr</code> is <code>xattr</code> on mac, and <code>Set-Content/Get-content</code> on Windows. See <ahref="https://www.lesbonscomptes.com/pxattr/index.html">pxattr</a> for lowlevel access.</p>
<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>
<p><strong>XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments</strong></p>
</blockquote>
<p>XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.<br>
Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments <strong>integrates all</strong> which allows a universal viewing experience.<br></p>
<p>Fact: our typical browser URL’s are just <strong>a possible implementation</strong> of URI’s (for untapped humancentric potential of URI’s <ahref="https://interpeer.io">see interpeer.io</a> or <ahref="https://nextgraph.org">NextGraph</a> )</p>
<blockquote>
<p>XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.<br>But approaches things from a higherlevel local-first 3D hypermedia browser-perspective.</p>
</blockquote>
<p>Below you can see how this translates back into good-old URLs:</p>
<p>?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation.</p>
<p>Explicit href metadata (‘extras’) in a 3D object (of a 3D file), hint the viewer that the user “can interact” with that object :</p>
| level0+1 | hover 3D file <ahref="#via-href-metadata">href</a> | show the preview PNG thumbnail (if any). |
| level0+1 | launch 3D file <ahref="#via-href-metadata">href</a> | replace the current scene with a new 3D file (<code>href: other.glb</code> e.g.) |
| level2 | click internal 3D file <ahref="#via-href-metadata">href</a> (<code>#roomB</code> e.g.) | teleport the camera to the origin of object(name <code>roomB</code>). See [[teleport camera]].|
| level2 | click external 3D file <ahref="#via-href-metadata">href</a> (<code>foo.glb</code> e.g.) | replace the current scene with a new 3D file (<code>href: other.glb</code> e.g.) |
| level2 | hover external 3D file <ahref="#via-href-metadata">href</a> | show the preview PNG thumbnail (if any sidecar, see level0) |
| level2 | click <ahref="#via-href-metadata">href</a> | hashbus: execute without changing the toplevel URL location (<code>href: xrf://#someObjectName</code> e.g.) |
| level3 | click <ahref="#via-href-metadata">href</a> | set the global 3D animation timeline to its Media Fragment value (<code>#t=2,3</code> e.g.) |</p>
<p>NOTE: hashbus links (<code>xrf://#foo&bar</code>) don’t change the toplevel URL, which makes it ideal for interactions (in contrast to typical <code>#roomC</code> navigation, which benefit back/forward browser-buttons), see <ahref="#hashbus">hashbus</a> for more info.</p>
<p><strong>Examples:</strong><code>#+menu</code> to show a object, <code>#-menu</code> to hide a menu, <code>#!menu</code> to teleport a menu, <code>#*block</code> to clone a grabbable block, <code>#|object</code> to share an object</p>
<p>Prefixing an object with an exclamation-symbol, will teleport a (local or remote) referenced object from/to its original/usercamera location.<br></p>
<p>This tiny but powerful symbol allows incredible interactive possibilities, by carefully positioning re-usable objects outside of a scene (below the usercamera’s floor e.g.).</p>
<p><strong>NOTE</strong>: level2 teleportation links, as well as instancing mitigates the ‘broken embedded image’-issue of HTML: <strong>always</strong> attaching the href-values to <strong>a 3D (preview) object</strong> (that way broken links will not break the design).</p>
<p><strong>Example:</strong> clicking a 3D button with title ‘menu’ and <ahref="#href">href</a>-value <code>xrf:menu.glb?instance#t=4,5</code> would instance a 3D menu (<code>menu.glb</code>) in front of the user, and loop its animation between from 4-5 seconds (<code>t=4,5</code>)</p>
<p><strong>NOTE</strong>: combining instance-operators allows dynamic construction of 3D scenes (<code>#london&!welcomeMenu&!fadeBox</code> e.g.)</p>
<p><strong>NOTE</strong>: this is basically the <ahref="#%23%21">#! operator</a> which infinitely <strong>clones</strong> the referenced object (instead of repositioning the object).</p>
<p>This URL can be fed straight into <ahref="https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API">Web Share API</a> or <ahref="https://www.freedesktop.org/wiki/Software/xdg-utils/">xdg-open</a></p>
<p>Prefixing the <code>xrf:</code> to <ahref="#href">href</a>-values <strong>will prevent</strong><ahref="#📜%20level2:%20explicit%20links">level2</a><ahref="#href">href</a>-values from changing the top-Level URL.</p>
<p><strong>Reason:</strong> XR Fragments is inspired by HTML’s <ahref="https://en.wikipedia.org/wiki/Hyperlink">href-attribute</a>, which does various things:</p>
<p>The URL-processing-flow for hypermedia browsers goes like this:</p>
<ol>
<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) (<ahref="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]">example</a>)</li>
<li>IF a camera-object exists with name <code>cam</code> assume that user(camera) position</li>
<li>the current (toplevel) <b>URL</b> (an URLbar etc)</li>
<li>URL-history (a <b>back/forward</b> button e.g.)</li>
<li>Clicking/Touching an <code>href</code> navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments).</li>
<li><p>clicking an outbound “external”- or “file URI” fully replaces the current scene and assumes <code>room2</code> by default (unless specified)</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>
<li><p>URL navigation should always be reflected in the client URL-bar (in case of javascript: see [<ahref="https://github.com/coderofsalvation/xrfragment/blob/dev/src/3rd/js/three/navigator.js">here</a> for an example navigator), and only update the URL-bar after the scene (default fragment <code>#</code>) has been loaded.</p></li>
<li><p>In immersive XR mode, the navigator back/forward-buttons should be always visible (using a wearable e.g., see [<ahref="https://github.com/coderofsalvation/xrfragment/blob/dev/example/aframe/sandbox/index.html#L26-L29">here</a> for an example wearable)</p></li>
<li><p>make sure that the “back-button” of the “browser-history” always refers to the previous position (see [<ahref="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js#L97">here</a>)</p></li>
<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 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>#...</code> primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)</p></li>
<p>The following metadata are non-normative but encouraged, since they are popular and cheap to parse:</p>
<ul>
<li><ahref="https://json-ld.org">RDF/JSON-LD</a> like <ahref="https://mvmd.org/standards/gltf/">this example</a> or via glTF’s <ahref="https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_xmp_json_ld">KHR_xmp_json_ld extension</a></li>
<li><ahref="https://bibtex.eu/fields">BibTex</a> when known bibtex-keys exist with values enclosed in <code>{</code> and <code>},</code></li>
</ul>
<blockquote>
<p>Example: object ‘tryceratops’ with <code>aria-description: is a huge dinosaurus standing on a #mountain</code> generates transcript <code>#tryceratops is a huge dinosaurus standing on a #mountain</code>, where the hashtags are clickable XR Fragments (activating the visible-links in the XR browser).</p>
</blockquote>
<p>Individual nodes can be enriched with such metadata, but most importantly the scene node:</p>
<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>
If a glTF implementation does not support a particular extension, the (XRF) extras field can serve as a fallback. This way, metadata provided in extras can still be useful for applications that don’t handle certain extensions.</li>
<p><strong>Example 1</strong> In case of the OMI_LINK glTF extension (<code>href: https://nlnet.nl</code>) and an XR Fragment (<code>href: #otherroom</code> or <code>href: otherplanet.glb</code>), it is clear that <code>https://nlnet.nl</code> should open in a browsertab, whereas the XR Fragment links should teleport the user. If the OMI_LINK contains an XR Fragment (<code>#room1</code> e.g.) a teleport should be performed only (and other [overlapping] metadata should be ignored).</p>
<p><strong>Example 2</strong> If an Extensions uses XR Fragments in URI’s (<code>href: #otherroom</code> or <code>href: xrf://-walls</code> in OMI_LINK e.g.), then perform them according to XR Fragment spec (teleport user). But only once: ignore further overlapping metadata for that usecase.</p>
<p>Vendor-specific metadata in a 3D scenefiles, are similar to vendor-specific <ahref="https://en.wikipedia.org/wiki/CSS#Vendor_prefixes">CSS-prefixes</a> (<code>-moz-opacity: 0.2</code> e.g.).
This allows popular 3D engines/frameworks, to initialize specific features when loading a scene/object, in a progressive enhanced way.</p>
<p>Vendor Prefixes allows embedding 3D engines/framework-specific features a 3D file via metadata:</p>
<p>Why? Because not all XR interactions can/should be solved/standardized by embedding XR Fragments into any 3D file.
The lowest common denominator between 3D engines is the ‘entity’-part of their entity-component-system (ECS). The ‘component’-part can be progressively enhanced via vendor prefixes.</p>
<p>String-templatevalues are evaluated as per <ahref="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</a> Level 1.</p>
<blockquote>
<p>This ‘separating of mechanism from policy’ (unix rule) does <strong>somewhat</strong> break portability of an XR experience, but still prevents (E-waste of) handcoded virtual worlds. It allows for (XR experience) metadata to survive in future 3D engines and scene-fileformats.</p>
<p>The only dynamic parts are <ahref="https://www.w3.org/TR/media-frags/">W3C Media Fragments</a> and <ahref="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</a>.<br>
The use of URI Templates is limited to pre-defined variables and Level0 fragments-expansion only, which makes it quite safe.<br>
<p><strong>Q:</strong> Why is everything HTTP GET-based, what about POST/PUT/DELETE HATEOS<br>
<strong>A:</strong> Because it’s out of scope: XR Fragment specifies a read-only way to surf XR documents. These things belong in the application layer (for example, an XR Hypermedia browser can decide to support POST/PUT/DELETE requests for embedded HTML thru <code>src</code> values)</p>
<p><strong>Q:</strong> Why isn’t there support for scripting, URI Template Fragments are so limited compared to WASM & javascript
<strong>A:</strong> This is out of scope as it unhyperifies hypermedia, and this is up to XR hypermedia browser-extensions.<br> Historically scripting/Javascript seems to been able to turn webpages from hypermedia documents into its opposite (hyperscripted nonhypermedia documents).<br>In order to prevent this backward-movement (hypermedia tends to liberate people from finnicky scripting) XR Fragment uses <ahref="https://www.w3.org/TR/media-frags/">W3C Media Fragments</a> and <ahref="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</a>, to prevent unhyperifying itself by hardcoupling to a particular markup or scripting language. <br>
XR Fragments supports filtering objects in a scene only, because in the history of the javascript-powered web, showing/hiding document-entities seems to be one of the most popular basic usecases.<br>
Doing advanced scripting & networkrequests under the hood are obviously interesting endavours, but this is something which should not be hardcoupled with XR Fragments or hypermedia.<br>This perhaps belongs more to browser extensions.<br>
Non-HTML Hypermedia browsers should make browser extensions the right place, to ‘extend’ experiences, in contrast to code/javascript inside hypermedia documents (this turned out as a hypermedia antipattern).</p>
<td>some resource at something somewhere via someprotocol (<code>http://me.com/foo.glb#foo</code> or <code>e76f8efec8efce98e6f</code><ahref="https://interpeer.io">see interpeer.io</a>)</td>
</tr>
<tr>
<td>URL</td>
<td>something somewhere via someprotocol (<code>http://me.com/foo.glb</code>)</td>
<td>an easy to speak/type/scan tagging SDL (<ahref="https://github.com/coderofsalvation/hashtagbibs">see here</a> which expands to BibTex/JSON/XML</td>