feat/escaperoom: work in progress [might break]
This commit is contained in:
parent
485c3d4cfd
commit
6fc94b66c4
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
* v0.5.1 generated at Wed Jun 26 11:16:30 AM UTC 2024
|
||||
* v0.5.1 generated at Tue Jul 9 04:28:50 PM UTC 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
// Generated by Haxe 4.3.3
|
||||
var $hx_exports = typeof exports != "undefined" ? exports : typeof window != "undefined" ? window : typeof self != "undefined" ? self : this;
|
||||
(function ($global) { "use strict";
|
||||
$hx_exports["xrfragment"] = $hx_exports["xrfragment"] || {};
|
||||
|
@ -158,24 +159,11 @@ Std.string = function(s) {
|
|||
return js_Boot.__string_rec(s,"");
|
||||
};
|
||||
Std.parseInt = function(x) {
|
||||
if(x != null) {
|
||||
var _g = 0;
|
||||
var _g1 = x.length;
|
||||
while(_g < _g1) {
|
||||
var i = _g++;
|
||||
var c = x.charCodeAt(i);
|
||||
if(c <= 8 || c >= 14 && c != 32 && c != 45) {
|
||||
var nc = x.charCodeAt(i + 1);
|
||||
var v = parseInt(x,nc == 120 || nc == 88 ? 16 : 10);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
var v = parseInt(x);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return v;
|
||||
};
|
||||
var StringBuf = function() {
|
||||
this.b = "";
|
||||
|
@ -471,10 +459,10 @@ haxe_Template.prototype = {
|
|||
var _g_offset = 0;
|
||||
var _g_s = data;
|
||||
while(_g_offset < _g_s.length) {
|
||||
var _g1_key = _g_offset;
|
||||
var _g1_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g1_key;
|
||||
var c = _g1_value;
|
||||
var _g_key = _g_offset;
|
||||
var _g_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g_key;
|
||||
var c = _g_value;
|
||||
if(c != 32) {
|
||||
l.add({ p : HxOverrides.substr(data,i,null), s : true});
|
||||
break;
|
||||
|
@ -1384,6 +1372,8 @@ xrfragment_URI.toAbsolute = function(url,newUrl) {
|
|||
}
|
||||
if(newURI.directory != null) {
|
||||
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||
var stripRelative_r = new RegExp("\\./.*","".split("u").join(""));
|
||||
directory = directory.replace(stripRelative_r,"");
|
||||
directory += newURI.directory;
|
||||
} else {
|
||||
directory = newURI.directory;
|
||||
|
@ -1668,6 +1658,7 @@ xrf.emit = function(eventName, data){
|
|||
console.groupCollapsed(label)
|
||||
console.info(data)
|
||||
console.groupEnd(label)
|
||||
if( eventName == 'reset' ) debugger
|
||||
if( xrf.debug > 2 ) debugger
|
||||
}
|
||||
return xrf.emit.promise(eventName,data)
|
||||
|
@ -1845,12 +1836,13 @@ pub.fragment = (k, opts ) => { // evaluate one fragment
|
|||
if( !opts.skipXRWG && isPVorMediaFrag ) pub.XRWG(k,opts)
|
||||
|
||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||
xrf.emit(k,opts)
|
||||
.then( () => {
|
||||
let func = xrf.frag[k] || function(){}
|
||||
if( typeof xrf[k] == 'function' ) xrf[k]( func, frag, opts)
|
||||
else func( frag, opts)
|
||||
})
|
||||
if( xrf.frag[k] ){
|
||||
xrf.emit(k,opts)
|
||||
.then( () => {
|
||||
let func = xrf.frag[k] || function(){}
|
||||
func( frag, opts)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub.XRWG = (word,opts) => {
|
||||
|
@ -2024,14 +2016,15 @@ xrf.hasNoMaterial = (mesh) => {
|
|||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||
}
|
||||
|
||||
xrf.navigator = {
|
||||
URI:{
|
||||
scheme: document.location.protocol.replace(/:$/,''),
|
||||
directory: document.location.pathname,
|
||||
host: document.location.hostname,
|
||||
port: document.location.port,
|
||||
file: 'index.glb'
|
||||
}
|
||||
URI: xrf.URI.parse(document.location.href)
|
||||
// scheme: document.location.protocol.replace(/:$/,''),
|
||||
// directory: document.location.pathname,
|
||||
// host: document.location.hostname,
|
||||
// port: document.location.port,
|
||||
// file: 'index.glb'
|
||||
// }
|
||||
}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
|
@ -2041,6 +2034,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
URI.hash = xrf.navigator.reactifyHash(URI.hash) // automatically reflect hash-changes to navigator.to(...)
|
||||
// decorate with extra state
|
||||
URI.fileChange = URI.file && URI.URN + URI.file != xrf.navigator.URI.URN + xrf.navigator.URI.file
|
||||
console.log( URI.URN + URI.file )
|
||||
console.log( xrf.navigator.URI.URN + xrf.navigator.URI.file )
|
||||
URI.external = URI.file && URI.URN != document.location.origin + document.location.pathname
|
||||
URI.hasPos = URI.hash.pos ? true : false
|
||||
URI.duplicatePos = URI.source == xrf.navigator.URI.source && URI.hasPos
|
||||
|
@ -2068,8 +2063,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
loader = loader || new Loader().setPath( URI.URN )
|
||||
}
|
||||
|
||||
|
||||
if( URI.duplicatePos || (!URI.fragment && !URI.file && !URI.fileExt) ){
|
||||
if( URI.duplicatePos || (!Object.values(URI.XRF).length && !URI.file && !URI.fileExt) ){
|
||||
return resolve(xrf.model) // nothing we can do here
|
||||
}
|
||||
if( xrf.model && !URI.fileChange && URI.hashChange && !URI.hasPos ){
|
||||
|
@ -2173,14 +2167,14 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
|||
xrf.navigator.updateHash = (hash,opts) => {
|
||||
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
||||
console.log(`URI: ${document.location.search.substr(1)}#${hash}`)
|
||||
xrf.navigator.updateHash.active = true // important to prevent recursion
|
||||
xrf.navigator.updateHash.active = false // important to prevent recursion
|
||||
document.location.hash = hash
|
||||
xrf.navigator.updateHash.active = false
|
||||
xrf.navigator.updateHash.active = true
|
||||
}
|
||||
|
||||
xrf.navigator.pushState = (file,hash) => {
|
||||
if( file == document.location.search.substr(1) ) return // page is in its default state
|
||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||
window.history.pushState({}, '', document.location.pathname + `?${xrf.navigator.URI.source.replace(/#.*/,'')}#${hash}` )
|
||||
xrf.emit('pushState', {file, hash} )
|
||||
}
|
||||
|
||||
|
@ -2243,7 +2237,8 @@ xrf.frag.href = function(v, opts){
|
|||
if( !mesh.material || !mesh.material.visible ) return // ignore invisible nodes
|
||||
|
||||
// update our values to the latest value (might be edited)
|
||||
xrf.Parser.parse( "href", mesh.userData.href, frag )
|
||||
let URI = xrf.URI.template( mesh.userData.href, xrf.URI.vars.__object )
|
||||
xrf.Parser.parse( "href", URI, frag )
|
||||
const v = frag.href
|
||||
|
||||
// bubble up!
|
||||
|
@ -2361,8 +2356,9 @@ xrf.addEventListener('audioInited', function(opts){
|
|||
*/
|
||||
// this is called by navigator.js rather than by a URL e.g.
|
||||
|
||||
xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
xrf.frag['#'] = xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
let {scene,model} = opts;
|
||||
if( !scene ) return
|
||||
let defaultFragment;
|
||||
scene.traverse( (n) => {
|
||||
if( n.userData && n.userData['#'] ){
|
||||
|
@ -2715,10 +2711,17 @@ xrf.frag.t.default = {
|
|||
xrf.addEventListener('parseModel', (opts) => {
|
||||
let {model} = opts
|
||||
let mixer = model.mixer = new xrf.THREE.AnimationMixer(model.scene)
|
||||
|
||||
mixer.model = model
|
||||
mixer.loop = {timeStart:0,timeStop:0,speed:1.0}
|
||||
mixer.i = xrf.mixers.length
|
||||
mixer.actions = []
|
||||
|
||||
// calculate total duration/frame based on longest animation
|
||||
mixer.duration = 0
|
||||
if( model.animations.length ){
|
||||
model.animations.map( (a) => mixer.duration = ( a.duration > mixer.duration ) ? a.duration : mixer.duration )
|
||||
}
|
||||
|
||||
model.animations.map( (anim) => {
|
||||
anim.optimize()
|
||||
|
@ -2739,7 +2742,7 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.updateLoop = (t) => {
|
||||
if( t ){
|
||||
mixer.loop.timeStart = t.x != undefined ? t.x : mixer.loop.timeStart
|
||||
mixer.loop.timeStop = t.y != undefined ? t.y : mixer.duration
|
||||
mixer.loop.timeStop = t.y != undefined ? t.y : mixer.loop.timeStop
|
||||
}
|
||||
mixer.actions.map( (action) => {
|
||||
if( mixer.loop.timeStart != undefined ){
|
||||
|
@ -2762,7 +2765,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.update = function(time){
|
||||
mixer.time = Math.abs(mixer.time)
|
||||
if( time == 0 ) return update.call(this,time)
|
||||
|
||||
// loop jump
|
||||
if( mixer.loop.timeStop > 0 && mixer.time > mixer.loop.timeStop ){
|
||||
if( mixer.loop.enabled ){
|
||||
|
@ -2774,12 +2776,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.update.patched = true
|
||||
}
|
||||
|
||||
// calculate total duration/frame based on longest animation
|
||||
mixer.duration = 0
|
||||
if( model.animations.length ){
|
||||
model.animations.map( (a) => mixer.duration = ( a.duration > mixer.duration ) ? a.duration : mixer.duration )
|
||||
}
|
||||
|
||||
xrf.mixers.push(mixer)
|
||||
})
|
||||
|
||||
|
@ -3401,8 +3397,8 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
|
||||
if( n.userData ){
|
||||
for( let i in n.userData ){
|
||||
if( i[0] == '#' || i.match(/^(href|tag)$/) ) continue // ignore XR Fragment aliases
|
||||
if( i == 'src' ){
|
||||
//if( i[0] == '#' || i.match(/^(href|tag)$/) ) continue // ignore XR Fragment aliases
|
||||
if( i.match(/^(src|href|tag)/) ){
|
||||
// lets declare empty variables found in src-values ('https://foo.com/video.mp4#{somevar}') e.g.
|
||||
if( n.userData[i].match(variables) ){
|
||||
let vars = [].concat( n.userData[i].match(variables) )
|
||||
|
@ -3431,10 +3427,11 @@ xrf.addEventListener('dynamicKeyValue', (opts) => {
|
|||
if( !xrf.URI.vars[ v.string ] ) return console.error(`'${v.string}' metadata-key not found in scene`)
|
||||
//if( xrf.URI.vars[ id ] && !match.length ) return console.error(`'${id}' object/tag/metadata-key not found in scene`)
|
||||
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}]='${v.string}'`)
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}] => '${v.string}'`)
|
||||
|
||||
if( xrf.URI.vars[id] ){
|
||||
xrf.URI.vars[ id ] = xrf.URI.vars[ v.string ] // update var
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}] => '${xrf.URI.vars[ v.string ]()}'`)
|
||||
xrf.scene.traverse( (n) => {
|
||||
// re-expand src-values which use the updated URI Template var
|
||||
if( n.userData && n.userData.src && n.userData.srcTemplate && n.userData.srcTemplate.match(`{${id}}`) ){
|
||||
|
@ -4178,6 +4175,14 @@ window.AFRAME.registerComponent('xrf', {
|
|||
if( VRbutton ) VRbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#VR' ) )
|
||||
})
|
||||
|
||||
// not part of the spec, but convenient to only show AR button when negative VR-tag was defined in default fragment ('#' in rootscene file)
|
||||
xrf.addEventListener('#', function(e){
|
||||
if( e.frag['#'].string.match(/-VR/) ){
|
||||
aScene.removeAttribute('xr-mode-ui')
|
||||
aScene.setAttribute('xr-mode-ui',"XRMode: ar")
|
||||
}
|
||||
})
|
||||
|
||||
let repositionUser = (scale) => () => {
|
||||
// sometimes AFRAME resets the user position to 0,0,0 when entering VR (not sure why)
|
||||
setTimeout( () => {
|
||||
|
@ -4190,6 +4195,7 @@ window.AFRAME.registerComponent('xrf', {
|
|||
aScene.addEventListener('enter-ar', repositionUser(2) )
|
||||
|
||||
xrf.addEventListener('navigateLoaded', (opts) => {
|
||||
|
||||
setTimeout( () => AFRAME.fade.out(),500)
|
||||
let isLocal = opts.url.match(/^#/)
|
||||
if( isLocal ) return
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Generated by Haxe 4.3.3
|
||||
var $hx_exports = typeof exports != "undefined" ? exports : typeof window != "undefined" ? window : typeof self != "undefined" ? self : this;
|
||||
(function ($global) { "use strict";
|
||||
$hx_exports["xrfragment"] = $hx_exports["xrfragment"] || {};
|
||||
|
@ -153,24 +154,11 @@ Std.string = function(s) {
|
|||
return js_Boot.__string_rec(s,"");
|
||||
};
|
||||
Std.parseInt = function(x) {
|
||||
if(x != null) {
|
||||
var _g = 0;
|
||||
var _g1 = x.length;
|
||||
while(_g < _g1) {
|
||||
var i = _g++;
|
||||
var c = x.charCodeAt(i);
|
||||
if(c <= 8 || c >= 14 && c != 32 && c != 45) {
|
||||
var nc = x.charCodeAt(i + 1);
|
||||
var v = parseInt(x,nc == 120 || nc == 88 ? 16 : 10);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
var v = parseInt(x);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return v;
|
||||
};
|
||||
var StringBuf = function() {
|
||||
this.b = "";
|
||||
|
@ -466,10 +454,10 @@ haxe_Template.prototype = {
|
|||
var _g_offset = 0;
|
||||
var _g_s = data;
|
||||
while(_g_offset < _g_s.length) {
|
||||
var _g1_key = _g_offset;
|
||||
var _g1_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g1_key;
|
||||
var c = _g1_value;
|
||||
var _g_key = _g_offset;
|
||||
var _g_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g_key;
|
||||
var c = _g_value;
|
||||
if(c != 32) {
|
||||
l.add({ p : HxOverrides.substr(data,i,null), s : true});
|
||||
break;
|
||||
|
@ -1379,6 +1367,8 @@ xrfragment_URI.toAbsolute = function(url,newUrl) {
|
|||
}
|
||||
if(newURI.directory != null) {
|
||||
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||
var stripRelative_r = new RegExp("\\./.*","".split("u").join(""));
|
||||
directory = directory.replace(stripRelative_r,"");
|
||||
directory += newURI.directory;
|
||||
} else {
|
||||
directory = newURI.directory;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,5 @@
|
|||
# Generated by Haxe 4.3.3
|
||||
# coding: utf-8
|
||||
import sys
|
||||
|
||||
import math as python_lib_Math
|
||||
|
@ -305,67 +307,48 @@ class Std:
|
|||
def parseInt(x):
|
||||
if (x is None):
|
||||
return None
|
||||
try:
|
||||
return int(x)
|
||||
except BaseException as _g:
|
||||
None
|
||||
base = 10
|
||||
_hx_len = len(x)
|
||||
foundCount = 0
|
||||
sign = 0
|
||||
firstDigitIndex = 0
|
||||
lastDigitIndex = -1
|
||||
previous = 0
|
||||
_g = 0
|
||||
_g1 = _hx_len
|
||||
while (_g < _g1):
|
||||
i = _g
|
||||
_g = (_g + 1)
|
||||
c = (-1 if ((i >= len(x))) else ord(x[i]))
|
||||
if (((c > 8) and ((c < 14))) or ((c == 32))):
|
||||
if (foundCount > 0):
|
||||
return None
|
||||
continue
|
||||
else:
|
||||
c1 = c
|
||||
if (c1 == 43):
|
||||
if (foundCount == 0):
|
||||
sign = 1
|
||||
elif (not (((48 <= c) and ((c <= 57))))):
|
||||
if (not (((base == 16) and ((((97 <= c) and ((c <= 122))) or (((65 <= c) and ((c <= 90))))))))):
|
||||
break
|
||||
elif (c1 == 45):
|
||||
if (foundCount == 0):
|
||||
sign = -1
|
||||
elif (not (((48 <= c) and ((c <= 57))))):
|
||||
if (not (((base == 16) and ((((97 <= c) and ((c <= 122))) or (((65 <= c) and ((c <= 90))))))))):
|
||||
break
|
||||
elif (c1 == 48):
|
||||
if (not (((foundCount == 0) or (((foundCount == 1) and ((sign != 0))))))):
|
||||
if (not (((48 <= c) and ((c <= 57))))):
|
||||
if (not (((base == 16) and ((((97 <= c) and ((c <= 122))) or (((65 <= c) and ((c <= 90))))))))):
|
||||
break
|
||||
elif ((c1 == 120) or ((c1 == 88))):
|
||||
if ((previous == 48) and ((((foundCount == 1) and ((sign == 0))) or (((foundCount == 2) and ((sign != 0))))))):
|
||||
base = 16
|
||||
elif (not (((48 <= c) and ((c <= 57))))):
|
||||
if (not (((base == 16) and ((((97 <= c) and ((c <= 122))) or (((65 <= c) and ((c <= 90))))))))):
|
||||
break
|
||||
elif (not (((48 <= c) and ((c <= 57))))):
|
||||
if (not (((base == 16) and ((((97 <= c) and ((c <= 122))) or (((65 <= c) and ((c <= 90))))))))):
|
||||
break
|
||||
if (((foundCount == 0) and ((sign == 0))) or (((foundCount == 1) and ((sign != 0))))):
|
||||
firstDigitIndex = i
|
||||
foundCount = (foundCount + 1)
|
||||
lastDigitIndex = i
|
||||
previous = c
|
||||
if (firstDigitIndex <= lastDigitIndex):
|
||||
digits = HxString.substring(x,firstDigitIndex,(lastDigitIndex + 1))
|
||||
try:
|
||||
return (((-1 if ((sign == -1)) else 1)) * int(digits,base))
|
||||
except BaseException as _g:
|
||||
return None
|
||||
_hx_len = len(x)
|
||||
index = 0
|
||||
while (index < _hx_len):
|
||||
if (not (x[index] in " \n\r\t\x0B\x0C")):
|
||||
break
|
||||
index = (index + 1)
|
||||
isNegative = None
|
||||
if (index < _hx_len):
|
||||
sign = x[index]
|
||||
if ((sign == "-") or ((sign == "+"))):
|
||||
index = (index + 1)
|
||||
isNegative = (sign == "-")
|
||||
else:
|
||||
isNegative = False
|
||||
isHexadecimal = None
|
||||
if ((index + 1) < _hx_len):
|
||||
cur = x[index]
|
||||
next = x[(index + 1)]
|
||||
isHexadecimal = ((cur == "0") and (((next == "x") or ((next == "X")))))
|
||||
else:
|
||||
isHexadecimal = False
|
||||
if isHexadecimal:
|
||||
index = (index + 2)
|
||||
cur = index
|
||||
if isHexadecimal:
|
||||
while (cur < _hx_len):
|
||||
if (not (x[cur] in "0123456789abcdefABCDEF")):
|
||||
break
|
||||
cur = (cur + 1)
|
||||
else:
|
||||
while (cur < _hx_len):
|
||||
if (not (x[cur] in "0123456789")):
|
||||
break
|
||||
cur = (cur + 1)
|
||||
firstInvalidIndex = cur
|
||||
if (index == firstInvalidIndex):
|
||||
return None
|
||||
result = int(HxString.substring(x,index,firstInvalidIndex),(16 if isHexadecimal else 10))
|
||||
if isNegative:
|
||||
return -result
|
||||
else:
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def shortenPossibleNumber(x):
|
||||
|
@ -860,13 +843,13 @@ class haxe_Template:
|
|||
_g_offset = 0
|
||||
_g_s = data
|
||||
while (_g_offset < len(_g_s)):
|
||||
_g1_key = _g_offset
|
||||
_g_key = _g_offset
|
||||
s = _g_s
|
||||
index = _g_offset
|
||||
_g_offset = (_g_offset + 1)
|
||||
_g1_value = (-1 if ((index >= len(s))) else ord(s[index]))
|
||||
i = _g1_key
|
||||
c = _g1_value
|
||||
_g_value = (-1 if ((index >= len(s))) else ord(s[index]))
|
||||
i = _g_key
|
||||
c = _g_value
|
||||
if (c != 32):
|
||||
l.add(_hx_AnonObject({'p': HxString.substr(data,i,None), 's': True}))
|
||||
break
|
||||
|
@ -1169,7 +1152,7 @@ class haxe_ValueException(haxe_Exception):
|
|||
|
||||
def __init__(self,value,previous = None,native = None):
|
||||
self.value = None
|
||||
super().__init__(Std.string(value),previous,native)
|
||||
super().__init__(("null" if ((value is None)) else Std.string(value)),previous,native)
|
||||
self.value = value
|
||||
|
||||
def unwrap(self):
|
||||
|
@ -1494,10 +1477,7 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,HxString.charCodeAt)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_0 == 11):
|
||||
if (field1 == "lastIndexOf"):
|
||||
return python_internal_MethodClosure(o,HxString.lastIndexOf)
|
||||
|
@ -1507,46 +1487,31 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,HxString.toUpperCase)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_0 == 9):
|
||||
if (field1 == "substring"):
|
||||
return python_internal_MethodClosure(o,HxString.substring)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_0 == 5):
|
||||
if (field1 == "split"):
|
||||
return python_internal_MethodClosure(o,HxString.split)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_0 == 7):
|
||||
if (field1 == "indexOf"):
|
||||
return python_internal_MethodClosure(o,HxString.indexOf)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_0 == 8):
|
||||
if (field1 == "toString"):
|
||||
return python_internal_MethodClosure(o,HxString.toString)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_0 == 6):
|
||||
if (field1 == "charAt"):
|
||||
return python_internal_MethodClosure(o,HxString.charAt)
|
||||
|
@ -1556,16 +1521,10 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,HxString.substr)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif isinstance(o,list):
|
||||
field1 = field
|
||||
_hx_local_1 = len(field1)
|
||||
|
@ -1574,10 +1533,7 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.lastIndexOf)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_1 == 4):
|
||||
if (field1 == "copy"):
|
||||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.copy)
|
||||
|
@ -1589,10 +1545,7 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.sort)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_1 == 5):
|
||||
if (field1 == "shift"):
|
||||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.shift)
|
||||
|
@ -1600,10 +1553,7 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.slice)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_1 == 7):
|
||||
if (field1 == "indexOf"):
|
||||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.indexOf)
|
||||
|
@ -1613,10 +1563,7 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.unshift)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_1 == 3):
|
||||
if (field1 == "map"):
|
||||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.map)
|
||||
|
@ -1624,10 +1571,7 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.pop)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_1 == 8):
|
||||
if (field1 == "contains"):
|
||||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.contains)
|
||||
|
@ -1637,19 +1581,13 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.toString)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_1 == 16):
|
||||
if (field1 == "keyValueIterator"):
|
||||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.keyValueIterator)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
elif (_hx_local_1 == 6):
|
||||
if (field1 == "concat"):
|
||||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.concat)
|
||||
|
@ -1665,22 +1603,13 @@ class python_Boot:
|
|||
return python_internal_MethodClosure(o,python_internal_ArrayImpl.splice)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
else:
|
||||
field1 = (("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field))
|
||||
if hasattr(o,field1):
|
||||
return getattr(o,field1)
|
||||
else:
|
||||
return None
|
||||
return (getattr(o,field1) if (hasattr(o,field1)) else None)
|
||||
|
||||
@staticmethod
|
||||
def getInstanceFields(c):
|
||||
|
@ -2574,6 +2503,8 @@ class xrfragment_URI:
|
|||
else:
|
||||
tmp = False
|
||||
if tmp:
|
||||
stripRelative = EReg("\\./.*","")
|
||||
directory = stripRelative.replace(directory,"")
|
||||
directory = (("null" if directory is None else directory) + HxOverrides.stringOrNull(newURI.directory))
|
||||
else:
|
||||
directory = newURI.directory
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
* v0.5.1 generated at Wed Jun 26 11:16:30 AM UTC 2024
|
||||
* v0.5.1 generated at Tue Jul 9 04:28:50 PM UTC 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
// Generated by Haxe 4.3.3
|
||||
var $hx_exports = typeof exports != "undefined" ? exports : typeof window != "undefined" ? window : typeof self != "undefined" ? self : this;
|
||||
(function ($global) { "use strict";
|
||||
$hx_exports["xrfragment"] = $hx_exports["xrfragment"] || {};
|
||||
|
@ -158,24 +159,11 @@ Std.string = function(s) {
|
|||
return js_Boot.__string_rec(s,"");
|
||||
};
|
||||
Std.parseInt = function(x) {
|
||||
if(x != null) {
|
||||
var _g = 0;
|
||||
var _g1 = x.length;
|
||||
while(_g < _g1) {
|
||||
var i = _g++;
|
||||
var c = x.charCodeAt(i);
|
||||
if(c <= 8 || c >= 14 && c != 32 && c != 45) {
|
||||
var nc = x.charCodeAt(i + 1);
|
||||
var v = parseInt(x,nc == 120 || nc == 88 ? 16 : 10);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
var v = parseInt(x);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return v;
|
||||
};
|
||||
var StringBuf = function() {
|
||||
this.b = "";
|
||||
|
@ -471,10 +459,10 @@ haxe_Template.prototype = {
|
|||
var _g_offset = 0;
|
||||
var _g_s = data;
|
||||
while(_g_offset < _g_s.length) {
|
||||
var _g1_key = _g_offset;
|
||||
var _g1_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g1_key;
|
||||
var c = _g1_value;
|
||||
var _g_key = _g_offset;
|
||||
var _g_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g_key;
|
||||
var c = _g_value;
|
||||
if(c != 32) {
|
||||
l.add({ p : HxOverrides.substr(data,i,null), s : true});
|
||||
break;
|
||||
|
@ -1384,6 +1372,8 @@ xrfragment_URI.toAbsolute = function(url,newUrl) {
|
|||
}
|
||||
if(newURI.directory != null) {
|
||||
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||
var stripRelative_r = new RegExp("\\./.*","".split("u").join(""));
|
||||
directory = directory.replace(stripRelative_r,"");
|
||||
directory += newURI.directory;
|
||||
} else {
|
||||
directory = newURI.directory;
|
||||
|
@ -1668,6 +1658,7 @@ xrf.emit = function(eventName, data){
|
|||
console.groupCollapsed(label)
|
||||
console.info(data)
|
||||
console.groupEnd(label)
|
||||
if( eventName == 'reset' ) debugger
|
||||
if( xrf.debug > 2 ) debugger
|
||||
}
|
||||
return xrf.emit.promise(eventName,data)
|
||||
|
@ -1845,12 +1836,13 @@ pub.fragment = (k, opts ) => { // evaluate one fragment
|
|||
if( !opts.skipXRWG && isPVorMediaFrag ) pub.XRWG(k,opts)
|
||||
|
||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||
xrf.emit(k,opts)
|
||||
.then( () => {
|
||||
let func = xrf.frag[k] || function(){}
|
||||
if( typeof xrf[k] == 'function' ) xrf[k]( func, frag, opts)
|
||||
else func( frag, opts)
|
||||
})
|
||||
if( xrf.frag[k] ){
|
||||
xrf.emit(k,opts)
|
||||
.then( () => {
|
||||
let func = xrf.frag[k] || function(){}
|
||||
func( frag, opts)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub.XRWG = (word,opts) => {
|
||||
|
@ -2024,14 +2016,15 @@ xrf.hasNoMaterial = (mesh) => {
|
|||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||
}
|
||||
|
||||
xrf.navigator = {
|
||||
URI:{
|
||||
scheme: document.location.protocol.replace(/:$/,''),
|
||||
directory: document.location.pathname,
|
||||
host: document.location.hostname,
|
||||
port: document.location.port,
|
||||
file: 'index.glb'
|
||||
}
|
||||
URI: xrf.URI.parse(document.location.href)
|
||||
// scheme: document.location.protocol.replace(/:$/,''),
|
||||
// directory: document.location.pathname,
|
||||
// host: document.location.hostname,
|
||||
// port: document.location.port,
|
||||
// file: 'index.glb'
|
||||
// }
|
||||
}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
|
@ -2041,6 +2034,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
URI.hash = xrf.navigator.reactifyHash(URI.hash) // automatically reflect hash-changes to navigator.to(...)
|
||||
// decorate with extra state
|
||||
URI.fileChange = URI.file && URI.URN + URI.file != xrf.navigator.URI.URN + xrf.navigator.URI.file
|
||||
console.log( URI.URN + URI.file )
|
||||
console.log( xrf.navigator.URI.URN + xrf.navigator.URI.file )
|
||||
URI.external = URI.file && URI.URN != document.location.origin + document.location.pathname
|
||||
URI.hasPos = URI.hash.pos ? true : false
|
||||
URI.duplicatePos = URI.source == xrf.navigator.URI.source && URI.hasPos
|
||||
|
@ -2068,8 +2063,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
loader = loader || new Loader().setPath( URI.URN )
|
||||
}
|
||||
|
||||
|
||||
if( URI.duplicatePos || (!URI.fragment && !URI.file && !URI.fileExt) ){
|
||||
if( URI.duplicatePos || (!Object.values(URI.XRF).length && !URI.file && !URI.fileExt) ){
|
||||
return resolve(xrf.model) // nothing we can do here
|
||||
}
|
||||
if( xrf.model && !URI.fileChange && URI.hashChange && !URI.hasPos ){
|
||||
|
@ -2173,14 +2167,14 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
|||
xrf.navigator.updateHash = (hash,opts) => {
|
||||
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
||||
console.log(`URI: ${document.location.search.substr(1)}#${hash}`)
|
||||
xrf.navigator.updateHash.active = true // important to prevent recursion
|
||||
xrf.navigator.updateHash.active = false // important to prevent recursion
|
||||
document.location.hash = hash
|
||||
xrf.navigator.updateHash.active = false
|
||||
xrf.navigator.updateHash.active = true
|
||||
}
|
||||
|
||||
xrf.navigator.pushState = (file,hash) => {
|
||||
if( file == document.location.search.substr(1) ) return // page is in its default state
|
||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||
window.history.pushState({}, '', document.location.pathname + `?${xrf.navigator.URI.source.replace(/#.*/,'')}#${hash}` )
|
||||
xrf.emit('pushState', {file, hash} )
|
||||
}
|
||||
|
||||
|
@ -2243,7 +2237,8 @@ xrf.frag.href = function(v, opts){
|
|||
if( !mesh.material || !mesh.material.visible ) return // ignore invisible nodes
|
||||
|
||||
// update our values to the latest value (might be edited)
|
||||
xrf.Parser.parse( "href", mesh.userData.href, frag )
|
||||
let URI = xrf.URI.template( mesh.userData.href, xrf.URI.vars.__object )
|
||||
xrf.Parser.parse( "href", URI, frag )
|
||||
const v = frag.href
|
||||
|
||||
// bubble up!
|
||||
|
@ -2361,8 +2356,9 @@ xrf.addEventListener('audioInited', function(opts){
|
|||
*/
|
||||
// this is called by navigator.js rather than by a URL e.g.
|
||||
|
||||
xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
xrf.frag['#'] = xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
let {scene,model} = opts;
|
||||
if( !scene ) return
|
||||
let defaultFragment;
|
||||
scene.traverse( (n) => {
|
||||
if( n.userData && n.userData['#'] ){
|
||||
|
@ -2715,10 +2711,17 @@ xrf.frag.t.default = {
|
|||
xrf.addEventListener('parseModel', (opts) => {
|
||||
let {model} = opts
|
||||
let mixer = model.mixer = new xrf.THREE.AnimationMixer(model.scene)
|
||||
|
||||
mixer.model = model
|
||||
mixer.loop = {timeStart:0,timeStop:0,speed:1.0}
|
||||
mixer.i = xrf.mixers.length
|
||||
mixer.actions = []
|
||||
|
||||
// calculate total duration/frame based on longest animation
|
||||
mixer.duration = 0
|
||||
if( model.animations.length ){
|
||||
model.animations.map( (a) => mixer.duration = ( a.duration > mixer.duration ) ? a.duration : mixer.duration )
|
||||
}
|
||||
|
||||
model.animations.map( (anim) => {
|
||||
anim.optimize()
|
||||
|
@ -2739,7 +2742,7 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.updateLoop = (t) => {
|
||||
if( t ){
|
||||
mixer.loop.timeStart = t.x != undefined ? t.x : mixer.loop.timeStart
|
||||
mixer.loop.timeStop = t.y != undefined ? t.y : mixer.duration
|
||||
mixer.loop.timeStop = t.y != undefined ? t.y : mixer.loop.timeStop
|
||||
}
|
||||
mixer.actions.map( (action) => {
|
||||
if( mixer.loop.timeStart != undefined ){
|
||||
|
@ -2762,7 +2765,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.update = function(time){
|
||||
mixer.time = Math.abs(mixer.time)
|
||||
if( time == 0 ) return update.call(this,time)
|
||||
|
||||
// loop jump
|
||||
if( mixer.loop.timeStop > 0 && mixer.time > mixer.loop.timeStop ){
|
||||
if( mixer.loop.enabled ){
|
||||
|
@ -2774,12 +2776,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.update.patched = true
|
||||
}
|
||||
|
||||
// calculate total duration/frame based on longest animation
|
||||
mixer.duration = 0
|
||||
if( model.animations.length ){
|
||||
model.animations.map( (a) => mixer.duration = ( a.duration > mixer.duration ) ? a.duration : mixer.duration )
|
||||
}
|
||||
|
||||
xrf.mixers.push(mixer)
|
||||
})
|
||||
|
||||
|
@ -3401,8 +3397,8 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
|
||||
if( n.userData ){
|
||||
for( let i in n.userData ){
|
||||
if( i[0] == '#' || i.match(/^(href|tag)$/) ) continue // ignore XR Fragment aliases
|
||||
if( i == 'src' ){
|
||||
//if( i[0] == '#' || i.match(/^(href|tag)$/) ) continue // ignore XR Fragment aliases
|
||||
if( i.match(/^(src|href|tag)/) ){
|
||||
// lets declare empty variables found in src-values ('https://foo.com/video.mp4#{somevar}') e.g.
|
||||
if( n.userData[i].match(variables) ){
|
||||
let vars = [].concat( n.userData[i].match(variables) )
|
||||
|
@ -3431,10 +3427,11 @@ xrf.addEventListener('dynamicKeyValue', (opts) => {
|
|||
if( !xrf.URI.vars[ v.string ] ) return console.error(`'${v.string}' metadata-key not found in scene`)
|
||||
//if( xrf.URI.vars[ id ] && !match.length ) return console.error(`'${id}' object/tag/metadata-key not found in scene`)
|
||||
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}]='${v.string}'`)
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}] => '${v.string}'`)
|
||||
|
||||
if( xrf.URI.vars[id] ){
|
||||
xrf.URI.vars[ id ] = xrf.URI.vars[ v.string ] // update var
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}] => '${xrf.URI.vars[ v.string ]()}'`)
|
||||
xrf.scene.traverse( (n) => {
|
||||
// re-expand src-values which use the updated URI Template var
|
||||
if( n.userData && n.userData.src && n.userData.srcTemplate && n.userData.srcTemplate.match(`{${id}}`) ){
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
* v0.5.1 generated at Wed Jun 26 11:16:30 AM UTC 2024
|
||||
* v0.5.1 generated at Tue Jul 9 04:28:50 PM UTC 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
// Generated by Haxe 4.3.3
|
||||
var $hx_exports = typeof exports != "undefined" ? exports : typeof window != "undefined" ? window : typeof self != "undefined" ? self : this;
|
||||
(function ($global) { "use strict";
|
||||
$hx_exports["xrfragment"] = $hx_exports["xrfragment"] || {};
|
||||
|
@ -158,24 +159,11 @@ Std.string = function(s) {
|
|||
return js_Boot.__string_rec(s,"");
|
||||
};
|
||||
Std.parseInt = function(x) {
|
||||
if(x != null) {
|
||||
var _g = 0;
|
||||
var _g1 = x.length;
|
||||
while(_g < _g1) {
|
||||
var i = _g++;
|
||||
var c = x.charCodeAt(i);
|
||||
if(c <= 8 || c >= 14 && c != 32 && c != 45) {
|
||||
var nc = x.charCodeAt(i + 1);
|
||||
var v = parseInt(x,nc == 120 || nc == 88 ? 16 : 10);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
var v = parseInt(x);
|
||||
if(isNaN(v)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return v;
|
||||
};
|
||||
var StringBuf = function() {
|
||||
this.b = "";
|
||||
|
@ -471,10 +459,10 @@ haxe_Template.prototype = {
|
|||
var _g_offset = 0;
|
||||
var _g_s = data;
|
||||
while(_g_offset < _g_s.length) {
|
||||
var _g1_key = _g_offset;
|
||||
var _g1_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g1_key;
|
||||
var c = _g1_value;
|
||||
var _g_key = _g_offset;
|
||||
var _g_value = _g_s.charCodeAt(_g_offset++);
|
||||
var i = _g_key;
|
||||
var c = _g_value;
|
||||
if(c != 32) {
|
||||
l.add({ p : HxOverrides.substr(data,i,null), s : true});
|
||||
break;
|
||||
|
@ -1384,6 +1372,8 @@ xrfragment_URI.toAbsolute = function(url,newUrl) {
|
|||
}
|
||||
if(newURI.directory != null) {
|
||||
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||
var stripRelative_r = new RegExp("\\./.*","".split("u").join(""));
|
||||
directory = directory.replace(stripRelative_r,"");
|
||||
directory += newURI.directory;
|
||||
} else {
|
||||
directory = newURI.directory;
|
||||
|
@ -1668,6 +1658,7 @@ xrf.emit = function(eventName, data){
|
|||
console.groupCollapsed(label)
|
||||
console.info(data)
|
||||
console.groupEnd(label)
|
||||
if( eventName == 'reset' ) debugger
|
||||
if( xrf.debug > 2 ) debugger
|
||||
}
|
||||
return xrf.emit.promise(eventName,data)
|
||||
|
@ -1845,12 +1836,13 @@ pub.fragment = (k, opts ) => { // evaluate one fragment
|
|||
if( !opts.skipXRWG && isPVorMediaFrag ) pub.XRWG(k,opts)
|
||||
|
||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||
xrf.emit(k,opts)
|
||||
.then( () => {
|
||||
let func = xrf.frag[k] || function(){}
|
||||
if( typeof xrf[k] == 'function' ) xrf[k]( func, frag, opts)
|
||||
else func( frag, opts)
|
||||
})
|
||||
if( xrf.frag[k] ){
|
||||
xrf.emit(k,opts)
|
||||
.then( () => {
|
||||
let func = xrf.frag[k] || function(){}
|
||||
func( frag, opts)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub.XRWG = (word,opts) => {
|
||||
|
@ -2024,14 +2016,15 @@ xrf.hasNoMaterial = (mesh) => {
|
|||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||
}
|
||||
|
||||
xrf.navigator = {
|
||||
URI:{
|
||||
scheme: document.location.protocol.replace(/:$/,''),
|
||||
directory: document.location.pathname,
|
||||
host: document.location.hostname,
|
||||
port: document.location.port,
|
||||
file: 'index.glb'
|
||||
}
|
||||
URI: xrf.URI.parse(document.location.href)
|
||||
// scheme: document.location.protocol.replace(/:$/,''),
|
||||
// directory: document.location.pathname,
|
||||
// host: document.location.hostname,
|
||||
// port: document.location.port,
|
||||
// file: 'index.glb'
|
||||
// }
|
||||
}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
|
@ -2041,6 +2034,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
URI.hash = xrf.navigator.reactifyHash(URI.hash) // automatically reflect hash-changes to navigator.to(...)
|
||||
// decorate with extra state
|
||||
URI.fileChange = URI.file && URI.URN + URI.file != xrf.navigator.URI.URN + xrf.navigator.URI.file
|
||||
console.log( URI.URN + URI.file )
|
||||
console.log( xrf.navigator.URI.URN + xrf.navigator.URI.file )
|
||||
URI.external = URI.file && URI.URN != document.location.origin + document.location.pathname
|
||||
URI.hasPos = URI.hash.pos ? true : false
|
||||
URI.duplicatePos = URI.source == xrf.navigator.URI.source && URI.hasPos
|
||||
|
@ -2068,8 +2063,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
loader = loader || new Loader().setPath( URI.URN )
|
||||
}
|
||||
|
||||
|
||||
if( URI.duplicatePos || (!URI.fragment && !URI.file && !URI.fileExt) ){
|
||||
if( URI.duplicatePos || (!Object.values(URI.XRF).length && !URI.file && !URI.fileExt) ){
|
||||
return resolve(xrf.model) // nothing we can do here
|
||||
}
|
||||
if( xrf.model && !URI.fileChange && URI.hashChange && !URI.hasPos ){
|
||||
|
@ -2173,14 +2167,14 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
|||
xrf.navigator.updateHash = (hash,opts) => {
|
||||
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
||||
console.log(`URI: ${document.location.search.substr(1)}#${hash}`)
|
||||
xrf.navigator.updateHash.active = true // important to prevent recursion
|
||||
xrf.navigator.updateHash.active = false // important to prevent recursion
|
||||
document.location.hash = hash
|
||||
xrf.navigator.updateHash.active = false
|
||||
xrf.navigator.updateHash.active = true
|
||||
}
|
||||
|
||||
xrf.navigator.pushState = (file,hash) => {
|
||||
if( file == document.location.search.substr(1) ) return // page is in its default state
|
||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||
window.history.pushState({}, '', document.location.pathname + `?${xrf.navigator.URI.source.replace(/#.*/,'')}#${hash}` )
|
||||
xrf.emit('pushState', {file, hash} )
|
||||
}
|
||||
|
||||
|
@ -2243,7 +2237,8 @@ xrf.frag.href = function(v, opts){
|
|||
if( !mesh.material || !mesh.material.visible ) return // ignore invisible nodes
|
||||
|
||||
// update our values to the latest value (might be edited)
|
||||
xrf.Parser.parse( "href", mesh.userData.href, frag )
|
||||
let URI = xrf.URI.template( mesh.userData.href, xrf.URI.vars.__object )
|
||||
xrf.Parser.parse( "href", URI, frag )
|
||||
const v = frag.href
|
||||
|
||||
// bubble up!
|
||||
|
@ -2361,8 +2356,9 @@ xrf.addEventListener('audioInited', function(opts){
|
|||
*/
|
||||
// this is called by navigator.js rather than by a URL e.g.
|
||||
|
||||
xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
xrf.frag['#'] = xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
let {scene,model} = opts;
|
||||
if( !scene ) return
|
||||
let defaultFragment;
|
||||
scene.traverse( (n) => {
|
||||
if( n.userData && n.userData['#'] ){
|
||||
|
@ -2715,10 +2711,17 @@ xrf.frag.t.default = {
|
|||
xrf.addEventListener('parseModel', (opts) => {
|
||||
let {model} = opts
|
||||
let mixer = model.mixer = new xrf.THREE.AnimationMixer(model.scene)
|
||||
|
||||
mixer.model = model
|
||||
mixer.loop = {timeStart:0,timeStop:0,speed:1.0}
|
||||
mixer.i = xrf.mixers.length
|
||||
mixer.actions = []
|
||||
|
||||
// calculate total duration/frame based on longest animation
|
||||
mixer.duration = 0
|
||||
if( model.animations.length ){
|
||||
model.animations.map( (a) => mixer.duration = ( a.duration > mixer.duration ) ? a.duration : mixer.duration )
|
||||
}
|
||||
|
||||
model.animations.map( (anim) => {
|
||||
anim.optimize()
|
||||
|
@ -2739,7 +2742,7 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.updateLoop = (t) => {
|
||||
if( t ){
|
||||
mixer.loop.timeStart = t.x != undefined ? t.x : mixer.loop.timeStart
|
||||
mixer.loop.timeStop = t.y != undefined ? t.y : mixer.duration
|
||||
mixer.loop.timeStop = t.y != undefined ? t.y : mixer.loop.timeStop
|
||||
}
|
||||
mixer.actions.map( (action) => {
|
||||
if( mixer.loop.timeStart != undefined ){
|
||||
|
@ -2762,7 +2765,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.update = function(time){
|
||||
mixer.time = Math.abs(mixer.time)
|
||||
if( time == 0 ) return update.call(this,time)
|
||||
|
||||
// loop jump
|
||||
if( mixer.loop.timeStop > 0 && mixer.time > mixer.loop.timeStop ){
|
||||
if( mixer.loop.enabled ){
|
||||
|
@ -2774,12 +2776,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.update.patched = true
|
||||
}
|
||||
|
||||
// calculate total duration/frame based on longest animation
|
||||
mixer.duration = 0
|
||||
if( model.animations.length ){
|
||||
model.animations.map( (a) => mixer.duration = ( a.duration > mixer.duration ) ? a.duration : mixer.duration )
|
||||
}
|
||||
|
||||
xrf.mixers.push(mixer)
|
||||
})
|
||||
|
||||
|
@ -3401,8 +3397,8 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
|
||||
if( n.userData ){
|
||||
for( let i in n.userData ){
|
||||
if( i[0] == '#' || i.match(/^(href|tag)$/) ) continue // ignore XR Fragment aliases
|
||||
if( i == 'src' ){
|
||||
//if( i[0] == '#' || i.match(/^(href|tag)$/) ) continue // ignore XR Fragment aliases
|
||||
if( i.match(/^(src|href|tag)/) ){
|
||||
// lets declare empty variables found in src-values ('https://foo.com/video.mp4#{somevar}') e.g.
|
||||
if( n.userData[i].match(variables) ){
|
||||
let vars = [].concat( n.userData[i].match(variables) )
|
||||
|
@ -3431,10 +3427,11 @@ xrf.addEventListener('dynamicKeyValue', (opts) => {
|
|||
if( !xrf.URI.vars[ v.string ] ) return console.error(`'${v.string}' metadata-key not found in scene`)
|
||||
//if( xrf.URI.vars[ id ] && !match.length ) return console.error(`'${id}' object/tag/metadata-key not found in scene`)
|
||||
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}]='${v.string}'`)
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}] => '${v.string}'`)
|
||||
|
||||
if( xrf.URI.vars[id] ){
|
||||
xrf.URI.vars[ id ] = xrf.URI.vars[ v.string ] // update var
|
||||
if( xrf.debug ) console.log(`URI.vars[${id}] => '${xrf.URI.vars[ v.string ]()}'`)
|
||||
xrf.scene.traverse( (n) => {
|
||||
// re-expand src-values which use the updated URI Template var
|
||||
if( n.userData && n.userData.src && n.userData.srcTemplate && n.userData.srcTemplate.match(`{${id}}`) ){
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
<script src="./../../../dist/xrfragment.aframe.js"></script>
|
||||
|
||||
<!-- important: allow touchevents in AR -->
|
||||
<style type="text/css"> canvas.a-dom-overlay:not(.a-no-style) { padding: 0; pointer-events: auto; }</style>
|
||||
<style type="text/css">
|
||||
canvas.a-dom-overlay:not(.a-no-style) { padding: 0; pointer-events: auto; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -55,6 +55,14 @@ window.AFRAME.registerComponent('xrf', {
|
|||
if( VRbutton ) VRbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#VR' ) )
|
||||
})
|
||||
|
||||
// not part of the spec, but convenient to only show AR button when negative VR-tag was defined in default fragment ('#' in rootscene file)
|
||||
xrf.addEventListener('#', function(e){
|
||||
if( e.frag['#'].string.match(/-VR/) ){
|
||||
aScene.removeAttribute('xr-mode-ui')
|
||||
aScene.setAttribute('xr-mode-ui',"XRMode: ar")
|
||||
}
|
||||
})
|
||||
|
||||
let repositionUser = (scale) => () => {
|
||||
// sometimes AFRAME resets the user position to 0,0,0 when entering VR (not sure why)
|
||||
setTimeout( () => {
|
||||
|
@ -67,6 +75,7 @@ window.AFRAME.registerComponent('xrf', {
|
|||
aScene.addEventListener('enter-ar', repositionUser(2) )
|
||||
|
||||
xrf.addEventListener('navigateLoaded', (opts) => {
|
||||
|
||||
setTimeout( () => AFRAME.fade.out(),500)
|
||||
let isLocal = opts.url.match(/^#/)
|
||||
if( isLocal ) return
|
||||
|
|
|
@ -114,7 +114,7 @@ window.accessibility = (opts) => new Proxy({
|
|||
this.helper.selected = n.uuid
|
||||
xrf.scene.add(this.helper)
|
||||
|
||||
notify(`${n.userData['aria-description']||''}` + (n.userData.href ? `<br><b>name:</b> ${n.name}<br><b>link:</b> ${n.userData['href']}` :'') )
|
||||
notify(`${n.userData['aria-description']||''}` + (n.userData.href ? `<br><b>name:</b> ${n.name}<br><b>href:</b> ${n.userData['href']}` :'') )
|
||||
}
|
||||
|
||||
if( e.key == 'Enter' && objects[cache.current].userData.href ){
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
|
||||
xrf.navigator = {
|
||||
URI:{
|
||||
scheme: document.location.protocol.replace(/:$/,''),
|
||||
directory: document.location.pathname,
|
||||
host: document.location.hostname,
|
||||
port: document.location.port,
|
||||
file: 'index.glb'
|
||||
}
|
||||
URI: xrf.URI.parse(document.location.href)
|
||||
// scheme: document.location.protocol.replace(/:$/,''),
|
||||
// directory: document.location.pathname,
|
||||
// host: document.location.hostname,
|
||||
// port: document.location.port,
|
||||
// file: 'index.glb'
|
||||
// }
|
||||
}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
|
@ -15,6 +16,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
URI.hash = xrf.navigator.reactifyHash(URI.hash) // automatically reflect hash-changes to navigator.to(...)
|
||||
// decorate with extra state
|
||||
URI.fileChange = URI.file && URI.URN + URI.file != xrf.navigator.URI.URN + xrf.navigator.URI.file
|
||||
console.log( URI.URN + URI.file )
|
||||
console.log( xrf.navigator.URI.URN + xrf.navigator.URI.file )
|
||||
URI.external = URI.file && URI.URN != document.location.origin + document.location.pathname
|
||||
URI.hasPos = URI.hash.pos ? true : false
|
||||
URI.duplicatePos = URI.source == xrf.navigator.URI.source && URI.hasPos
|
||||
|
@ -146,14 +149,14 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
|||
xrf.navigator.updateHash = (hash,opts) => {
|
||||
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
||||
console.log(`URI: ${document.location.search.substr(1)}#${hash}`)
|
||||
xrf.navigator.updateHash.active = true // important to prevent recursion
|
||||
xrf.navigator.updateHash.active = false // important to prevent recursion
|
||||
document.location.hash = hash
|
||||
xrf.navigator.updateHash.active = false
|
||||
xrf.navigator.updateHash.active = true
|
||||
}
|
||||
|
||||
xrf.navigator.pushState = (file,hash) => {
|
||||
if( file == document.location.search.substr(1) ) return // page is in its default state
|
||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${xrf.navigator.URI.source}#${hash}` )
|
||||
window.history.pushState({}, '', document.location.pathname + `?${xrf.navigator.URI.source.replace(/#.*/,'')}#${hash}` )
|
||||
xrf.emit('pushState', {file, hash} )
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// this is called by navigator.js rather than by a URL e.g.
|
||||
|
||||
xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
xrf.frag['#'] = xrf.frag.defaultPredefinedViews = (opts) => {
|
||||
let {scene,model} = opts;
|
||||
if( !scene ) return
|
||||
let defaultFragment;
|
||||
scene.traverse( (n) => {
|
||||
if( n.userData && n.userData['#'] ){
|
||||
|
|
|
@ -17,5 +17,7 @@
|
|||
{"fn":"url","data":"/bar/flop#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"host","out":"foo.com"},"label":"test URLBrowser (maintain host)"},
|
||||
{"fn":"url","data":"c/d?foo=1#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"path","out":"/bar/flop/c/d"},"label":"test URLBrowser (append path+query)"},
|
||||
{"fn":"url","data":"a/b#foo=bar", "expect":{ "fn":"testURL", "input":"hash.foo","out":"bar"},"label":"test URL hash #mycustom == foo"},
|
||||
{"fn":"url","data":"a/b?index.glb#foo=bar://foo/flop.gltf", "expect":{ "fn":"testURL", "input":"directory","out":"a/b"},"label":"test URLhash with protocol"}
|
||||
{"fn":"url","data":"./../../xyz", "expect":{ "fn":"testURLBrowse", "input":"path","out":"/bar/flop/c/d/./../../xyz"},"label":"test URL relative path"},
|
||||
{"fn":"url","data":"./../../xyz", "expect":{ "fn":"testURLBrowse", "input":"path","out":"/bar/flop/c/d/./../../xyz"},"label":"test URL relative path"},
|
||||
{"fn":"url","data":"a/b?index.glb#foo=bar://foo/flop.gltf", "expect":{ "fn":"testURL", "input":"directory","out":"/a/b"},"label":"test URLhash with protocol"}
|
||||
]
|
||||
|
|
|
@ -434,6 +434,8 @@ class URI {
|
|||
if (newURI.directory != null)
|
||||
{
|
||||
if( newUrl.charAt(0) != '/' && newUrl.indexOf("://") == -1 ){
|
||||
var stripRelative : EReg = ~/\.\/.*/;
|
||||
directory = stripRelative.replace( directory, '');
|
||||
directory += newURI.directory;
|
||||
}else{
|
||||
directory = newURI.directory;
|
||||
|
@ -448,7 +450,7 @@ class URI {
|
|||
}else{
|
||||
resultURI.file = url.file;
|
||||
}
|
||||
|
||||
|
||||
resultURI.path = resultURI.directory + resultURI.file;
|
||||
|
||||
if (newURI.query != null)
|
||||
|
|
Loading…
Reference in New Issue