994 lines
57 KiB
Markdown
994 lines
57 KiB
Markdown
%%%
|
||
Title = "XR Fragments"
|
||
area = "Internet"
|
||
workgroup = "Jens & Leon Internet Engineering Task Force"
|
||
|
||
[seriesInfo]
|
||
name = "XR-Fragments"
|
||
value = "draft-XRFRAGMENTS-leonvankammen-00"
|
||
stream = "IETF"
|
||
status = "informational"
|
||
|
||
date = 2023-04-12T00:00:00Z
|
||
|
||
[[author]]
|
||
initials="L.R."
|
||
surname="van Kammen"
|
||
fullname="L.R. van Kammen"
|
||
|
||
%%%
|
||
|
||
<!-- for annotated version see: https://raw.githubusercontent.com/ietf-tools/rfcxml-templates-and-schemas/main/draft-rfcxml-general-template-annotated-00.xml -->
|
||
|
||
<!--{
|
||
|
||
<style type="text/css">
|
||
body{
|
||
font-family: monospace;
|
||
max-width: 1000px;
|
||
font-size: 15px;
|
||
padding: 0% 10%;
|
||
line-height: 30px;
|
||
color:#555;
|
||
background:#F7F7F7;
|
||
}
|
||
h1 { margin-top:40px; }
|
||
pre{ line-height:18px; }
|
||
a,a:visited,a:active{ color: #70f; }
|
||
code{
|
||
border: 1px solid #AAA;
|
||
border-radius: 3px;
|
||
padding: 0px 5px 2px 5px;
|
||
}
|
||
|
||
pre{
|
||
line-height: 18px;
|
||
overflow: auto;
|
||
padding: 12px;
|
||
}
|
||
pre + code {
|
||
background:#DDD;
|
||
}
|
||
pre>code{
|
||
border:none;
|
||
border-radius:0px;
|
||
padding:0;
|
||
}
|
||
blockquote{
|
||
padding-left: 30px;
|
||
margin: 0;
|
||
border-left: 5px solid #CCC;
|
||
}
|
||
th {
|
||
border-bottom: 1px solid #000;
|
||
text-align: left;
|
||
padding-right:45px;
|
||
padding-left:7px;
|
||
background: #DDD;
|
||
}
|
||
|
||
td {
|
||
border-bottom: 1px solid #CCC;
|
||
font-size:13px;
|
||
}
|
||
|
||
</style>
|
||
|
||
<br>
|
||
<h1>XR Fragments</h1>
|
||
<br>
|
||
|
||
<pre>
|
||
stream: IETF
|
||
area: Internet
|
||
status: informational
|
||
author: Leon van Kammen
|
||
date: 2023-04-12T00:00:00Z
|
||
workgroup: Internet Engineering Task Force
|
||
value: draft-XRFRAGMENTS-leonvankammen-00
|
||
</pre>
|
||
|
||
|
||
}-->
|
||
|
||
.# Abstract
|
||
|
||
> Version: 0.5
|
||
|
||
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>
|
||
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>
|
||
|
||
> Almost every idea in this document is demonstrated at [https://xrfragment.org](https://xrfragment.org)
|
||
|
||
{mainmatter}
|
||
|
||
# Quick reference
|
||
|
||
1. [Abstract](#abstract)
|
||
1. [Index](#index)
|
||
1. [Introduction](#introduction)
|
||
1. [How does it work](#how-does-it-work)
|
||
1. [What does it solve](#what-does-it-solve)
|
||
1. [HFL (Hypermediatic Feedback Loop) for XR Browsers](#hfl-hypermediatic-feedback-loop-for-xr-browsers)
|
||
1. [Conventions and Definitions](#conventions-and-definitions)
|
||
1. [XR Fragment URL Grammar](#xr-fragment-url-grammar)
|
||
1. [Spatial Referencing 3D](#spatial-referencing-3d)
|
||
1. [Level0: Files](#level0-files)
|
||
1. [via href metadata](#via-href-metadata)
|
||
1. [via chained extension](#via-chained-extension)
|
||
1. [via subdocuments/xattr](#via-subdocuments-xattr)
|
||
1. [JSON sidecar-file](#json-sidecar-file)
|
||
1. [Level1: URI](#level1-uri)
|
||
1. [List of URI Fragments](#list-of-uri-fragments)
|
||
1. [List of explicit metadata](#list-of-explicit-metadata)
|
||
1. [Level2: href links](#level2-href-links)
|
||
1. [Interaction behaviour](#interaction-behaviour)
|
||
1. [XR Viewer implementation](#xr-viewer-implementation)
|
||
1. [Level3: Media Fragments](#level3-media-fragments)
|
||
1. [Animation(s) timeline](#animation-s-timeline)
|
||
1. [Specify playback loopmode](#specify-playback-loopmode)
|
||
1. [Controlling embedded content](#controlling-embedded-content)
|
||
1. [Level4: prefix operators](#level4-prefix-operators)
|
||
1. [Object teleports](#object-teleports)
|
||
1. [Object multipliers](#object-multipliers)
|
||
1. [De/selectors (+ and -)](#de-selectors-and)
|
||
1. [Sharing object or file (#|)](#sharing-object-or-file)
|
||
1. [xrf:// URI scheme](#xrf-uri-scheme)
|
||
1. [Level5: URI Templates (RFC6570)](#level5-uri-templates-rfc6570)
|
||
1. [Top-level URL processing](#top-level-url-processing)
|
||
1. [UX](#ux)
|
||
1. [Example: Navigating content href portals](#example-navigating-content-href-portals)
|
||
1. [Walking surfaces](#walking-surfaces)
|
||
1. [Example: Virtual world rings](#example-virtual-world-rings)
|
||
1. [Additional scene metadata](#additional-scene-metadata)
|
||
1. [Accessibility interface](#accessibility-interface)
|
||
1. [Two-button navigation](#two-button-navigation)
|
||
1. [Overlap with fileformat-specific extensions](#overlap-with-fileformat-specific-extensions)
|
||
1. [Vendor Prefixes](#vendor-prefixes)
|
||
1. [Security Considerations](#security-considerations)
|
||
1. [FAQ](#faq)
|
||
1. [Authors](#authors)
|
||
1. [IANA Considerations](#iana-considerations)
|
||
1. [Acknowledgments](#acknowledgments)
|
||
1. [Appendix: Definitions](#appendix-definitions)
|
||
|
||
# Introduction
|
||
(!Introduction)
|
||
|
||
How can we add more control to existing text and 3D scenes, without introducing new dataformats?<br>
|
||
Historically, there's many attempts to create the ultimate 3D fileformat.<br>
|
||
The lowest common denominator is: designers describing/tagging/naming things using **plain text**.<br>
|
||
XR Fragments exploits the fact that all 3D models already contain such metadata:
|
||
|
||
**XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments**
|
||
|
||
# How does it work
|
||
(!What is XR Fragments )
|
||
|
||
XR Fragments utilizes URLs:
|
||
|
||
1. for 3D viewers/browser to manipulate the camera or objects (via URI fragments)
|
||
2. implicitly: by mapping 3D objectnames (of a 3D scene/file) to URI fragments (3D deeplinking)
|
||
3. explicitly: by scanning `href` metadata **inside** 3D scene-files to enable interactions
|
||
4. externally: progressively enhance a 3D (file) into an experience via [sidecarfiles](https://en.wikipedia.org/wiki/Sidecar_file)
|
||
|
||
# What does it solve
|
||
|
||
It solves:
|
||
|
||
1. addressibility and [hypermediatic](https://github.com/coderofsalvation/hypermediatic) navigation of 3D scenes/objects: [URI Fragments](https://en.wikipedia.org/wiki/URI_fragment) using src/href spatial metadata
|
||
1. Interlinking text & spatial objects by collapsing space into a Word Graph (XRWG) to show [visible links](#visible-links)
|
||
1. unlocking spatial potential of the (originally 2D) hashtag (which jumps to a chapter) for navigating XR documents
|
||
1. refraining from introducing scripting-engines for mundane tasks (and preventing its inevitable security-headaches)
|
||
1. the gap between text an 3d objects: object-names directly map to hashtags (=fragments), which allows 3D to text transcription.
|
||
|
||
> NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible
|
||
|
||
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 [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 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.
|
||
|
||
# HFL (Hypermediatic Feedback Loop) for XR Browsers
|
||
(!HFL (Hypermediatic Feedback Loop) for XR Browsers)
|
||
|
||
`href` metadata traditionally implies **click** AND **navigate**, however XR Fragments adds stateless **click** (`xrf://....`) via the `xrf://` 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 **hashbus**-only events/
|
||
|
||
> Being able to use the same URI Fragment DSL for navigation (`href: #foo`) as well as interactions (`href: xrf://#foo`) 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).
|
||
* potentially 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`)
|
||
* potentially 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 | 3D 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
|
||
(!Conventions and Definitions)
|
||
|
||
See appendix below in case certain terms are not clear.
|
||
|
||
## XR Fragment URL Grammar
|
||
(! 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&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
|
||
(!Spatial Referencing 3D )
|
||
|
||
3D files contain an hierarchy of objects.<br>
|
||
XR Fragments assumes the following objectname-to-URI-Fragment mapping, in order to deeplink 3D objects:
|
||
|
||
```
|
||
|
||
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`
|
||
|
||
> 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.
|
||
|
||
# Level0: Files
|
||
(!Level0: Files )
|
||
(!Level0: Files)
|
||
|
||
These are **optional** auto-loaded [side-car files]() to enable hasslefree [XR Movies](#XR%20Movies).<br>
|
||
they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a `.glb` e.g.).
|
||
|
||
## via href metadata
|
||
|
||
```
|
||
scene.glb <--- 'href' extra [heuristic] detected inside!
|
||
scene.png (preview thumbnail)
|
||
scene.ogg (soundtrack to plays when global 3D animation starts)
|
||
scene.vtt (subtitles for accessibility or screenreaders)
|
||
scene.json (sidecar JSON-file with explicit metadata)
|
||
```
|
||
|
||
**heuristics**:
|
||
|
||
* if at least one `href` custom property/extra is found in a 3D scene
|
||
* The viewer should poll for the above mentioned sidecar-file extensions (and present accordingly)
|
||
|
||
## via chained extension
|
||
|
||
```
|
||
scene.xrf.glb <--- '.xrf.' sidecar file heuristic detected!
|
||
scene.xrf.png (preview thumbnail)
|
||
scene.xrf.ogg (soundtrack to plays when global 3D animation starts)
|
||
scene.xrf.vtt (subtitles for accessibility or screenreaders)
|
||
scene.xrf.json (sidecar JSON-file with explicit metadata)
|
||
```
|
||
|
||
> A fallback-mechanism to turn 3D files into [XR Movies](#XR%20Movies) without editing them.
|
||
|
||
**heuristics**:
|
||
|
||
* the chained-extension heuristic `.xrf.` should be present in the filename (`scene.xrf.glb` e.g.)
|
||
|
||
## via subdocuments/xattr
|
||
|
||
More secure protocols (Nextgraph e.g.) don't allow for simply polling files.
|
||
In such case, subdocuments or extended attributes should be polled:
|
||
|
||
> NOTE: in the examples below we use the href-heuristic, but also the `.xrf.` chained-extension applies here.
|
||
|
||
```
|
||
myspreadsheet.ods
|
||
└── explainer.glb <--- 'href' extra [heuristic] detected inside!
|
||
├── explainer.ogg (soundtrack to play when global 3D animation starts)
|
||
├── explainer.png (preview thumnbnail)
|
||
├── explainer.json (sidecar JSON-file with explicit metadata)
|
||
└── explainer.vtt (subtitles for accessibility or screenreaders)
|
||
```
|
||
|
||
If only extended attributes (xattr) are available, the respective referenced file can be embedded:
|
||
|
||
```
|
||
$ setfattr -n explainer.ogg -v "soundtrack.ogg" explainer.glb
|
||
$ setfattr -n explainer.png -v "thumbnail.png" explainer.glb
|
||
$ setfattr -n explainer.vtt -v "subtitles.vtt" explainer.glb
|
||
```
|
||
|
||
> NOTE: Linux's `setfattr/getfattr` is `xattr` on mac, and `Set-Content/Get-content` on Windows. See [pxattr](https://www.lesbonscomptes.com/pxattr/index.html) for lowlevel access.
|
||
|
||
## JSON sidecar-file
|
||
|
||
For developers, sidecar-file can allow for defining **explicit** XR Fragments links (>level1), outside of the 3D file.<br>
|
||
This can be done via (objectname/metadata) key/value-pairs in a JSON [sidecar-file](https://en.wikipedia.org/wiki/Sidecar_file):
|
||
|
||
* experience.glb
|
||
* experience.json `<----`
|
||
|
||
|
||
```json
|
||
{
|
||
"/":
|
||
"aria-description": "description of scene",
|
||
},
|
||
"button": {
|
||
"href": "#roomB"
|
||
}
|
||
}
|
||
```
|
||
|
||
> This will make object `button` clickable, and teleport the user to object `roomB`.
|
||
|
||
So after loading `experience.glb` the existence of `experience.json` is detected, to apply the explicit metadata.<br>
|
||
The sidecar will define (or **override** already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).
|
||
|
||
> In THREE.js-code this would boil down to:
|
||
|
||
```javascript
|
||
scene.userData['aria-description'] = "description of scene"
|
||
scene.getObjectByName("button").userData.href = "#roomB"
|
||
|
||
// now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene
|
||
```
|
||
|
||
# Level1: URI
|
||
(!Level1: URI)
|
||
|
||
> **XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments**
|
||
|
||
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 **integrates all** which allows a universal viewing experience.<br>
|
||
|
||
```
|
||
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
||
│ │
|
||
│ U R N │
|
||
│ U R L | │
|
||
│ | |-----------------+--------| │
|
||
│ +--------------------------------------------------| │
|
||
│ | │
|
||
│ + https://foo.com/some/foo/scene.glb#someview <-- http URI (=URL and has URN) │
|
||
│ | │
|
||
│ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview <-- an IPFS URI (=URL and has URN) │
|
||
│ │
|
||
│ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI │
|
||
│ │
|
||
│ │
|
||
│ |------------------------+-------------------------| │
|
||
│ | │
|
||
│ U R I │
|
||
│ │
|
||
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
||
|
||
```
|
||
|
||
Fact: our typical browser URL's are just **a possible implementation** of URI's (for untapped humancentric potential of URI's [see interpeer.io](https://interpeer.io) or [NextGraph](https://nextgraph.org) )
|
||
|
||
> 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.
|
||
|
||
Below you can see how this translates back into good-old URLs:
|
||
|
||
```
|
||
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
||
│ │
|
||
│ the soul of any URL: ://macro /meso ?micro #nano │
|
||
│ │
|
||
│ 2D URL: ://library.com /document ?search #chapter │
|
||
│ xrf:// │
|
||
│ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #object ─> hashbus │
|
||
│ │ #filter │ │
|
||
│ │ #tag │ │
|
||
│ │ (hypermediatic) #material │ │
|
||
│ │ ( feedback ) #animation │ │
|
||
│ │ ( loop ) #texture │ │
|
||
│ │ #variable │ │
|
||
│ │ │ │
|
||
│ XRWG <─────────────────────<─────────────+ │
|
||
│ │ │ │
|
||
│ └─ objects ──────────────>─────────────+ │
|
||
│ │
|
||
│ │
|
||
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
||
|
||
```
|
||
|
||
> ?-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.
|
||
|
||
## List of URI Fragments
|
||
|
||
| fragment | type | example | info |
|
||
|-------------------|------------|--------------------|----------------------------------------------------------------------|
|
||
| `#......` | vector3 | `#room1` `#room2` `#cam2` | positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera and upvector |
|
||
| [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
|
||
|
||
| key | type | example (JSON) | function | existing compatibility |
|
||
|--------------|----------|------------------------|---------------------|----------------------------------------|
|
||
| `href` | string | `"href": "b.gltf"` | XR teleport | custom property in 3D fileformats |
|
||
|
||
|
||
# Level2: href links
|
||
(!Level2: href links)
|
||
|
||
Explicit href metadata ('extras') in a 3D object (of a 3D file), hint the viewer that the user ''can interact'' with that object :
|
||
|
||
| fragment | type | example value |
|
||
|`href`| string (uri or predefined view) | `#pyramid`<br>`#lastvisit`<br>`xrf://#-someobject`<br>`://somefile.gltf#foo`<br> |
|
||
|
||
## Interaction behaviour
|
||
|
||
When clicking an ''href''-value, the user(camera) is teleport to the referenced object.
|
||
|
||
The imported/teleported destination can be another object in the same scene-file, or a different file.
|
||
|
||
## XR Viewer implementation
|
||
|
||
| **spec** | **action** | **feature** |
|
||
|-|-|-|
|
||
| level0+1 | hover 3D file [href](#via-href-metadata) | show the preview PNG thumbnail (if any). |
|
||
| level0+1 | launch 3D file [href](#via-href-metadata) | replace the current scene with a new 3D file (`href: other.glb` e.g.) |
|
||
| level2 | click internal 3D file [href](#via-href-metadata) (`#roomB` e.g.) | teleport the camera to the origin of object(name `roomB`). See [[teleport camera]].|
|
||
| level2 | click external 3D file [href](#via-href-metadata) (`foo.glb` e.g.) | replace the current scene with a new 3D file (`href: other.glb` e.g.) |
|
||
| level2 | hover external 3D file [href](#via-href-metadata) | show the preview PNG thumbnail (if any sidecar, see level0) |
|
||
| level2 | click [href](#via-href-metadata) | hashbus: execute without changing the toplevel URL location (`href: xrf://#someObjectName` e.g.) |
|
||
| level3 | click [href](#via-href-metadata) | set the global 3D animation timeline to its Media Fragment value (`#t=2,3` e.g.) |
|
||
|
||
> NOTE: hashbus links (`xrf://#foo&bar`) don't change the toplevel URL, which makes it ideal for interactions (in contrast to typical `#roomC` navigation, which benefit back/forward browser-buttons), see <a href="#hashbus">hashbus</a> for more info.
|
||
|
||
# Level3: Media Fragments
|
||
(!Level3: Media Fragments )
|
||
|
||
> these allow for XR Movies with a controllable timeline using `href` URI's with Media Fragments
|
||
|
||
Just like with 2D media-files, W3C mediafragments (`#t=1,2`) can be used to control a timeline via the [#t](##t) primitive.
|
||
XR Fragments Level3 makes the 3D timeline, as well as URL-referenced files **controllable** via Media Fragments like:
|
||
|
||
* level2 hrefs (`href: #t=4` e.g. to control 3D timeline)
|
||
* level4: `xrf:` URI scheme:
|
||
* `href: xrf:foo.wav#t=0` to play a wav
|
||
* `href: xrf:news.glb?clone#t=0` to instance and play another experience
|
||
|
||
## Animation(s) timeline
|
||
|
||
controls the animation(s) of the scene (or `src` resource which contains a timeline)
|
||
|
||
| fragment | type | functionality |
|
||
| <b>#t</b>=start,stop | [[vector2]] (default:`#t=0,0`) | start,stop (in seconds |
|
||
|
||
|
||
| Example Value | Explanation |
|
||
| `#t=1` | play (3D) animations from 1 seconds till end (and stop) |
|
||
| `#t=1,100` | play (3D) animations from 1 till 100 seconds (and stop) |
|
||
| `#t=0,0` | stop (3D) animations at frame 0 |
|
||
|
||
> Use [[#s 🌱]] to control playback speed
|
||
|
||
## Specify playback loopmode
|
||
|
||
This compensates a missing element from Media Fragments to enable/disable temporal looping. .
|
||
|
||
| fragment | type | functionality |
|
||
| <b>#loop</b> | string | enables animation/video/audio loop |
|
||
| <b>#-loop</b> | string | disables animation/video/audio loop |
|
||
|
||
|
||
## Controlling embedded content
|
||
|
||
use [[URI Templates]] to control embedded media, for example a simple video-player:
|
||
|
||
```
|
||
foo.usdz
|
||
│
|
||
├── ◻ loopbutton_enable
|
||
│ └ href: #loop <-- enable global loop
|
||
│
|
||
├── ◻ loopbutton_enable
|
||
│ └ href: #-loop <-- disable global loop
|
||
│
|
||
├── ◻ playbutton
|
||
│ └ href: #t=10&loop <-- play global 3D timeline (all anims) (looped)
|
||
│
|
||
└── ◻ playbutton_external
|
||
└ href: https://my.org/animation.glb#!&t=3,10 <-- import & play external anim
|
||
|
||
```
|
||
|
||
# Level4: prefix operators
|
||
(!Level4: prefix operators)
|
||
|
||
Prefixing objectnames with the following simple operators allow for **extremely powerful** XR interactions:
|
||
|
||
* #!
|
||
* #*
|
||
* #+ or #-
|
||
* #|
|
||
* xrf: URI scheme
|
||
|
||
> **Examples:** `#+menu` to show a object, `#-menu` to hide a menu, `#!menu` to teleport a menu, `#*block` to clone a grabbable block, `#|object` to share an object
|
||
|
||
|
||
## Object teleports (!)
|
||
|
||
Prefixing an object with an exclamation-symbol, will teleport a (local or remote) referenced object from/to its original/usercamera location.<br>
|
||
|
||
[img[objecteleport.png]]
|
||
|
||
Usecases:
|
||
* show/hide objects/buttons (menu e.g.) in front of user
|
||
* embed remote (object within) 3D file via remote URL
|
||
* instance an interactive object near the user regardless of location
|
||
* instance HUD or semi-transparent-textured-sphere (LUT) around the user
|
||
|
||
<div class="border padding" style="border:4px solid #888">
|
||
<span class="big hi1">#!menu</span>
|
||
</div>
|
||
<br>
|
||
|
||
Clicking the [href](#via-href-metadata)-value above will:
|
||
|
||
1. **reposition the referenced object** (menu) to the usercamera's-coordinates.
|
||
2. **zoom** in case of (non-empty) mesh-object: rescale to 1 m³, and position 1m in front of the camera
|
||
3. toggle behaviour: revert values if 1/2 were already applied
|
||
4. `#+` is always implied (objects are always made visible)
|
||
|
||
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.).
|
||
|
||
* href: `#whiteroom&!explainer&!exitmenu`
|
||
|
||
> This will teleport the user to `whiteroom` and moves object `explainer` and `exitmenu` in front of the user.
|
||
|
||
* href: `https://my.org/foo.glb#!
|
||
|
||
Clicking the [href](#via-href-metadata)-value above will:
|
||
|
||
1. import `foo.glb` from `my.org`'s webserver
|
||
2. show it in front of the user (because `#!` indicates object teleport)
|
||
|
||
* href: `https://foo.glb#roomB&!bar`
|
||
|
||
Clicking the [href](#via-href-metadata)-value above will:
|
||
|
||
1. replace the current scene with `foo.glb`
|
||
2. teleport the user to #roomB inside `foo.glb`
|
||
3. **instance the referenced object** (bar inside foo.glb) in front of the user.
|
||
4. it will update the top-Level URL (because `xrf:` was not used)
|
||
5. hide the **instanced object** when clicked again (toggle visibility)
|
||
|
||
> **NOTE**: level2 teleportation links, as well as instancing mitigates the 'broken embedded image'-issue of HTML: **always** attaching the href-values to **a 3D (preview) object** (that way broken links will not break the design).
|
||
|
||
**Example:** clicking a 3D button with title 'menu' and [href](#href)-value `xrf:menu.glb?instance#t=4,5` would instance a 3D menu (`menu.glb`) in front of the user, and loop its animation between from 4-5 seconds (`t=4,5`)
|
||
|
||
> **NOTE**: combining instance-operators allows dynamic construction of 3D scenes (`#london&!welcomeMenu&!fadeBox` e.g.)
|
||
|
||
## Object multipliers (*)
|
||
|
||
The star-prefix will clone a (local or remote) referenced object to the usercamera's location, and make it grabbable.<br>
|
||
Usecases:
|
||
* object-picker (build stuff with objects)
|
||
|
||
> **NOTE**: this is basically the [#! operator](#%23%21) which infinitely **clones** the referenced object (instead of repositioning the object).
|
||
|
||
## De/selectors (+ and -)
|
||
|
||
* href: `#-welcome` (or `#+welcome`)
|
||
|
||
Clicking href-value above will do:
|
||
|
||
1. show/hide the target object (and children)
|
||
|
||
* href: `#https://my.org/foo.glb/#bar&-welcome`
|
||
|
||
> **NOTE:** the latter shows that (de)selectors can also be with regular [href](#href)-values
|
||
|
||
## Sharing object or file (#|)
|
||
|
||
The pipe-symbol (`|`) sends a (targeted) object to the OS.
|
||
Clicking the href-value below will:
|
||
|
||
1. share the (targeted object in the) file to a another application
|
||
|
||
> This URL can be fed straight into [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API) or [xdg-open](https://www.freedesktop.org/wiki/Software/xdg-utils/)
|
||
|
||
* href: `xrf://#|bar`
|
||
|
||
> **NOTE**: sharing is limited to (internal objects) via `xrf:` scheme-only
|
||
|
||
## xrf:// URI scheme
|
||
|
||
Prefixing the `xrf:` to [href](#href)-values **will prevent** [level2](#📜%20level2:%20explicit%20links) [href](#href)-values from changing the top-Level URL.
|
||
|
||
> **Usecase**: for non-shareable URLs like `href: xrf:#t=4,5`, to display a stateful msg e.g.).
|
||
|
||
**Reason:** XR Fragments is inspired by HTML's [href-attribute](https://en.wikipedia.org/wiki/Hyperlink), which does various things:
|
||
|
||
1. it updates the browser-location
|
||
2. it makes something clickable
|
||
3. it jumps to another document / elsewhere in the same document
|
||
4. and more
|
||
|
||
The `xrf:` scheme will just do 2 & 3 (so the URL-values will not leak into the top-level URL).
|
||
|
||
> **compliance with RFC 3986**: unimplemented/unknown URI schemes (`xrf:...` e.g.) will not update the top-level URL
|
||
|
||
# Level5: URI Templates (RFC6570)
|
||
(!Level5: URI Templates (RFC6570))
|
||
|
||
XR Fragments adopts Level1 URI **Fragment** expansion to provide safe interactivity.<br>
|
||
This is non-normative, and the draft spec is available on request.
|
||
|
||
|
||
# Top-level URL processing
|
||
(!Top-level URL processing)
|
||
|
||
> Example URL: `://foo/world.gltf#room1&t=10&cam`
|
||
|
||
The URL-processing-flow for hypermedia browsers goes like this:
|
||
|
||
1. 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.
|
||
2. 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]]))
|
||
3. IF a camera-object exists with name `cam` assume that user(camera) position
|
||
|
||
## UX
|
||
|
||
End-users should always have read/write access to:
|
||
|
||
1. the current (toplevel) <b>URL</b> (an URLbar etc)
|
||
2. URL-history (a <b>back/forward</b> button e.g.)
|
||
3. Clicking/Touching an `href` navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments).
|
||
|
||
|
||
# Example: Navigating content href portals
|
||
(!Example: Navigating content href portals)
|
||
|
||
navigation, portals & mutations
|
||
|
||
| fragment | type | example value |
|
||
|----------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||
|`href` | string (uri or predefined view) | `#room1`<br>`#room1`<br>`://somefile.gltf#room1`<br> |
|
||
|
||
1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes `room2` by default (unless specified)
|
||
|
||
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.)
|
||
|
||
4. URL navigation should always be reflected in the client URL-bar (in case of javascript: see [[here](https://github.com/coderofsalvation/xrfragment/blob/dev/src/3rd/js/three/navigator.js) for an example navigator), and only update the URL-bar after the scene (default fragment `#`) has been loaded.
|
||
|
||
5. In immersive XR mode, the navigator back/forward-buttons should be always visible (using a wearable e.g., see [[here](https://github.com/coderofsalvation/xrfragment/blob/dev/example/aframe/sandbox/index.html#L26-L29) for an example wearable)
|
||
|
||
6. make sure that the ''back-button'' of the ''browser-history'' always refers to the previous position (see [[here](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js#L97))
|
||
|
||
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 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 `#...` 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>
|
||
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/1)<br>
|
||
|
||
## Walking surfaces
|
||
|
||
> By default position `0,0,0` of the 3D scene represents the walkable plane, however this is overridden when the following applies:
|
||
|
||
XR Fragment-compatible viewers can infer this data based scanning the scene for:
|
||
|
||
1. materialless (nameless & textureless) mesh-objects (without `href` and >0 faces)
|
||
|
||
> optionally the viewer can offer thumbstick, mouse or joystick teleport-tools for non-roomscale VR/AR setups.
|
||
|
||
# Example: Virtual world rings
|
||
(!Example: Virtual world rings )
|
||
|
||
Consider 3D scenes linking to eachother using these `href` values, attached to 3D button-objects:
|
||
|
||
* `href: schoolA.edu/projects.gltf#math`
|
||
* `href: schoolB.edu/projects.gltf#math`
|
||
* `href: university.edu/projects.gltf#math`
|
||
|
||
This would teleport users to the math-projects of those universities.<br>
|
||
Now consider adding a 'webring index'-button to each file, with this href-value:
|
||
|
||
|
||
* href: workgroup.edu/webrings.glb#!webringmenu
|
||
|
||
This would allow displaying the (remote 3D file) webring menu with various href-buttons inside, all centrally curated by the workgroup.
|
||
|
||
# Additional scene metadata
|
||
(!Additional scene metadata )
|
||
|
||
XR Fragments does not aim to redefine the metadata-space or accessibility-space by introducing its own cataloging-metadata fields.
|
||
Instead, it encourages browsers to scan nodes for the following custom properties:
|
||
|
||
* [SPDX](https://spdx.dev/) license information
|
||
* [ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) attributes (`aria-*: .....`)
|
||
* [datapackage.json](https://datapackage.org) findability, accessibility, interoperability, and reusability of data
|
||
|
||
ARIA's `aria-description`-metadata is normative, to aid accessibility and scene transcripts
|
||
|
||
> **NOTE**: please always start `aria-description` with a verb to aid transcripts.
|
||
|
||
The following metadata are non-normative but encouraged, since they are popular and cheap to parse:
|
||
|
||
* [RDF/JSON-LD](https://json-ld.org) like [this example](https://mvmd.org/standards/gltf/) or via glTF's [KHR_xmp_json_ld extension](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_xmp_json_ld)
|
||
* [Open Graph](https://ogp.me) attributes (`og:*: .....`)
|
||
* [Dublin-Core](https://www.dublincore.org/specifications/dublin-core/application-profile-guidelines/) attributes(`dc:*: .....`)
|
||
* [BibTex](https://bibtex.eu/fields) when known bibtex-keys exist with values enclosed in `{` and `},`
|
||
|
||
|
||
> Example: object 'tryceratops' with `aria-description: is a huge dinosaurus standing on a #mountain` generates transcript `#tryceratops is a huge dinosaurus standing on a #mountain`, where the hashtags are clickable XR Fragments (activating the visible-links in the XR browser).
|
||
|
||
Individual nodes can be enriched with such metadata, but most importantly the scene node:
|
||
|
||
| metadata key | example value |
|
||
|--------------------------------------------------------|-------------------------------------------------|
|
||
| `aria-description`, `og:description`, `dc:description` | `An immersive experience about Triceratops` (*) |
|
||
| `SPDX` | `CC0-1.0` |
|
||
| `dc:creator` | `John Doe` |
|
||
| `dc:title`, `og:title` | 'Triceratops` (*) |
|
||
| `og:site_name` | `https://xrfragment.org` |
|
||
| `dc.publisher` | `NLNET` |
|
||
| `dc.date` | `2024-01-01` |
|
||
| `dc.identifier` | `XRFRAGMENT-001` |
|
||
| `journal` (bibTeX) | `{Future Of Text Vol 3},` |
|
||
|
||
> \* = these are interchangable (only one needs to be defined)
|
||
|
||
There's no silver bullet when it comes to metadata, so XR Fragment-implementations should support where the metadata is/goes.
|
||
|
||
> These attributes can be scanned and presented during an `href` or `src` eye/mouse-over.
|
||
|
||
# Accessibility interface
|
||
(!Accessibility interface)
|
||
|
||
The addressibility of XR Fragments allows for unique 3D-to-text transcripts, as well as an textual interface to navigate 3D content.<br>
|
||
Spec:<br><Br>
|
||
|
||
1. The enduser must be able to enable an accessibility-mode (which persists across application/webpage restarts)
|
||
2. Accessibility-mode must contain a text-input for the user to enter text
|
||
3. Accessibility-mode must contain a flexible textlog for the user to read (via screenreader, screen, or TTS e.g.)
|
||
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 `#...` 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 `#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>
|
||
Therefore a 2-button navigation-interface is the bare minimum interface:
|
||
|
||
1. objects with href metadata can be cycled via a key (tab on a keyboard)
|
||
2. objects with href metadata can be activated via a key (enter on a keyboard)
|
||
3. the TTS reads the href-value (and/or aria-description if available)
|
||
|
||
## Overlap with fileformat-specific extensions
|
||
|
||
Some 3D scene-fileformats have support for extensions.
|
||
What if the functionality of those overlap?
|
||
For example, GLTF has the `OMI_LINK` extension which might overlap with XR Fragment's `href`:
|
||
|
||
> Priority Order and Precedence, otherwise fallback applies
|
||
|
||
1.**Extensions Take Precedence**: Since glTF-specific extensions are designed with the format’s
|
||
specific needs and optimizations in mind, they should take precedence over extras metadata
|
||
in cases where both contain overlapping functionality.
|
||
This approach aligns with the idea that extensions are more likely to be interpreted uniformly by glTF-compatible software.
|
||
|
||
2. **Fallback Fall-through Mechanism**:
|
||
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.
|
||
|
||
> **Example 1** In case of the OMI_LINK glTF extension (`href: https://nlnet.nl`) and an XR Fragment (`href: #otherroom` or `href: otherplanet.glb`), it is clear that `https://nlnet.nl` should open in a browsertab, whereas the XR Fragment links should teleport the user. If the OMI_LINK contains an XR Fragment (`#room1` e.g.) a teleport should be performed only (and other [overlapping] metadata should be ignored).
|
||
|
||
> **Example 2** If an Extensions uses XR Fragments in URI's (`href: #otherroom` or `href: xrf://-walls` 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.
|
||
|
||
# Vendor Prefixes
|
||
(!Vendor Prefixes )
|
||
|
||
Vendor-specific metadata in a 3D scenefiles, are similar to vendor-specific [CSS-prefixes](https://en.wikipedia.org/wiki/CSS#Vendor_prefixes) (`-moz-opacity: 0.2` e.g.).
|
||
This allows popular 3D engines/frameworks, to initialize specific features when loading a scene/object, in a progressive enhanced way.
|
||
|
||
Vendor Prefixes allows embedding 3D engines/framework-specific features a 3D file via metadata:
|
||
|
||
| what | XR metadata | Lowest common denominator |
|
||
|------------------|---------------------|-------------------------------------------------------|
|
||
| CSS | vendor-agnostic | 2D canvas + object referencing/styling |
|
||
| XR Fragments | vendor-agnostic | 3D camera + object(file) load/embed/click/referencing |
|
||
| Vendor prefixs | vendor-**specific** | Specialized Entity-Component implementation |
|
||
|
||
> 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.
|
||
|
||
For example, the following metadata can be added to a .glb file, to make an object grabbable in AFRAME:
|
||
|
||
```
|
||
+────────────────────────────────────────────────────────────────────────────────────────────────────────+
|
||
│ http://y.io/z.glb | AFRAME app │
|
||
│-----------------------------------------------+--------------------------------------------------------│
|
||
│ | │
|
||
│ | after loading the glb, john can be placed into the │
|
||
│ +-[3D mesh]-+ | castle via hands, because the author added metadata to │
|
||
│ | / \ | | john via either: │
|
||
│ | / \ | | │
|
||
│ | / \ | | 1. Blender (custom property-box, no plugins needed) │
|
||
│ | |_____| | | │
|
||
│ +-----│-----+ | 2. javascript-code: │
|
||
│ │ | │
|
||
│ ├─ name: castle | for( var com in this.el.components ){ │
|
||
│ └─ tag: house baroque | this.el.object3D.userData[`-AFRAME-${com}`] = '' │
|
||
│ | } │
|
||
│ [3D mesh-+ | // save to z.glb in AFRAME inspector │
|
||
│ | ├─ name: john | │
|
||
│ | O ├─ age: 23 | │
|
||
│ | /|\ ├─ -aframe-grabbable: '' | > inits 'grabbable' component on object john │
|
||
│ | / \ ├─ -aframe-material.color: '#F0A' | > inits 'material' component on object john │
|
||
│ | ├─ -aframe-text.value: '{name}{age}'| > inits 'text' component (*) with value 'john' │
|
||
│ | ├─ -three-material.fog: false | > changes material settings in THREE.js app │
|
||
│ | ├─ -godot-Label3D.text: '{name}{age}'| > inits 'Label3D' component (*) in Godot │
|
||
│ +--------+ | │
|
||
│ | │
|
||
├─ -GODOT-version: '4.3' | > exporters/authors can report targeted version │
|
||
├─ -AFRAME-version: '1.6.0' | and (optionally) hint component-repo│
|
||
├─ -AFRAME-info: 'https://git.benetou.fr/comps' │
|
||
│ | │
|
||
+────────────────────────────────────────────────────────────────────────────────────────────────────────+
|
||
```
|
||
|
||
* key/value syntax: -`<vendorname>`-`<component|version>`.`<key>` `[string/boolean/float/int]`-value
|
||
|
||
String-templatevalues are evaluated as per [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) Level 1.
|
||
|
||
> This 'separating of mechanism from policy' (unix rule) does **somewhat** 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.
|
||
|
||
|
||
# Security Considerations
|
||
(!Security Considerations)
|
||
|
||
The only dynamic parts are [W3C Media Fragments](https://www.w3.org/TR/media-frags/) and [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570).<br>
|
||
The use of URI Templates is limited to pre-defined variables and Level0 fragments-expansion only, which makes it quite safe.<br>
|
||
n fact, it is much safer than relying on a scripting language (javascript) which can change URN too.
|
||
|
||
# FAQ
|
||
(!FAQ )
|
||
|
||
**Q:** Why is everything HTTP GET-based, what about POST/PUT/DELETE HATEOS<br>
|
||
**A:** 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 `src` values)
|
||
|
||
---
|
||
|
||
**Q:** Why isn't there support for scripting, URI Template Fragments are so limited compared to WASM & javascript
|
||
**A:** 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 [W3C Media Fragments](https://www.w3.org/TR/media-frags/) and [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570), 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).
|
||
|
||
# authors
|
||
(!authors)
|
||
|
||
* Leon van Kammen (@lvk@mastodon.online)
|
||
* Jens Finkhäuser (@jens@social.finkhaeuser.de)
|
||
|
||
# IANA Considerations
|
||
(!IANA Considerations)
|
||
|
||
This document has no IANA actions.
|
||
|
||
# Acknowledgments
|
||
(!Acknowledgments)
|
||
|
||
* [NLNET](https://nlnet.nl)
|
||
* [Future of Text](https://futureoftext.org)
|
||
* [visual-meta.info](https://visual-meta.info)
|
||
* Michiel Leenaars
|
||
* Gerben van der Broeke
|
||
* Mauve
|
||
* Jens Finkhäuser
|
||
* Marc Belmont
|
||
* Tim Gerritsen
|
||
* Frode Hegland
|
||
* Brandel Zackernuk
|
||
* Mark Anderson
|
||
|
||
# Appendix: Definitions
|
||
(!Appendix: Definitions )
|
||
|
||
|definition | explanation |
|
||
|----------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||
|human | a sentient being who thinks fuzzy, absorbs, and shares thought (by plain text, not markuplanguage) |
|
||
|scene | a (local/remote) 3D scene or 3D file (index.gltf e.g.) |
|
||
|3D object | an object inside a scene characterized by vertex-, face- and customproperty data. |
|
||
|URI | some resource at something somewhere via someprotocol (`http://me.com/foo.glb#foo` or `e76f8efec8efce98e6f` [see interpeer.io](https://interpeer.io))|
|
||
|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 (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 |
|
||
|teleportation | repositioning the enduser to a different position (or 3D scene/file) |
|
||
|sourceportation | teleporting the enduser to the original XR Document of an `src` embedded object. |
|
||
|placeholder object | a 3D object which with src-metadata (which will be replaced by the src-data.) |
|
||
|src | (HTML-piggybacked) metadata of a 3D object which instances content |
|
||
|href | (HTML-piggybacked) metadata of a 3D object which links to content |
|
||
|filter | URI Fragment(s) which show/hide object(s) in a scene based on name/tag/property (`#cube&-price=>3`) |
|
||
|visual-meta | [visual-meta](https://visual.meta.info) data appended to text/books/papers which is indirectly visible/editable in XR. |
|
||
|requestless metadata | metadata which never spawns new requests (unlike RDF/HTML, which can cause framerate-dropping, hence not used a lot in games) |
|
||
|FPS | frames per second in spatial experiences (games,VR,AR e.g.), should be as high as possible |
|
||
|introspective | inward sensemaking ("I feel this belongs to that") |
|
||
|extrospective | outward sensemaking ("I'm fairly sure John is a person who lives in oklahoma") |
|
||
|`◻` | ascii representation of an 3D object/mesh |
|
||
|(un)obtrusive | obtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words |
|
||
|flat 3D object | a 3D object of which all verticies share a plane |
|
||
|BibTeX | simple tagging/citing/referencing standard for plaintext |
|
||
|BibTag | a BibTeX tag |
|
||
|(hashtag)bibs | an easy to speak/type/scan tagging SDL ([see here](https://github.com/coderofsalvation/hashtagbibs) which expands to BibTex/JSON/XML |
|
||
|