| import { Vector3 } from '../math/Vector3.js'; |
| import { Object3D } from '../core/Object3D.js'; |
|
|
| |
| |
| |
| |
| |
|
|
| 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 }; |
|
|