177 lines
2.7 KiB
JavaScript
177 lines
2.7 KiB
JavaScript
|
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 };
|