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{
|
}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) => {
|
||||||
|
|
|
||||||
|
|
@ -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 ){
|
||||||
|
|
|
||||||
|
|
@ -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,34 +32,43 @@ xrf.frag.uv.scroll = function(){
|
||||||
|
|
||||||
// translate!
|
// translate!
|
||||||
for( let i = 0; i < uv.count; i++ ){
|
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.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.uloop ){
|
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 )
|
||||||
u += this.uv.uspeed * xrf.clock.delta
|
|
||||||
}else{
|
if( this.uv.uloop || this.uv.vloop ){
|
||||||
// recover from super-high uv-values due to looped scrolling
|
let u = uv.getX(i)
|
||||||
if( Math.abs(u-uTarget) > 1.0 ) u = uv.old.getX(i)
|
let v = uv.getY(i)
|
||||||
u = u > uTarget ? u + (this.uv.uspeed * -uTarget ) // -xrf.clock.delta)
|
let uTarget = this.uv.ushift ? uv.getX(i) + this.uv.u : uv.old.getX(i) + this.uv.u
|
||||||
: u + (this.uv.uspeed * uTarget ) // xrf.clock.delta)
|
let vTarget = this.uv.vshift ? uv.getY(i) + this.uv.v : uv.old.getY(i) + this.uv.v
|
||||||
diffU += Math.abs( u - uTarget ) // are we done yet? (non-looping mode)
|
|
||||||
|
// 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
|
uv.needsUpdate = true
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue