Spaces:
Running
Running
import { Vector3 } from '../math/Vector3.js'; | |
import { Object3D } from '../core/Object3D.js'; | |
/** | |
* @author mikael emtinger / http://gomo.se/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function LOD() { | |
Object3D.call( this ); | |
this.type = 'LOD'; | |
Object.defineProperties( this, { | |
levels: { | |
enumerable: true, | |
value: [] | |
} | |
} ); | |
} | |
LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { | |
constructor: LOD, | |
copy: function ( source ) { | |
Object3D.prototype.copy.call( this, source, false ); | |
var levels = source.levels; | |
for ( var i = 0, l = levels.length; i < l; i ++ ) { | |
var level = levels[ i ]; | |
this.addLevel( level.object.clone(), level.distance ); | |
} | |
return this; | |
}, | |
addLevel: function ( object, distance ) { | |
if ( distance === undefined ) distance = 0; | |
distance = Math.abs( distance ); | |
var levels = this.levels; | |
for ( var l = 0; l < levels.length; l ++ ) { | |
if ( distance < levels[ l ].distance ) { | |
break; | |
} | |
} | |
levels.splice( l, 0, { distance: distance, object: object } ); | |
this.add( object ); | |
}, | |
getObjectForDistance: function ( distance ) { | |
var levels = this.levels; | |
for ( var i = 1, l = levels.length; i < l; i ++ ) { | |
if ( distance < levels[ i ].distance ) { | |
break; | |
} | |
} | |
return levels[ i - 1 ].object; | |
}, | |
raycast: ( function () { | |
var matrixPosition = new Vector3(); | |
return function raycast( raycaster, intersects ) { | |
matrixPosition.setFromMatrixPosition( this.matrixWorld ); | |
var distance = raycaster.ray.origin.distanceTo( matrixPosition ); | |
this.getObjectForDistance( distance ).raycast( raycaster, intersects ); | |
}; | |
}() ), | |
update: function () { | |
var v1 = new Vector3(); | |
var v2 = new Vector3(); | |
return function update( camera ) { | |
var levels = this.levels; | |
if ( levels.length > 1 ) { | |
v1.setFromMatrixPosition( camera.matrixWorld ); | |
v2.setFromMatrixPosition( this.matrixWorld ); | |
var distance = v1.distanceTo( v2 ); | |
levels[ 0 ].object.visible = true; | |
for ( var i = 1, l = levels.length; i < l; i ++ ) { | |
if ( distance >= levels[ i ].distance ) { | |
levels[ i - 1 ].object.visible = false; | |
levels[ i ].object.visible = true; | |
} else { | |
break; | |
} | |
} | |
for ( ; i < l; i ++ ) { | |
levels[ i ].object.visible = false; | |
} | |
} | |
}; | |
}(), | |
toJSON: function ( meta ) { | |
var data = Object3D.prototype.toJSON.call( this, meta ); | |
data.object.levels = []; | |
var levels = this.levels; | |
for ( var i = 0, l = levels.length; i < l; i ++ ) { | |
var level = levels[ i ]; | |
data.object.levels.push( { | |
object: level.object.uuid, | |
distance: level.distance | |
} ); | |
} | |
return data; | |
} | |
} ); | |
export { LOD }; | |