work in progress [might break]

This commit is contained in:
Leon van Kammen 2024-02-15 10:58:09 +00:00
parent dadb117556
commit 786173a9e0
5 changed files with 127 additions and 54 deletions

Binary file not shown.

View file

@ -0,0 +1,85 @@
xrf.optimize = (opts) => {
opts.animatedObjects = []
xrf.optimize
.checkAnimations(opts)
.freezeUnAnimatedObjects(opts)
.disableShadows(opts)
.disableEmbeddedLights(opts)
.removeDuplicateLights()
}
// check unused animations
xrf.optimize.checkAnimations = (opts) => {
console.log("TODO: fix freezeUnAnimatedObjects for SRC's")
return xrf.optimize
let {model} = opts
model.animations.map( (anim) => {
// collect zombie animations and warn user
let zombies = anim.tracks.map( (t) => {
let name = t.name.replace(/\..*/,'')
let obj = model.scene.getObjectByName(name)
if( !model.scene.getObjectByName(name) ) return {anim:anim.name,obj:name}
else opts.animatedObjects.push(name)
return undefined
})
if( zombies.length > 0 ){ // only warn for zombies in main scene (because src-scenes might be filtered anyways)
zombies
.filter( (z) => z ) // filter out undefined
.map( (z) => console.warn(`gltf: object '${z.obj}' not found (anim: '${z.anim}'`) )
console.warn(`TIP: remove dots in objectnames in blender (which adds dots when duplicating)`)
}
})
return xrf.optimize
}
xrf.optimize.freezeUnAnimatedObjects = (opts) => {
console.log("TODO: fix freezeUnAnimatedObjects for SRC's")
return xrf.optimize
let {model} = opts
let scene = model.scene
// increase performance by freezing all objects
scene.traverse( (n) => n.matrixAutoUpdate = false )
// except animated objects and children
scene.traverse( (n) => {
if( ~opts.animatedObjects.indexOf(n.name) ){
n.matrixAutoUpdate = true
n.traverse( (m) => m.matrixAutoUpdate = true )
}
})
return xrf.optimize
}
xrf.optimize.disableShadows = (opts) => {
opts.model.scene.traverse( (n) => {
if( n.castShadow !== undefined ) n.castShadow = false
})
return xrf.optimize
}
xrf.optimize.disableEmbeddedLights = (opts) => {
if( !opts.isSRC ) return xrf.optimize
// remove lights from SRC's
opts.model.scene.traverse( (n) => {
if( n.type.match(/light/i) ) n.remove()
})
return xrf.optimize
}
xrf.optimize.removeDuplicateLights = () => {
// local/extern src's can cause duplicate lights which tax performance
let lights = {}
xrf.scene.traverse( (n) => {
if( n.type.match(/light/i) ){
if( !lights[n.name] ) lights[n.name] = true
else n.remove()
}
})
return xrf.optimize
}
xrf.addEventListener('parseModel', (opts) => {
xrf.optimize(opts)
})

View file

@ -40,10 +40,11 @@ xrf.frag.src.addModel = (model,url,frag,opts) => {
}else{ }else{
xrf.frag.src.scale( scene, opts, url ) // scale scene xrf.frag.src.scale( scene, opts, url ) // scale scene
mesh.add(scene) mesh.add(scene)
xrf.emit('parseModel', {...opts, isSRC:true, scene, model})
} }
// flag everything isSRC & isXRF // flag everything isSRC & isXRF
mesh.traverse( (n) => { n.isSRC = n.isXRF = n[ opts.isLocal ? 'isSRCLocal' : 'isSRCExternal' ] = true }) mesh.traverse( (n) => { n.isSRC = n.isXRF = n[ opts.isLocal ? 'isSRCLocal' : 'isSRCExternal' ] = true })
xrf.emit('parseModel', {...opts, isSRC:true, scene, model})
} }
xrf.frag.src.renderAsPortal = (mesh) => { xrf.frag.src.renderAsPortal = (mesh) => {

View file

@ -51,25 +51,6 @@ xrf.addEventListener('parseModel', (opts) => {
mixer.actions.push( mixer.clipAction( anim, model.scene ) ) mixer.actions.push( mixer.clipAction( anim, model.scene ) )
}) })
mixer.checkZombies = (animations) => {
if( mixer.zombieCheck ) return // fire only once
animations.map( (anim) => {
// collect zombie animations and warn user
let zombies = anim.tracks.map( (t) => {
let name = t.name.replace(/\..*/,'')
let obj = model.scene.getObjectByName(name)
return !model.scene.getObjectByName(name) ? {anim:anim.name,obj:name} : undefined
})
if( zombies.length > 0 && mixer.i == 0 ){ // only warn for zombies in main scene (because src-scenes might be filtered anyways)
zombies
.filter( (z) => z ) // filter out undefined
.map( (z) => console.warn(`gltf: object '${z.obj}' not found (anim: '${z.anim}'`) )
console.warn(`TIP: remove dots in objectnames in blender (which adds dots when duplicating)`)
}
})
mixer.zombieCheck = true
}
mixer.play = (t) => { mixer.play = (t) => {
mixer.isPlaying = t.x !== undefined && t.x != t.y mixer.isPlaying = t.x !== undefined && t.x != t.y
mixer.updateLoop(t) mixer.updateLoop(t)
@ -118,8 +99,6 @@ xrf.addEventListener('parseModel', (opts) => {
mixer.update.patched = true mixer.update.patched = true
} }
mixer.checkZombies( model.animations)
// calculate total duration/frame based on longest animation // calculate total duration/frame based on longest animation
mixer.duration = 0 mixer.duration = 0
if( model.animations.length ){ if( model.animations.length ){

View file

@ -2,24 +2,23 @@ xrf.frag.uv = function(v, opts){
let { frag, mesh, model, camera, scene, renderer, THREE} = opts let { frag, mesh, model, camera, scene, renderer, THREE} = opts
if( !mesh.geometry ) return // nothing to do here if( !mesh.geometry ) return // nothing to do here
if( v.floats.length < 2 ) return console.warn('xrfragment.js: got less than 4 uv values ') if( v.floats.length != 4 ) return console.warn('xrfragment.js: got less than 4 uv values ')
xrf.frag.uv.init(mesh) xrf.frag.uv.init(mesh)
mesh.uv.u = v.floats[0] mesh.uv.u = v.floats[0]
mesh.uv.v = v.floats[1] mesh.uv.v = v.floats[1]
mesh.uv.uspeed = v.floats[2] || 1.0 mesh.uv.uspeed = v.floats[2] || 1.0
mesh.uv.vspeed = v.floats[3] || 1.0 mesh.uv.vspeed = v.floats[3] || 1.0
mesh.uv.ushift = v.shift[0] mesh.uv.ushift = v.shift[0] || v.floats[0] < 0 // negative u is always relative
mesh.uv.vshift = v.shift[1] mesh.uv.vshift = v.shift[1] || v.floats[1] < 0 // negative v is always relative
mesh.uv.uloop = v.shift[2] || false mesh.uv.uloop = v.shift[2] || false
mesh.uv.vloop = v.shift[3] || false mesh.uv.vloop = v.shift[3] || false
debugger
mesh.onBeforeRender = xrf.frag.uv.scroll mesh.onBeforeRender = xrf.frag.uv.scroll
} }
xrf.frag.uv.init = function(mesh){ xrf.frag.uv.init = function(mesh){
if( !mesh.uv ) mesh.uv = {u:0, v:0, uspeed:1, vspeed:1, uloop:false, vloop:false, uv:false, ushift:false,vshift:false} if( !mesh.uv ) mesh.uv = {u:0, v:0, uspeed:1, vspeed:1, uloop:false, vloop:false, uv:false}
let uv = mesh.geometry.getAttribute("uv") let uv = mesh.geometry.getAttribute("uv")
if( !uv.old ) uv.old = mesh.geometry.getAttribute("uv").clone() if( !uv.old ) uv.old = mesh.geometry.getAttribute("uv").clone()
@ -33,35 +32,44 @@ xrf.frag.uv.scroll = function(){
// translate! // translate!
for( let i = 0; i < uv.count; i++ ){ for( let i = 0; i < uv.count; i++ ){
if( this.uv.uspeed == 1.0 ) uv.setX(i, this.uv.ushift ? uv.getX(i) + this.uv.u : uv.old.getX(i) + this.uv.u )
if( this.uv.vspeed == 1.0 ) uv.setY(i, this.uv.vshift ? uv.getY(i) + this.uv.v : uv.old.getY(i) + this.uv.v )
if( this.uv.uloop || this.uv.vloop ){
let u = uv.getX(i) let u = uv.getX(i)
let v = uv.getY(i) let v = uv.getY(i)
let uTarget = (this.uv.ushift ? u : uv.old.getX(i) ) + this.uv.u let uTarget = this.uv.ushift ? uv.getX(i) + this.uv.u : uv.old.getX(i) + this.uv.u
let vTarget = (this.uv.vshift ? v : uv.old.getY(i) ) + this.uv.v let vTarget = this.uv.vshift ? uv.getY(i) + this.uv.v : uv.old.getY(i) + this.uv.v
// scroll U // scroll U
if( this.uv.uloop ){ if( this.uv.uloop ){
u += this.uv.uspeed * xrf.clock.delta u += this.uv.uspeed * xrf.clock.delta
}else{ }else{
// recover from super-high uv-values due to looped scrolling // *TODO* tween to offset
if( Math.abs(u-uTarget) > 1.0 ) u = uv.old.getX(i) //// recover from super-high uv-values due to looped scrolling
u = u > uTarget ? u + (this.uv.uspeed * -uTarget ) // -xrf.clock.delta) //if( Math.abs(u-uTarget) > 10.0 ) u = uv.old.getX(i)
: u + (this.uv.uspeed * uTarget ) // xrf.clock.delta) //u = u > uTarget ? u + (this.uv.uspeed * -xrf.clock.delta)
diffU += Math.abs( u - uTarget ) // are we done yet? (non-looping mode) // : u + (this.uv.uspeed * xrf.clock.delta)
//diffU += Math.abs( u - uTarget ) // are we done yet? (non-looping mode)
} }
// scroll V // scroll V
if( this.uv.vloop ){ if( this.uv.vloop ){
v += this.uv.vspeed * xrf.clock.delta v += this.uv.vspeed * xrf.clock.delta
}else{ }else{
// recover from super-high uv-values due to looped scrolling // *TODO* tween to offset
if( Math.abs(v-vTarget) > 1.0 ) v = uv.old.getY(i) //// recover from super-high uv-values due to looped scrolling
v = v > vTarget ? v + (this.uv.vspeed * -vTarget ) // -xrf.clock.delta) //// recover from super-high uv-values due to looped scrolling
: v + (this.uv.vspeed * vTarget ) // xrf.clock.delta) //if( Math.abs(v-vTarget) > 10.0 ) v = uv.old.getY(i)
diffV += Math.abs( v - vTarget ) //v = v > vTarget ? v + (this.uv.vspeed * -xrf.clock.delta)
// : v + (this.uv.vspeed * xrf.clock.delta)
//diffV += Math.abs( v - vTarget )
} }
uv.setXY(i,u,v) uv.setXY(i,u,v)
} }
}
uv.needsUpdate = true uv.needsUpdate = true
if( (!this.uv.uloop && diffU < 0.05) && if( (!this.uv.uloop && diffU < 0.05) &&