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

154 lines
5.1 KiB
JavaScript
Raw Normal View History

2023-06-07 17:42:21 +02:00
// *TODO* use webgl instancing
xrf.frag.src = function(v, opts){
opts.embedded = v // indicate embedded XR fragment
2023-06-07 17:42:21 +02:00
let { mesh, model, camera, scene, renderer, THREE} = opts
2023-07-06 15:27:27 +02:00
console.log("SRCCC")
console.dir(mesh)
2023-07-04 15:23:10 +02:00
console.log(" └ instancing src")
2023-06-07 17:42:21 +02:00
let src = new THREE.Group()
2023-07-04 15:23:10 +02:00
let frag = xrfragment.URI.parse(v.string)
2023-06-07 17:42:21 +02:00
2023-07-04 15:23:10 +02:00
const localSRC = () => {
2023-06-07 17:42:21 +02:00
2023-07-06 15:27:27 +02:00
// scale embedded XR fragments https://xrfragment.org/#scaling%20of%20instanced%20objects
2023-06-07 17:42:21 +02:00
setTimeout( () => {
2023-07-06 15:27:27 +02:00
// scale URI XR Fragments inside src-value
2023-06-07 17:42:21 +02:00
for( var i in frag ){
xrf.eval.fragment(i, Object.assign(opts,{frag, model,scene}))
}
if( frag.q.query ){
let srcScene = frag.q.scene // three/xrf/q.js initializes .scene
2023-06-07 17:42:21 +02:00
if( !srcScene || !srcScene.visible ) return
console.log(" └ inserting "+i+" (srcScene)")
srcScene.position.set(0,0,0)
srcScene.rotation.set(0,0,0)
srcScene.traverse( (m) => {
2023-07-04 17:15:23 +02:00
m.isSRC = true
2023-06-07 17:42:21 +02:00
if( m.userData && (m.userData.src || m.userData.href) ) return ;//delete m.userData.src // prevent infinite recursion
xrf.eval.mesh(m,{scene,recursive:true})
})
console.dir(xrf)
2023-06-07 17:42:21 +02:00
if( srcScene.visible ) src.add( srcScene )
}
2023-07-06 15:27:27 +02:00
xrf.frag.src.scale( src, opts )
2023-06-07 17:42:21 +02:00
},10)
}
2023-07-04 15:23:10 +02:00
const externalSRC = () => {
2023-07-05 16:43:07 +02:00
fetch(v.string, { method: 'HEAD' })
.then( (res) => {
console.log(`loading src ${v.string}`)
let mimetype = res.headers.get('Content-type')
console.log("src mimetype: "+mimetype)
return xrf.frag.src.type[ mimetype ] ? xrf.frag.src.type[ mimetype ](v.string,opts) : xrf.frag.src.type.unknown(v.string,opts)
})
.finally( () => {
})
.catch( console.error )
2023-07-06 15:27:27 +02:00
//// scale URI XR Fragments inside src-value
2023-07-04 18:15:08 +02:00
//for( var i in frag ){
// xrf.eval.fragment(i, Object.assign(opts,{frag, model,scene}))
//}
2023-07-04 15:23:10 +02:00
}
2023-07-05 16:43:07 +02:00
if( v.string[0] == "#" ) localSRC() // current file
else externalSRC() // external file
}
/*
* replace the src-mesh with the contents of the src
*/
2023-07-06 15:27:27 +02:00
xrf.frag.src.scale = function(scene, opts, url){
2023-07-05 16:43:07 +02:00
let { mesh, model, camera, renderer, THREE} = opts
2023-07-06 15:27:27 +02:00
let restrictToBoundingBox = mesh.geometry
2023-07-05 16:43:07 +02:00
if( url ){
let frag = xrfragment.URI.parse(url)
console.log("parse url:"+url)
console.log("children:"+scene.children.length)
2023-07-06 15:27:27 +02:00
// scale URI XR Fragments (queries) inside src-value
2023-07-05 16:43:07 +02:00
for( var i in frag ){
xrf.eval.fragment(i, Object.assign(opts,{frag, model:{scene},scene}))
}
// if( frag.q ) scene = frag.q.scene
console.dir(frag)
//xrf.add( model.scene )
xrf.eval( '#', {scene} ) // execute the default projection '#' (if exist)
xrf.eval( url, {scene} ) // and eval URI XR fragments
//if( !hash.match(/pos=/) )
// xrf.eval( '#pos=0,0,0' ) // set default position if not specified
2023-07-06 15:27:27 +02:00
}
scene.isXRF = model.scene.isSRC = true
if( restrictToBoundingBox ){
2023-07-05 16:43:07 +02:00
let bboxMesh = new THREE.Box3().setFromObject(mesh);
let bboxScene = new THREE.Box3().setFromObject(scene);
let maxScene = bboxScene.max.y > bboxScene.max.x ? bboxScene.max.y : bboxScene.max.x
let maxMesh = bboxMesh.max.y > bboxMesh.max.x ? bboxMesh.max.y : bboxMesh.max.x
let factor = maxMesh > maxScene ? maxScene / maxMesh : maxMesh / maxScene
scene.scale.multiplyScalar( factor )
}
//scene.position.copy( mesh.position )
//scene.rotation.copy( mesh.rotation )
//scene.scale.copy( mesh.scale )
scene.scale.multiply( mesh.scale )
mesh.add( scene )
if( !opts.recursive && mesh.material ) mesh.material.visible = false // lets hide the preview object because deleting disables animations+nested objs
}
xrf.frag.src.type = {}
/*
* mimetype: unknown
*/
xrf.frag.src.type['unknown'] = function( url, opts ){
return new Promise( (resolve,reject) => {
reject(`${url} mimetype not supported (yet)`)
})
}
/*
* mimetype: model/gltf+json
*/
xrf.frag.src.type['model/gltf+json'] = function( url, opts ){
return new Promise( (resolve,reject) => {
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
let loader
const Loader = xrf.loaders[ext]
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
if( !dir.match("://") ){ // force relative path
dir = dir[0] == '.' ? dir : `.${dir}`
loader = new Loader().setPath( dir )
}else loader = new Loader()
const onLoad = (model) => {
2023-07-06 15:27:27 +02:00
xrf.frag.src.scale( model.scene, {...opts, model, scene: model.scene}, url )
2023-07-05 16:43:07 +02:00
resolve(model)
}
loader.load(url, onLoad )
})
2023-06-07 17:42:21 +02:00
}
2023-07-06 15:27:27 +02:00
/*
* mimetype: image/png
* mimetype: image/jpg
* mimetype: image/gif
*/
xrf.frag.src.type['image/png'] = function(url,opts){
const texture = new THREE.TextureLoader().load( 'textures/crate.gif' );
texture.colorSpace = THREE.SRGBColorSpace;
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { map: texture } );
}
xrf.frag.src.type['image/gif'] = xrf.frag.src.type['image/png']
xrf.frag.src.type['image/jpg'] = xrf.frag.src.type['image/png']