diff --git a/.gitignore b/.gitignore
index 6d90f51..38a8853 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@ tags
example/assets/*.blend*
2wa.gitlab.io/*
src/3rd/js/aframe/build/aframe
-
+example/godot/addons
+example/godot/dist
diff --git a/doc/RF6_XR_Fragments.png b/doc/RF6_XR_Fragments.png
index 006922e..8188c86 100644
Binary files a/doc/RF6_XR_Fragments.png and b/doc/RF6_XR_Fragments.png differ
diff --git a/doc/RFC_XR_Fragments.html b/doc/RFC_XR_Fragments.html
index 4f81486..e2c916d 100644
--- a/doc/RFC_XR_Fragments.html
+++ b/doc/RFC_XR_Fragments.html
@@ -720,7 +720,11 @@ For example, to render a portal with a preview-version of the scene, create an 3
set the position of the camera accordingly to the vector3 values of #pos
rot
sets the rotation of the camera (only for non-VR/AR headsets)
mediafragment t
in the top-URL sets the playbackspeed and animation-range of the global scene animation
-after scene load: in case an href
does not mention any pos
-coordinate, pos=0,0,0
will be assumed
+before scene load: the scene is cleared
+after scene load: in case the scene (rootnode) contains an #
default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)
+after scene load: in case the scene (rootnode) contains an #
default view with a fragment value: execute positional fragment via the hashbus + update top-level URL
+in case of no default #
view on the scene (rootnode), default player(rig) position 0,0,0
is assumed.
+in case a href
does not mention any pos
-coordinate, the current position will be assumed
Here’s an ascii representation of a 3D scene-graph which contains 3D objects ◻
and their metadata:
@@ -761,7 +765,7 @@ In case of buttonA
the end-user will be teleported to another locat
Embedding XR content using src
src
is the 3D version of the iframe.
-It instances content (in objects) in the current scene/asset.
+It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.
diff --git a/doc/RFC_XR_Fragments.md b/doc/RFC_XR_Fragments.md
index d16e33d..2db971d 100644
--- a/doc/RFC_XR_Fragments.md
+++ b/doc/RFC_XR_Fragments.md
@@ -383,10 +383,14 @@ Example URI's:
[» discussion](https://github.com/coderofsalvation/xrfragment/issues/5)
1. the Y-coordinate of `pos` identifies the floorposition. This means that desktop-projections usually need to add 1.5m (average person height) on top (which is done automatically by VR/AR headsets).
-1. set the position of the camera accordingly to the vector3 values of `#pos`
-1. `rot` sets the rotation of the camera (only for non-VR/AR headsets)
-1. mediafragment `t` in the top-URL sets the playbackspeed and animation-range of the global scene animation
-1. after scene load: in case an `href` does not mention any `pos`-coordinate, `pos=0,0,0` will be assumed
+2. set the position of the camera accordingly to the vector3 values of `#pos`
+3. `rot` sets the rotation of the camera (only for non-VR/AR headsets)
+4. mediafragment `t` in the top-URL sets the playbackspeed and animation-range of the global scene animation
+5. before scene load: the scene is cleared
+6. after scene load: in case the scene (rootnode) contains an `#` default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)
+7. after scene load: in case the scene (rootnode) contains an `#` default view with a fragment value: execute positional fragment via the hashbus + update top-level URL
+8. in case of no default `#` view on the scene (rootnode), default player(rig) position `0,0,0` is assumed.
+9. in case a `href` does not mention any `pos`-coordinate, the current position will be assumed
Here's an ascii representation of a 3D scene-graph which contains 3D objects `◻` and their metadata:
@@ -424,7 +428,7 @@ The URL-processing-flow for hypermedia browsers goes like this:
# Embedding XR content using src
`src` is the 3D version of the iframe.
-It instances content (in objects) in the current scene/asset.
+It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.
| fragment | type | example value |
|----------|------|---------------|
diff --git a/doc/RFC_XR_Fragments.txt b/doc/RFC_XR_Fragments.txt
index 3444f6e..cea33b4 100644
--- a/doc/RFC_XR_Fragments.txt
+++ b/doc/RFC_XR_Fragments.txt
@@ -3,7 +3,7 @@
Jens & Leon Internet Engineering Task Force L.R. van Kammen
-Internet-Draft 25 April 2024
+Internet-Draft 9 May 2024
Intended status: Informational
@@ -46,16 +46,16 @@ Status of This Memo
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
- This Internet-Draft will expire on 27 October 2024.
+ This Internet-Draft will expire on 10 November 2024.
-van Kammen Expires 27 October 2024 [Page 1]
+van Kammen Expires 10 November 2024 [Page 1]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
Copyright Notice
@@ -109,9 +109,9 @@ Table of Contents
-van Kammen Expires 27 October 2024 [Page 2]
+van Kammen Expires 10 November 2024 [Page 2]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
21. Additional scene metadata . . . . . . . . . . . . . . . . . . 35
@@ -165,9 +165,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 3]
+van Kammen Expires 10 November 2024 [Page 3]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
XR Fragments tries to seek to connect the world of text (semantical
@@ -221,9 +221,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 4]
+van Kammen Expires 10 November 2024 [Page 4]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
+───────────────────────────────────────────────────────────────────────────────────────────────+
@@ -277,9 +277,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 5]
+van Kammen Expires 10 November 2024 [Page 5]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
* allowing 3D assets/nodes to publish XR Fragments to themselves/
@@ -333,9 +333,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 6]
+van Kammen Expires 10 November 2024 [Page 6]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
+=========+======================+=====================================+
@@ -389,9 +389,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 7]
+van Kammen Expires 10 November 2024 [Page 7]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
4. Conventions and Definitions
@@ -445,9 +445,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 8]
+van Kammen Expires 10 November 2024 [Page 8]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
my.io/scene.fbx
@@ -501,9 +501,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 9]
+van Kammen Expires 10 November 2024 [Page 9]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
|Media Fragments |media fragment |#t=0,2&loop |play (and |
@@ -557,9 +557,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 10]
+van Kammen Expires 10 November 2024 [Page 10]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
6.2. Fragment-to-metadata mapping
@@ -613,9 +613,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 11]
+van Kammen Expires 10 November 2024 [Page 11]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
| | | | |metadata (bar:#t=0 |
@@ -669,9 +669,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 12]
+van Kammen Expires 10 November 2024 [Page 12]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
| temporal | s=x | 1 | set playback |
@@ -725,9 +725,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 13]
+van Kammen Expires 10 November 2024 [Page 13]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
| | | | uv |
@@ -781,9 +781,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 14]
+van Kammen Expires 10 November 2024 [Page 14]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
+──────────────────────────────────────────────────────────+
@@ -837,9 +837,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 15]
+van Kammen Expires 10 November 2024 [Page 15]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
1. the Y-coordinate of pos identifies the floorposition. This means
@@ -850,8 +850,17 @@ Internet-Draft XR Fragments April 2024
3. rot sets the rotation of the camera (only for non-VR/AR headsets)
4. mediafragment t in the top-URL sets the playbackspeed and
animation-range of the global scene animation
- 5. after scene load: in case an href does not mention any pos-
- coordinate, pos=0,0,0 will be assumed
+ 5. before scene load: the scene is cleared
+ 6. after scene load: in case the scene (rootnode) contains an #
+ default view with a fragment value: execute non-positional
+ fragments via the hashbus (no top-level URL change)
+ 7. after scene load: in case the scene (rootnode) contains an #
+ default view with a fragment value: execute positional fragment
+ via the hashbus + update top-level URL
+ 8. in case of no default # view on the scene (rootnode), default
+ player(rig) position 0,0,0 is assumed.
+ 9. in case a href does not mention any pos-coordinate, the current
+ position will be assumed
Here's an ascii representation of a 3D scene-graph which contains 3D
objects ◻ and their metadata:
@@ -881,23 +890,20 @@ Internet-Draft XR Fragments April 2024
The URL-processing-flow for hypermedia browsers goes like this:
+
+
+
+van Kammen Expires 10 November 2024 [Page 16]
+
+Internet-Draft XR Fragments May 2024
+
+
1. IF a #cube matches a custom property-key (of an object) in the 3D
file/scene (#cube: #......) THEN execute that
predefined_view.
2. IF scene operators (pos) and/or animation operator (t) are
present in the URL then (re)position the camera and/or animation-
range accordingly.
-
-
-
-
-
-
-van Kammen Expires 27 October 2024 [Page 16]
-
-Internet-Draft XR Fragments April 2024
-
-
3. IF no camera-position has been set in step 1 or 2 update
the top-level URL with #pos=0,0,0 (example (https://github.com/co
derofsalvation/xrfragment/blob/main/src/3rd/js/three/
@@ -912,7 +918,9 @@ Internet-Draft XR Fragments April 2024
src is the 3D version of the iframe.
- It instances content (in objects) in the current scene/asset.
+ It instances content (in objects) in the current scene/asset, and
+ follows similar logic like the previous chapter, except that it does
+ not modify the camera.
+========+========+===================================================+
|fragment|type |example value |
@@ -941,17 +949,9 @@ Internet-Draft XR Fragments April 2024
-
-
-
-
-
-
-
-
-van Kammen Expires 27 October 2024 [Page 17]
+van Kammen Expires 10 November 2024 [Page 17]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
+────────────────────────────────────────────────────────+ +─────────────────────────+
@@ -1005,9 +1005,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 18]
+van Kammen Expires 10 November 2024 [Page 18]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
6. external src values should be served with appropriate
@@ -1061,9 +1061,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 19]
+van Kammen Expires 10 November 2024 [Page 19]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
+==========+==================+============================+
@@ -1117,9 +1117,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 20]
+van Kammen Expires 10 November 2024 [Page 20]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
» example implementation
@@ -1173,9 +1173,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 21]
+van Kammen Expires 10 November 2024 [Page 21]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
* calculate the bounding box of the instanced scene, and
@@ -1229,9 +1229,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 22]
+van Kammen Expires 10 November 2024 [Page 22]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
14. XR audio/video integration
@@ -1285,9 +1285,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 23]
+van Kammen Expires 10 November 2024 [Page 23]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
15.1. including/excluding
@@ -1341,9 +1341,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 24]
+van Kammen Expires 10 November 2024 [Page 24]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
2. detect object id's & properties foo=1 and foo (reference regex=
@@ -1397,9 +1397,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 25]
+van Kammen Expires 10 November 2024 [Page 25]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
| The XR Fragments does this by collapsing space into a *Word Graph*
@@ -1453,9 +1453,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 26]
+van Kammen Expires 10 November 2024 [Page 26]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
http://y.io/z.fbx | Derived XRWG (expressed as BibTex)
@@ -1509,9 +1509,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 27]
+van Kammen Expires 10 November 2024 [Page 27]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
As seen above, the XRWG can expand bibs
@@ -1565,9 +1565,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 28]
+van Kammen Expires 10 November 2024 [Page 28]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
12. Default font (unless specified otherwise) is a modern monospace
@@ -1621,9 +1621,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 29]
+van Kammen Expires 10 November 2024 [Page 29]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
* lines beginning with @ will not be rendered verbatim by default
@@ -1677,9 +1677,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 30]
+van Kammen Expires 10 November 2024 [Page 30]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
+--------------------------------------------------------------+ +------------------------+
@@ -1733,9 +1733,9 @@ xrtext = {
-van Kammen Expires 27 October 2024 [Page 31]
+van Kammen Expires 10 November 2024 [Page 31]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
// bibtex: ↓@ ↓ ↓property ↓end
@@ -1789,9 +1789,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 32]
+van Kammen Expires 10 November 2024 [Page 32]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
str = `
@@ -1845,9 +1845,9 @@ console.log( xrtext.encode(text,tags) ) // multiplex text & bibtex back to
-van Kammen Expires 27 October 2024 [Page 33]
+van Kammen Expires 10 November 2024 [Page 33]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
2. mirroring files on another protocol using (HTTP) errorcode tags
@@ -1901,9 +1901,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 34]
+van Kammen Expires 10 November 2024 [Page 34]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
* href: university.edu/projects.gltf#math&-theme math
@@ -1957,9 +1957,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 35]
+van Kammen Expires 10 November 2024 [Page 35]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
* BibTex (https://bibtex.eu/fields) when known bibtex-keys exist
@@ -2013,9 +2013,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 36]
+van Kammen Expires 10 November 2024 [Page 36]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
22. Accessibility interface
@@ -2069,9 +2069,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 37]
+van Kammen Expires 10 November 2024 [Page 37]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
(javascript) which can change URN too.
@@ -2125,9 +2125,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 38]
+van Kammen Expires 10 November 2024 [Page 38]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
* visual-meta.info (https://visual-meta.info)
@@ -2181,9 +2181,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 39]
+van Kammen Expires 10 November 2024 [Page 39]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
| hashtags | time |
@@ -2237,9 +2237,9 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 40]
+van Kammen Expires 10 November 2024 [Page 40]
-Internet-Draft XR Fragments April 2024
+Internet-Draft XR Fragments May 2024
+-----------------+---------------------------------------------+
@@ -2293,4 +2293,4 @@ Internet-Draft XR Fragments April 2024
-van Kammen Expires 27 October 2024 [Page 41]
+van Kammen Expires 10 November 2024 [Page 41]
diff --git a/doc/RFC_XR_Fragments.xml b/doc/RFC_XR_Fragments.xml
index c3fb0c3..e41a3a1 100644
--- a/doc/RFC_XR_Fragments.xml
+++ b/doc/RFC_XR_Fragments.xml
@@ -612,7 +612,11 @@ For example, to render a portal with a preview-version of the scene, create an 3
set the position of the camera accordingly to the vector3 values of #pos
rot sets the rotation of the camera (only for non-VR/AR headsets)
mediafragment t in the top-URL sets the playbackspeed and animation-range of the global scene animation
-after scene load: in case an href does not mention any pos-coordinate, pos=0,0,0 will be assumed
+before scene load: the scene is cleared
+after scene load: in case the scene (rootnode) contains an # default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)
+after scene load: in case the scene (rootnode) contains an # default view with a fragment value: execute positional fragment via the hashbus + update top-level URL
+in case of no default # view on the scene (rootnode), default player(rig) position 0,0,0 is assumed.
+in case a href does not mention any pos-coordinate, the current position will be assumed
Here's an ascii representation of a 3D scene-graph which contains 3D objects ◻ and their metadata:
@@ -651,7 +655,7 @@ In case of buttonA the end-user will be teleported to another location
Embedding XR content using src
src is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.
-It instances content (in objects) in the current scene/asset.
+It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.
diff --git a/doc/RFC_XR_Macros.txt b/doc/RFC_XR_Macros.txt
index 713dd45..dceb5da 100644
--- a/doc/RFC_XR_Macros.txt
+++ b/doc/RFC_XR_Macros.txt
@@ -3,7 +3,7 @@
Internet Engineering Task Force L.R. van Kammen
-Internet-Draft 25 April 2024
+Internet-Draft 9 May 2024
Intended status: Informational
@@ -38,7 +38,7 @@ Status of This Memo
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
- This Internet-Draft will expire on 27 October 2024.
+ This Internet-Draft will expire on 10 November 2024.
Copyright Notice
@@ -53,9 +53,9 @@ Copyright Notice
-van Kammen Expires 27 October 2024 [Page 1]
+van Kammen Expires 10 November 2024 [Page 1]
-Internet-Draft XR Macros April 2024
+Internet-Draft XR Macros May 2024
extracted from this document must include Revised BSD License text as
@@ -109,9 +109,9 @@ Table of Contents
-van Kammen Expires 27 October 2024 [Page 2]
+van Kammen Expires 10 November 2024 [Page 2]
-Internet-Draft XR Macros April 2024
+Internet-Draft XR Macros May 2024
3. Metadata-values can contain the | symbol to 🎲 roundrobin variable
@@ -165,9 +165,9 @@ Internet-Draft XR Macros April 2024
-van Kammen Expires 27 October 2024 [Page 3]
+van Kammen Expires 10 November 2024 [Page 3]
-Internet-Draft XR Macros April 2024
+Internet-Draft XR Macros May 2024
+=========+======+===================+=================+=============+
@@ -221,9 +221,9 @@ Internet-Draft XR Macros April 2024
-van Kammen Expires 27 October 2024 [Page 4]
+van Kammen Expires 10 November 2024 [Page 4]
-Internet-Draft XR Macros April 2024
+Internet-Draft XR Macros May 2024
Table 3
@@ -277,9 +277,9 @@ Internet-Draft XR Macros April 2024
-van Kammen Expires 27 October 2024 [Page 5]
+van Kammen Expires 10 November 2024 [Page 5]
-Internet-Draft XR Macros April 2024
+Internet-Draft XR Macros May 2024
4.5. Usecase: present context menu with options
@@ -333,9 +333,9 @@ click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
-van Kammen Expires 27 October 2024 [Page 6]
+van Kammen Expires 10 November 2024 [Page 6]
-Internet-Draft XR Macros April 2024
+Internet-Draft XR Macros May 2024
| Note that only macro's can trigger roundrobin values or
@@ -389,4 +389,4 @@ Internet-Draft XR Macros April 2024
-van Kammen Expires 27 October 2024 [Page 7]
+van Kammen Expires 10 November 2024 [Page 7]
diff --git a/example/godot/index.glb b/example/godot/index.glb
deleted file mode 120000
index 0675c21..0000000
--- a/example/godot/index.glb
+++ /dev/null
@@ -1 +0,0 @@
-../assets/index.glb
\ No newline at end of file
diff --git a/example/godot/main.gd b/example/godot/main.gd
index d1cbff4..aa97513 100644
--- a/example/godot/main.gd
+++ b/example/godot/main.gd
@@ -1,14 +1,32 @@
extends Node3D
var xr_interface: XRInterface
+var xrf
+var scene
+var player:CharacterBody3D
func _ready():
- # Import MyClass
- const XRF = preload("res://xrfragment.gd")
- var xrf = XRF.new()
+ xrf = preload("res://xrfragment.gd").new()
add_child(xrf)
- print( xrf.parseURL("https://foo.com/?foo#flop=bar&fap=fop") )
- print( xrf.parseURL("https://foo.com/flop.html?foo#flop=bar&fap=fop") )
- xrf.load("https://xrfragment.org/index.glb")
-
+ xrf.to("https://xrfragment.org/index.glb", _onXRF )
+ player = find_child("PlayerBody")
+ player.enabled = false # optional: turn off gravity
+func _onXRF(event:String,data ):
+ if event == "scene_loaded":
+ scene = data
+ setPredefinedSceneView()
+
+func _input(event):
+ if event is InputEventMouseMotion:
+ var mouse_sens = 0.2
+ var cam = find_child("XRCamera3D")
+ cam.rotate_y(deg_to_rad(-event.relative.x*mouse_sens))
+
+# info: https://xrfragment.org/#predefined_view
+# spec: 6-8 @ https://xrfragment.org/doc/RFC_XR_Fragments.html#navigating-3d
+func setPredefinedSceneView():
+ var XRF = scene.get_meta("XRF")
+ if XRF && XRF.has("#") && XRF["#"]["fragment"]["pos"]:
+ player.teleport( xrf.posToTransform3D(XRF["#"]["fragment"]["pos"]) )
+
diff --git a/example/godot/project.godot b/example/godot/project.godot
index b1195af..ad910ca 100644
--- a/example/godot/project.godot
+++ b/example/godot/project.godot
@@ -21,7 +21,7 @@ XRToolsUserSettings="*res://addons/godot-xr-tools/user_settings/user_settings.gd
[editor_plugins]
-enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg")
+enabled=PackedStringArray()
[rendering]
diff --git a/example/godot/xrfragment.gd b/example/godot/xrfragment.gd
deleted file mode 120000
index cb55d13..0000000
--- a/example/godot/xrfragment.gd
+++ /dev/null
@@ -1 +0,0 @@
-../../src/xrfragment/xrfragment.gd
\ No newline at end of file
diff --git a/example/godot/xrfragment.gd b/example/godot/xrfragment.gd
new file mode 100644
index 0000000..f4ed7e7
--- /dev/null
+++ b/example/godot/xrfragment.gd
@@ -0,0 +1,233 @@
+# https://xrfragment.org"
+# SPDX-License-Identifier: MPL-2.0"
+
+extends Node
+
+class_name XRF
+
+var scene
+var isModelLoading = false
+var metadata
+var callback: Callable;
+var Type = {
+ "isColor": "^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$",
+ "isInt": "^[0-9]+$",
+ "isFloat": "^[0-9]+%.[0-9]+$",
+ "isVector": "([,]+|%w)"
+}
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ pass # Replace with function body.
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ pass
+
+####################################################################################################
+# URI Related functions
+####################################################################################################
+
+func parseURL(url: String) -> Dictionary:
+ var URI = {}
+
+ # Split URL by '://' to get protocol and the rest of the URL
+ var parts = url.split("://")
+ if parts.size() > 1:
+ URI["protocol"] = parts[0]
+ url = parts[1]
+ else:
+ URI["protocol"] = "http" # Default to http if protocol is missing
+
+ # Split URL by '/' to separate domain, path, and file
+ parts = url.split("/")
+ URI["domain"] = parts[0]
+ if parts.size() > 1:
+ var path_and_file = parts[1]
+ var path_and_file_parts = path_and_file.split("/")
+ if path_and_file_parts.size() > 1:
+ URI["path"] = path_and_file_parts
+ var file = path_and_file_parts.pop_back()
+ URI["path"] = path_and_file_parts.join("/")
+ else:
+ URI["path"] = path_and_file
+
+ # Check if there's a query string
+ if url.find("?") != -1:
+ parts = url.split("?")
+ URI["path"] = parts[0]
+ var args = parts[1]
+ if args.find("#"):
+ args = args.split("#")[0]
+ URI["query"] = parseArgs(args)
+ else:
+ URI["query"] = {}
+
+ # Check if there's a fragment
+ if url.find("#") != -1:
+ parts = url.split("#")
+ URI["fragment"] = parseArgs(parts[1])
+ else:
+ URI["fragment"] = {}
+
+ return URI
+
+func parseArgs(fragment: String) -> Dictionary:
+ var ARG = {}
+
+ # Split fragment by '&' to separate items
+ var items = fragment.split("&")
+
+ for item in items:
+ # Split item by '=' to separate key and value
+ var key_value = item.split("=")
+ if key_value.size() > 1:
+ ARG[key_value[0]] = guess_type(key_value[1])
+ else:
+ ARG[key_value[0]] = ""
+
+ return ARG
+
+func guess_type(str: String) -> Dictionary:
+ var v = {
+ "string": str,
+ "x": null,
+ "y": null,
+ "color":null,
+ "float": null,
+ "int": null
+ }
+ var parts = str.split(",")
+ if parts.size() > 1:
+ v.x = parts[0].to_int()
+ v.y = parts[1].to_int()
+ if parts.size() > 2:
+ v.z = parts[2].to_int()
+ if str.match(Type.isColor):
+ v.color = str
+ if str.match(Type.isFloat):
+ v.float = str.to_float()
+ if str.match(Type.isInt):
+ v.int = str.to_int()
+ return v
+
+####################################################################################################
+# Model Related functions
+####################################################################################################
+
+# Download model by HTTP and run `downloadModelSuccess` if OK
+func to(url, f:Callable ):
+ print("loading "+url)
+ callback = f
+ var http_request = HTTPRequest.new()
+ add_child(http_request)
+ http_request.request_completed.connect(downloadModelSuccess)
+
+ var error = http_request.request(url)
+ if error != OK:
+ push_error("An error occurred in the HTTP request.")
+
+func downloadModelSuccess(result, response_code, headers, body):
+ # TODO: here different parsing functions should be called
+ # based on the filetype (glb,gltf,ade,obj e.g.)
+ loadModelFromBufferByGLTFDocument(body)
+ _parseXRFMetadata(scene)
+ traverse( scene, _parseXRFMetadata )
+ # setup actions & embeds
+ traverse( scene, init_href )
+ traverse( scene, init_src )
+ callback.call("scene_loaded", scene)
+
+func loadModelFromBufferByGLTFDocument(body):
+ print("loadModelFromBuffer")
+ var doc = GLTFDocument.new()
+ var state = GLTFState.new()
+ #state.set_handle_binary_image(GLTFState.HANDLE_BINARY_EMBED_AS_BASISU) # Fixed in new Godot version (4.3 as I see) https://github.com/godotengine/godot/blob/17e7f85c06366b427e5068c5b3e2940e27ff5f1d/scene/resources/portable_compressed_texture.cpp#L116
+ var error = doc.append_from_buffer(body, "", state)
+ if error == OK:
+ scene = doc.generate_scene(state)
+ metadata = _parseMetadata(state,scene)
+ add_child(scene)
+ print("model added")
+ else:
+ print("Couldn't load glTF scene (error code: %s). Are you connected to internet?" % error_string(error))
+
+func _parseXRFMetadata(node:Node):
+ if node.has_meta("extras"):
+ var extras = node.get_meta("extras")
+ var XRF = {}
+ for i in extras:
+ if typeof(extras[i]) == TYPE_STRING:
+ XRF[ i ] = parseURL( extras[i] )
+ node.set_meta("XRF", XRF)
+
+func traverse(node, f:Callable ):
+ for N in node.get_children():
+ if N.get_child_count() > 0:
+ f.call(N)
+ self.traverse(N,f)
+ else:
+ f.call(N)
+
+func _parseMetadata(state: GLTFState, scene: Node) -> Error:
+ #var meta = new Dictionary()
+
+ # Add metadata to materials
+ var materials_json : Array = state.json.get("materials", [])
+ var materials : Array[Material] = state.get_materials()
+ for i in materials_json.size():
+ if materials_json[i].has("extras"):
+ materials[i].set_meta("extras", materials_json[i]["extras"])
+
+ # Add metadata to ImporterMeshes
+ var meshes_json : Array = state.json.get("meshes", [])
+ var meshes : Array[GLTFMesh] = state.get_meshes()
+ for i in meshes_json.size():
+ if meshes_json[i].has("extras"):
+ meshes[i].mesh.set_meta("extras", meshes_json[i]["extras"])
+
+ # Add metadata to scene
+ var scenes_json : Array = state.json.get("scenes", [])
+ if scenes_json[0].has("extras"):
+ scene.set_meta("extras", scenes_json[0]["extras"])
+
+ # Add metadata to nodes
+ var nodes_json : Array = state.json.get("nodes", [])
+ for i in nodes_json.size():
+ if nodes_json[i].has("extras"):
+ var name = nodes_json[i]["name"].replace(".","_")
+ var node = scene.find_child(name) #state.get_scene_node(i)
+ if node:
+ node.set_meta( "extras", nodes_json[i]["extras"] )
+ else:
+ print(name+" could not be found")
+ return OK
+
+func posToTransform3D(v:Dictionary):
+ var pos = Vector3()
+ if !v.x:
+ var node:Node3D = scene.find_child(v.string)
+ pos.x = node.position.x
+ pos.y = node.position.y
+ pos.z = node.position.z
+ else:
+ pos.x = v.x
+ pos.y = v.y
+ pos.z = v.z
+ var transform = Transform3D()
+ transform.origin = pos
+ return transform
+
+
+####################################################################################################
+# The XR Fragments
+# spec: https://xrfragment.org/doc/RFC_XR_Fragments.html
+####################################################################################################
+
+func init_href(node:Node):
+ null
+
+func init_src(node:Node):
+ null
+
diff --git a/make b/make
index 36ea4d1..9a3e47c 100755
--- a/make
+++ b/make
@@ -27,9 +27,10 @@ install(){
}
godot(){
- test -d src/xrfragment/godot/addons || mkdir src/xrfragment/godot/addons
- test -d src/xrfragment/godot/addons/godot-xr-tools || {
- cd src/xrfragment/godot
+ DIR_GODOT=example/godot
+ test -d $DIR_GODOT/addons || mkdir -p $DIR_GODOT/addons
+ test -d $DIR_GODOT/addons/godot-xr-tools || {
+ cd $DIR_GODOT
wget "https://github.com/GodotVR/godot-xr-tools/releases/download/4.3.1/godot-xr-tools.zip"
unzip godot-xr-tools.zip
mv godot-xr-tools/addons/godot-xr-tools addons/.
diff --git a/src/xrfragment/xrfragment.gd b/src/xrfragment/xrfragment.gd
deleted file mode 100644
index 5bbe66c..0000000
--- a/src/xrfragment/xrfragment.gd
+++ /dev/null
@@ -1,221 +0,0 @@
-extends Node
-
-class_name XRF
-
-var rootScene
-var isModelLoading = false
-
-# Called when the node enters the scene tree for the first time.
-func _ready():
- pass # Replace with function body.
-
-
-# Called every frame. 'delta' is the elapsed time since the previous frame.
-func _process(delta):
- pass
-
-####################################################################################################
-# URI Related functions
-####################################################################################################
-
-func parseURL(url: String) -> Dictionary:
- var URI = {}
-
- # Split URL by '://' to get protocol and the rest of the URL
- var parts = url.split("://")
- if parts.size() > 1:
- URI["protocol"] = parts[0]
- url = parts[1]
- else:
- URI["protocol"] = "http" # Default to http if protocol is missing
-
- # Split URL by '/' to separate domain, path, and file
- parts = url.split("/")
- URI["domain"] = parts[0]
- if parts.size() > 1:
- var path_and_file = parts[1]
- var path_and_file_parts = path_and_file.split("/")
- if path_and_file_parts.size() > 1:
- URI["path"] = path_and_file_parts
- var file = path_and_file_parts.pop_back()
- URI["path"] = path_and_file_parts.join("/")
- else:
- URI["path"] = path_and_file
-
- # Check if there's a query string
- if url.find("?") != -1:
- parts = url.split("?")
- URI["path"] = parts[0]
- var args = parts[1]
- if args.find("#"):
- args = args.split("#")[0]
- URI["query"] = parseArgs(args)
- else:
- URI["query"] = {}
-
- # Check if there's a fragment
- if url.find("#") != -1:
- parts = url.split("#")
- URI["fragment"] = parseArgs(parts[1])
- else:
- URI["fragment"] = {}
-
- return URI
-
-func parseArgs(fragment: String) -> Dictionary:
- var ARG = {}
-
- # Split fragment by '&' to separate items
- var items = fragment.split("&")
-
- for item in items:
- # Split item by '=' to separate key and value
- var key_value = item.split("=")
- if key_value.size() > 1:
- ARG[key_value[0]] = key_value[1]
- else:
- ARG[key_value[0]] = ""
-
- return ARG
-
-####################################################################################################
-# Model Related functions
-####################################################################################################
-
-# Download model by HTTP and run `downloadModelSuccess` if OK
-func load(url):
- print("loading "+url)
- var http_request = HTTPRequest.new()
- add_child(http_request)
- http_request.request_completed.connect(downloadModelSuccess)
-
- var error = http_request.request(url)
- if error != OK:
- push_error("An error occurred in the HTTP request.")
-
-
-
-func placeModelToEditorScene(model):
- add_child(model)
- #model.translate(Vector3(0.0, 0.0, -1.0))
- print("model added")
-
-func downloadModelSuccess(result, response_code, headers, body):
- # TODO: here different parsing functions should be called
- # based on the filetype (glb,gltf,ade,obj e.g.)
- loadModelFromBufferByGLTFDocument(body)
-
-func loadModelFromBufferByGLTFDocument(body):
- print("loadModelFromBuffer")
- var doc = GLTFDocument.new()
- var state = GLTFState.new()
- #state.set_handle_binary_image(GLTFState.HANDLE_BINARY_EMBED_AS_BASISU) # Fixed in new Godot version (4.3 as I see) https://github.com/godotengine/godot/blob/17e7f85c06366b427e5068c5b3e2940e27ff5f1d/scene/resources/portable_compressed_texture.cpp#L116
-
- var error = doc.append_from_buffer(body, "", state)
- if error == OK:
- #var glb_importer_model: GLTFMesh = state.get_meshes()[0]
- #var glb_importer_model_mesh: ImporterMesh = glb_importer_model.get_mesh()
- var scene = doc.generate_scene(state)
- scene.set_meta("json",state.json)
- #var ok:Error = _parseExtras(state)
- traverse(scene, evalNode)
- self.placeModelToEditorScene(scene)
-
- else:
- print("Couldn't load glTF scene (error code: %s)." % error_string(error))
-
-func evalNode(node:Node):
- print(node.name)
- #if node.has_meta("extras"):
- # print(node.get_meta("extras",""))
-
-func traverse(node, f:Callable ):
- for N in node.get_children():
- if N.get_child_count() > 0:
- f.call(N)
- self.traverse(N,f)
- else:
- f.call(N)
-
-func _parseExtras(state: GLTFState) -> Error:
- print( state.json.keys() )
-
- # Add metadata to materials
- var materials_json : Array = state.json.get("materials", [])
- var materials : Array[Material] = state.get_materials()
- for i in materials_json.size():
- if materials_json[i].has("extras"):
- materials[i].set_meta("extras", materials_json[i]["extras"])
-
- # Add metadata to ImporterMeshes
- var meshes_json : Array = state.json.get("meshes", [])
- var meshes : Array[GLTFMesh] = state.get_meshes()
- for i in meshes_json.size():
- if meshes_json[i].has("extras"):
- meshes[i].mesh.set_meta("extras", meshes_json[i]["extras"])
-
- # Add metadata to nodes
- var nodes_json : Array = state.json.get("nodes", [])
- for i in nodes_json.size():
- var node = state.get_scene_node(i)
- if !node:
- continue
- if nodes_json[i].has("extras"):
- # Handle special case
- if node is ImporterMeshInstance3D:
- # ImporterMeshInstance3D nodes will be converted later to either
- # MeshInstance3D or StaticBody3D and metadata will be lost
- # A sibling is created preserving the metadata. It can be later
- # merged back in using a EditorScenePostImport script
- var metadata_node = Node.new()
- metadata_node.set_meta("extras", nodes_json[i]["extras"])
-
- # Meshes are also ImporterMeshes that will be later converted either
- # to ArrayMesh or some form of collision shape.
- # We'll save it as another metadata item. If the mesh is reused we'll
- # have duplicated info but at least it will always be accurate
- if node.mesh and node.mesh.has_meta("extras"):
- metadata_node.set_meta("mesh_extras", node.mesh.get_meta("extras"))
-
- # Well add it as sibling so metadata node always follows the actual metadata owner
- node.add_sibling(metadata_node)
- # Make sure owner is set otherwise it won't get serialized to disk
- metadata_node.owner = node.owner
- # Add a suffix to the generated name so it's easy to find
- metadata_node.name += "_meta"
- # In all other cases just set_meta
- else:
- node.set_meta("extras", nodes_json[i]["extras"])
-
- ## now we merge extras to the scene
- #var verbose_output = []
- #var nodes : Array[Node] = scene.find_children("*" + "_meta", "Node")
- #verbose_output.append_array(["Metadata nodes:", nodes])
- #for node in nodes:
- #var extras = node.get_meta("extras")
- #if !extras:
- #verbose_output.append("Node %s contains no 'extras' metadata" % node)
- #continue
- #var parent = node.get_parent()
- #if !parent:
- #verbose_output.append("Node %s has no parent" % node)
- #continue
- #var idx_original = node.get_index() - 1
- #if idx_original < 0 or parent.get_child_count() <= idx_original:
- #verbose_output.append("Original node index %s is out of bounds. Parent child count: %s" % [idx_original, parent.get_child_count()])
- #continue
- #var original = node.get_parent().get_child(idx_original)
- #if original:
- #verbose_output.append("Setting extras metadata for %s" % original)
- #original.set_meta("extras", extras)
- #if node.has_meta("mesh_extras"):
- #if original is MeshInstance3D and original.mesh:
- #verbose_output.append("Setting extras metadata for mesh %s" % original.mesh)
- #original.mesh.set_meta("extras", node.get_meta("mesh_extras"))
- #else:
- #verbose_output.append("Metadata node %s has 'mesh_extras' but original %s has no mesh, preserving as 'mesh_extras'" % [node, original])
- #original.set_meta("mesh_extras", node.get_meta("mesh_extras"))
- #else:
- #verbose_output.append("Original node not found for %s" % node)
- #node.queue_free()
- return OK
diff --git a/src/xrfragment/xrfragment.gd b/src/xrfragment/xrfragment.gd
new file mode 120000
index 0000000..2f8b4cd
--- /dev/null
+++ b/src/xrfragment/xrfragment.gd
@@ -0,0 +1 @@
+../../example/godot/xrfragment.gd
\ No newline at end of file