pages: work in progress [might break]

This commit is contained in:
Leon van Kammen 2024-07-12 15:12:40 +02:00
parent 925cbe4deb
commit 0f7f482a3d
5 changed files with 392 additions and 1059 deletions

View file

@ -1120,67 +1120,42 @@ Perhaps the following question is related: why is HTML adopted less in games out
<li>XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG (<a href="https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js">example</a>)</li> <li>XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG (<a href="https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js">example</a>)</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 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 &amp; Data URI)</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 &amp; Data URI)</li>
<li>XR Fragments primes the XRWG, by collecting tags/id&rsquo;s from linked hypermedia (URI fragments for HTML e.g.)</li>
<li>The XRWG should be recalculated when textvalues (in <code>src</code>) change</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, or as embedded src content)</li> <li>HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer, or as embedded src content)</li>
<li>Applications don&rsquo;t have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes.</li> <li>Applications don&rsquo;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> <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>
<li>Tags are the scope for now (supporting <a href="https://github.com/WICG/scroll-to-text-fragment">https://github.com/WICG/scroll-to-text-fragment</a> will be considered)</li> <li>Instead of exact lowercase word-matching, levensteihn-distance-based matching is preferred</li>
</ol> </ol>
<p>Example of generating BiBTex out of the XRWG and textdata with hashtags:</p> <p>Example of generating XRWG out of the XRWG and textdata with hashtags:</p>
<pre><code> http://y.io/z.fbx | Derived XRWG (expressed as BibTex) <pre><code> http://y.io/z.fbx | Derived XRWG (expressed as JSON)
----------------------------------------------------------------------------+-------------------------------------- ----------------------------------------------------------------------------+--------------------------------------
| @house{castle, | Chapter: ['#mydoc']
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | url = {https://y.io/z.fbx#castle} +-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc']
| Chapter one | | / \ | | } | Chapter one | | / \ | | houses: ['#castle','#mydoc','#house']
| | | / \ | | @baroque{castle, | | | / \ | | baroque: ['#mydoc','#castle']
| John built houses in baroque style. | | / \ | | url = {https://y.io/z.fbx#castle} | John built houses in baroque style. | | / \ | | castle: ['#baroque','#house']
| | | |_____| | | } | | | |_____| | | john: ['#john','#mydoc']
| | +-----│-----+ | @baroque{john} | | +-----│-----+ | mydoc: ['#mydoc']
| | │ | | | │ |
| | ├─ name: castle | | | ├─ name: castle |
| | └─ tag: house baroque | | | └─ tag: house baroque |
+----------------------------------------+ | +----------------------------------------+ |
[3D mesh ] | └─ name: mydoc [3D mesh-+ |
| O ├─ name: john | | 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 of deriving a graphdata from the XRWG:</p>
<pre><code> http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
----------------------------------------------------------------------------+--------------------------------------
| |
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | @house{castle, [remotestorage.io]+ [ localstorage]-+ | &lt;- the XR Fragment-compatible
| Chapter one | | / \ | | url = {https://y.io/z.fbx#castle} | XRWG (JSON) | | XRWG (JSON | | &lt;- 3D hypermedia viewer should
| | | / \ | | } | | | | | &lt;- be able to select the active XRWG
| 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> </code></pre>
<blockquote> <p>This allows hasslefree authoring and copy-paste of associations <strong>for and by humans</strong>, but also makes these URLs possible:</p>
<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 &lsquo;baroque&rsquo;.</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> <table>
<thead> <thead>
@ -1193,12 +1168,12 @@ This allows hasslefree authoring and copy-paste of associations <strong>for and
<tbody> <tbody>
<tr> <tr>
<td><code>https://my.com/foo.gltf#baroque</code></td> <td><code>https://my.com/foo.gltf#baroque</code></td>
<td>draws lines between mesh <code>john</code>, 3D mesh <code>castle</code>, text <code>John built(..)</code></td> <td>draws lines between 3D mesh <code>castle</code>, and <code>mydoc</code>&rsquo;s text <code>baroque</code></td>
</tr> </tr>
<tr> <tr>
<td><code>https://my.com/foo.gltf#john</code></td> <td><code>https://my.com/foo.gltf#john</code></td>
<td>draws lines between mesh <code>john</code>, and the text <code>John built (..)</code></td> <td>draws lines between mesh <code>john</code>, and the text <code>John</code> of <code>mydoc</code></td>
</tr> </tr>
<tr> <tr>
@ -1209,10 +1184,10 @@ This allows hasslefree authoring and copy-paste of associations <strong>for and
</table> </table>
<blockquote> <blockquote>
<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> <p>the URI fragment <code>#john&amp;mydoc&amp;house</code> would draw a connection between these 3 meshes.</p>
</blockquote> </blockquote>
<p>The XRWG allows XR Browsers to show/hide relationships in realtime at various levels:</p> <p>The XRWG allows endusers to show/hide relationships in realtime in XR Browsers at various levels:</p>
<ul> <ul>
<li>wordmatch <strong>inside</strong> <code>src</code> text</li> <li>wordmatch <strong>inside</strong> <code>src</code> text</li>
@ -1233,29 +1208,6 @@ Some pointers for good UX (but not necessary to be XR Fragment compatible):</p>
<li>anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.</li> <li>anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.</li>
</ol> </ol>
<blockquote>
<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>&lt;John&gt; Hey what about this: https://my.com/station.gltf#pos=0,0,1&amp;rot=90,2,0&amp;t=500,1000
&lt;Sarah&gt; I'm checking it right now
&lt;Sarah&gt; I don't see everything..where's our text from yesterday?
&lt;John&gt; Ah wait, that's tagged with tag 'draft' (and hidden)..hold on, try this:
&lt;John&gt; https://my.com/station.gltf#.draft&amp;pos=0,0,1&amp;rot=90,2,0&amp;t=500,1000
&lt;Sarah&gt; how about we link the draft to the upcoming YELLO-event?
&lt;John&gt; ok I'm adding #draft@YELLO
&lt;Sarah&gt; Yesterday I also came up with other usefull assocations between other texts in the scene:
#event#YELLO
#2025@YELLO
&lt;John&gt; thanks, added.
&lt;Sarah&gt; Btw. I stumbled upon this spatial book which references station.gltf in some chapters:
&lt;Sarah&gt; https://thecommunity.org/forum/foo/mytrainstory.txt
&lt;John&gt; interesting, I'm importing mytrainstory.txt into station.gltf
&lt;John&gt; 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> <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> <p>The <code>src</code>-values work as expected (respecting mime-types), however:</p>
@ -1264,32 +1216,23 @@ Some pointers for good UX (but not necessary to be XR Fragment compatible):</p>
<p><code>text/plain;charset=US-ASCII</code></p> <p><code>text/plain;charset=US-ASCII</code></p>
<p>to a hashtagbib(tex)-friendly one:</p> <p>to a hashtag-friendly one:</p>
<p><code>text/plain;charset=utf-8;bib=^@</code></p> <p><code>text/plain;charset=utf-8;hashtag</code></p>
<p>This indicates that:</p> <p>This indicates that:</p>
<ul> <ul>
<li>utf-8 is supported by default</li> <li>utf-8 is supported by default</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>words beginning with <code>#</code> (hashtags) will prime the XRWG by adding the hashtag to the XRWG, linking to the current sentence/paragraph/alltext (depending on &lsquo;.&rsquo;) to the XRWG</li>
<li>the XRWG should expand bibs to BibTex occurring in text (<code>#contactjohn@todo@important</code> e.g.)</li>
</ul> </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>
<p>Advantages:</p> <p>Advantages:</p>
<ul> <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>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>no network-overhead for metadata (see <a href="#core-principle">the core principle</a>)</li>
<li>ensuring high FPS: HTML/RDF historically is too &lsquo;requesty&rsquo;/&lsquo;parsy&rsquo; for game studios</li> <li>ensuring high FPS: realtime HTML/RDF historically is too &lsquo;requesty&rsquo;/&lsquo;parsy&rsquo; for game studios</li>
<li>rich send/receive/copy-paste everywhere by default, metadata being retained (see <a href="#core-principle">the core principle</a>)</li> <li>rich send/receive/copy-paste everywhere by default, metadata being retained (see <a href="#core-principle">the core principle</a>)</li>
<li>netto result: less webservices, therefore less servers, and overall better FPS in XR</li> <li>netto result: less webservices, therefore less servers, and overall better FPS in XR</li>
</ul> </ul>
@ -1325,117 +1268,13 @@ The XR Fragment-compatible browser can let the enduser access visual-meta(data)-
<p>additional tagging using <a href="https://github.com/coderofsalvation/hashtagbibs">bibs</a>: to tag spatial object <code>note_canvas</code> with &lsquo;todo&rsquo;, 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 &lsquo;todo&rsquo;, the enduser can type or speak <code>#note_canvas@todo</code></p>
</blockquote> </blockquote>
<h2 id="xr-text-example-parser">XR Text example parser</h2> <h1 id="importing-exporting">Importing/exporting</h1>
<p>To prime the XRWG with text from plain text <code>src</code>-values, here&rsquo;s an example XR Text (de)multiplexer in javascript (which supports inline bibs &amp; bibtex):</p> <p>For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play.</p>
<pre><code>xrtext = { <ol>
<li>export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.</li>
expandBibs: (text) =&gt; { </ol>
let bibs = { regex: /(#[a-zA-Z0-9_+@\-]+(#)?)/g, tags: {}}
text.replace( bibs.regex , (m,k,v) =&gt; {
tok = m.substr(1).split(&quot;@&quot;)
match = tok.shift()
if( tok.length ) tok.map( (t) =&gt; 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) =&gt; {
// bibtex: ↓@ ↓&lt;tag|tag{phrase,|{ruler}&gt; ↓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 &lt; lines.length &amp;&amp; !String(lines[i]).match( /^@/ ); i++ )
text += lines[i]+'\n'
bibtex = lines.join('\n').substr( text.length )
bibtex.split( pat[0] ).map( (t) =&gt; {
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 =&gt; {
if( !(kv = kv.trim()) || kv == &quot;}&quot; ) return
v[ kv.match(/\s?(\S+)\s?=/)[1] ] = kv.substr( kv.indexOf(&quot;{&quot;)+1 )
})
tags.push( { k:tag, v } )
}catch(e){ console.error(e) }
})
return {text, tags}
},
encode: (text,tags) =&gt; {
let str = text+&quot;\n&quot;
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
}
}
</code></pre>
<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&rsquo;s to translate/steelman to a more formal form/language.</p>
</blockquote>
<pre><code>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 &amp; bibtex
tags.find( (t) =&gt; 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 &amp; bibtex back together
</code></pre>
<p>This expands to the following (hidden by default) BibTex appendix:</p>
<pre><code>hello world
here are some hashtagbibs followed by bibtex:
@{some-section}
@flap{
asdf = {1}
}
@world{world,
}
@greeting{hello,
}
@{another-section}
@bar{
abc = {123}
}
</code></pre>
<blockquote>
<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="transclusion-broken-link-resolution">Transclusion (broken link) resolution</h1> <h1 id="transclusion-broken-link-resolution">Transclusion (broken link) resolution</h1>

View file

@ -664,75 +664,53 @@ Hence:
1. XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG ([example](https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js)) 1. XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG ([example](https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js))
2. XR Fragments primes the XRWG, by collecting words from the `tag` and name-property of 3D objects. 2. XR Fragments primes the XRWG, by collecting words from the `tag` and name-property of 3D objects.
3. XR Fragments primes the XRWG, by collecting words from **optional** metadata **at the end of content** of text (see default mimetype & Data URI) 3. XR Fragments primes the XRWG, by collecting words from **optional** metadata **at the end of content** of text (see default mimetype & Data URI)
6. The XRWG should be recalculated when textvalues (in `src`) change 4. XR Fragments primes the XRWG, by collecting tags/id's from linked hypermedia (URI fragments for HTML e.g.)
7. HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer, or as embedded src content) 5. The XRWG should be recalculated when textvalues (in `src`) change
8. Applications don't have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes. 6. HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer, or as embedded src content)
9. 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) 7. Applications don't have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes.
10. Tags are the scope for now (supporting https://github.com/WICG/scroll-to-text-fragment will be considered) 8. 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)
9. Instead of exact lowercase word-matching, levensteihn-distance-based matching is preferred
Example of generating BiBTex out of the XRWG and textdata with hashtags: Example of generating XRWG out of the XRWG and textdata with hashtags:
``` ```
http://y.io/z.fbx | Derived XRWG (expressed as BibTex) http://y.io/z.fbx | Derived XRWG (expressed as JSON)
----------------------------------------------------------------------------+-------------------------------------- ----------------------------------------------------------------------------+--------------------------------------
| @house{castle, | Chapter: ['#mydoc']
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | url = {https://y.io/z.fbx#castle} +-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc']
| Chapter one | | / \ | | } | Chapter one | | / \ | | houses: ['#castle','#mydoc','#house']
| | | / \ | | @baroque{castle, | | | / \ | | baroque: ['#mydoc','#castle']
| John built houses in baroque style. | | / \ | | url = {https://y.io/z.fbx#castle} | John built houses in baroque style. | | / \ | | castle: ['#baroque','#house']
| | | |_____| | | } | | | |_____| | | john: ['#john','#mydoc']
| | +-----│-----+ | @baroque{john} | | +-----│-----+ | mydoc: ['#mydoc']
| | │ | | | │ |
| | ├─ name: castle | | | ├─ name: castle |
| | └─ tag: house baroque | | | └─ tag: house baroque |
+----------------------------------------+ | +----------------------------------------+ |
[3D mesh ] | └─ name: mydoc [3D mesh-+ |
| O ├─ name: john | | O ├─ name: john |
| /|\ | | | /|\ | |
| / \ | | | / \ | | ^ ^ ^
+--------+ | +--------+ | | | |
```
> the `#john@baroque`-bib associates both text `John` and objectname `john`, with tag `baroque`
Another example of deriving a graphdata from the XRWG:
```
http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
----------------------------------------------------------------------------+--------------------------------------
| |
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | @house{castle, [remotestorage.io]+ [ localstorage]-+ | <- the XR Fragment-compatible
| Chapter one | | / \ | | url = {https://y.io/z.fbx#castle} | XRWG (JSON) | | XRWG (JSON | | <- 3D hypermedia viewer should
| | | / \ | | } | | | | | <- be able to select the active XRWG
| 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 | | /|\ | |
| ... | | / \ | |
+----------------------------------------+ +--------+ |
``` ```
> both `#john@baroque`-bib and BibTex `@baroque{john}` result in the same XRWG, however on top of that 2 tages (`house` and `todo`) are now associated with text/objectname/tag 'baroque'.
As seen above, the XRWG can expand [bibs](https://github.com/coderofsalvation/hashtagbibs) (and the whole scene) to BibTeX.<br>
This allows hasslefree authoring and copy-paste of associations **for and by humans**, but also makes these URLs possible: This allows hasslefree authoring and copy-paste of associations **for and by humans**, but also makes these URLs possible:
| URL example | Result | | URL example | Result |
|---------------------------------------|---------------------------------------------------------------------------| |---------------------------------------|---------------------------------------------------------------------------|
| `https://my.com/foo.gltf#baroque` | draws lines between mesh `john`, 3D mesh `castle`, text `John built(..)` | | `https://my.com/foo.gltf#baroque` | draws lines between 3D mesh `castle`, and `mydoc`'s text `baroque` |
| `https://my.com/foo.gltf#john` | draws lines between mesh `john`, and the text `John built (..)` | | `https://my.com/foo.gltf#john` | draws lines between mesh `john`, and the text `John` of `mydoc` |
| `https://my.com/foo.gltf#house` | draws lines between mesh `castle`, and other objects with tag `house` or `todo` | | `https://my.com/foo.gltf#house` | draws lines between mesh `castle`, and other objects with tag `house` or `todo` |
> [hashtagbibs](https://github.com/coderofsalvation/hashtagbibs) potentially allow the enduser to annotate text/objects by **speaking/typing/scanning associations**, which the XR Browser saves to remotestorage (or localStorage per toplevel URL). As well as, referencing BibTags per URI later on: `https://y.io/z.fbx#@baroque@todo` e.g. > the URI fragment `#john&mydoc&house` would draw a connection between these 3 meshes.
The XRWG allows XR Browsers to show/hide relationships in realtime at various levels: The XRWG allows endusers to show/hide relationships in realtime in XR Browsers at various levels:
* wordmatch **inside** `src` text * wordmatch **inside** `src` text
* wordmatch **inside** `href` text * wordmatch **inside** `href` text
@ -749,28 +727,6 @@ Some pointers for good UX (but not necessary to be XR Fragment compatible):
14. anti-pattern: hardcoupling an XR Browser with a mandatory **markup/scripting-language** which departs from onubtrusive plain text (HTML/VRML/Javascript) (see [the core principle](#core-principle)) 14. anti-pattern: hardcoupling an XR Browser with a mandatory **markup/scripting-language** which departs from onubtrusive plain text (HTML/VRML/Javascript) (see [the core principle](#core-principle))
15. anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen. 15. anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.
> The simplicity of appending metadata (and leveling the metadata-playfield between humans and machines) is also demonstrated by [visual-meta](https://visual-meta.info) in greater detail.
Fictional chat:
```
<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
```
## Default Data URI mimetype ## Default Data URI mimetype
The `src`-values work as expected (respecting mime-types), however: The `src`-values work as expected (respecting mime-types), however:
@ -779,27 +735,20 @@ The XR Fragment specification advices to bump the traditional default browser-mi
`text/plain;charset=US-ASCII` `text/plain;charset=US-ASCII`
to a hashtagbib(tex)-friendly one: to a hashtag-friendly one:
`text/plain;charset=utf-8;bib=^@` `text/plain;charset=utf-8;hashtag`
This indicates that: This indicates that:
* utf-8 is supported by default * utf-8 is supported by default
* lines beginning with `@` will not be rendered verbatim by default ([read more](https://github.com/coderofsalvation/hashtagbibs#hashtagbib-mimetypes)) * words beginning with `#` (hashtags) will prime the XRWG by adding the hashtag to the XRWG, linking to the current sentence/paragraph/alltext (depending on '.') to the XRWG
* the XRWG should expand bibs to BibTex occurring in text (`#contactjohn@todo@important` e.g.)
By doing so, the XR Browser (applications-layer) can interpret microformats ([visual-meta](https://visual-meta.info)
to connect text further with its environment ( setup links between textual/spatial objects automatically e.g.).
> for more info on this mimetype see [bibs](https://github.com/coderofsalvation/hashtagbibs)
Advantages: Advantages:
* auto-expanding of [hashtagbibs](https://github.com/coderofsalvation/hashtagbibs) associations
* out-of-the-box (de)multiplex human text and metadata in one go (see [the core principle](#core-principle)) * out-of-the-box (de)multiplex human text and metadata in one go (see [the core principle](#core-principle))
* no network-overhead for metadata (see [the core principle](#core-principle)) * no network-overhead for metadata (see [the core principle](#core-principle))
* ensuring high FPS: HTML/RDF historically is too 'requesty'/'parsy' for game studios * ensuring high FPS: realtime HTML/RDF historically is too 'requesty'/'parsy' for game studios
* rich send/receive/copy-paste everywhere by default, metadata being retained (see [the core principle](#core-principle)) * rich send/receive/copy-paste everywhere by default, metadata being retained (see [the core principle](#core-principle))
* netto result: less webservices, therefore less servers, and overall better FPS in XR * netto result: less webservices, therefore less servers, and overall better FPS in XR
@ -831,115 +780,12 @@ The XR Fragment-compatible browser can let the enduser access visual-meta(data)-
> additional tagging using [bibs](https://github.com/coderofsalvation/hashtagbibs): to tag spatial object `note_canvas` with 'todo', the enduser can type or speak `#note_canvas@todo` > additional tagging using [bibs](https://github.com/coderofsalvation/hashtagbibs): to tag spatial object `note_canvas` with 'todo', the enduser can type or speak `#note_canvas@todo`
## XR Text example parser # Importing/exporting
To prime the XRWG with text from plain text `src`-values, here's an example XR Text (de)multiplexer in javascript (which supports inline bibs & bibtex): For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play.
``` 1. export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.
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
}
}
```
The above functions (de)multiplexe text/metadata, expands bibs, (de)serialize bibtex and vice versa
> above can be used as a startingpoint for LLVM's to translate/steelman to a more formal form/language.
```
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
```
This expands to the following (hidden by default) BibTex appendix:
```
hello world
here are some hashtagbibs followed by bibtex:
@{some-section}
@flap{
asdf = {1}
}
@world{world,
}
@greeting{hello,
}
@{another-section}
@bar{
abc = {123}
}
```
> when an XR browser updates the human text, a quick scan for nonmatching tags (`@book{nonmatchingbook` e.g.) should be performed and prompt the enduser for deleting them.
# Transclusion (broken link) resolution # Transclusion (broken link) resolution

File diff suppressed because it is too large Load diff

View file

@ -52,18 +52,18 @@ XR Fragments exploits the fact that all 3D models already contain such metadata:
Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments <strong>integrates all</strong> which allows a universal viewing experience.<br /> Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments <strong>integrates all</strong> which allows a universal viewing experience.<br />
</t> </t>
<artwork> +───────────────────────────────────────────────────────────────────────────────────────────────+ <artwork><![CDATA[ +───────────────────────────────────────────────────────────────────────────────────────────────+
│ │ │ │
│ U R N │ │ U R N │
│ U R L | │ │ U R L | │
│ | |-----------------+--------| │ │ | |-----------------+--------| │
│ +--------------------------------------------------| │ │ +--------------------------------------------------| │
│ | │ │ | │
│ + https://foo.com/some/foo/scene.glb#someview &lt;-- http URI (=URL and has URN) │ │ + https://foo.com/some/foo/scene.glb#someview <-- http URI (=URL and has URN)
│ | │ │ | │
│ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview &lt;-- an IPFS URI (=URL and has URN) │ │ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview <-- an IPFS URI (=URL and has URN)
│ │ │ │
│ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe &lt;-- an interpeer URI │ │ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI
│ │ │ │
│ │ │ │
│ |------------------------+-------------------------| │ │ |------------------------+-------------------------| │
@ -72,19 +72,20 @@ Instead of forcing authors to combine 3D/2D objects programmatically (publishing
│ │ │ │
+───────────────────────────────────────────────────────────────────────────────────────────────+ +───────────────────────────────────────────────────────────────────────────────────────────────+
]]>
</artwork> </artwork>
<t>Fact: our typical browser URL's are just <strong>a possible implementation</strong> of URI's (for untapped humancentric potential of URI's <eref target="https://interpeer.io">see interpeer.io</eref>)</t> <t>Fact: our typical browser URL's are just <strong>a possible implementation</strong> of URI's (for untapped humancentric potential of URI's <eref target="https://interpeer.io">see interpeer.io</eref>)</t>
<blockquote><t>XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.<br /> <blockquote><t>XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.<br />
But approaches things from a higherlevel feedbackloop/hypermedia browser-perspective.</t> But approaches things from a higherlevel feedbackloop/hypermedia browser-perspective.</t>
</blockquote><t>Below you can see how this translates back into good-old URLs:</t> </blockquote><t>Below you can see how this translates back into good-old URLs:</t>
<artwork> +───────────────────────────────────────────────────────────────────────────────────────────────+ <artwork><![CDATA[ +───────────────────────────────────────────────────────────────────────────────────────────────+
│ │ │ │
│ the soul of any URL: ://macro /meso ?micro #nano │ │ the soul of any URL: ://macro /meso ?micro #nano │
│ │ │ │
│ 2D URL: ://library.com /document ?search #chapter │ │ 2D URL: ://library.com /document ?search #chapter │
│ xrf:// │ │ xrf:// │
│ 4D URL: ://park.com /4Dscene.fbx ─&gt; ?other.glb ─&gt; #view ───&gt; hashbus │ │ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #view ───> hashbus │
│ │ #filter │ │ │ │ #filter │ │
│ │ #tag │ │ │ │ #tag │ │
│ │ (hypermediatic) #material │ │ │ │ (hypermediatic) #material │ │
@ -92,13 +93,14 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec
│ │ ( loop ) #texture │ │ │ │ ( loop ) #texture │ │
│ │ #variable │ │ │ │ #variable │ │
│ │ │ │ │ │ │ │
│ XRWG &lt;─────────────────────&lt;─────────────+ │ │ XRWG <─────────────────────<─────────────+ │
│ │ │ │ │ │ │ │
│ └─ objects ──────────────&gt;─────────────+ │ │ └─ objects ──────────────>─────────────+ │
│ │ │ │
│ │ │ │
+───────────────────────────────────────────────────────────────────────────────────────────────+ +───────────────────────────────────────────────────────────────────────────────────────────────+
]]>
</artwork> </artwork>
<blockquote><t>?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation.</t> <blockquote><t>?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation.</t>
</blockquote><t>Traditional webbrowsers can become 4D document-ready by:</t> </blockquote><t>Traditional webbrowsers can become 4D document-ready by:</t>
@ -196,9 +198,10 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec
<section anchor="xr-fragment-url-grammar"><name>XR Fragment URL Grammar</name> <section anchor="xr-fragment-url-grammar"><name>XR Fragment URL Grammar</name>
<t>For typical HTTP-like browsers/applications:</t> <t>For typical HTTP-like browsers/applications:</t>
<artwork>reserved = gen-delims / sub-delims <artwork><![CDATA[reserved = gen-delims / sub-delims
gen-delims = &quot;#&quot; / &quot;&amp;&quot; gen-delims = "#" / "&"
sub-delims = &quot;,&quot; / &quot;=&quot; sub-delims = "," / "="
]]>
</artwork> </artwork>
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#pos=1,0,0&amp;prio=-5&amp;t=0,100</tt></t> <blockquote><t>Example: <tt>://foo.com/my3d.gltf#pos=1,0,0&amp;prio=-5&amp;t=0,100</tt></t>
</blockquote><table> </blockquote><table>
@ -232,7 +235,7 @@ That way, if the link gets shared, the XR Fragments implementation at <tt>https:
<section anchor="spatial-referencing-3d"><name>Spatial Referencing 3D</name> <section anchor="spatial-referencing-3d"><name>Spatial Referencing 3D</name>
<t>XR Fragments assume the following objectname-to-URIFragment mapping:</t> <t>XR Fragments assume the following objectname-to-URIFragment mapping:</t>
<artwork> <artwork><![CDATA[
my.io/scene.fbx my.io/scene.fbx
+─────────────────────────────+ +─────────────────────────────+
│ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor) │ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor)
@ -248,6 +251,7 @@ That way, if the link gets shared, the XR Fragments implementation at <tt>https:
│ +─────────────────────────+ │ │ +─────────────────────────+ │
+─────────────────────────────+ +─────────────────────────────+
]]>
</artwork> </artwork>
<blockquote><t>Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).</t> <blockquote><t>Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).</t>
</blockquote><t>Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.<br /> </blockquote><t>Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.<br />
@ -544,12 +548,12 @@ For example, to render a portal with a preview-version of the scene, create an 3
<li><tt>https://shaders.org/plasma.glsl#t=0&amp;u:col2=0,1,0</tt> (red-green shader plasma starts playing from time-offset 0)</li> <li><tt>https://shaders.org/plasma.glsl#t=0&amp;u:col2=0,1,0</tt> (red-green shader plasma starts playing from time-offset 0)</li>
</ul> </ul>
<artwork> +──────────────────────────────────────────────────────────+ <artwork><![CDATA[ +──────────────────────────────────────────────────────────+
│ │ │ │
│ index.gltf#playall │ │ index.gltf#playall │
│ │ │ │ │ │
│ ├ # : #t=0&amp;shared=play │ apply default XR Fragment on load (`t` plays global 3D animation timeline) │ ├ # : #t=0&shared=play │ apply default XR Fragment on load (`t` plays global 3D animation timeline)
│ ├ play : #t=0&amp;loop │ variable for [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) │ ├ play : #t=0&loop │ variable for [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
│ │ │ │ │ │
│ ├── ◻ plane (with material) │ │ ├── ◻ plane (with material) │
│ │ └ #: #uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps │ │ └ #: #uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps
@ -558,18 +562,19 @@ For example, to render a portal with a preview-version of the scene, create an 3
│ │ └ src: foo.jpg#uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps │ │ └ src: foo.jpg#uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps
│ │ │ │ │ │
│ ├── ◻ media │ │ ├── ◻ media │
│ │ └ src: cat.mp4#t=l:2,10&amp;uv=0.5,0.5 │ loop cat.mp4 (or mp3/wav/jpg) between 2 and 10 seconds (uv's shifted with 0.5,0.5) │ │ └ src: cat.mp4#t=l:2,10&uv=0.5,0.5 │ loop cat.mp4 (or mp3/wav/jpg) between 2 and 10 seconds (uv's shifted with 0.5,0.5)
│ │ │ │ │ │
│ └── ◻ wall │ │ └── ◻ wall │
│ ├ href: #color=blue │ updates uniform values (IFS shader e.g.) │ ├ href: #color=blue │ updates uniform values (IFS shader e.g.)
│ ├ blue: t=0&amp;u:col=0,0,1 │ variable for [Level1 URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) │ ├ blue: t=0&u:col=0,0,1 │ variable for [Level1 URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
│ └ src: ://a.com/art.glsl#{color}&amp;{shared} │ .fs/.vs/.glsl/.wgsl etc shader [Level1 URI Template (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) │ └ src: ://a.com/art.glsl#{color}&{shared} │ .fs/.vs/.glsl/.wgsl etc shader [Level1 URI Template (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
│ │ │ │
│ │ │ │
+──────────────────────────────────────────────────────────+ +──────────────────────────────────────────────────────────+
&gt; NOTE: URI Template variables are immutable and respect scope: in other words, the end-user cannot modify `blue` by entering an URL like `#blue=.....` in the browser URL, and `blue` is not accessible by the plane/media-object (however `{play}` would work). > NOTE: URI Template variables are immutable and respect scope: in other words, the end-user cannot modify `blue` by entering an URL like `#blue=.....` in the browser URL, and `blue` is not accessible by the plane/media-object (however `{play}` would work).
]]>
</artwork> </artwork>
</section> </section>
</section> </section>
@ -615,18 +620,19 @@ For example, to render a portal with a preview-version of the scene, create an 3
</ol> </ol>
<t>Here's an ascii representation of a 3D scene-graph which contains 3D objects <tt></tt> and their metadata:</t> <t>Here's an ascii representation of a 3D scene-graph which contains 3D objects <tt></tt> and their metadata:</t>
<artwork> +────────────────────────────────────────────────────────+ <artwork><![CDATA[ +────────────────────────────────────────────────────────+
│ │ │ │
│ index.gltf │ │ index.gltf │
│ │ │ │ │ │
│ ├── ◻ buttonA │ │ ├── ◻ buttonA │
│ │ └ href: #pos=1,0,1&amp;t=100,200 │ │ │ └ href: #pos=1,0,1&t=100,200 │
│ │ │ │ │ │
│ └── ◻ buttonB │ │ └── ◻ buttonB │
│ └ href: other.fbx │ &lt;── file─agnostic (can be .gltf .obj etc) │ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc)
│ │ │ │
+────────────────────────────────────────────────────────+ +────────────────────────────────────────────────────────+
]]>
</artwork> </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 /> <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 />
@ -674,7 +680,7 @@ It instances content (in objects) in the current scene/asset, and follows simila
</tbody> </tbody>
</table><t>Here's an ascii representation of a 3D scene-graph with 3D objects <tt></tt> which embeds remote &amp; local 3D objects <tt></tt> with/out using filters:</t> </table><t>Here's an ascii representation of a 3D scene-graph with 3D objects <tt></tt> which embeds remote &amp; local 3D objects <tt></tt> with/out using filters:</t>
<artwork> +────────────────────────────────────────────────────────+ +─────────────────────────+ <artwork><![CDATA[ +────────────────────────────────────────────────────────+ +─────────────────────────+
│ │ │ │ │ │ │ │
│ index.gltf │ │ ocean.com/aquarium.fbx │ │ index.gltf │ │ ocean.com/aquarium.fbx │
│ │ │ │ ├ room │ │ │ │ │ ├ room │
@ -691,6 +697,7 @@ It instances content (in objects) in the current scene/asset, and follows simila
│ └ src: #canvas │ │ └ src: #canvas │
│ │ │ │
+────────────────────────────────────────────────────────+ +────────────────────────────────────────────────────────+
]]>
</artwork> </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 /> <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 />
@ -985,59 +992,41 @@ Perhaps the following question is related: why is HTML adopted less in games out
<li>XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG (<eref target="https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js">example</eref>)</li> <li>XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG (<eref target="https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js">example</eref>)</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 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 &amp; Data URI)</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 &amp; Data URI)</li>
<li>XR Fragments primes the XRWG, by collecting tags/id's from linked hypermedia (URI fragments for HTML e.g.)</li>
<li>The XRWG should be recalculated when textvalues (in <tt>src</tt>) change</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, or as embedded src content)</li> <li>HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer, or as embedded src content)</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>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> <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>
<li>Tags are the scope for now (supporting <eref target="https://github.com/WICG/scroll-to-text-fragment">https://github.com/WICG/scroll-to-text-fragment</eref> will be considered)</li> <li>Instead of exact lowercase word-matching, levensteihn-distance-based matching is preferred</li>
</ol> </ol>
<t>Example of generating BiBTex out of the XRWG and textdata with hashtags:</t> <t>Example of generating XRWG out of the XRWG and textdata with hashtags:</t>
<artwork> http://y.io/z.fbx | Derived XRWG (expressed as BibTex) <artwork><![CDATA[ http://y.io/z.fbx | Derived XRWG (expressed as JSON)
----------------------------------------------------------------------------+-------------------------------------- ----------------------------------------------------------------------------+--------------------------------------
| @house{castle, | Chapter: ['#mydoc']
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | url = {https://y.io/z.fbx#castle} +-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc']
| Chapter one | | / \ | | } | Chapter one | | / \ | | houses: ['#castle','#mydoc','#house']
| | | / \ | | @baroque{castle, | | | / \ | | baroque: ['#mydoc','#castle']
| John built houses in baroque style. | | / \ | | url = {https://y.io/z.fbx#castle} | John built houses in baroque style. | | / \ | | castle: ['#baroque','#house']
| | | |_____| | | } | | | |_____| | | john: ['#john','#mydoc']
| | +-----│-----+ | @baroque{john} | | +-----│-----+ | mydoc: ['#mydoc']
| | │ | | | │ |
| | ├─ name: castle | | | ├─ name: castle |
| | └─ tag: house baroque | | | └─ tag: house baroque |
+----------------------------------------+ | +----------------------------------------+ |
[3D mesh ] | └─ name: mydoc [3D mesh-+ |
| O ├─ name: john | | 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 of deriving a graphdata from the XRWG:</t>
<artwork> http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
----------------------------------------------------------------------------+--------------------------------------
| |
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | @house{castle, [remotestorage.io]+ [ localstorage]-+ | <- the XR Fragment-compatible
| Chapter one | | / \ | | url = {https://y.io/z.fbx#castle} | XRWG (JSON) | | XRWG (JSON | | <- 3D hypermedia viewer should
| | | / \ | | } | | | | | <- be able to select the active XRWG
| 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> </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> <t>This allows hasslefree authoring and copy-paste of associations <strong>for and by humans</strong>, but also makes these URLs possible:</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> <table>
<thead> <thead>
<tr> <tr>
@ -1049,12 +1038,12 @@ This allows hasslefree authoring and copy-paste of associations <strong>for and
<tbody> <tbody>
<tr> <tr>
<td><tt>https://my.com/foo.gltf#baroque</tt></td> <td><tt>https://my.com/foo.gltf#baroque</tt></td>
<td>draws lines between mesh <tt>john</tt>, 3D mesh <tt>castle</tt>, text <tt>John built(..)</tt></td> <td>draws lines between 3D mesh <tt>castle</tt>, and <tt>mydoc</tt>'s text <tt>baroque</tt></td>
</tr> </tr>
<tr> <tr>
<td><tt>https://my.com/foo.gltf#john</tt></td> <td><tt>https://my.com/foo.gltf#john</tt></td>
<td>draws lines between mesh <tt>john</tt>, and the text <tt>John built (..)</tt></td> <td>draws lines between mesh <tt>john</tt>, and the text <tt>John</tt> of <tt>mydoc</tt></td>
</tr> </tr>
<tr> <tr>
@ -1062,8 +1051,8 @@ This allows hasslefree authoring and copy-paste of associations <strong>for and
<td>draws lines between mesh <tt>castle</tt>, and other objects with tag <tt>house</tt> or <tt>todo</tt></td> <td>draws lines between mesh <tt>castle</tt>, and other objects with tag <tt>house</tt> or <tt>todo</tt></td>
</tr> </tr>
</tbody> </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> </table><blockquote><t>the URI fragment <tt>#john&amp;mydoc&amp;house</tt> would draw a connection between these 3 meshes.</t>
</blockquote><t>The XRWG allows XR Browsers to show/hide relationships in realtime at various levels:</t> </blockquote><t>The XRWG allows endusers to show/hide relationships in realtime in XR Browsers at various levels:</t>
<ul spacing="compact"> <ul spacing="compact">
<li>wordmatch <strong>inside</strong> <tt>src</tt> text</li> <li>wordmatch <strong>inside</strong> <tt>src</tt> text</li>
@ -1083,49 +1072,25 @@ Some pointers for good UX (but not necessary to be XR Fragment compatible):</t>
<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: 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> <li>anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.</li>
</ol> </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>&lt;John&gt; Hey what about this: https://my.com/station.gltf#pos=0,0,1&amp;rot=90,2,0&amp;t=500,1000
&lt;Sarah&gt; I'm checking it right now
&lt;Sarah&gt; I don't see everything..where's our text from yesterday?
&lt;John&gt; Ah wait, that's tagged with tag 'draft' (and hidden)..hold on, try this:
&lt;John&gt; https://my.com/station.gltf#.draft&amp;pos=0,0,1&amp;rot=90,2,0&amp;t=500,1000
&lt;Sarah&gt; how about we link the draft to the upcoming YELLO-event?
&lt;John&gt; ok I'm adding #draft@YELLO
&lt;Sarah&gt; Yesterday I also came up with other usefull assocations between other texts in the scene:
#event#YELLO
#2025@YELLO
&lt;John&gt; thanks, added.
&lt;Sarah&gt; Btw. I stumbled upon this spatial book which references station.gltf in some chapters:
&lt;Sarah&gt; https://thecommunity.org/forum/foo/mytrainstory.txt
&lt;John&gt; interesting, I'm importing mytrainstory.txt into station.gltf
&lt;John&gt; 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> <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 <tt>src</tt>-values work as expected (respecting mime-types), however:</t>
<t>The XR Fragment specification advices to bump the traditional default browser-mimetype</t> <t>The XR Fragment specification advices to bump the traditional default browser-mimetype</t>
<t><tt>text/plain;charset=US-ASCII</tt></t> <t><tt>text/plain;charset=US-ASCII</tt></t>
<t>to a hashtagbib(tex)-friendly one:</t> <t>to a hashtag-friendly one:</t>
<t><tt>text/plain;charset=utf-8;bib=^@</tt></t> <t><tt>text/plain;charset=utf-8;hashtag</tt></t>
<t>This indicates that:</t> <t>This indicates that:</t>
<ul spacing="compact"> <ul spacing="compact">
<li>utf-8 is supported by default</li> <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>words beginning with <tt>#</tt> (hashtags) will prime the XRWG by adding the hashtag to the XRWG, linking to the current sentence/paragraph/alltext (depending on '.') to the XRWG</li>
<li>the XRWG should expand bibs to BibTex occurring in text (<tt>#contactjohn@todo@important</tt> e.g.)</li>
</ul> </ul>
<t>By doing so, the XR Browser (applications-layer) can interpret microformats (<eref target="https://visual-meta.info">visual-meta</eref> <t>Advantages:</t>
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"> <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>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>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>ensuring high FPS: realtime 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>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> <li>netto result: less webservices, therefore less servers, and overall better FPS in XR</li>
</ul> </ul>
@ -1136,7 +1101,7 @@ to connect text further with its environment ( setup links between textual/spati
<section anchor="url-and-data-uri"><name>URL and Data URI</name> <section anchor="url-and-data-uri"><name>URL and Data URI</name>
<artwork> +--------------------------------------------------------------+ +------------------------+ <artwork><![CDATA[ +--------------------------------------------------------------+ +------------------------+
| | | author.com/article.txt | | | | author.com/article.txt |
| index.gltf | +------------------------+ | index.gltf | +------------------------+
| │ | | | | │ | | |
@ -1148,6 +1113,7 @@ to connect text further with its environment ( setup links between textual/spati
| | +------------------------+ | | +------------------------+
| | | |
+--------------------------------------------------------------+ +--------------------------------------------------------------+
]]>
</artwork> </artwork>
<t>The enduser will only see <tt>welcome human</tt> and <tt>Hello friends</tt> rendered verbatim (see mimetype). <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). The beauty is that text in Data URI automatically promotes rich copy-paste (retaining metadata).
@ -1155,110 +1121,14 @@ In both cases, the text gets rendered immediately (onto a plane geometry, hence
The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.).</t> 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><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> </blockquote></section>
</section>
<section anchor="xr-text-example-parser"><name>XR Text example parser</name> <section anchor="importing-exporting"><name>Importing/exporting</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 &amp; bibtex):</t> <t>For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play.</t>
<artwork>xrtext = { <ol spacing="compact">
<li>export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.</li>
expandBibs: (text) =&gt; { </ol>
let bibs = { regex: /(#[a-zA-Z0-9_+@\-]+(#)?)/g, tags: {}}
text.replace( bibs.regex , (m,k,v) =&gt; {
tok = m.substr(1).split(&quot;@&quot;)
match = tok.shift()
if( tok.length ) tok.map( (t) =&gt; 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) =&gt; {
// bibtex: ↓@ ↓&lt;tag|tag{phrase,|{ruler}&gt; ↓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 &lt; lines.length &amp;&amp; !String(lines[i]).match( /^@/ ); i++ )
text += lines[i]+'\n'
bibtex = lines.join('\n').substr( text.length )
bibtex.split( pat[0] ).map( (t) =&gt; {
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 =&gt; {
if( !(kv = kv.trim()) || kv == &quot;}&quot; ) return
v[ kv.match(/\s?(\S+)\s?=/)[1] ] = kv.substr( kv.indexOf(&quot;{&quot;)+1 )
})
tags.push( { k:tag, v } )
}catch(e){ console.error(e) }
})
return {text, tags}
},
encode: (text,tags) =&gt; {
let str = text+&quot;\n&quot;
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 &amp; bibtex
tags.find( (t) =&gt; 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 &amp; 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>
<section anchor="transclusion-broken-link-resolution"><name>Transclusion (broken link) resolution</name> <section anchor="transclusion-broken-link-resolution"><name>Transclusion (broken link) resolution</name>
@ -1272,7 +1142,7 @@ here are some hashtagbibs followed by bibtex:
<blockquote><t>due to the popularity, maturity and extensiveness of HTTP codes for client/server communication, non-HTTP protocols easily map to HTTP codes (ipfs ERR_NOT_FOUND maps to 404 e.g.)</t> <blockquote><t>due to the popularity, maturity and extensiveness of HTTP codes for client/server communication, non-HTTP protocols easily map to HTTP codes (ipfs ERR_NOT_FOUND maps to 404 e.g.)</t>
</blockquote><t>For example:</t> </blockquote><t>For example:</t>
<artwork> +────────────────────────────────────────────────────────+ <artwork><![CDATA[ +────────────────────────────────────────────────────────+
│ │ │ │
│ index.gltf │ │ index.gltf │
│ │ │ │ │ │
@ -1284,13 +1154,14 @@ here are some hashtagbibs followed by bibtex:
│ │ └ href@400: #clienterrortext │ │ │ └ href@400: #clienterrortext │
│ │ └ ◻ offlinetext │ │ │ └ ◻ offlinetext │
│ │ │ │ │ │
│ └── ◻ embeddedObject &lt;--------- the meshdata inside embeddedObject will (not) │ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not)
│ └ src: https://foo.io/bar.gltf │ be flushed when the request (does not) succeed. │ └ src: https://foo.io/bar.gltf │ be flushed when the request (does not) succeed.
│ └ src@404: http://foo.io/bar.gltf │ So worstcase the 3D data (of the time of publishing index.gltf) │ └ src@404: http://foo.io/bar.gltf │ So worstcase the 3D data (of the time of publishing index.gltf)
│ └ src@400: https://archive.org/l2kj43.gltf │ will be displayed. │ └ src@400: https://archive.org/l2kj43.gltf │ will be displayed.
│ │ │ │
+────────────────────────────────────────────────────────+ +────────────────────────────────────────────────────────+
]]>
</artwork> </artwork>
</section> </section>
@ -1322,7 +1193,7 @@ To filter out non-related objects one could take it a step further using filters
The following demonstrates a simple video player:</t> The following demonstrates a simple video player:</t>
<artwork> <artwork><![CDATA[
+─────────────────────────────────────────────+ +─────────────────────────────────────────────+
│ │ │ │
│ foo.usdz │ │ foo.usdz │
@ -1330,18 +1201,19 @@ The following demonstrates a simple video player:</t>
│ │ │ │ │ │
│ ├── ◻ stopbutton │ │ ├── ◻ stopbutton │
│ │ ├ #: #-stopbutton │ │ │ ├ #: #-stopbutton │
│ │ └ href: #player=stop&amp;-stopbutton │ (stop and hide stop-button) │ │ └ href: #player=stop&-stopbutton │ (stop and hide stop-button)
│ │ │ │ │ │
│ └── ◻ plane │ │ └── ◻ plane │
│ ├ play: #t=l:0,10 │ │ ├ play: #t=l:0,10 │
│ ├ stop: #t=0,0 │ │ ├ stop: #t=0,0 │
│ ├ href: #player=play&amp;stopbutton │ (play and show stop-button) │ ├ href: #player=play&stopbutton │ (play and show stop-button)
│ └ src: cat.mp4#{player} │ │ └ src: cat.mp4#{player} │
│ │ │ │
│ │ │ │
+─────────────────────────────────────────────+ +─────────────────────────────────────────────+
]]>
</artwork> </artwork>
</section> </section>

Binary file not shown.