update documentation
This commit is contained in:
parent
cfcca8b66c
commit
723e7572cc
|
@ -18,7 +18,7 @@
|
|||
padding: 0% 20%;
|
||||
line-height: 30px;
|
||||
color:#555;
|
||||
background:#F0F0F3
|
||||
background:#F7F7F7;
|
||||
}
|
||||
h1 { margin-top:40px; }
|
||||
pre{ line-height:18px; }
|
||||
|
@ -80,8 +80,8 @@ value: draft-XRFRAGMENTS-leonvankammen-00
|
|||
|
||||
<h1 class="special" id="abstract">Abstract</h1>
|
||||
|
||||
<p>This draft offers a specification for 4D URLs & navigation, to link 3D scenes and text together with- or without a network-connection.<br>
|
||||
The specification promotes spatial addressibility, sharing, navigation, query-ing and tagging interactive (text)objects across for (XR) Browsers.<br>
|
||||
<p>This draft is a specification for 4D URLs & 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>
|
||||
|
||||
<blockquote>
|
||||
|
@ -97,7 +97,8 @@ XR Fragments allows us to enrich/connect existing dataformats, by recursive use
|
|||
|
||||
<ol>
|
||||
<li>addressibility and navigation of 3D scenes/objects: <a href="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</a> + src/href spatial metadata</li>
|
||||
<li>hasslefree tagging across text and spatial objects using <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/& 3D by collapsing space into a Word Graph (XRWG) (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>extend the hashtag-to-browser-viewport paradigm beyond 2D documents (XR documents)</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
|
@ -107,25 +108,112 @@ XR Fragments allows us to enrich/connect existing dataformats, by recursive use
|
|||
<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></p>
|
||||
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>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>principle</th>
|
||||
<th>XR 4D URL</th>
|
||||
<th>HTML 2D URL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>the XRWG</td>
|
||||
<td>wordgraph (collapses 3D scene to tags)</td>
|
||||
<td>Ctrl-F (find)</td>
|
||||
</tr>
|
||||
|
||||
<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>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>“When a car breaks down, the ones <strong>without</strong> turbosupercharger are easier to fix”</p>
|
||||
<p>XR Fragments does not look at XR (or the web) thru the lens of HTML.<br>But approaches things from a higherlevel browser-perspective:</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Let’s always focus on average humans: our fuzzy symbolical mind must be served first, before serving a greater <a href="https://en.wikipedia.org/wiki/Borg">categorized typesafe RDF hive mind</a>).</p>
|
||||
<pre><code> +----------------------------------------------------------------------------------------------+
|
||||
| |
|
||||
| the soul of any URL: ://macro /meso ?micro #nano |
|
||||
| |
|
||||
| 2D URL: ://library.com /document ?search #chapter |
|
||||
| |
|
||||
| 4D URL: ://park.com /4Dscene.fbx --> ?search --> #view ---> hashbus |
|
||||
| │ | |
|
||||
| XRWG <---------------------<------------+ |
|
||||
| │ | |
|
||||
| ├─ objects --------------->------------| |
|
||||
| └─ text --------------->------------+ |
|
||||
| |
|
||||
| |
|
||||
+----------------------------------------------------------------------------------------------+
|
||||
|
||||
<blockquote>
|
||||
<p>Humans first, machines (AI) later.</p>
|
||||
</blockquote>
|
||||
</code></pre>
|
||||
|
||||
<p>Thererfore, XR Fragments does not look at XR (or the web) thru the lens of HTML.<br>
|
||||
XR Fragments itself is HTML-agnostic, though pseudo-XR Fragment browsers <strong>can</strong> be implemented on top of HTML/Javascript.</p>
|
||||
<p>Traditional webbrowsers can become 4D document-ready by:</p>
|
||||
|
||||
<ul>
|
||||
<li>loading 3D assets (gltf/fbx e.g.) natively (not thru HTML).</li>
|
||||
<li>allowing assets to publish hashtags to themselves (the scene) using the hashbus (like hashtags controlling the scrollbar).</li>
|
||||
<li>collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus</li>
|
||||
</ul>
|
||||
|
||||
<p>XR Fragments itself is HTML-agnostic, though pseudo-XR Fragment browsers <strong>can</strong> be implemented on top of HTML/Javascript.</p>
|
||||
|
||||
<h1 id="conventions-and-definitions">Conventions and Definitions</h1>
|
||||
|
||||
<p>See appendix below in case certain terms are not clear.</p>
|
||||
|
||||
<h2 id="xr-fragment-uri-grammar">XR Fragment URI Grammar</h2>
|
||||
|
||||
<pre><code>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
</code></pre>
|
||||
|
||||
<blockquote>
|
||||
<p>Example: <code>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</code></p>
|
||||
</blockquote>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Demo</th>
|
||||
<th>Explanation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>pos=1,2,3</code></td>
|
||||
<td>vector/coordinate argument e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>pos=1,2,3&rot=0,90,0&q=.foo</code></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>this is already implemented in all browsers</p>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="list-of-uri-fragments">List of URI Fragments</h1>
|
||||
|
||||
<table>
|
||||
|
@ -143,7 +231,7 @@ XR Fragments itself is HTML-agnostic, though pseudo-XR Fragment browsers <strong
|
|||
<td><code>#pos</code></td>
|
||||
<td>vector3</td>
|
||||
<td><code>#pos=0.5,0,0</code></td>
|
||||
<td>positions camera to xyz-coord 0.5,0,0</td>
|
||||
<td>positions camera (or XR floor) to xyz-coord 0.5,0,0,</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -164,7 +252,7 @@ XR Fragments itself is HTML-agnostic, though pseudo-XR Fragment browsers <strong
|
|||
<td><code>#......</code></td>
|
||||
<td>string</td>
|
||||
<td><code>#.cubes</code> <code>#cube</code></td>
|
||||
<td>object(s) of interest (fragment to object name or class mapping)</td>
|
||||
<td>predefined views, XRWG fragments and ID fragments</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -194,9 +282,9 @@ XR Fragments itself is HTML-agnostic, though pseudo-XR Fragment browsers <strong
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>class</code></td>
|
||||
<td><code>tag</code></td>
|
||||
<td>string</td>
|
||||
<td><code>"class": "cubes"</code></td>
|
||||
<td><code>"tag": "cubes geo"</code></td>
|
||||
<td>available through custom property in 3D fileformats</td>
|
||||
</tr>
|
||||
|
||||
|
@ -210,7 +298,7 @@ XR Fragments itself is HTML-agnostic, though pseudo-XR Fragment browsers <strong
|
|||
<tr>
|
||||
<td><code>src</code></td>
|
||||
<td>string</td>
|
||||
<td><code>"src": "#q=cube"</code></td>
|
||||
<td><code>"src": "#cube"</code></td>
|
||||
<td>available through custom property in 3D fileformats</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -255,13 +343,13 @@ In case of <code>buttonA</code> the end-user will be teleported to another locat
|
|||
| │ └ src: painting.png | | ├─ ◻ bass |
|
||||
| │ | | └─ ◻ tuna |
|
||||
| ├── ◻ aquariumcube | | |
|
||||
| │ └ src: ://rescue.com/fish.gltf#q=bass%20tuna | +-------------------------+
|
||||
| │ └ src: ://rescue.com/fish.gltf#bass%20tuna | +-------------------------+
|
||||
| │ |
|
||||
| ├── ◻ bedroom |
|
||||
| │ └ src: #q=canvas |
|
||||
| │ └ src: #canvas |
|
||||
| │ |
|
||||
| └── ◻ livingroom |
|
||||
| └ src: #q=canvas |
|
||||
| └ src: #canvas |
|
||||
| |
|
||||
+--------------------------------------------------------+
|
||||
</code></pre>
|
||||
|
@ -270,33 +358,49 @@ In case of <code>buttonA</code> the end-user will be teleported to another locat
|
|||
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>
|
||||
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>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="xr-fragment-queries">XR Fragment queries</h1>
|
||||
|
||||
<p>Include, exclude, hide/shows objects using space-separated strings:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>#q=cube</code></li>
|
||||
<li><code>#q=cube -ball_inside_cube</code></li>
|
||||
<li><code>#q=* -sky</code></li>
|
||||
<li><code>#q=-.language .english</code></li>
|
||||
<li><code>#q=cube&rot=0,90,0</code></li>
|
||||
<li><code>#q=price:>2 price:<5</code></li>
|
||||
</ul>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>example</th>
|
||||
<th>outcome</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<p>It’s simple but powerful syntax which allows <b>css</b>-like class/id-selectors with a searchengine prompt-style feeling:</p>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>#q=-sky</code></td>
|
||||
<td>show everything except object named <code>sky</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>#q=-.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>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>It’s simple but powerful syntax which allows <b>css</b>-like tag/id-selectors with a searchengine prompt-style feeling:</p>
|
||||
|
||||
<ol>
|
||||
<li>queries are showing/hiding objects <strong>only</strong> when defined as <code>src</code> value (prevents sharing of scene-tampered URL’s).</li>
|
||||
<li>queries are highlighting objects when defined in the top-Level (browser) URL (bar).</li>
|
||||
<li>search words like <code>cube</code> and <code>foo</code> in <code>#q=cube foo</code> are matched against 3D object names or custom metadata-key(values)</li>
|
||||
<li>search words like <code>cube</code> and <code>foo</code> in <code>#q=cube foo</code> are matched against tags (BibTeX) inside plaintext <code>src</code> values like <code>@cube{redcube, ...</code> e.g.</li>
|
||||
<li><code>#</code> equals <code>#q=*</code></li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match class-metadata of 3D objects like <code>"class":"german"</code></li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match class-metadata of (BibTeX) tags in XR Text objects like <code>@german{KarlHeinz, ...</code> e.g.</li>
|
||||
<li>queries are a way to traverse a scene, and filter objects based on their tag- or property-values.</li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match tag-metadata of 3D objects like <code>"tag":"german"</code></li>
|
||||
<li>words starting with <code>.</code> like <code>.german</code> match tag-metadata of (BibTeX) tags in XR Text objects like <code>@german{KarlHeinz, ...</code> e.g.</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p><strong>For example</strong>: <code>#q=.foo</code> is a shorthand for <code>#q=class:foo</code>, which will select objects with custom property <code>class</code>:<code>foo</code>. Just a simple <code>#q=cube</code> will simply select an object named <code>cube</code>.</p>
|
||||
<p><strong>For example</strong>: <code>#q=.foo</code> is a shorthand for <code>#q=tag:foo</code>, which will select objects with custom property <code>tag</code>:<code>foo</code>. Just a simple <code>#q=cube</code> will simply select an object named <code>cube</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
<ul>
|
||||
|
@ -314,11 +418,6 @@ Resizing will be happen accordingly to its placeholder object <code>aquariumcube
|
|||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>*</code></td>
|
||||
<td>select all objects (only useful in <code>src</code> custom property)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>-</code></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
|
@ -331,7 +430,7 @@ Resizing will be happen accordingly to its placeholder object <code>aquariumcube
|
|||
|
||||
<tr>
|
||||
<td><code>.</code></td>
|
||||
<td>alias for <code>"class" :".foo"</code> equals <code>class:foo</code></td>
|
||||
<td>alias for <code>"tag" :".foo"</code> equals <code>tag:foo</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -363,9 +462,9 @@ Resizing will be happen accordingly to its placeholder object <code>aquariumcube
|
|||
<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 class selectors like <code>.foo</code> (reference regex: <code>/^[-]?class$/</code> )</li>
|
||||
<li>detect tag selectors like <code>.foo</code> (reference regex: <code>/^[-]?tag$/</code> )</li>
|
||||
<li>detect number values like <code>foo:1</code> (reference regex: <code>/^[0-9\.]+$/</code> )</li>
|
||||
<li>expand aliases like <code>.foo</code> into <code>class:foo</code></li>
|
||||
<li>expand aliases like <code>.foo</code> into <code>tag:foo</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>
|
||||
|
@ -380,137 +479,285 @@ Resizing will be happen accordingly to its placeholder object <code>aquariumcube
|
|||
<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>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="xr-fragment-uri-grammar">XR Fragment URI Grammar</h2>
|
||||
<h1 id="embedding-content-src-instancing">Embedding content (src-instancing)</h1>
|
||||
|
||||
<pre><code>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
</code></pre>
|
||||
|
||||
<blockquote>
|
||||
<p>Example: <code>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</code></p>
|
||||
</blockquote>
|
||||
<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>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Demo</th>
|
||||
<th>Explanation</th>
|
||||
<th>fragment</th>
|
||||
<th>type</th>
|
||||
<th>example value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>pos=1,2,3</code></td>
|
||||
<td>vector/coordinate argument e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>pos=1,2,3&rot=0,90,0&q=.foo</code></td>
|
||||
<td>combinators</td>
|
||||
<td><code>src</code></td>
|
||||
<td>string (uri or [[predefined view</td>
|
||||
<td>predefined_view]] or [[query</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<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>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> (file) 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>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>when only one object was cherrypicked (<code>#cube</code> e.g.), set its position to <code>0,0,0</code></li>
|
||||
</ol>
|
||||
|
||||
<ul>
|
||||
<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>
|
||||
</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>
|
||||
|
||||
<h2 id="referencing-content-href-portals">Referencing content (href portals)</h2>
|
||||
|
||||
<p>navigation, portals & mutations</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>fragment</th>
|
||||
<th>type</th>
|
||||
<th>example value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>href</code></td>
|
||||
<td>string (uri or predefined view)</td>
|
||||
<td><code>#pos=1,1,0</code><br><code>#pos=1,1,0&rot=90,0,0</code><br><code>://somefile.gltf#pos=1,1,0</code><br></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<ol>
|
||||
<li><p>clicking an “external”- or “file URI” fully replaces the current scene and assumes <code>pos=0,0,0&rot=0,0,0</code> by default (unless specified)</p></li>
|
||||
|
||||
<li><p>relocation/reorientation should happen locally for local URI’s (<code>#pos=....</code>)</p></li>
|
||||
|
||||
<li><p>navigation should not happen “immediately” when user is more than 2 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)</p></li>
|
||||
|
||||
<li><p>URL navigation should always be reflected in the client (in case of javascript: see [<a href="https://github.com/coderofsalvation/xrfragment/blob/dev/src/3rd/js/three/navigator.js">here</a> for an example navigator).</p></li>
|
||||
|
||||
<li><p>In XR mode, the navigator back/forward-buttons should be always visible (using a wearable e.g., see [<a href="https://github.com/coderofsalvation/xrfragment/blob/dev/example/aframe/sandbox/index.html#L26-L29">here</a> for an example wearable)</p></li>
|
||||
|
||||
<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>
|
||||
</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="scaling-instanced-content">Scaling instanced content</h2>
|
||||
|
||||
<p>Sometimes embedded properties (like [[href|href]] or [[src|src]]) instance new objects.<br>
|
||||
But what about their scale?<br>
|
||||
How does the scale of the object (with the embedded properties) impact the scale of the referenced content?<br></p>
|
||||
|
||||
<blockquote>
|
||||
<p>Rule of thumb: visible placeholder objects act as a ‘3D canvas’ for the referenced scene (a plane acts like a 2D canvas for images e, a cube as a 3D canvas e.g.).</p>
|
||||
</blockquote>
|
||||
|
||||
<ol>
|
||||
<li><b>IF</b> an embedded property (<code>src</code> e.g.) is set on an non-empty placeholder object (geometry of >2 vertices):</li>
|
||||
</ol>
|
||||
|
||||
<ul>
|
||||
<li>calculate the <b>bounding box</b> of the “placeholder” object (maxsize=1.4 e.g.)</li>
|
||||
<li>hide the “placeholder” object (material e.g.)</li>
|
||||
<li>instance the <code>src</code> scene as a child of the existing object</li>
|
||||
<li>calculate the <b>bounding box</b> of the instanced scene, and scale it accordingly (to 1.4 e.g.)</li>
|
||||
</ul>
|
||||
|
||||
<blockquote>
|
||||
<p>REASON: non-empty placeholder object can act as a protective bounding-box (for remote content of which might grow over time e.g.)</p>
|
||||
</blockquote>
|
||||
|
||||
<ol start="2">
|
||||
<li>ELSE multiply the scale-vector of the instanced scene with the scale-vector of the <b>placeholder</b> object.</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p>TODO: needs intermediate visuals to make things more obvious</p>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="text-in-xr-tagging-linking-to-spatial-objects">Text in XR (tagging,linking to spatial objects)</h1>
|
||||
|
||||
<p>We still think and speak in simple text, not in HTML or RDF.<br>
|
||||
The most advanced human will probably not shout <code><h1>FIRE!</h1></code> in case of emergency.<br>
|
||||
Given the new dawn of (non-keyboard) XR interfaces, keeping text as is (not obscuring with markup) is preferred.<br>
|
||||
Ideally metadata must come <strong>with</strong> text, but not <strong>obfuscate</strong> the text, or <strong>in another</strong> file.<br></p>
|
||||
|
||||
<p>This way:</p>
|
||||
|
||||
<ol>
|
||||
<li>XR Fragments allows <b id="tagging-text">hasslefree spatial tagging</b>, by detecting BibTeX metadata <strong>at the end of content</strong> of text (see default mimetype & Data URI)</li>
|
||||
<li>XR Fragments allows <b id="tagging-objects">hasslefree spatial tagging</b>, by treating 3D object name/class-pairs as BibTeX tags.</li>
|
||||
<li>XR Fragments allows hasslefree <a href="#textual-tag">textual tagging</a>, <a href="#spatial-tag">spatial tagging</a>, and <a href="#supra-tagging">supra tagging</a>, by mapping 3D/text object (class)names using BibTeX ‘tags’</li>
|
||||
<li>BibTex & Hashtagbibs are the first-choice <strong>requestless metadata</strong>-layer for XR text, HTML/RDF/JSON is great (but fits better in the application-layer)</li>
|
||||
<li>Default font (unless specified otherwise) is a modern monospace font, for maximized tabular expressiveness (see <a href="#core-principle">the core principle</a>).</li>
|
||||
<li>anti-pattern: hardcoupling a mandatory <strong>obtrusive markuplanguage</strong> or framework with an XR browsers (HTML/VRML/Javascript) (see <a href="#core-principle">the core principle</a>)</li>
|
||||
<li>anti-pattern: limiting human introspection, by immediately funneling human thought into typesafe, precise, pre-categorized metadata like RDF (see <a href="#core-principle">the core principle</a>)</li>
|
||||
</ol>
|
||||
|
||||
<p>This allows recursive connections between text itself, as well as 3D objects and vice versa, using <strong>BibTags</strong> :</p>
|
||||
|
||||
<pre><code> http://y.io/z.fbx | (Evaluated) BibTex/ 'wires' / tags |
|
||||
----------------------------------------------------------------------------+-------------------------------------
|
||||
| @house{castle,
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | url = {https://y.io/z.fbx#castle}
|
||||
| My Notes | | / \ | | }
|
||||
| | | / \ | | @baroque{castle,
|
||||
| The houses are built in baroque style. | | / \ | | url = {https://y.io/z.fbx#castle}
|
||||
| | | |_____| | | }
|
||||
| @house{baroque, | +-----│-----+ | @house{baroque,
|
||||
| description = {classic} | ├─ name: castle | description = {classic}
|
||||
| } | └─ class: house baroque | }
|
||||
+----------------------------------------+ | @house{contactowner,
|
||||
| }
|
||||
+-[remotestorage.io / localstorage]------+ | @todo{contactowner,
|
||||
| #contactowner@todo@house | | }
|
||||
| ... | |
|
||||
+----------------------------------------+ |
|
||||
</code></pre>
|
||||
|
||||
<p>BibTex (generated from 3D objects), can be extended by the enduser with personal BiBTex or <a href="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs</a>.</p>
|
||||
<p>How does XR Fragments interlink text with objects?</p>
|
||||
|
||||
<blockquote>
|
||||
<p><a href="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs</a> allows the enduser to add ‘postit’ connections (compressed BibTex) by speaking/typing/scanning text, which the XR Browser saves to remotestorage (or localStorage per toplevel URL). As well as, referencing BibTags per URI later on: <code>https://y.io/z.fbx#@baroque@todo</code> e.g.</p>
|
||||
<p>The XR Fragments does this by collapsing space into a <strong>Word Graph</strong> (the <strong>XRWG</strong>), augmented by Bib(s)Tex.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Obviously, expressing the relationships above in XML/JSON instead of BibTeX, would cause instant cognitive overload.<br>
|
||||
The This allows instant realtime filtering of relationships at various levels:</p>
|
||||
<p>Instead of just throwing together all kinds media types into one experience (games), what about the intrinsic connections between them?<br>
|
||||
Why is HTML adopted less in games outside the browser?
|
||||
Through the lens of game-making, ideally metadata must come <strong>with</strong> that text, but not <strong>obfuscate</strong> the text, or <strong>spawning another request</strong> to fetch it.<br>
|
||||
XR Fragments does this by detecting Bib(s)Tex, without introducing a new language or fileformat<br></p>
|
||||
|
||||
<blockquote>
|
||||
<p>Why Bib(s)Tex? Because its seems to be the lowest common denominator for an human-curated XRWG (extendable by speech/scanner/writing/typing e.g, see <a href="https://github.com/coderofsalvation/hashtagbibs#bibs--bibtex-combo-lowest-common-denominator-for-linking-data">further motivation here</a>)</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Hence:</p>
|
||||
|
||||
<ol>
|
||||
<li>XR Fragments promotes (de)serializing a scene to the XRWG</li>
|
||||
<li>XR Fragments primes the XRWG, by collecting words from the <code>tag</code> and name-property of 3D objects.</li>
|
||||
<li>XR Fragments primes the XRWG, by collecting words from <strong>optional</strong> metadata <strong>at the end of content</strong> of text (see default mimetype & Data URI)</li>
|
||||
<li><a href="https://github.com/coderofsalvation/hashtagbibs">Bib’s</a> and BibTex are first tag citizens for priming the XRWG with words (from XR text)</li>
|
||||
<li>Like Bibs, XR Fragments generalizes the BibTex author/title-semantics (<code>author{title}</code>) into <strong>this</strong> points to <strong>that</strong> (<code>this{that}</code>)</li>
|
||||
<li>The XRWG should be recalculated when textvalues (in <code>src</code>) change</li>
|
||||
<li>HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer)</li>
|
||||
<li>Applications don’t have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes.</li>
|
||||
<li>The XR Fragment focuses on fast and easy-to-generate end-user controllable word graphs (instead of complex implementations that try to defeat word ambiguity)</li>
|
||||
</ol>
|
||||
|
||||
<p>Example:</p>
|
||||
|
||||
<pre><code> http://y.io/z.fbx | Derived XRWG (shown as BibTex)
|
||||
----------------------------------------------------------------------------+--------------------------------------
|
||||
| @house{castle,
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | url = {https://y.io/z.fbx#castle}
|
||||
| Chapter one | | / \ | | }
|
||||
| | | / \ | | @baroque{castle,
|
||||
| John built houses in baroque style. | | / \ | | url = {https://y.io/z.fbx#castle}
|
||||
| | | |_____| | | }
|
||||
| #john@baroque | +-----│-----+ | @baroque{john}
|
||||
| | │ |
|
||||
| | ├─ name: castle |
|
||||
| | └─ tag: house baroque |
|
||||
+----------------------------------------+ |
|
||||
[3D mesh ] |
|
||||
| O ├─ name: john |
|
||||
| /|\ | |
|
||||
| / \ | |
|
||||
+--------+ |
|
||||
</code></pre>
|
||||
|
||||
<blockquote>
|
||||
<p>the <code>#john@baroque</code>-bib associates both text <code>John</code> and objectname <code>john</code>, with tag <code>baroque</code></p>
|
||||
</blockquote>
|
||||
|
||||
<p>Another example:</p>
|
||||
|
||||
<pre><code> http://y.io/z.fbx | Derived XRWG (printed as BibTex)
|
||||
----------------------------------------------------------------------------+--------------------------------------
|
||||
|
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | @house{castle,
|
||||
| Chapter one | | / \ | | url = {https://y.io/z.fbx#castle}
|
||||
| | | / \ | | }
|
||||
| John built houses in baroque style. | | / \ | | @baroque{castle,
|
||||
| | | |_____| | | url = {https://y.io/z.fbx#castle}
|
||||
| #john@baroque | +-----│-----+ | }
|
||||
| @baroque{john} | │ | @baroque{john}
|
||||
| | ├─ name: castle |
|
||||
| | └─ tag: house baroque |
|
||||
+----------------------------------------+ | @house{baroque}
|
||||
[3D mesh ] | @todo{baroque}
|
||||
+-[remotestorage.io / localstorage]------+ | O + name: john |
|
||||
| #baroque@todo@house | | /|\ | |
|
||||
| ... | | / \ | |
|
||||
+----------------------------------------+ +--------+ |
|
||||
</code></pre>
|
||||
|
||||
<blockquote>
|
||||
<p>both <code>#john@baroque</code>-bib and BibTex <code>@baroque{john}</code> result in the same XRWG, however on top of that 2 tages (<code>house</code> and <code>todo</code>) are now associated with text/objectname/tag ‘baroque’.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>As seen above, the XRWG can expand <a href="https://github.com/coderofsalvation/hashtagbibs">bibs</a> (and the whole scene) to BibTeX.<br>
|
||||
This allows hasslefree authoring and copy-paste of associations <strong>for and by humans</strong>, but also makes these URLs possible:</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>scope</th>
|
||||
<th>matching algo</th>
|
||||
<th>URL example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b id="textual-tagging">textual</b></td>
|
||||
<td>text containing ‘baroque’ is now automatically tagged with ‘house’ (incl. plaintext <code>src</code> child nodes)</td>
|
||||
<td><code>https://my.com/foo.gltf#.baroque</code></td>
|
||||
<td>highlights mesh <code>john</code>, 3D mesh <code>castle</code>, text <code>John built(..)</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b id="spatial-tagging">spatial</b></td>
|
||||
<td>spatial object(s) with name <code>baroque</code> or <code>"class":"house"</code> are now automatically tagged with ‘house’ (incl. child nodes)</td>
|
||||
<td><code>https://my.com/foo.gltf#john</code></td>
|
||||
<td>highlights mesh <code>john</code>, and the text <code>John built (..)</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b id="supra-tagging">supra</b></td>
|
||||
<td>text- or spatial-object(s) (non-descendant nodes) elsewhere, (class)named ‘baroque’ or ‘house’, are automatically tagged with ‘house’ (current node to root nodes)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b id="omni-tagging">omni</b></td>
|
||||
<td>text- or spatial-object(s) (non-descendant nodes) elsewhere, (class)named ‘baroque’ or ‘house’, are automatically tagged with ‘house’ (too node to all nodes)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b id="infinite-tagging">infinite</b></td>
|
||||
<td>text- or spatial-object(s) (non-descendant nodes) elsewhere, (class)named ‘baroque’ or ‘house’, are automatically tagged with ‘house’ (too node to all nodes)</td>
|
||||
<td><code>https://my.com/foo.gltf#house</code></td>
|
||||
<td>highlights mesh <code>castle</code>, and other objects with tag <code>house</code> or <code>todo</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>BibTex allows the enduser to adjust different levels of associations (see <a href="#core-principle">the core principle</a>): spatial wires can be rendered, words can be highlighted, spatial objects can be highlighted/moved/scaled, links can be manipulated by the user.<br></p>
|
||||
|
||||
<blockquote>
|
||||
<p>NOTE: infinite matches both ‘baroque’ and ‘style’-occurences in text, as well as spatial objects with <code>"class":"style"</code> or name “baroque”. This multiplexing of id/category is deliberate because of <a href="#core-principle">the core principle</a>.</p>
|
||||
<p><a href="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs</a> potentially allow the enduser to annotate text/objects by <strong>speaking/typing/scanning associations</strong>, which the XR Browser saves to remotestorage (or localStorage per toplevel URL). As well as, referencing BibTags per URI later on: <code>https://y.io/z.fbx#@baroque@todo</code> e.g.</p>
|
||||
</blockquote>
|
||||
|
||||
<ol start="8">
|
||||
<p>The XRWG allows XR Browsers to show/hide relationships in realtime at various levels:</p>
|
||||
|
||||
<ul>
|
||||
<li>wordmatch <strong>inside</strong> <code>src</code> text</li>
|
||||
<li>wordmatch <strong>inside</strong> <code>href</code> text</li>
|
||||
<li>wordmatch object-names</li>
|
||||
<li>wordmatch object-tagnames</li>
|
||||
</ul>
|
||||
|
||||
<p>Spatial wires can be rendered, words/objects can be highlighted/scaled etc.<br>
|
||||
Some pointers for good UX (but not necessary to be XR Fragment compatible):</p>
|
||||
|
||||
<ol start="9">
|
||||
<li>The XR Browser needs to adjust tag-scope based on the endusers needs/focus (infinite tagging only makes sense when environment is scaled down significantly)</li>
|
||||
<li>The XR Browser should always allow the human to view/edit the metadata, by clicking ‘toggle metadata’ on the ‘back’ (contextmenu e.g.) of any XR text, anywhere anytime.</li>
|
||||
<li>respect multi-line BiBTeX metadata in text because of <a href="#core-principle">the core principle</a></li>
|
||||
<li>Default font (unless specified otherwise) is a modern monospace font, for maximized tabular expressiveness (see <a href="#core-principle">the core principle</a>).</li>
|
||||
<li>anti-pattern: hardcoupling an XR Browser with a mandatory <strong>markup/scripting-language</strong> which departs from onubtrusive plain text (HTML/VRML/Javascript) (see <a href="#core-principle">the core principle</a>)</li>
|
||||
<li>anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.</li>
|
||||
</ol>
|
||||
|
||||
<blockquote>
|
||||
<p>The simplicity of appending BibTeX (and leveling the metadata-playfield between humans and machines) is also demonstrated by <a href="https://visual-meta.info">visual-meta</a> in greater detail.</p>
|
||||
<p>The simplicity of appending metadata (and leveling the metadata-playfield between humans and machines) is also demonstrated by <a href="https://visual-meta.info">visual-meta</a> in greater detail.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Fictional chat:</p>
|
||||
|
||||
<pre><code><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
|
||||
</code></pre>
|
||||
|
||||
<h2 id="default-data-uri-mimetype">Default Data URI mimetype</h2>
|
||||
|
||||
<p>The <code>src</code>-values work as expected (respecting mime-types), however:</p>
|
||||
|
@ -527,12 +774,13 @@ The This allows instant realtime filtering of relationships at various levels:</
|
|||
|
||||
<ul>
|
||||
<li>utf-8 is supported by default</li>
|
||||
<li><a href="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs</a> are expanded to <a href="https://en.wikipedia.org/wiki/BibTeX">bibtags</a></li>
|
||||
<li>lines matching regex <code>^@</code> will automatically get filtered out, in order to:</li>
|
||||
<li>links between textual/spatial objects can automatically be detected</li>
|
||||
<li>bibtag appendices (<a href="https://visual-meta.info">visual-meta</a> can be interpreted e.g.</li>
|
||||
<li>lines beginning with <code>@</code> will not be rendered verbatim by default (<a href="https://github.com/coderofsalvation/hashtagbibs#hashtagbib-mimetypes">read more</a>)</li>
|
||||
<li>the XRWG should expand bibs to BibTex occurring in text (<code>#contactjohn@todo@important</code> e.g.)</li>
|
||||
</ul>
|
||||
|
||||
<p>By doing so, the XR Browser (applications-layer) can interpret microformats (<a href="https://visual-meta.info">visual-meta</a>
|
||||
to connect text further with its environment ( setup links between textual/spatial objects automatically e.g.).</p>
|
||||
|
||||
<blockquote>
|
||||
<p>for more info on this mimetype see <a href="https://github.com/coderofsalvation/hashtagbibs">bibs</a></p>
|
||||
</blockquote>
|
||||
|
@ -540,6 +788,7 @@ The This allows instant realtime filtering of relationships at various levels:</
|
|||
<p>Advantages:</p>
|
||||
|
||||
<ul>
|
||||
<li>auto-expanding of <a href="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs</a> associations</li>
|
||||
<li>out-of-the-box (de)multiplex human text and metadata in one go (see <a href="#core-principle">the core principle</a>)</li>
|
||||
<li>no network-overhead for metadata (see <a href="#core-principle">the core principle</a>)</li>
|
||||
<li>ensuring high FPS: HTML/RDF historically is too ‘requesty’/‘parsy’ for game studios</li>
|
||||
|
@ -561,193 +810,26 @@ The This allows instant realtime filtering of relationships at various levels:</
|
|||
| │ | | |
|
||||
| ├── ◻ article_canvas | | Hello friends. |
|
||||
| │ └ src: ://author.com/article.txt | | |
|
||||
| │ | | @friend{friends |
|
||||
| │ | | @book{greatgatsby |
|
||||
| └── ◻ note_canvas | | ... |
|
||||
| └ src:`data:welcome human\n@...` | | } |
|
||||
| └ src:`data:welcome human\n@book{sunday...}` | | } |
|
||||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
</code></pre>
|
||||
|
||||
<p>The enduser will only see <code>welcome human</code> and <code>Hello friends</code> rendered spatially (see mimetype).
|
||||
<p>The enduser will only see <code>welcome human</code> and <code>Hello friends</code> rendered verbatim (see mimetype).
|
||||
The beauty is that text in Data URI automatically promotes rich copy-paste (retaining metadata).
|
||||
In both cases, the text gets rendered immediately (onto a plane geometry, hence the name ‘_canvas’).
|
||||
The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.).</p>
|
||||
|
||||
<blockquote>
|
||||
<p>additional tagging using <a href="https://github.com/coderofsalvation/hashtagbibs">bibs</a>: to tag spatial object <code>note_canvas</code> with ‘todo’, the enduser can type or speak <code>@note_canvas@todo</code></p>
|
||||
<p>additional tagging using <a href="https://github.com/coderofsalvation/hashtagbibs">bibs</a>: to tag spatial object <code>note_canvas</code> with ‘todo’, the enduser can type or speak <code>#note_canvas@todo</code></p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="bibs-bibtex-lowest-common-denominator-for-linking-data">Bibs & BibTeX: lowest common denominator for linking data</h2>
|
||||
|
||||
<blockquote>
|
||||
<p>“When a car breaks down, the ones <strong>without</strong> turbosupercharger are easier to fix”</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Unlike XML or JSON, BibTex is typeless, unnested, and uncomplicated, hence a great advantage for introspection.<br>
|
||||
It’s a missing sensemaking precursor to extrospective RDF.<br>
|
||||
BibTeX-appendices are already used in the digital AND physical world (academic books, <a href="https://visual-meta.info">visual-meta</a>), perhaps due to its terseness & simplicity.<br>
|
||||
In that sense, it’s one step up from the <code>.ini</code> fileformat (which has never leaked into the physical world like BibTex):</p>
|
||||
|
||||
<ol>
|
||||
<li><b id="frictionless-copy-paste">frictionless copy/pasting</b> (by humans) of (unobtrusive) content AND metadata</li>
|
||||
<li>an introspective ‘sketchpad’ for metadata, which can (optionally) mature into RDF later</li>
|
||||
</ol>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>characteristic</th>
|
||||
<th>UTF8 Plain Text (with BibTeX)</th>
|
||||
<th>RDF</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>perspective</td>
|
||||
<td>introspective</td>
|
||||
<td>extrospective</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>structure</td>
|
||||
<td>fuzzy (sensemaking)</td>
|
||||
<td>precise</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>space/scope</td>
|
||||
<td>local</td>
|
||||
<td>world</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>everything is text (string)</td>
|
||||
<td>yes</td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>voice/paper-friendly</td>
|
||||
<td><a href="https://github.com/coderofsalvation/hashtagbibs">bibs</a></td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>leaves (dictated) text intact</td>
|
||||
<td>yes</td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>markup language</td>
|
||||
<td>just an appendix</td>
|
||||
<td>~4 different</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>polyglot format</td>
|
||||
<td>no</td>
|
||||
<td>yes</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>easy to copy/paste content+metadata</td>
|
||||
<td>yes</td>
|
||||
<td>up to application</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>easy to write/repair for layman</td>
|
||||
<td>yes</td>
|
||||
<td>depends</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>easy to (de)serialize</td>
|
||||
<td>yes (fits on A4 paper)</td>
|
||||
<td>depends</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>infrastructure</td>
|
||||
<td>selfcontained (plain text)</td>
|
||||
<td>(semi)networked</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>freeform tagging/annotation</td>
|
||||
<td>yes, terse</td>
|
||||
<td>yes, verbose</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>can be appended to text-content</td>
|
||||
<td>yes</td>
|
||||
<td>up to application</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>copy-paste text preserves metadata</td>
|
||||
<td>yes</td>
|
||||
<td>up to application</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>emoji</td>
|
||||
<td>yes</td>
|
||||
<td>depends on encoding</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>predicates</td>
|
||||
<td>free</td>
|
||||
<td>semi pre-determined</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>implementation/network overhead</td>
|
||||
<td>no</td>
|
||||
<td>depends</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>used in (physical) books/PDF</td>
|
||||
<td>yes (visual-meta)</td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>terse non-verb predicates</td>
|
||||
<td>yes</td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nested structures</td>
|
||||
<td>no (but: BibTex rulers)</td>
|
||||
<td>yes</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<blockquote>
|
||||
<p>To keep XR Fragments a lightweight spec, BibTeX is used for rudimentary text/spatial tagging (not JSON, RDF or a scripting language because they’re harder to write/speak/repair.).</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Of course, on an application-level JSON(LD / RDF) can still be used at will, by embedding RDF-urls/data as custom properties (but is not interpreted by this spec).</p>
|
||||
|
||||
<h2 id="xr-text-example-parser">XR Text example parser</h2>
|
||||
|
||||
<ol>
|
||||
<li>The XR Fragments spec does not aim to harden the BiBTeX format</li>
|
||||
<li>respect multi-line BibTex values because of <a href="#core-principle">the core principle</a></li>
|
||||
<li>Respect hashtag(bibs) and rulers (like <code>${visual-meta-start}</code>) according to the <a href="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs spec</a></li>
|
||||
<li>BibTeX snippets should always start in the beginning of a line (regex: ^@), hence mimetype <code>text/plain;charset=utf-8;bib=^@</code></li>
|
||||
</ol>
|
||||
|
||||
<p>Here’s an XR Text (de)multiplexer in javascript, which ticks all the above boxes:</p>
|
||||
<p>To prime the XRWG with text from plain text <code>src</code>-values, here’s an example XR Text (de)multiplexer in javascript (which supports inline bibs & bibtex):</p>
|
||||
|
||||
<pre><code>xrtext = {
|
||||
|
||||
|
@ -779,6 +861,7 @@ In that sense, it’s one step up from the <code>.ini</code> fileformat (whi
|
|||
if( !(t = t.trim()) ) return
|
||||
if( tag = t.match( pat[1] ) ) tag = tag[0]
|
||||
if( tag.match( /^{.*}$/ ) ) return tags.push({ruler:tag})
|
||||
if( tag.match( /}$/ ) ) return tags.push({k: tag.replace(/}$/,''), v: {}})
|
||||
t = t.substr( tag.length )
|
||||
t.split( pat[2] )
|
||||
.map( kv => {
|
||||
|
@ -808,7 +891,7 @@ In that sense, it’s one step up from the <code>.ini</code> fileformat (whi
|
|||
}
|
||||
</code></pre>
|
||||
|
||||
<p>The above functions (de)multiplexe text/metadata, expands bibs, (de)serialize bibtex (and all fits more or less on one A4 paper)</p>
|
||||
<p>The above functions (de)multiplexe text/metadata, expands bibs, (de)serialize bibtex and vice versa</p>
|
||||
|
||||
<blockquote>
|
||||
<p>above can be used as a startingpoint for LLVM’s to translate/steelman to a more formal form/language.</p>
|
||||
|
@ -856,24 +939,12 @@ here are some hashtagbibs followed by bibtex:
|
|||
<p>when an XR browser updates the human text, a quick scan for nonmatching tags (<code>@book{nonmatchingbook</code> e.g.) should be performed and prompt the enduser for deleting them.</p>
|
||||
</blockquote>
|
||||
|
||||
<h1 id="hyper-copy-paste">HYPER copy/paste</h1>
|
||||
|
||||
<p>The previous example, offers something exciting compared to simple copy/paste of 3D objects or text.
|
||||
XR Text according to the XR Fragment spec, allows HYPER-copy/paste: time, space and text interlinked.
|
||||
Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share data in these ways:</p>
|
||||
|
||||
<ol>
|
||||
<li>time/space: 3D object (current animation-loop)</li>
|
||||
<li>text: TeXt object (including BibTeX/visual-meta if any)</li>
|
||||
<li>interlinked: Collected objects by visual-meta tag</li>
|
||||
</ol>
|
||||
|
||||
<h1 id="security-considerations">Security Considerations</h1>
|
||||
|
||||
<p>Since XR Text contains metadata too, the user should be able to set up tagging-rules, so the copy-paste feature can :</p>
|
||||
|
||||
<ul>
|
||||
<li>filter out sensitive data when copy/pasting (XR text with <code>class:secret</code> e.g.)</li>
|
||||
<li>filter out sensitive data when copy/pasting (XR text with <code>tag:secret</code> e.g.)</li>
|
||||
</ul>
|
||||
|
||||
<h1 id="iana-considerations">IANA Considerations</h1>
|
||||
|
@ -924,6 +995,26 @@ Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share
|
|||
<td>URI Fragment with spatial hints like <code>#pos=0,0,0&t=1,100</code> e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>the XRWG</td>
|
||||
<td>wordgraph (collapses 3D scene to tags)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>the hashbus</td>
|
||||
<td>hashtags map to camera/scene-projections</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>spacetime hashtags</td>
|
||||
<td>positions camera, triggers scene-preset/time</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>placeholder object</td>
|
||||
<td>a 3D object which with src-metadata (which will be replaced by the src-data.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>src</td>
|
||||
<td>(HTML-piggybacked) metadata of a 3D object which instances content</td>
|
||||
|
@ -986,7 +1077,7 @@ Therefore, the enduser in an XR Fragment-compatible browser can copy/paste/share
|
|||
|
||||
<tr>
|
||||
<td>(hashtag)bibs</td>
|
||||
<td>an easy to speak/type/scan tagging SDL (<a href="https://github.com/coderofsalvation/hashtagbibs">see here</a></td>
|
||||
<td>an easy to speak/type/scan tagging SDL (<a href="https://github.com/coderofsalvation/hashtagbibs">see here</a> which expands to BibTex/JSON/XML</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -30,7 +30,7 @@ fullname="L.R. van Kammen"
|
|||
padding: 0% 20%;
|
||||
line-height: 30px;
|
||||
color:#555;
|
||||
background:#F0F0F3
|
||||
background:#F7F7F7;
|
||||
}
|
||||
h1 { margin-top:40px; }
|
||||
pre{ line-height:18px; }
|
||||
|
@ -181,10 +181,10 @@ sub-delims = "," / "="
|
|||
|
||||
| fragment | type | example | info |
|
||||
|--------------|----------|-------------------|---------------------------------------------------------------------|
|
||||
| `#pos` | vector3 | `#pos=0.5,0,0` | positions camera to xyz-coord 0.5,0,0 |
|
||||
| `#pos` | vector3 | `#pos=0.5,0,0` | positions camera (or XR floor) to xyz-coord 0.5,0,0, |
|
||||
| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 |
|
||||
| `#t` | vector2 | `#t=500,1000` | sets animation-loop range between frame 500 and 1000 |
|
||||
| `#......` | string | `#.cubes` `#cube` | object(s) of interest (fragment-to-object-or-tagname) |
|
||||
| `#......` | string | `#.cubes` `#cube` | predefined views, XRWG fragments and ID fragments |
|
||||
|
||||
> xyz coordinates are similar to ones found in SVG Media Fragments
|
||||
|
||||
|
@ -312,7 +312,7 @@ Here's how to write a query parser:
|
|||
|
||||
> An example query-parser (which compiles to many languages) can be [found here](https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Query.hx)
|
||||
|
||||
# Embedding local/remote content (instancing)
|
||||
# Embedding content (src-instancing)
|
||||
|
||||
`src` 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.
|
||||
|
@ -321,12 +321,12 @@ It instances content (in objects) in the current scene/asset.
|
|||
|----------|------|---------------|
|
||||
|`src`| string (uri or [[predefined view|predefined_view]] or [[query|queries]]) | `#cube`<br>`#q=-ball_inside_cube`<br>`#q=-/sky -rain`<br>`#q=-.language .english`<br>`#q=price:>2 price:<5`<br>`https://linux.org/penguin.png`<br>`https://linux.world/distrowatch.gltf#t=1,100`<br>`linuxapp://conference/nixworkshop/apply.gltf#q=flyer`<br>`androidapp://page1?tutorial#pos=0,0,1&t1,100`|
|
||||
|
||||
|
||||
1. local/remote content is instanced by the `src` (query) value (and attaches it to the placeholder mesh containing the `src` property)
|
||||
1. <b>local</b> `src` values (URL **starting** with `#`, like `#cube&foo`) means **only** the mentioned objectnames will be copied to the instanced scene (from the current scene) while preserving their names (to support recursive selectors). [[(example code)|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js]]
|
||||
1. <b>local</b> `src` values indicating a query (`#q=`), 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). [[(example code)|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js]]
|
||||
1. <b>local</b> `src` values (URL **starting** with `#`, like `#cube&foo`) means **only** the mentioned objectnames will be copied to the instanced scene (from the current scene) while preserving their names (to support recursive selectors). [(example code)](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js)
|
||||
1. <b>local</b> `src` values indicating a query (`#q=`), 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). [(example code)](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js)
|
||||
1. the instanced scene (from a `src` 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.
|
||||
1. <b>external</b> `src` (file) 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:
|
||||
1. 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.
|
||||
1. when only one object was cherrypicked (`#cube` e.g.), set its position to `0,0,0`
|
||||
|
||||
* `model/gltf+json`
|
||||
|
@ -334,8 +334,56 @@ It instances content (in objects) in the current scene/asset.
|
|||
* `image/jpg`
|
||||
* `text/plain;charset=utf-8;bib=^@`
|
||||
|
||||
[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js)<br>
|
||||
[» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/src.gltf#L192)<br>
|
||||
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/4)<br>
|
||||
|
||||
## Referencing content (href portals)
|
||||
|
||||
navigation, portals & mutations
|
||||
|
||||
| fragment | type | example value |
|
||||
|----------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
|`href` | string (uri or predefined view) | `#pos=1,1,0`<br>`#pos=1,1,0&rot=90,0,0`<br>`://somefile.gltf#pos=1,1,0`<br> |
|
||||
|
||||
1. clicking an ''external''- or ''file URI'' fully replaces the current scene and assumes `pos=0,0,0&rot=0,0,0` by default (unless specified)
|
||||
|
||||
2. relocation/reorientation should happen locally for local URI's (`#pos=....`)
|
||||
|
||||
3. navigation should not happen ''immediately'' when user is more than 2 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)
|
||||
|
||||
4. URL navigation should always be reflected in the client (in case of javascript: see [[here](https://github.com/coderofsalvation/xrfragment/blob/dev/src/3rd/js/three/navigator.js) for an example navigator).
|
||||
|
||||
5. In XR mode, the navigator back/forward-buttons should be always visible (using a wearable e.g., see [[here](https://github.com/coderofsalvation/xrfragment/blob/dev/example/aframe/sandbox/index.html#L26-L29) for an example wearable)
|
||||
|
||||
6. 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 [[here](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js#L97))
|
||||
|
||||
7. portal-rendering: a 2:1 ratio texture-material indicates an equirectangular projection
|
||||
|
||||
[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js)<br>
|
||||
[» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/href.gltf#L192)<br>
|
||||
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/1)<br>
|
||||
|
||||
## Scaling instanced content
|
||||
|
||||
Sometimes embedded properties (like [[href|href]] or [[src|src]]) instance new objects.<br>
|
||||
But what about their scale?<br>
|
||||
How does the scale of the object (with the embedded properties) impact the scale of the referenced content?<br>
|
||||
|
||||
> Rule of thumb: visible placeholder objects act as a '3D canvas' for the referenced scene (a plane acts like a 2D canvas for images e, a cube as a 3D canvas e.g.).
|
||||
|
||||
1. <b>IF</b> an embedded property (`src` e.g.) is set on an non-empty placeholder object (geometry of >2 vertices):
|
||||
|
||||
* calculate the <b>bounding box</b> of the ''placeholder'' object (maxsize=1.4 e.g.)
|
||||
* hide the ''placeholder'' object (material e.g.)
|
||||
* instance the `src` scene as a child of the existing object
|
||||
* calculate the <b>bounding box</b> of the instanced scene, and scale it accordingly (to 1.4 e.g.)
|
||||
|
||||
> REASON: non-empty placeholder object can act as a protective bounding-box (for remote content of which might grow over time e.g.)
|
||||
|
||||
2. ELSE multiply the scale-vector of the instanced scene with the scale-vector of the <b>placeholder</b> object.
|
||||
|
||||
> TODO: needs intermediate visuals to make things more obvious
|
||||
|
||||
|
||||
# Text in XR (tagging,linking to spatial objects)
|
||||
|
@ -388,7 +436,6 @@ Example:
|
|||
|
||||
> the `#john@baroque`-bib associates both text `John` and objectname `john`, with tag `baroque`
|
||||
|
||||
```
|
||||
|
||||
Another example:
|
||||
|
||||
|
@ -663,6 +710,7 @@ This document has no IANA actions.
|
|||
|the XRWG | wordgraph (collapses 3D scene to tags) |
|
||||
|the hashbus | hashtags map to camera/scene-projections |
|
||||
|spacetime hashtags | positions camera, triggers scene-preset/time |
|
||||
|placeholder object | a 3D object which with src-metadata (which will be replaced by the src-data.) |
|
||||
|src | (HTML-piggybacked) metadata of a 3D object which instances content |
|
||||
|href | (HTML-piggybacked) metadata of a 3D object which links to content |
|
||||
|query | an URI Fragment-operator which queries object(s) from a scene like `#q=cube` |
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,945 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
|
||||
<rfc version="3" ipr="trust200902" docName="draft-XRFRAGMENTS-leonvankammen-00" submissionType="IETF" category="info" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true" consensus="true">
|
||||
|
||||
<front>
|
||||
<title>XR Fragments</title><seriesInfo value="draft-XRFRAGMENTS-leonvankammen-00" stream="IETF" status="informational" name="XR-Fragments"></seriesInfo>
|
||||
<author initials="L.R." surname="van Kammen" fullname="L.R. van Kammen"><organization></organization><address><postal><street></street>
|
||||
</postal></address></author><date/>
|
||||
<area>Internet</area>
|
||||
<workgroup>Internet Engineering Task Force</workgroup>
|
||||
|
||||
<abstract>
|
||||
<t>This draft is a specification for 4D URLs & 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 <eref target="https://en.wikipedia.org/wiki/URI_fragment">URI Fragments</eref> and BibTags notation.<br />
|
||||
</t>
|
||||
<t>Almost every idea in this document is demonstrated at <eref target="https://xrfragment.org">https://xrfragment.org</eref></t>
|
||||
</abstract>
|
||||
|
||||
</front>
|
||||
|
||||
<middle>
|
||||
|
||||
<section anchor="introduction"><name>Introduction</name>
|
||||
<t>How can we add more features to existing text & 3D scenes, without introducing new dataformats?<br />
|
||||
|
||||
Historically, there's many attempts to create the ultimate markuplanguage or 3D fileformat.<br />
|
||||
|
||||
Their lowest common denominator is: (co)authoring using plain text.<br />
|
||||
|
||||
XR Fragments allows us to enrich/connect existing dataformats, by recursive use of existing technologies:<br />
|
||||
</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>addressibility and 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) (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>extend the hashtag-to-browser-viewport paradigm beyond 2D documents (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 />
|
||||
|
||||
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>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>principle</th>
|
||||
<th>XR 4D URL</th>
|
||||
<th>HTML 2D URL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>the XRWG</td>
|
||||
<td>wordgraph (collapses 3D scene to tags)</td>
|
||||
<td>Ctrl-F (find)</td>
|
||||
</tr>
|
||||
|
||||
<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>
|
||||
</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 browser-perspective:</t>
|
||||
</blockquote>
|
||||
<artwork> +----------------------------------------------------------------------------------------------+
|
||||
| |
|
||||
| the soul of any URL: ://macro /meso ?micro #nano |
|
||||
| |
|
||||
| 2D URL: ://library.com /document ?search #chapter |
|
||||
| |
|
||||
| 4D URL: ://park.com /4Dscene.fbx --> ?search --> #view ---> hashbus |
|
||||
| │ | |
|
||||
| XRWG <---------------------<------------+ |
|
||||
| │ | |
|
||||
| ├─ objects --------------->------------| |
|
||||
| └─ text --------------->------------+ |
|
||||
| |
|
||||
| |
|
||||
+----------------------------------------------------------------------------------------------+
|
||||
|
||||
</artwork>
|
||||
<t>Traditional webbrowsers can become 4D document-ready by:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>loading 3D assets (gltf/fbx e.g.) natively (not thru HTML).</li>
|
||||
<li>allowing assets to publish hashtags to themselves (the scene) using the hashbus (like hashtags controlling the scrollbar).</li>
|
||||
<li>collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus</li>
|
||||
</ul>
|
||||
<t>XR Fragments itself is HTML-agnostic, though pseudo-XR Fragment browsers <strong>can</strong> be implemented on top of HTML/Javascript.</t>
|
||||
</section>
|
||||
|
||||
<section anchor="conventions-and-definitions"><name>Conventions and Definitions</name>
|
||||
<t>See appendix below in case certain terms are not clear.</t>
|
||||
|
||||
<section anchor="xr-fragment-uri-grammar"><name>XR Fragment URI Grammar</name>
|
||||
|
||||
<artwork>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>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Demo</th>
|
||||
<th>Explanation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>pos=1,2,3</tt></td>
|
||||
<td>vector/coordinate argument e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>pos=1,2,3&rot=0,90,0&q=.foo</tt></td>
|
||||
<td>combinators</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>this is already implemented in all browsers</t>
|
||||
</blockquote></section>
|
||||
</section>
|
||||
|
||||
<section anchor="list-of-uri-fragments"><name>List of URI Fragments</name>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>fragment</th>
|
||||
<th>type</th>
|
||||
<th>example</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>#pos</tt></td>
|
||||
<td>vector3</td>
|
||||
<td><tt>#pos=0.5,0,0</tt></td>
|
||||
<td>positions camera (or XR floor) to xyz-coord 0.5,0,0,</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#rot</tt></td>
|
||||
<td>vector3</td>
|
||||
<td><tt>#rot=0,90,0</tt></td>
|
||||
<td>rotates camera to xyz-coord 0.5,0,0</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#t</tt></td>
|
||||
<td>vector2</td>
|
||||
<td><tt>#t=500,1000</tt></td>
|
||||
<td>sets animation-loop range between frame 500 and 1000</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>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t>xyz coordinates are similar to ones found in SVG Media Fragments</t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="list-of-metadata-for-3d-nodes"><name>List of metadata for 3D nodes</name>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>key</th>
|
||||
<th>type</th>
|
||||
<th>example (JSON)</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>name</tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>"name": "cube"</tt></td>
|
||||
<td>available in all 3D fileformats & scenes</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>tag</tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>"tag": "cubes geo"</tt></td>
|
||||
<td>available through custom property in 3D fileformats</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>href</tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>"href": "b.gltf"</tt></td>
|
||||
<td>available through custom property in 3D fileformats</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>src</tt></td>
|
||||
<td>string</td>
|
||||
<td><tt>"src": "#cube"</tt></td>
|
||||
<td>available through custom property in 3D fileformats</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><t>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 file-agnostic, which means that the metadata exist in programmatic 3D scene(nodes) too.</t>
|
||||
</blockquote></section>
|
||||
|
||||
<section anchor="navigating-3d"><name>Navigating 3D</name>
|
||||
<t>Here's an ascii representation of a 3D scene-graph which contains 3D objects <tt>◻</tt> and their metadata:</t>
|
||||
|
||||
<artwork> +--------------------------------------------------------+
|
||||
| |
|
||||
| index.gltf |
|
||||
| │ |
|
||||
| ├── ◻ buttonA |
|
||||
| │ └ href: #pos=1,0,1&t=100,200 |
|
||||
| │ |
|
||||
| └── ◻ buttonB |
|
||||
| └ 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 />
|
||||
|
||||
In case of <tt>buttonA</tt> the end-user will be teleported to another location and time in the <strong>current loaded scene</strong>, but <tt>buttonB</tt> will
|
||||
<strong>replace the current scene</strong> with a new one, like <tt>other.fbx</tt>.</t>
|
||||
</section>
|
||||
|
||||
<section anchor="embedding-3d-content"><name>Embedding 3D content</name>
|
||||
<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>
|
||||
|
||||
<artwork> +--------------------------------------------------------+ +-------------------------+
|
||||
| | | |
|
||||
| index.gltf | | ocean.com/aquarium.fbx |
|
||||
| │ | | │ |
|
||||
| ├── ◻ canvas | | └── ◻ fishbowl |
|
||||
| │ └ src: painting.png | | ├─ ◻ bass |
|
||||
| │ | | └─ ◻ tuna |
|
||||
| ├── ◻ aquariumcube | | |
|
||||
| │ └ src: ://rescue.com/fish.gltf#bass%20tuna | +-------------------------+
|
||||
| │ |
|
||||
| ├── ◻ bedroom |
|
||||
| │ └ src: #canvas |
|
||||
| │ |
|
||||
| └── ◻ livingroom |
|
||||
| └ 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 />
|
||||
|
||||
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></section>
|
||||
|
||||
<section anchor="xr-fragment-queries"><name>XR Fragment queries</name>
|
||||
<t>Include, exclude, hide/shows objects using space-separated strings:</t>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>example</th>
|
||||
<th>outcome</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>#q=-sky</tt></td>
|
||||
<td>show everything except object named <tt>sky</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>#q=-.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>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><t>It's simple but powerful syntax which allows <b>css</b>-like tag/id-selectors with a 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 starting with <tt>.</tt> like <tt>.german</tt> match tag-metadata of 3D objects like <tt>"tag":"german"</tt></li>
|
||||
<li>words starting with <tt>.</tt> like <tt>.german</tt> match tag-metadata of (BibTeX) tags in XR Text objects like <tt>@german{KarlHeinz, ...</tt> e.g.</li>
|
||||
</ol>
|
||||
<blockquote><t><strong>For example</strong>: <tt>#q=.foo</tt> is a shorthand for <tt>#q=tag:foo</tt>, which will select objects with custom property <tt>tag</tt>:<tt>foo</tt>. Just a simple <tt>#q=cube</tt> will simply select an object named <tt>cube</tt>.</t>
|
||||
</blockquote>
|
||||
<ul spacing="compact">
|
||||
<li>see <eref target="https://coderofsalvation.github.io/xrfragment.media/queries.mp4">an example video here</eref></li>
|
||||
</ul>
|
||||
|
||||
<section anchor="including-excluding"><name>including/excluding</name>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>operator</th>
|
||||
<th>info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>-</tt></td>
|
||||
<td>removes/hides object(s)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>:</tt></td>
|
||||
<td>indicates an object-embedded custom property key/value</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>.</tt></td>
|
||||
<td>alias for <tt>"tag" :".foo"</tt> equals <tt>tag:foo</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>></tt> <tt><</tt></td>
|
||||
<td>compare float or int number</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>
|
||||
</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>
|
||||
</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/issues/3">» discussion</eref></t>
|
||||
</section>
|
||||
|
||||
<section anchor="query-parser"><name>Query Parser</name>
|
||||
<t>Here's how to write a query 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 tag selectors like <tt>.foo</tt> (reference regex: <tt>/^[-]?tag$/</tt> )</li>
|
||||
<li>detect number values like <tt>foo:1</tt> (reference regex: <tt>/^[0-9\.]+$/</tt> )</li>
|
||||
<li>expand aliases like <tt>.foo</tt> into <tt>tag:foo</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>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>
|
||||
</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></section>
|
||||
</section>
|
||||
|
||||
<section anchor="embedding-content-src-instancing"><name>Embedding content (src-instancing)</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>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>fragment</th>
|
||||
<th>type</th>
|
||||
<th>example value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>src</tt></td>
|
||||
<td>string (uri or [[predefined view</td>
|
||||
<td>predefined_view]] or [[query</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<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>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> (file) 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>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>when only one object was cherrypicked (<tt>#cube</tt> e.g.), set its position to <tt>0,0,0</tt></li>
|
||||
</ol>
|
||||
|
||||
<ul spacing="compact">
|
||||
<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>
|
||||
</ul>
|
||||
<t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js">» example implementation</eref><br />
|
||||
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/src.gltf#L192">» example 3D asset</eref><br />
|
||||
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/issues/4">» discussion</eref><br />
|
||||
</t>
|
||||
|
||||
<section anchor="referencing-content-href-portals"><name>Referencing content (href portals)</name>
|
||||
<t>navigation, portals & mutations</t>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>fragment</th>
|
||||
<th>type</th>
|
||||
<th>example value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>href</tt></td>
|
||||
<td>string (uri or predefined view)</td>
|
||||
<td><tt>#pos=1,1,0</tt><br />
|
||||
<tt>#pos=1,1,0&rot=90,0,0</tt><br />
|
||||
<tt>://somefile.gltf#pos=1,1,0</tt><br />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<ol>
|
||||
<li><t>clicking an ''external''- or ''file URI'' fully replaces the current scene and assumes <tt>pos=0,0,0&rot=0,0,0</tt> by default (unless specified)</t>
|
||||
</li>
|
||||
<li><t>relocation/reorientation should happen locally for local URI's (<tt>#pos=....</tt>)</t>
|
||||
</li>
|
||||
<li><t>navigation should not happen ''immediately'' when user is more than 2 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)</t>
|
||||
</li>
|
||||
<li><t>URL navigation should always be reflected in the client (in case of javascript: see [<eref target="https://github.com/coderofsalvation/xrfragment/blob/dev/src/3rd/js/three/navigator.js">here</eref> for an example navigator).</t>
|
||||
</li>
|
||||
<li><t>In XR mode, the navigator back/forward-buttons should be always visible (using a wearable e.g., see [<eref target="https://github.com/coderofsalvation/xrfragment/blob/dev/example/aframe/sandbox/index.html#L26-L29">here</eref> for an example wearable)</t>
|
||||
</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>
|
||||
</ol>
|
||||
<t><eref target="https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js">» example implementation</eref><br />
|
||||
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/href.gltf#L192">» example 3D asset</eref><br />
|
||||
|
||||
<eref target="https://github.com/coderofsalvation/xrfragment/issues/1">» discussion</eref><br />
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="scaling-instanced-content"><name>Scaling instanced content</name>
|
||||
<t>Sometimes embedded properties (like [[href|href]] or [[src|src]]) instance new objects.<br />
|
||||
|
||||
But what about their scale?<br />
|
||||
|
||||
How does the scale of the object (with the embedded properties) impact the scale of the referenced content?<br />
|
||||
</t>
|
||||
<blockquote><t>Rule of thumb: visible placeholder objects act as a '3D canvas' for the referenced scene (a plane acts like a 2D canvas for images e, a cube as a 3D canvas e.g.).</t>
|
||||
</blockquote>
|
||||
<ol spacing="compact">
|
||||
<li><b>IF</b> an embedded property (<tt>src</tt> e.g.) is set on an non-empty placeholder object (geometry of >2 vertices):</li>
|
||||
</ol>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>calculate the <b>bounding box</b> of the ''placeholder'' object (maxsize=1.4 e.g.)</li>
|
||||
<li>hide the ''placeholder'' object (material e.g.)</li>
|
||||
<li>instance the <tt>src</tt> scene as a child of the existing object</li>
|
||||
<li>calculate the <b>bounding box</b> of the instanced scene, and scale it accordingly (to 1.4 e.g.)</li>
|
||||
</ul>
|
||||
<blockquote><t>REASON: non-empty placeholder object can act as a protective bounding-box (for remote content of which might grow over time e.g.)</t>
|
||||
</blockquote>
|
||||
<ol spacing="compact" start="2">
|
||||
<li>ELSE multiply the scale-vector of the instanced scene with the scale-vector of the <b>placeholder</b> object.</li>
|
||||
</ol>
|
||||
<blockquote><t>TODO: needs intermediate visuals to make things more obvious</t>
|
||||
</blockquote></section>
|
||||
</section>
|
||||
|
||||
<section anchor="text-in-xr-tagging-linking-to-spatial-objects"><name>Text in XR (tagging,linking to spatial objects)</name>
|
||||
<t>How does XR Fragments interlink text with objects?</t>
|
||||
<blockquote><t>The XR Fragments does this by collapsing space into a <strong>Word Graph</strong> (the <strong>XRWG</strong>), augmented by Bib(s)Tex.</t>
|
||||
</blockquote><t>Instead of just throwing together all kinds media types into one experience (games), what about the intrinsic connections between them?<br />
|
||||
|
||||
Why is HTML adopted less in games outside the browser?
|
||||
Through the lens of game-making, ideally metadata must come <strong>with</strong> that text, but not <strong>obfuscate</strong> the text, or <strong>spawning another request</strong> to fetch it.<br />
|
||||
|
||||
XR Fragments does this by detecting Bib(s)Tex, without introducing a new language or fileformat<br />
|
||||
</t>
|
||||
<blockquote><t>Why Bib(s)Tex? Because its seems to be the lowest common denominator for an human-curated XRWG (extendable by speech/scanner/writing/typing e.g, see <eref target="https://github.com/coderofsalvation/hashtagbibs#bibs--bibtex-combo-lowest-common-denominator-for-linking-data">further motivation here</eref>)</t>
|
||||
</blockquote><t>Hence:</t>
|
||||
|
||||
<ol spacing="compact">
|
||||
<li>XR Fragments promotes (de)serializing a scene to the XRWG</li>
|
||||
<li>XR Fragments primes the XRWG, by collecting words from the <tt>tag</tt> and name-property of 3D objects.</li>
|
||||
<li>XR Fragments primes the XRWG, by collecting words from <strong>optional</strong> metadata <strong>at the end of content</strong> of text (see default mimetype & Data URI)</li>
|
||||
<li><eref target="https://github.com/coderofsalvation/hashtagbibs">Bib's</eref> and BibTex are first tag citizens for priming the XRWG with words (from XR text)</li>
|
||||
<li>Like Bibs, XR Fragments generalizes the BibTex author/title-semantics (<tt>author{title}</tt>) into <strong>this</strong> points to <strong>that</strong> (<tt>this{that}</tt>)</li>
|
||||
<li>The XRWG should be recalculated when textvalues (in <tt>src</tt>) change</li>
|
||||
<li>HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer)</li>
|
||||
<li>Applications don't have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes.</li>
|
||||
<li>The XR Fragment focuses on fast and easy-to-generate end-user controllable word graphs (instead of complex implementations that try to defeat word ambiguity)</li>
|
||||
</ol>
|
||||
<t>Example:</t>
|
||||
|
||||
<artwork> http://y.io/z.fbx | Derived XRWG (shown as BibTex)
|
||||
----------------------------------------------------------------------------+--------------------------------------
|
||||
| @house{castle,
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | url = {https://y.io/z.fbx#castle}
|
||||
| Chapter one | | / \ | | }
|
||||
| | | / \ | | @baroque{castle,
|
||||
| John built houses in baroque style. | | / \ | | url = {https://y.io/z.fbx#castle}
|
||||
| | | |_____| | | }
|
||||
| #john@baroque | +-----│-----+ | @baroque{john}
|
||||
| | │ |
|
||||
| | ├─ name: castle |
|
||||
| | └─ tag: house baroque |
|
||||
+----------------------------------------+ |
|
||||
[3D mesh ] |
|
||||
| O ├─ name: john |
|
||||
| /|\ | |
|
||||
| / \ | |
|
||||
+--------+ |
|
||||
</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 (printed as BibTex)
|
||||
----------------------------------------------------------------------------+--------------------------------------
|
||||
|
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | @house{castle,
|
||||
| Chapter one | | / \ | | url = {https://y.io/z.fbx#castle}
|
||||
| | | / \ | | }
|
||||
| John built houses in baroque style. | | / \ | | @baroque{castle,
|
||||
| | | |_____| | | url = {https://y.io/z.fbx#castle}
|
||||
| #john@baroque | +-----│-----+ | }
|
||||
| @baroque{john} | │ | @baroque{john}
|
||||
| | ├─ name: castle |
|
||||
| | └─ tag: house baroque |
|
||||
+----------------------------------------+ | @house{baroque}
|
||||
[3D mesh ] | @todo{baroque}
|
||||
+-[remotestorage.io / localstorage]------+ | O + name: john |
|
||||
| #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 />
|
||||
|
||||
This allows hasslefree authoring and copy-paste of associations <strong>for and by humans</strong>, but also makes these URLs possible:</t>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>https://my.com/foo.gltf#.baroque</tt></td>
|
||||
<td>highlights mesh <tt>john</tt>, 3D mesh <tt>castle</tt>, text <tt>John built(..)</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>https://my.com/foo.gltf#john</tt></td>
|
||||
<td>highlights mesh <tt>john</tt>, and the text <tt>John built (..)</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>https://my.com/foo.gltf#house</tt></td>
|
||||
<td>highlights mesh <tt>castle</tt>, and other objects with tag <tt>house</tt> or <tt>todo</tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table><blockquote><t><eref target="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs</eref> potentially allow the enduser to annotate text/objects by <strong>speaking/typing/scanning associations</strong>, which the XR Browser saves to remotestorage (or localStorage per toplevel URL). As well as, referencing BibTags per URI later on: <tt>https://y.io/z.fbx#@baroque@todo</tt> e.g.</t>
|
||||
</blockquote><t>The XRWG allows XR Browsers to show/hide relationships in realtime at various levels:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>wordmatch <strong>inside</strong> <tt>src</tt> text</li>
|
||||
<li>wordmatch <strong>inside</strong> <tt>href</tt> text</li>
|
||||
<li>wordmatch object-names</li>
|
||||
<li>wordmatch object-tagnames</li>
|
||||
</ul>
|
||||
<t>Spatial wires can be rendered, words/objects can be highlighted/scaled etc.<br />
|
||||
|
||||
Some pointers for good UX (but not necessary to be XR Fragment compatible):</t>
|
||||
|
||||
<ol spacing="compact" start="9">
|
||||
<li>The XR Browser needs to adjust tag-scope based on the endusers needs/focus (infinite tagging only makes sense when environment is scaled down significantly)</li>
|
||||
<li>The XR Browser should always allow the human to view/edit the metadata, by clicking 'toggle metadata' on the 'back' (contextmenu e.g.) of any XR text, anywhere anytime.</li>
|
||||
<li>respect multi-line BiBTeX metadata in text because of <eref target="#core-principle">the core principle</eref></li>
|
||||
<li>Default font (unless specified otherwise) is a modern monospace font, for maximized tabular expressiveness (see <eref target="#core-principle">the core principle</eref>).</li>
|
||||
<li>anti-pattern: hardcoupling an XR Browser with a mandatory <strong>markup/scripting-language</strong> which departs from onubtrusive plain text (HTML/VRML/Javascript) (see <eref target="#core-principle">the core principle</eref>)</li>
|
||||
<li>anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.</li>
|
||||
</ol>
|
||||
<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:
|
||||
#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
|
||||
</artwork>
|
||||
|
||||
<section anchor="default-data-uri-mimetype"><name>Default Data URI mimetype</name>
|
||||
<t>The <tt>src</tt>-values work as expected (respecting mime-types), however:</t>
|
||||
<t>The XR Fragment specification bumps the traditional default browser-mimetype</t>
|
||||
<t><tt>text/plain;charset=US-ASCII</tt></t>
|
||||
<t>to a hashtagbib(tex)-friendly one:</t>
|
||||
<t><tt>text/plain;charset=utf-8;bib=^@</tt></t>
|
||||
<t>This indicates that:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>utf-8 is supported by default</li>
|
||||
<li>lines beginning with <tt>@</tt> will not be rendered verbatim by default (<eref target="https://github.com/coderofsalvation/hashtagbibs#hashtagbib-mimetypes">read more</eref>)</li>
|
||||
<li>the XRWG should expand bibs to BibTex occurring in text (<tt>#contactjohn@todo@important</tt> e.g.)</li>
|
||||
</ul>
|
||||
<t>By doing so, the XR Browser (applications-layer) can interpret microformats (<eref target="https://visual-meta.info">visual-meta</eref>
|
||||
to connect text further with its environment ( setup links between textual/spatial objects automatically e.g.).</t>
|
||||
<blockquote><t>for more info on this mimetype see <eref target="https://github.com/coderofsalvation/hashtagbibs">bibs</eref></t>
|
||||
</blockquote><t>Advantages:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>auto-expanding of <eref target="https://github.com/coderofsalvation/hashtagbibs">hashtagbibs</eref> associations</li>
|
||||
<li>out-of-the-box (de)multiplex human text and metadata in one go (see <eref target="#core-principle">the core principle</eref>)</li>
|
||||
<li>no network-overhead for metadata (see <eref target="#core-principle">the core principle</eref>)</li>
|
||||
<li>ensuring high FPS: HTML/RDF historically is too 'requesty'/'parsy' for game studios</li>
|
||||
<li>rich send/receive/copy-paste everywhere by default, metadata being retained (see <eref target="#core-principle">the core principle</eref>)</li>
|
||||
<li>netto result: less webservices, therefore less servers, and overall better FPS in XR</li>
|
||||
</ul>
|
||||
<blockquote><t>This significantly expands expressiveness and portability of human tagged text, by <strong>postponing machine-concerns to the end of the human text</strong> in contrast to literal interweaving of content and markupsymbols (or extra network requests, webservices e.g.).</t>
|
||||
</blockquote><t>For all other purposes, regular mimetypes can be used (but are not required by the spec).<br />
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="url-and-data-uri"><name>URL and Data URI</name>
|
||||
|
||||
<artwork> +--------------------------------------------------------------+ +------------------------+
|
||||
| | | author.com/article.txt |
|
||||
| index.gltf | +------------------------+
|
||||
| │ | | |
|
||||
| ├── ◻ article_canvas | | Hello friends. |
|
||||
| │ └ src: ://author.com/article.txt | | |
|
||||
| │ | | @book{greatgatsby |
|
||||
| └── ◻ note_canvas | | ... |
|
||||
| └ src:`data:welcome human\n@book{sunday...}` | | } |
|
||||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
</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).
|
||||
In both cases, the text gets rendered immediately (onto a plane geometry, hence the name '_canvas').
|
||||
The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.).</t>
|
||||
<blockquote><t>additional tagging using <eref target="https://github.com/coderofsalvation/hashtagbibs">bibs</eref>: to tag spatial object <tt>note_canvas</tt> with 'todo', the enduser can type or speak <tt>#note_canvas@todo</tt></t>
|
||||
</blockquote></section>
|
||||
|
||||
<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 = {
|
||||
|
||||
expandBibs: (text) => {
|
||||
let bibs = { regex: /(#[a-zA-Z0-9_+@\-]+(#)?)/g, tags: {}}
|
||||
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}` )
|
||||
else if( match.substr(-1) == '#' )
|
||||
bibs.tags[match] = `@{${match.replace(/#/,'')}}`
|
||||
else bibs.tags[match] = `@${match}{${match},\n}`
|
||||
})
|
||||
return text.replace( bibs.regex, '') + Object.values(bibs.tags).join('\n')
|
||||
},
|
||||
|
||||
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++ )
|
||||
text += lines[i]+'\n'
|
||||
|
||||
bibtex = lines.join('\n').substr( text.length )
|
||||
bibtex.split( pat[0] ).map( (t) => {
|
||||
try{
|
||||
let v = {}
|
||||
if( !(t = t.trim()) ) return
|
||||
if( tag = t.match( pat[1] ) ) tag = tag[0]
|
||||
if( tag.match( /^{.*}$/ ) ) return tags.push({ruler:tag})
|
||||
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 )
|
||||
})
|
||||
tags.push( { k:tag, v } )
|
||||
}catch(e){ console.error(e) }
|
||||
})
|
||||
return {text, tags}
|
||||
},
|
||||
|
||||
encode: (text,tags) => {
|
||||
let str = text+"\n"
|
||||
for( let i in tags ){
|
||||
let item = tags[i]
|
||||
if( item.ruler ){
|
||||
str += `@${item.ruler}\n`
|
||||
continue;
|
||||
}
|
||||
str += `@${item.k}\n`
|
||||
for( let j in item.v ) str += ` ${j} = {${item.v[j]}}\n`
|
||||
str += `}\n`
|
||||
}
|
||||
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 = `
|
||||
hello world
|
||||
here are some hashtagbibs followed by bibtex:
|
||||
|
||||
#world
|
||||
#hello@greeting
|
||||
#another-section#
|
||||
|
||||
@{some-section}
|
||||
@flap{
|
||||
asdf = {23423}
|
||||
}`
|
||||
|
||||
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
|
||||
</artwork>
|
||||
<t>This expands to the following (hidden by default) BibTex appendix:</t>
|
||||
|
||||
<artwork>hello world
|
||||
here are some hashtagbibs followed by bibtex:
|
||||
|
||||
@{some-section}
|
||||
@flap{
|
||||
asdf = {1}
|
||||
}
|
||||
@world{world,
|
||||
}
|
||||
@greeting{hello,
|
||||
}
|
||||
@{another-section}
|
||||
@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>
|
||||
</section>
|
||||
|
||||
<section anchor="security-considerations"><name>Security Considerations</name>
|
||||
<t>Since XR Text contains metadata too, the user should be able to set up tagging-rules, so the copy-paste feature can :</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li>filter out sensitive data when copy/pasting (XR text with <tt>tag:secret</tt> e.g.)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section anchor="iana-considerations"><name>IANA Considerations</name>
|
||||
<t>This document has no IANA actions.</t>
|
||||
</section>
|
||||
|
||||
<section anchor="acknowledgments"><name>Acknowledgments</name>
|
||||
|
||||
<ul spacing="compact">
|
||||
<li><eref target="https://nlnet.nl">NLNET</eref></li>
|
||||
<li><eref target="https://futureoftext.org">Future of Text</eref></li>
|
||||
<li><eref target="https://visual-meta.info">visual-meta.info</eref></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section anchor="appendix-definitions"><name>Appendix: Definitions</name>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>definition</th>
|
||||
<th>explanation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>human</td>
|
||||
<td>a sentient being who thinks fuzzy, absorbs, and shares thought (by plain text, not markuplanguage)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>scene</td>
|
||||
<td>a (local/remote) 3D scene or 3D file (index.gltf e.g.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>3D object</td>
|
||||
<td>an object inside a scene characterized by vertex-, face- and customproperty data.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>metadata</td>
|
||||
<td>custom properties of text, 3D Scene or Object(nodes), relevant to machines and a human minority (academics/developers)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>XR fragment</td>
|
||||
<td>URI Fragment with spatial hints like <tt>#pos=0,0,0&t=1,100</tt> e.g.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>the XRWG</td>
|
||||
<td>wordgraph (collapses 3D scene to tags)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>the hashbus</td>
|
||||
<td>hashtags map to camera/scene-projections</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>spacetime hashtags</td>
|
||||
<td>positions camera, triggers scene-preset/time</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>placeholder object</td>
|
||||
<td>a 3D object which with src-metadata (which will be replaced by the src-data.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>src</td>
|
||||
<td>(HTML-piggybacked) metadata of a 3D object which instances content</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>href</td>
|
||||
<td>(HTML-piggybacked) metadata of a 3D object which links to content</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>query</td>
|
||||
<td>an URI Fragment-operator which queries object(s) from a scene like <tt>#q=cube</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>visual-meta</td>
|
||||
<td><eref target="https://visual.meta.info">visual-meta</eref> data appended to text/books/papers which is indirectly visible/editable in XR.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>requestless metadata</td>
|
||||
<td>metadata which never spawns new requests (unlike RDF/HTML, which can cause framerate-dropping, hence not used a lot in games)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>FPS</td>
|
||||
<td>frames per second in spatial experiences (games,VR,AR e.g.), should be as high as possible</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>introspective</td>
|
||||
<td>inward sensemaking ("I feel this belongs to that")</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>extrospective</td>
|
||||
<td>outward sensemaking ("I'm fairly sure John is a person who lives in oklahoma")</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>◻</tt></td>
|
||||
<td>ascii representation of an 3D object/mesh</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>(un)obtrusive</td>
|
||||
<td>obtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>BibTeX</td>
|
||||
<td>simple tagging/citing/referencing standard for plaintext</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>BibTag</td>
|
||||
<td>a BibTeX tag</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>(hashtag)bibs</td>
|
||||
<td>an easy to speak/type/scan tagging SDL (<eref target="https://github.com/coderofsalvation/hashtagbibs">see here</eref> which expands to BibTex/JSON/XML</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></section>
|
||||
|
||||
</middle>
|
||||
|
||||
</rfc>
|
25
index.html
25
index.html
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue