update documentation
This commit is contained in:
parent
267c9d3155
commit
6ffd8a5d81
|
@ -81,8 +81,8 @@ value: draft-XRFRAGMENTS-leonvankammen-00
|
|||
<h1 class="special" id="abstract">Abstract</h1>
|
||||
|
||||
<p>This draft is a specification for 4D URLs & <a href="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> navigation, which links together space, time & text together, for hypermedia browsers with- or without a network-connection.<br>
|
||||
The specification promotes spatial addressibility, sharing, navigation, query-ing and annotating interactive (text)objects across for (XR) Browsers.<br>
|
||||
XR Fragments allows us to enrich existing dataformats, by recursive use of existing proven technologies like <a href="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a> and BibTags notation.<br></p>
|
||||
The specification promotes spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.<br>
|
||||
XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like <a href="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a>.</p>
|
||||
|
||||
<blockquote>
|
||||
<p>Almost every idea in this document is demonstrated at <a href="https://xrfragment.org">https://xrfragment.org</a></p>
|
||||
|
@ -90,14 +90,18 @@ XR Fragments allows us to enrich existing dataformats, by recursive use of exist
|
|||
<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>
|
||||
<p>How can we add more control to existing text & 3D scenes, without introducing new dataformats?<br>
|
||||
Historically, there’s many attempts to create the ultimate markuplanguage or 3D fileformat.<br>
|
||||
The lowest common denominator is: describing/tagging/naming nodes using <strong>plain text</strong>.<br>
|
||||
XR Fragments allows us to enrich/connect existing dataformats, by introducing existing technologies/ideas:<br></p>
|
||||
The lowest common denominator is: designers describing/tagging/naming things using <strong>plain text</strong>.<br>
|
||||
XR Fragments exploits the fact that all 3D models already contain such metadata:</p>
|
||||
|
||||
<p><strong>XR Fragments allows controlling of metadata in 3D scene(files) using URLs</strong></p>
|
||||
|
||||
<p>Or more detailed:</p>
|
||||
|
||||
<ol>
|
||||
<li>addressibility and <a href="https://github.com/coderofsalvation/hypermediatic">hypermediatic</a> navigation of 3D scenes/objects: <a href="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a> + src/href spatial metadata</li>
|
||||
<li>Interlinking text/& 3D by collapsing space into a Word Graph (XRWG) to show <a href="#visible-links">visible links</a> (and augmenting text with <a href="https://github.com/coderofsalvation/tagbibs">bibs</a> / <a href="https://en.wikipedia.org/wiki/BibTeX">BibTags</a> appendices (see <a href="https://visual-meta.info">visual-meta</a> e.g.)</li>
|
||||
<li>Interlinking (text)objects by collapsing space into a Word Graph (XRWG) to show <a href="#visible-links">visible links</a></li>
|
||||
<li>unlocking spatial potential of the (originally 2D) hashtag (which jumps to a chapter) for navigating XR documents</li>
|
||||
</ol>
|
||||
|
||||
|
@ -107,10 +111,10 @@ XR Fragments allows us to enrich/connect existing dataformats, by introducing ex
|
|||
|
||||
<h1 id="core-principle">Core principle</h1>
|
||||
|
||||
<p>XR Fragments strives to serve (nontechnical/fuzzy) humans first, and machine(implementations) later, by ensuring hasslefree text-vs-thought feedback loops.<br>
|
||||
This also means that the repair-ability of machine-matters should be human friendly too (not too complex).<br>
|
||||
XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.<br>
|
||||
Instead of combining them (in a game-editor e.g.), XR Fragments is opting for a more integrated path <strong>towards</strong> them, by describing how to make browsers <strong>4D URL-ready</strong>:</p>
|
||||
<p><strong>XR Fragments allows controlling of metadata in 3D scene(files) using URLs</strong></p>
|
||||
|
||||
<p>XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.<br>
|
||||
Instead of combining them (in a game-editor e.g.), XR Fragments <strong>integrates all</strong>, by collecting metadata into an XRWG and control it via URL:</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -130,14 +134,8 @@ Instead of combining them (in a game-editor e.g.), XR Fragments is opting for a
|
|||
|
||||
<tr>
|
||||
<td>the hashbus</td>
|
||||
<td>hashtags map to camera/scene-projections</td>
|
||||
<td>hashtags map to document positions</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>spacetime hashtags</td>
|
||||
<td>positions camera, triggers scene-preset/time</td>
|
||||
<td>jumps/scrolls to chapter</td>
|
||||
<td>hashtags alter camera/scene/object-projections</td>
|
||||
<td>hashtags alter document positions</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -154,20 +152,26 @@ Instead of combining them (in a game-editor e.g.), XR Fragments is opting for a
|
|||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>repositions camera or animation-range</td>
|
||||
<td>jumps to camera</td>
|
||||
<td>triggers predefined view</td>
|
||||
<td>Media fragments</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>triggers camera/scene/object/projections</td>
|
||||
<td>n/a</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>draws visible connection(s) for XRWG ‘tag’</td>
|
||||
<td></td>
|
||||
<td>n/a</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>triggers predefined view</td>
|
||||
<td>Media fragments</td>
|
||||
<td>filters certain (in)visible objects</td>
|
||||
<td>n/a</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -183,13 +187,16 @@ Instead of combining them (in a game-editor e.g.), XR Fragments is opting for a
|
|||
│ 2D URL: ://library.com /document ?search #chapter │
|
||||
│ │
|
||||
│ 4D URL: ://park.com /4Dscene.fbx ──> ?misc ──> #view ───> hashbus │
|
||||
│ │ #query │ │
|
||||
│ │ #filter │ │
|
||||
│ │ #tag │ │
|
||||
│ │ #material │ │
|
||||
│ │ #animation │ │
|
||||
│ │ #texture │ │
|
||||
│ │ #variable │ │
|
||||
│ │ │ │
|
||||
│ XRWG <─────────────────────<────────────+ │
|
||||
│ │ │ │
|
||||
│ ├─ objects ───────────────>────────────│ │
|
||||
│ └─ text ───────────────>────────────+ │
|
||||
│ └─ objects ──────────────>────────────+ │
|
||||
│ │
|
||||
│ │
|
||||
+──────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
|
@ -236,7 +243,7 @@ sub-delims = "," / "="
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>pos=1,2,3&rot=0,90,0&q=.foo</code></td>
|
||||
<td><code>pos=1,2,3&rot=0,90,0&foo</code></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -275,25 +282,14 @@ sub-delims = "," / "="
|
|||
|
||||
<tr>
|
||||
<td><code>#t</code></td>
|
||||
<td>vector3</td>
|
||||
<td><code>#t=1,500,1000</code></td>
|
||||
<td>play animation-loop range between frame 500 and 1000, at normal speed</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#......</code></td>
|
||||
<td>string</td>
|
||||
<td><code>#.cubes</code> <code>#cube</code></td>
|
||||
<td>predefined views, XRWG fragments and ID fragments</td>
|
||||
<td>timevector</td>
|
||||
<td><code>#t=2,2000,1</code></td>
|
||||
<td>play animation-loop range between frame 2 and 2000 at (normal) speed 1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>xyz coordinates are similar to ones found in SVG Media Fragments</p>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="list-of-metadata-for-3d-nodes">List of metadata for 3D nodes</h1>
|
||||
<h2 id="list-of-metadata-for-3d-nodes">List of metadata for 3D nodes</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -327,17 +323,149 @@ sub-delims = "," / "="
|
|||
<td><code>tag</code></td>
|
||||
<td>string</td>
|
||||
<td><code>"tag": "cubes geo"</code></td>
|
||||
<td>tag object (for query-use / XRWG highlighting)</td>
|
||||
<td>tag object (for filter-use / XRWG highlighting)</td>
|
||||
<td>custom property in 3D fileformats</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>Supported popular compatible 3D fileformats: <code>.gltf</code>, <code>.obj</code>, <code>.fbx</code>, <code>.usdz</code>, <code>.json</code> (THREE.js), <code>.dae</code> and so on.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="vector-datatypes">vector datatypes</h2>
|
||||
|
||||
<p>| type | syntax | example | info |</p>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>vector2</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>vector3</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>timevector</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>NOTE: XR Fragments are optional but also file- and protocol-agnostic, which means that programmatic 3D scene(nodes) can also use the mechanism/metadata.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="dynamic-xr-fragments-databindings">Dynamic XR Fragments (+databindings)</h2>
|
||||
|
||||
<p>These are automatic fragment-to-metadata mappings, which only trigger if the 3D scene metadata matches a specific identifier (<code>aliasname</code> e.g.)</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>fragment</th>
|
||||
<th>type</th>
|
||||
<th>example</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>#<aliasname></code></td>
|
||||
<td>string</td>
|
||||
<td><code>#cubes</code></td>
|
||||
<td>evaluate predefined views (<code>#cubes: #foo&bar</code> e.g.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#<tag_or_objectname></code></td>
|
||||
<td>string</td>
|
||||
<td><code>#person</code></td>
|
||||
<td>focus object(s) with <code>tag: person</code> or name <code>person</code> by looking up XRWG</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#<cameraname></code></td>
|
||||
<td>string</td>
|
||||
<td><code>#cam01</code></td>
|
||||
<td>set camera as active camera</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#<objectname>=<material></code></td>
|
||||
<td>string=string</td>
|
||||
<td><code>#car=metallic</code></td>
|
||||
<td>set material of car to material with name <code>metallic</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>string=string</td>
|
||||
<td><code>#product=metallic</code></td>
|
||||
<td>set material of objects tagged with <code>product</code> to material with name <code>metallic</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#<objectname>=<mediafrag></code></td>
|
||||
<td>string=<a href="https://www.w3.org/TR/media-frags/#valid-uri">media frag</a></td>
|
||||
<td><code>#foo=0,1</code></td>
|
||||
<td>play media <code>src</code> using <a href="https://www.w3.org/TR/media-frags/#valid-uri">media fragment URI</a></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#<objectname>=<timevector></code></td>
|
||||
<td>string=timevector</td>
|
||||
<td><code>#sky=0,0.5,0.1,0</code></td>
|
||||
<td>sets 1D/2D/3D time(line) vectors (uv-position e.g.) to <code>0,0.5</code> (and autoscroll x with max <code>0.1</code> every second)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><code>#music=1,2</code></td>
|
||||
<td>play media of object (<code>src: podcast.mp3</code> e.g.) from beginning (<code>1</code>) at double speed (<code>2</code>)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1 id="spatial-referencing-3d">Spatial Referencing 3D</h1>
|
||||
|
||||
<p>XR Fragments assume the following objectname-to-URIFragment mapping:</p>
|
||||
|
@ -390,8 +518,8 @@ For example, to render a portal with a preview-version of the scene, create an 3
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><b>#pos</b>=0,0,0</td>
|
||||
<td>vector3</td>
|
||||
<td>(re)position camera</td>
|
||||
<td>vector3 or string</td>
|
||||
<td>(re)position camera based on coordinates directly, or indirectly using objectname (its worldposition)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -415,7 +543,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
|
|||
<li>set the position of the camera accordingly to the vector3 values of <code>#pos</code></li>
|
||||
<li><code>rot</code> sets the rotation of the camera (only for non-VR/AR headsets)</li>
|
||||
<li><code>t</code> sets the playbackspeed and animation-range of the current scene animation(s) or <code>src</code>-mediacontent (video/audioframes e.g., use <code>t=0,7,7</code> to ‘STOP’ at frame 7 e.g.)</li>
|
||||
<li>in case an <code>href</code> does not mention any <code>pos</code>-coordinate, <code>pos=0,0,0</code> will be assumed</li>
|
||||
<li>after scene load: in case an <code>href</code> does not mention any <code>pos</code>-coordinate, <code>pos=0,0,0</code> will be assumed</li>
|
||||
</ol>
|
||||
|
||||
<p>Here’s an ascii representation of a 3D scene-graph which contains 3D objects <code>◻</code> and their metadata:</p>
|
||||
|
@ -453,7 +581,7 @@ In case of <code>buttonA</code> the end-user will be teleported to another locat
|
|||
<li>IF a <code>#cube</code> matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).</li>
|
||||
</ol>
|
||||
|
||||
<h1 id="embedding-xr-content-src-instancing">Embedding XR content (src-instancing)</h1>
|
||||
<h1 id="embedding-xr-content-using-src">Embedding XR content using src</h1>
|
||||
|
||||
<p><code>src</code> is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br>
|
||||
It instances content (in objects) in the current scene/asset.</p>
|
||||
|
@ -470,22 +598,22 @@ It instances content (in objects) in the current scene/asset.</p>
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><code>src</code></td>
|
||||
<td>string (uri, hashtag/query)</td>
|
||||
<td><code>#cube</code><br><code>#sometag</code><br>#q=-ball_inside_cube<code><br></code>#q=-/sky -rain<code><br></code>#q=-.language .english<code><br></code>#q=price:>2 price:<5`<br><code>https://linux.org/penguin.png</code><br><code>https://linux.world/distrowatch.gltf#t=1,100</code><br><code>linuxapp://conference/nixworkshop/apply.gltf#q=flyer</code><br><code>androidapp://page1?tutorial#pos=0,0,1&t1,100</code></td>
|
||||
<td>string (uri, hashtag/filter)</td>
|
||||
<td><code>#cube</code><br><code>#sometag</code><br>#cube&-ball_inside_cube<code><br></code>#-sky&-rain<code><br></code>#-language&english<code><br></code>#price=>5<code><br></code><a href="https://linux.org/penguin.png`">https://linux.org/penguin.png`</a><br><code>https://linux.world/distrowatch.gltf#t=1,100</code><br><code>linuxapp://conference/nixworkshop/apply.gltf#-cta&cta_apply</code><br><code>androidapp://page1?tutorial#pos=0,0,1&t1,100</code><br><code>foo.mp3#0,0,0</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Here’s an ascii representation of a 3D scene-graph with 3D objects <code>◻</code> which embeds remote & local 3D objects <code>◻</code> with/out using queries:</p>
|
||||
<p>Here’s an ascii representation of a 3D scene-graph with 3D objects <code>◻</code> which embeds remote & local 3D objects <code>◻</code> with/out using filters:</p>
|
||||
|
||||
<pre><code> +────────────────────────────────────────────────────────+ +─────────────────────────+
|
||||
│ │ │ │
|
||||
│ index.gltf │ │ ocean.com/aquarium.fbx │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ ├ room │
|
||||
│ ├── ◻ canvas │ │ └── ◻ fishbowl │
|
||||
│ │ └ src: painting.png │ │ ├─ ◻ bass │
|
||||
│ │ │ │ └─ ◻ tuna │
|
||||
│ ├── ◻ aquariumcube │ │ │
|
||||
│ │ └ src: ://rescue.com/fish.gltf#bass%20tuna │ +─────────────────────────+
|
||||
│ │ └ src: ://rescue.com/fish.gltf#fishbowl │ +─────────────────────────+
|
||||
│ │ │
|
||||
│ ├── ◻ bedroom │
|
||||
│ │ └ src: #canvas │
|
||||
|
@ -497,41 +625,45 @@ It instances content (in objects) in the current scene/asset.</p>
|
|||
</code></pre>
|
||||
|
||||
<p>An XR Fragment-compatible browser viewing this scene, lazy-loads and projects <code>painting.png</code> onto the (plane) object called <code>canvas</code> (which is copy-instanced in the bed and livingroom).<br>
|
||||
Also, after lazy-loading <code>ocean.com/aquarium.gltf</code>, only the queried objects <code>bass</code> and <code>tuna</code> will be instanced inside <code>aquariumcube</code>.<br>
|
||||
Also, after lazy-loading <code>ocean.com/aquarium.gltf</code>, only the queried objects <code>fishbowl</code> (and <code>bass</code> and <code>tuna</code>) will be instanced inside <code>aquariumcube</code>.<br>
|
||||
Resizing will be happen accordingly to its placeholder object <code>aquariumcube</code>, see chapter Scaling.<br></p>
|
||||
|
||||
<blockquote>
|
||||
<p>Instead of cherrypicking objects with <code>#bass&tuna</code> thru <code>src</code>, queries can be used to import the whole scene (and filter out certain objects). See next chapter below.</p>
|
||||
<p>Instead of cherrypicking a rootobject <code>#fishbowl</code> with <code>src</code>, additional filters can be used to include/exclude certain objects. See next chapter on filtering below.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><strong>Specification</strong>:</p>
|
||||
|
||||
<ol>
|
||||
<li>local/remote content is instanced by the <code>src</code> (query) value (and attaches it to the placeholder mesh containing the <code>src</code> property)</li>
|
||||
<li><b>local</b> <code>src</code> values (URL <strong>starting</strong> with <code>#</code>, like <code>#cube&foo</code>) means <strong>only</strong> the mentioned objectnames will be copied to the instanced scene (from the current scene) while preserving their names (to support recursive selectors). <a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js">(example code)</a></li>
|
||||
<li><b>local</b> <code>src</code> values indicating a query (<code>#q=</code>), means that all included objects (from the current scene) will be copied to the instanced scene (before applying the query) while preserving their names (to support recursive selectors). <a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js">(example code)</a></li>
|
||||
<li>local/remote content is instanced by the <code>src</code> (filter) value (and attaches it to the placeholder mesh containing the <code>src</code> property)</li>
|
||||
<li>by default all objects are loaded into the instanced src (scene) object (but not shown yet)</li>
|
||||
<li><b>local</b> <code>src</code> values (<code>#...</code> e.g.) starting with a non-negating filter (<code>#cube</code> e.g.) will (deep)reparent that object (with name <code>cube</code>) as the new root of the scene at position 0,0,0</li>
|
||||
<li><b>local</b> <code>src</code> values should respect (negative) filters (<code>#-foo&price=>3</code>)</li>
|
||||
<li>the instanced scene (from a <code>src</code> value) should be <b>scaled accordingly</b> to its placeholder object or <b>scaled relatively</b> based on the scale-property (of a geometry-less placeholder, an ‘empty’-object in blender e.g.). For more info see Chapter Scaling.</li>
|
||||
<li><b>external</b> <code>src</code> values should be served with appropriate mimetype (so the XR Fragment-compatible browser will now how to render it). The bare minimum supported mimetypes are:</li>
|
||||
<li><code>src</code> values should make its placeholder object invisible, and only flush its children when the resolved content can succesfully be retrieved (see <a href="#links">broken links</a>)</li>
|
||||
<li><b>external</b> <code>src</code> values should respect the fallback link mechanism (see <a href="#broken-links">broken links</a></li>
|
||||
<li>when the placeholder object is a 2D plane, but the mimetype is 3D, then render the spatial content on that plane via a stencil buffer.</li>
|
||||
<li>src-values are non-recursive: when linking to an external object (<code>src: foo.fbx#bar</code>), then <code>src</code>-metadata on object <code>bar</code> should be ignored.</li>
|
||||
<li>clicking on external <code>src</code>-values always allow sourceportation: teleporting to the origin URI to which the object belongs.</li>
|
||||
<li>an external <code>src</code>-value should always allow a sourceportation icon within 3 meter: teleporting to the origin URI to which the object belongs.</li>
|
||||
<li>when only one object was cherrypicked (<code>#cube</code> e.g.), set its position to <code>0,0,0</code></li>
|
||||
<li>when the enduser clicks an href with <code>#t=1,0,0</code> (play) will be applied to all src mediacontent with a timeline (mp4/mp3 e.g.)</li>
|
||||
<li>a non-euclidian portal can be rendered for flat 3D objects (using stencil buffer e.g.) in case ofspatial <code>src</code>-values (an object <code>#world3</code> or URL <code>world3.fbx</code> e.g.).</li>
|
||||
</ol>
|
||||
|
||||
<ul>
|
||||
<li><code>model/gltf-binary</code></li>
|
||||
<li><code>model/gltf+json</code></li>
|
||||
<li><code>image/png</code></li>
|
||||
<li><code>image/jpg</code></li>
|
||||
<li><code>text/plain;charset=utf-8;bib=^@</code></li>
|
||||
<li><code>text/plain;charset=utf-8</code></li>
|
||||
</ul>
|
||||
|
||||
<p><a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js">» example implementation</a><br>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/src.gltf#L192">» example 3D asset</a><br>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/issues/4">» discussion</a><br></p>
|
||||
|
||||
<h1 id="navigating-content-internal-outbound-href-portals">Navigating content (internal/outbound href portals)</h1>
|
||||
<h1 id="navigating-content-href-portals">Navigating content href portals</h1>
|
||||
|
||||
<p>navigation, portals & mutations</p>
|
||||
|
||||
|
@ -566,13 +698,25 @@ Resizing will be happen accordingly to its placeholder object <code>aquariumcube
|
|||
|
||||
<li><p>in case of navigating to a new [[pos)ition, “first” navigate to the “current position” so that the “back-button” of the “browser-history” always refers to the previous position (see [<a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js#L97">here</a>)</p></li>
|
||||
|
||||
<li><p>portal-rendering: a 2:1 ratio texture-material indicates an equirectangular projection</p></li>
|
||||
<li><p>ignore previous rule in special cases, like clicking an <code>href</code> using camera-portal collision (the back-button would cause a teleport-loop)</p></li>
|
||||
</ol>
|
||||
|
||||
<p><a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js">» example implementation</a><br>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/href.gltf#L192">» example 3D asset</a><br>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/issues/1">» discussion</a><br></p>
|
||||
|
||||
<h2 id="walking-surfaces">Walking surfaces</h2>
|
||||
|
||||
<p>XR Fragment-compatible viewers can infer this data based scanning the scene for:</p>
|
||||
|
||||
<ol>
|
||||
<li>materialless (nameless & textureless) mesh-objects (without <code>src</code> and <code>href</code>)</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p>optionally the viewer can offer thumbstick, mouse or joystick teleport-tools for non-roomscale VR/AR setups.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="ux-spec">UX spec</h2>
|
||||
|
||||
<p>End-users should always have read/write access to:</p>
|
||||
|
@ -616,7 +760,53 @@ How does the scale of the object (with the embedded properties) impact the scale
|
|||
<p>TODO: needs intermediate visuals to make things more obvious</p>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="xr-fragment-queries">XR Fragment queries</h1>
|
||||
<h1 id="xr-fragment-pos">XR Fragment: pos</h1>
|
||||
|
||||
<h1 id="xr-fragment-rot">XR Fragment: rot</h1>
|
||||
|
||||
<h1 id="xr-fragment-t">XR Fragment: t</h1>
|
||||
|
||||
<p>controls the animation(s) of the scene (or <code>src</code> resource which contains a timeline)</p>
|
||||
|
||||
<p>| fragment | type | functionality |
|
||||
| <b>#t</b>=1,1,100 | <a href="default:`#t=1,0,0`">[vector3|vector]</a> | speed,framestart,framestop |</p>
|
||||
|
||||
<ul>
|
||||
<li>playposition is reset to framestart, when framestart or framestop is greater than 0 |</li>
|
||||
</ul>
|
||||
|
||||
<p>| Example Value | Explanation |
|
||||
|-|-|
|
||||
| <code>1,1,100</code> | play loop between frame 1 and 100 |
|
||||
| <code>1,1,0</code> | play once from frame 1 (oneshot) |
|
||||
| <code>1,0,0</code> | play (previously set looprange if any) |
|
||||
| <code>0,0,0</code> | pause |
|
||||
| <code>1,1,1</code> | play and auto-loop between begin and end of duration |
|
||||
| <code>-1,0,0</code> | reverse playback speed |
|
||||
| <code>2.3,0,0</code> | set (forward) playback speed to 2.3 (no restart) |
|
||||
| <code>-2.3,0,0</code> | set (reverse) playback speed to -2.3 ( no restart)|
|
||||
| <code>-2.3,100,0</code> | set (reverse) playback speed to -2.3 restarting from frame 100 |</p>
|
||||
|
||||
<p>[[» example implementation|<a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/t.js]">https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/t.js]</a>]<br>
|
||||
[[» discussion|<a href="https://github.com/coderofsalvation/xrfragment/issues/10]">https://github.com/coderofsalvation/xrfragment/issues/10]</a>]<br></p>
|
||||
|
||||
<h1 id="xr-audio-video-integration">XR audio/video integration</h1>
|
||||
|
||||
<p>To play global audio/video items:</p>
|
||||
|
||||
<ol>
|
||||
<li>add a <code>src: foo.mp3</code> or <code>src: bar.mp4</code> metadata to a 3D object (<code>cube</code> e.g.)</li>
|
||||
<li>to disable auto-play and global timeline ([[#t=|t]]) control: hardcode a [[#t=|t]] XR Fragment: (<code>src: bar.mp3#t=0,0,0</code> e.g.)</li>
|
||||
<li>to play it, add <code>href: #cube</code> somewhere else</li>
|
||||
<li>when the enduser clicks the <code>href</code>, <code>#t=1,0,0</code> (play) will be applied to the <code>src</code> value</li>
|
||||
<li>to play a single animation, add href: #animationname=1,0,0 somewhere else</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p>NOTE: hardcoded framestart/framestop uses sampleRate/fps of embedded audio/video, otherwise the global fps applies. For more info see [[#t|t]].</p>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="xr-fragment-filters">XR Fragment filters</h1>
|
||||
|
||||
<p>Include, exclude, hide/shows objects using space-separated strings:</p>
|
||||
|
||||
|
@ -630,35 +820,36 @@ How does the scale of the object (with the embedded properties) impact the scale
|
|||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>#q=-sky</code></td>
|
||||
<td><code>#-sky</code></td>
|
||||
<td>show everything except object named <code>sky</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#q=-tag:language tag:english</code></td>
|
||||
<td><code>#-language&english</code></td>
|
||||
<td>hide everything with tag <code>language</code>, but show all tag <code>english</code> objects</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#q=price:>2 price:<5</code></td>
|
||||
<td>of all objects with property <code>price</code>, show only objects with value between 2 and 5</td>
|
||||
<td><code>#-price&price=>10</code></td>
|
||||
<td>hide all objects with property <code>price</code>, then only show object with price above 10</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>It’s simple but powerful syntax which allows filtering the scene using searchengine prompt-style feeling:</p>
|
||||
|
||||
<ol>
|
||||
<li>queries are a way to traverse a scene, and filter objects based on their tag- or property-values.</li>
|
||||
<li>words like <code>german</code> match tag-metadata of 3D objects like <code>"tag":"german"</code></li>
|
||||
<li>words like <code>german</code> match (XR Text) objects with (Bib(s)TeX) tags like <code>#KarlHeinz@german</code> or <code>@german{KarlHeinz, ...</code> e.g.</li>
|
||||
<li>filters are a way to traverse a scene, and filter objects based on their name, tag- or property-values.</li>
|
||||
</ol>
|
||||
|
||||
<ul>
|
||||
<li>see <a href="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an (outdated) example video here</a></li>
|
||||
<li>see <a href="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an (outdated) example video here</a> which used a dedicated <code>q=</code> variable (now deprecated and usable directly)</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="including-excluding">including/excluding</h2>
|
||||
|
||||
<p>By default, selectors work like photoshop-layers: they scan for matching layer(name/properties) within the scene-graph.
|
||||
Each matched object (not their children) will be toggled (in)visible when selecting.</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -670,56 +861,55 @@ How does the scale of the object (with the embedded properties) impact the scale
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><code>-</code></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
<td>hides object(s) (<code>#-myobject&-objects</code> e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>:</code></td>
|
||||
<td>indicates an object-embedded custom property key/value</td>
|
||||
<td><code>=</code></td>
|
||||
<td>indicates an object-embedded custom property key/value (<code>#price=4&category=foo</code> e.g.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>></code> <code><</code></td>
|
||||
<td>compare float or int number</td>
|
||||
<td><code>=></code> <code>=<</code></td>
|
||||
<td>compare float or int number (<code>#price=>4</code> e.g.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>/</code></td>
|
||||
<td>reference to root-scene.<br>Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by <code>src</code>) (*)</td>
|
||||
<td><code>*</code></td>
|
||||
<td>deepselect: automatically select children of selected object, including local (nonremote) embedded objects (starting with <code>#</code>)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>* = <code>#q=-/cube</code> hides object <code>cube</code> only in the root-scene (not nested <code>cube</code> objects)<br> <code>#q=-cube</code> hides both object <code>cube</code> in the root-scene <b>AND</b> nested <code>skybox</code> objects |</p>
|
||||
<p>NOTE 1: after an external embedded object has been instanced (<code>src: https://y.com/bar.fbx#room</code> e.g.), filters do not affect them anymore (reason: local tag/name collisions can be mitigated easily, but not in case of remote content).</p>
|
||||
|
||||
<p>NOTE 2: depending on the used 3D framework, toggling objects (in)visible should happen by enabling/disableing writing to the colorbuffer (to allow children being still visible while their parents are invisible).</p>
|
||||
</blockquote>
|
||||
|
||||
<p><a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js">» example implementation</a>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192">» example 3D asset</a>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/filter.gltf#L192">» example 3D asset</a>
|
||||
<a href="https://github.com/coderofsalvation/xrfragment/issues/3">» discussion</a></p>
|
||||
|
||||
<h2 id="query-parser">Query Parser</h2>
|
||||
<h2 id="filter-parser">Filter Parser</h2>
|
||||
|
||||
<p>Here’s how to write a query parser:</p>
|
||||
<p>Here’s how to write a filter parser:</p>
|
||||
|
||||
<ol>
|
||||
<li>create an associative array/object to store query-arguments as objects</li>
|
||||
<li>detect object id’s & properties <code>foo:1</code> and <code>foo</code> (reference regex: <code>/^.*:[><=!]?/</code> )</li>
|
||||
<li>detect excluders like <code>-foo</code>,<code>-foo:1</code>,<code>-.foo</code>,<code>-/foo</code> (reference regex: <code>/^-/</code> )</li>
|
||||
<li>detect root selectors like <code>/foo</code> (reference regex: <code>/^[-]?\//</code> )</li>
|
||||
<li>detect number values like <code>foo:1</code> (reference regex: <code>/^[0-9\.]+$/</code> )</li>
|
||||
<li>for every query token split string on <code>:</code></li>
|
||||
<li>create an empty array <code>rules</code></li>
|
||||
<li>then strip key-operator: convert “-foo” into “foo”</li>
|
||||
<li>add operator and value to rule-array</li>
|
||||
<li>therefore we we set <code>id</code> to <code>true</code> or <code>false</code> (false=excluder <code>-</code>)</li>
|
||||
<li>create an associative array/object to store filter-arguments as objects</li>
|
||||
<li>detect object id’s & properties <code>foo=1</code> and <code>foo</code> (reference regex= <code>~/^.*=[><=]?/</code> )</li>
|
||||
<li>detect excluders like <code>-foo</code>,<code>-foo=1</code>,<code>-.foo</code>,<code>-/foo</code> (reference regex= <code>/^-/</code> )</li>
|
||||
<li>detect root selectors like <code>/foo</code> (reference regex= <code>/^[-]?\//</code> )</li>
|
||||
<li>detect number values like <code>foo=1</code> (reference regex= <code>/^[0-9\.]+$/</code> )</li>
|
||||
<li>detect operators so you can easily strip keys (reference regex= <code>/(^-|\*$)/</code> )</li>
|
||||
<li>detect exclude keys like <code>-foo</code> (reference regex= <code>/^-/</code> )</li>
|
||||
<li>for every filter token split string on <code>=</code></li>
|
||||
<li>and we set <code>root</code> to <code>true</code> or <code>false</code> (true=<code>/</code> root selector is present)</li>
|
||||
<li>we convert key ‘/foo’ into ‘foo’</li>
|
||||
<li>finally we add the key/value to the store like <code>store.foo = {id:false,root:true}</code> e.g.</li>
|
||||
<li>therefore we we set <code>show</code> to <code>true</code> or <code>false</code> (false=excluder <code>-</code>)</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p>An example query-parser (which compiles to many languages) can be <a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx">found here</a></p>
|
||||
<p>An example filter-parser (which compiles to many languages) can be <a href="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Filter.hx">found here</a></p>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="visible-links">Visible links</h1>
|
||||
|
@ -1103,12 +1293,12 @@ here are some hashtagbibs followed by bibtex:
|
|||
│ │
|
||||
│ index.gltf │
|
||||
│ │ │
|
||||
│ │ #: #q=-offlinetext │
|
||||
│ │ #: #-offlinetext │
|
||||
│ │ │
|
||||
│ ├── ◻ buttonA │
|
||||
│ │ └ href: http://foo.io/campagne.fbx │
|
||||
│ │ └ href@404: ipfs://foo.io/campagne.fbx │
|
||||
│ │ └ href@400: #q=clienterrortext │
|
||||
│ │ └ href@400: #clienterrortext │
|
||||
│ │ └ ◻ offlinetext │
|
||||
│ │ │
|
||||
│ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not)
|
||||
|
@ -1132,12 +1322,12 @@ Consider 3D scenes linking to eachother using these <code>href</code> values:</p
|
|||
</ul>
|
||||
|
||||
<p>These links would all show visible links to math-tagged objects in the scene.<br>
|
||||
To filter out non-related objects one could take it a step further using queries:</p>
|
||||
To filter out non-related objects one could take it a step further using filters:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>href: schoolA.edu/projects.gltf#math&q=-topics math</code></li>
|
||||
<li><code>href: schoolB.edu/projects.gltf#math&q=-courses math</code></li>
|
||||
<li><code>href: university.edu/projects.gltf#math&q=-theme math</code></li>
|
||||
<li><code>href: schoolA.edu/projects.gltf#math&-topics math</code></li>
|
||||
<li><code>href: schoolB.edu/projects.gltf#math&-courses math</code></li>
|
||||
<li><code>href: university.edu/projects.gltf#math&-theme math</code></li>
|
||||
</ul>
|
||||
|
||||
<blockquote>
|
||||
|
@ -1177,6 +1367,15 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
|
|||
<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>
|
||||
<li>Michiel Leenaars</li>
|
||||
<li>Gerben van der Broeke</li>
|
||||
<li>Mauve</li>
|
||||
<li>Jens Finkhäuser</li>
|
||||
<li>Marc Belmont</li>
|
||||
<li>Tim Gerritsen</li>
|
||||
<li>Frode Hegland</li>
|
||||
<li>Brandel Zackernuk</li>
|
||||
<li>Mark Anderson</li>
|
||||
</ul>
|
||||
|
||||
<h1 id="appendix-definitions">Appendix: Definitions</h1>
|
||||
|
@ -1256,8 +1455,8 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>query</td>
|
||||
<td>an URI Fragment-operator which queries object(s) from a scene like <code>#q=cube</code></td>
|
||||
<td>filter</td>
|
||||
<td>URI Fragment(s) which show/hide object(s) in a scene based on name/tag/property (<code>#cube&-price=>3</code>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -1295,6 +1494,11 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
|
|||
<td>obtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>flat 3D object</td>
|
||||
<td>a 3D object of which all verticies share a plane</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>BibTeX</td>
|
||||
<td>simple tagging/citing/referencing standard for plaintext</td>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,10 +12,9 @@
|
|||
<abstract>
|
||||
<t>This draft is a specification for 4D URLs & <eref target="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> navigation, which links together space, time & text together, for hypermedia browsers with- or without a network-connection.<br />
|
||||
|
||||
The specification promotes spatial addressibility, sharing, navigation, query-ing and annotating interactive (text)objects across for (XR) Browsers.<br />
|
||||
The specification promotes spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.<br />
|
||||
|
||||
XR Fragments allows us to enrich existing dataformats, by recursive use of existing proven technologies like <eref target="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref> and BibTags notation.<br />
|
||||
</t>
|
||||
XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like <eref target="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref>.</t>
|
||||
<t>Almost every idea in this document is demonstrated at <eref target="https://xrfragment.org">https://xrfragment.org</eref></t>
|
||||
</abstract>
|
||||
|
||||
|
@ -24,31 +23,29 @@ XR Fragments allows us to enrich existing dataformats, by recursive use of exist
|
|||
<middle>
|
||||
|
||||
<section anchor="introduction"><name>Introduction</name>
|
||||
<t>How can we add more features to existing text & 3D scenes, without introducing new dataformats?<br />
|
||||
<t>How can we add more control to existing text & 3D scenes, without introducing new dataformats?<br />
|
||||
|
||||
Historically, there's many attempts to create the ultimate markuplanguage or 3D fileformat.<br />
|
||||
|
||||
The lowest common denominator is: describing/tagging/naming nodes using <strong>plain text</strong>.<br />
|
||||
The lowest common denominator is: designers describing/tagging/naming things using <strong>plain text</strong>.<br />
|
||||
|
||||
XR Fragments allows us to enrich/connect existing dataformats, by introducing existing technologies/ideas:<br />
|
||||
</t>
|
||||
XR Fragments exploits the fact that all 3D models already contain such metadata:</t>
|
||||
<t><strong>XR Fragments allows controlling of metadata in 3D scene(files) using URLs</strong></t>
|
||||
<t>Or more detailed:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>addressibility and <eref target="https://github.com/coderofsalvation/hypermediatic">hypermediatic</eref> navigation of 3D scenes/objects: <eref target="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref> + src/href spatial metadata</li>
|
||||
<li>Interlinking text/& 3D by collapsing space into a Word Graph (XRWG) to show <eref target="#visible-links">visible links</eref> (and augmenting text with <eref target="https://github.com/coderofsalvation/tagbibs">bibs</eref> / <eref target="https://en.wikipedia.org/wiki/BibTeX">BibTags</eref> appendices (see <eref target="https://visual-meta.info">visual-meta</eref> e.g.)</li>
|
||||
<li>Interlinking (text)objects by collapsing space into a Word Graph (XRWG) to show <eref target="#visible-links">visible links</eref></li>
|
||||
<li>unlocking spatial potential of the (originally 2D) hashtag (which jumps to a chapter) for navigating XR documents</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>
|
||||
<t>XR Fragments strives to serve (nontechnical/fuzzy) humans first, and machine(implementations) later, by ensuring hasslefree text-vs-thought feedback loops.<br />
|
||||
<t><strong>XR Fragments allows controlling of metadata in 3D scene(files) using URLs</strong></t>
|
||||
<t>XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.<br />
|
||||
|
||||
This also means that the repair-ability of machine-matters should be human friendly too (not too complex).<br />
|
||||
|
||||
XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.<br />
|
||||
|
||||
Instead of combining them (in a game-editor e.g.), XR Fragments is opting for a more integrated path <strong>towards</strong> them, by describing how to make browsers <strong>4D URL-ready</strong>:</t>
|
||||
Instead of combining them (in a game-editor e.g.), XR Fragments <strong>integrates all</strong>, by collecting metadata into an XRWG and control it via URL:</t>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -67,14 +64,8 @@ Instead of combining them (in a game-editor e.g.), XR Fragments is opting for a
|
|||
|
||||
<tr>
|
||||
<td>the hashbus</td>
|
||||
<td>hashtags map to camera/scene-projections</td>
|
||||
<td>hashtags map to document positions</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>spacetime hashtags</td>
|
||||
<td>positions camera, triggers scene-preset/time</td>
|
||||
<td>jumps/scrolls to chapter</td>
|
||||
<td>hashtags alter camera/scene/object-projections</td>
|
||||
<td>hashtags alter document positions</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -91,43 +82,53 @@ Instead of combining them (in a game-editor e.g.), XR Fragments is opting for a
|
|||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>repositions camera or animation-range</td>
|
||||
<td>jumps to camera</td>
|
||||
<td>triggers predefined view</td>
|
||||
<td>Media fragments</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>triggers camera/scene/object/projections</td>
|
||||
<td>n/a</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>draws visible connection(s) for XRWG 'tag'</td>
|
||||
<td></td>
|
||||
<td>n/a</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>href metadata</td>
|
||||
<td>triggers predefined view</td>
|
||||
<td>Media fragments</td>
|
||||
<td>filters certain (in)visible objects</td>
|
||||
<td>n/a</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>XR Fragments does not look at XR (or the web) thru the lens of HTML.<br />
|
||||
But approaches things from a higherlevel feedbackloop/hypermedia browser-perspective:</t>
|
||||
</blockquote>
|
||||
<artwork> +──────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
<artwork><![CDATA[ +──────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
│ │
|
||||
│ the soul of any URL: ://macro /meso ?micro #nano │
|
||||
│ │
|
||||
│ 2D URL: ://library.com /document ?search #chapter │
|
||||
│ │
|
||||
│ 4D URL: ://park.com /4Dscene.fbx ──> ?misc ──> #view ───> hashbus │
|
||||
│ │ #query │ │
|
||||
│ 4D URL: ://park.com /4Dscene.fbx ──> ?misc ──> #view ───> hashbus │
|
||||
│ │ #filter │ │
|
||||
│ │ #tag │ │
|
||||
│ │ #material │ │
|
||||
│ │ #animation │ │
|
||||
│ │ #texture │ │
|
||||
│ │ #variable │ │
|
||||
│ │ │ │
|
||||
│ XRWG <─────────────────────<────────────+ │
|
||||
│ XRWG <─────────────────────<────────────+ │
|
||||
│ │ │ │
|
||||
│ ├─ objects ───────────────>────────────│ │
|
||||
│ └─ text ───────────────>────────────+ │
|
||||
│ └─ objects ──────────────>────────────+ │
|
||||
│ │
|
||||
│ │
|
||||
+──────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
<t>Traditional webbrowsers can become 4D document-ready by:</t>
|
||||
|
||||
|
@ -144,9 +145,10 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec
|
|||
|
||||
<section anchor="xr-fragment-uri-grammar"><name>XR Fragment URI Grammar</name>
|
||||
|
||||
<artwork>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
<artwork><![CDATA[reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
]]>
|
||||
</artwork>
|
||||
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</tt></t>
|
||||
</blockquote><table>
|
||||
|
@ -164,7 +166,7 @@ sub-delims = "," / "="
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>pos=1,2,3&rot=0,90,0&q=.foo</tt></td>
|
||||
<td><tt>pos=1,2,3&rot=0,90,0&foo</tt></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -200,21 +202,12 @@ sub-delims = "," / "="
|
|||
|
||||
<tr>
|
||||
<td><tt>#t</tt></td>
|
||||
<td>vector3</td>
|
||||
<td><tt>#t=1,500,1000</tt></td>
|
||||
<td>play animation-loop range between frame 500 and 1000, at normal speed</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#......</tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>#.cubes</tt> <tt>#cube</tt></td>
|
||||
<td>predefined views, XRWG fragments and ID fragments</td>
|
||||
<td>timevector</td>
|
||||
<td><tt>#t=2,2000,1</tt></td>
|
||||
<td>play animation-loop range between frame 2 and 2000 at (normal) speed 1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>xyz coordinates are similar to ones found in SVG Media Fragments</t>
|
||||
</blockquote></section>
|
||||
|
||||
</table>
|
||||
<section anchor="list-of-metadata-for-3d-nodes"><name>List of metadata for 3D nodes</name>
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -248,18 +241,144 @@ sub-delims = "," / "="
|
|||
<td><tt>tag</tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>"tag": "cubes geo"</tt></td>
|
||||
<td>tag object (for query-use / XRWG highlighting)</td>
|
||||
<td>tag object (for filter-use / XRWG highlighting)</td>
|
||||
<td>custom property in 3D fileformats</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><t>Supported popular compatible 3D fileformats: <tt>.gltf</tt>, <tt>.obj</tt>, <tt>.fbx</tt>, <tt>.usdz</tt>, <tt>.json</tt> (THREE.js), <tt>.dae</tt> and so on.</t>
|
||||
<blockquote><t>NOTE: XR Fragments are optional but also file- and protocol-agnostic, which means that programmatic 3D scene(nodes) can also use the mechanism/metadata.</t>
|
||||
</table><blockquote><t>Supported popular compatible 3D fileformats: <tt>.gltf</tt>, <tt>.obj</tt>, <tt>.fbx</tt>, <tt>.usdz</tt>, <tt>.json</tt> (THREE.js), <tt>.dae</tt> and so on.</t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="vector-datatypes"><name>vector datatypes</name>
|
||||
<t>| type | syntax | example | info |</t>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>vector2</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>vector3</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>timevector</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>NOTE: XR Fragments are optional but also file- and protocol-agnostic, which means that programmatic 3D scene(nodes) can also use the mechanism/metadata.</t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="dynamic-xr-fragments-databindings"><name>Dynamic XR Fragments (+databindings)</name>
|
||||
<t>These are automatic fragment-to-metadata mappings, which only trigger if the 3D scene metadata matches a specific identifier (<tt>aliasname</tt> e.g.)</t>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>fragment</th>
|
||||
<th>type</th>
|
||||
<th>example</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>#<aliasname></tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>#cubes</tt></td>
|
||||
<td>evaluate predefined views (<tt>#cubes: #foo&bar</tt> e.g.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#<tag_or_objectname></tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>#person</tt></td>
|
||||
<td>focus object(s) with <tt>tag: person</tt> or name <tt>person</tt> by looking up XRWG</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#<cameraname></tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>#cam01</tt></td>
|
||||
<td>set camera as active camera</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#<objectname>=<material></tt></td>
|
||||
<td>string=string</td>
|
||||
<td><tt>#car=metallic</tt></td>
|
||||
<td>set material of car to material with name <tt>metallic</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>string=string</td>
|
||||
<td><tt>#product=metallic</tt></td>
|
||||
<td>set material of objects tagged with <tt>product</tt> to material with name <tt>metallic</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#<objectname>=<mediafrag></tt></td>
|
||||
<td>string=<eref target="https://www.w3.org/TR/media-frags/#valid-uri">media frag</eref></td>
|
||||
<td><tt>#foo=0,1</tt></td>
|
||||
<td>play media <tt>src</tt> using <eref target="https://www.w3.org/TR/media-frags/#valid-uri">media fragment URI</eref></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#<objectname>=<timevector></tt></td>
|
||||
<td>string=timevector</td>
|
||||
<td><tt>#sky=0,0.5,0.1,0</tt></td>
|
||||
<td>sets 1D/2D/3D time(line) vectors (uv-position e.g.) to <tt>0,0.5</tt> (and autoscroll x with max <tt>0.1</tt> every second)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><tt>#music=1,2</tt></td>
|
||||
<td>play media of object (<tt>src: podcast.mp3</tt> e.g.) from beginning (<tt>1</tt>) at double speed (<tt>2</tt>)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></section>
|
||||
</section>
|
||||
|
||||
<section anchor="spatial-referencing-3d"><name>Spatial Referencing 3D</name>
|
||||
<t>XR Fragments assume the following objectname-to-URIFragment mapping:</t>
|
||||
|
||||
<artwork>
|
||||
<artwork><![CDATA[
|
||||
my.io/scene.fbx
|
||||
+─────────────────────────────+
|
||||
│ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor)
|
||||
|
@ -275,6 +394,7 @@ sub-delims = "," / "="
|
|||
│ +─────────────────────────+ │
|
||||
+─────────────────────────────+
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
<blockquote><t>Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).</t>
|
||||
</blockquote><t>Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.<br />
|
||||
|
@ -301,8 +421,8 @@ For example, to render a portal with a preview-version of the scene, create an 3
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><b>#pos</b>=0,0,0</td>
|
||||
<td>vector3</td>
|
||||
<td>(re)position camera</td>
|
||||
<td>vector3 or string</td>
|
||||
<td>(re)position camera based on coordinates directly, or indirectly using objectname (its worldposition)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -327,22 +447,23 @@ For example, to render a portal with a preview-version of the scene, create an 3
|
|||
<li>set the position of the camera accordingly to the vector3 values of <tt>#pos</tt></li>
|
||||
<li><tt>rot</tt> sets the rotation of the camera (only for non-VR/AR headsets)</li>
|
||||
<li><tt>t</tt> sets the playbackspeed and animation-range of the current scene animation(s) or <tt>src</tt>-mediacontent (video/audioframes e.g., use <tt>t=0,7,7</tt> to 'STOP' at frame 7 e.g.)</li>
|
||||
<li>in case an <tt>href</tt> does not mention any <tt>pos</tt>-coordinate, <tt>pos=0,0,0</tt> will be assumed</li>
|
||||
<li>after scene load: in case an <tt>href</tt> does not mention any <tt>pos</tt>-coordinate, <tt>pos=0,0,0</tt> will be assumed</li>
|
||||
</ol>
|
||||
<t>Here's an ascii representation of a 3D scene-graph which contains 3D objects <tt>◻</tt> and their metadata:</t>
|
||||
|
||||
<artwork> +────────────────────────────────────────────────────────+
|
||||
<artwork><![CDATA[ +────────────────────────────────────────────────────────+
|
||||
│ │
|
||||
│ index.gltf │
|
||||
│ │ │
|
||||
│ ├── ◻ buttonA │
|
||||
│ │ └ href: #pos=1,0,1&t=100,200 │
|
||||
│ │ └ href: #pos=1,0,1&t=100,200 │
|
||||
│ │ │
|
||||
│ └── ◻ buttonB │
|
||||
│ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc)
|
||||
│ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc)
|
||||
│ │
|
||||
+────────────────────────────────────────────────────────+
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
<t>An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the <tt>buttonA</tt> and <tt>buttonB</tt>.<br />
|
||||
|
||||
|
@ -362,7 +483,7 @@ In case of <tt>buttonA</tt> the end-user will be teleported to another location
|
|||
</ol>
|
||||
</section>
|
||||
|
||||
<section anchor="embedding-xr-content-src-instancing"><name>Embedding XR content (src-instancing)</name>
|
||||
<section anchor="embedding-xr-content-using-src"><name>Embedding XR content using src</name>
|
||||
<t><tt>src</tt> is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.<br />
|
||||
|
||||
It instances content (in objects) in the current scene/asset.</t>
|
||||
|
@ -378,26 +499,27 @@ It instances content (in objects) in the current scene/asset.</t>
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><tt>src</tt></td>
|
||||
<td>string (uri, hashtag/query)</td>
|
||||
<td>string (uri, hashtag/filter)</td>
|
||||
<td><tt>#cube</tt><br />
|
||||
<tt>#sometag</tt><br />
|
||||
#q=-ball_inside_cube<tt><br></tt>#q=-/sky -rain<tt><br></tt>#q=-.language .english<tt><br></tt>#q=price:>2 price:<5`<br><tt>https://linux.org/penguin.png</tt><br />
|
||||
#cube&-ball_inside_cube<tt><br></tt>#-sky&-rain<tt><br></tt>#-language&english<tt><br></tt>#price=>5<tt><br></tt><eref target="https://linux.org/penguin.png`">https://linux.org/penguin.png`</eref><br />
|
||||
<tt>https://linux.world/distrowatch.gltf#t=1,100</tt><br />
|
||||
<tt>linuxapp://conference/nixworkshop/apply.gltf#q=flyer</tt><br />
|
||||
<tt>androidapp://page1?tutorial#pos=0,0,1&t1,100</tt></td>
|
||||
<tt>linuxapp://conference/nixworkshop/apply.gltf#-cta&cta_apply</tt><br />
|
||||
<tt>androidapp://page1?tutorial#pos=0,0,1&t1,100</tt><br />
|
||||
<tt>foo.mp3#0,0,0</tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><t>Here's an ascii representation of a 3D scene-graph with 3D objects <tt>◻</tt> which embeds remote & local 3D objects <tt>◻</tt> with/out using queries:</t>
|
||||
</table><t>Here's an ascii representation of a 3D scene-graph with 3D objects <tt>◻</tt> which embeds remote & local 3D objects <tt>◻</tt> with/out using filters:</t>
|
||||
|
||||
<artwork> +────────────────────────────────────────────────────────+ +─────────────────────────+
|
||||
<artwork><![CDATA[ +────────────────────────────────────────────────────────+ +─────────────────────────+
|
||||
│ │ │ │
|
||||
│ index.gltf │ │ ocean.com/aquarium.fbx │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ ├ room │
|
||||
│ ├── ◻ canvas │ │ └── ◻ fishbowl │
|
||||
│ │ └ src: painting.png │ │ ├─ ◻ bass │
|
||||
│ │ │ │ └─ ◻ tuna │
|
||||
│ ├── ◻ aquariumcube │ │ │
|
||||
│ │ └ src: ://rescue.com/fish.gltf#bass%20tuna │ +─────────────────────────+
|
||||
│ │ └ src: ://rescue.com/fish.gltf#fishbowl │ +─────────────────────────+
|
||||
│ │ │
|
||||
│ ├── ◻ bedroom │
|
||||
│ │ └ src: #canvas │
|
||||
|
@ -406,35 +528,40 @@ It instances content (in objects) in the current scene/asset.</t>
|
|||
│ └ src: #canvas │
|
||||
│ │
|
||||
+────────────────────────────────────────────────────────+
|
||||
]]>
|
||||
</artwork>
|
||||
<t>An XR Fragment-compatible browser viewing this scene, lazy-loads and projects <tt>painting.png</tt> onto the (plane) object called <tt>canvas</tt> (which is copy-instanced in the bed and livingroom).<br />
|
||||
|
||||
Also, after lazy-loading <tt>ocean.com/aquarium.gltf</tt>, only the queried objects <tt>bass</tt> and <tt>tuna</tt> will be instanced inside <tt>aquariumcube</tt>.<br />
|
||||
Also, after lazy-loading <tt>ocean.com/aquarium.gltf</tt>, only the queried objects <tt>fishbowl</tt> (and <tt>bass</tt> and <tt>tuna</tt>) will be instanced inside <tt>aquariumcube</tt>.<br />
|
||||
|
||||
Resizing will be happen accordingly to its placeholder object <tt>aquariumcube</tt>, see chapter Scaling.<br />
|
||||
</t>
|
||||
<blockquote><t>Instead of cherrypicking objects with <tt>#bass&tuna</tt> thru <tt>src</tt>, queries can be used to import the whole scene (and filter out certain objects). See next chapter below.</t>
|
||||
<blockquote><t>Instead of cherrypicking a rootobject <tt>#fishbowl</tt> with <tt>src</tt>, additional filters can be used to include/exclude certain objects. See next chapter on filtering below.</t>
|
||||
</blockquote><t><strong>Specification</strong>:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>local/remote content is instanced by the <tt>src</tt> (query) value (and attaches it to the placeholder mesh containing the <tt>src</tt> property)</li>
|
||||
<li><b>local</b> <tt>src</tt> values (URL <strong>starting</strong> with <tt>#</tt>, like <tt>#cube&foo</tt>) means <strong>only</strong> the mentioned objectnames will be copied to the instanced scene (from the current scene) while preserving their names (to support recursive selectors). <eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js">(example code)</eref></li>
|
||||
<li><b>local</b> <tt>src</tt> values indicating a query (<tt>#q=</tt>), means that all included objects (from the current scene) will be copied to the instanced scene (before applying the query) while preserving their names (to support recursive selectors). <eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js">(example code)</eref></li>
|
||||
<li>local/remote content is instanced by the <tt>src</tt> (filter) value (and attaches it to the placeholder mesh containing the <tt>src</tt> property)</li>
|
||||
<li>by default all objects are loaded into the instanced src (scene) object (but not shown yet)</li>
|
||||
<li><b>local</b> <tt>src</tt> values (<tt>#...</tt> e.g.) starting with a non-negating filter (<tt>#cube</tt> e.g.) will (deep)reparent that object (with name <tt>cube</tt>) as the new root of the scene at position 0,0,0</li>
|
||||
<li><b>local</b> <tt>src</tt> values should respect (negative) filters (<tt>#-foo&price=>3</tt>)</li>
|
||||
<li>the instanced scene (from a <tt>src</tt> value) should be <b>scaled accordingly</b> to its placeholder object or <b>scaled relatively</b> based on the scale-property (of a geometry-less placeholder, an 'empty'-object in blender e.g.). For more info see Chapter Scaling.</li>
|
||||
<li><b>external</b> <tt>src</tt> values should be served with appropriate mimetype (so the XR Fragment-compatible browser will now how to render it). The bare minimum supported mimetypes are:</li>
|
||||
<li><tt>src</tt> values should make its placeholder object invisible, and only flush its children when the resolved content can succesfully be retrieved (see <eref target="#links">broken links</eref>)</li>
|
||||
<li><b>external</b> <tt>src</tt> values should respect the fallback link mechanism (see <eref target="#broken-links">broken links</eref></li>
|
||||
<li>when the placeholder object is a 2D plane, but the mimetype is 3D, then render the spatial content on that plane via a stencil buffer.</li>
|
||||
<li>src-values are non-recursive: when linking to an external object (<tt>src: foo.fbx#bar</tt>), then <tt>src</tt>-metadata on object <tt>bar</tt> should be ignored.</li>
|
||||
<li>clicking on external <tt>src</tt>-values always allow sourceportation: teleporting to the origin URI to which the object belongs.</li>
|
||||
<li>an external <tt>src</tt>-value should always allow a sourceportation icon within 3 meter: teleporting to the origin URI to which the object belongs.</li>
|
||||
<li>when only one object was cherrypicked (<tt>#cube</tt> e.g.), set its position to <tt>0,0,0</tt></li>
|
||||
<li>when the enduser clicks an href with <tt>#t=1,0,0</tt> (play) will be applied to all src mediacontent with a timeline (mp4/mp3 e.g.)</li>
|
||||
<li>a non-euclidian portal can be rendered for flat 3D objects (using stencil buffer e.g.) in case ofspatial <tt>src</tt>-values (an object <tt>#world3</tt> or URL <tt>world3.fbx</tt> e.g.).</li>
|
||||
</ol>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li><tt>model/gltf-binary</tt></li>
|
||||
<li><tt>model/gltf+json</tt></li>
|
||||
<li><tt>image/png</tt></li>
|
||||
<li><tt>image/jpg</tt></li>
|
||||
<li><tt>text/plain;charset=utf-8;bib=^@</tt></li>
|
||||
<li><tt>text/plain;charset=utf-8</tt></li>
|
||||
</ul>
|
||||
<t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js">» example implementation</eref><br />
|
||||
|
||||
|
@ -444,7 +571,7 @@ Resizing will be happen accordingly to its placeholder object <tt>aquariumcube</
|
|||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="navigating-content-internal-outbound-href-portals"><name>Navigating content (internal/outbound href portals)</name>
|
||||
<section anchor="navigating-content-href-portals"><name>Navigating content href portals</name>
|
||||
<t>navigation, portals & mutations</t>
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -479,7 +606,7 @@ Resizing will be happen accordingly to its placeholder object <tt>aquariumcube</
|
|||
</li>
|
||||
<li><t>in case of navigating to a new [[pos)ition, ''first'' navigate to the ''current position'' so that the ''back-button'' of the ''browser-history'' always refers to the previous position (see [<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js#L97">here</eref>)</t>
|
||||
</li>
|
||||
<li><t>portal-rendering: a 2:1 ratio texture-material indicates an equirectangular projection</t>
|
||||
<li><t>ignore previous rule in special cases, like clicking an <tt>href</tt> using camera-portal collision (the back-button would cause a teleport-loop)</t>
|
||||
</li>
|
||||
</ol>
|
||||
<t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js">» example implementation</eref><br />
|
||||
|
@ -489,6 +616,15 @@ Resizing will be happen accordingly to its placeholder object <tt>aquariumcube</
|
|||
<eref target="https://github.com/coderofsalvation/xrfragment/issues/1">» discussion</eref><br />
|
||||
</t>
|
||||
|
||||
<section anchor="walking-surfaces"><name>Walking surfaces</name>
|
||||
<t>XR Fragment-compatible viewers can infer this data based scanning the scene for:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>materialless (nameless & textureless) mesh-objects (without <tt>src</tt> and <tt>href</tt>)</li>
|
||||
</ol>
|
||||
<blockquote><t>optionally the viewer can offer thumbstick, mouse or joystick teleport-tools for non-roomscale VR/AR setups.</t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="ux-spec"><name>UX spec</name>
|
||||
<t>End-users should always have read/write access to:</t>
|
||||
|
||||
|
@ -527,7 +663,51 @@ How does the scale of the object (with the embedded properties) impact the scale
|
|||
</blockquote></section>
|
||||
</section>
|
||||
|
||||
<section anchor="xr-fragment-queries"><name>XR Fragment queries</name>
|
||||
<section anchor="xr-fragment-pos"><name>XR Fragment: pos</name>
|
||||
</section>
|
||||
|
||||
<section anchor="xr-fragment-rot"><name>XR Fragment: rot</name>
|
||||
</section>
|
||||
|
||||
<section anchor="xr-fragment-t"><name>XR Fragment: t</name>
|
||||
<t>controls the animation(s) of the scene (or <tt>src</tt> resource which contains a timeline)</t>
|
||||
<t>| fragment | type | functionality |
|
||||
| <b>#t</b>=1,1,100 | <eref target="default:`#t=1,0,0`">[vector3|vector]</eref> | speed,framestart,framestop |</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>playposition is reset to framestart, when framestart or framestop is greater than 0 |</li>
|
||||
</ul>
|
||||
<t>| Example Value | Explanation |
|
||||
|-|-|
|
||||
| <tt>1,1,100</tt> | play loop between frame 1 and 100 |
|
||||
| <tt>1,1,0</tt> | play once from frame 1 (oneshot) |
|
||||
| <tt>1,0,0</tt> | play (previously set looprange if any) |
|
||||
| <tt>0,0,0</tt> | pause |
|
||||
| <tt>1,1,1</tt> | play and auto-loop between begin and end of duration |
|
||||
| <tt>-1,0,0</tt> | reverse playback speed |
|
||||
| <tt>2.3,0,0</tt> | set (forward) playback speed to 2.3 (no restart) |
|
||||
| <tt>-2.3,0,0</tt> | set (reverse) playback speed to -2.3 ( no restart)|
|
||||
| <tt>-2.3,100,0</tt> | set (reverse) playback speed to -2.3 restarting from frame 100 |</t>
|
||||
<t>[[» example implementation|<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/t.js]">https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/t.js]</eref>]<br />
|
||||
|
||||
[[» discussion|<eref target="https://github.com/coderofsalvation/xrfragment/issues/10]">https://github.com/coderofsalvation/xrfragment/issues/10]</eref>]<br />
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="xr-audio-video-integration"><name>XR audio/video integration</name>
|
||||
<t>To play global audio/video items:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>add a <tt>src: foo.mp3</tt> or <tt>src: bar.mp4</tt> metadata to a 3D object (<tt>cube</tt> e.g.)</li>
|
||||
<li>to disable auto-play and global timeline ([[#t=|t]]) control: hardcode a [[#t=|t]] XR Fragment: (<tt>src: bar.mp3#t=0,0,0</tt> e.g.)</li>
|
||||
<li>to play it, add <tt>href: #cube</tt> somewhere else</li>
|
||||
<li>when the enduser clicks the <tt>href</tt>, <tt>#t=1,0,0</tt> (play) will be applied to the <tt>src</tt> value</li>
|
||||
<li>to play a single animation, add href: #animationname=1,0,0 somewhere else</li>
|
||||
</ol>
|
||||
<blockquote><t>NOTE: hardcoded framestart/framestop uses sampleRate/fps of embedded audio/video, otherwise the global fps applies. For more info see [[#t|t]].</t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="xr-fragment-filters"><name>XR Fragment filters</name>
|
||||
<t>Include, exclude, hide/shows objects using space-separated strings:</t>
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -539,33 +719,33 @@ How does the scale of the object (with the embedded properties) impact the scale
|
|||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>#q=-sky</tt></td>
|
||||
<td><tt>#-sky</tt></td>
|
||||
<td>show everything except object named <tt>sky</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#q=-tag:language tag:english</tt></td>
|
||||
<td><tt>#-language&english</tt></td>
|
||||
<td>hide everything with tag <tt>language</tt>, but show all tag <tt>english</tt> objects</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#q=price:>2 price:<5</tt></td>
|
||||
<td>of all objects with property <tt>price</tt>, show only objects with value between 2 and 5</td>
|
||||
<td><tt>#-price&price=>10</tt></td>
|
||||
<td>hide all objects with property <tt>price</tt>, then only show object with price above 10</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><t>It's simple but powerful syntax which allows filtering the scene using searchengine prompt-style feeling:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>queries are a way to traverse a scene, and filter objects based on their tag- or property-values.</li>
|
||||
<li>words like <tt>german</tt> match tag-metadata of 3D objects like <tt>"tag":"german"</tt></li>
|
||||
<li>words like <tt>german</tt> match (XR Text) objects with (Bib(s)TeX) tags like <tt>#KarlHeinz@german</tt> or <tt>@german{KarlHeinz, ...</tt> e.g.</li>
|
||||
<li>filters are a way to traverse a scene, and filter objects based on their name, tag- or property-values.</li>
|
||||
</ol>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>see <eref target="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an (outdated) example video here</eref></li>
|
||||
<li>see <eref target="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an (outdated) example video here</eref> which used a dedicated <tt>q=</tt> variable (now deprecated and usable directly)</li>
|
||||
</ul>
|
||||
|
||||
<section anchor="including-excluding"><name>including/excluding</name>
|
||||
<t>By default, selectors work like photoshop-layers: they scan for matching layer(name/properties) within the scene-graph.
|
||||
Each matched object (not their children) will be toggled (in)visible when selecting.</t>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -577,51 +757,47 @@ How does the scale of the object (with the embedded properties) impact the scale
|
|||
<tbody>
|
||||
<tr>
|
||||
<td><tt>-</tt></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
<td>hides object(s) (<tt>#-myobject&-objects</tt> e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>:</tt></td>
|
||||
<td>indicates an object-embedded custom property key/value</td>
|
||||
<td><tt>=</tt></td>
|
||||
<td>indicates an object-embedded custom property key/value (<tt>#price=4&category=foo</tt> e.g.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>></tt> <tt><</tt></td>
|
||||
<td>compare float or int number</td>
|
||||
<td><tt>=></tt> <tt>=<</tt></td>
|
||||
<td>compare float or int number (<tt>#price=>4</tt> e.g.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>/</tt></td>
|
||||
<td>reference to root-scene.<br />
|
||||
Useful in case of (preventing) showing/hiding objects in nested scenes (instanced by <tt>src</tt>) (*)</td>
|
||||
<td><tt>*</tt></td>
|
||||
<td>deepselect: automatically select children of selected object, including local (nonremote) embedded objects (starting with <tt>#</tt>)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>* = <tt>#q=-/cube</tt> hides object <tt>cube</tt> only in the root-scene (not nested <tt>cube</tt> objects)<br />
|
||||
<tt>#q=-cube</tt> hides both object <tt>cube</tt> in the root-scene <b>AND</b> nested <tt>skybox</tt> objects |</t>
|
||||
</table><blockquote><t>NOTE 1: after an external embedded object has been instanced (<tt>src: https://y.com/bar.fbx#room</tt> e.g.), filters do not affect them anymore (reason: local tag/name collisions can be mitigated easily, but not in case of remote content).</t>
|
||||
<t>NOTE 2: depending on the used 3D framework, toggling objects (in)visible should happen by enabling/disableing writing to the colorbuffer (to allow children being still visible while their parents are invisible).</t>
|
||||
</blockquote><t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js">» example implementation</eref>
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/query.gltf#L192">» example 3D asset</eref>
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/filter.gltf#L192">» example 3D asset</eref>
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/issues/3">» discussion</eref></t>
|
||||
</section>
|
||||
|
||||
<section anchor="query-parser"><name>Query Parser</name>
|
||||
<t>Here's how to write a query parser:</t>
|
||||
<section anchor="filter-parser"><name>Filter Parser</name>
|
||||
<t>Here's how to write a filter parser:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>create an associative array/object to store query-arguments as objects</li>
|
||||
<li>detect object id's & properties <tt>foo:1</tt> and <tt>foo</tt> (reference regex: <tt>/^.*:[><=!]?/</tt> )</li>
|
||||
<li>detect excluders like <tt>-foo</tt>,<tt>-foo:1</tt>,<tt>-.foo</tt>,<tt>-/foo</tt> (reference regex: <tt>/^-/</tt> )</li>
|
||||
<li>detect root selectors like <tt>/foo</tt> (reference regex: <tt>/^[-]?\//</tt> )</li>
|
||||
<li>detect number values like <tt>foo:1</tt> (reference regex: <tt>/^[0-9\.]+$/</tt> )</li>
|
||||
<li>for every query token split string on <tt>:</tt></li>
|
||||
<li>create an empty array <tt>rules</tt></li>
|
||||
<li>then strip key-operator: convert "-foo" into "foo"</li>
|
||||
<li>add operator and value to rule-array</li>
|
||||
<li>therefore we we set <tt>id</tt> to <tt>true</tt> or <tt>false</tt> (false=excluder <tt>-</tt>)</li>
|
||||
<li>create an associative array/object to store filter-arguments as objects</li>
|
||||
<li>detect object id's & properties <tt>foo=1</tt> and <tt>foo</tt> (reference regex= <tt>~/^.*=[><=]?/</tt> )</li>
|
||||
<li>detect excluders like <tt>-foo</tt>,<tt>-foo=1</tt>,<tt>-.foo</tt>,<tt>-/foo</tt> (reference regex= <tt>/^-/</tt> )</li>
|
||||
<li>detect root selectors like <tt>/foo</tt> (reference regex= <tt>/^[-]?\//</tt> )</li>
|
||||
<li>detect number values like <tt>foo=1</tt> (reference regex= <tt>/^[0-9\.]+$/</tt> )</li>
|
||||
<li>detect operators so you can easily strip keys (reference regex= <tt>/(^-|\*$)/</tt> )</li>
|
||||
<li>detect exclude keys like <tt>-foo</tt> (reference regex= <tt>/^-/</tt> )</li>
|
||||
<li>for every filter token split string on <tt>=</tt></li>
|
||||
<li>and we set <tt>root</tt> to <tt>true</tt> or <tt>false</tt> (true=<tt>/</tt> root selector is present)</li>
|
||||
<li>we convert key '/foo' into 'foo'</li>
|
||||
<li>finally we add the key/value to the store like <tt>store.foo = {id:false,root:true}</tt> e.g.</li>
|
||||
<li>therefore we we set <tt>show</tt> to <tt>true</tt> or <tt>false</tt> (false=excluder <tt>-</tt>)</li>
|
||||
</ol>
|
||||
<blockquote><t>An example query-parser (which compiles to many languages) can be <eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx">found here</eref></t>
|
||||
<blockquote><t>An example filter-parser (which compiles to many languages) can be <eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Filter.hx">found here</eref></t>
|
||||
</blockquote></section>
|
||||
</section>
|
||||
|
||||
|
@ -669,7 +845,7 @@ XR Fragments does this by detecting Bib(s)Tex, without introducing a new languag
|
|||
</ol>
|
||||
<t>Example:</t>
|
||||
|
||||
<artwork> http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
|
||||
<artwork><![CDATA[ http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
|
||||
----------------------------------------------------------------------------+--------------------------------------
|
||||
| @house{castle,
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | url = {https://y.io/z.fbx#castle}
|
||||
|
@ -687,11 +863,12 @@ XR Fragments does this by detecting Bib(s)Tex, without introducing a new languag
|
|||
| /|\ | |
|
||||
| / \ | |
|
||||
+--------+ |
|
||||
]]>
|
||||
</artwork>
|
||||
<blockquote><t>the <tt>#john@baroque</tt>-bib associates both text <tt>John</tt> and objectname <tt>john</tt>, with tag <tt>baroque</tt></t>
|
||||
</blockquote><t>Another example:</t>
|
||||
|
||||
<artwork> http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
|
||||
<artwork><![CDATA[ http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
|
||||
----------------------------------------------------------------------------+--------------------------------------
|
||||
|
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | @house{castle,
|
||||
|
@ -709,6 +886,7 @@ XR Fragments does this by detecting Bib(s)Tex, without introducing a new languag
|
|||
| #baroque@todo@house | | /|\ | |
|
||||
| ... | | / \ | |
|
||||
+----------------------------------------+ +--------+ |
|
||||
]]>
|
||||
</artwork>
|
||||
<blockquote><t>both <tt>#john@baroque</tt>-bib and BibTex <tt>@baroque{john}</tt> result in the same XRWG, however on top of that 2 tages (<tt>house</tt> and <tt>todo</tt>) are now associated with text/objectname/tag 'baroque'.</t>
|
||||
</blockquote><t>As seen above, the XRWG can expand <eref target="https://github.com/coderofsalvation/hashtagbibs">bibs</eref> (and the whole scene) to BibTeX.<br />
|
||||
|
@ -762,21 +940,22 @@ Some pointers for good UX (but not necessary to be XR Fragment compatible):</t>
|
|||
<blockquote><t>The simplicity of appending metadata (and leveling the metadata-playfield between humans and machines) is also demonstrated by <eref target="https://visual-meta.info">visual-meta</eref> in greater detail.</t>
|
||||
</blockquote><t>Fictional chat:</t>
|
||||
|
||||
<artwork><John> Hey what about this: https://my.com/station.gltf#pos=0,0,1&rot=90,2,0&t=500,1000
|
||||
<Sarah> I'm checking it right now
|
||||
<Sarah> I don't see everything..where's our text from yesterday?
|
||||
<John> Ah wait, that's tagged with tag 'draft' (and hidden)..hold on, try this:
|
||||
<John> https://my.com/station.gltf#.draft&pos=0,0,1&rot=90,2,0&t=500,1000
|
||||
<Sarah> how about we link the draft to the upcoming YELLO-event?
|
||||
<John> ok I'm adding #draft@YELLO
|
||||
<Sarah> Yesterday I also came up with other usefull assocations between other texts in the scene:
|
||||
<artwork><![CDATA[<John> Hey what about this: https://my.com/station.gltf#pos=0,0,1&rot=90,2,0&t=500,1000
|
||||
<Sarah> I'm checking it right now
|
||||
<Sarah> I don't see everything..where's our text from yesterday?
|
||||
<John> Ah wait, that's tagged with tag 'draft' (and hidden)..hold on, try this:
|
||||
<John> https://my.com/station.gltf#.draft&pos=0,0,1&rot=90,2,0&t=500,1000
|
||||
<Sarah> how about we link the draft to the upcoming YELLO-event?
|
||||
<John> ok I'm adding #draft@YELLO
|
||||
<Sarah> Yesterday I also came up with other usefull assocations between other texts in the scene:
|
||||
#event#YELLO
|
||||
#2025@YELLO
|
||||
<John> thanks, added.
|
||||
<Sarah> Btw. I stumbled upon this spatial book which references station.gltf in some chapters:
|
||||
<Sarah> https://thecommunity.org/forum/foo/mytrainstory.txt
|
||||
<John> interesting, I'm importing mytrainstory.txt into station.gltf
|
||||
<John> ah yes, chapter three points to trainterminal_2A in the scene, cool
|
||||
<John> thanks, added.
|
||||
<Sarah> Btw. I stumbled upon this spatial book which references station.gltf in some chapters:
|
||||
<Sarah> https://thecommunity.org/forum/foo/mytrainstory.txt
|
||||
<John> interesting, I'm importing mytrainstory.txt into station.gltf
|
||||
<John> ah yes, chapter three points to trainterminal_2A in the scene, cool
|
||||
]]>
|
||||
</artwork>
|
||||
|
||||
<section anchor="default-data-uri-mimetype"><name>Default Data URI mimetype</name>
|
||||
|
@ -812,7 +991,7 @@ to connect text further with its environment ( setup links between textual/spati
|
|||
|
||||
<section anchor="url-and-data-uri"><name>URL and Data URI</name>
|
||||
|
||||
<artwork> +--------------------------------------------------------------+ +------------------------+
|
||||
<artwork><![CDATA[ +--------------------------------------------------------------+ +------------------------+
|
||||
| | | author.com/article.txt |
|
||||
| index.gltf | +------------------------+
|
||||
| │ | | |
|
||||
|
@ -824,6 +1003,7 @@ to connect text further with its environment ( setup links between textual/spati
|
|||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
]]>
|
||||
</artwork>
|
||||
<t>The enduser will only see <tt>welcome human</tt> and <tt>Hello friends</tt> rendered verbatim (see mimetype).
|
||||
The beauty is that text in Data URI automatically promotes rich copy-paste (retaining metadata).
|
||||
|
@ -835,14 +1015,14 @@ The XR Fragment-compatible browser can let the enduser access visual-meta(data)-
|
|||
<section anchor="xr-text-example-parser"><name>XR Text example parser</name>
|
||||
<t>To prime the XRWG with text from plain text <tt>src</tt>-values, here's an example XR Text (de)multiplexer in javascript (which supports inline bibs & bibtex):</t>
|
||||
|
||||
<artwork>xrtext = {
|
||||
<artwork><![CDATA[xrtext = {
|
||||
|
||||
expandBibs: (text) => {
|
||||
expandBibs: (text) => {
|
||||
let bibs = { regex: /(#[a-zA-Z0-9_+@\-]+(#)?)/g, tags: {}}
|
||||
text.replace( bibs.regex , (m,k,v) => {
|
||||
tok = m.substr(1).split("@")
|
||||
text.replace( bibs.regex , (m,k,v) => {
|
||||
tok = m.substr(1).split("@")
|
||||
match = tok.shift()
|
||||
if( tok.length ) tok.map( (t) => bibs.tags[t] = `@${t}{${match},\n}` )
|
||||
if( tok.length ) tok.map( (t) => bibs.tags[t] = `@${t}{${match},\n}` )
|
||||
else if( match.substr(-1) == '#' )
|
||||
bibs.tags[match] = `@{${match.replace(/#/,'')}}`
|
||||
else bibs.tags[match] = `@${match}{${match},\n}`
|
||||
|
@ -850,16 +1030,16 @@ The XR Fragment-compatible browser can let the enduser access visual-meta(data)-
|
|||
return text.replace( bibs.regex, '') + Object.values(bibs.tags).join('\n')
|
||||
},
|
||||
|
||||
decode: (str) => {
|
||||
// bibtex: ↓@ ↓<tag|tag{phrase,|{ruler}> ↓property ↓end
|
||||
decode: (str) => {
|
||||
// bibtex: ↓@ ↓<tag|tag{phrase,|{ruler}> ↓property ↓end
|
||||
let pat = [ /@/, /^\S+[,{}]/, /},/, /}/ ]
|
||||
let tags = [], text='', i=0, prop=''
|
||||
let lines = xrtext.expandBibs(str).replace(/\r?\n/g,'\n').split(/\n/)
|
||||
for( let i = 0; i < lines.length && !String(lines[i]).match( /^@/ ); i++ )
|
||||
for( let i = 0; i < lines.length && !String(lines[i]).match( /^@/ ); i++ )
|
||||
text += lines[i]+'\n'
|
||||
|
||||
bibtex = lines.join('\n').substr( text.length )
|
||||
bibtex.split( pat[0] ).map( (t) => {
|
||||
bibtex.split( pat[0] ).map( (t) => {
|
||||
try{
|
||||
let v = {}
|
||||
if( !(t = t.trim()) ) return
|
||||
|
@ -868,9 +1048,9 @@ The XR Fragment-compatible browser can let the enduser access visual-meta(data)-
|
|||
if( tag.match( /}$/ ) ) return tags.push({k: tag.replace(/}$/,''), v: {}})
|
||||
t = t.substr( tag.length )
|
||||
t.split( pat[2] )
|
||||
.map( kv => {
|
||||
if( !(kv = kv.trim()) || kv == "}" ) return
|
||||
v[ kv.match(/\s?(\S+)\s?=/)[1] ] = kv.substr( kv.indexOf("{")+1 )
|
||||
.map( kv => {
|
||||
if( !(kv = kv.trim()) || kv == "}" ) return
|
||||
v[ kv.match(/\s?(\S+)\s?=/)[1] ] = kv.substr( kv.indexOf("{")+1 )
|
||||
})
|
||||
tags.push( { k:tag, v } )
|
||||
}catch(e){ console.error(e) }
|
||||
|
@ -878,8 +1058,8 @@ The XR Fragment-compatible browser can let the enduser access visual-meta(data)-
|
|||
return {text, tags}
|
||||
},
|
||||
|
||||
encode: (text,tags) => {
|
||||
let str = text+"\n"
|
||||
encode: (text,tags) => {
|
||||
let str = text+"\n"
|
||||
for( let i in tags ){
|
||||
let item = tags[i]
|
||||
if( item.ruler ){
|
||||
|
@ -893,11 +1073,12 @@ The XR Fragment-compatible browser can let the enduser access visual-meta(data)-
|
|||
return str
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</artwork>
|
||||
<t>The above functions (de)multiplexe text/metadata, expands bibs, (de)serialize bibtex and vice versa</t>
|
||||
<blockquote><t>above can be used as a startingpoint for LLVM's to translate/steelman to a more formal form/language.</t>
|
||||
</blockquote>
|
||||
<artwork>str = `
|
||||
<artwork><![CDATA[str = `
|
||||
hello world
|
||||
here are some hashtagbibs followed by bibtex:
|
||||
|
||||
|
@ -910,14 +1091,15 @@ here are some hashtagbibs followed by bibtex:
|
|||
asdf = {23423}
|
||||
}`
|
||||
|
||||
var {tags,text} = xrtext.decode(str) // demultiplex text & bibtex
|
||||
tags.find( (t) => t.k == 'flap{' ).v.asdf = 1 // edit tag
|
||||
var {tags,text} = xrtext.decode(str) // demultiplex text & bibtex
|
||||
tags.find( (t) => t.k == 'flap{' ).v.asdf = 1 // edit tag
|
||||
tags.push({ k:'bar{', v:{abc:123} }) // add tag
|
||||
console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back together
|
||||
console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back together
|
||||
]]>
|
||||
</artwork>
|
||||
<t>This expands to the following (hidden by default) BibTex appendix:</t>
|
||||
|
||||
<artwork>hello world
|
||||
<artwork><![CDATA[hello world
|
||||
here are some hashtagbibs followed by bibtex:
|
||||
|
||||
@{some-section}
|
||||
|
@ -932,6 +1114,7 @@ here are some hashtagbibs followed by bibtex:
|
|||
@bar{
|
||||
abc = {123}
|
||||
}
|
||||
]]>
|
||||
</artwork>
|
||||
<blockquote><t>when an XR browser updates the human text, a quick scan for nonmatching tags (<tt>@book{nonmatchingbook</tt> e.g.) should be performed and prompt the enduser for deleting them.</t>
|
||||
</blockquote></section>
|
||||
|
@ -948,25 +1131,26 @@ here are some hashtagbibs followed by bibtex:
|
|||
<blockquote><t>due to the popularity, maturity and extensiveness of HTTP codes for client/server communication, non-HTTP protocols easily map to HTTP codes (ipfs ERR_NOT_FOUND maps to 404 e.g.)</t>
|
||||
</blockquote><t>For example:</t>
|
||||
|
||||
<artwork> +────────────────────────────────────────────────────────+
|
||||
<artwork><![CDATA[ +────────────────────────────────────────────────────────+
|
||||
│ │
|
||||
│ index.gltf │
|
||||
│ │ │
|
||||
│ │ #: #q=-offlinetext │
|
||||
│ │ #: #-offlinetext │
|
||||
│ │ │
|
||||
│ ├── ◻ buttonA │
|
||||
│ │ └ href: http://foo.io/campagne.fbx │
|
||||
│ │ └ href@404: ipfs://foo.io/campagne.fbx │
|
||||
│ │ └ href@400: #q=clienterrortext │
|
||||
│ │ └ href@400: #clienterrortext │
|
||||
│ │ └ ◻ offlinetext │
|
||||
│ │ │
|
||||
│ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not)
|
||||
│ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not)
|
||||
│ └ src: https://foo.io/bar.gltf │ be flushed when the request (does not) succeed.
|
||||
│ └ src@404: http://foo.io/bar.gltf │ So worstcase the 3D data (of the time of publishing index.gltf)
|
||||
│ └ src@400: https://archive.org/l2kj43.gltf │ will be displayed.
|
||||
│ │
|
||||
+────────────────────────────────────────────────────────+
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
</section>
|
||||
|
||||
|
@ -982,12 +1166,12 @@ Consider 3D scenes linking to eachother using these <tt>href</tt> values:</t>
|
|||
</ul>
|
||||
<t>These links would all show visible links to math-tagged objects in the scene.<br />
|
||||
|
||||
To filter out non-related objects one could take it a step further using queries:</t>
|
||||
To filter out non-related objects one could take it a step further using filters:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li><tt>href: schoolA.edu/projects.gltf#math&q=-topics math</tt></li>
|
||||
<li><tt>href: schoolB.edu/projects.gltf#math&q=-courses math</tt></li>
|
||||
<li><tt>href: university.edu/projects.gltf#math&q=-theme math</tt></li>
|
||||
<li><tt>href: schoolA.edu/projects.gltf#math&-topics math</tt></li>
|
||||
<li><tt>href: schoolB.edu/projects.gltf#math&-courses math</tt></li>
|
||||
<li><tt>href: university.edu/projects.gltf#math&-theme math</tt></li>
|
||||
</ul>
|
||||
<blockquote><t>This would hide all object tagged with <tt>topic</tt>, <tt>courses</tt> or <tt>theme</tt> (including math) so that later only objects tagged with <tt>math</tt> will be visible</t>
|
||||
</blockquote><t>This makes spatial content multi-purpose, without the need to separate content into separate files, or show/hide things using a complex logiclayer like javascript.</t>
|
||||
|
@ -1028,6 +1212,15 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
|
|||
<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>
|
||||
<li>Michiel Leenaars</li>
|
||||
<li>Gerben van der Broeke</li>
|
||||
<li>Mauve</li>
|
||||
<li>Jens Finkhäuser</li>
|
||||
<li>Marc Belmont</li>
|
||||
<li>Tim Gerritsen</li>
|
||||
<li>Frode Hegland</li>
|
||||
<li>Brandel Zackernuk</li>
|
||||
<li>Mark Anderson</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
@ -1107,8 +1300,8 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>query</td>
|
||||
<td>an URI Fragment-operator which queries object(s) from a scene like <tt>#q=cube</tt></td>
|
||||
<td>filter</td>
|
||||
<td>URI Fragment(s) which show/hide object(s) in a scene based on name/tag/property (<tt>#cube&-price=>3</tt>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -1146,6 +1339,11 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to
|
|||
<td>obtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>flat 3D object</td>
|
||||
<td>a 3D object of which all verticies share a plane</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>BibTeX</td>
|
||||
<td>simple tagging/citing/referencing standard for plaintext</td>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
|
||||
Internet Engineering Task Force L.R. van Kammen
|
||||
Internet-Draft 12 October 2023
|
||||
Internet-Draft 6 December 2023
|
||||
Intended status: Informational
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ Status of This Memo
|
|||
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 14 April 2024.
|
||||
This Internet-Draft will expire on 8 June 2024.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
|
@ -53,9 +53,9 @@ Copyright Notice
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 14 April 2024 [Page 1]
|
||||
van Kammen Expires 8 June 2024 [Page 1]
|
||||
|
||||
Internet-Draft XR Macros October 2023
|
||||
Internet-Draft XR Macros December 2023
|
||||
|
||||
|
||||
extracted from this document must include Revised BSD License text as
|
||||
|
@ -109,13 +109,13 @@ Table of Contents
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 14 April 2024 [Page 2]
|
||||
van Kammen Expires 8 June 2024 [Page 2]
|
||||
|
||||
Internet-Draft XR Macros October 2023
|
||||
Internet-Draft XR Macros December 2023
|
||||
|
||||
|
||||
3. Metadata-values can contain the | symbol to 🎲 roundrobin
|
||||
variable values (!toggleme: fog=0,10|fog=0,1000 e.g.)
|
||||
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
|
||||
|
@ -165,9 +165,9 @@ Internet-Draft XR Macros October 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 14 April 2024 [Page 3]
|
||||
van Kammen Expires 8 June 2024 [Page 3]
|
||||
|
||||
Internet-Draft XR Macros October 2023
|
||||
Internet-Draft XR Macros December 2023
|
||||
|
||||
|
||||
+=========+======+===================+=================+=============+
|
||||
|
@ -221,9 +221,9 @@ Internet-Draft XR Macros October 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 14 April 2024 [Page 4]
|
||||
van Kammen Expires 8 June 2024 [Page 4]
|
||||
|
||||
Internet-Draft XR Macros October 2023
|
||||
Internet-Draft XR Macros December 2023
|
||||
|
||||
|
||||
Table 3
|
||||
|
@ -277,9 +277,9 @@ Internet-Draft XR Macros October 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 14 April 2024 [Page 5]
|
||||
van Kammen Expires 8 June 2024 [Page 5]
|
||||
|
||||
Internet-Draft XR Macros October 2023
|
||||
Internet-Draft XR Macros December 2023
|
||||
|
||||
|
||||
4.5. Usecase: present context menu with options
|
||||
|
@ -333,9 +333,9 @@ click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 14 April 2024 [Page 6]
|
||||
van Kammen Expires 8 June 2024 [Page 6]
|
||||
|
||||
Internet-Draft XR Macros October 2023
|
||||
Internet-Draft XR Macros December 2023
|
||||
|
||||
|
||||
| Note that only macro's can trigger roundrobin values or
|
||||
|
@ -375,7 +375,7 @@ Internet-Draft XR Macros October 2023
|
|||
| | (games,VR,AR e.g.), should be as high as |
|
||||
| | possible |
|
||||
+---------------+---------------------------------------------------+
|
||||
| ◻ | ascii representation of an 3D object/mesh |
|
||||
| ◻ | ascii representation of an 3D object/mesh |
|
||||
+---------------+---------------------------------------------------+
|
||||
| (un)obtrusive | obtrusive: wrapping human text/thought in |
|
||||
| | XML/HTML/JSON obfuscates human text into |
|
||||
|
@ -389,4 +389,4 @@ Internet-Draft XR Macros October 2023
|
|||
|
||||
|
||||
|
||||
van Kammen Expires 14 April 2024 [Page 7]
|
||||
van Kammen Expires 8 June 2024 [Page 7]
|
||||
|
|
|
@ -282,16 +282,17 @@ Macros also act as events, so more serious scripting languages can react to them
|
|||
<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> ◻
|
||||
<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> ◻
|
||||
<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.)?
|
||||
|
@ -299,6 +300,7 @@ Macros also act as events, so more serious scripting languages can react to them
|
|||
└── 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 />
|
||||
|
|
Loading…
Reference in New Issue