xrfragment-haxe/src/3rd/js/three/index.js

102 lines
3.3 KiB
JavaScript
Raw Normal View History

xrf.frag = {}
2023-05-17 21:31:28 +02:00
xrf.model = {}
2023-10-30 16:15:08 +01:00
xrf.mixers = []
2023-06-07 17:42:21 +02:00
xrf.init = ((init) => function(opts){
2023-09-21 13:05:30 +02:00
let scene = new opts.THREE.Group()
opts.scene.add(scene)
opts.scene = scene
2023-06-07 17:42:21 +02:00
init(opts)
if( opts.loaders ) Object.values(opts.loaders).map( xrf.patchLoader )
2023-05-17 21:31:28 +02:00
2023-10-30 16:15:08 +01:00
xrf.patchRenderer(opts)
xrf.navigator.init()
2023-06-07 17:42:21 +02:00
// return xrfragment lib as 'xrf' query functor (like jquery)
for ( let i in xrf ) xrf.query[i] = xrf[i]
return xrf.query
})(xrf.init)
2023-10-30 16:15:08 +01:00
xrf.patchRenderer = function(opts){
let {renderer,camera} = opts
renderer.xr.addEventListener( 'sessionstart', () => xrf.baseReferenceSpace = renderer.xr.getReferenceSpace() );
renderer.xr.enabled = true;
2023-10-30 16:15:08 +01:00
xrf.clock = new xrf.THREE.Clock()
2023-05-10 19:12:15 +02:00
renderer.render = ((render) => function(scene,camera){
2023-10-26 18:45:13 +02:00
// update clock
2023-10-30 16:15:08 +01:00
let time = xrf.clock.getDelta()
2023-10-26 18:45:13 +02:00
// allow entities to do stuff during render (onBeforeRender and onAfterRender don't always fire)
2023-11-08 18:28:18 +01:00
xrf.emit('render',{scene,camera,time,render}) // allow fragments to do something at renderframe
2023-05-10 19:12:15 +02:00
render(scene,camera)
})(renderer.render.bind(renderer))
2023-10-30 16:15:08 +01:00
2023-05-10 19:12:15 +02:00
}
xrf.patchLoader = function(loader){
2023-07-04 17:15:23 +02:00
if( loader.prototype.load.xrf_patched ) return // prevent patching aliased loaders twice
loader.prototype.load = ((load) => function(url, onLoad, onProgress, onError){
load.call( this,
url,
2023-06-07 17:42:21 +02:00
(model) => {
onLoad(model);
xrf.parseModel(model,url)
},
onProgress,
onError)
})(loader.prototype.load)
2023-07-04 17:15:23 +02:00
loader.prototype.load.xrf_patched = true
}
xrf.getFile = (url) => url.split("/").pop().replace(/#.*/,'')
2023-05-05 18:53:42 +02:00
xrf.parseModel = function(model,url){
let file = xrf.getFile(url)
2023-05-05 18:53:42 +02:00
model.file = file
2023-05-18 17:11:11 +02:00
// eval embedded XR fragments
2023-10-26 18:45:13 +02:00
model.scene.traverse( (mesh) => {
xrf.hashbus.pub.mesh(mesh,model)
})
model.animations.map( (a) => console.log("anim: "+a.name) )
xrf.emit('parseModel',{model,url,file})
}
xrf.getLastModel = () => xrf.model.last
xrf.reset = () => {
2023-05-17 21:31:28 +02:00
const disposeObject = (obj) => {
if (obj.children.length > 0) obj.children.forEach((child) => disposeObject(child));
if (obj.geometry) obj.geometry.dispose();
if (obj.material) {
if (obj.material.map) obj.material.map.dispose();
obj.material.dispose();
}
2023-05-22 15:03:23 +02:00
obj.clear()
obj.removeFromParent()
2023-05-17 21:31:28 +02:00
return true
};
2023-05-22 15:03:23 +02:00
let nodes = []
2023-11-06 11:50:04 +01:00
xrf.scene.traverse( (n) => n.audio ? n.audio.remove() : false )
2023-05-22 15:03:23 +02:00
xrf.scene.traverse( (child) => child.isXRF ? nodes.push(child) : false )
nodes.map( disposeObject ) // leave non-XRF objects intact
xrf.interactive = xrf.InteractiveGroup( xrf.THREE, xrf.renderer, xrf.camera)
2023-09-21 13:05:30 +02:00
xrf.add( xrf.interactive )
xrf.layers = 0
2023-10-25 11:43:44 +02:00
xrf.emit('reset',{})
2023-10-30 16:15:08 +01:00
// remove mixers
2023-11-08 18:28:18 +01:00
xrf.mixers.map( (m) => m.stop())
2023-10-30 16:15:08 +01:00
xrf.mixers = []
}
2023-05-17 21:31:28 +02:00
xrf.parseUrl = (url) => {
const urlObj = new URL( url.match(/:\/\//) ? url : String(`https://fake.com/${url}`).replace(/\/\//,'/') )
let dir = url.substring(0, url.lastIndexOf('/') + 1)
const file = urlObj.pathname.substring(urlObj.pathname.lastIndexOf('/') + 1);
const hash = url.match(/#/) ? url.replace(/.*#/,'') : ''
const ext = file.split('.').pop()
return {urlObj,dir,file,hash,ext}
}
xrf.add = (object) => {
object.isXRF = true // mark for easy deletion when replacing scene
xrf.scene.add(object)
}