<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 <ereftarget="https://xrfragment.org">https://xrfragment.org</eref>, as this spec was created during the <ereftarget="https://xrfragment.org">XR Fragments</eref> spec.</t>
<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 (<ereftarget="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>
<sectionanchor="conventions-and-definitions"><name>Conventions and Definitions</name>
<t>See appendix below in case certain terms are not clear.</t>
</section>
<sectionanchor="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 <ereftarget="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/>
</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>
</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>
<sectionanchor="usecase-click-object-or-uri-fragment-and-scene-load-trigger"><name>Usecase: click object or URI fragment, and scene load trigger</name>
</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>
<t>click object with (<tt>!clickme</tt>:<tt>AR</tt> or <tt>!clickme</tt>: <tt>!reset</tt> e.g.)</t>
<artwork> ◻
│
└── 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> ◻
│
└── 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>