added timelines to spec + index.html
This commit is contained in:
		
							parent
							
								
									976d222ab6
								
							
						
					
					
						commit
						afc0a77935
					
				
					 6 changed files with 21 additions and 1496 deletions
				
			
		| 
						 | 
					@ -115,6 +115,7 @@ XR Fragments allows us to better use implicit metadata inside 3D scene(files), b
 | 
				
			||||||
  1. [XR Fragment URL Grammar](#xr-fragment-url-grammar)
 | 
					  1. [XR Fragment URL Grammar](#xr-fragment-url-grammar)
 | 
				
			||||||
1. [Spatial Referencing 3D](#spatial-referencing-3d)
 | 
					1. [Spatial Referencing 3D](#spatial-referencing-3d)
 | 
				
			||||||
1. [Level0: Files](#level0-files)
 | 
					1. [Level0: Files](#level0-files)
 | 
				
			||||||
 | 
					  1. [timelines](#timelines)
 | 
				
			||||||
  1. [via href metadata](#via-href-metadata)
 | 
					  1. [via href metadata](#via-href-metadata)
 | 
				
			||||||
  1. [via chained extension](#via-chained-extension)
 | 
					  1. [via chained extension](#via-chained-extension)
 | 
				
			||||||
  1. [via subdocuments/xattr](#via-subdocuments-xattr)
 | 
					  1. [via subdocuments/xattr](#via-subdocuments-xattr)
 | 
				
			||||||
| 
						 | 
					@ -304,6 +305,16 @@ A 3D scene-file can be considered <b>XR Fragment-compatible</b> when it contains
 | 
				
			||||||
There are **optional** auto-loaded [side-car files]() to enable hasslefree [XR Movies](#XR%20Movies).<br>
 | 
					There 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.).
 | 
					they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a `.glb` e.g.).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Timelines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					when a loaded file contains a timeline (animations/subtitles e.g.), then:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> All timelines must play (looped) by default (to enable [[XR Movies]])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless an object has multiple animations (actions e.g.), then just play the first or with name `default`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## via href metadata
 | 
					## via href metadata
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,465 +0,0 @@
 | 
				
			||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html>
 | 
					 | 
				
			||||||
<head>
 | 
					 | 
				
			||||||
  <title>XR Macros</title>
 | 
					 | 
				
			||||||
  <meta name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl">
 | 
					 | 
				
			||||||
  <meta charset="utf-8">
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
<body>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- 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% 20%;
 | 
					 | 
				
			||||||
    line-height: 30px;
 | 
					 | 
				
			||||||
    color:#555;
 | 
					 | 
				
			||||||
    background:#F0F0F3
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  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 Macros</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-XRMACROS-leonvankammen-00
 | 
					 | 
				
			||||||
</pre>  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 class="special" id="abstract">Abstract</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>This draft offers a specification for embedding macros in existing 3D scenes/assets, to offer simple interactions and configure the renderer further.<br>
 | 
					 | 
				
			||||||
Together with URI Fragments, it allows for rich immersive experiences without the need of a complicated sandboxed scripting languages.</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<blockquote>
 | 
					 | 
				
			||||||
<p>Almost every idea in this document is demonstrated at <a href="https://xrfragment.org">https://xrfragment.org</a>, as this spec was created during the <a href="https://xrfragment.org">XR Fragments</a> spec.</p>
 | 
					 | 
				
			||||||
</blockquote>
 | 
					 | 
				
			||||||
<section data-matter="main">
 | 
					 | 
				
			||||||
<h1 id="introduction">Introduction</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>How can we add more features to existing text & 3D scenes, without introducing new dataformats?<br>
 | 
					 | 
				
			||||||
Historically, there’s many attempts to create the ultimate markuplanguage or 3D fileformat.<br>
 | 
					 | 
				
			||||||
Their lowest common denominator is: (co)authoring using plain text.<br>
 | 
					 | 
				
			||||||
Therefore, XR Macros allows us to enrich/connect existing dataformats, by offering a polyglot notation based on existing notations:<br></p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<ol>
 | 
					 | 
				
			||||||
<li>getting/setting common used 3D properties using querystring- or JSON-notation</li>
 | 
					 | 
				
			||||||
<li>targeting 3D properties using the lightweight query notation present in <a href="https://xrfragment.org">XR Fragments</a></li>
 | 
					 | 
				
			||||||
</ol>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<blockquote>
 | 
					 | 
				
			||||||
<p>NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible</p>
 | 
					 | 
				
			||||||
</blockquote>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 id="core-principle">Core principle</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<ol>
 | 
					 | 
				
			||||||
<li>XR Macros use querystrings, but are HTML-agnostic (though pseudo-XR Fragment browsers <strong>can</strong> be implemented on top of HTML/Javascript).</li>
 | 
					 | 
				
			||||||
<li>An XR Macro is 3D metadata which starts with ‘!’ (<code>!clickme: fog=0,10</code> e.g.)</li>
 | 
					 | 
				
			||||||
<li>Metadata-values can contain the <code>|</code> symbol to 🎲 roundrobin variable values (<code>!toggleme: fog=0,10|fog=0,1000</code> e.g.)</li>
 | 
					 | 
				
			||||||
<li>XR Macros acts as simple eventhandlers for URI Fragments: they are automatically published on the (<a href="https://xrfragment.org">XR Fragments</a>) hashbus, to act as events (so more serious scripting languages can react to them as well).</li>
 | 
					 | 
				
			||||||
<li>XR Macros can assign object metadata (<code>!setlocal: foo=1</code> writes <code>foo:1</code> metadata to the object containing the <code>!setlocal</code> metadata)</li>
 | 
					 | 
				
			||||||
<li>XR Macros can assign global metadata  (<code>!setfoo: #foo=1</code> writes <code>foo:1</code> metadata to the root scene-node)</li>
 | 
					 | 
				
			||||||
</ol>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<blockquote>
 | 
					 | 
				
			||||||
<p>These very simple principles allow for rich interactions and dynamic querying</p>
 | 
					 | 
				
			||||||
</blockquote>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 id="conventions-and-definitions">Conventions and Definitions</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>See appendix below in case certain terms are not clear.</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 id="list-of-xr-macros">List of XR Macros</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>(XR) Macros can be embedded in 3D assets/scenes.<br>
 | 
					 | 
				
			||||||
Macros enrich existing spatial content with a lowcode, limited logic-layer, by recursive (economic) use of the querystring syntax (which search engines and <a href="https://xrfragment.org">XR Fragments</a> already uses.<br>
 | 
					 | 
				
			||||||
This is done by allowing string/integer variables, and the <code>|</code> symbol to roundrobin variable values.<br>
 | 
					 | 
				
			||||||
Macros also act as events, so more serious scripting languages can react to them as well.<br></p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>key</th>
 | 
					 | 
				
			||||||
<th>type</th>
 | 
					 | 
				
			||||||
<th>example (JSON)</th>
 | 
					 | 
				
			||||||
<th>function</th>
 | 
					 | 
				
			||||||
<th>existing compatibility</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><code>@bg</code></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><code>"@bg":"#cube"</code></td>
 | 
					 | 
				
			||||||
<td>bg: binds fog near/far based to cube x/y/z (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><code>@fog</code></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><code>"@fog":"#cube"</code></td>
 | 
					 | 
				
			||||||
<td>fog: binds fog near/far based to cube x/y (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><code>@scroll</code></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><code>"@scroll":"#cube"</code></td>
 | 
					 | 
				
			||||||
<td>texturescrolling: binds texture x/y/rot based to cube x/y/z (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><code>@emissive</code></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><code>"@emissive":"#cube"</code></td>
 | 
					 | 
				
			||||||
<td>day/night/mood: binds material’s emissive value to cube x/y/z (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h2 id="usecase-click-object">Usecase: click object</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!clickme</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1&foo=2</td>
 | 
					 | 
				
			||||||
<td>object clicked</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h2 id="usecase-conditional-click-object">Usecase: conditional click object</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>#</td>
 | 
					 | 
				
			||||||
<td>foo=1</td>
 | 
					 | 
				
			||||||
<td>scene</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!clickme</td>
 | 
					 | 
				
			||||||
<td>q=foo>2&bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>object clicked and foo > 2</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<blockquote>
 | 
					 | 
				
			||||||
<p>when a user clicks an object with the custom properties above, it should set the backgroundcolor to <code>1,1,1</code> when <code>foo</code> is greater than <code>2</code> (see previous example)</p>
 | 
					 | 
				
			||||||
</blockquote>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h2 id="usecase-click-object-roundrobin">Usecase: click object (roundrobin)</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!cycleme</td>
 | 
					 | 
				
			||||||
<td>day|noon|night</td>
 | 
					 | 
				
			||||||
<td>object clicked</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>day</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>noon</td>
 | 
					 | 
				
			||||||
<td>bg=0.5,0.5,0.5</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>night</td>
 | 
					 | 
				
			||||||
<td>bg=0,0,0&foo=2</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<blockquote>
 | 
					 | 
				
			||||||
<p>when a user clicks an object with the custom properties above, it should trigger either <code>day</code> <code>noon</code> or <code>night</code> in roundrobin fashion.</p>
 | 
					 | 
				
			||||||
</blockquote>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h2 id="usecase-click-object-or-uri-fragment-and-scene-load-trigger">Usecase: click object or URI fragment, and scene load trigger</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>#</td>
 | 
					 | 
				
			||||||
<td>random</td>
 | 
					 | 
				
			||||||
<td>scene loaded</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>#random</td>
 | 
					 | 
				
			||||||
<td>random</td>
 | 
					 | 
				
			||||||
<td>URL contains #random</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!random</td>
 | 
					 | 
				
			||||||
<td>day|noon|night</td>
 | 
					 | 
				
			||||||
<td>#random, # or click</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>day</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>noon</td>
 | 
					 | 
				
			||||||
<td>bg=0.5,0.5,0.5</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>night</td>
 | 
					 | 
				
			||||||
<td>bg=0,0,0&foo=2</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h2 id="usecase-present-context-menu-with-options">Usecase: present context menu with options</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!random</td>
 | 
					 | 
				
			||||||
<td>!day</td>
 | 
					 | 
				
			||||||
<td>!noon</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!day</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>clicked in contextmenu</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!noon</td>
 | 
					 | 
				
			||||||
<td>bg=0.5,0.5,0.5</td>
 | 
					 | 
				
			||||||
<td>clicked in contextmenu</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!night</td>
 | 
					 | 
				
			||||||
<td>bg=0,0,0&foo=2</td>
 | 
					 | 
				
			||||||
<td>clicked in contextmenu</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<blockquote>
 | 
					 | 
				
			||||||
<p>When interacting with an object with more than one <code>!</code>-macro, the XR Browser should offer a contextmenu to execute a macro.</p>
 | 
					 | 
				
			||||||
</blockquote>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>In a similar way, when <strong>any</strong> <code>!</code>-macro is present on the sceneroot, the XR Browser should offer a context-menu to execute those macro’s.</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h2 id="event-bubble-flow">Event Bubble-flow</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>click object with (<code>!clickme</code>:<code>AR</code> or <code>!clickme</code>: <code>!reset</code> e.g.)</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<pre><code>  ◻
 | 
					 | 
				
			||||||
  │  
 | 
					 | 
				
			||||||
  └── does current object contain this property-key (`AR` or `!reset` e.g.)?
 | 
					 | 
				
			||||||
         └── no: is there any (root)object containing property `AR`
 | 
					 | 
				
			||||||
           └── yes: evaluate its (roundrobin) XR macro-value(s) (and exit)
 | 
					 | 
				
			||||||
           └── no: trigger URL: #AR 
 | 
					 | 
				
			||||||
</code></pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>click object with (<code>!clickme</code>:<code>#AR|#VR</code> e.g.)</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<pre><code>  ◻
 | 
					 | 
				
			||||||
  │  
 | 
					 | 
				
			||||||
  └── apply the roundrobin (rotate the options, value `#AR` becomes `#VR` upon next click)
 | 
					 | 
				
			||||||
      └── is there any object with property-key (`#AR` e.g.)?
 | 
					 | 
				
			||||||
         └── no: just update the URL to `#AR`
 | 
					 | 
				
			||||||
           └── yes: apply its value to the scene, and update the URL to `#AR`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
 | 
					 | 
				
			||||||
</code></pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>◻
 | 
					 | 
				
			||||||
  │<br>
 | 
					 | 
				
			||||||
  └── apply the roundrobin (rotate the options, value <code>!foo</code> becomes <code>!bar</code> upon next click)
 | 
					 | 
				
			||||||
      └── is there any object with property-key (<code>!foo</code> e.g.)?
 | 
					 | 
				
			||||||
         └── no: do nothing
 | 
					 | 
				
			||||||
           └── yes: apply its value to the scene
 | 
					 | 
				
			||||||
“`</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<blockquote>
 | 
					 | 
				
			||||||
<p>Note that only macro’s can trigger roundrobin values or contextmenu’s, as well as roundrobin values never ending up in the toplevel URL.</p>
 | 
					 | 
				
			||||||
</blockquote>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 id="security-considerations">Security Considerations</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 id="iana-considerations">IANA Considerations</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<p>This document has no IANA actions.</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 id="acknowledgments">Acknowledgments</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<ul>
 | 
					 | 
				
			||||||
<li><a href="https://nlnet.nl">NLNET</a></li>
 | 
					 | 
				
			||||||
<li><a href="https://futureoftext.org">Future of Text</a></li>
 | 
					 | 
				
			||||||
<li><a href="https://visual-meta.info">visual-meta.info</a></li>
 | 
					 | 
				
			||||||
</ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h1 id="appendix-definitions">Appendix: Definitions</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>definition</th>
 | 
					 | 
				
			||||||
<th>explanation</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>scene</td>
 | 
					 | 
				
			||||||
<td>a (local/remote) 3D scene or 3D file (index.gltf e.g.)</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>3D object</td>
 | 
					 | 
				
			||||||
<td>an object inside a scene characterized by vertex-, face- and customproperty data.</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>XR fragments</td>
 | 
					 | 
				
			||||||
<td>URI Fragment with spatial hints like <code>#pos=0,0,0&t=1,100</code> e.g.</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>query</td>
 | 
					 | 
				
			||||||
<td>an URI Fragment-operator which queries object(s) from a scene like <code>#q=cube</code></td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>FPS</td>
 | 
					 | 
				
			||||||
<td>frames per second in spatial experiences (games,VR,AR e.g.), should be as high as possible</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><code>◻</code></td>
 | 
					 | 
				
			||||||
<td>ascii representation of an 3D object/mesh</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>(un)obtrusive</td>
 | 
					 | 
				
			||||||
<td>obtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,251 +0,0 @@
 | 
				
			||||||
%%%
 | 
					 | 
				
			||||||
Title = "XR Macros"
 | 
					 | 
				
			||||||
area = "Internet"
 | 
					 | 
				
			||||||
workgroup = "Internet Engineering Task Force"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[seriesInfo]
 | 
					 | 
				
			||||||
name = "XR-Macros"
 | 
					 | 
				
			||||||
value = "draft-XRMACROS-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% 20%;
 | 
					 | 
				
			||||||
    line-height: 30px;
 | 
					 | 
				
			||||||
    color:#555;
 | 
					 | 
				
			||||||
    background:#F0F0F3
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  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 Macros</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-XRMACROS-leonvankammen-00
 | 
					 | 
				
			||||||
</pre>  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}-->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.# Abstract
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This draft offers a specification for embedding macros in existing 3D scenes/assets, to offer simple interactions and configure the renderer further.<br>
 | 
					 | 
				
			||||||
Together with URI Fragments, it allows for rich immersive experiences without the need of a complicated sandboxed scripting languages.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> Almost every idea in this document is demonstrated at [https://xrfragment.org](https://xrfragment.org), as this spec was created during the [XR Fragments](https://xrfragment.org) spec.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{mainmatter}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Introduction
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
How can we add more features to existing text & 3D scenes, without introducing new dataformats?<br>
 | 
					 | 
				
			||||||
Historically, there's many attempts to create the ultimate markuplanguage or 3D fileformat.<br>
 | 
					 | 
				
			||||||
Their lowest common denominator is: (co)authoring using plain text.<br>
 | 
					 | 
				
			||||||
Therefore, XR Macros allows us to enrich/connect existing dataformats, by offering a polyglot notation based on existing notations:<br>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. getting/setting common used 3D properties using querystring- or JSON-notation 
 | 
					 | 
				
			||||||
1. targeting 3D properties using the lightweight query notation present in [XR Fragments](https://xrfragment.org)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Core principle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. XR Macros use querystrings, but are HTML-agnostic (though pseudo-XR Fragment browsers **can** be implemented on top of HTML/Javascript). 
 | 
					 | 
				
			||||||
1. An XR Macro is 3D metadata which starts with '!' (`!clickme: fog=0,10` e.g.)
 | 
					 | 
				
			||||||
1. Metadata-values can contain the `|` symbol to 🎲 roundrobin variable values (`!toggleme: fog=0,10|fog=0,1000` e.g.)
 | 
					 | 
				
			||||||
1. XR Macros acts as simple eventhandlers for URI Fragments: they are automatically published on the ([XR Fragments](https://xrfragment.org)) hashbus, to act as events (so more serious scripting languages can react to them as well).
 | 
					 | 
				
			||||||
1. XR Macros can assign object metadata (`!setlocal: foo=1` writes `foo:1` metadata to the object containing the `!setlocal` metadata)
 | 
					 | 
				
			||||||
1. XR Macros can assign global metadata  (`!setfoo: #foo=1` writes `foo:1` metadata to the root scene-node)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> These very simple principles allow for rich interactions and dynamic querying
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Conventions and Definitions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See appendix below in case certain terms are not clear.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# List of XR Macros 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(XR) Macros can be embedded in 3D assets/scenes.<br>
 | 
					 | 
				
			||||||
Macros enrich existing spatial content with a lowcode, limited logic-layer, by recursive (economic) use of the querystring syntax (which search engines and [XR Fragments](https://xrfragment.org) already uses.<br>
 | 
					 | 
				
			||||||
This is done by allowing string/integer variables, and the `|` symbol to roundrobin variable values.<br>
 | 
					 | 
				
			||||||
Macros also act as events, so more serious scripting languages can react to them as well.<br>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| key          | type     | example (JSON)         | function            | existing compatibility                 |
 | 
					 | 
				
			||||||
|--------------|----------|------------------------|---------------------|----------------------------------------|
 | 
					 | 
				
			||||||
| `@bg`        | string   | `"@bg":"#cube"`        | bg: binds fog near/far based to cube x/y/z (anim) values | custom property in 3D fileformats      |
 | 
					 | 
				
			||||||
| `@fog`       | string   | `"@fog":"#cube"`       | fog: binds fog near/far based to cube x/y (anim) values | custom property in 3D fileformats      |
 | 
					 | 
				
			||||||
| `@scroll`    | string   | `"@scroll":"#cube"`    | texturescrolling: binds texture x/y/rot based to cube x/y/z (anim) values | custom property in 3D fileformats      |
 | 
					 | 
				
			||||||
| `@emissive`  | string   | `"@emissive":"#cube"`  | day/night/mood: binds material's emissive value to cube x/y/z (anim) values | custom property in 3D fileformats      |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Usecase: click object
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| custom property | value                    | trigger when           |
 | 
					 | 
				
			||||||
|-----------------|--------------------------|------------------------|
 | 
					 | 
				
			||||||
| !clickme        | bg=1,1,1&foo=2           | object clicked         |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Usecase: conditional click object
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| custom property | value                    | trigger when                |
 | 
					 | 
				
			||||||
|-----------------|--------------------------|-----------------------------|
 | 
					 | 
				
			||||||
| #               | foo=1                    | scene                       |
 | 
					 | 
				
			||||||
| !clickme        | q=foo>2&bg=1,1,1         | object clicked and foo > 2  |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> when a user clicks an object with the custom properties above, it should set the backgroundcolor to `1,1,1` when `foo` is greater than `2` (see previous example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Usecase: click object (roundrobin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| custom property | value                    | trigger when           |
 | 
					 | 
				
			||||||
|-----------------|--------------------------|------------------------|
 | 
					 | 
				
			||||||
| !cycleme        | day|noon|night | object clicked         |
 | 
					 | 
				
			||||||
| day             | bg=1,1,1                 | roundrobin             |
 | 
					 | 
				
			||||||
| noon            | bg=0.5,0.5,0.5           | roundrobin             |
 | 
					 | 
				
			||||||
| night           | bg=0,0,0&foo=2           | roundrobin             |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> when a user clicks an object with the custom properties above, it should trigger either `day` `noon` or `night` in roundrobin fashion.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Usecase: click object or URI fragment, and scene load trigger
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| custom property | value                    | trigger when           |
 | 
					 | 
				
			||||||
|-----------------|--------------------------|------------------------|
 | 
					 | 
				
			||||||
| #               | random                   | scene loaded           |
 | 
					 | 
				
			||||||
| #random         | random                   | URL contains #random   |
 | 
					 | 
				
			||||||
| !random         | day|noon|night | #random, # or click    |
 | 
					 | 
				
			||||||
| day             | bg=1,1,1                 | roundrobin             |
 | 
					 | 
				
			||||||
| noon            | bg=0.5,0.5,0.5           | roundrobin             |
 | 
					 | 
				
			||||||
| night           | bg=0,0,0&foo=2           | roundrobin             |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Usecase: present context menu with options
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| custom property | value                    | trigger when           |
 | 
					 | 
				
			||||||
|-----------------|--------------------------|------------------------|
 | 
					 | 
				
			||||||
| !random         | !day|!noon|!night        | clicked in contextmenu |
 | 
					 | 
				
			||||||
| !day            | bg=1,1,1                 | clicked in contextmenu |
 | 
					 | 
				
			||||||
| !noon           | bg=0.5,0.5,0.5           | clicked in contextmenu |
 | 
					 | 
				
			||||||
| !night          | bg=0,0,0&foo=2           | clicked in contextmenu |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> When interacting with an object with more than one `!`-macro, the XR Browser should offer a contextmenu to execute a macro.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In a similar way, when **any** `!`-macro is present on the sceneroot, the XR Browser should offer a context-menu to execute those macro's.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Event Bubble-flow
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
click object with (`!clickme`:`AR` or `!clickme`: `!reset` e.g.)
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
  ◻
 | 
					 | 
				
			||||||
  │  
 | 
					 | 
				
			||||||
  └── does current object contain this property-key (`AR` or `!reset` e.g.)?
 | 
					 | 
				
			||||||
         └── no: is there any (root)object containing property `AR`
 | 
					 | 
				
			||||||
           └── yes: evaluate its (roundrobin) XR macro-value(s) (and exit)
 | 
					 | 
				
			||||||
           └── no: trigger URL: #AR 
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
click object with (`!clickme`:`#AR|#VR` e.g.)
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
  ◻
 | 
					 | 
				
			||||||
  │  
 | 
					 | 
				
			||||||
  └── apply the roundrobin (rotate the options, value `#AR` becomes `#VR` upon next click)
 | 
					 | 
				
			||||||
      └── is there any object with property-key (`#AR` e.g.)?
 | 
					 | 
				
			||||||
         └── no: just update the URL to `#AR`
 | 
					 | 
				
			||||||
           └── yes: apply its value to the scene, and update the URL to `#AR`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
  ◻
 | 
					 | 
				
			||||||
  │  
 | 
					 | 
				
			||||||
  └── apply the roundrobin (rotate the options, value `!foo` becomes `!bar` upon next click)
 | 
					 | 
				
			||||||
      └── is there any object with property-key (`!foo` e.g.)?
 | 
					 | 
				
			||||||
         └── no: do nothing 
 | 
					 | 
				
			||||||
           └── yes: apply its value to the scene
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> Note that only macro's can trigger roundrobin values or contextmenu's, as well as roundrobin values never ending up in the toplevel URL.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Security Considerations
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# IANA Considerations
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This document has no IANA actions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Acknowledgments
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [NLNET](https://nlnet.nl)
 | 
					 | 
				
			||||||
* [Future of Text](https://futureoftext.org)
 | 
					 | 
				
			||||||
* [visual-meta.info](https://visual-meta.info)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Appendix: Definitions 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
|definition            | explanation                                                                                                                   |
 | 
					 | 
				
			||||||
|----------------------|-------------------------------------------------------------------------------------------------------------------------------|
 | 
					 | 
				
			||||||
|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.                                             |
 | 
					 | 
				
			||||||
|XR fragments          | URI Fragment with spatial hints like `#pos=0,0,0&t=1,100` e.g.                                                                |
 | 
					 | 
				
			||||||
|query                 | an URI Fragment-operator which queries object(s) from a scene like `#q=cube`                                                  |
 | 
					 | 
				
			||||||
|FPS                   | frames per second in spatial experiences (games,VR,AR e.g.), should be as high as possible                                    |
 | 
					 | 
				
			||||||
|`◻`                   | 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       |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,392 +0,0 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Internet Engineering Task Force                          L.R. van Kammen
 | 
					 | 
				
			||||||
Internet-Draft                                         24 September 2025
 | 
					 | 
				
			||||||
Intended status: Informational                                          
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                               XR Macros
 | 
					 | 
				
			||||||
                    draft-XRMACROS-leonvankammen-00
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Abstract
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   This draft offers a specification for embedding macros in existing 3D
 | 
					 | 
				
			||||||
   scenes/assets, to offer simple interactions and configure the
 | 
					 | 
				
			||||||
   renderer further.
 | 
					 | 
				
			||||||
   Together with URI Fragments, it allows for rich immersive experiences
 | 
					 | 
				
			||||||
   without the need of a complicated sandboxed scripting languages.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Almost every idea in this document is demonstrated at
 | 
					 | 
				
			||||||
   https://xrfragment.org (https://xrfragment.org), as this spec was
 | 
					 | 
				
			||||||
   created during the XR Fragments (https://xrfragment.org) spec.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Status of This Memo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   This Internet-Draft is submitted in full conformance with the
 | 
					 | 
				
			||||||
   provisions of BCP 78 and BCP 79.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Internet-Drafts are working documents of the Internet Engineering
 | 
					 | 
				
			||||||
   Task Force (IETF).  Note that other groups may also distribute
 | 
					 | 
				
			||||||
   working documents as Internet-Drafts.  The list of current Internet-
 | 
					 | 
				
			||||||
   Drafts is at https://datatracker.ietf.org/drafts/current/.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Internet-Drafts are draft documents valid for a maximum of six months
 | 
					 | 
				
			||||||
   and may be updated, replaced, or obsoleted by other documents at any
 | 
					 | 
				
			||||||
   time.  It is inappropriate to use Internet-Drafts as reference
 | 
					 | 
				
			||||||
   material or to cite them other than as "work in progress."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   This Internet-Draft will expire on 28 March 2026.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Copyright Notice
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright (c) 2025 IETF Trust and the persons identified as the
 | 
					 | 
				
			||||||
   document authors.  All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   This document is subject to BCP 78 and the IETF Trust's Legal
 | 
					 | 
				
			||||||
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
 | 
					 | 
				
			||||||
   license-info) in effect on the date of publication of this document.
 | 
					 | 
				
			||||||
   Please review these documents carefully, as they describe your rights
 | 
					 | 
				
			||||||
   and restrictions with respect to this document.  Code Components
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
van Kammen                Expires 28 March 2026                 [Page 1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Internet-Draft                  XR Macros                 September 2025
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   extracted from this document must include Revised BSD License text as
 | 
					 | 
				
			||||||
   described in Section 4.e of the Trust Legal Provisions and are
 | 
					 | 
				
			||||||
   provided without warranty as described in the Revised BSD License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Table of Contents
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
 | 
					 | 
				
			||||||
   2.  Core principle  . . . . . . . . . . . . . . . . . . . . . . .   2
 | 
					 | 
				
			||||||
   3.  Conventions and Definitions . . . . . . . . . . . . . . . . .   3
 | 
					 | 
				
			||||||
   4.  List of XR Macros . . . . . . . . . . . . . . . . . . . . . .   3
 | 
					 | 
				
			||||||
     4.1.  Usecase: click object . . . . . . . . . . . . . . . . . .   4
 | 
					 | 
				
			||||||
     4.2.  Usecase: conditional click object . . . . . . . . . . . .   4
 | 
					 | 
				
			||||||
     4.3.  Usecase: click object (roundrobin)  . . . . . . . . . . .   5
 | 
					 | 
				
			||||||
     4.4.  Usecase: click object or URI fragment, and scene load
 | 
					 | 
				
			||||||
           trigger . . . . . . . . . . . . . . . . . . . . . . . . .   5
 | 
					 | 
				
			||||||
     4.5.  Usecase: present context menu with options  . . . . . . .   6
 | 
					 | 
				
			||||||
     4.6.  Event Bubble-flow . . . . . . . . . . . . . . . . . . . .   6
 | 
					 | 
				
			||||||
   5.  Security Considerations . . . . . . . . . . . . . . . . . . .   7
 | 
					 | 
				
			||||||
   6.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .   7
 | 
					 | 
				
			||||||
   7.  Acknowledgments . . . . . . . . . . . . . . . . . . . . . . .   7
 | 
					 | 
				
			||||||
   8.  Appendix: Definitions . . . . . . . . . . . . . . . . . . . .   7
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.  Introduction
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   How can we add more features to existing text & 3D scenes, without
 | 
					 | 
				
			||||||
   introducing new dataformats?
 | 
					 | 
				
			||||||
   Historically, there's many attempts to create the ultimate
 | 
					 | 
				
			||||||
   markuplanguage or 3D fileformat.
 | 
					 | 
				
			||||||
   Their lowest common denominator is: (co)authoring using plain text.
 | 
					 | 
				
			||||||
   Therefore, XR Macros allows us to enrich/connect existing
 | 
					 | 
				
			||||||
   dataformats, by offering a polyglot notation based on existing
 | 
					 | 
				
			||||||
   notations:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   1.  getting/setting common used 3D properties using querystring- or
 | 
					 | 
				
			||||||
       JSON-notation
 | 
					 | 
				
			||||||
   2.  targeting 3D properties using the lightweight query notation
 | 
					 | 
				
			||||||
       present in XR Fragments (https://xrfragment.org)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   |  NOTE: The chapters in this document are ordered from highlevel to
 | 
					 | 
				
			||||||
   |  lowlevel (technical) as much as possible
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.  Core principle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   1.  XR Macros use querystrings, but are HTML-agnostic (though pseudo-
 | 
					 | 
				
			||||||
       XR Fragment browsers *can* be implemented on top of HTML/
 | 
					 | 
				
			||||||
       Javascript).
 | 
					 | 
				
			||||||
   2.  An XR Macro is 3D metadata which starts with '!' (!clickme:
 | 
					 | 
				
			||||||
       fog=0,10 e.g.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
van Kammen                Expires 28 March 2026                 [Page 2]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Internet-Draft                  XR Macros                 September 2025
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   3.  Metadata-values can contain the | symbol to 🎲 roundrobin variable
 | 
					 | 
				
			||||||
       values (!toggleme: fog=0,10|fog=0,1000 e.g.)
 | 
					 | 
				
			||||||
   4.  XR Macros acts as simple eventhandlers for URI Fragments: they
 | 
					 | 
				
			||||||
       are automatically published on the (XR Fragments
 | 
					 | 
				
			||||||
       (https://xrfragment.org)) hashbus, to act as events (so more
 | 
					 | 
				
			||||||
       serious scripting languages can react to them as well).
 | 
					 | 
				
			||||||
   5.  XR Macros can assign object metadata (!setlocal: foo=1 writes
 | 
					 | 
				
			||||||
       foo:1 metadata to the object containing the !setlocal metadata)
 | 
					 | 
				
			||||||
   6.  XR Macros can assign global metadata (!setfoo: #foo=1 writes
 | 
					 | 
				
			||||||
       foo:1 metadata to the root scene-node)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   |  These very simple principles allow for rich interactions and
 | 
					 | 
				
			||||||
   |  dynamic querying
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
3.  Conventions and Definitions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   See appendix below in case certain terms are not clear.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4.  List of XR Macros
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   (XR) Macros can be embedded in 3D assets/scenes.
 | 
					 | 
				
			||||||
   Macros enrich existing spatial content with a lowcode, limited logic-
 | 
					 | 
				
			||||||
   layer, by recursive (economic) use of the querystring syntax (which
 | 
					 | 
				
			||||||
   search engines and XR Fragments (https://xrfragment.org) already
 | 
					 | 
				
			||||||
   uses.
 | 
					 | 
				
			||||||
   This is done by allowing string/integer variables, and the | symbol
 | 
					 | 
				
			||||||
   to roundrobin variable values.
 | 
					 | 
				
			||||||
   Macros also act as events, so more serious scripting languages can
 | 
					 | 
				
			||||||
   react to them as well.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
van Kammen                Expires 28 March 2026                 [Page 3]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Internet-Draft                  XR Macros                 September 2025
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   +=========+======+===================+=================+=============+
 | 
					 | 
				
			||||||
   |key      |type  |example (JSON)     |function         |existing     |
 | 
					 | 
				
			||||||
   |         |      |                   |                 |compatibility|
 | 
					 | 
				
			||||||
   +=========+======+===================+=================+=============+
 | 
					 | 
				
			||||||
   |@bg      |string|"@bg":"#cube"      |bg: binds fog    |custom       |
 | 
					 | 
				
			||||||
   |         |      |                   |near/far based to|property in  |
 | 
					 | 
				
			||||||
   |         |      |                   |cube x/y/z (anim)|3D           |
 | 
					 | 
				
			||||||
   |         |      |                   |values           |fileformats  |
 | 
					 | 
				
			||||||
   +---------+------+-------------------+-----------------+-------------+
 | 
					 | 
				
			||||||
   |@fog     |string|"@fog":"#cube"     |fog: binds fog   |custom       |
 | 
					 | 
				
			||||||
   |         |      |                   |near/far based to|property in  |
 | 
					 | 
				
			||||||
   |         |      |                   |cube x/y (anim)  |3D           |
 | 
					 | 
				
			||||||
   |         |      |                   |values           |fileformats  |
 | 
					 | 
				
			||||||
   +---------+------+-------------------+-----------------+-------------+
 | 
					 | 
				
			||||||
   |@scroll  |string|"@scroll":"#cube"  |texturescrolling:|custom       |
 | 
					 | 
				
			||||||
   |         |      |                   |binds texture    |property in  |
 | 
					 | 
				
			||||||
   |         |      |                   |x/y/rot based to |3D           |
 | 
					 | 
				
			||||||
   |         |      |                   |cube x/y/z (anim)|fileformats  |
 | 
					 | 
				
			||||||
   |         |      |                   |values           |             |
 | 
					 | 
				
			||||||
   +---------+------+-------------------+-----------------+-------------+
 | 
					 | 
				
			||||||
   |@emissive|string|"@emissive":"#cube"|day/night/mood:  |custom       |
 | 
					 | 
				
			||||||
   |         |      |                   |binds material's |property in  |
 | 
					 | 
				
			||||||
   |         |      |                   |emissive value to|3D           |
 | 
					 | 
				
			||||||
   |         |      |                   |cube x/y/z (anim)|fileformats  |
 | 
					 | 
				
			||||||
   |         |      |                   |values           |             |
 | 
					 | 
				
			||||||
   +---------+------+-------------------+-----------------+-------------+
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                  Table 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4.1.  Usecase: click object
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
           +=================+================+================+
 | 
					 | 
				
			||||||
           | custom property | value          | trigger when   |
 | 
					 | 
				
			||||||
           +=================+================+================+
 | 
					 | 
				
			||||||
           | !clickme        | bg=1,1,1&foo=2 | object clicked |
 | 
					 | 
				
			||||||
           +-----------------+----------------+----------------+
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                  Table 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4.2.  Usecase: conditional click object
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    +=================+==================+============================+
 | 
					 | 
				
			||||||
    | custom property | value            | trigger when               |
 | 
					 | 
				
			||||||
    +=================+==================+============================+
 | 
					 | 
				
			||||||
    | #               | foo=1            | scene                      |
 | 
					 | 
				
			||||||
    +-----------------+------------------+----------------------------+
 | 
					 | 
				
			||||||
    | !clickme        | q=foo>2&bg=1,1,1 | object clicked and foo > 2 |
 | 
					 | 
				
			||||||
    +-----------------+------------------+----------------------------+
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
van Kammen                Expires 28 March 2026                 [Page 4]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Internet-Draft                  XR Macros                 September 2025
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                  Table 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   |  when a user clicks an object with the custom properties above, it
 | 
					 | 
				
			||||||
   |  should set the backgroundcolor to 1,1,1 when foo is greater than 2
 | 
					 | 
				
			||||||
   |  (see previous example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4.3.  Usecase: click object (roundrobin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
           +=================+================+================+
 | 
					 | 
				
			||||||
           | custom property | value          | trigger when   |
 | 
					 | 
				
			||||||
           +=================+================+================+
 | 
					 | 
				
			||||||
           | !cycleme        | day|noon|night | object clicked |
 | 
					 | 
				
			||||||
           +-----------------+----------------+----------------+
 | 
					 | 
				
			||||||
           | day             | bg=1,1,1       | roundrobin     |
 | 
					 | 
				
			||||||
           +-----------------+----------------+----------------+
 | 
					 | 
				
			||||||
           | noon            | bg=0.5,0.5,0.5 | roundrobin     |
 | 
					 | 
				
			||||||
           +-----------------+----------------+----------------+
 | 
					 | 
				
			||||||
           | night           | bg=0,0,0&foo=2 | roundrobin     |
 | 
					 | 
				
			||||||
           +-----------------+----------------+----------------+
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                  Table 4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   |  when a user clicks an object with the custom properties above, it
 | 
					 | 
				
			||||||
   |  should trigger either day noon or night in roundrobin fashion.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4.4.  Usecase: click object or URI fragment, and scene load trigger
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        +=================+================+======================+
 | 
					 | 
				
			||||||
        | custom property | value          | trigger when         |
 | 
					 | 
				
			||||||
        +=================+================+======================+
 | 
					 | 
				
			||||||
        | #               | random         | scene loaded         |
 | 
					 | 
				
			||||||
        +-----------------+----------------+----------------------+
 | 
					 | 
				
			||||||
        | #random         | random         | URL contains #random |
 | 
					 | 
				
			||||||
        +-----------------+----------------+----------------------+
 | 
					 | 
				
			||||||
        | !random         | day|noon|night | #random, # or click  |
 | 
					 | 
				
			||||||
        +-----------------+----------------+----------------------+
 | 
					 | 
				
			||||||
        | day             | bg=1,1,1       | roundrobin           |
 | 
					 | 
				
			||||||
        +-----------------+----------------+----------------------+
 | 
					 | 
				
			||||||
        | noon            | bg=0.5,0.5,0.5 | roundrobin           |
 | 
					 | 
				
			||||||
        +-----------------+----------------+----------------------+
 | 
					 | 
				
			||||||
        | night           | bg=0,0,0&foo=2 | roundrobin           |
 | 
					 | 
				
			||||||
        +-----------------+----------------+----------------------+
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                  Table 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
van Kammen                Expires 28 March 2026                 [Page 5]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Internet-Draft                  XR Macros                 September 2025
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4.5.  Usecase: present context menu with options
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       +=================+================+========================+
 | 
					 | 
				
			||||||
       | custom property | value          | trigger when           |
 | 
					 | 
				
			||||||
       +=================+================+========================+
 | 
					 | 
				
			||||||
       | !random         | !day           | !noon                  |
 | 
					 | 
				
			||||||
       +-----------------+----------------+------------------------+
 | 
					 | 
				
			||||||
       | !day            | bg=1,1,1       | clicked in contextmenu |
 | 
					 | 
				
			||||||
       +-----------------+----------------+------------------------+
 | 
					 | 
				
			||||||
       | !noon           | bg=0.5,0.5,0.5 | clicked in contextmenu |
 | 
					 | 
				
			||||||
       +-----------------+----------------+------------------------+
 | 
					 | 
				
			||||||
       | !night          | bg=0,0,0&foo=2 | clicked in contextmenu |
 | 
					 | 
				
			||||||
       +-----------------+----------------+------------------------+
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                  Table 6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   |  When interacting with an object with more than one !-macro, the XR
 | 
					 | 
				
			||||||
   |  Browser should offer a contextmenu to execute a macro.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   In a similar way, when *any* !-macro is present on the sceneroot, the
 | 
					 | 
				
			||||||
   XR Browser should offer a context-menu to execute those macro's.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4.6.  Event Bubble-flow
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   click object with (!clickme:AR or !clickme: !reset e.g.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ◻
 | 
					 | 
				
			||||||
  │
 | 
					 | 
				
			||||||
  └── does current object contain this property-key (`AR` or `!reset` e.g.)?
 | 
					 | 
				
			||||||
         └── no: is there any (root)object containing property `AR`
 | 
					 | 
				
			||||||
           └── yes: evaluate its (roundrobin) XR macro-value(s) (and exit)
 | 
					 | 
				
			||||||
           └── no: trigger URL: #AR
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   click object with (!clickme:#AR|#VR e.g.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ◻
 | 
					 | 
				
			||||||
  │
 | 
					 | 
				
			||||||
  └── apply the roundrobin (rotate the options, value `#AR` becomes `#VR` upon next click)
 | 
					 | 
				
			||||||
      └── is there any object with property-key (`#AR` e.g.)?
 | 
					 | 
				
			||||||
         └── no: just update the URL to `#AR`
 | 
					 | 
				
			||||||
           └── yes: apply its value to the scene, and update the URL to `#AR`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   ◻ │
 | 
					 | 
				
			||||||
   └── apply the roundrobin (rotate the options, value !foo becomes !bar
 | 
					 | 
				
			||||||
   upon next click) └── is there any object with property-key (!foo
 | 
					 | 
				
			||||||
   e.g.)?  └── no: do nothing └── yes: apply its value to the scene ```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
van Kammen                Expires 28 March 2026                 [Page 6]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Internet-Draft                  XR Macros                 September 2025
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   |  Note that only macro's can trigger roundrobin values or
 | 
					 | 
				
			||||||
   |  contextmenu's, as well as roundrobin values never ending up in the
 | 
					 | 
				
			||||||
   |  toplevel URL.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
5.  Security Considerations
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
6.  IANA Considerations
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   This document has no IANA actions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
7.  Acknowledgments
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   *  NLNET (https://nlnet.nl)
 | 
					 | 
				
			||||||
   *  Future of Text (https://futureoftext.org)
 | 
					 | 
				
			||||||
   *  visual-meta.info (https://visual-meta.info)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
8.  Appendix: Definitions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   +===============+===================================================+
 | 
					 | 
				
			||||||
   | definition    | explanation                                       |
 | 
					 | 
				
			||||||
   +===============+===================================================+
 | 
					 | 
				
			||||||
   | 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.           |
 | 
					 | 
				
			||||||
   +---------------+---------------------------------------------------+
 | 
					 | 
				
			||||||
   | XR fragments  | URI Fragment with spatial hints like              |
 | 
					 | 
				
			||||||
   |               | #pos=0,0,0&t=1,100 e.g.                           |
 | 
					 | 
				
			||||||
   +---------------+---------------------------------------------------+
 | 
					 | 
				
			||||||
   | query         | an URI Fragment-operator which queries            |
 | 
					 | 
				
			||||||
   |               | object(s) from a scene like #q=cube               |
 | 
					 | 
				
			||||||
   +---------------+---------------------------------------------------+
 | 
					 | 
				
			||||||
   | FPS           | frames per second in spatial experiences          |
 | 
					 | 
				
			||||||
   |               | (games,VR,AR e.g.), should be as high as          |
 | 
					 | 
				
			||||||
   |               | possible                                          |
 | 
					 | 
				
			||||||
   +---------------+---------------------------------------------------+
 | 
					 | 
				
			||||||
   | ◻             | 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              |
 | 
					 | 
				
			||||||
   +---------------+---------------------------------------------------+
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                  Table 7
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
van Kammen                Expires 28 March 2026                 [Page 7]
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,381 +0,0 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					 | 
				
			||||||
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
 | 
					 | 
				
			||||||
<rfc version="3" ipr="trust200902" docName="draft-XRMACROS-leonvankammen-00" submissionType="IETF" category="info" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true" consensus="true">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<front>
 | 
					 | 
				
			||||||
<title>XR Macros</title><seriesInfo value="draft-XRMACROS-leonvankammen-00" stream="IETF" status="informational" name="XR-Macros"></seriesInfo>
 | 
					 | 
				
			||||||
<author initials="L.R." surname="van Kammen" fullname="L.R. van Kammen"><organization></organization><address><postal><street></street>
 | 
					 | 
				
			||||||
</postal></address></author><date/>
 | 
					 | 
				
			||||||
<area>Internet</area>
 | 
					 | 
				
			||||||
<workgroup>Internet Engineering Task Force</workgroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<abstract>
 | 
					 | 
				
			||||||
<t>This draft offers a specification for embedding macros in existing 3D scenes/assets, to offer simple interactions and configure the renderer further.<br />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Together with URI Fragments, it allows for rich immersive experiences without the need of a complicated sandboxed scripting languages.</t>
 | 
					 | 
				
			||||||
<t>Almost every idea in this document is demonstrated at <eref target="https://xrfragment.org">https://xrfragment.org</eref>, as this spec was created during the <eref target="https://xrfragment.org">XR Fragments</eref> spec.</t>
 | 
					 | 
				
			||||||
</abstract>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</front>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<middle>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="introduction"><name>Introduction</name>
 | 
					 | 
				
			||||||
<t>How can we add more features to existing text & 3D scenes, without introducing new dataformats?<br />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Historically, there's many attempts to create the ultimate markuplanguage or 3D fileformat.<br />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Their lowest common denominator is: (co)authoring using plain text.<br />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Therefore, XR Macros allows us to enrich/connect existing dataformats, by offering a polyglot notation based on existing notations:<br />
 | 
					 | 
				
			||||||
</t>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<ol spacing="compact">
 | 
					 | 
				
			||||||
<li>getting/setting common used 3D properties using querystring- or JSON-notation</li>
 | 
					 | 
				
			||||||
<li>targeting 3D properties using the lightweight query notation present in <eref target="https://xrfragment.org">XR Fragments</eref></li>
 | 
					 | 
				
			||||||
</ol>
 | 
					 | 
				
			||||||
<blockquote><t>NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible</t>
 | 
					 | 
				
			||||||
</blockquote></section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="core-principle"><name>Core principle</name>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<ol spacing="compact">
 | 
					 | 
				
			||||||
<li>XR Macros use querystrings, but are HTML-agnostic (though pseudo-XR Fragment browsers <strong>can</strong> be implemented on top of HTML/Javascript).</li>
 | 
					 | 
				
			||||||
<li>An XR Macro is 3D metadata which starts with '!' (<tt>!clickme: fog=0,10</tt> e.g.)</li>
 | 
					 | 
				
			||||||
<li>Metadata-values can contain the <tt>|</tt> symbol to 🎲 roundrobin variable values (<tt>!toggleme: fog=0,10|fog=0,1000</tt> e.g.)</li>
 | 
					 | 
				
			||||||
<li>XR Macros acts as simple eventhandlers for URI Fragments: they are automatically published on the (<eref target="https://xrfragment.org">XR Fragments</eref>) hashbus, to act as events (so more serious scripting languages can react to them as well).</li>
 | 
					 | 
				
			||||||
<li>XR Macros can assign object metadata (<tt>!setlocal: foo=1</tt> writes <tt>foo:1</tt> metadata to the object containing the <tt>!setlocal</tt> metadata)</li>
 | 
					 | 
				
			||||||
<li>XR Macros can assign global metadata  (<tt>!setfoo: #foo=1</tt> writes <tt>foo:1</tt> metadata to the root scene-node)</li>
 | 
					 | 
				
			||||||
</ol>
 | 
					 | 
				
			||||||
<blockquote><t>These very simple principles allow for rich interactions and dynamic querying</t>
 | 
					 | 
				
			||||||
</blockquote></section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="conventions-and-definitions"><name>Conventions and Definitions</name>
 | 
					 | 
				
			||||||
<t>See appendix below in case certain terms are not clear.</t>
 | 
					 | 
				
			||||||
</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="list-of-xr-macros"><name>List of XR Macros</name>
 | 
					 | 
				
			||||||
<t>(XR) Macros can be embedded in 3D assets/scenes.<br />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Macros enrich existing spatial content with a lowcode, limited logic-layer, by recursive (economic) use of the querystring syntax (which search engines and <eref target="https://xrfragment.org">XR Fragments</eref> already uses.<br />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is done by allowing string/integer variables, and the <tt>|</tt> symbol to roundrobin variable values.<br />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Macros also act as events, so more serious scripting languages can react to them as well.<br />
 | 
					 | 
				
			||||||
</t>
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>key</th>
 | 
					 | 
				
			||||||
<th>type</th>
 | 
					 | 
				
			||||||
<th>example (JSON)</th>
 | 
					 | 
				
			||||||
<th>function</th>
 | 
					 | 
				
			||||||
<th>existing compatibility</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><tt>@bg</tt></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><tt>"@bg":"#cube"</tt></td>
 | 
					 | 
				
			||||||
<td>bg: binds fog near/far based to cube x/y/z (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><tt>@fog</tt></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><tt>"@fog":"#cube"</tt></td>
 | 
					 | 
				
			||||||
<td>fog: binds fog near/far based to cube x/y (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><tt>@scroll</tt></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><tt>"@scroll":"#cube"</tt></td>
 | 
					 | 
				
			||||||
<td>texturescrolling: binds texture x/y/rot based to cube x/y/z (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><tt>@emissive</tt></td>
 | 
					 | 
				
			||||||
<td>string</td>
 | 
					 | 
				
			||||||
<td><tt>"@emissive":"#cube"</tt></td>
 | 
					 | 
				
			||||||
<td>day/night/mood: binds material's emissive value to cube x/y/z (anim) values</td>
 | 
					 | 
				
			||||||
<td>custom property in 3D fileformats</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
<section anchor="usecase-click-object"><name>Usecase: click object</name>
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!clickme</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1&foo=2</td>
 | 
					 | 
				
			||||||
<td>object clicked</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table></section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="usecase-conditional-click-object"><name>Usecase: conditional click object</name>
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>#</td>
 | 
					 | 
				
			||||||
<td>foo=1</td>
 | 
					 | 
				
			||||||
<td>scene</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!clickme</td>
 | 
					 | 
				
			||||||
<td>q=foo>2&bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>object clicked and foo > 2</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table><blockquote><t>when a user clicks an object with the custom properties above, it should set the backgroundcolor to <tt>1,1,1</tt> when <tt>foo</tt> is greater than <tt>2</tt> (see previous example)</t>
 | 
					 | 
				
			||||||
</blockquote></section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="usecase-click-object-roundrobin"><name>Usecase: click object (roundrobin)</name>
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!cycleme</td>
 | 
					 | 
				
			||||||
<td>day|noon|night</td>
 | 
					 | 
				
			||||||
<td>object clicked</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>day</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>noon</td>
 | 
					 | 
				
			||||||
<td>bg=0.5,0.5,0.5</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>night</td>
 | 
					 | 
				
			||||||
<td>bg=0,0,0&foo=2</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table><blockquote><t>when a user clicks an object with the custom properties above, it should trigger either <tt>day</tt> <tt>noon</tt> or <tt>night</tt> in roundrobin fashion.</t>
 | 
					 | 
				
			||||||
</blockquote></section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="usecase-click-object-or-uri-fragment-and-scene-load-trigger"><name>Usecase: click object or URI fragment, and scene load trigger</name>
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>#</td>
 | 
					 | 
				
			||||||
<td>random</td>
 | 
					 | 
				
			||||||
<td>scene loaded</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>#random</td>
 | 
					 | 
				
			||||||
<td>random</td>
 | 
					 | 
				
			||||||
<td>URL contains #random</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!random</td>
 | 
					 | 
				
			||||||
<td>day|noon|night</td>
 | 
					 | 
				
			||||||
<td>#random, # or click</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>day</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>noon</td>
 | 
					 | 
				
			||||||
<td>bg=0.5,0.5,0.5</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>night</td>
 | 
					 | 
				
			||||||
<td>bg=0,0,0&foo=2</td>
 | 
					 | 
				
			||||||
<td>roundrobin</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table></section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="usecase-present-context-menu-with-options"><name>Usecase: present context menu with options</name>
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>custom property</th>
 | 
					 | 
				
			||||||
<th>value</th>
 | 
					 | 
				
			||||||
<th>trigger when</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!random</td>
 | 
					 | 
				
			||||||
<td>!day</td>
 | 
					 | 
				
			||||||
<td>!noon</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!day</td>
 | 
					 | 
				
			||||||
<td>bg=1,1,1</td>
 | 
					 | 
				
			||||||
<td>clicked in contextmenu</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!noon</td>
 | 
					 | 
				
			||||||
<td>bg=0.5,0.5,0.5</td>
 | 
					 | 
				
			||||||
<td>clicked in contextmenu</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>!night</td>
 | 
					 | 
				
			||||||
<td>bg=0,0,0&foo=2</td>
 | 
					 | 
				
			||||||
<td>clicked in contextmenu</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table><blockquote><t>When interacting with an object with more than one <tt>!</tt>-macro, the XR Browser should offer a contextmenu to execute a macro.</t>
 | 
					 | 
				
			||||||
</blockquote><t>In a similar way, when <strong>any</strong> <tt>!</tt>-macro is present on the sceneroot, the XR Browser should offer a context-menu to execute those macro's.</t>
 | 
					 | 
				
			||||||
</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="event-bubble-flow"><name>Event Bubble-flow</name>
 | 
					 | 
				
			||||||
<t>click object with (<tt>!clickme</tt>:<tt>AR</tt> or <tt>!clickme</tt>: <tt>!reset</tt> e.g.)</t>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<artwork><![CDATA[  ◻
 | 
					 | 
				
			||||||
  │  
 | 
					 | 
				
			||||||
  └── does current object contain this property-key (`AR` or `!reset` e.g.)?
 | 
					 | 
				
			||||||
         └── no: is there any (root)object containing property `AR`
 | 
					 | 
				
			||||||
           └── yes: evaluate its (roundrobin) XR macro-value(s) (and exit)
 | 
					 | 
				
			||||||
           └── no: trigger URL: #AR 
 | 
					 | 
				
			||||||
]]>
 | 
					 | 
				
			||||||
</artwork>
 | 
					 | 
				
			||||||
<t>click object with (<tt>!clickme</tt>:<tt>#AR|#VR</tt> e.g.)</t>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<artwork><![CDATA[  ◻
 | 
					 | 
				
			||||||
  │  
 | 
					 | 
				
			||||||
  └── apply the roundrobin (rotate the options, value `#AR` becomes `#VR` upon next click)
 | 
					 | 
				
			||||||
      └── is there any object with property-key (`#AR` e.g.)?
 | 
					 | 
				
			||||||
         └── no: just update the URL to `#AR`
 | 
					 | 
				
			||||||
           └── yes: apply its value to the scene, and update the URL to `#AR`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
 | 
					 | 
				
			||||||
]]>
 | 
					 | 
				
			||||||
</artwork>
 | 
					 | 
				
			||||||
<t>◻
 | 
					 | 
				
			||||||
  │<br />
 | 
					 | 
				
			||||||
  └── apply the roundrobin (rotate the options, value <tt>!foo</tt> becomes <tt>!bar</tt> upon next click)
 | 
					 | 
				
			||||||
      └── is there any object with property-key (<tt>!foo</tt> e.g.)?
 | 
					 | 
				
			||||||
         └── no: do nothing
 | 
					 | 
				
			||||||
           └── yes: apply its value to the scene
 | 
					 | 
				
			||||||
```</t>
 | 
					 | 
				
			||||||
<blockquote><t>Note that only macro's can trigger roundrobin values or contextmenu's, as well as roundrobin values never ending up in the toplevel URL.</t>
 | 
					 | 
				
			||||||
</blockquote></section>
 | 
					 | 
				
			||||||
</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="security-considerations"><name>Security Considerations</name>
 | 
					 | 
				
			||||||
</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="iana-considerations"><name>IANA Considerations</name>
 | 
					 | 
				
			||||||
<t>This document has no IANA actions.</t>
 | 
					 | 
				
			||||||
</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="acknowledgments"><name>Acknowledgments</name>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<ul spacing="compact">
 | 
					 | 
				
			||||||
<li><eref target="https://nlnet.nl">NLNET</eref></li>
 | 
					 | 
				
			||||||
<li><eref target="https://futureoftext.org">Future of Text</eref></li>
 | 
					 | 
				
			||||||
<li><eref target="https://visual-meta.info">visual-meta.info</eref></li>
 | 
					 | 
				
			||||||
</ul>
 | 
					 | 
				
			||||||
</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<section anchor="appendix-definitions"><name>Appendix: Definitions</name>
 | 
					 | 
				
			||||||
<table>
 | 
					 | 
				
			||||||
<thead>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<th>definition</th>
 | 
					 | 
				
			||||||
<th>explanation</th>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</thead>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tbody>
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>scene</td>
 | 
					 | 
				
			||||||
<td>a (local/remote) 3D scene or 3D file (index.gltf e.g.)</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>3D object</td>
 | 
					 | 
				
			||||||
<td>an object inside a scene characterized by vertex-, face- and customproperty data.</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>XR fragments</td>
 | 
					 | 
				
			||||||
<td>URI Fragment with spatial hints like <tt>#pos=0,0,0&t=1,100</tt> e.g.</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>query</td>
 | 
					 | 
				
			||||||
<td>an URI Fragment-operator which queries object(s) from a scene like <tt>#q=cube</tt></td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>FPS</td>
 | 
					 | 
				
			||||||
<td>frames per second in spatial experiences (games,VR,AR e.g.), should be as high as possible</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td><tt>◻</tt></td>
 | 
					 | 
				
			||||||
<td>ascii representation of an 3D object/mesh</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<tr>
 | 
					 | 
				
			||||||
<td>(un)obtrusive</td>
 | 
					 | 
				
			||||||
<td>obtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words</td>
 | 
					 | 
				
			||||||
</tr>
 | 
					 | 
				
			||||||
</tbody>
 | 
					 | 
				
			||||||
</table></section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</middle>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</rfc>
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								index.html
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								index.html
									
										
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		
		Reference in a new issue