work in progress [might break]
This commit is contained in:
parent
dadb117556
commit
786173a9e0
5 changed files with 127 additions and 54 deletions
Binary file not shown.
85
src/3rd/js/three/util/optimize.js
Normal file
85
src/3rd/js/three/util/optimize.js
Normal 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)
|
||||
})
|
||||
|
|
@ -40,10 +40,11 @@ xrf.frag.src.addModel = (model,url,frag,opts) => {
|
|||
}else{
|
||||
xrf.frag.src.scale( scene, opts, url ) // scale scene
|
||||
mesh.add(scene)
|
||||
xrf.emit('parseModel', {...opts, isSRC:true, scene, model})
|
||||
}
|
||||
// flag everything isSRC & isXRF
|
||||
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) => {
|
||||
|
|
|
|||
|
|
@ -51,25 +51,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
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.isPlaying = t.x !== undefined && t.x != t.y
|
||||
mixer.updateLoop(t)
|
||||
|
|
@ -118,8 +99,6 @@ xrf.addEventListener('parseModel', (opts) => {
|
|||
mixer.update.patched = true
|
||||
}
|
||||
|
||||
mixer.checkZombies( model.animations)
|
||||
|
||||
// calculate total duration/frame based on longest animation
|
||||
mixer.duration = 0
|
||||
if( model.animations.length ){
|
||||
|
|
|
|||
|
|
@ -2,24 +2,23 @@ xrf.frag.uv = function(v, opts){
|
|||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
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)
|
||||
mesh.uv.u = v.floats[0]
|
||||
mesh.uv.v = v.floats[1]
|
||||
mesh.uv.uspeed = v.floats[2] || 1.0
|
||||
mesh.uv.vspeed = v.floats[3] || 1.0
|
||||
mesh.uv.ushift = v.shift[0]
|
||||
mesh.uv.vshift = v.shift[1]
|
||||
mesh.uv.uloop = v.shift[2] || false
|
||||
mesh.uv.vloop = v.shift[3] || false
|
||||
debugger
|
||||
mesh.uv.ushift = v.shift[0] || v.floats[0] < 0 // negative u is always relative
|
||||
mesh.uv.vshift = v.shift[1] || v.floats[1] < 0 // negative v is always relative
|
||||
mesh.uv.uloop = v.shift[2] || false
|
||||
mesh.uv.vloop = v.shift[3] || false
|
||||
|
||||
mesh.onBeforeRender = xrf.frag.uv.scroll
|
||||
}
|
||||
|
||||
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")
|
||||
if( !uv.old ) uv.old = mesh.geometry.getAttribute("uv").clone()
|
||||
|
|
@ -33,34 +32,43 @@ xrf.frag.uv.scroll = function(){
|
|||
|
||||
// translate!
|
||||
for( let i = 0; i < uv.count; i++ ){
|
||||
let u = uv.getX(i)
|
||||
let v = uv.getY(i)
|
||||
let uTarget = (this.uv.ushift ? u : uv.old.getX(i) ) + this.uv.u
|
||||
let vTarget = (this.uv.vshift ? v : uv.old.getY(i) ) + this.uv.v
|
||||
|
||||
// scroll U
|
||||
if( this.uv.uloop ){
|
||||
u += this.uv.uspeed * xrf.clock.delta
|
||||
}else{
|
||||
// recover from super-high uv-values due to looped scrolling
|
||||
if( Math.abs(u-uTarget) > 1.0 ) u = uv.old.getX(i)
|
||||
u = u > uTarget ? u + (this.uv.uspeed * -uTarget ) // -xrf.clock.delta)
|
||||
: u + (this.uv.uspeed * uTarget ) // xrf.clock.delta)
|
||||
diffU += Math.abs( u - uTarget ) // are we done yet? (non-looping mode)
|
||||
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 v = uv.getY(i)
|
||||
let uTarget = this.uv.ushift ? uv.getX(i) + this.uv.u : uv.old.getX(i) + this.uv.u
|
||||
let vTarget = this.uv.vshift ? uv.getY(i) + this.uv.v : uv.old.getY(i) + this.uv.v
|
||||
|
||||
// scroll U
|
||||
if( this.uv.uloop ){
|
||||
u += this.uv.uspeed * xrf.clock.delta
|
||||
}else{
|
||||
// *TODO* tween to offset
|
||||
//// recover from super-high uv-values due to looped scrolling
|
||||
//if( Math.abs(u-uTarget) > 10.0 ) u = uv.old.getX(i)
|
||||
//u = u > uTarget ? u + (this.uv.uspeed * -xrf.clock.delta)
|
||||
// : u + (this.uv.uspeed * xrf.clock.delta)
|
||||
//diffU += Math.abs( u - uTarget ) // are we done yet? (non-looping mode)
|
||||
}
|
||||
|
||||
// scroll V
|
||||
if( this.uv.vloop ){
|
||||
v += this.uv.vspeed * xrf.clock.delta
|
||||
}else{
|
||||
// *TODO* tween to offset
|
||||
//// recover from super-high uv-values due to looped scrolling
|
||||
//// recover from super-high uv-values due to looped scrolling
|
||||
//if( Math.abs(v-vTarget) > 10.0 ) v = uv.old.getY(i)
|
||||
//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)
|
||||
}
|
||||
|
||||
// scroll V
|
||||
if( this.uv.vloop ){
|
||||
v += this.uv.vspeed * xrf.clock.delta
|
||||
}else{
|
||||
// recover from super-high uv-values due to looped scrolling
|
||||
if( Math.abs(v-vTarget) > 1.0 ) v = uv.old.getY(i)
|
||||
v = v > vTarget ? v + (this.uv.vspeed * -vTarget ) // -xrf.clock.delta)
|
||||
: v + (this.uv.vspeed * vTarget ) // xrf.clock.delta)
|
||||
diffV += Math.abs( v - vTarget )
|
||||
|
||||
}
|
||||
uv.setXY(i,u,v)
|
||||
}
|
||||
uv.needsUpdate = true
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue