UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

153 lines • 5.86 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { LOD as ThreeLOD, Object3D, Vector3 } from "three"; import { serializable } from "../engine/engine_serialization_decorator.js"; import { getParam } from "../engine/engine_utils.js"; import { Behaviour } from "./Component.js"; import { Renderer } from "./Renderer.js"; const debug = getParam("debuglods"); const noLods = getParam("nolods"); var LODFadeMode; (function (LODFadeMode) { LODFadeMode[LODFadeMode["None"] = 0] = "None"; LODFadeMode[LODFadeMode["CrossFade"] = 1] = "CrossFade"; LODFadeMode[LODFadeMode["SpeedTree"] = 2] = "SpeedTree"; })(LODFadeMode || (LODFadeMode = {})); export class LODModel { screenRelativeTransitionHeight; distance; renderers; } __decorate([ serializable() ], LODModel.prototype, "screenRelativeTransitionHeight", void 0); __decorate([ serializable() ], LODModel.prototype, "distance", void 0); __decorate([ serializable(Renderer) ], LODModel.prototype, "renderers", void 0); class LOD { model; get renderers() { return this.model.renderers; } constructor(model) { this.model = model; } } /** * LODGroup allows to create a group of LOD levels for an object. * @category Rendering * @group Components */ export class LODGroup extends Behaviour { fadeMode = LODFadeMode.None; localReferencePoint = undefined; lodCount = 0; size = 0; animateCrossFading = false; lodModels; _lods = []; _settings = []; // https://threejs.org/docs/#api/en/objects/LOD _lodsHandler; start() { if (debug) console.log("LODGROUP", this.name, this.lodModels, this); if (noLods) return; if (this._lodsHandler) return; if (!this.gameObject) return; if (this.lodModels && Array.isArray(this.lodModels)) { const renderers = []; for (const model of this.lodModels) { const lod = new LOD(model); this._lods.push(lod); for (const rend of lod.renderers) { if (!renderers.includes(rend)) renderers.push(rend); } } this._lodsHandler = new Array(); for (let i = 0; i < renderers.length; i++) { const handler = new ThreeLOD(); this._lodsHandler.push(handler); this.gameObject.add(handler); } const empty = new Object3D(); empty.name = "Cull " + this.name; for (let i = 0; i < renderers.length; i++) { const rend = renderers[i]; const handler = this._lodsHandler[i]; const obj = rend.gameObject; if (debug) console.log(i, obj.name); for (const lod of this._lods) { const dist = lod.model.distance; // get object to be lodded, it can be empty let object = null; if (lod.renderers.includes(rend)) { object = obj; } else { object = empty; } if (object.type === "Group") { console.warn(`LODGroup ${this.name}: Group or MultiMaterial object's are not supported as LOD object: ${object.name}`); continue; } if (debug) console.log("LEVEL", object.name, dist); handler.autoUpdate = false; this.onAddLodLevel(handler, object, lod.model.distance); } } } } onAfterRender() { if (!this.gameObject) return; if (!this._lodsHandler) return; const cam = this.context.mainCamera; if (!cam) return; for (const h of this._lodsHandler) { h.update(cam); const levelIndex = h.getCurrentLevel(); const level = h.levels[levelIndex]; h.layers.mask = level.object.layers.mask; } } onAddLodLevel(lod, obj, dist) { if (obj === this.gameObject) { console.warn("LODGroup component must be on parent object and not mesh directly at the moment", obj.name, obj); return; } lod.addLevel(obj, dist * this._distanceFactor, .01); const setting = { lod: lod, levelIndex: lod.levels.length - 1, distance: dist }; this._settings.push(setting); } _distanceFactor = 1; distanceFactor(factor) { if (factor === this._distanceFactor) return; this._distanceFactor = factor; for (const setting of this._settings) { const level = setting.lod.levels[setting.levelIndex]; level.distance = setting.distance * factor; } } } __decorate([ serializable(Vector3) ], LODGroup.prototype, "localReferencePoint", void 0); __decorate([ serializable(LODModel) ], LODGroup.prototype, "lodModels", void 0); //# sourceMappingURL=LODGroup.js.map