improving boundingbox scaling by hiding invisible objects
This commit is contained in:
parent
7e656a02f0
commit
211652fa5e
Binary file not shown.
|
@ -12,7 +12,9 @@ xrf.filter.scene = function(opts){
|
|||
xrf.filter
|
||||
.sort(frag) // get (sorted) filters from XR Fragments
|
||||
.process(frag,scene) // show/hide things
|
||||
|
||||
|
||||
scene.visible = true // always enable scene
|
||||
|
||||
return scene
|
||||
}
|
||||
|
||||
|
@ -25,22 +27,27 @@ xrf.filter.sort = function(frag){
|
|||
}
|
||||
|
||||
xrf.filter.process = function(frag,scene,opts){
|
||||
// include all when query starts with negative objectnames/tags are included
|
||||
let firstFilter = frag.filters[0].filter.get()
|
||||
let showAll = firstFilter.show === false
|
||||
let showers = frag.filters.filter( (v) => v.filter.get().show === true )
|
||||
if( !showAll ) scene.traverse( (n) => n.visible = false )
|
||||
const hasName = (m,name,filter) => m.name == name
|
||||
const hasNameOrTag = (m,name_or_tag,filter) => hasName(m,name_or_tag) || m.userData[filter.key]
|
||||
const cleanupKey = (k) => k.replace(/[-\*]/g,'')
|
||||
|
||||
// reparent if first selector is positive and has no value
|
||||
if( firstFilter.show === true ){
|
||||
let obj = scene.getObjectByName( firstFilter.key )
|
||||
while( scene.children.length > 0 ) scene.children[0].removeFromParent()
|
||||
if(obj) scene.add(obj)
|
||||
let firstFilter = frag.filters[0].filter.get()
|
||||
let showers = frag.filters.filter( (v) => v.filter.get().show === true )
|
||||
|
||||
// reparent scene based on object in case it matches a primary (non-negating) selector
|
||||
if( !firstFilter.value && firstFilter.show === true ){
|
||||
let obj
|
||||
scene.traverse( (n) => hasName(n, firstFilter.key,firstFilter) && (obj = n) )
|
||||
if(obj){
|
||||
while( scene.children.length > 0 ) scene.children[0].removeFromParent()
|
||||
scene.add( obj )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// then show/hide things based on secondary selectors
|
||||
frag.filters.map( (v) => {
|
||||
const filter = v.filter.get()
|
||||
const name_or_tag = v.fragment.replace(/[-\*]/g,'')
|
||||
const name_or_tag = cleanupKey(v.fragment)
|
||||
let seen = {}
|
||||
|
||||
const setVisibleUnseen = (m,visible) => {
|
||||
|
@ -50,7 +57,6 @@ xrf.filter.process = function(frag,scene,opts){
|
|||
}
|
||||
|
||||
scene.traverse( (m) => {
|
||||
const isMatch = m.name == name_or_tag || m.userData[filter.key]
|
||||
|
||||
// filter on value(expression) #foo=>3 e.g.
|
||||
if( filter.value && m.userData[filter.key] ){
|
||||
|
@ -63,12 +69,13 @@ xrf.filter.process = function(frag,scene,opts){
|
|||
}
|
||||
|
||||
// include/exclude object(s) when id/tag matches (#foo or #-foo e.g.)
|
||||
if( isMatch ){
|
||||
if( hasNameOrTag(m,name_or_tag,filter) ){
|
||||
m.visible = filter.show
|
||||
if( filter.deep ) m.traverse( (n) => n.visible = m.visible )
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return xrf.filter
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ xrf.frag.src = function(v, opts){
|
|||
mesh.add(model.scene)
|
||||
mesh.traverse( (n) => n.isSRC = n.isXRF = true ) // mark everything SRC
|
||||
xrf.emit('parseModel', {...opts, scene, model})
|
||||
if( mesh.material ) mesh.material.visible = false
|
||||
if( mesh.material ) mesh.material.visible = false // hide placeholder object
|
||||
}
|
||||
|
||||
const enableSourcePortation = (src) => {
|
||||
|
@ -93,6 +93,13 @@ xrf.frag.src.eval = function(scene, opts, url){
|
|||
xrf.frag.src.scale = function(scene, opts, url){
|
||||
let { mesh, model, camera, renderer, THREE} = opts
|
||||
|
||||
// remove invisible objects (hidden by selectors) which might corrupt boundingbox size-detection
|
||||
let cleanScene = scene.clone()
|
||||
if( !cleanScene ) debugger
|
||||
let remove = []
|
||||
cleanScene.traverse( (n) => !n.visible && n.children.length == 0 && (remove.push(n)) )
|
||||
remove.map( (n) => n.removeFromParent() )
|
||||
|
||||
let restrictTo3DBoundingBox = mesh.geometry
|
||||
if( restrictTo3DBoundingBox ){
|
||||
// spec 3 of https://xrfragment.org/#src
|
||||
|
@ -100,23 +107,11 @@ xrf.frag.src.scale = function(scene, opts, url){
|
|||
// normalize instanced objectsize to boundingbox
|
||||
let sizeFrom = new THREE.Vector3()
|
||||
let sizeTo = new THREE.Vector3()
|
||||
|
||||
let empty = new THREE.Object3D()
|
||||
|
||||
// *TODO* exclude invisible objects from boundingbox size-detection
|
||||
//
|
||||
// THREE.Box3.prototype.expandByObject = (function(expandByObject){
|
||||
// return function(object,precise){
|
||||
// return expandByObject.call(this, object.visible ? object : empty, precise)
|
||||
// }
|
||||
// })(THREE.Box3.prototype.expandByObject)
|
||||
|
||||
new THREE.Box3().setFromObject(mesh).getSize(sizeTo)
|
||||
new THREE.Box3().setFromObject(scene).getSize(sizeFrom)
|
||||
new THREE.Box3().setFromObject(cleanScene).getSize(sizeFrom)
|
||||
let ratio = sizeFrom.divide(sizeTo)
|
||||
scene.scale.multiplyScalar( 1.0 / Math.max(ratio.x, ratio.y, ratio.z));
|
||||
// let factor = getMax(sizeTo) < getMax(sizeFrom) ? getMax(sizeTo) / getMax(sizeFrom) : getMax(sizeFrom) / getMax(sizeTo)
|
||||
// scene.scale.multiplyScalar( factor )
|
||||
}else{
|
||||
// spec 4 of https://xrfragment.org/#src
|
||||
// spec 2 of https://xrfragment.org/#scaling%20of%20instanced%20objects
|
||||
|
@ -131,30 +126,10 @@ xrf.frag.src.filterScene = (scene,opts) => {
|
|||
xrf.filter.scene({scene,frag})
|
||||
if( scene.children.length == 1 ) scene.children[0].position.set(0,0,0)
|
||||
|
||||
/*
|
||||
if( !frag.filter ){
|
||||
src = new THREE.Group()
|
||||
if( Object.keys(frag).length > 0 ){
|
||||
for( var i in frag ){
|
||||
if( scene.getObjectByName(i) ){
|
||||
src.add( obj = scene.getObjectByName(i).clone(true) )
|
||||
}
|
||||
hashbus.pub.fragment(i, Object.assign(opts,{frag, model,scene}))
|
||||
}
|
||||
}
|
||||
if( src.children.length == 1 ) obj.position.set(0,0,0);
|
||||
}
|
||||
|
||||
// filtering of objects using query
|
||||
if( Object.keys(frag).length > 1 ){
|
||||
src = scene
|
||||
xrf.filter.scene(src,frag)
|
||||
}
|
||||
src.traverse( (m) => {
|
||||
scene.traverse( (m) => {
|
||||
if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion
|
||||
hashbus.pub.mesh(m,{scene,recursive:true}) // cool idea: recursion-depth based distance between face & src
|
||||
})
|
||||
*/
|
||||
return scene
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
|||
mesh.material = mat
|
||||
// set range
|
||||
video.addEventListener('timeupdate', function timeupdate() {
|
||||
if (video.t && video.currentTime < video.t.y || video.currentTime >= video.y.z ) {
|
||||
if (video.t && video.currentTime < video.t.y || video.currentTime >= video.t.z ) {
|
||||
vid.currentTime = video.t.y
|
||||
}
|
||||
},false)
|
||||
|
|
|
@ -28,7 +28,7 @@ filterScene = (URI) => {
|
|||
scene = filterScene("#b")
|
||||
test = () => !scene.getObjectByName("a") &&
|
||||
scene.getObjectByName("b").visible &&
|
||||
!scene.getObjectByName("c")
|
||||
!scene.getObjectByName("c").visible
|
||||
console.assert( test(), {scene,reason:`objectname: #b => a = removed b = visible c = removed`})
|
||||
|
||||
scene = filterScene("#b*")
|
||||
|
@ -68,6 +68,7 @@ test = () => scene.getObjectByName("a").visible &&
|
|||
console.assert( test(), {scene,reason:`objectname: #-b&b => a = visible b = visible c = invisible`})
|
||||
|
||||
scene = filterScene("#score")
|
||||
console.dir(scene)
|
||||
test = () => !scene.getObjectByName("a") &&
|
||||
scene.getObjectByName("b").visible &&
|
||||
!scene.getObjectByName("c").visible
|
||||
|
@ -80,13 +81,13 @@ test = () => !scene.getObjectByName("a") &&
|
|||
console.assert( test(), {scene,reason:`objectname: #score=>1 => a = removed b = visible c = invisible`})
|
||||
|
||||
scene = filterScene("#score=>3")
|
||||
test = () => !scene.getObjectByName("a").visible &&
|
||||
test = () => !scene.getObjectByName("a") &&
|
||||
!scene.getObjectByName("b").visible &&
|
||||
!scene.getObjectByName("c").visible
|
||||
console.assert( test(), {scene,reason:`objectname: #score=>3 => a = invisible b = visible c = invisible`})
|
||||
|
||||
scene = filterScene("#score*=>1")
|
||||
test = () => !scene.getObjectByName("a").visible &&
|
||||
test = () => !scene.getObjectByName("a") &&
|
||||
scene.getObjectByName("b").visible &&
|
||||
scene.getObjectByName("c").visible
|
||||
console.assert( test(), {scene,reason:`objectname: #score*=>1 => a = invisible b = visible c = visible`})
|
||||
|
|
Loading…
Reference in New Issue