improving boundingbox scaling by hiding invisible objects
This commit is contained in:
parent
7e656a02f0
commit
211652fa5e
5 changed files with 37 additions and 54 deletions
Binary file not shown.
|
|
@ -13,6 +13,8 @@ xrf.filter.scene = function(opts){
|
||||||
.sort(frag) // get (sorted) filters from XR Fragments
|
.sort(frag) // get (sorted) filters from XR Fragments
|
||||||
.process(frag,scene) // show/hide things
|
.process(frag,scene) // show/hide things
|
||||||
|
|
||||||
|
scene.visible = true // always enable scene
|
||||||
|
|
||||||
return scene
|
return scene
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,22 +27,27 @@ xrf.filter.sort = function(frag){
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf.filter.process = function(frag,scene,opts){
|
xrf.filter.process = function(frag,scene,opts){
|
||||||
// include all when query starts with negative objectnames/tags are included
|
const hasName = (m,name,filter) => m.name == name
|
||||||
let firstFilter = frag.filters[0].filter.get()
|
const hasNameOrTag = (m,name_or_tag,filter) => hasName(m,name_or_tag) || m.userData[filter.key]
|
||||||
let showAll = firstFilter.show === false
|
const cleanupKey = (k) => k.replace(/[-\*]/g,'')
|
||||||
let showers = frag.filters.filter( (v) => v.filter.get().show === true )
|
|
||||||
if( !showAll ) scene.traverse( (n) => n.visible = false )
|
|
||||||
|
|
||||||
// reparent if first selector is positive and has no value
|
let firstFilter = frag.filters[0].filter.get()
|
||||||
if( firstFilter.show === true ){
|
let showers = frag.filters.filter( (v) => v.filter.get().show === true )
|
||||||
let obj = scene.getObjectByName( firstFilter.key )
|
|
||||||
while( scene.children.length > 0 ) scene.children[0].removeFromParent()
|
// reparent scene based on object in case it matches a primary (non-negating) selector
|
||||||
if(obj) scene.add(obj)
|
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) => {
|
frag.filters.map( (v) => {
|
||||||
const filter = v.filter.get()
|
const filter = v.filter.get()
|
||||||
const name_or_tag = v.fragment.replace(/[-\*]/g,'')
|
const name_or_tag = cleanupKey(v.fragment)
|
||||||
let seen = {}
|
let seen = {}
|
||||||
|
|
||||||
const setVisibleUnseen = (m,visible) => {
|
const setVisibleUnseen = (m,visible) => {
|
||||||
|
|
@ -50,7 +57,6 @@ xrf.filter.process = function(frag,scene,opts){
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.traverse( (m) => {
|
scene.traverse( (m) => {
|
||||||
const isMatch = m.name == name_or_tag || m.userData[filter.key]
|
|
||||||
|
|
||||||
// filter on value(expression) #foo=>3 e.g.
|
// filter on value(expression) #foo=>3 e.g.
|
||||||
if( filter.value && m.userData[filter.key] ){
|
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.)
|
// 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
|
m.visible = filter.show
|
||||||
if( filter.deep ) m.traverse( (n) => n.visible = m.visible )
|
if( filter.deep ) m.traverse( (n) => n.visible = m.visible )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return xrf.filter
|
return xrf.filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ xrf.frag.src = function(v, opts){
|
||||||
mesh.add(model.scene)
|
mesh.add(model.scene)
|
||||||
mesh.traverse( (n) => n.isSRC = n.isXRF = true ) // mark everything SRC
|
mesh.traverse( (n) => n.isSRC = n.isXRF = true ) // mark everything SRC
|
||||||
xrf.emit('parseModel', {...opts, scene, model})
|
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) => {
|
const enableSourcePortation = (src) => {
|
||||||
|
|
@ -93,6 +93,13 @@ xrf.frag.src.eval = function(scene, opts, url){
|
||||||
xrf.frag.src.scale = function(scene, opts, url){
|
xrf.frag.src.scale = function(scene, opts, url){
|
||||||
let { mesh, model, camera, renderer, THREE} = opts
|
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
|
let restrictTo3DBoundingBox = mesh.geometry
|
||||||
if( restrictTo3DBoundingBox ){
|
if( restrictTo3DBoundingBox ){
|
||||||
// spec 3 of https://xrfragment.org/#src
|
// spec 3 of https://xrfragment.org/#src
|
||||||
|
|
@ -100,23 +107,11 @@ xrf.frag.src.scale = function(scene, opts, url){
|
||||||
// normalize instanced objectsize to boundingbox
|
// normalize instanced objectsize to boundingbox
|
||||||
let sizeFrom = new THREE.Vector3()
|
let sizeFrom = new THREE.Vector3()
|
||||||
let sizeTo = new THREE.Vector3()
|
let sizeTo = new THREE.Vector3()
|
||||||
|
|
||||||
let empty = new THREE.Object3D()
|
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(mesh).getSize(sizeTo)
|
||||||
new THREE.Box3().setFromObject(scene).getSize(sizeFrom)
|
new THREE.Box3().setFromObject(cleanScene).getSize(sizeFrom)
|
||||||
let ratio = sizeFrom.divide(sizeTo)
|
let ratio = sizeFrom.divide(sizeTo)
|
||||||
scene.scale.multiplyScalar( 1.0 / Math.max(ratio.x, ratio.y, ratio.z));
|
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{
|
}else{
|
||||||
// spec 4 of https://xrfragment.org/#src
|
// spec 4 of https://xrfragment.org/#src
|
||||||
// spec 2 of https://xrfragment.org/#scaling%20of%20instanced%20objects
|
// 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})
|
xrf.filter.scene({scene,frag})
|
||||||
if( scene.children.length == 1 ) scene.children[0].position.set(0,0,0)
|
if( scene.children.length == 1 ) scene.children[0].position.set(0,0,0)
|
||||||
|
|
||||||
/*
|
scene.traverse( (m) => {
|
||||||
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) => {
|
|
||||||
if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion
|
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
|
hashbus.pub.mesh(m,{scene,recursive:true}) // cool idea: recursion-depth based distance between face & src
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
return scene
|
return scene
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
||||||
mesh.material = mat
|
mesh.material = mat
|
||||||
// set range
|
// set range
|
||||||
video.addEventListener('timeupdate', function timeupdate() {
|
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
|
vid.currentTime = video.t.y
|
||||||
}
|
}
|
||||||
},false)
|
},false)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ filterScene = (URI) => {
|
||||||
scene = filterScene("#b")
|
scene = filterScene("#b")
|
||||||
test = () => !scene.getObjectByName("a") &&
|
test = () => !scene.getObjectByName("a") &&
|
||||||
scene.getObjectByName("b").visible &&
|
scene.getObjectByName("b").visible &&
|
||||||
!scene.getObjectByName("c")
|
!scene.getObjectByName("c").visible
|
||||||
console.assert( test(), {scene,reason:`objectname: #b => a = removed b = visible c = removed`})
|
console.assert( test(), {scene,reason:`objectname: #b => a = removed b = visible c = removed`})
|
||||||
|
|
||||||
scene = filterScene("#b*")
|
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`})
|
console.assert( test(), {scene,reason:`objectname: #-b&b => a = visible b = visible c = invisible`})
|
||||||
|
|
||||||
scene = filterScene("#score")
|
scene = filterScene("#score")
|
||||||
|
console.dir(scene)
|
||||||
test = () => !scene.getObjectByName("a") &&
|
test = () => !scene.getObjectByName("a") &&
|
||||||
scene.getObjectByName("b").visible &&
|
scene.getObjectByName("b").visible &&
|
||||||
!scene.getObjectByName("c").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`})
|
console.assert( test(), {scene,reason:`objectname: #score=>1 => a = removed b = visible c = invisible`})
|
||||||
|
|
||||||
scene = filterScene("#score=>3")
|
scene = filterScene("#score=>3")
|
||||||
test = () => !scene.getObjectByName("a").visible &&
|
test = () => !scene.getObjectByName("a") &&
|
||||||
!scene.getObjectByName("b").visible &&
|
!scene.getObjectByName("b").visible &&
|
||||||
!scene.getObjectByName("c").visible
|
!scene.getObjectByName("c").visible
|
||||||
console.assert( test(), {scene,reason:`objectname: #score=>3 => a = invisible b = visible c = invisible`})
|
console.assert( test(), {scene,reason:`objectname: #score=>3 => a = invisible b = visible c = invisible`})
|
||||||
|
|
||||||
scene = filterScene("#score*=>1")
|
scene = filterScene("#score*=>1")
|
||||||
test = () => !scene.getObjectByName("a").visible &&
|
test = () => !scene.getObjectByName("a") &&
|
||||||
scene.getObjectByName("b").visible &&
|
scene.getObjectByName("b").visible &&
|
||||||
scene.getObjectByName("c").visible
|
scene.getObjectByName("c").visible
|
||||||
console.assert( test(), {scene,reason:`objectname: #score*=>1 => a = invisible b = visible c = visible`})
|
console.assert( test(), {scene,reason:`objectname: #score*=>1 => a = invisible b = visible c = visible`})
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue