@babylonjs/loaders 5.0.0-alpha.8 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/OBJ/index.d.ts +2 -0
- package/OBJ/index.js +4 -2
- package/OBJ/index.js.map +1 -1
- package/OBJ/mtlFileLoader.d.ts +4 -2
- package/OBJ/mtlFileLoader.js +7 -6
- package/OBJ/mtlFileLoader.js.map +1 -1
- package/OBJ/objFileLoader.d.ts +12 -84
- package/OBJ/objFileLoader.js +52 -669
- package/OBJ/objFileLoader.js.map +1 -1
- package/OBJ/objLoadingOptions.d.ts +43 -0
- package/OBJ/objLoadingOptions.js +2 -0
- package/OBJ/objLoadingOptions.js.map +1 -0
- package/OBJ/solidParser.d.ts +153 -0
- package/OBJ/solidParser.js +700 -0
- package/OBJ/solidParser.js.map +1 -0
- package/STL/index.js +1 -1
- package/STL/stlFileLoader.d.ts +6 -0
- package/STL/stlFileLoader.js +38 -11
- package/STL/stlFileLoader.js.map +1 -1
- package/glTF/1.0/glTFBinaryExtension.js +4 -4
- package/glTF/1.0/glTFLoader.d.ts +4 -4
- package/glTF/1.0/glTFLoader.js +60 -55
- package/glTF/1.0/glTFLoader.js.map +1 -1
- package/glTF/1.0/glTFLoaderInterfaces.d.ts +3 -1
- package/glTF/1.0/glTFLoaderInterfaces.js.map +1 -1
- package/glTF/1.0/glTFLoaderUtils.js +6 -6
- package/glTF/1.0/glTFMaterialsCommonExtension.js +12 -12
- package/glTF/1.0/index.js +5 -5
- package/glTF/2.0/Extensions/EXT_lights_image_based.js +15 -12
- package/glTF/2.0/Extensions/EXT_lights_image_based.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.d.ts +1 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +8 -7
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_meshopt_compression.d.ts +1 -5
- package/glTF/2.0/Extensions/EXT_meshopt_compression.js +6 -22
- package/glTF/2.0/Extensions/EXT_meshopt_compression.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_texture_webp.js +4 -4
- package/glTF/2.0/Extensions/EXT_texture_webp.js.map +1 -1
- package/glTF/2.0/Extensions/ExtrasAsMetadata.js +1 -1
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js +35 -11
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_lights_punctual.js +10 -9
- package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +9 -9
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.d.ts +30 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js +46 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.d.ts +1 -2
- package/glTF/2.0/Extensions/KHR_materials_ior.js +4 -5
- package/glTF/2.0/Extensions/KHR_materials_ior.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js +8 -9
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +0 -1
- package/glTF/2.0/Extensions/KHR_materials_sheen.js +8 -9
- package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_specular.d.ts +1 -2
- package/glTF/2.0/Extensions/KHR_materials_specular.js +14 -8
- package/glTF/2.0/Extensions/KHR_materials_specular.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_translucency.js +8 -8
- package/glTF/2.0/Extensions/KHR_materials_translucency.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_transmission.js +95 -86
- package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_unlit.js +6 -6
- package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_variants.js +76 -11
- package/glTF/2.0/Extensions/KHR_materials_variants.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_volume.d.ts +31 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.js +79 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.js +1 -1
- package/glTF/2.0/Extensions/KHR_texture_basisu.d.ts +1 -2
- package/glTF/2.0/Extensions/KHR_texture_basisu.js +5 -6
- package/glTF/2.0/Extensions/KHR_texture_basisu.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_texture_transform.js +3 -3
- package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.js +6 -3
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_audio_emitter.js +19 -20
- package/glTF/2.0/Extensions/MSFT_audio_emitter.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_lod.d.ts +1 -1
- package/glTF/2.0/Extensions/MSFT_lod.js +20 -17
- package/glTF/2.0/Extensions/MSFT_lod.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js +3 -3
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.js +3 -3
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.js.map +1 -1
- package/glTF/2.0/Extensions/index.d.ts +2 -0
- package/glTF/2.0/Extensions/index.js +26 -24
- package/glTF/2.0/Extensions/index.js.map +1 -1
- package/glTF/2.0/glTFLoader.d.ts +10 -13
- package/glTF/2.0/glTFLoader.js +416 -299
- package/glTF/2.0/glTFLoader.js.map +1 -1
- package/glTF/2.0/glTFLoaderInterfaces.d.ts +4 -5
- package/glTF/2.0/glTFLoaderInterfaces.js.map +1 -1
- package/glTF/2.0/index.d.ts +1 -1
- package/glTF/2.0/index.js +4 -4
- package/glTF/2.0/index.js.map +1 -1
- package/glTF/glTFFileLoader.d.ts +25 -10
- package/glTF/glTFFileLoader.js +86 -94
- package/glTF/glTFFileLoader.js.map +1 -1
- package/glTF/glTFValidation.js +2 -2
- package/glTF/glTFValidation.js.map +1 -1
- package/glTF/index.d.ts +2 -2
- package/glTF/index.js +4 -4
- package/glTF/index.js.map +1 -1
- package/index.d.ts +3 -3
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/legacy/legacy-glTF.js +4 -4
- package/legacy/legacy-glTF1.d.ts +1 -1
- package/legacy/legacy-glTF1.js +1 -1
- package/legacy/legacy-glTF1.js.map +1 -1
- package/legacy/legacy-glTF1FileLoader.js +2 -2
- package/legacy/legacy-glTF2.d.ts +1 -1
- package/legacy/legacy-glTF2.js +3 -3
- package/legacy/legacy-glTF2.js.map +1 -1
- package/legacy/legacy-glTF2FileLoader.js +2 -2
- package/legacy/legacy-glTFFileLoader.js +3 -3
- package/legacy/legacy-objFileLoader.d.ts +1 -1
- package/legacy/legacy-objFileLoader.js +2 -2
- package/legacy/legacy-objFileLoader.js.map +1 -1
- package/legacy/legacy-stlFileLoader.d.ts +1 -1
- package/legacy/legacy-stlFileLoader.js +2 -2
- package/legacy/legacy-stlFileLoader.js.map +1 -1
- package/legacy/legacy.js +6 -6
- package/package.json +16 -4
@@ -1,9 +1,8 @@
|
|
1
1
|
import { AnimationGroup } from "@babylonjs/core/Animations/animationGroup";
|
2
|
-
import { Bone } from "@babylonjs/core/Bones/bone";
|
3
2
|
import { Skeleton } from "@babylonjs/core/Bones/skeleton";
|
4
3
|
import { Material } from "@babylonjs/core/Materials/material";
|
5
4
|
import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
|
6
|
-
import { Buffer, VertexBuffer } from "@babylonjs/core/
|
5
|
+
import { Buffer, VertexBuffer } from "@babylonjs/core/Buffers/buffer";
|
7
6
|
import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh";
|
8
7
|
import { Mesh } from "@babylonjs/core/Meshes/mesh";
|
9
8
|
import * as GLTF2 from "babylonjs-gltf2interface";
|
@@ -23,7 +22,9 @@ export interface IAccessor extends GLTF2.IAccessor, IArrayItem {
|
|
23
22
|
/** @hidden */
|
24
23
|
_data?: Promise<ArrayBufferView>;
|
25
24
|
/** @hidden */
|
26
|
-
_babylonVertexBuffer?:
|
25
|
+
_babylonVertexBuffer?: {
|
26
|
+
[kind: string]: Promise<VertexBuffer>;
|
27
|
+
};
|
27
28
|
}
|
28
29
|
/**
|
29
30
|
* Loader interface with additional members.
|
@@ -143,8 +144,6 @@ export interface INode extends GLTF2.INode, IArrayItem {
|
|
143
144
|
/** @hidden */
|
144
145
|
_primitiveBabylonMeshes?: AbstractMesh[];
|
145
146
|
/** @hidden */
|
146
|
-
_babylonBones?: Bone[];
|
147
|
-
/** @hidden */
|
148
147
|
_numMorphTargets?: number;
|
149
148
|
}
|
150
149
|
/** @hidden */
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"glTFLoaderInterfaces.js","sourceRoot":"","sources":["../../../../sourceES6/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts"],"names":[],"mappings":"","sourcesContent":["import { AnimationGroup } from \"@babylonjs/core/Animations/animationGroup\";\r\nimport {
|
1
|
+
{"version":3,"file":"glTFLoaderInterfaces.js","sourceRoot":"","sources":["../../../../sourceES6/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts"],"names":[],"mappings":"","sourcesContent":["import { AnimationGroup } from \"@babylonjs/core/Animations/animationGroup\";\r\nimport { Skeleton } from \"@babylonjs/core/Bones/skeleton\";\r\nimport { Material } from \"@babylonjs/core/Materials/material\";\r\nimport { TransformNode } from \"@babylonjs/core/Meshes/transformNode\";\r\nimport { Buffer, VertexBuffer } from \"@babylonjs/core/Buffers/buffer\";\r\nimport { AbstractMesh } from \"@babylonjs/core/Meshes/abstractMesh\";\r\nimport { Mesh } from \"@babylonjs/core/Meshes/mesh\";\r\n\r\nimport * as GLTF2 from \"babylonjs-gltf2interface\";\r\n\r\n/**\r\n * Loader interface with an index field.\r\n */\r\nexport interface IArrayItem {\r\n /**\r\n * The index of this item in the array.\r\n */\r\n index: number;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IAccessor extends GLTF2.IAccessor, IArrayItem {\r\n /** @hidden */\r\n _data?: Promise<ArrayBufferView>;\r\n\r\n /** @hidden */\r\n _babylonVertexBuffer?: { [kind: string]: Promise<VertexBuffer>; };\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IAnimationChannel extends GLTF2.IAnimationChannel, IArrayItem {\r\n}\r\n\r\n/** @hidden */\r\nexport interface _IAnimationSamplerData {\r\n input: Float32Array;\r\n interpolation: GLTF2.AnimationSamplerInterpolation;\r\n output: Float32Array;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IAnimationSampler extends GLTF2.IAnimationSampler, IArrayItem {\r\n /** @hidden */\r\n _data?: Promise<_IAnimationSamplerData>;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IAnimation extends GLTF2.IAnimation, IArrayItem {\r\n channels: IAnimationChannel[];\r\n samplers: IAnimationSampler[];\r\n\r\n /** @hidden */\r\n _babylonAnimationGroup?: AnimationGroup;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IBuffer extends GLTF2.IBuffer, IArrayItem {\r\n /** @hidden */\r\n _data?: Promise<ArrayBufferView>;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IBufferView extends GLTF2.IBufferView, IArrayItem {\r\n /** @hidden */\r\n _data?: Promise<ArrayBufferView>;\r\n\r\n /** @hidden */\r\n _babylonBuffer?: Promise<Buffer>;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface ICamera extends GLTF2.ICamera, IArrayItem {\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IImage extends GLTF2.IImage, IArrayItem {\r\n /** @hidden */\r\n _data?: Promise<ArrayBufferView>;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IMaterialNormalTextureInfo extends GLTF2.IMaterialNormalTextureInfo, ITextureInfo {\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IMaterialOcclusionTextureInfo extends GLTF2.IMaterialOcclusionTextureInfo, ITextureInfo {\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IMaterialPbrMetallicRoughness extends GLTF2.IMaterialPbrMetallicRoughness {\r\n baseColorTexture?: ITextureInfo;\r\n metallicRoughnessTexture?: ITextureInfo;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IMaterial extends GLTF2.IMaterial, IArrayItem {\r\n pbrMetallicRoughness?: IMaterialPbrMetallicRoughness;\r\n normalTexture?: IMaterialNormalTextureInfo;\r\n occlusionTexture?: IMaterialOcclusionTextureInfo;\r\n emissiveTexture?: ITextureInfo;\r\n\r\n /** @hidden */\r\n _data?: {\r\n [babylonDrawMode: number]: {\r\n babylonMaterial: Material;\r\n babylonMeshes: AbstractMesh[];\r\n promise: Promise<void>;\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IMesh extends GLTF2.IMesh, IArrayItem {\r\n primitives: IMeshPrimitive[];\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IMeshPrimitive extends GLTF2.IMeshPrimitive, IArrayItem {\r\n /** @hidden */\r\n _instanceData?: {\r\n babylonSourceMesh: Mesh;\r\n promise: Promise<any>;\r\n };\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface INode extends GLTF2.INode, IArrayItem {\r\n /**\r\n * The parent glTF node.\r\n */\r\n parent?: INode;\r\n\r\n /** @hidden */\r\n _babylonTransformNode?: TransformNode;\r\n\r\n /** @hidden */\r\n _primitiveBabylonMeshes?: AbstractMesh[];\r\n\r\n /** @hidden */\r\n _numMorphTargets?: number;\r\n}\r\n\r\n/** @hidden */\r\nexport interface _ISamplerData {\r\n noMipMaps: boolean;\r\n samplingMode: number;\r\n wrapU: number;\r\n wrapV: number;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface ISampler extends GLTF2.ISampler, IArrayItem {\r\n /** @hidden */\r\n _data?: _ISamplerData;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IScene extends GLTF2.IScene, IArrayItem {\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface ISkin extends GLTF2.ISkin, IArrayItem {\r\n /** @hidden */\r\n _data?: {\r\n babylonSkeleton: Skeleton;\r\n promise: Promise<void>;\r\n };\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface ITexture extends GLTF2.ITexture, IArrayItem {\r\n /** @hidden */\r\n _textureInfo: ITextureInfo;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface ITextureInfo extends GLTF2.ITextureInfo {\r\n /** false or undefined if the texture holds color data (true if data are roughness, normal, ...) */\r\n nonColorData?: boolean;\r\n}\r\n\r\n/**\r\n * Loader interface with additional members.\r\n */\r\nexport interface IGLTF extends GLTF2.IGLTF {\r\n accessors?: IAccessor[];\r\n animations?: IAnimation[];\r\n buffers?: IBuffer[];\r\n bufferViews?: IBufferView[];\r\n cameras?: ICamera[];\r\n images?: IImage[];\r\n materials?: IMaterial[];\r\n meshes?: IMesh[];\r\n nodes?: INode[];\r\n samplers?: ISampler[];\r\n scenes?: IScene[];\r\n skins?: ISkin[];\r\n textures?: ITexture[];\r\n}\r\n"]}
|
package/glTF/2.0/index.d.ts
CHANGED
package/glTF/2.0/index.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
export * from "./glTFLoader";
|
2
|
-
export * from "./glTFLoaderExtension";
|
3
|
-
export * from "./glTFLoaderInterfaces";
|
4
|
-
export * from "./Extensions";
|
1
|
+
export * from "./glTFLoader.js";
|
2
|
+
export * from "./glTFLoaderExtension.js";
|
3
|
+
export * from "./glTFLoaderInterfaces.js";
|
4
|
+
export * from "./Extensions/index.js";
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/glTF/2.0/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../sourceES6/loaders/src/glTF/2.0/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../sourceES6/loaders/src/glTF/2.0/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC","sourcesContent":["export * from \"./glTFLoader\";\r\nexport * from \"./glTFLoaderExtension\";\r\nexport * from \"./glTFLoaderInterfaces\";\r\nexport * from \"./Extensions/index\";"]}
|
package/glTF/glTFFileLoader.d.ts
CHANGED
@@ -10,8 +10,8 @@ import { AssetContainer } from "@babylonjs/core/assetContainer";
|
|
10
10
|
import { Scene, IDisposable } from "@babylonjs/core/scene";
|
11
11
|
import { WebRequest } from "@babylonjs/core/Misc/webRequest";
|
12
12
|
import { IFileRequest } from "@babylonjs/core/Misc/fileRequest";
|
13
|
-
import { IDataBuffer } from
|
14
|
-
import {
|
13
|
+
import { IDataBuffer } from "@babylonjs/core/Misc/dataReader";
|
14
|
+
import { LoadFileError } from "@babylonjs/core/Misc/fileTools";
|
15
15
|
/**
|
16
16
|
* Mode that determines the coordinate system to use.
|
17
17
|
*/
|
@@ -92,8 +92,7 @@ export declare enum GLTFLoaderState {
|
|
92
92
|
}
|
93
93
|
/** @hidden */
|
94
94
|
export interface IGLTFLoader extends IDisposable {
|
95
|
-
|
96
|
-
importMeshAsync: (meshesNames: any, scene: Scene, forAssetContainer: boolean, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string) => Promise<ISceneLoaderAsyncResult>;
|
95
|
+
importMeshAsync: (meshesNames: any, scene: Scene, container: Nullable<AssetContainer>, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string) => Promise<ISceneLoaderAsyncResult>;
|
97
96
|
loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string) => Promise<void>;
|
98
97
|
}
|
99
98
|
/**
|
@@ -171,8 +170,21 @@ export declare class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAs
|
|
171
170
|
*/
|
172
171
|
loadAllMaterials: boolean;
|
173
172
|
/**
|
174
|
-
*
|
173
|
+
* If true, load the color (gamma encoded) textures into sRGB buffers (if supported by the GPU), which will yield more accurate results when sampling the texture. Defaults to true.
|
175
174
|
*/
|
175
|
+
useSRGBBuffers: boolean;
|
176
|
+
/**
|
177
|
+
* When loading glTF animations, which are defined in seconds, target them to this FPS. Defaults to 60.
|
178
|
+
*/
|
179
|
+
targetFps: number;
|
180
|
+
/**
|
181
|
+
* Defines if the loader should always compute the nearest common ancestor of the skeleton joints instead of using `skin.skeleton`. Defaults to false.
|
182
|
+
* Set this to true if loading assets with invalid `skin.skeleton` values.
|
183
|
+
*/
|
184
|
+
alwaysComputeSkeletonRootNode: boolean;
|
185
|
+
/**
|
186
|
+
* Function called before loading a url referenced by the asset.
|
187
|
+
*/
|
176
188
|
preprocessUrlAsync: (url: string) => Promise<string>;
|
177
189
|
/**
|
178
190
|
* Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
|
@@ -277,6 +289,7 @@ export declare class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAs
|
|
277
289
|
*/
|
278
290
|
set onValidated(callback: (results: GLTF2.IGLTFValidationResults) => void);
|
279
291
|
private _loader;
|
292
|
+
private _state;
|
280
293
|
private _progressCallback?;
|
281
294
|
private _requests;
|
282
295
|
private static magicBase64Encoded;
|
@@ -291,9 +304,7 @@ export declare class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAs
|
|
291
304
|
*/
|
292
305
|
dispose(): void;
|
293
306
|
/** @hidden */
|
294
|
-
|
295
|
-
/** @hidden */
|
296
|
-
readFile(scene: Scene, file: File, onSuccess: (data: any) => void, onProgress?: (ev: ISceneLoaderProgressEvent) => any, useArrayBuffer?: boolean, onError?: (error: any) => void): IFileRequest;
|
307
|
+
loadFile(scene: Scene, fileOrUrl: File | string, onSuccess: (data: any, responseURL?: string) => void, onProgress?: (ev: ISceneLoaderProgressEvent) => void, useArrayBuffer?: boolean, onError?: (request?: WebRequest, exception?: LoadFileError) => void): IFileRequest;
|
297
308
|
/** @hidden */
|
298
309
|
importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<ISceneLoaderAsyncResult>;
|
299
310
|
/** @hidden */
|
@@ -317,15 +328,19 @@ export declare class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAs
|
|
317
328
|
* The loader state or null if the loader is not active.
|
318
329
|
*/
|
319
330
|
get loaderState(): Nullable<GLTFLoaderState>;
|
331
|
+
/**
|
332
|
+
* Observable raised when the loader state changes.
|
333
|
+
*/
|
334
|
+
onLoaderStateChangedObservable: Observable<Nullable<GLTFLoaderState>>;
|
320
335
|
/**
|
321
336
|
* Returns a promise that resolves when the asset is completely loaded.
|
322
337
|
* @returns a promise that resolves when the asset is completely loaded.
|
323
338
|
*/
|
324
339
|
whenCompleteAsync(): Promise<void>;
|
325
340
|
/** @hidden */
|
326
|
-
|
341
|
+
_setState(state: GLTFLoaderState): void;
|
327
342
|
/** @hidden */
|
328
|
-
|
343
|
+
_loadFile(scene: Scene, fileOrUrl: File | string, onSuccess: (data: string | ArrayBuffer) => void, useArrayBuffer?: boolean, onError?: (request?: WebRequest) => void, onOpened?: (request: WebRequest) => void): IFileRequest;
|
329
344
|
private _onProgress;
|
330
345
|
private _validate;
|
331
346
|
private _getLoader;
|
package/glTF/glTFFileLoader.js
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
-
import { Observable } from "@babylonjs/core/Misc/observable";
|
2
|
-
import { Tools } from "@babylonjs/core/Misc/tools";
|
3
|
-
import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader";
|
4
|
-
import { AssetContainer } from "@babylonjs/core/assetContainer";
|
5
|
-
import { Logger } from
|
6
|
-
import { DataReader } from
|
7
|
-
import { GLTFValidation } from
|
8
|
-
import {
|
1
|
+
import { Observable } from "@babylonjs/core/Misc/observable.js";
|
2
|
+
import { Tools } from "@babylonjs/core/Misc/tools.js";
|
3
|
+
import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader.js";
|
4
|
+
import { AssetContainer } from "@babylonjs/core/assetContainer.js";
|
5
|
+
import { Logger } from "@babylonjs/core/Misc/logger.js";
|
6
|
+
import { DataReader } from "@babylonjs/core/Misc/dataReader.js";
|
7
|
+
import { GLTFValidation } from "./glTFValidation.js";
|
8
|
+
import { DecodeBase64UrlToBinary } from "@babylonjs/core/Misc/fileTools.js";
|
9
|
+
import { StringTools } from "@babylonjs/core/Misc/stringTools.js";
|
10
|
+
import { RuntimeError, ErrorCodes } from "@babylonjs/core/Misc/error.js";
|
11
|
+
function readAsync(arrayBuffer, byteOffset, byteLength) {
|
12
|
+
try {
|
13
|
+
return Promise.resolve(new Uint8Array(arrayBuffer, byteOffset, byteLength));
|
14
|
+
}
|
15
|
+
catch (e) {
|
16
|
+
return Promise.reject(e);
|
17
|
+
}
|
18
|
+
}
|
9
19
|
/**
|
10
20
|
* Mode that determines the coordinate system to use.
|
11
21
|
*/
|
@@ -116,8 +126,21 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
116
126
|
*/
|
117
127
|
this.loadAllMaterials = false;
|
118
128
|
/**
|
119
|
-
*
|
129
|
+
* If true, load the color (gamma encoded) textures into sRGB buffers (if supported by the GPU), which will yield more accurate results when sampling the texture. Defaults to true.
|
130
|
+
*/
|
131
|
+
this.useSRGBBuffers = true;
|
132
|
+
/**
|
133
|
+
* When loading glTF animations, which are defined in seconds, target them to this FPS. Defaults to 60.
|
134
|
+
*/
|
135
|
+
this.targetFps = 60;
|
136
|
+
/**
|
137
|
+
* Defines if the loader should always compute the nearest common ancestor of the skeleton joints instead of using `skin.skeleton`. Defaults to false.
|
138
|
+
* Set this to true if loading assets with invalid `skin.skeleton` values.
|
120
139
|
*/
|
140
|
+
this.alwaysComputeSkeletonRootNode = false;
|
141
|
+
/**
|
142
|
+
* Function called before loading a url referenced by the asset.
|
143
|
+
*/
|
121
144
|
this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
|
122
145
|
/**
|
123
146
|
* Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
|
@@ -164,6 +187,7 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
164
187
|
*/
|
165
188
|
this.onValidatedObservable = new Observable();
|
166
189
|
this._loader = null;
|
190
|
+
this._state = null;
|
167
191
|
this._requests = new Array();
|
168
192
|
/**
|
169
193
|
* Name of the loader ("gltf")
|
@@ -174,6 +198,10 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
174
198
|
".gltf": { isBinary: false },
|
175
199
|
".glb": { isBinary: true }
|
176
200
|
};
|
201
|
+
/**
|
202
|
+
* Observable raised when the loader state changes.
|
203
|
+
*/
|
204
|
+
this.onLoaderStateChangedObservable = new Observable();
|
177
205
|
this._logIndentLevel = 0;
|
178
206
|
this._loggingEnabled = false;
|
179
207
|
/** @hidden */
|
@@ -388,9 +416,11 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
388
416
|
this.onDisposeObservable.clear();
|
389
417
|
};
|
390
418
|
/** @hidden */
|
391
|
-
GLTFFileLoader.prototype.
|
419
|
+
GLTFFileLoader.prototype.loadFile = function (scene, fileOrUrl, onSuccess, onProgress, useArrayBuffer, onError) {
|
392
420
|
var _this = this;
|
393
421
|
this._progressCallback = onProgress;
|
422
|
+
var rootUrl = fileOrUrl.name ? "file:" : Tools.GetFolderPath(fileOrUrl);
|
423
|
+
var fileName = fileOrUrl.name || Tools.GetFilename(fileOrUrl);
|
394
424
|
if (useArrayBuffer) {
|
395
425
|
if (this.useRangeRequests) {
|
396
426
|
if (this.validate) {
|
@@ -403,12 +433,12 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
403
433
|
var dataBuffer = {
|
404
434
|
readAsync: function (byteOffset, byteLength) {
|
405
435
|
return new Promise(function (resolve, reject) {
|
406
|
-
_this.
|
436
|
+
_this._loadFile(scene, fileOrUrl, function (data) {
|
407
437
|
resolve(new Uint8Array(data));
|
408
438
|
}, true, function (error) {
|
409
439
|
reject(error);
|
410
440
|
}, function (webRequest) {
|
411
|
-
webRequest.setRequestHeader("Range", "bytes="
|
441
|
+
webRequest.setRequestHeader("Range", "bytes=".concat(byteOffset, "-").concat(byteOffset + byteLength - 1));
|
412
442
|
});
|
413
443
|
});
|
414
444
|
},
|
@@ -417,50 +447,33 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
417
447
|
this._unpackBinaryAsync(new DataReader(dataBuffer)).then(function (loaderData) {
|
418
448
|
fileRequest_1.onCompleteObservable.notifyObservers(fileRequest_1);
|
419
449
|
onSuccess(loaderData);
|
420
|
-
}, onError);
|
450
|
+
}, onError ? function (error) { return onError(undefined, error); } : undefined);
|
421
451
|
return fileRequest_1;
|
422
452
|
}
|
423
|
-
return this.
|
424
|
-
|
453
|
+
return this._loadFile(scene, fileOrUrl, function (data) {
|
454
|
+
_this._validate(scene, data, rootUrl, fileName);
|
425
455
|
_this._unpackBinaryAsync(new DataReader({
|
426
|
-
readAsync: function (byteOffset, byteLength) { return
|
427
|
-
byteLength:
|
456
|
+
readAsync: function (byteOffset, byteLength) { return readAsync(data, byteOffset, byteLength); },
|
457
|
+
byteLength: data.byteLength
|
428
458
|
})).then(function (loaderData) {
|
429
|
-
onSuccess(loaderData
|
430
|
-
}, onError);
|
459
|
+
onSuccess(loaderData);
|
460
|
+
}, onError ? function (error) { return onError(undefined, error); } : undefined);
|
431
461
|
}, true, onError);
|
432
462
|
}
|
433
|
-
return this.
|
434
|
-
_this._validate(scene, data,
|
435
|
-
onSuccess({ json: _this._parseJson(data) }
|
463
|
+
return this._loadFile(scene, fileOrUrl, function (data) {
|
464
|
+
_this._validate(scene, data, rootUrl, fileName);
|
465
|
+
onSuccess({ json: _this._parseJson(data) });
|
436
466
|
}, useArrayBuffer, onError);
|
437
467
|
};
|
438
468
|
/** @hidden */
|
439
|
-
GLTFFileLoader.prototype.readFile = function (scene, file, onSuccess, onProgress, useArrayBuffer, onError) {
|
440
|
-
var _this = this;
|
441
|
-
return scene._readFile(file, function (data) {
|
442
|
-
_this._validate(scene, data, "file:", file.name);
|
443
|
-
if (useArrayBuffer) {
|
444
|
-
var arrayBuffer_1 = data;
|
445
|
-
_this._unpackBinaryAsync(new DataReader({
|
446
|
-
readAsync: function (byteOffset, byteLength) { return Promise.resolve(new Uint8Array(arrayBuffer_1, byteOffset, byteLength)); },
|
447
|
-
byteLength: arrayBuffer_1.byteLength
|
448
|
-
})).then(onSuccess, onError);
|
449
|
-
}
|
450
|
-
else {
|
451
|
-
onSuccess({ json: _this._parseJson(data) });
|
452
|
-
}
|
453
|
-
}, onProgress, useArrayBuffer, onError);
|
454
|
-
};
|
455
|
-
/** @hidden */
|
456
469
|
GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress, fileName) {
|
457
470
|
var _this = this;
|
458
471
|
return Promise.resolve().then(function () {
|
459
472
|
_this.onParsedObservable.notifyObservers(data);
|
460
473
|
_this.onParsedObservable.clear();
|
461
|
-
_this._log("Loading "
|
474
|
+
_this._log("Loading ".concat(fileName || ""));
|
462
475
|
_this._loader = _this._getLoader(data);
|
463
|
-
return _this._loader.importMeshAsync(meshesNames, scene,
|
476
|
+
return _this._loader.importMeshAsync(meshesNames, scene, null, data, rootUrl, onProgress, fileName);
|
464
477
|
});
|
465
478
|
};
|
466
479
|
/** @hidden */
|
@@ -469,7 +482,7 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
469
482
|
return Promise.resolve().then(function () {
|
470
483
|
_this.onParsedObservable.notifyObservers(data);
|
471
484
|
_this.onParsedObservable.clear();
|
472
|
-
_this._log("Loading "
|
485
|
+
_this._log("Loading ".concat(fileName || ""));
|
473
486
|
_this._loader = _this._getLoader(data);
|
474
487
|
return _this._loader.loadAsync(scene, data, rootUrl, onProgress, fileName);
|
475
488
|
});
|
@@ -480,7 +493,7 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
480
493
|
return Promise.resolve().then(function () {
|
481
494
|
_this.onParsedObservable.notifyObservers(data);
|
482
495
|
_this.onParsedObservable.clear();
|
483
|
-
_this._log("Loading "
|
496
|
+
_this._log("Loading ".concat(fileName || ""));
|
484
497
|
_this._loader = _this._getLoader(data);
|
485
498
|
// Prepare the asset container.
|
486
499
|
var container = new AssetContainer(scene);
|
@@ -488,36 +501,16 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
488
501
|
var materials = [];
|
489
502
|
_this.onMaterialLoadedObservable.add(function (material) {
|
490
503
|
materials.push(material);
|
491
|
-
material.onDisposeObservable.addOnce(function () {
|
492
|
-
var index = container.materials.indexOf(material);
|
493
|
-
if (index > -1) {
|
494
|
-
container.materials.splice(index, 1);
|
495
|
-
}
|
496
|
-
index = materials.indexOf(material);
|
497
|
-
if (index > -1) {
|
498
|
-
materials.splice(index, 1);
|
499
|
-
}
|
500
|
-
});
|
501
504
|
});
|
502
505
|
var textures = [];
|
503
506
|
_this.onTextureLoadedObservable.add(function (texture) {
|
504
507
|
textures.push(texture);
|
505
|
-
texture.onDisposeObservable.addOnce(function () {
|
506
|
-
var index = container.textures.indexOf(texture);
|
507
|
-
if (index > -1) {
|
508
|
-
container.textures.splice(index, 1);
|
509
|
-
}
|
510
|
-
index = textures.indexOf(texture);
|
511
|
-
if (index > -1) {
|
512
|
-
textures.splice(index, 1);
|
513
|
-
}
|
514
|
-
});
|
515
508
|
});
|
516
509
|
var cameras = [];
|
517
510
|
_this.onCameraLoadedObservable.add(function (camera) {
|
518
511
|
cameras.push(camera);
|
519
512
|
});
|
520
|
-
return _this._loader.importMeshAsync(null, scene,
|
513
|
+
return _this._loader.importMeshAsync(null, scene, container, data, rootUrl, onProgress, fileName).then(function (result) {
|
521
514
|
Array.prototype.push.apply(container.geometries, result.geometries);
|
522
515
|
Array.prototype.push.apply(container.meshes, result.meshes);
|
523
516
|
Array.prototype.push.apply(container.particleSystems, result.particleSystems);
|
@@ -535,20 +528,22 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
535
528
|
/** @hidden */
|
536
529
|
GLTFFileLoader.prototype.canDirectLoad = function (data) {
|
537
530
|
return (data.indexOf("asset") !== -1 && data.indexOf("version") !== -1)
|
538
|
-
|| StringTools.StartsWith(data, "data:base64," + GLTFFileLoader.magicBase64Encoded)
|
531
|
+
|| StringTools.StartsWith(data, "data:base64," + GLTFFileLoader.magicBase64Encoded) // this is technically incorrect, but will continue to support for backcompat.
|
532
|
+
|| StringTools.StartsWith(data, "data:;base64," + GLTFFileLoader.magicBase64Encoded)
|
539
533
|
|| StringTools.StartsWith(data, "data:application/octet-stream;base64," + GLTFFileLoader.magicBase64Encoded)
|
540
534
|
|| StringTools.StartsWith(data, "data:model/gltf-binary;base64," + GLTFFileLoader.magicBase64Encoded);
|
541
535
|
};
|
542
536
|
/** @hidden */
|
543
537
|
GLTFFileLoader.prototype.directLoad = function (scene, data) {
|
544
|
-
if (StringTools.StartsWith(data, "base64," + GLTFFileLoader.magicBase64Encoded) ||
|
538
|
+
if (StringTools.StartsWith(data, "base64," + GLTFFileLoader.magicBase64Encoded) || // this is technically incorrect, but will continue to support for backcompat.
|
539
|
+
StringTools.StartsWith(data, ";base64," + GLTFFileLoader.magicBase64Encoded) ||
|
545
540
|
StringTools.StartsWith(data, "application/octet-stream;base64," + GLTFFileLoader.magicBase64Encoded) ||
|
546
541
|
StringTools.StartsWith(data, "model/gltf-binary;base64," + GLTFFileLoader.magicBase64Encoded)) {
|
547
|
-
var
|
548
|
-
this._validate(scene,
|
542
|
+
var arrayBuffer_1 = DecodeBase64UrlToBinary(data);
|
543
|
+
this._validate(scene, arrayBuffer_1);
|
549
544
|
return this._unpackBinaryAsync(new DataReader({
|
550
|
-
readAsync: function (byteOffset, byteLength) { return
|
551
|
-
byteLength:
|
545
|
+
readAsync: function (byteOffset, byteLength) { return readAsync(arrayBuffer_1, byteOffset, byteLength); },
|
546
|
+
byteLength: arrayBuffer_1.byteLength
|
552
547
|
}));
|
553
548
|
}
|
554
549
|
this._validate(scene, data);
|
@@ -563,7 +558,7 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
563
558
|
* The loader state or null if the loader is not active.
|
564
559
|
*/
|
565
560
|
get: function () {
|
566
|
-
return this.
|
561
|
+
return this._state;
|
567
562
|
},
|
568
563
|
enumerable: false,
|
569
564
|
configurable: true
|
@@ -584,23 +579,20 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
584
579
|
});
|
585
580
|
};
|
586
581
|
/** @hidden */
|
587
|
-
GLTFFileLoader.prototype.
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
});
|
595
|
-
this._requests.push(request);
|
596
|
-
return request;
|
582
|
+
GLTFFileLoader.prototype._setState = function (state) {
|
583
|
+
if (this._state === state) {
|
584
|
+
return;
|
585
|
+
}
|
586
|
+
this._state = state;
|
587
|
+
this.onLoaderStateChangedObservable.notifyObservers(this._state);
|
588
|
+
this._log(GLTFLoaderState[this._state]);
|
597
589
|
};
|
598
590
|
/** @hidden */
|
599
|
-
GLTFFileLoader.prototype.
|
591
|
+
GLTFFileLoader.prototype._loadFile = function (scene, fileOrUrl, onSuccess, useArrayBuffer, onError, onOpened) {
|
600
592
|
var _this = this;
|
601
|
-
var request = scene.
|
593
|
+
var request = scene._loadFile(fileOrUrl, onSuccess, function (event) {
|
602
594
|
_this._onProgress(event, request);
|
603
|
-
},
|
595
|
+
}, true, useArrayBuffer, onError, onOpened);
|
604
596
|
request.onCompleteObservable.add(function (request) {
|
605
597
|
_this._requests.splice(_this._requests.indexOf(request), 1);
|
606
598
|
});
|
@@ -648,15 +640,15 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
648
640
|
_this.onValidatedObservable.clear();
|
649
641
|
}, function (reason) {
|
650
642
|
_this._endPerformanceCounter("Validate JSON");
|
651
|
-
Tools.Warn("Failed to validate: "
|
643
|
+
Tools.Warn("Failed to validate: ".concat(reason.message));
|
652
644
|
_this.onValidatedObservable.clear();
|
653
645
|
});
|
654
646
|
};
|
655
647
|
GLTFFileLoader.prototype._getLoader = function (loaderData) {
|
656
648
|
var asset = loaderData.json.asset || {};
|
657
|
-
this._log("Asset version: "
|
658
|
-
asset.minVersion && this._log("Asset minimum version: "
|
659
|
-
asset.generator && this._log("Asset generator: "
|
649
|
+
this._log("Asset version: ".concat(asset.version));
|
650
|
+
asset.minVersion && this._log("Asset minimum version: ".concat(asset.minVersion));
|
651
|
+
asset.generator && this._log("Asset generator: ".concat(asset.generator));
|
660
652
|
var version = GLTFFileLoader._parseVersion(asset.version);
|
661
653
|
if (!version) {
|
662
654
|
throw new Error("Invalid version: " + asset.version);
|
@@ -682,7 +674,7 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
682
674
|
};
|
683
675
|
GLTFFileLoader.prototype._parseJson = function (json) {
|
684
676
|
this._startPerformanceCounter("Parse JSON");
|
685
|
-
this._log("JSON length: "
|
677
|
+
this._log("JSON length: ".concat(json.length));
|
686
678
|
var parsed = JSON.parse(json);
|
687
679
|
this._endPerformanceCounter("Parse JSON");
|
688
680
|
return parsed;
|
@@ -697,15 +689,15 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
697
689
|
};
|
698
690
|
var magic = dataReader.readUint32();
|
699
691
|
if (magic !== Binary.Magic) {
|
700
|
-
throw new
|
692
|
+
throw new RuntimeError("Unexpected magic: " + magic, ErrorCodes.GLTFLoaderUnexpectedMagicError);
|
701
693
|
}
|
702
694
|
var version = dataReader.readUint32();
|
703
695
|
if (_this.loggingEnabled) {
|
704
|
-
_this._log("Binary version: "
|
696
|
+
_this._log("Binary version: ".concat(version));
|
705
697
|
}
|
706
698
|
var length = dataReader.readUint32();
|
707
699
|
if (dataReader.buffer.byteLength !== 0 && length !== dataReader.buffer.byteLength) {
|
708
|
-
throw new Error("Length in header does not match actual data length: "
|
700
|
+
throw new Error("Length in header does not match actual data length: ".concat(length, " != ").concat(dataReader.buffer.byteLength));
|
709
701
|
}
|
710
702
|
var unpacked;
|
711
703
|
switch (version) {
|
@@ -732,7 +724,7 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
732
724
|
var contentLength = dataReader.readUint32();
|
733
725
|
var contentFormat = dataReader.readUint32();
|
734
726
|
if (contentFormat !== ContentFormat.JSON) {
|
735
|
-
throw new Error("Unexpected content format: "
|
727
|
+
throw new Error("Unexpected content format: ".concat(contentFormat));
|
736
728
|
}
|
737
729
|
var bodyLength = length - dataReader.byteOffset;
|
738
730
|
var data = { json: this._parseJson(dataReader.readString(contentLength)), bin: null };
|
@@ -838,7 +830,7 @@ var GLTFFileLoader = /** @class */ (function () {
|
|
838
830
|
};
|
839
831
|
GLTFFileLoader.prototype._logEnabled = function (message) {
|
840
832
|
var spaces = GLTFFileLoader._logSpaces.substr(0, this._logIndentLevel * 2);
|
841
|
-
Logger.Log(""
|
833
|
+
Logger.Log("".concat(spaces).concat(message));
|
842
834
|
};
|
843
835
|
GLTFFileLoader.prototype._logDisabled = function (message) {
|
844
836
|
};
|