import { Vector3 } from '../math/Vector3.js'; import { Object3D } from '../core/Object3D.js'; const _v1 = /*@__PURE__*/ new Vector3(); const _v2 = /*@__PURE__*/ new Vector3(); class LOD extends Object3D { constructor() { super(); this._currentLevel = 0; this.type = 'LOD'; Object.defineProperties(this, { levels: { enumerable: true, value: [], }, isLOD: { value: true, }, }); this.autoUpdate = true; } copy(source) { super.copy(source, false); const levels = source.levels; for (let i = 0, l = levels.length; i < l; i++) { const level = levels[i]; this.addLevel(level.object.clone(), level.distance); } this.autoUpdate = source.autoUpdate; return this; } addLevel(object, distance = 0) { distance = Math.abs(distance); const levels = this.levels; let l; for (l = 0; l < levels.length; l++) { if (distance < levels[l].distance) { break; } } levels.splice(l, 0, { distance: distance, object: object }); this.add(object); return this; } getCurrentLevel() { return this._currentLevel; } getObjectForDistance(distance) { const levels = this.levels; if (levels.length > 0) { let i, l; for (i = 1, l = levels.length; i < l; i++) { if (distance < levels[i].distance) { break; } } return levels[i - 1].object; } return null; } raycast(raycaster, intersects) { const levels = this.levels; if (levels.length > 0) { _v1.setFromMatrixPosition(this.matrixWorld); const distance = raycaster.ray.origin.distanceTo(_v1); this.getObjectForDistance(distance).raycast(raycaster, intersects); } } update(camera) { const levels = this.levels; if (levels.length > 1) { _v1.setFromMatrixPosition(camera.matrixWorld); _v2.setFromMatrixPosition(this.matrixWorld); const distance = _v1.distanceTo(_v2) / camera.zoom; levels[0].object.visible = true; let i, l; for (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; } } this._currentLevel = i - 1; for (; i < l; i++) { levels[i].object.visible = false; } } } toJSON(meta) { const data = super.toJSON(meta); if (this.autoUpdate === false) data.object.autoUpdate = false; data.object.levels = []; const levels = this.levels; for (let i = 0, l = levels.length; i < l; i++) { const level = levels[i]; data.object.levels.push({ object: level.object.uuid, distance: level.distance, }); } return data; } } export { LOD };