UNPKG

nanogl-gltf

Version:
140 lines (139 loc) 4.88 kB
import { mat3 } from "gl-matrix"; import DirectionalLight from "nanogl-pbr/lighting/DirectionalLight"; import PointLight from "nanogl-pbr/lighting/PointLight"; import SpotLight from "nanogl-pbr/lighting/SpotLight"; import GltfTypes from "../../types/GltfTypes"; const M3 = mat3.create(); const EXT_ID = 'KHR_lights_punctual'; // =========================================== // Data Spec // =========================================== var IKHR_LP_LightType; (function (IKHR_LP_LightType) { IKHR_LP_LightType["Directional"] = "directional"; IKHR_LP_LightType["Point"] = "point"; IKHR_LP_LightType["Spot"] = "spot"; })(IKHR_LP_LightType || (IKHR_LP_LightType = {})); /** * Class to manage a collection of lights */ export class LightCollection { constructor() { this.list = []; this._items = []; } /** * Add a light to the collection * @param light Light to add * @param name Light's name */ addLight(light, name = undefined) { this.list.push(light); this._items.push({ name: name, index: this.list.length - 1 }); } /** * Get a light from this collection by its name * @param name Light's name to get */ getLightByName(name) { let out; for (let i = 0; i < this._items.length; i++) { if (this._items[i].name == name) { out = this.list[this._items[i].index]; break; } } return out; } /** * Get a list of lights from this collection by their name * @param name Lights' name to get */ getLightsByName(name) { const out = []; for (let i = 0; i < this._items.length; i++) { if (this._items[i].name == name) { out.push(this.list[this._items[i].index]); } } return out; } } class Instance { constructor(gltfLoader) { this.name = EXT_ID; this.priority = 1; this.loader = gltfLoader; this.lights = new LightCollection(); gltfLoader.gltf.extras.lights = this.lights; } _getLightData(index) { var _a; const lightDatas = (_a = this.loader._data.extensions) === null || _a === void 0 ? void 0 : _a[EXT_ID]; if (lightDatas === undefined) throw new Error(EXT_ID + ' no extension data'); return lightDatas.lights[index]; } _createDirectional(lightData) { return new DirectionalLight(); } _createPoint(lightData) { var _a; const l = new PointLight(); l.radius = (_a = lightData.range) !== null && _a !== void 0 ? _a : -1; return l; } _createSpot(lightData) { var _a, _b, _c, _d, _e; const l = new SpotLight(); l.radius = (_a = lightData.range) !== null && _a !== void 0 ? _a : -1; l.innerAngle = (_c = (_b = lightData.spot) === null || _b === void 0 ? void 0 : _b.innerConeAngle) !== null && _c !== void 0 ? _c : 0; l.outerAngle = (_e = (_d = lightData.spot) === null || _d === void 0 ? void 0 : _d.outerConeAngle) !== null && _e !== void 0 ? _e : 0; return l; } _createLightInstance(lightData) { switch (lightData.type) { case IKHR_LP_LightType.Directional: return this._createDirectional(lightData); case IKHR_LP_LightType.Point: return this._createPoint(lightData); case IKHR_LP_LightType.Spot: return this._createSpot(lightData); } } _createLight(node, iData) { var _a, _b; const lightData = this._getLightData(iData.light); const light = this._createLightInstance(lightData); const color = (_a = lightData.color) !== null && _a !== void 0 ? _a : [1, 1, 1]; const intensity = (_b = lightData.intensity) !== null && _b !== void 0 ? _b : 1; color[0] *= intensity; color[1] *= intensity; color[2] *= intensity; light._color.set(color); node.add(light); const name = lightData.name; this.lights.addLight(light, name); return light; } acceptElement(data, element) { if (element.gltftype === GltfTypes.NODE && data.extensions && data.extensions[EXT_ID]) { const node = element; this._createLight(node, data.extensions[EXT_ID]); } return null; } loadElement(data) { return null; } } /** * This extension allows to define in a glTF file a set of lights that can be used by the scene. * The 3 possible types of lights (directional, spot and point) will be created as nanogl-pbr DirectionalLight, * SpotLight and PointLight, and added to the Node they are linked to. */ export default class KHR_lights_punctual { constructor() { this.name = EXT_ID; } createInstance(gltfLoader) { return new Instance(gltfLoader); } }