<t>An open specification for hyperlinking & deeplinking 3D fileformats.
This draft is a specification for interactive URI-controllable 3D files, enabling <ereftarget="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> 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 <ereftarget="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref>.<br/>
XR Fragments views XR experiences thru the lens of 3D deeplinked URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).
The standard comprises of various (optional) support levels, which also include <ereftarget="https://www.w3.org/TR/media-frags/">W3C Media Fragments</eref> and <ereftarget="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/>
</t>
<t>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.</t>
<li>addressibility and <ereftarget="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> navigation of 3D scenes/objects: <ereftarget="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref> using src/href spatial metadata</li>
<li>Interlinking text & spatial objects by collapsing space into a Word Graph (XRWG) to show <ereftarget="#visible-links">visible links</eref></li>
<li>for 3D viewers/browser to manipulate the camera or objects (via URI fragments)</li>
<li>implicitly: by mapping 3D objectnames (of a 3D scene/file) to URI fragments (3D deeplinking)</li>
<li>explicitly: by scanning <tt>href</tt> metadata <strong>inside</strong> 3D scene-files to enable interactions</li>
<li>externally: progressively enhance a 3D (file) into an experience via <ereftarget="https://en.wikipedia.org/wiki/Sidecar_file">sidecarfiles</eref></li>
<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>) via the <tt>xrf://</tt> 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/</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://#foo</tt>) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.</t>
<li><ereftarget="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> 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 <tt>xrf://</tt> hashbus (<tt>xrf://#person=walk</tt> to trigger <tt>walk</tt>-animation for object <tt>person</tt>)</li>
<li>potentially collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus</li>
<t>XR Fragments itself are <ereftarget="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> and HTML-agnostic, though pseudo-XR Fragment browsers <strong>can</strong> be implemented on top of HTML/Javascript.</t>
</table><blockquote><t>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' (<tt>xrf://#.....</tt>). This decoupling between navigation and interaction prevents non-standard things like (<tt>href</tt>:<tt>javascript:dosomething()</tt>).</t>
</blockquote><t>Pseudo (non-native) browser-implementations (supporting XR Fragments using HTML+JS e.g.) can use the <tt>?</tt> search-operator to address outbound content.<br/>
In other words, the URL updates to: <tt>https://me.com?https://me.com/other.glb</tt> when navigating to <tt>https://me.com/other.glb</tt> from inside a <tt>https://me.com</tt> WebXR experience e.g.<br/>
That way, if the link gets shared, the XR Fragments implementation at <tt>https://me.com</tt> can load the latter (and still indicates which XR Fragments entrypoint-experience/client was used).</t>
<blockquote><t>Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).</t>
</blockquote><t>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:</t>
<ulspacing="compact">
<li>href: <tt>https://scene.fbx</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><t>NOTE: Linux's <tt>setfattr/getfattr</tt> is <tt>xattr</tt> on mac, and <tt>Set-Content/Get-content</tt> on Windows. See <ereftarget="https://www.lesbonscomptes.com/pxattr/index.html">pxattr</eref> for lowlevel access.</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><t>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/>
<t>Fact: our typical browser URL's are just <strong>a possible implementation</strong> of URI's (for untapped humancentric potential of URI's <ereftarget="https://interpeer.io">see interpeer.io</eref> or <ereftarget="https://nextgraph.org">NextGraph</eref> )</t>
<blockquote><t>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.</t>
</blockquote><t>Below you can see how this translates back into good-old URLs:</t>
<blockquote><t>?-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.</t>
<irefitem="Level2: href links"/><t>Explicit href metadata ('extras') in a 3D object (of a 3D file), hint the viewer that the user ''can interact'' with that object :</t>
| level0+1 | hover 3D file <ereftarget="#via-href-metadata">href</eref> | show the preview PNG thumbnail (if any). |
| level0+1 | launch 3D file <ereftarget="#via-href-metadata">href</eref> | replace the current scene with a new 3D file (<tt>href: other.glb</tt> e.g.) |
| level2 | click internal 3D file <ereftarget="#via-href-metadata">href</eref> (<tt>#roomB</tt> e.g.) | teleport the camera to the origin of object(name <tt>roomB</tt>). See [[teleport camera]].|
| level2 | click external 3D file <ereftarget="#via-href-metadata">href</eref> (<tt>foo.glb</tt> e.g.) | replace the current scene with a new 3D file (<tt>href: other.glb</tt> e.g.) |
| level2 | hover external 3D file <ereftarget="#via-href-metadata">href</eref> | show the preview PNG thumbnail (if any sidecar, see level0) |
| level2 | click <ereftarget="#via-href-metadata">href</eref> | hashbus: execute without changing the toplevel URL location (<tt>href: xrf://#someObjectName</tt> e.g.) |
| level3 | click <ereftarget="#via-href-metadata">href</eref> | set the global 3D animation timeline to its Media Fragment value (<tt>#t=2,3</tt> e.g.) |</t>
<blockquote><t>NOTE: hashbus links (<tt>xrf://#foo&bar</tt>) don't change the toplevel URL, which makes it ideal for interactions (in contrast to typical <tt>#roomC</tt> navigation, which benefit back/forward browser-buttons), see <a href="#hashbus">hashbus</a> for more info.</t>
<irefitem="Level3: Media Fragments"/><blockquote><t>these allow for XR Movies with a controllable timeline using <tt>href</tt> URI's with Media Fragments</t>
</blockquote><t>Just like with 2D media-files, W3C mediafragments (<tt>#t=1,2</tt>) can be used to control a timeline via the <ereftarget="##t">#t</eref> primitive.
XR Fragments Level3 makes the 3D timeline, as well as URL-referenced files <strong>controllable</strong> via Media Fragments like:</t>
<irefitem="Level4: prefix operators"/><t>Prefixing objectnames with the following simple operators allow for <strong>extremely powerful</strong> XR interactions:</t>
<blockquote><t><strong>Examples:</strong><tt>#+menu</tt> to show a object, <tt>#-menu</tt> to hide a menu, <tt>#!menu</tt> to teleport a menu, <tt>#*block</tt> to clone a grabbable block, <tt>#|object</tt> to share an object</t>
<t>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.).</t>
<blockquote><t><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).</t>
</blockquote><t><strong>Example:</strong> clicking a 3D button with title 'menu' and <ereftarget="#href">href</eref>-value <tt>xrf:menu.glb?instance#t=4,5</tt> would instance a 3D menu (<tt>menu.glb</tt>) in front of the user, and loop its animation between from 4-5 seconds (<tt>t=4,5</tt>)</t>
<blockquote><t><strong>NOTE</strong>: combining instance-operators allows dynamic construction of 3D scenes (<tt>#london&!welcomeMenu&!fadeBox</tt> e.g.)</t>
<blockquote><t><strong>NOTE</strong>: this is basically the <ereftarget="#%23%21">#! operator</eref> which infinitely <strong>clones</strong> the referenced object (instead of repositioning the object).</t>
<blockquote><t>This URL can be fed straight into <ereftarget="https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API">Web Share API</eref> or <ereftarget="https://www.freedesktop.org/wiki/Software/xdg-utils/">xdg-open</eref></t>
<sectionanchor="xrf-uri-scheme"><name>xrf:// URI scheme</name>
<t>Prefixing the <tt>xrf:</tt> to <ereftarget="#href">href</eref>-values <strong>will prevent</strong><ereftarget="#📜%20level2:%20explicit%20links">level2</eref><ereftarget="#href">href</eref>-values from changing the top-Level URL.</t>
<blockquote><t><strong>Usecase</strong>: for non-shareable URLs like <tt>href: xrf:#t=4,5</tt>, to display a stateful msg e.g.).</t>
</blockquote><t><strong>Reason:</strong> XR Fragments is inspired by HTML's <ereftarget="https://en.wikipedia.org/wiki/Hyperlink">href-attribute</eref>, which does various things:</t>
<li>it jumps to another document / elsewhere in the same document</li>
<li>and more</li>
</ol>
<t>The <tt>xrf:</tt> scheme will just do 2 & 3 (so the URL-values will not leak into the top-level URL).</t>
<blockquote><t><strong>compliance with RFC 3986</strong>: unimplemented/unknown URI schemes (<tt>xrf:...</tt> e.g.) will not update the top-level URL</t>
</blockquote><t>The URL-processing-flow for hypermedia browsers goes like this:</t>
<olspacing="compact">
<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) (<ereftarget="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]]">example</eref>)</li>
<li>IF a camera-object exists with name <tt>cam</tt> assume that user(camera) position</li>
</ol>
<sectionanchor="ux"><name>UX</name>
<t>End-users should always have read/write access to:</t>
<olspacing="compact">
<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 <tt>href</tt> navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments).</li>
<li><t>clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes <tt>room2</tt> by default (unless specified)</t>
<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><t>URL navigation should always be reflected in the client URL-bar (in case of javascript: see [<ereftarget="https://github.com/coderofsalvation/xrfragment/blob/dev/src/3rd/js/three/navigator.js">here</eref> for an example navigator), and only update the URL-bar after the scene (default fragment <tt>#</tt>) has been loaded.</t>
<li><t>In immersive XR mode, the navigator back/forward-buttons should be always visible (using a wearable e.g., see [<ereftarget="https://github.com/coderofsalvation/xrfragment/blob/dev/example/aframe/sandbox/index.html#L26-L29">here</eref> for an example wearable)</t>
<li><t>make sure that the ''back-button'' of the ''browser-history'' always refers to the previous position (see [<ereftarget="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js#L97">here</eref>)</t>
<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><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><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>
<blockquote><t>By default position <tt>0,0,0</tt> of the 3D scene represents the walkable plane, however this is overridden when the following applies:</t>
</blockquote><t>XR Fragment-compatible viewers can infer this data based scanning the scene for:</t>
<sectionanchor="example-virtual-world-rings"><name>Example: Virtual world rings</name>
<irefitem="Example: Virtual world rings"/><t>Consider 3D scenes linking to eachother using these <tt>href</tt> values, attached to 3D button-objects:</t>
<irefitem="Additional scene metadata"/><t>XR Fragments does not aim to redefine the metadata-space or accessibility-space by introducing its own cataloging-metadata fields.
</blockquote><t>The following metadata are non-normative but encouraged, since they are popular and cheap to parse:</t>
<ulspacing="compact">
<li><ereftarget="https://json-ld.org">RDF/JSON-LD</eref> like <ereftarget="https://mvmd.org/standards/gltf/">this example</eref> or via glTF's <ereftarget="https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_xmp_json_ld">KHR_xmp_json_ld extension</eref></li>
<li><ereftarget="https://bibtex.eu/fields">BibTex</eref> when known bibtex-keys exist with values enclosed in <tt>{</tt> and <tt>},</tt></li>
</ul>
<blockquote><t>Example: object 'tryceratops' with <tt>aria-description: is a huge dinosaurus standing on a #mountain</tt> generates transcript <tt>#tryceratops is a huge dinosaurus standing on a #mountain</tt>, where the hashtags are clickable XR Fragments (activating the visible-links in the XR browser).</t>
</blockquote><t>Individual nodes can be enriched with such metadata, but most importantly the scene node:</t>
<irefitem="Accessibility interface"/><t>The addressibility of XR Fragments allows for unique 3D-to-text transcripts, as well as an textual interface to navigate 3D content.<br/>
<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>
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>
<blockquote><t><strong>Example 1</strong> In case of the OMI_LINK glTF extension (<tt>href: https://nlnet.nl</tt>) and an XR Fragment (<tt>href: #otherroom</tt> or <tt>href: otherplanet.glb</tt>), it is clear that <tt>https://nlnet.nl</tt> should open in a browsertab, whereas the XR Fragment links should teleport the user. If the OMI_LINK contains an XR Fragment (<tt>#room1</tt> e.g.) a teleport should be performed only (and other [overlapping] metadata should be ignored).</t>
<t><strong>Example 2</strong> If an Extensions uses XR Fragments in URI's (<tt>href: #otherroom</tt> or <tt>href: xrf://-walls</tt> 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.</t>
<irefitem="Vendor Prefixes"/><t>Vendor-specific metadata in a 3D scenefiles, are similar to vendor-specific <ereftarget="https://en.wikipedia.org/wiki/CSS#Vendor_prefixes">CSS-prefixes</eref> (<tt>-moz-opacity: 0.2</tt> e.g.).
</table><blockquote><t>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.</t>
<t>String-templatevalues are evaluated as per <ereftarget="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</eref> Level 1.</t>
<blockquote><t>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.</t>
<irefitem="Security Considerations"/><t>The only dynamic parts are <ereftarget="https://www.w3.org/TR/media-frags/">W3C Media Fragments</eref> and <ereftarget="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</eref>.<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 <tt>src</tt> values)</t>
<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 <ereftarget="https://www.w3.org/TR/media-frags/">W3C Media Fragments</eref> and <ereftarget="https://www.rfc-editor.org/rfc/rfc6570">URI Templates (RFC6570)</eref>, 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).</t>
<td>some resource at something somewhere via someprotocol (<tt>http://me.com/foo.glb#foo</tt> or <tt>e76f8efec8efce98e6f</tt><ereftarget="https://interpeer.io">see interpeer.io</eref>)</td>
</tr>
<tr>
<td>URL</td>
<td>something somewhere via someprotocol (<tt>http://me.com/foo.glb</tt>)</td>
<td>simple tagging/citing/referencing standard for plaintext</td>
</tr>
<tr>
<td>BibTag</td>
<td>a BibTeX tag</td>
</tr>
<tr>
<td>(hashtag)bibs</td>
<td>an easy to speak/type/scan tagging SDL (<ereftarget="https://github.com/coderofsalvation/hashtagbibs">see here</eref> which expands to BibTex/JSON/XML</td>