bugfix: recursive animation works

This commit is contained in:
Leon van Kammen 2023-11-17 16:34:11 +01:00
parent 7162621efe
commit 0bbf3ae5e4
4 changed files with 86 additions and 81 deletions

Binary file not shown.

View file

@ -4,6 +4,7 @@ xrf.frag.t = function(v, opts){
if( !model.animations || model.animations[0] == undefined ) return console.warn('no animation in scene') if( !model.animations || model.animations[0] == undefined ) return console.warn('no animation in scene')
xrf.mixers.map ( (mixer) => { xrf.mixers.map ( (mixer) => {
mixer.t = v mixer.t = v
// update speed // update speed
@ -27,22 +28,26 @@ xrf.addEventListener('parseModel', (opts) => {
let {model} = opts let {model} = opts
let mixer = model.mixer = new xrf.THREE.AnimationMixer(model.scene) let mixer = model.mixer = new xrf.THREE.AnimationMixer(model.scene)
mixer.model = model mixer.model = model
mixer.loop = {} mixer.loop = {timeStart:0,timeStop:0}
mixer.i = xrf.mixers.length mixer.i = xrf.mixers.length
mixer.actions = []
model.animations.map( (anim) => { model.animations.map( (anim) => {
anim.action = mixer.clipAction( anim, model.scene ) anim.optimize()
mixer.actions.push( mixer.clipAction( anim, model.scene ) )
}) })
mixer.checkZombies = (animations) => { mixer.checkZombies = (animations) => {
if( mixer.zombieCheck ) return // fire only once if( mixer.zombieCheck ) return // fire only once
animations.map( (anim) => { animations.map( (anim) => {
// collect zombie animations and warn user // collect zombie animations and warn user
let zombies = anim.tracks.map( (t) => { let zombies = anim.tracks.map( (t) => {
let name = t.name.replace(/\..*/,'') let name = t.name.replace(/\..*/,'')
return !model.scene.getObjectByName(name) ? {anim:anim.name,obj:t.name} : undefined let obj = model.scene.getObjectByName(name)
return !model.scene.getObjectByName(name) ? {anim:anim.name,obj:name} : undefined
}) })
if( zombies.length > 0 ){ if( zombies.length > 0 && mixer.i == 0 ){ // only warn for zombies in main scene (because src-scenes might be filtered anyways)
zombies zombies
.filter( (z) => z ) // filter out undefined .filter( (z) => z ) // filter out undefined
.map( (z) => console.warn(`gltf: object '${z.obj}' not found (anim: '${z.anim}'`) ) .map( (z) => console.warn(`gltf: object '${z.obj}' not found (anim: '${z.anim}'`) )
@ -65,15 +70,15 @@ xrf.addEventListener('parseModel', (opts) => {
mixer.updateLoop = (t) => { mixer.updateLoop = (t) => {
mixer.loop.timeStart = t.y != undefined ? t.y : mixer.loop.timeStart mixer.loop.timeStart = t.y != undefined ? t.y : mixer.loop.timeStart
mixer.loop.timeStop = t.z != undefined ? t.z : mixer.loop.timeStop mixer.loop.timeStop = t.z != undefined ? t.z : mixer.loop.timeStop
mixer.model.animations.map( (anim) => { mixer.actions.map( (action) => {
if( mixer.loop.timeStart != undefined ){ if( mixer.loop.timeStart != undefined ){
//if( anim.action ) delete anim.action action.time = mixer.loop.timeStart
//anim.action = mixer.clipAction( anim ) action.setLoop( THREE.LoopOnce, )
anim.action.time = mixer.loop.timeStart action.timeScale = mixer.timeScale
anim.action.setLoop( THREE.LoopOnce, ) action.enabled = true
anim.action.timeScale = mixer.timeScale if( t.x != 0 ){
anim.action.enabled = true action.play()
if( t.x != 0 ) anim.action.play() }
} }
}) })
mixer.setTime(mixer.loop.timeStart) mixer.setTime(mixer.loop.timeStart)
@ -90,7 +95,7 @@ xrf.addEventListener('parseModel', (opts) => {
if( time == 0 ) return update.call(this,time) if( time == 0 ) return update.call(this,time)
// loop jump // loop jump
if( mixer.loop.speed > 0.0 && mixer.time > mixer.loop.timeStop ){ if( mixer.loop.speed > 0.0 && (mixer.loop.timeStop > 0 && mixer.time > mixer.loop.timeStop) ){
setTimeout( (time,anims) => mixer.updateLoop(time), 0, mixer.loop.timeStart ) // prevent recursion setTimeout( (time,anims) => mixer.updateLoop(time), 0, mixer.loop.timeStart ) // prevent recursion
} }
return update.call( this, time ) return update.call( this, time )

View file

@ -1,4 +1,4 @@
// test the XR Fragments parser-filters with THREEjs scenes // test the XR Fragments parser-filters with THREEjs scns
THREE = AFRAME.THREE THREE = AFRAME.THREE
createScene = (noadd) => { createScene = (noadd) => {
@ -6,6 +6,7 @@ createScene = (noadd) => {
for ( let i in obj ){ for ( let i in obj ){
obj[i] = new THREE.Object3D() obj[i] = new THREE.Object3D()
obj[i].name = i obj[i].name = i
obj[i].material = {visible:true, clone: () => ({visible:true}) }
} }
let {a,b,c} = obj let {a,b,c} = obj
let scene = new THREE.Scene() let scene = new THREE.Scene()
@ -15,6 +16,11 @@ createScene = (noadd) => {
scene.add(a) scene.add(a)
} }
b.userData.score = 2 b.userData.score = 2
b.userData.tag = "foo bar"
c.userData.tag = "flop flap"
a.userData.price = 1
b.userData.price = 5
c.userData.price = 10
return {a,b,c,scene} return {a,b,c,scene}
} }
@ -22,84 +28,78 @@ filterScene = (URI) => {
frag = xrf.URI.parse(URI) frag = xrf.URI.parse(URI)
var {a,b,c,scene} = createScene() var {a,b,c,scene} = createScene()
xrf.filter.scene({scene,frag}) xrf.filter.scene({scene,frag})
scene.visible = (objname, expected, checkMaterial) => {
let o = scene.getObjectByName(objname)
if( !o ) return false === expected
let is = checkMaterial ? o.material.visible : o.visible
if( is !== expected ) console.dir(o)
return is === expected
}
return scene return scene
} }
scene = filterScene("#b") scn = filterScene("#b")
test = () => !scene.getObjectByName("a") && test = () => !scn.visible("a") && scn.visible("b",true) && scn.visible("c",true)
scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`objectname: #b `})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #b => a = removed b = visible c = removed`})
scene = filterScene("#b*") scn = filterScene("#-b")
test = () => !scene.getObjectByName("a") && test = () => scn.visible("a",true) && scn.visible("b",false) && scn.visible("c",false)
scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`objectname: #-b `})
scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #b* => a = removed b = visible c = visible`})
scene = filterScene("#-b") scn = filterScene("#a&-b")
test = () => scene.getObjectByName("a").visible && test = () => scn.visible("a",true) && scn.visible("b",false) && scn.visible("c",false)
!scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`objectname: #a&-b `})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #-b => a = visible b = invisible c = invisible`})
scene = filterScene("#a&-b") scn = filterScene("#-b&b")
test = () => scene.getObjectByName("a").visible && test = () => scn.visible("a",false) && scn.visible("b",true) && scn.visible("c",true)
!scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`objectname: #-b&b `})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #a&-b => a = visible b = invisible c = invisible`})
scene = filterScene("#-b&b") scn = filterScene("#-c")
test = () => !scene.getObjectByName("a") && test = () => scn.visible("a",true) && scn.visible("b",true) && scn.visible("c",false)
scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`objectname: #-c `})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #-b&b => a = removed b = invisible c = invisible (last duplicate wins)`})
scene = filterScene("#-c") scn = filterScene("#score")
test = () => scene.getObjectByName("a").visible && test = () => scn.visible("a",true) && scn.visible("b",true) && scn.visible("c",true)
scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`propertyfilter: #score `})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #-b&b => a = visible b = visible c = invisible`})
scene = filterScene("#-b*") scn = filterScene("#score=>1")
test = () => scene.getObjectByName("a").visible && test = () => scn.visible("a",true) && scn.visible("b",true) && scn.visible("c",true)
!scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`propertyfilter: #score`})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #-b&b => a = visible b = visible c = invisible`})
scene = filterScene("#score") scn = filterScene("#score=2")
console.dir(scene) test = () => scn.visible("a",true) && scn.visible("b",true) && scn.visible("c",true)
test = () => !scene.getObjectByName("a") && console.assert( test(), {scn,reason:`propertyfilter: #score`})
scene.getObjectByName("b").visible &&
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #score => a = removed b = visible c = invisible`})
scene = filterScene("#score=>1") scn = filterScene("#score=>3")
test = () => !scene.getObjectByName("a") && test = () => scn.visible("a",true) && scn.visible("b",false) && scn.visible("c",false)
scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`propertyfilter: #score`})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #score=>1 => a = removed b = visible c = invisible`})
scene = filterScene("#score=>3") scn = filterScene("#-score=>1")
test = () => !scene.getObjectByName("a") && test = () => scn.visible("a",true) && scn.visible("b",false) && scn.visible("c",false)
!scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`propertyfilter: #-score`})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #score=>3 => a = invisible b = visible c = invisible`})
scene = filterScene("#score*=>1") scn = filterScene("#-score=>1&c")
test = () => !scene.getObjectByName("a") && test = () => scn.visible("a",true) && scn.visible("b",true) && scn.visible("b",false,true) && scn.visible("c",true)
scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`propertyfilter: #-score`})
scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #score*=>1 => a = invisible b = visible c = visible`})
scene = filterScene("#-score*=>1") scn = filterScene("#-foo")
test = () => scene.getObjectByName("a").visible && test = () => scn.visible("a",true) && scn.visible("b",false) && scn.visible("b",false)
!scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`tagfilter: #-foo `})
!scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #-score*=>1 => a = visible b = invisible c = invisible`})
scene = filterScene("#-score*=>1&c") scn = filterScene("#-c&flop")
test = () => scene.getObjectByName("a").visible && test = () => scn.visible("a",true) && scn.visible("b",true) && scn.visible("c",true)
!scene.getObjectByName("b").visible && console.assert( test(), {scn,reason:`tagfilter: #-c&flop`})
scene.getObjectByName("c").visible
console.assert( test(), {scene,reason:`objectname: #-score*=>1 => a = visible b = invisible c = visible`}) scn = filterScene("#-b&-foo&bar&flop")
test = () => scn.visible("a",true) && scn.visible("b",true) && scn.visible("c",true)
console.assert( test(), {scn,reason:`tagfilter: #-b&-foo&bar&flop`})
scn = filterScene("#-b&-foo&bar&flop&-bar&flop")
test = () => scn.visible("a",true) && scn.visible("b",false,true) && scn.visible("c",true)
console.assert( test(), {scn,reason:`tagfilter: #-b&-foo&bar&flop&-bar&flop"`})
scn = filterScene("#-price&price=>4")
test = () => scn.visible("a",false,true) && scn.visible("b",true) && scn.visible("c",true)
console.assert( test(), {scn,reason:`tagfilter: #-price&price=>4"`})

View file

@ -8,7 +8,7 @@
console.assert = ((assert) => (a,b) => { console.assert = ((assert) => (a,b) => {
console.log('♥ test: '+b.reason) console.log("\x1b[34m♥ \x1b[36;49mtest: "+b.reason+"\x1B[m")
assert.call( console, a, b ) assert.call( console, a, b )
})(console.assert) })(console.assert)