@babylonjs/loaders
Version:
The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.
754 lines • 31 kB
JavaScript
import { Observable } from "@babylonjs/core/Misc/observable";
import { Tools } from "@babylonjs/core/Misc/tools";
import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader";
import { AssetContainer } from "@babylonjs/core/assetContainer";
/**
* Mode that determines the coordinate system to use.
*/
export var GLTFLoaderCoordinateSystemMode;
(function (GLTFLoaderCoordinateSystemMode) {
/**
* Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
*/
GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["AUTO"] = 0] = "AUTO";
/**
* Sets the useRightHandedSystem flag on the scene.
*/
GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 1] = "FORCE_RIGHT_HANDED";
})(GLTFLoaderCoordinateSystemMode || (GLTFLoaderCoordinateSystemMode = {}));
/**
* Mode that determines what animations will start.
*/
export var GLTFLoaderAnimationStartMode;
(function (GLTFLoaderAnimationStartMode) {
/**
* No animation will start.
*/
GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["NONE"] = 0] = "NONE";
/**
* The first animation will start.
*/
GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["FIRST"] = 1] = "FIRST";
/**
* All animations will start.
*/
GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["ALL"] = 2] = "ALL";
})(GLTFLoaderAnimationStartMode || (GLTFLoaderAnimationStartMode = {}));
/**
* Loader state.
*/
export var GLTFLoaderState;
(function (GLTFLoaderState) {
/**
* The asset is loading.
*/
GLTFLoaderState[GLTFLoaderState["LOADING"] = 0] = "LOADING";
/**
* The asset is ready for rendering.
*/
GLTFLoaderState[GLTFLoaderState["READY"] = 1] = "READY";
/**
* The asset is completely loaded.
*/
GLTFLoaderState[GLTFLoaderState["COMPLETE"] = 2] = "COMPLETE";
})(GLTFLoaderState || (GLTFLoaderState = {}));
/**
* File loader for loading glTF files into a scene.
*/
var GLTFFileLoader = /** @class */ (function () {
function GLTFFileLoader() {
// --------------
// Common options
// --------------
/**
* Raised when the asset has been parsed
*/
this.onParsedObservable = new Observable();
// ----------
// V2 options
// ----------
/**
* The coordinate system mode. Defaults to AUTO.
*/
this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
/**
* The animation start mode. Defaults to FIRST.
*/
this.animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
/**
* Defines if the loader should compile materials before raising the success callback. Defaults to false.
*/
this.compileMaterials = false;
/**
* Defines if the loader should also compile materials with clip planes. Defaults to false.
*/
this.useClipPlane = false;
/**
* Defines if the loader should compile shadow generators before raising the success callback. Defaults to false.
*/
this.compileShadowGenerators = false;
/**
* Defines if the Alpha blended materials are only applied as coverage.
* If false, (default) The luminance of each pixel will reduce its opacity to simulate the behaviour of most physical materials.
* If true, no extra effects are applied to transparent pixels.
*/
this.transparencyAsCoverage = false;
/**
* Function called before loading a url referenced by the asset.
*/
this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
/**
* Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
*/
this.onMeshLoadedObservable = new Observable();
/**
* Observable raised when the loader creates a texture after parsing the glTF properties of the texture.
*/
this.onTextureLoadedObservable = new Observable();
/**
* Observable raised when the loader creates a material after parsing the glTF properties of the material.
*/
this.onMaterialLoadedObservable = new Observable();
/**
* Observable raised when the loader creates a camera after parsing the glTF properties of the camera.
*/
this.onCameraLoadedObservable = new Observable();
/**
* Observable raised when the asset is completely loaded, immediately before the loader is disposed.
* For assets with LODs, raised when all of the LODs are complete.
* For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
*/
this.onCompleteObservable = new Observable();
/**
* Observable raised when an error occurs.
*/
this.onErrorObservable = new Observable();
/**
* Observable raised after the loader is disposed.
*/
this.onDisposeObservable = new Observable();
/**
* Observable raised after a loader extension is created.
* Set additional options for a loader extension in this event.
*/
this.onExtensionLoadedObservable = new Observable();
/**
* Defines if the loader should validate the asset.
*/
this.validate = false;
/**
* Observable raised after validation when validate is set to true. The event data is the result of the validation.
*/
this.onValidatedObservable = new Observable();
this._loader = null;
/**
* Name of the loader ("gltf")
*/
this.name = "gltf";
/**
* Supported file extensions of the loader (.gltf, .glb)
*/
this.extensions = {
".gltf": { isBinary: false },
".glb": { isBinary: true }
};
this._logIndentLevel = 0;
this._loggingEnabled = false;
/** @hidden */
this._log = this._logDisabled;
this._capturePerformanceCounters = false;
/** @hidden */
this._startPerformanceCounter = this._startPerformanceCounterDisabled;
/** @hidden */
this._endPerformanceCounter = this._endPerformanceCounterDisabled;
}
Object.defineProperty(GLTFFileLoader.prototype, "onParsed", {
/**
* Raised when the asset has been parsed
*/
set: function (callback) {
if (this._onParsedObserver) {
this.onParsedObservable.remove(this._onParsedObserver);
}
this._onParsedObserver = this.onParsedObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
/**
* Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh.
*/
set: function (callback) {
if (this._onMeshLoadedObserver) {
this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
}
this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
/**
* Callback raised when the loader creates a texture after parsing the glTF properties of the texture.
*/
set: function (callback) {
if (this._onTextureLoadedObserver) {
this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
}
this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
/**
* Callback raised when the loader creates a material after parsing the glTF properties of the material.
*/
set: function (callback) {
if (this._onMaterialLoadedObserver) {
this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
}
this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onCameraLoaded", {
/**
* Callback raised when the loader creates a camera after parsing the glTF properties of the camera.
*/
set: function (callback) {
if (this._onCameraLoadedObserver) {
this.onCameraLoadedObservable.remove(this._onCameraLoadedObserver);
}
this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
/**
* Callback raised when the asset is completely loaded, immediately before the loader is disposed.
* For assets with LODs, raised when all of the LODs are complete.
* For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
*/
set: function (callback) {
if (this._onCompleteObserver) {
this.onCompleteObservable.remove(this._onCompleteObserver);
}
this._onCompleteObserver = this.onCompleteObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onError", {
/**
* Callback raised when an error occurs.
*/
set: function (callback) {
if (this._onErrorObserver) {
this.onErrorObservable.remove(this._onErrorObserver);
}
this._onErrorObserver = this.onErrorObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
/**
* Callback raised after the loader is disposed.
*/
set: function (callback) {
if (this._onDisposeObserver) {
this.onDisposeObservable.remove(this._onDisposeObserver);
}
this._onDisposeObserver = this.onDisposeObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
/**
* Callback raised after a loader extension is created.
*/
set: function (callback) {
if (this._onExtensionLoadedObserver) {
this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
}
this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "loggingEnabled", {
/**
* Defines if the loader logging is enabled.
*/
get: function () {
return this._loggingEnabled;
},
set: function (value) {
if (this._loggingEnabled === value) {
return;
}
this._loggingEnabled = value;
if (this._loggingEnabled) {
this._log = this._logEnabled;
}
else {
this._log = this._logDisabled;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "capturePerformanceCounters", {
/**
* Defines if the loader should capture performance counters.
*/
get: function () {
return this._capturePerformanceCounters;
},
set: function (value) {
if (this._capturePerformanceCounters === value) {
return;
}
this._capturePerformanceCounters = value;
if (this._capturePerformanceCounters) {
this._startPerformanceCounter = this._startPerformanceCounterEnabled;
this._endPerformanceCounter = this._endPerformanceCounterEnabled;
}
else {
this._startPerformanceCounter = this._startPerformanceCounterDisabled;
this._endPerformanceCounter = this._endPerformanceCounterDisabled;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(GLTFFileLoader.prototype, "onValidated", {
/**
* Callback raised after a loader extension is created.
*/
set: function (callback) {
if (this._onValidatedObserver) {
this.onValidatedObservable.remove(this._onValidatedObserver);
}
this._onValidatedObserver = this.onValidatedObservable.add(callback);
},
enumerable: true,
configurable: true
});
/**
* Disposes the loader, releases resources during load, and cancels any outstanding requests.
*/
GLTFFileLoader.prototype.dispose = function () {
if (this._loader) {
this._loader.dispose();
this._loader = null;
}
this._clear();
this.onDisposeObservable.notifyObservers(undefined);
this.onDisposeObservable.clear();
};
/** @hidden */
GLTFFileLoader.prototype._clear = function () {
this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
this.onMeshLoadedObservable.clear();
this.onTextureLoadedObservable.clear();
this.onMaterialLoadedObservable.clear();
this.onCameraLoadedObservable.clear();
this.onCompleteObservable.clear();
this.onExtensionLoadedObservable.clear();
};
/**
* Imports one or more meshes from the loaded glTF data and adds them to the scene
* @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
* @param scene the scene the meshes should be added to
* @param data the glTF data to load
* @param rootUrl root url to load from
* @param onProgress event that fires when loading progress has occured
* @param fileName Defines the name of the file to load
* @returns a promise containg the loaded meshes, particles, skeletons and animations
*/
GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress, fileName) {
var _this = this;
return this._parseAsync(scene, data, rootUrl, fileName).then(function (loaderData) {
_this._log("Loading " + (fileName || ""));
_this._loader = _this._getLoader(loaderData);
return _this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onProgress, fileName);
});
};
/**
* Imports all objects from the loaded glTF data and adds them to the scene
* @param scene the scene the objects should be added to
* @param data the glTF data to load
* @param rootUrl root url to load from
* @param onProgress event that fires when loading progress has occured
* @param fileName Defines the name of the file to load
* @returns a promise which completes when objects have been loaded to the scene
*/
GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress, fileName) {
var _this = this;
return this._parseAsync(scene, data, rootUrl, fileName).then(function (loaderData) {
_this._log("Loading " + (fileName || ""));
_this._loader = _this._getLoader(loaderData);
return _this._loader.loadAsync(scene, loaderData, rootUrl, onProgress, fileName);
});
};
/**
* Load into an asset container.
* @param scene The scene to load into
* @param data The data to import
* @param rootUrl The root url for scene and resources
* @param onProgress The callback when the load progresses
* @param fileName Defines the name of the file to load
* @returns The loaded asset container
*/
GLTFFileLoader.prototype.loadAssetContainerAsync = function (scene, data, rootUrl, onProgress, fileName) {
var _this = this;
return this._parseAsync(scene, data, rootUrl, fileName).then(function (loaderData) {
_this._log("Loading " + (fileName || ""));
_this._loader = _this._getLoader(loaderData);
return _this._loader.importMeshAsync(null, scene, loaderData, rootUrl, onProgress, fileName).then(function (result) {
var container = new AssetContainer(scene);
Array.prototype.push.apply(container.meshes, result.meshes);
Array.prototype.push.apply(container.particleSystems, result.particleSystems);
Array.prototype.push.apply(container.skeletons, result.skeletons);
Array.prototype.push.apply(container.animationGroups, result.animationGroups);
container.removeAllFromScene();
return container;
});
});
};
/**
* If the data string can be loaded directly.
* @param data string contianing the file data
* @returns if the data can be loaded directly
*/
GLTFFileLoader.prototype.canDirectLoad = function (data) {
return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
};
/**
* Instantiates a glTF file loader plugin.
* @returns the created plugin
*/
GLTFFileLoader.prototype.createPlugin = function () {
return new GLTFFileLoader();
};
Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
/**
* The loader state or null if the loader is not active.
*/
get: function () {
return this._loader ? this._loader.state : null;
},
enumerable: true,
configurable: true
});
/**
* Returns a promise that resolves when the asset is completely loaded.
* @returns a promise that resolves when the asset is completely loaded.
*/
GLTFFileLoader.prototype.whenCompleteAsync = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.onCompleteObservable.addOnce(function () {
resolve();
});
_this.onErrorObservable.addOnce(function (reason) {
reject(reason);
});
});
};
GLTFFileLoader.prototype._parseAsync = function (scene, data, rootUrl, fileName) {
var _this = this;
return Promise.resolve().then(function () {
var unpacked = (data instanceof ArrayBuffer) ? _this._unpackBinary(data) : { json: data, bin: null };
return _this._validateAsync(scene, unpacked.json, rootUrl, fileName).then(function () {
_this._startPerformanceCounter("Parse JSON");
_this._log("JSON length: " + unpacked.json.length);
var loaderData = {
json: JSON.parse(unpacked.json),
bin: unpacked.bin
};
_this._endPerformanceCounter("Parse JSON");
_this.onParsedObservable.notifyObservers(loaderData);
_this.onParsedObservable.clear();
return loaderData;
});
});
};
GLTFFileLoader.prototype._validateAsync = function (scene, json, rootUrl, fileName) {
var _this = this;
if (!this.validate || typeof GLTFValidator === "undefined") {
return Promise.resolve();
}
this._startPerformanceCounter("Validate JSON");
var options = {
externalResourceFunction: function (uri) {
return _this.preprocessUrlAsync(rootUrl + uri)
.then(function (url) { return scene._loadFileAsync(url, true, true); })
.then(function (data) { return new Uint8Array(data); });
}
};
if (fileName && fileName.substr(0, 5) !== "data:") {
options.uri = (rootUrl === "file:" ? fileName : "" + rootUrl + fileName);
}
return GLTFValidator.validateString(json, options).then(function (result) {
_this._endPerformanceCounter("Validate JSON");
_this.onValidatedObservable.notifyObservers(result);
_this.onValidatedObservable.clear();
}, function (reason) {
_this._endPerformanceCounter("Validate JSON");
Tools.Warn("Failed to validate: " + reason);
_this.onValidatedObservable.clear();
});
};
GLTFFileLoader.prototype._getLoader = function (loaderData) {
var asset = loaderData.json.asset || {};
this._log("Asset version: " + asset.version);
asset.minVersion && this._log("Asset minimum version: " + asset.minVersion);
asset.generator && this._log("Asset generator: " + asset.generator);
var version = GLTFFileLoader._parseVersion(asset.version);
if (!version) {
throw new Error("Invalid version: " + asset.version);
}
if (asset.minVersion !== undefined) {
var minVersion = GLTFFileLoader._parseVersion(asset.minVersion);
if (!minVersion) {
throw new Error("Invalid minimum version: " + asset.minVersion);
}
if (GLTFFileLoader._compareVersion(minVersion, { major: 2, minor: 0 }) > 0) {
throw new Error("Incompatible minimum version: " + asset.minVersion);
}
}
var createLoaders = {
1: GLTFFileLoader._CreateGLTF1Loader,
2: GLTFFileLoader._CreateGLTF2Loader
};
var createLoader = createLoaders[version.major];
if (!createLoader) {
throw new Error("Unsupported version: " + asset.version);
}
return createLoader(this);
};
GLTFFileLoader.prototype._unpackBinary = function (data) {
this._startPerformanceCounter("Unpack binary");
this._log("Binary length: " + data.byteLength);
var Binary = {
Magic: 0x46546C67
};
var binaryReader = new BinaryReader(data);
var magic = binaryReader.readUint32();
if (magic !== Binary.Magic) {
throw new Error("Unexpected magic: " + magic);
}
var version = binaryReader.readUint32();
if (this.loggingEnabled) {
this._log("Binary version: " + version);
}
var unpacked;
switch (version) {
case 1: {
unpacked = this._unpackBinaryV1(binaryReader);
break;
}
case 2: {
unpacked = this._unpackBinaryV2(binaryReader);
break;
}
default: {
throw new Error("Unsupported version: " + version);
}
}
this._endPerformanceCounter("Unpack binary");
return unpacked;
};
GLTFFileLoader.prototype._unpackBinaryV1 = function (binaryReader) {
var ContentFormat = {
JSON: 0
};
var length = binaryReader.readUint32();
if (length != binaryReader.getLength()) {
throw new Error("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
}
var contentLength = binaryReader.readUint32();
var contentFormat = binaryReader.readUint32();
var content;
switch (contentFormat) {
case ContentFormat.JSON: {
content = GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(contentLength));
break;
}
default: {
throw new Error("Unexpected content format: " + contentFormat);
}
}
var bytesRemaining = binaryReader.getLength() - binaryReader.getPosition();
var body = binaryReader.readUint8Array(bytesRemaining);
return {
json: content,
bin: body
};
};
GLTFFileLoader.prototype._unpackBinaryV2 = function (binaryReader) {
var ChunkFormat = {
JSON: 0x4E4F534A,
BIN: 0x004E4942
};
var length = binaryReader.readUint32();
if (length !== binaryReader.getLength()) {
throw new Error("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
}
// JSON chunk
var chunkLength = binaryReader.readUint32();
var chunkFormat = binaryReader.readUint32();
if (chunkFormat !== ChunkFormat.JSON) {
throw new Error("First chunk format is not JSON");
}
var json = GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(chunkLength));
// Look for BIN chunk
var bin = null;
while (binaryReader.getPosition() < binaryReader.getLength()) {
var chunkLength_1 = binaryReader.readUint32();
var chunkFormat_1 = binaryReader.readUint32();
switch (chunkFormat_1) {
case ChunkFormat.JSON: {
throw new Error("Unexpected JSON chunk");
}
case ChunkFormat.BIN: {
bin = binaryReader.readUint8Array(chunkLength_1);
break;
}
default: {
// ignore unrecognized chunkFormat
binaryReader.skipBytes(chunkLength_1);
break;
}
}
}
return {
json: json,
bin: bin
};
};
GLTFFileLoader._parseVersion = function (version) {
if (version === "1.0" || version === "1.0.1") {
return {
major: 1,
minor: 0
};
}
var match = (version + "").match(/^(\d+)\.(\d+)/);
if (!match) {
return null;
}
return {
major: parseInt(match[1]),
minor: parseInt(match[2])
};
};
GLTFFileLoader._compareVersion = function (a, b) {
if (a.major > b.major) {
return 1;
}
if (a.major < b.major) {
return -1;
}
if (a.minor > b.minor) {
return 1;
}
if (a.minor < b.minor) {
return -1;
}
return 0;
};
GLTFFileLoader._decodeBufferToText = function (buffer) {
if (typeof TextDecoder !== "undefined") {
return new TextDecoder().decode(buffer);
}
var result = "";
var length = buffer.byteLength;
for (var i = 0; i < length; i++) {
result += String.fromCharCode(buffer[i]);
}
return result;
};
/** @hidden */
GLTFFileLoader.prototype._logOpen = function (message) {
this._log(message);
this._logIndentLevel++;
};
/** @hidden */
GLTFFileLoader.prototype._logClose = function () {
--this._logIndentLevel;
};
GLTFFileLoader.prototype._logEnabled = function (message) {
var spaces = GLTFFileLoader._logSpaces.substr(0, this._logIndentLevel * 2);
Tools.Log("" + spaces + message);
};
GLTFFileLoader.prototype._logDisabled = function (message) {
};
GLTFFileLoader.prototype._startPerformanceCounterEnabled = function (counterName) {
Tools.StartPerformanceCounter(counterName);
};
GLTFFileLoader.prototype._startPerformanceCounterDisabled = function (counterName) {
};
GLTFFileLoader.prototype._endPerformanceCounterEnabled = function (counterName) {
Tools.EndPerformanceCounter(counterName);
};
GLTFFileLoader.prototype._endPerformanceCounterDisabled = function (counterName) {
};
// ----------
// V1 options
// ----------
/**
* Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders.
* Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled.
* Defaults to true.
* @hidden
*/
GLTFFileLoader.IncrementalLoading = true;
/**
* Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters.
* Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates.
* @hidden
*/
GLTFFileLoader.HomogeneousCoordinates = false;
GLTFFileLoader._logSpaces = " ";
return GLTFFileLoader;
}());
export { GLTFFileLoader };
var BinaryReader = /** @class */ (function () {
function BinaryReader(arrayBuffer) {
this._arrayBuffer = arrayBuffer;
this._dataView = new DataView(arrayBuffer);
this._byteOffset = 0;
}
BinaryReader.prototype.getPosition = function () {
return this._byteOffset;
};
BinaryReader.prototype.getLength = function () {
return this._arrayBuffer.byteLength;
};
BinaryReader.prototype.readUint32 = function () {
var value = this._dataView.getUint32(this._byteOffset, true);
this._byteOffset += 4;
return value;
};
BinaryReader.prototype.readUint8Array = function (length) {
var value = new Uint8Array(this._arrayBuffer, this._byteOffset, length);
this._byteOffset += length;
return value;
};
BinaryReader.prototype.skipBytes = function (length) {
this._byteOffset += length;
};
return BinaryReader;
}());
if (SceneLoader) {
SceneLoader.RegisterPlugin(new GLTFFileLoader());
}
//# sourceMappingURL=glTFFileLoader.js.map