@babylonjs/loaders 7.30.0 → 7.31.0
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/SPLAT/splatFileLoader.js +10 -240
- package/SPLAT/splatFileLoader.js.map +1 -1
- package/glTF/2.0/glTFLoader.js +8 -0
- package/glTF/2.0/glTFLoader.js.map +1 -1
- package/glTF/glTFFileLoader.d.ts +5 -0
- package/glTF/glTFFileLoader.js +6 -0
- package/glTF/glTFFileLoader.js.map +1 -1
- package/package.json +3 -3
package/SPLAT/splatFileLoader.js
CHANGED
|
@@ -4,11 +4,10 @@ import { GaussianSplattingMesh } from "@babylonjs/core/Meshes/GaussianSplatting/
|
|
|
4
4
|
import { AssetContainer } from "@babylonjs/core/assetContainer.js";
|
|
5
5
|
import { Mesh } from "@babylonjs/core/Meshes/mesh.js";
|
|
6
6
|
import { Logger } from "@babylonjs/core/Misc/logger.js";
|
|
7
|
-
import {
|
|
7
|
+
import { Vector3 } from "@babylonjs/core/Maths/math.vector.js";
|
|
8
8
|
import { PointsCloudSystem } from "@babylonjs/core/Particles/pointsCloudSystem.js";
|
|
9
9
|
import { Color4 } from "@babylonjs/core/Maths/math.color.js";
|
|
10
10
|
import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData.js";
|
|
11
|
-
import { Scalar } from "@babylonjs/core/Maths/math.scalar.js";
|
|
12
11
|
/**
|
|
13
12
|
* Indicator of the parsed ply buffer. A standard ready to use splat or an array of positions for a point cloud
|
|
14
13
|
*/
|
|
@@ -18,12 +17,6 @@ var Mode;
|
|
|
18
17
|
Mode[Mode["PointCloud"] = 1] = "PointCloud";
|
|
19
18
|
Mode[Mode["Mesh"] = 2] = "Mesh";
|
|
20
19
|
})(Mode || (Mode = {}));
|
|
21
|
-
/** @internal */
|
|
22
|
-
var ElementMode;
|
|
23
|
-
(function (ElementMode) {
|
|
24
|
-
ElementMode[ElementMode["Vertex"] = 0] = "Vertex";
|
|
25
|
-
ElementMode[ElementMode["Chunk"] = 1] = "Chunk";
|
|
26
|
-
})(ElementMode || (ElementMode = {}));
|
|
27
20
|
/**
|
|
28
21
|
* @experimental
|
|
29
22
|
* SPLAT file type loader.
|
|
@@ -223,12 +216,12 @@ export class SPLATFileLoader {
|
|
|
223
216
|
}
|
|
224
217
|
const vertexCount = parseInt(/element vertex (\d+)\n/.exec(header)[1]);
|
|
225
218
|
const faceElement = /element face (\d+)\n/.exec(header);
|
|
226
|
-
const chunkElement = /element chunk (\d+)\n/.exec(header);
|
|
227
219
|
let faceCount = 0;
|
|
228
|
-
let chunkCount = 0;
|
|
229
220
|
if (faceElement) {
|
|
230
221
|
faceCount = parseInt(faceElement[1]);
|
|
231
222
|
}
|
|
223
|
+
const chunkElement = /element chunk (\d+)\n/.exec(header);
|
|
224
|
+
let chunkCount = 0;
|
|
232
225
|
if (chunkElement) {
|
|
233
226
|
chunkCount = parseInt(chunkElement[1]);
|
|
234
227
|
}
|
|
@@ -244,6 +237,11 @@ export class SPLATFileLoader {
|
|
|
244
237
|
uchar: 1,
|
|
245
238
|
list: 0,
|
|
246
239
|
};
|
|
240
|
+
let ElementMode;
|
|
241
|
+
(function (ElementMode) {
|
|
242
|
+
ElementMode[ElementMode["Vertex"] = 0] = "Vertex";
|
|
243
|
+
ElementMode[ElementMode["Chunk"] = 1] = "Chunk";
|
|
244
|
+
})(ElementMode || (ElementMode = {}));
|
|
247
245
|
let chunkMode = 1 /* ElementMode.Chunk */;
|
|
248
246
|
const vertexProperties = [];
|
|
249
247
|
const chunkProperties = [];
|
|
@@ -275,237 +273,9 @@ export class SPLATFileLoader {
|
|
|
275
273
|
}
|
|
276
274
|
const rowVertexLength = rowVertexOffset;
|
|
277
275
|
const rowChunkLength = rowChunkOffset;
|
|
278
|
-
const
|
|
279
|
-
const SH_C0 = 0.28209479177387814;
|
|
280
|
-
let offset = 0;
|
|
276
|
+
const buffer = GaussianSplattingMesh.ConvertPLYToSplat(data);
|
|
281
277
|
const dataView = new DataView(data, headerEndIndex + headerEnd.length);
|
|
282
|
-
|
|
283
|
-
const q = new Quaternion();
|
|
284
|
-
const temp3 = TmpVectors.Vector3[0];
|
|
285
|
-
const unpackUnorm = (value, bits) => {
|
|
286
|
-
const t = (1 << bits) - 1;
|
|
287
|
-
return (value & t) / t;
|
|
288
|
-
};
|
|
289
|
-
const unpack111011 = (value, result) => {
|
|
290
|
-
result.x = unpackUnorm(value >>> 21, 11);
|
|
291
|
-
result.y = unpackUnorm(value >>> 11, 10);
|
|
292
|
-
result.z = unpackUnorm(value, 11);
|
|
293
|
-
};
|
|
294
|
-
const unpack8888 = (value, result) => {
|
|
295
|
-
result[0] = unpackUnorm(value >>> 24, 8) * 255;
|
|
296
|
-
result[1] = unpackUnorm(value >>> 16, 8) * 255;
|
|
297
|
-
result[2] = unpackUnorm(value >>> 8, 8) * 255;
|
|
298
|
-
result[3] = unpackUnorm(value, 8) * 255;
|
|
299
|
-
};
|
|
300
|
-
// unpack quaternion with 2,10,10,10 format (largest element, 3x10bit element)
|
|
301
|
-
const unpackRot = (value, result) => {
|
|
302
|
-
const norm = 1.0 / (Math.sqrt(2) * 0.5);
|
|
303
|
-
const a = (unpackUnorm(value >>> 20, 10) - 0.5) * norm;
|
|
304
|
-
const b = (unpackUnorm(value >>> 10, 10) - 0.5) * norm;
|
|
305
|
-
const c = (unpackUnorm(value, 10) - 0.5) * norm;
|
|
306
|
-
const m = Math.sqrt(1.0 - (a * a + b * b + c * c));
|
|
307
|
-
switch (value >>> 30) {
|
|
308
|
-
case 0:
|
|
309
|
-
result.set(m, a, b, c);
|
|
310
|
-
break;
|
|
311
|
-
case 1:
|
|
312
|
-
result.set(a, m, b, c);
|
|
313
|
-
break;
|
|
314
|
-
case 2:
|
|
315
|
-
result.set(a, b, m, c);
|
|
316
|
-
break;
|
|
317
|
-
case 3:
|
|
318
|
-
result.set(a, b, c, m);
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
const compressedChunks = new Array(chunkCount);
|
|
323
|
-
for (let i = 0; i < chunkCount; i++) {
|
|
324
|
-
const currentChunk = { min: new Vector3(), max: new Vector3(), minScale: new Vector3(), maxScale: new Vector3() };
|
|
325
|
-
compressedChunks[i] = currentChunk;
|
|
326
|
-
for (let propertyIndex = 0; propertyIndex < chunkProperties.length; propertyIndex++) {
|
|
327
|
-
const property = chunkProperties[propertyIndex];
|
|
328
|
-
let value;
|
|
329
|
-
switch (property.type) {
|
|
330
|
-
case "float":
|
|
331
|
-
value = dataView.getFloat32(property.offset + offset, true);
|
|
332
|
-
break;
|
|
333
|
-
default:
|
|
334
|
-
//throw new Error(`Unsupported property type: ${property.type}`);
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
switch (property.name) {
|
|
338
|
-
case "min_x":
|
|
339
|
-
currentChunk.min.x = value;
|
|
340
|
-
break;
|
|
341
|
-
case "min_y":
|
|
342
|
-
currentChunk.min.y = value;
|
|
343
|
-
break;
|
|
344
|
-
case "min_z":
|
|
345
|
-
currentChunk.min.z = value;
|
|
346
|
-
break;
|
|
347
|
-
case "max_x":
|
|
348
|
-
currentChunk.max.x = value;
|
|
349
|
-
break;
|
|
350
|
-
case "max_y":
|
|
351
|
-
currentChunk.max.y = value;
|
|
352
|
-
break;
|
|
353
|
-
case "max_z":
|
|
354
|
-
currentChunk.max.z = value;
|
|
355
|
-
break;
|
|
356
|
-
case "min_scale_x":
|
|
357
|
-
currentChunk.minScale.x = value;
|
|
358
|
-
break;
|
|
359
|
-
case "min_scale_y":
|
|
360
|
-
currentChunk.minScale.y = value;
|
|
361
|
-
break;
|
|
362
|
-
case "min_scale_z":
|
|
363
|
-
currentChunk.minScale.z = value;
|
|
364
|
-
break;
|
|
365
|
-
case "max_scale_x":
|
|
366
|
-
currentChunk.maxScale.x = value;
|
|
367
|
-
break;
|
|
368
|
-
case "max_scale_y":
|
|
369
|
-
currentChunk.maxScale.y = value;
|
|
370
|
-
break;
|
|
371
|
-
case "max_scale_z":
|
|
372
|
-
currentChunk.maxScale.z = value;
|
|
373
|
-
break;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
offset += rowChunkLength;
|
|
377
|
-
}
|
|
378
|
-
for (let i = 0; i < vertexCount; i++) {
|
|
379
|
-
const position = new Float32Array(buffer, i * rowOutputLength, 3);
|
|
380
|
-
const scale = new Float32Array(buffer, i * rowOutputLength + 12, 3);
|
|
381
|
-
const rgba = new Uint8ClampedArray(buffer, i * rowOutputLength + 24, 4);
|
|
382
|
-
const rot = new Uint8ClampedArray(buffer, i * rowOutputLength + 28, 4);
|
|
383
|
-
const chunkIndex = i >> 8;
|
|
384
|
-
let r0 = 255;
|
|
385
|
-
let r1 = 0;
|
|
386
|
-
let r2 = 0;
|
|
387
|
-
let r3 = 0;
|
|
388
|
-
for (let propertyIndex = 0; propertyIndex < vertexProperties.length; propertyIndex++) {
|
|
389
|
-
const property = vertexProperties[propertyIndex];
|
|
390
|
-
let value;
|
|
391
|
-
switch (property.type) {
|
|
392
|
-
case "float":
|
|
393
|
-
value = dataView.getFloat32(offset + property.offset, true);
|
|
394
|
-
break;
|
|
395
|
-
case "int":
|
|
396
|
-
value = dataView.getInt32(offset + property.offset, true);
|
|
397
|
-
break;
|
|
398
|
-
case "uint":
|
|
399
|
-
value = dataView.getUint32(offset + property.offset, true);
|
|
400
|
-
break;
|
|
401
|
-
case "double":
|
|
402
|
-
value = dataView.getFloat64(offset + property.offset, true);
|
|
403
|
-
break;
|
|
404
|
-
case "uchar":
|
|
405
|
-
value = dataView.getUint8(offset + property.offset);
|
|
406
|
-
break;
|
|
407
|
-
default:
|
|
408
|
-
//throw new Error(`Unsupported property type: ${property.type}`);
|
|
409
|
-
continue;
|
|
410
|
-
}
|
|
411
|
-
switch (property.name) {
|
|
412
|
-
case "packed_position":
|
|
413
|
-
{
|
|
414
|
-
const compressedChunk = compressedChunks[chunkIndex];
|
|
415
|
-
unpack111011(value, temp3);
|
|
416
|
-
position[0] = Scalar.Lerp(compressedChunk.min.x, compressedChunk.max.x, temp3.x);
|
|
417
|
-
position[1] = -Scalar.Lerp(compressedChunk.min.y, compressedChunk.max.y, temp3.y);
|
|
418
|
-
position[2] = Scalar.Lerp(compressedChunk.min.z, compressedChunk.max.z, temp3.z);
|
|
419
|
-
}
|
|
420
|
-
break;
|
|
421
|
-
case "packed_rotation":
|
|
422
|
-
{
|
|
423
|
-
unpackRot(value, q);
|
|
424
|
-
r0 = q.w;
|
|
425
|
-
r1 = q.z;
|
|
426
|
-
r2 = q.y;
|
|
427
|
-
r3 = q.x;
|
|
428
|
-
}
|
|
429
|
-
break;
|
|
430
|
-
case "packed_scale":
|
|
431
|
-
{
|
|
432
|
-
const compressedChunk = compressedChunks[chunkIndex];
|
|
433
|
-
unpack111011(value, temp3);
|
|
434
|
-
scale[0] = Math.exp(Scalar.Lerp(compressedChunk.minScale.x, compressedChunk.maxScale.x, temp3.x));
|
|
435
|
-
scale[1] = Math.exp(Scalar.Lerp(compressedChunk.minScale.y, compressedChunk.maxScale.y, temp3.y));
|
|
436
|
-
scale[2] = Math.exp(Scalar.Lerp(compressedChunk.minScale.z, compressedChunk.maxScale.z, temp3.z));
|
|
437
|
-
}
|
|
438
|
-
break;
|
|
439
|
-
case "packed_color":
|
|
440
|
-
unpack8888(value, rgba);
|
|
441
|
-
break;
|
|
442
|
-
case "x":
|
|
443
|
-
position[0] = value;
|
|
444
|
-
break;
|
|
445
|
-
case "y":
|
|
446
|
-
position[1] = value;
|
|
447
|
-
break;
|
|
448
|
-
case "z":
|
|
449
|
-
position[2] = value;
|
|
450
|
-
break;
|
|
451
|
-
case "scale_0":
|
|
452
|
-
scale[0] = Math.exp(value);
|
|
453
|
-
break;
|
|
454
|
-
case "scale_1":
|
|
455
|
-
scale[1] = Math.exp(value);
|
|
456
|
-
break;
|
|
457
|
-
case "scale_2":
|
|
458
|
-
scale[2] = Math.exp(value);
|
|
459
|
-
break;
|
|
460
|
-
case "diffuse_red":
|
|
461
|
-
case "red":
|
|
462
|
-
rgba[0] = value;
|
|
463
|
-
break;
|
|
464
|
-
case "diffuse_green":
|
|
465
|
-
case "green":
|
|
466
|
-
rgba[1] = value;
|
|
467
|
-
break;
|
|
468
|
-
case "diffuse_blue":
|
|
469
|
-
case "blue":
|
|
470
|
-
rgba[2] = value;
|
|
471
|
-
break;
|
|
472
|
-
case "f_dc_0":
|
|
473
|
-
rgba[0] = (0.5 + SH_C0 * value) * 255;
|
|
474
|
-
break;
|
|
475
|
-
case "f_dc_1":
|
|
476
|
-
rgba[1] = (0.5 + SH_C0 * value) * 255;
|
|
477
|
-
break;
|
|
478
|
-
case "f_dc_2":
|
|
479
|
-
rgba[2] = (0.5 + SH_C0 * value) * 255;
|
|
480
|
-
break;
|
|
481
|
-
case "f_dc_3":
|
|
482
|
-
rgba[3] = (0.5 + SH_C0 * value) * 255;
|
|
483
|
-
break;
|
|
484
|
-
case "opacity":
|
|
485
|
-
rgba[3] = (1 / (1 + Math.exp(-value))) * 255;
|
|
486
|
-
break;
|
|
487
|
-
case "rot_0":
|
|
488
|
-
r0 = value;
|
|
489
|
-
break;
|
|
490
|
-
case "rot_1":
|
|
491
|
-
r1 = value;
|
|
492
|
-
break;
|
|
493
|
-
case "rot_2":
|
|
494
|
-
r2 = value;
|
|
495
|
-
break;
|
|
496
|
-
case "rot_3":
|
|
497
|
-
r3 = value;
|
|
498
|
-
break;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
q.set(r1, r2, r3, r0);
|
|
502
|
-
q.normalize();
|
|
503
|
-
rot[0] = q.w * 128 + 128;
|
|
504
|
-
rot[1] = q.x * 128 + 128;
|
|
505
|
-
rot[2] = q.y * 128 + 128;
|
|
506
|
-
rot[3] = q.z * 128 + 128;
|
|
507
|
-
offset += rowVertexLength;
|
|
508
|
-
}
|
|
278
|
+
let offset = rowChunkLength * chunkCount + rowVertexLength * vertexCount;
|
|
509
279
|
// faces
|
|
510
280
|
const faces = [];
|
|
511
281
|
if (faceCount) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"splatFileLoader.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/splatFileLoader.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ISceneLoaderPluginAsync, ISceneLoaderPluginFactory, ISceneLoaderAsyncResult, ISceneLoaderProgressEvent, SceneLoaderPluginOptions } from \"core/Loading/sceneLoader\";\r\nimport { registerSceneLoaderPlugin } from \"core/Loading/sceneLoader\";\r\nimport { SPLATFileLoaderMetadata } from \"./splatFileLoader.metadata\";\r\nimport { GaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplattingMesh\";\r\nimport { AssetContainer } from \"core/assetContainer\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Quaternion, TmpVectors, Vector3 } from \"core/Maths/math.vector\";\r\nimport { PointsCloudSystem } from \"core/Particles/pointsCloudSystem\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport type { SPLATLoadingOptions } from \"./splatLoadingOptions\";\r\nimport { Scalar } from \"core/Maths/math.scalar\";\r\n\r\ndeclare module \"core/Loading/sceneLoader\" {\r\n // eslint-disable-next-line jsdoc/require-jsdoc\r\n export interface SceneLoaderPluginOptions {\r\n /**\r\n * Defines options for the splat loader.\r\n */\r\n [SPLATFileLoaderMetadata.name]: Partial<SPLATLoadingOptions>;\r\n }\r\n}\r\n\r\n/**\r\n * Indicator of the parsed ply buffer. A standard ready to use splat or an array of positions for a point cloud\r\n */\r\nconst enum Mode {\r\n Splat = 0,\r\n PointCloud = 1,\r\n Mesh = 2,\r\n}\r\n\r\n/**\r\n * A parsed buffer and how to use it\r\n */\r\ninterface ParsedPLY {\r\n data: ArrayBuffer;\r\n mode: Mode;\r\n faces?: number[];\r\n hasVertexColors?: boolean;\r\n}\r\n\r\n/** @internal */\r\ninterface CompressedPLYChunk {\r\n min: Vector3;\r\n max: Vector3;\r\n minScale: Vector3;\r\n maxScale: Vector3;\r\n}\r\n\r\n/** @internal */\r\nconst enum ElementMode {\r\n Vertex = 0,\r\n Chunk = 1,\r\n}\r\n\r\n/**\r\n * @experimental\r\n * SPLAT file type loader.\r\n * This is a babylon scene loader plugin.\r\n */\r\nexport class SPLATFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {\r\n /**\r\n * Defines the name of the plugin.\r\n */\r\n public readonly name = SPLATFileLoaderMetadata.name;\r\n\r\n private _assetContainer: Nullable<AssetContainer> = null;\r\n\r\n private readonly _loadingOptions: Readonly<SPLATLoadingOptions>;\r\n /**\r\n * Defines the extensions the splat loader is able to load.\r\n * force data to come in as an ArrayBuffer\r\n */\r\n public readonly extensions = SPLATFileLoaderMetadata.extensions;\r\n\r\n /**\r\n * Creates loader for gaussian splatting files\r\n * @param loadingOptions options for loading and parsing splat and PLY files.\r\n */\r\n constructor(loadingOptions: Partial<Readonly<SPLATLoadingOptions>> = SPLATFileLoader._DefaultLoadingOptions) {\r\n this._loadingOptions = loadingOptions;\r\n }\r\n\r\n private static readonly _DefaultLoadingOptions = {\r\n keepInRam: false,\r\n } as const satisfies SPLATLoadingOptions;\r\n\r\n /** @internal */\r\n createPlugin(options: SceneLoaderPluginOptions): ISceneLoaderPluginAsync {\r\n return new SPLATFileLoader(options[SPLATFileLoaderMetadata.name]);\r\n }\r\n\r\n /**\r\n * Imports from the loaded gaussian splatting data and adds them to the scene\r\n * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file\r\n * @param scene the scene the meshes should be added to\r\n * @param data the gaussian splatting data to load\r\n * @param rootUrl root url to load from\r\n * @param onProgress callback called while file is loading\r\n * @param fileName Defines the name of the file to load\r\n * @returns a promise containing the loaded meshes, particles, skeletons and animations\r\n */\r\n public async importMeshAsync(\r\n meshesNames: any,\r\n scene: Scene,\r\n data: any,\r\n rootUrl: string,\r\n onProgress?: (event: ISceneLoaderProgressEvent) => void,\r\n fileName?: string\r\n ): Promise<ISceneLoaderAsyncResult> {\r\n return this._parse(meshesNames, scene, data, rootUrl).then((meshes) => {\r\n return {\r\n meshes: meshes,\r\n particleSystems: [],\r\n skeletons: [],\r\n animationGroups: [],\r\n transformNodes: [],\r\n geometries: [],\r\n lights: [],\r\n spriteManagers: [],\r\n };\r\n });\r\n }\r\n\r\n private static _BuildPointCloud(pointcloud: PointsCloudSystem, data: ArrayBuffer): boolean {\r\n if (!data.byteLength) {\r\n return false;\r\n }\r\n const uBuffer = new Uint8Array(data);\r\n const fBuffer = new Float32Array(data);\r\n\r\n // parsed array contains room for position(3floats), normal(3floats), color (4b), quantized quaternion (4b)\r\n const rowLength = 3 * 4 + 3 * 4 + 4 + 4;\r\n const vertexCount = uBuffer.length / rowLength;\r\n\r\n const pointcloudfunc = function (particle: any, i: number) {\r\n const x = fBuffer[8 * i + 0];\r\n const y = fBuffer[8 * i + 1];\r\n const z = fBuffer[8 * i + 2];\r\n particle.position = new Vector3(x, y, z);\r\n\r\n const r = uBuffer[rowLength * i + 24 + 0] / 255;\r\n const g = uBuffer[rowLength * i + 24 + 1] / 255;\r\n const b = uBuffer[rowLength * i + 24 + 2] / 255;\r\n particle.color = new Color4(r, g, b, 1);\r\n };\r\n\r\n pointcloud.addPoints(vertexCount, pointcloudfunc);\r\n return true;\r\n }\r\n\r\n private static _BuildMesh(scene: Scene, parsedPLY: ParsedPLY): Mesh {\r\n const mesh = new Mesh(\"PLYMesh\", scene);\r\n\r\n const uBuffer = new Uint8Array(parsedPLY.data);\r\n const fBuffer = new Float32Array(parsedPLY.data);\r\n\r\n const rowLength = 3 * 4 + 3 * 4 + 4 + 4;\r\n const vertexCount = uBuffer.length / rowLength;\r\n\r\n const positions = [];\r\n\r\n const vertexData = new VertexData();\r\n for (let i = 0; i < vertexCount; i++) {\r\n const x = fBuffer[8 * i + 0];\r\n const y = fBuffer[8 * i + 1];\r\n const z = fBuffer[8 * i + 2];\r\n positions.push(x, y, z);\r\n }\r\n\r\n if (parsedPLY.hasVertexColors) {\r\n const colors = new Float32Array(vertexCount * 4);\r\n for (let i = 0; i < vertexCount; i++) {\r\n const r = uBuffer[rowLength * i + 24 + 0] / 255;\r\n const g = uBuffer[rowLength * i + 24 + 1] / 255;\r\n const b = uBuffer[rowLength * i + 24 + 2] / 255;\r\n colors[i * 4 + 0] = r;\r\n colors[i * 4 + 1] = g;\r\n colors[i * 4 + 2] = b;\r\n colors[i * 4 + 3] = 1;\r\n }\r\n vertexData.colors = colors;\r\n }\r\n\r\n vertexData.positions = positions;\r\n vertexData.indices = parsedPLY.faces!;\r\n\r\n vertexData.applyToMesh(mesh);\r\n return mesh;\r\n }\r\n\r\n private _parse(meshesNames: any, scene: Scene, data: any, rootUrl: string): Promise<Array<AbstractMesh>> {\r\n const babylonMeshesArray: Array<Mesh> = []; //The mesh for babylon\r\n const parsedPLY = SPLATFileLoader._ConvertPLYToSplat(data as ArrayBuffer);\r\n switch (parsedPLY.mode) {\r\n case Mode.Splat:\r\n {\r\n const gaussianSplatting = new GaussianSplattingMesh(\"GaussianSplatting\", null, scene, this._loadingOptions.keepInRam);\r\n gaussianSplatting._parentContainer = this._assetContainer;\r\n babylonMeshesArray.push(gaussianSplatting);\r\n gaussianSplatting.loadDataAsync(parsedPLY.data);\r\n }\r\n break;\r\n case Mode.PointCloud:\r\n {\r\n const pointcloud = new PointsCloudSystem(\"PointCloud\", 1, scene);\r\n if (SPLATFileLoader._BuildPointCloud(pointcloud, parsedPLY.data)) {\r\n return Promise.all([pointcloud.buildMeshAsync()]).then((mesh) => {\r\n babylonMeshesArray.push(mesh[0]);\r\n return babylonMeshesArray;\r\n });\r\n } else {\r\n pointcloud.dispose();\r\n }\r\n }\r\n break;\r\n case Mode.Mesh:\r\n {\r\n if (parsedPLY.faces) {\r\n babylonMeshesArray.push(SPLATFileLoader._BuildMesh(scene, parsedPLY));\r\n } else {\r\n throw new Error(\"PLY mesh doesn't contain face informations.\");\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(\"Unsupported Splat mode\");\r\n }\r\n return Promise.resolve(babylonMeshesArray);\r\n }\r\n\r\n /**\r\n * Load into an asset container.\r\n * @param scene The scene to load into\r\n * @param data The data to import\r\n * @param rootUrl The root url for scene and resources\r\n * @returns The loaded asset container\r\n */\r\n public loadAssetContainerAsync(scene: Scene, data: string, rootUrl: string): Promise<AssetContainer> {\r\n const container = new AssetContainer(scene);\r\n this._assetContainer = container;\r\n\r\n return this.importMeshAsync(null, scene, data, rootUrl)\r\n .then((result) => {\r\n result.meshes.forEach((mesh) => container.meshes.push(mesh));\r\n // mesh material will be null before 1st rendered frame.\r\n this._assetContainer = null;\r\n return container;\r\n })\r\n .catch((ex) => {\r\n this._assetContainer = null;\r\n throw ex;\r\n });\r\n }\r\n\r\n /**\r\n * Imports all objects from the loaded OBJ data and adds them to the scene\r\n * @param scene the scene the objects should be added to\r\n * @param data the OBJ data to load\r\n * @param rootUrl root url to load from\r\n * @returns a promise which completes when objects have been loaded to the scene\r\n */\r\n public loadAsync(scene: Scene, data: string, rootUrl: string): Promise<void> {\r\n //Get the 3D model\r\n return this.importMeshAsync(null, scene, data, rootUrl).then(() => {\r\n // return void\r\n });\r\n }\r\n\r\n /**\r\n * Code from https://github.com/dylanebert/gsplat.js/blob/main/src/loaders/PLYLoader.ts Under MIT license\r\n * Converts a .ply data array buffer to splat\r\n * if data array buffer is not ply, returns the original buffer\r\n * @param data the .ply data to load\r\n * @returns the loaded splat buffer\r\n */\r\n private static _ConvertPLYToSplat(data: ArrayBuffer): ParsedPLY {\r\n const ubuf = new Uint8Array(data);\r\n const header = new TextDecoder().decode(ubuf.slice(0, 1024 * 10));\r\n const headerEnd = \"end_header\\n\";\r\n const headerEndIndex = header.indexOf(headerEnd);\r\n if (headerEndIndex < 0 || !header) {\r\n // standard splat\r\n return { mode: Mode.Splat, data: data };\r\n }\r\n const vertexCount = parseInt(/element vertex (\\d+)\\n/.exec(header)![1]);\r\n const faceElement = /element face (\\d+)\\n/.exec(header);\r\n const chunkElement = /element chunk (\\d+)\\n/.exec(header);\r\n let faceCount = 0;\r\n let chunkCount = 0;\r\n if (faceElement) {\r\n faceCount = parseInt(faceElement[1]);\r\n }\r\n if (chunkElement) {\r\n chunkCount = parseInt(chunkElement[1]);\r\n }\r\n let rowVertexOffset = 0;\r\n let rowChunkOffset = 0;\r\n const offsets: Record<string, number> = {\r\n double: 8,\r\n int: 4,\r\n uint: 4,\r\n float: 4,\r\n short: 2,\r\n ushort: 2,\r\n uchar: 1,\r\n list: 0,\r\n };\r\n\r\n type PlyProperty = {\r\n name: string;\r\n type: string;\r\n offset: number;\r\n };\r\n let chunkMode = ElementMode.Chunk;\r\n const vertexProperties: PlyProperty[] = [];\r\n const chunkProperties: PlyProperty[] = [];\r\n const filtered = header.slice(0, headerEndIndex).split(\"\\n\");\r\n for (const prop of filtered) {\r\n if (prop.startsWith(\"property \")) {\r\n const [, type, name] = prop.split(\" \");\r\n\r\n if (chunkMode == ElementMode.Chunk) {\r\n chunkProperties.push({ name, type, offset: rowChunkOffset });\r\n rowChunkOffset += offsets[type];\r\n } else if (chunkMode == ElementMode.Vertex) {\r\n vertexProperties.push({ name, type, offset: rowVertexOffset });\r\n rowVertexOffset += offsets[type];\r\n }\r\n\r\n if (!offsets[type]) {\r\n Logger.Warn(`Unsupported property type: ${type}.`);\r\n }\r\n } else if (prop.startsWith(\"element \")) {\r\n const [, type] = prop.split(\" \");\r\n if (type == \"chunk\") {\r\n chunkMode = ElementMode.Chunk;\r\n } else if (type == \"vertex\") {\r\n chunkMode = ElementMode.Vertex;\r\n }\r\n }\r\n }\r\n\r\n const rowVertexLength = rowVertexOffset;\r\n const rowChunkLength = rowChunkOffset;\r\n\r\n const rowOutputLength = 3 * 4 + 3 * 4 + 4 + 4; // Vector3 position, Vector3 scale, 1 u8 quaternion, 1 color with alpha\r\n const SH_C0 = 0.28209479177387814;\r\n let offset = 0;\r\n\r\n const dataView = new DataView(data, headerEndIndex + headerEnd.length);\r\n const buffer = new ArrayBuffer(rowOutputLength * vertexCount);\r\n const q = new Quaternion();\r\n const temp3 = TmpVectors.Vector3[0];\r\n\r\n const unpackUnorm = (value: number, bits: number) => {\r\n const t = (1 << bits) - 1;\r\n return (value & t) / t;\r\n };\r\n\r\n const unpack111011 = (value: number, result: Vector3) => {\r\n result.x = unpackUnorm(value >>> 21, 11);\r\n result.y = unpackUnorm(value >>> 11, 10);\r\n result.z = unpackUnorm(value, 11);\r\n };\r\n\r\n const unpack8888 = (value: number, result: Uint8ClampedArray) => {\r\n result[0] = unpackUnorm(value >>> 24, 8) * 255;\r\n result[1] = unpackUnorm(value >>> 16, 8) * 255;\r\n result[2] = unpackUnorm(value >>> 8, 8) * 255;\r\n result[3] = unpackUnorm(value, 8) * 255;\r\n };\r\n\r\n // unpack quaternion with 2,10,10,10 format (largest element, 3x10bit element)\r\n const unpackRot = (value: number, result: Quaternion) => {\r\n const norm = 1.0 / (Math.sqrt(2) * 0.5);\r\n const a = (unpackUnorm(value >>> 20, 10) - 0.5) * norm;\r\n const b = (unpackUnorm(value >>> 10, 10) - 0.5) * norm;\r\n const c = (unpackUnorm(value, 10) - 0.5) * norm;\r\n const m = Math.sqrt(1.0 - (a * a + b * b + c * c));\r\n\r\n switch (value >>> 30) {\r\n case 0:\r\n result.set(m, a, b, c);\r\n break;\r\n case 1:\r\n result.set(a, m, b, c);\r\n break;\r\n case 2:\r\n result.set(a, b, m, c);\r\n break;\r\n case 3:\r\n result.set(a, b, c, m);\r\n break;\r\n }\r\n };\r\n\r\n const compressedChunks = new Array<CompressedPLYChunk>(chunkCount);\r\n for (let i = 0; i < chunkCount; i++) {\r\n const currentChunk = { min: new Vector3(), max: new Vector3(), minScale: new Vector3(), maxScale: new Vector3() };\r\n compressedChunks[i] = currentChunk;\r\n for (let propertyIndex = 0; propertyIndex < chunkProperties.length; propertyIndex++) {\r\n const property = chunkProperties[propertyIndex];\r\n let value;\r\n switch (property.type) {\r\n case \"float\":\r\n value = dataView.getFloat32(property.offset + offset, true);\r\n break;\r\n default:\r\n //throw new Error(`Unsupported property type: ${property.type}`);\r\n continue;\r\n }\r\n\r\n switch (property.name) {\r\n case \"min_x\":\r\n currentChunk.min.x = value;\r\n break;\r\n case \"min_y\":\r\n currentChunk.min.y = value;\r\n break;\r\n case \"min_z\":\r\n currentChunk.min.z = value;\r\n break;\r\n case \"max_x\":\r\n currentChunk.max.x = value;\r\n break;\r\n case \"max_y\":\r\n currentChunk.max.y = value;\r\n break;\r\n case \"max_z\":\r\n currentChunk.max.z = value;\r\n break;\r\n case \"min_scale_x\":\r\n currentChunk.minScale.x = value;\r\n break;\r\n case \"min_scale_y\":\r\n currentChunk.minScale.y = value;\r\n break;\r\n case \"min_scale_z\":\r\n currentChunk.minScale.z = value;\r\n break;\r\n case \"max_scale_x\":\r\n currentChunk.maxScale.x = value;\r\n break;\r\n case \"max_scale_y\":\r\n currentChunk.maxScale.y = value;\r\n break;\r\n case \"max_scale_z\":\r\n currentChunk.maxScale.z = value;\r\n break;\r\n }\r\n }\r\n offset += rowChunkLength;\r\n }\r\n\r\n for (let i = 0; i < vertexCount; i++) {\r\n const position = new Float32Array(buffer, i * rowOutputLength, 3);\r\n const scale = new Float32Array(buffer, i * rowOutputLength + 12, 3);\r\n const rgba = new Uint8ClampedArray(buffer, i * rowOutputLength + 24, 4);\r\n const rot = new Uint8ClampedArray(buffer, i * rowOutputLength + 28, 4);\r\n const chunkIndex = i >> 8;\r\n let r0: number = 255;\r\n let r1: number = 0;\r\n let r2: number = 0;\r\n let r3: number = 0;\r\n\r\n for (let propertyIndex = 0; propertyIndex < vertexProperties.length; propertyIndex++) {\r\n const property = vertexProperties[propertyIndex];\r\n let value;\r\n switch (property.type) {\r\n case \"float\":\r\n value = dataView.getFloat32(offset + property.offset, true);\r\n break;\r\n case \"int\":\r\n value = dataView.getInt32(offset + property.offset, true);\r\n break;\r\n case \"uint\":\r\n value = dataView.getUint32(offset + property.offset, true);\r\n break;\r\n case \"double\":\r\n value = dataView.getFloat64(offset + property.offset, true);\r\n break;\r\n case \"uchar\":\r\n value = dataView.getUint8(offset + property.offset);\r\n break;\r\n default:\r\n //throw new Error(`Unsupported property type: ${property.type}`);\r\n continue;\r\n }\r\n\r\n switch (property.name) {\r\n case \"packed_position\":\r\n {\r\n const compressedChunk = compressedChunks[chunkIndex];\r\n unpack111011(value, temp3);\r\n position[0] = Scalar.Lerp(compressedChunk.min.x, compressedChunk.max.x, temp3.x);\r\n position[1] = -Scalar.Lerp(compressedChunk.min.y, compressedChunk.max.y, temp3.y);\r\n position[2] = Scalar.Lerp(compressedChunk.min.z, compressedChunk.max.z, temp3.z);\r\n }\r\n break;\r\n case \"packed_rotation\":\r\n {\r\n unpackRot(value, q);\r\n r0 = q.w;\r\n r1 = q.z;\r\n r2 = q.y;\r\n r3 = q.x;\r\n }\r\n break;\r\n case \"packed_scale\":\r\n {\r\n const compressedChunk = compressedChunks[chunkIndex];\r\n unpack111011(value, temp3);\r\n scale[0] = Math.exp(Scalar.Lerp(compressedChunk.minScale.x, compressedChunk.maxScale.x, temp3.x));\r\n scale[1] = Math.exp(Scalar.Lerp(compressedChunk.minScale.y, compressedChunk.maxScale.y, temp3.y));\r\n scale[2] = Math.exp(Scalar.Lerp(compressedChunk.minScale.z, compressedChunk.maxScale.z, temp3.z));\r\n }\r\n break;\r\n case \"packed_color\":\r\n unpack8888(value, rgba);\r\n break;\r\n case \"x\":\r\n position[0] = value;\r\n break;\r\n case \"y\":\r\n position[1] = value;\r\n break;\r\n case \"z\":\r\n position[2] = value;\r\n break;\r\n case \"scale_0\":\r\n scale[0] = Math.exp(value);\r\n break;\r\n case \"scale_1\":\r\n scale[1] = Math.exp(value);\r\n break;\r\n case \"scale_2\":\r\n scale[2] = Math.exp(value);\r\n break;\r\n case \"diffuse_red\":\r\n case \"red\":\r\n rgba[0] = value;\r\n break;\r\n case \"diffuse_green\":\r\n case \"green\":\r\n rgba[1] = value;\r\n break;\r\n case \"diffuse_blue\":\r\n case \"blue\":\r\n rgba[2] = value;\r\n break;\r\n case \"f_dc_0\":\r\n rgba[0] = (0.5 + SH_C0 * value) * 255;\r\n break;\r\n case \"f_dc_1\":\r\n rgba[1] = (0.5 + SH_C0 * value) * 255;\r\n break;\r\n case \"f_dc_2\":\r\n rgba[2] = (0.5 + SH_C0 * value) * 255;\r\n break;\r\n case \"f_dc_3\":\r\n rgba[3] = (0.5 + SH_C0 * value) * 255;\r\n break;\r\n case \"opacity\":\r\n rgba[3] = (1 / (1 + Math.exp(-value))) * 255;\r\n break;\r\n case \"rot_0\":\r\n r0 = value;\r\n break;\r\n case \"rot_1\":\r\n r1 = value;\r\n break;\r\n case \"rot_2\":\r\n r2 = value;\r\n break;\r\n case \"rot_3\":\r\n r3 = value;\r\n break;\r\n }\r\n }\r\n\r\n q.set(r1, r2, r3, r0);\r\n q.normalize();\r\n rot[0] = q.w * 128 + 128;\r\n rot[1] = q.x * 128 + 128;\r\n rot[2] = q.y * 128 + 128;\r\n rot[3] = q.z * 128 + 128;\r\n offset += rowVertexLength;\r\n }\r\n\r\n // faces\r\n const faces = [];\r\n if (faceCount) {\r\n for (let i = 0; i < faceCount; i++) {\r\n const faceVertexCount = dataView.getUint8(offset);\r\n if (faceVertexCount != 3) {\r\n continue; // only support triangles\r\n }\r\n offset += 1;\r\n\r\n for (let j = 0; j < faceVertexCount; j++) {\r\n const vertexIndex = dataView.getUint32(offset + (2 - j) * 4, true); // change face winding\r\n faces.push(vertexIndex);\r\n }\r\n offset += 12;\r\n }\r\n }\r\n\r\n // early exit for chunked/quantized ply\r\n if (chunkCount) {\r\n return { mode: Mode.Splat, data: buffer, faces: faces, hasVertexColors: false };\r\n }\r\n // count available properties. if all necessary are present then it's a splat. Otherwise, it's a point cloud\r\n // if faces are found, then it's a standard mesh\r\n let propertyCount = 0;\r\n let propertyColorCount = 0;\r\n const splatProperties = [\"x\", \"y\", \"z\", \"scale_0\", \"scale_1\", \"scale_2\", \"opacity\", \"rot_0\", \"rot_1\", \"rot_2\", \"rot_3\"];\r\n const splatColorProperties = [\"red\", \"green\", \"blue\", \"f_dc_0\", \"f_dc_1\", \"f_dc_2\"];\r\n for (let propertyIndex = 0; propertyIndex < vertexProperties.length; propertyIndex++) {\r\n const property = vertexProperties[propertyIndex];\r\n if (splatProperties.includes(property.name)) {\r\n propertyCount++;\r\n }\r\n if (splatColorProperties.includes(property.name)) {\r\n propertyColorCount++;\r\n }\r\n }\r\n const hasMandatoryProperties = propertyCount == splatProperties.length && propertyColorCount == 3;\r\n const currentMode = faceCount ? Mode.Mesh : hasMandatoryProperties ? Mode.Splat : Mode.PointCloud;\r\n // parsed ready ready to be used as a splat\r\n return { mode: currentMode, data: buffer, faces: faces, hasVertexColors: !!propertyColorCount };\r\n }\r\n}\r\n\r\n// Add this loader into the register plugin\r\nregisterSceneLoaderPlugin(new SPLATFileLoader());\r\n"]}
|
|
1
|
+
{"version":3,"file":"splatFileLoader.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/splatFileLoader.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ISceneLoaderPluginAsync, ISceneLoaderPluginFactory, ISceneLoaderAsyncResult, ISceneLoaderProgressEvent, SceneLoaderPluginOptions } from \"core/Loading/sceneLoader\";\r\nimport { registerSceneLoaderPlugin } from \"core/Loading/sceneLoader\";\r\nimport { SPLATFileLoaderMetadata } from \"./splatFileLoader.metadata\";\r\nimport { GaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplattingMesh\";\r\nimport { AssetContainer } from \"core/assetContainer\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Vector3 } from \"core/Maths/math.vector\";\r\nimport { PointsCloudSystem } from \"core/Particles/pointsCloudSystem\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport type { SPLATLoadingOptions } from \"./splatLoadingOptions\";\r\n\r\ndeclare module \"core/Loading/sceneLoader\" {\r\n // eslint-disable-next-line jsdoc/require-jsdoc\r\n export interface SceneLoaderPluginOptions {\r\n /**\r\n * Defines options for the splat loader.\r\n */\r\n [SPLATFileLoaderMetadata.name]: Partial<SPLATLoadingOptions>;\r\n }\r\n}\r\n\r\n/**\r\n * Indicator of the parsed ply buffer. A standard ready to use splat or an array of positions for a point cloud\r\n */\r\nconst enum Mode {\r\n Splat = 0,\r\n PointCloud = 1,\r\n Mesh = 2,\r\n}\r\n\r\n/**\r\n * A parsed buffer and how to use it\r\n */\r\ninterface ParsedPLY {\r\n data: ArrayBuffer;\r\n mode: Mode;\r\n faces?: number[];\r\n hasVertexColors?: boolean;\r\n}\r\n\r\n/**\r\n * @experimental\r\n * SPLAT file type loader.\r\n * This is a babylon scene loader plugin.\r\n */\r\nexport class SPLATFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {\r\n /**\r\n * Defines the name of the plugin.\r\n */\r\n public readonly name = SPLATFileLoaderMetadata.name;\r\n\r\n private _assetContainer: Nullable<AssetContainer> = null;\r\n\r\n private readonly _loadingOptions: Readonly<SPLATLoadingOptions>;\r\n /**\r\n * Defines the extensions the splat loader is able to load.\r\n * force data to come in as an ArrayBuffer\r\n */\r\n public readonly extensions = SPLATFileLoaderMetadata.extensions;\r\n\r\n /**\r\n * Creates loader for gaussian splatting files\r\n * @param loadingOptions options for loading and parsing splat and PLY files.\r\n */\r\n constructor(loadingOptions: Partial<Readonly<SPLATLoadingOptions>> = SPLATFileLoader._DefaultLoadingOptions) {\r\n this._loadingOptions = loadingOptions;\r\n }\r\n\r\n private static readonly _DefaultLoadingOptions = {\r\n keepInRam: false,\r\n } as const satisfies SPLATLoadingOptions;\r\n\r\n /** @internal */\r\n createPlugin(options: SceneLoaderPluginOptions): ISceneLoaderPluginAsync {\r\n return new SPLATFileLoader(options[SPLATFileLoaderMetadata.name]);\r\n }\r\n\r\n /**\r\n * Imports from the loaded gaussian splatting data and adds them to the scene\r\n * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file\r\n * @param scene the scene the meshes should be added to\r\n * @param data the gaussian splatting data to load\r\n * @param rootUrl root url to load from\r\n * @param onProgress callback called while file is loading\r\n * @param fileName Defines the name of the file to load\r\n * @returns a promise containing the loaded meshes, particles, skeletons and animations\r\n */\r\n public async importMeshAsync(\r\n meshesNames: any,\r\n scene: Scene,\r\n data: any,\r\n rootUrl: string,\r\n onProgress?: (event: ISceneLoaderProgressEvent) => void,\r\n fileName?: string\r\n ): Promise<ISceneLoaderAsyncResult> {\r\n return this._parse(meshesNames, scene, data, rootUrl).then((meshes) => {\r\n return {\r\n meshes: meshes,\r\n particleSystems: [],\r\n skeletons: [],\r\n animationGroups: [],\r\n transformNodes: [],\r\n geometries: [],\r\n lights: [],\r\n spriteManagers: [],\r\n };\r\n });\r\n }\r\n\r\n private static _BuildPointCloud(pointcloud: PointsCloudSystem, data: ArrayBuffer): boolean {\r\n if (!data.byteLength) {\r\n return false;\r\n }\r\n const uBuffer = new Uint8Array(data);\r\n const fBuffer = new Float32Array(data);\r\n\r\n // parsed array contains room for position(3floats), normal(3floats), color (4b), quantized quaternion (4b)\r\n const rowLength = 3 * 4 + 3 * 4 + 4 + 4;\r\n const vertexCount = uBuffer.length / rowLength;\r\n\r\n const pointcloudfunc = function (particle: any, i: number) {\r\n const x = fBuffer[8 * i + 0];\r\n const y = fBuffer[8 * i + 1];\r\n const z = fBuffer[8 * i + 2];\r\n particle.position = new Vector3(x, y, z);\r\n\r\n const r = uBuffer[rowLength * i + 24 + 0] / 255;\r\n const g = uBuffer[rowLength * i + 24 + 1] / 255;\r\n const b = uBuffer[rowLength * i + 24 + 2] / 255;\r\n particle.color = new Color4(r, g, b, 1);\r\n };\r\n\r\n pointcloud.addPoints(vertexCount, pointcloudfunc);\r\n return true;\r\n }\r\n\r\n private static _BuildMesh(scene: Scene, parsedPLY: ParsedPLY): Mesh {\r\n const mesh = new Mesh(\"PLYMesh\", scene);\r\n\r\n const uBuffer = new Uint8Array(parsedPLY.data);\r\n const fBuffer = new Float32Array(parsedPLY.data);\r\n\r\n const rowLength = 3 * 4 + 3 * 4 + 4 + 4;\r\n const vertexCount = uBuffer.length / rowLength;\r\n\r\n const positions = [];\r\n\r\n const vertexData = new VertexData();\r\n for (let i = 0; i < vertexCount; i++) {\r\n const x = fBuffer[8 * i + 0];\r\n const y = fBuffer[8 * i + 1];\r\n const z = fBuffer[8 * i + 2];\r\n positions.push(x, y, z);\r\n }\r\n\r\n if (parsedPLY.hasVertexColors) {\r\n const colors = new Float32Array(vertexCount * 4);\r\n for (let i = 0; i < vertexCount; i++) {\r\n const r = uBuffer[rowLength * i + 24 + 0] / 255;\r\n const g = uBuffer[rowLength * i + 24 + 1] / 255;\r\n const b = uBuffer[rowLength * i + 24 + 2] / 255;\r\n colors[i * 4 + 0] = r;\r\n colors[i * 4 + 1] = g;\r\n colors[i * 4 + 2] = b;\r\n colors[i * 4 + 3] = 1;\r\n }\r\n vertexData.colors = colors;\r\n }\r\n\r\n vertexData.positions = positions;\r\n vertexData.indices = parsedPLY.faces!;\r\n\r\n vertexData.applyToMesh(mesh);\r\n return mesh;\r\n }\r\n\r\n private _parse(meshesNames: any, scene: Scene, data: any, rootUrl: string): Promise<Array<AbstractMesh>> {\r\n const babylonMeshesArray: Array<Mesh> = []; //The mesh for babylon\r\n const parsedPLY = SPLATFileLoader._ConvertPLYToSplat(data as ArrayBuffer);\r\n switch (parsedPLY.mode) {\r\n case Mode.Splat:\r\n {\r\n const gaussianSplatting = new GaussianSplattingMesh(\"GaussianSplatting\", null, scene, this._loadingOptions.keepInRam);\r\n gaussianSplatting._parentContainer = this._assetContainer;\r\n babylonMeshesArray.push(gaussianSplatting);\r\n gaussianSplatting.loadDataAsync(parsedPLY.data);\r\n }\r\n break;\r\n case Mode.PointCloud:\r\n {\r\n const pointcloud = new PointsCloudSystem(\"PointCloud\", 1, scene);\r\n if (SPLATFileLoader._BuildPointCloud(pointcloud, parsedPLY.data)) {\r\n return Promise.all([pointcloud.buildMeshAsync()]).then((mesh) => {\r\n babylonMeshesArray.push(mesh[0]);\r\n return babylonMeshesArray;\r\n });\r\n } else {\r\n pointcloud.dispose();\r\n }\r\n }\r\n break;\r\n case Mode.Mesh:\r\n {\r\n if (parsedPLY.faces) {\r\n babylonMeshesArray.push(SPLATFileLoader._BuildMesh(scene, parsedPLY));\r\n } else {\r\n throw new Error(\"PLY mesh doesn't contain face informations.\");\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(\"Unsupported Splat mode\");\r\n }\r\n return Promise.resolve(babylonMeshesArray);\r\n }\r\n\r\n /**\r\n * Load into an asset container.\r\n * @param scene The scene to load into\r\n * @param data The data to import\r\n * @param rootUrl The root url for scene and resources\r\n * @returns The loaded asset container\r\n */\r\n public loadAssetContainerAsync(scene: Scene, data: string, rootUrl: string): Promise<AssetContainer> {\r\n const container = new AssetContainer(scene);\r\n this._assetContainer = container;\r\n\r\n return this.importMeshAsync(null, scene, data, rootUrl)\r\n .then((result) => {\r\n result.meshes.forEach((mesh) => container.meshes.push(mesh));\r\n // mesh material will be null before 1st rendered frame.\r\n this._assetContainer = null;\r\n return container;\r\n })\r\n .catch((ex) => {\r\n this._assetContainer = null;\r\n throw ex;\r\n });\r\n }\r\n\r\n /**\r\n * Imports all objects from the loaded OBJ data and adds them to the scene\r\n * @param scene the scene the objects should be added to\r\n * @param data the OBJ data to load\r\n * @param rootUrl root url to load from\r\n * @returns a promise which completes when objects have been loaded to the scene\r\n */\r\n public loadAsync(scene: Scene, data: string, rootUrl: string): Promise<void> {\r\n //Get the 3D model\r\n return this.importMeshAsync(null, scene, data, rootUrl).then(() => {\r\n // return void\r\n });\r\n }\r\n\r\n /**\r\n * Code from https://github.com/dylanebert/gsplat.js/blob/main/src/loaders/PLYLoader.ts Under MIT license\r\n * Converts a .ply data array buffer to splat\r\n * if data array buffer is not ply, returns the original buffer\r\n * @param data the .ply data to load\r\n * @returns the loaded splat buffer\r\n */\r\n private static _ConvertPLYToSplat(data: ArrayBuffer): ParsedPLY {\r\n const ubuf = new Uint8Array(data);\r\n const header = new TextDecoder().decode(ubuf.slice(0, 1024 * 10));\r\n const headerEnd = \"end_header\\n\";\r\n const headerEndIndex = header.indexOf(headerEnd);\r\n if (headerEndIndex < 0 || !header) {\r\n // standard splat\r\n return { mode: Mode.Splat, data: data };\r\n }\r\n\r\n const vertexCount = parseInt(/element vertex (\\d+)\\n/.exec(header)![1]);\r\n const faceElement = /element face (\\d+)\\n/.exec(header);\r\n let faceCount = 0;\r\n if (faceElement) {\r\n faceCount = parseInt(faceElement[1]);\r\n }\r\n const chunkElement = /element chunk (\\d+)\\n/.exec(header);\r\n let chunkCount = 0;\r\n if (chunkElement) {\r\n chunkCount = parseInt(chunkElement[1]);\r\n }\r\n\r\n let rowVertexOffset = 0;\r\n let rowChunkOffset = 0;\r\n const offsets: Record<string, number> = {\r\n double: 8,\r\n int: 4,\r\n uint: 4,\r\n float: 4,\r\n short: 2,\r\n ushort: 2,\r\n uchar: 1,\r\n list: 0,\r\n };\r\n\r\n type PlyProperty = {\r\n name: string;\r\n type: string;\r\n offset: number;\r\n };\r\n\r\n const enum ElementMode {\r\n Vertex = 0,\r\n Chunk = 1,\r\n }\r\n\r\n let chunkMode = ElementMode.Chunk;\r\n const vertexProperties: PlyProperty[] = [];\r\n const chunkProperties: PlyProperty[] = [];\r\n const filtered = header.slice(0, headerEndIndex).split(\"\\n\");\r\n for (const prop of filtered) {\r\n if (prop.startsWith(\"property \")) {\r\n const [, type, name] = prop.split(\" \");\r\n\r\n if (chunkMode == ElementMode.Chunk) {\r\n chunkProperties.push({ name, type, offset: rowChunkOffset });\r\n rowChunkOffset += offsets[type];\r\n } else if (chunkMode == ElementMode.Vertex) {\r\n vertexProperties.push({ name, type, offset: rowVertexOffset });\r\n rowVertexOffset += offsets[type];\r\n }\r\n\r\n if (!offsets[type]) {\r\n Logger.Warn(`Unsupported property type: ${type}.`);\r\n }\r\n } else if (prop.startsWith(\"element \")) {\r\n const [, type] = prop.split(\" \");\r\n if (type == \"chunk\") {\r\n chunkMode = ElementMode.Chunk;\r\n } else if (type == \"vertex\") {\r\n chunkMode = ElementMode.Vertex;\r\n }\r\n }\r\n }\r\n\r\n const rowVertexLength = rowVertexOffset;\r\n const rowChunkLength = rowChunkOffset;\r\n\r\n const buffer = GaussianSplattingMesh.ConvertPLYToSplat(data);\r\n const dataView = new DataView(data, headerEndIndex + headerEnd.length);\r\n let offset = rowChunkLength * chunkCount + rowVertexLength * vertexCount;\r\n // faces\r\n const faces = [];\r\n if (faceCount) {\r\n for (let i = 0; i < faceCount; i++) {\r\n const faceVertexCount = dataView.getUint8(offset);\r\n if (faceVertexCount != 3) {\r\n continue; // only support triangles\r\n }\r\n offset += 1;\r\n\r\n for (let j = 0; j < faceVertexCount; j++) {\r\n const vertexIndex = dataView.getUint32(offset + (2 - j) * 4, true); // change face winding\r\n faces.push(vertexIndex);\r\n }\r\n offset += 12;\r\n }\r\n }\r\n\r\n // early exit for chunked/quantized ply\r\n if (chunkCount) {\r\n return { mode: Mode.Splat, data: buffer, faces: faces, hasVertexColors: false };\r\n }\r\n // count available properties. if all necessary are present then it's a splat. Otherwise, it's a point cloud\r\n // if faces are found, then it's a standard mesh\r\n let propertyCount = 0;\r\n let propertyColorCount = 0;\r\n const splatProperties = [\"x\", \"y\", \"z\", \"scale_0\", \"scale_1\", \"scale_2\", \"opacity\", \"rot_0\", \"rot_1\", \"rot_2\", \"rot_3\"];\r\n const splatColorProperties = [\"red\", \"green\", \"blue\", \"f_dc_0\", \"f_dc_1\", \"f_dc_2\"];\r\n for (let propertyIndex = 0; propertyIndex < vertexProperties.length; propertyIndex++) {\r\n const property = vertexProperties[propertyIndex];\r\n if (splatProperties.includes(property.name)) {\r\n propertyCount++;\r\n }\r\n if (splatColorProperties.includes(property.name)) {\r\n propertyColorCount++;\r\n }\r\n }\r\n const hasMandatoryProperties = propertyCount == splatProperties.length && propertyColorCount == 3;\r\n const currentMode = faceCount ? Mode.Mesh : hasMandatoryProperties ? Mode.Splat : Mode.PointCloud;\r\n // parsed ready ready to be used as a splat\r\n return { mode: currentMode, data: buffer, faces: faces, hasVertexColors: !!propertyColorCount };\r\n }\r\n}\r\n\r\n// Add this loader into the register plugin\r\nregisterSceneLoaderPlugin(new SPLATFileLoader());\r\n"]}
|
package/glTF/2.0/glTFLoader.js
CHANGED
|
@@ -1898,10 +1898,18 @@ export class GLTFLoader {
|
|
|
1898
1898
|
const name = image.uri || `${this._fileName}#image${image.index}`;
|
|
1899
1899
|
const dataUrl = `data:${this._uniqueRootUrl}${name}`;
|
|
1900
1900
|
babylonTexture.updateURL(dataUrl, data);
|
|
1901
|
+
// Set the internal texture label.
|
|
1902
|
+
const internalTexture = babylonTexture.getInternalTexture();
|
|
1903
|
+
if (internalTexture) {
|
|
1904
|
+
internalTexture.label = image.name;
|
|
1905
|
+
}
|
|
1901
1906
|
}));
|
|
1902
1907
|
babylonTexture.wrapU = samplerData.wrapU;
|
|
1903
1908
|
babylonTexture.wrapV = samplerData.wrapV;
|
|
1904
1909
|
assign(babylonTexture);
|
|
1910
|
+
if (this._parent.useGltfTextureNames) {
|
|
1911
|
+
babylonTexture.name = image.name || image.uri || `image${image.index}`;
|
|
1912
|
+
}
|
|
1905
1913
|
return Promise.all(promises).then(() => {
|
|
1906
1914
|
return babylonTexture;
|
|
1907
1915
|
});
|