pages: work in progress [might break]
This commit is contained in:
parent
925cbe4deb
commit
0f7f482a3d
|
@ -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 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>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 <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>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>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>
|
||||
|
||||
<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,
|
||||
+-[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}
|
||||
| | | |_____| | | }
|
||||
| | +-----│-----+ | @baroque{john}
|
||||
| Chapter: ['#mydoc']
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc']
|
||||
| Chapter one | | / \ | | houses: ['#castle','#mydoc','#house']
|
||||
| | | / \ | | baroque: ['#mydoc','#castle']
|
||||
| John built houses in baroque style. | | / \ | | castle: ['#baroque','#house']
|
||||
| | | |_____| | | john: ['#john','#mydoc']
|
||||
| | +-----│-----+ | mydoc: ['#mydoc']
|
||||
| | │ |
|
||||
| | ├─ name: castle |
|
||||
| | └─ tag: house baroque |
|
||||
+----------------------------------------+ |
|
||||
[3D mesh ] |
|
||||
└─ name: mydoc [3D mesh-+ |
|
||||
| O ├─ name: john |
|
||||
| /|\ | |
|
||||
| / \ | |
|
||||
+--------+ |
|
||||
| / \ | | ^ ^ ^
|
||||
+--------+ | | | |
|
||||
|
|
||||
[remotestorage.io]+ [ localstorage]-+ | <- the XR Fragment-compatible
|
||||
| XRWG (JSON) | | XRWG (JSON | | <- 3D hypermedia viewer should
|
||||
| | | | | <- be able to select the active XRWG
|
||||
+-----------------+ +---------------+ |
|
||||
</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,
|
||||
| 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>
|
||||
<p>This allows hasslefree authoring and copy-paste of associations <strong>for and by humans</strong>, but also makes these URLs possible:</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -1193,12 +1168,12 @@ This allows hasslefree authoring and copy-paste of associations <strong>for and
|
|||
<tbody>
|
||||
<tr>
|
||||
<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>’s text <code>baroque</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<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>
|
||||
|
@ -1209,10 +1184,10 @@ This allows hasslefree authoring and copy-paste of associations <strong>for and
|
|||
</table>
|
||||
|
||||
<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&mydoc&house</code> would draw a connection between these 3 meshes.</p>
|
||||
</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>
|
||||
<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>
|
||||
</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><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>
|
||||
|
@ -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>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>
|
||||
|
||||
<ul>
|
||||
<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>the XRWG should expand bibs to BibTex occurring in text (<code>#contactjohn@todo@important</code> e.g.)</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 ‘.’) to the XRWG</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>
|
||||
|
||||
<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>
|
||||
<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 <a href="#core-principle">the core principle</a>)</li>
|
||||
<li>netto result: less webservices, therefore less servers, and overall better FPS in XR</li>
|
||||
</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 ‘todo’, the enduser can type or speak <code>#note_canvas@todo</code></p>
|
||||
</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’s an example XR Text (de)multiplexer in javascript (which supports inline bibs & bibtex):</p>
|
||||
<p>For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play.</p>
|
||||
|
||||
<pre><code>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
|
||||
}
|
||||
}
|
||||
</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’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 & 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
|
||||
</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>
|
||||
<ol>
|
||||
<li>export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.</li>
|
||||
</ol>
|
||||
|
||||
<h1 id="transclusion-broken-link-resolution">Transclusion (broken link) resolution</h1>
|
||||
|
||||
|
|
|
@ -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))
|
||||
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)
|
||||
6. The XRWG should be recalculated when textvalues (in `src`) change
|
||||
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)
|
||||
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.
|
||||
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)
|
||||
10. Tags are the scope for now (supporting https://github.com/WICG/scroll-to-text-fragment will be considered)
|
||||
4. XR Fragments primes the XRWG, by collecting tags/id's from linked hypermedia (URI fragments for HTML e.g.)
|
||||
5. The XRWG should be recalculated when textvalues (in `src`) change
|
||||
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)
|
||||
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.
|
||||
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,
|
||||
+-[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}
|
||||
| | | |_____| | | }
|
||||
| | +-----│-----+ | @baroque{john}
|
||||
| Chapter: ['#mydoc']
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc']
|
||||
| Chapter one | | / \ | | houses: ['#castle','#mydoc','#house']
|
||||
| | | / \ | | baroque: ['#mydoc','#castle']
|
||||
| John built houses in baroque style. | | / \ | | castle: ['#baroque','#house']
|
||||
| | | |_____| | | john: ['#john','#mydoc']
|
||||
| | +-----│-----+ | mydoc: ['#mydoc']
|
||||
| | │ |
|
||||
| | ├─ name: castle |
|
||||
| | └─ tag: house baroque |
|
||||
+----------------------------------------+ |
|
||||
[3D mesh ] |
|
||||
└─ name: mydoc [3D mesh-+ |
|
||||
| O ├─ name: john |
|
||||
| /|\ | |
|
||||
| / \ | |
|
||||
+--------+ |
|
||||
| / \ | | ^ ^ ^
|
||||
+--------+ | | | |
|
||||
|
|
||||
[remotestorage.io]+ [ localstorage]-+ | <- the XR Fragment-compatible
|
||||
| XRWG (JSON) | | XRWG (JSON | | <- 3D hypermedia viewer should
|
||||
| | | | | <- be able to select the active XRWG
|
||||
+-----------------+ +---------------+ |
|
||||
```
|
||||
|
||||
> 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,
|
||||
| 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 | | /|\ | |
|
||||
| ... | | / \ | |
|
||||
+----------------------------------------+ +--------+ |
|
||||
```
|
||||
|
||||
> 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:
|
||||
|
||||
| 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#john` | draws lines between mesh `john`, and the 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` of `mydoc` |
|
||||
| `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** `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))
|
||||
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
|
||||
|
||||
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`
|
||||
|
||||
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:
|
||||
|
||||
* 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))
|
||||
* 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)
|
||||
* 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
|
||||
|
||||
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))
|
||||
* 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))
|
||||
* 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`
|
||||
|
||||
## 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.
|
||||
|
||||
```
|
||||
xrtext = {
|
||||
1. export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.
|
||||
|
||||
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
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 />
|
||||
</t>
|
||||
|
||||
<artwork> +───────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
<artwork><![CDATA[ +───────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
│ │
|
||||
│ U R N │
|
||||
│ U R L | │
|
||||
│ | |-----------------+--------| │
|
||||
│ +--------------------------------------------------| │
|
||||
│ | │
|
||||
│ + https://foo.com/some/foo/scene.glb#someview <-- 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 <-- an IPFS URI (=URL and has URN) │
|
||||
│ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview <-- an IPFS URI (=URL and has URN) │
|
||||
│ │
|
||||
│ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI │
|
||||
│ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI │
|
||||
│ │
|
||||
│ │
|
||||
│ |------------------------+-------------------------| │
|
||||
|
@ -72,19 +72,20 @@ Instead of forcing authors to combine 3D/2D objects programmatically (publishing
|
|||
│ │
|
||||
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
|
||||
]]>
|
||||
</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>
|
||||
<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>
|
||||
</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 │
|
||||
│ │
|
||||
│ 2D URL: ://library.com /document ?search #chapter │
|
||||
│ xrf:// │
|
||||
│ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #view ───> hashbus │
|
||||
│ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #view ───> hashbus │
|
||||
│ │ #filter │ │
|
||||
│ │ #tag │ │
|
||||
│ │ (hypermediatic) #material │ │
|
||||
|
@ -92,13 +93,14 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec
|
|||
│ │ ( loop ) #texture │ │
|
||||
│ │ #variable │ │
|
||||
│ │ │ │
|
||||
│ XRWG <─────────────────────<─────────────+ │
|
||||
│ XRWG <─────────────────────<─────────────+ │
|
||||
│ │ │ │
|
||||
│ └─ objects ──────────────>─────────────+ │
|
||||
│ └─ objects ──────────────>─────────────+ │
|
||||
│ │
|
||||
│ │
|
||||
+───────────────────────────────────────────────────────────────────────────────────────────────+
|
||||
|
||||
]]>
|
||||
</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>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>
|
||||
<t>For typical HTTP-like browsers/applications:</t>
|
||||
|
||||
<artwork>reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
<artwork><![CDATA[reserved = gen-delims / sub-delims
|
||||
gen-delims = "#" / "&"
|
||||
sub-delims = "," / "="
|
||||
]]>
|
||||
</artwork>
|
||||
<blockquote><t>Example: <tt>://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100</tt></t>
|
||||
</blockquote><table>
|
||||
|
@ -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>
|
||||
<t>XR Fragments assume the following objectname-to-URIFragment mapping:</t>
|
||||
|
||||
<artwork>
|
||||
<artwork><![CDATA[
|
||||
my.io/scene.fbx
|
||||
+─────────────────────────────+
|
||||
│ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor)
|
||||
|
@ -248,6 +251,7 @@ That way, if the link gets shared, the XR Fragments implementation at <tt>https:
|
|||
│ +─────────────────────────+ │
|
||||
+─────────────────────────────+
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
<blockquote><t>Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects).</t>
|
||||
</blockquote><t>Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.<br />
|
||||
|
@ -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&u:col2=0,1,0</tt> (red-green shader plasma starts playing from time-offset 0)</li>
|
||||
</ul>
|
||||
|
||||
<artwork> +──────────────────────────────────────────────────────────+
|
||||
<artwork><![CDATA[ +──────────────────────────────────────────────────────────+
|
||||
│ │
|
||||
│ index.gltf#playall │
|
||||
│ │ │
|
||||
│ ├ # : #t=0&shared=play │ apply default XR Fragment on load (`t` plays global 3D animation timeline)
|
||||
│ ├ play : #t=0&loop │ variable for [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
|
||||
│ ├ # : #t=0&shared=play │ apply default XR Fragment on load (`t` plays global 3D animation timeline)
|
||||
│ ├ play : #t=0&loop │ variable for [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
|
||||
│ │ │
|
||||
│ ├── ◻ plane (with material) │
|
||||
│ │ └ #: #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
|
||||
│ │ │
|
||||
│ ├── ◻ media │
|
||||
│ │ └ 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)
|
||||
│ │ └ 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 │
|
||||
│ ├ href: #color=blue │ updates uniform values (IFS shader e.g.)
|
||||
│ ├ 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}&{shared} │ .fs/.vs/.glsl/.wgsl etc shader [Level1 URI Template (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}&{shared} │ .fs/.vs/.glsl/.wgsl etc shader [Level1 URI Template (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
|
||||
│ │
|
||||
│ │
|
||||
+──────────────────────────────────────────────────────────+
|
||||
|
||||
> 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>
|
||||
</section>
|
||||
</section>
|
||||
|
@ -615,18 +620,19 @@ For example, to render a portal with a preview-version of the scene, create an 3
|
|||
</ol>
|
||||
<t>Here's an ascii representation of a 3D scene-graph which contains 3D objects <tt>◻</tt> and their metadata:</t>
|
||||
|
||||
<artwork> +────────────────────────────────────────────────────────+
|
||||
<artwork><![CDATA[ +────────────────────────────────────────────────────────+
|
||||
│ │
|
||||
│ index.gltf │
|
||||
│ │ │
|
||||
│ ├── ◻ buttonA │
|
||||
│ │ └ href: #pos=1,0,1&t=100,200 │
|
||||
│ │ └ href: #pos=1,0,1&t=100,200 │
|
||||
│ │ │
|
||||
│ └── ◻ buttonB │
|
||||
│ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc)
|
||||
│ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc)
|
||||
│ │
|
||||
+────────────────────────────────────────────────────────+
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
<t>An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the <tt>buttonA</tt> and <tt>buttonB</tt>.<br />
|
||||
|
||||
|
@ -674,7 +680,7 @@ It instances content (in objects) in the current scene/asset, and follows simila
|
|||
</tbody>
|
||||
</table><t>Here's an ascii representation of a 3D scene-graph with 3D objects <tt>◻</tt> which embeds remote & local 3D objects <tt>◻</tt> with/out using filters:</t>
|
||||
|
||||
<artwork> +────────────────────────────────────────────────────────+ +─────────────────────────+
|
||||
<artwork><![CDATA[ +────────────────────────────────────────────────────────+ +─────────────────────────+
|
||||
│ │ │ │
|
||||
│ index.gltf │ │ ocean.com/aquarium.fbx │
|
||||
│ │ │ │ ├ room │
|
||||
|
@ -691,6 +697,7 @@ It instances content (in objects) in the current scene/asset, and follows simila
|
|||
│ └ 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 />
|
||||
|
||||
|
@ -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 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>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>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>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>
|
||||
<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,
|
||||
+-[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}
|
||||
| | | |_____| | | }
|
||||
| | +-----│-----+ | @baroque{john}
|
||||
| Chapter: ['#mydoc']
|
||||
+-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc']
|
||||
| Chapter one | | / \ | | houses: ['#castle','#mydoc','#house']
|
||||
| | | / \ | | baroque: ['#mydoc','#castle']
|
||||
| John built houses in baroque style. | | / \ | | castle: ['#baroque','#house']
|
||||
| | | |_____| | | john: ['#john','#mydoc']
|
||||
| | +-----│-----+ | mydoc: ['#mydoc']
|
||||
| | │ |
|
||||
| | ├─ name: castle |
|
||||
| | └─ tag: house baroque |
|
||||
+----------------------------------------+ |
|
||||
[3D mesh ] |
|
||||
└─ name: mydoc [3D mesh-+ |
|
||||
| O ├─ name: john |
|
||||
| /|\ | |
|
||||
| / \ | |
|
||||
+--------+ |
|
||||
| / \ | | ^ ^ ^
|
||||
+--------+ | | | |
|
||||
|
|
||||
[remotestorage.io]+ [ localstorage]-+ | <- the XR Fragment-compatible
|
||||
| XRWG (JSON) | | XRWG (JSON | | <- 3D hypermedia viewer should
|
||||
| | | | | <- be able to select the active XRWG
|
||||
+-----------------+ +---------------+ |
|
||||
]]>
|
||||
</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,
|
||||
| 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>
|
||||
<t>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>
|
||||
|
@ -1049,12 +1038,12 @@ This allows hasslefree authoring and copy-paste of associations <strong>for and
|
|||
<tbody>
|
||||
<tr>
|
||||
<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>
|
||||
<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>
|
||||
|
@ -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>
|
||||
</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>
|
||||
</table><blockquote><t>the URI fragment <tt>#john&mydoc&house</tt> would draw a connection between these 3 meshes.</t>
|
||||
</blockquote><t>The XRWG allows endusers to show/hide relationships in realtime in XR Browsers at various levels:</t>
|
||||
|
||||
<ul spacing="compact">
|
||||
<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: 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 advices to bump 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>to a hashtag-friendly one:</t>
|
||||
<t><tt>text/plain;charset=utf-8;hashtag</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>
|
||||
<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>
|
||||
</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>
|
||||
<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>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>netto result: less webservices, therefore less servers, and overall better FPS in XR</li>
|
||||
</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>
|
||||
|
||||
<artwork> +--------------------------------------------------------------+ +------------------------+
|
||||
<artwork><![CDATA[ +--------------------------------------------------------------+ +------------------------+
|
||||
| | | author.com/article.txt |
|
||||
| index.gltf | +------------------------+
|
||||
| │ | | |
|
||||
|
@ -1148,6 +1113,7 @@ to connect text further with its environment ( setup links between textual/spati
|
|||
| | +------------------------+
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
]]>
|
||||
</artwork>
|
||||
<t>The enduser will only see <tt>welcome human</tt> and <tt>Hello friends</tt> rendered verbatim (see mimetype).
|
||||
The beauty is that text in Data URI automatically promotes rich copy-paste (retaining metadata).
|
||||
|
@ -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>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<section anchor="importing-exporting"><name>Importing/exporting</name>
|
||||
<t>For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play.</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>
|
||||
<ol spacing="compact">
|
||||
<li>export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<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>For example:</t>
|
||||
|
||||
<artwork> +────────────────────────────────────────────────────────+
|
||||
<artwork><![CDATA[ +────────────────────────────────────────────────────────+
|
||||
│ │
|
||||
│ index.gltf │
|
||||
│ │ │
|
||||
|
@ -1284,13 +1154,14 @@ here are some hashtagbibs followed by bibtex:
|
|||
│ │ └ href@400: #clienterrortext │
|
||||
│ │ └ ◻ offlinetext │
|
||||
│ │ │
|
||||
│ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not)
|
||||
│ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not)
|
||||
│ └ src: https://foo.io/bar.gltf │ be flushed when the request (does not) succeed.
|
||||
│ └ src@404: http://foo.io/bar.gltf │ So worstcase the 3D data (of the time of publishing index.gltf)
|
||||
│ └ src@400: https://archive.org/l2kj43.gltf │ will be displayed.
|
||||
│ │
|
||||
+────────────────────────────────────────────────────────+
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
</section>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
<artwork>
|
||||
<artwork><![CDATA[
|
||||
+─────────────────────────────────────────────+
|
||||
│ │
|
||||
│ foo.usdz │
|
||||
|
@ -1330,18 +1201,19 @@ The following demonstrates a simple video player:</t>
|
|||
│ │ │
|
||||
│ ├── ◻ stopbutton │
|
||||
│ │ ├ #: #-stopbutton │
|
||||
│ │ └ href: #player=stop&-stopbutton │ (stop and hide stop-button)
|
||||
│ │ └ href: #player=stop&-stopbutton │ (stop and hide stop-button)
|
||||
│ │ │
|
||||
│ └── ◻ plane │
|
||||
│ ├ play: #t=l:0,10 │
|
||||
│ ├ stop: #t=0,0 │
|
||||
│ ├ href: #player=play&stopbutton │ (play and show stop-button)
|
||||
│ ├ href: #player=play&stopbutton │ (play and show stop-button)
|
||||
│ └ src: cat.mp4#{player} │
|
||||
│ │
|
||||
│ │
|
||||
+─────────────────────────────────────────────+
|
||||
|
||||
|
||||
]]>
|
||||
</artwork>
|
||||
</section>
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue