@onerjs/core 8.31.8 → 8.32.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.
Files changed (93) hide show
  1. package/Behaviors/Cameras/autoRotationBehavior.d.ts +4 -0
  2. package/Behaviors/Cameras/autoRotationBehavior.js +7 -0
  3. package/Behaviors/Cameras/autoRotationBehavior.js.map +1 -1
  4. package/Behaviors/Cameras/bouncingBehavior.d.ts +5 -0
  5. package/Behaviors/Cameras/bouncingBehavior.js +8 -0
  6. package/Behaviors/Cameras/bouncingBehavior.js.map +1 -1
  7. package/Behaviors/Cameras/framingBehavior.d.ts +4 -0
  8. package/Behaviors/Cameras/framingBehavior.js +7 -0
  9. package/Behaviors/Cameras/framingBehavior.js.map +1 -1
  10. package/Behaviors/Cameras/interpolatingBehavior.d.ts +7 -2
  11. package/Behaviors/Cameras/interpolatingBehavior.js +12 -4
  12. package/Behaviors/Cameras/interpolatingBehavior.js.map +1 -1
  13. package/Behaviors/Meshes/attachToBoxBehavior.d.ts +5 -0
  14. package/Behaviors/Meshes/attachToBoxBehavior.js +8 -1
  15. package/Behaviors/Meshes/attachToBoxBehavior.js.map +1 -1
  16. package/Behaviors/Meshes/baseSixDofDragBehavior.d.ts +5 -2
  17. package/Behaviors/Meshes/baseSixDofDragBehavior.js +8 -0
  18. package/Behaviors/Meshes/baseSixDofDragBehavior.js.map +1 -1
  19. package/Behaviors/Meshes/fadeInOutBehavior.d.ts +5 -0
  20. package/Behaviors/Meshes/fadeInOutBehavior.js +6 -0
  21. package/Behaviors/Meshes/fadeInOutBehavior.js.map +1 -1
  22. package/Behaviors/Meshes/handConstraintBehavior.d.ts +5 -0
  23. package/Behaviors/Meshes/handConstraintBehavior.js +8 -0
  24. package/Behaviors/Meshes/handConstraintBehavior.js.map +1 -1
  25. package/Behaviors/Meshes/multiPointerScaleBehavior.d.ts +5 -0
  26. package/Behaviors/Meshes/multiPointerScaleBehavior.js +8 -0
  27. package/Behaviors/Meshes/multiPointerScaleBehavior.js.map +1 -1
  28. package/Behaviors/Meshes/pointerDragBehavior.d.ts +1 -1
  29. package/Behaviors/Meshes/pointerDragBehavior.js.map +1 -1
  30. package/Behaviors/Meshes/sixDofDragBehavior.js +1 -1
  31. package/Behaviors/Meshes/sixDofDragBehavior.js.map +1 -1
  32. package/Behaviors/Meshes/surfaceMagnetismBehavior.d.ts +5 -0
  33. package/Behaviors/Meshes/surfaceMagnetismBehavior.js +7 -0
  34. package/Behaviors/Meshes/surfaceMagnetismBehavior.js.map +1 -1
  35. package/Behaviors/behavior.d.ts +4 -0
  36. package/Behaviors/behavior.js.map +1 -1
  37. package/Cameras/geospatialCamera.d.ts +4 -5
  38. package/Cameras/geospatialCamera.js +42 -29
  39. package/Cameras/geospatialCamera.js.map +1 -1
  40. package/Cameras/geospatialCameraMovement.js +1 -1
  41. package/Cameras/geospatialCameraMovement.js.map +1 -1
  42. package/Engines/WebGPU/Extensions/engine.multiRender.d.ts +2 -1
  43. package/Engines/WebGPU/Extensions/engine.multiRender.js +5 -2
  44. package/Engines/WebGPU/Extensions/engine.multiRender.js.map +1 -1
  45. package/Engines/WebGPU/webgpuTextureHelper.d.ts +1 -0
  46. package/Engines/WebGPU/webgpuTextureHelper.js +11 -0
  47. package/Engines/WebGPU/webgpuTextureHelper.js.map +1 -1
  48. package/Engines/WebGPU/webgpuTextureManager.d.ts +1 -0
  49. package/Engines/WebGPU/webgpuTextureManager.js +100 -9
  50. package/Engines/WebGPU/webgpuTextureManager.js.map +1 -1
  51. package/Engines/abstractEngine.js +2 -2
  52. package/Engines/abstractEngine.js.map +1 -1
  53. package/Engines/renderTargetWrapper.js +6 -1
  54. package/Engines/renderTargetWrapper.js.map +1 -1
  55. package/Engines/webgpuEngine.d.ts +7 -4
  56. package/Engines/webgpuEngine.js +45 -16
  57. package/Engines/webgpuEngine.js.map +1 -1
  58. package/Helpers/sceneHelpers.js +1 -1
  59. package/Helpers/sceneHelpers.js.map +1 -1
  60. package/Lights/index.d.ts +1 -0
  61. package/Lights/index.js +1 -0
  62. package/Lights/index.js.map +1 -1
  63. package/Lights/lightingVolume.d.ts +89 -0
  64. package/Lights/lightingVolume.js +426 -0
  65. package/Lights/lightingVolume.js.map +1 -0
  66. package/Materials/GaussianSplatting/gaussianSplattingMaterial.d.ts +7 -0
  67. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +19 -5
  68. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
  69. package/Materials/Node/nodeMaterial.js +8 -5
  70. package/Materials/Node/nodeMaterial.js.map +1 -1
  71. package/Materials/floatingOriginMatrixOverrides.js +6 -5
  72. package/Materials/floatingOriginMatrixOverrides.js.map +1 -1
  73. package/Materials/uniformBuffer.d.ts +1 -0
  74. package/Materials/uniformBuffer.js +8 -1
  75. package/Materials/uniformBuffer.js.map +1 -1
  76. package/Meshes/GaussianSplatting/gaussianSplattingMesh.d.ts +5 -2
  77. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +138 -45
  78. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  79. package/Particles/solidParticle.d.ts +9 -0
  80. package/Particles/solidParticle.js +11 -0
  81. package/Particles/solidParticle.js.map +1 -1
  82. package/Particles/solidParticleSystem.d.ts +28 -0
  83. package/Particles/solidParticleSystem.js +75 -0
  84. package/Particles/solidParticleSystem.js.map +1 -1
  85. package/ShadersWGSL/gaussianSplattingDepth.fragment.d.ts +0 -1
  86. package/ShadersWGSL/gaussianSplattingDepth.fragment.js +0 -2
  87. package/ShadersWGSL/gaussianSplattingDepth.fragment.js.map +1 -1
  88. package/ShadersWGSL/lightingVolume.compute.d.ts +5 -0
  89. package/ShadersWGSL/lightingVolume.compute.js +27 -0
  90. package/ShadersWGSL/lightingVolume.compute.js.map +1 -0
  91. package/package.json +1 -1
  92. package/scene.js +6 -4
  93. package/scene.js.map +1 -1
@@ -245,6 +245,27 @@ export class GaussianSplattingMesh extends Mesh {
245
245
  get material() {
246
246
  return this._material;
247
247
  }
248
+ static _MakeSplatGeometryForMesh(mesh) {
249
+ const vertexData = new VertexData();
250
+ const originPositions = [-2, -2, 0, 2, -2, 0, 2, 2, 0, -2, 2, 0];
251
+ const originIndices = [0, 1, 2, 0, 2, 3];
252
+ const positions = [];
253
+ const indices = [];
254
+ for (let i = 0; i < GaussianSplattingMesh._BatchSize; i++) {
255
+ for (let j = 0; j < 12; j++) {
256
+ if (j == 2 || j == 5 || j == 8 || j == 11) {
257
+ positions.push(i); // local splat index
258
+ }
259
+ else {
260
+ positions.push(originPositions[j]);
261
+ }
262
+ }
263
+ indices.push(originIndices.map((v) => v + i * 4));
264
+ }
265
+ vertexData.positions = positions;
266
+ vertexData.indices = indices.flat();
267
+ vertexData.applyToMesh(mesh);
268
+ }
248
269
  /**
249
270
  * Creates a new gaussian splatting mesh
250
271
  * @param name defines the name of the mesh
@@ -256,7 +277,6 @@ export class GaussianSplattingMesh extends Mesh {
256
277
  super(name, scene);
257
278
  this._vertexCount = 0;
258
279
  this._worker = null;
259
- this._frameIdLastUpdate = -1;
260
280
  this._modelViewMatrix = Matrix.Identity();
261
281
  this._canPostToWorker = true;
262
282
  this._readyToDisplay = false;
@@ -271,35 +291,15 @@ export class GaussianSplattingMesh extends Mesh {
271
291
  this._sh = null;
272
292
  this._keepInRam = false;
273
293
  this._delayedTextureUpdate = null;
274
- this._oldDirection = new Vector3();
275
294
  this._useRGBACovariants = false;
276
295
  this._material = null;
277
296
  this._tmpCovariances = [0, 0, 0, 0, 0, 0];
278
297
  this._sortIsDirty = false;
279
298
  this._shDegree = 0;
280
299
  this._viewDirectionFactor = new Vector3(1, 1, -1);
281
- const vertexData = new VertexData();
282
- const originPositions = [-2, -2, 0, 2, -2, 0, 2, 2, 0, -2, 2, 0];
283
- const originIndices = [0, 1, 2, 0, 2, 3];
284
- const positions = [];
285
- const indices = [];
286
- const batchSize = 16; // 16 splats per instance
287
- for (let i = 0; i < batchSize; i++) {
288
- for (let j = 0; j < 12; j++) {
289
- if (j == 2 || j == 5 || j == 8 || j == 11) {
290
- positions.push(i); // local splat index
291
- }
292
- else {
293
- positions.push(originPositions[j]);
294
- }
295
- }
296
- indices.push(originIndices.map((v) => v + i * 4));
297
- }
298
- vertexData.positions = positions;
299
- vertexData.indices = indices.flat();
300
- vertexData.applyToMesh(this);
300
+ this._cameraViewInfos = new Map();
301
301
  this.subMeshes = [];
302
- new SubMesh(0, 0, 4 * batchSize, 0, 6 * batchSize, this);
302
+ new SubMesh(0, 0, 4 * GaussianSplattingMesh._BatchSize, 0, 6 * GaussianSplattingMesh._BatchSize, this);
303
303
  this.setEnabled(false);
304
304
  // webGL2 and webGPU support for RG texture with float16 is fine. not webGL1
305
305
  this._useRGBACovariants = !this.getEngine().isWebGPU && this.getEngine().version === 1.0;
@@ -308,7 +308,19 @@ export class GaussianSplattingMesh extends Mesh {
308
308
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
309
309
  this.loadFileAsync(url);
310
310
  }
311
- this._material = new GaussianSplattingMaterial(this.name + "_material", this._scene);
311
+ const gaussianSplattingMaterial = new GaussianSplattingMaterial(this.name + "_material", this._scene);
312
+ gaussianSplattingMaterial.setSourceMesh(this);
313
+ this._material = gaussianSplattingMaterial;
314
+ // delete meshes created for cameras on camera removal
315
+ this._scene.onCameraRemovedObservable.add((camera) => {
316
+ const cameraId = camera.uniqueId;
317
+ // delete mesh for this camera
318
+ if (this._cameraViewInfos.has(cameraId)) {
319
+ const cameraViewInfos = this._cameraViewInfos.get(cameraId);
320
+ cameraViewInfos?.mesh.dispose();
321
+ this._cameraViewInfos.delete(cameraId);
322
+ }
323
+ });
312
324
  }
313
325
  /**
314
326
  * Returns the class name
@@ -340,25 +352,76 @@ export class GaussianSplattingMesh extends Mesh {
340
352
  }
341
353
  return true;
342
354
  }
355
+ _getCameraDirection(camera) {
356
+ const cameraMatrix = camera.getViewMatrix();
357
+ this.getWorldMatrix().multiplyToRef(cameraMatrix, this._modelViewMatrix);
358
+ cameraMatrix.invertToRef(TmpVectors.Matrix[0]);
359
+ this.getWorldMatrix().multiplyToRef(TmpVectors.Matrix[0], TmpVectors.Matrix[1]);
360
+ Vector3.TransformNormalToRef(Vector3.Forward(this._scene.useRightHandedSystem), TmpVectors.Matrix[1], TmpVectors.Vector3[2]);
361
+ TmpVectors.Vector3[2].normalize();
362
+ return TmpVectors.Vector3[2];
363
+ }
343
364
  /** @internal */
344
365
  _postToWorker(forced = false) {
345
- const frameId = this.getScene().getFrameId();
346
- if ((forced || frameId !== this._frameIdLastUpdate) && this._worker && this._scene.activeCamera && this._canPostToWorker) {
347
- const cameraMatrix = this._scene.activeCamera.getViewMatrix();
348
- this.getWorldMatrix().multiplyToRef(cameraMatrix, this._modelViewMatrix);
349
- cameraMatrix.invertToRef(TmpVectors.Matrix[0]);
350
- this.getWorldMatrix().multiplyToRef(TmpVectors.Matrix[0], TmpVectors.Matrix[1]);
351
- Vector3.TransformNormalToRef(Vector3.Forward(this._scene.useRightHandedSystem), TmpVectors.Matrix[1], TmpVectors.Vector3[2]);
352
- TmpVectors.Vector3[2].normalize();
353
- const dot = Vector3.Dot(TmpVectors.Vector3[2], this._oldDirection);
354
- if (forced || Math.abs(dot - 1) >= 0.01) {
355
- this._oldDirection.copyFrom(TmpVectors.Vector3[2]);
356
- this._frameIdLastUpdate = frameId;
357
- this._canPostToWorker = false;
358
- this._worker.postMessage({ view: this._modelViewMatrix.m, depthMix: this._depthMix, useRightHandedSystem: this._scene.useRightHandedSystem }, [
359
- this._depthMix.buffer,
360
- ]);
366
+ const scene = this._scene;
367
+ const frameId = scene.getFrameId();
368
+ // force update or at least frame update for camera is outdated
369
+ let outdated = false;
370
+ this._cameraViewInfos.forEach((cameraViewInfos) => {
371
+ if (cameraViewInfos.frameIdLastUpdate !== frameId) {
372
+ outdated = true;
361
373
  }
374
+ });
375
+ if ((forced || outdated) && this._worker && (this._scene.activeCameras || this._scene.activeCamera) && this._canPostToWorker) {
376
+ // array of cameras used for rendering
377
+ const cameras = this._scene.activeCameras?.length ? this._scene.activeCameras : [this._scene.activeCamera];
378
+ // list view infos for active cameras
379
+ const activeViewInfos = [];
380
+ cameras.forEach((camera) => {
381
+ const cameraId = camera.uniqueId;
382
+ const cameraViewInfos = this._cameraViewInfos.get(cameraId);
383
+ if (cameraViewInfos) {
384
+ activeViewInfos.push(cameraViewInfos);
385
+ }
386
+ else {
387
+ // mesh doesn't exist yet for this camera
388
+ const cameraMesh = new Mesh(this.name + "_cameraMesh_" + cameraId, this._scene);
389
+ // not visible with inspector or the scene graph
390
+ cameraMesh.reservedDataStore = { hidden: true };
391
+ cameraMesh.setEnabled(false);
392
+ cameraMesh.material = this.material;
393
+ GaussianSplattingMesh._MakeSplatGeometryForMesh(cameraMesh);
394
+ const newViewInfos = {
395
+ camera: camera,
396
+ cameraDirection: new Vector3(0, 0, 0),
397
+ mesh: cameraMesh,
398
+ frameIdLastUpdate: frameId,
399
+ splatIndexBufferSet: false,
400
+ };
401
+ activeViewInfos.push(newViewInfos);
402
+ this._cameraViewInfos.set(cameraId, newViewInfos);
403
+ }
404
+ });
405
+ // sort view infos by last updated frame id: first item is the least recently updated
406
+ activeViewInfos.sort((a, b) => a.frameIdLastUpdate - b.frameIdLastUpdate);
407
+ // view infos sorted by least recent updated frame id
408
+ activeViewInfos.forEach((cameraViewInfos) => {
409
+ const camera = cameraViewInfos.camera;
410
+ const cameraDirection = this._getCameraDirection(camera);
411
+ const previousCameraDirection = cameraViewInfos.cameraDirection;
412
+ const dot = Vector3.Dot(cameraDirection, previousCameraDirection);
413
+ if ((forced || cameraViewInfos.frameIdLastUpdate !== frameId || Math.abs(dot - 1) >= 0.01) && this._canPostToWorker) {
414
+ cameraViewInfos.cameraDirection.copyFrom(cameraDirection);
415
+ cameraViewInfos.frameIdLastUpdate = frameId;
416
+ this._canPostToWorker = false;
417
+ this._worker.postMessage({
418
+ view: this._modelViewMatrix.m,
419
+ depthMix: this._depthMix,
420
+ useRightHandedSystem: this._scene.useRightHandedSystem,
421
+ cameraId: camera.uniqueId,
422
+ }, [this._depthMix.buffer]);
423
+ }
424
+ });
362
425
  }
363
426
  }
364
427
  /**
@@ -370,7 +433,18 @@ export class GaussianSplattingMesh extends Mesh {
370
433
  */
371
434
  render(subMesh, enableAlphaMode, effectiveMeshReplacement) {
372
435
  this._postToWorker();
373
- return super.render(subMesh, enableAlphaMode, effectiveMeshReplacement);
436
+ // geometry used for shadows, bind the first found in the camera view infos
437
+ if (!this._geometry && this._cameraViewInfos.size) {
438
+ this._geometry = this._cameraViewInfos.values().next().value.mesh.geometry;
439
+ }
440
+ const cameraId = this._scene.activeCamera.uniqueId;
441
+ const cameraViewInfos = this._cameraViewInfos.get(cameraId);
442
+ if (!cameraViewInfos || !cameraViewInfos.splatIndexBufferSet) {
443
+ return this;
444
+ }
445
+ const mesh = cameraViewInfos.mesh;
446
+ mesh.getWorldMatrix().copyFrom(this.getWorldMatrix());
447
+ return mesh.render(subMesh, enableAlphaMode, effectiveMeshReplacement);
374
448
  }
375
449
  static _TypeNameToEnum(name) {
376
450
  switch (name) {
@@ -378,7 +452,6 @@ export class GaussianSplattingMesh extends Mesh {
378
452
  return 0 /* PLYType.FLOAT */;
379
453
  case "int":
380
454
  return 1 /* PLYType.INT */;
381
- break;
382
455
  case "uint":
383
456
  return 2 /* PLYType.UINT */;
384
457
  case "double":
@@ -1062,6 +1135,10 @@ export class GaussianSplattingMesh extends Mesh {
1062
1135
  this._shTextures = null;
1063
1136
  this._worker?.terminate();
1064
1137
  this._worker = null;
1138
+ // delete meshes created for each camera
1139
+ this._cameraViewInfos.forEach((cameraViewInfo) => {
1140
+ cameraViewInfo.mesh.dispose();
1141
+ });
1065
1142
  super.dispose(doNotRecurse, true);
1066
1143
  }
1067
1144
  _copyTextures(source) {
@@ -1300,7 +1377,10 @@ export class GaussianSplattingMesh extends Mesh {
1300
1377
  const paddedVertexCount = (vertexCount + 15) & ~0xf;
1301
1378
  if (!this._splatIndex || vertexCount > this._splatIndex.length) {
1302
1379
  this._splatIndex = new Float32Array(paddedVertexCount);
1303
- this.thinInstanceSetBuffer("splatIndex", this._splatIndex, 16, false);
1380
+ // update meshes for knowns cameras
1381
+ this._cameraViewInfos.forEach((cameraViewInfos) => {
1382
+ cameraViewInfos.mesh.thinInstanceSetBuffer("splatIndex", this._splatIndex, 16, false);
1383
+ });
1304
1384
  }
1305
1385
  this.forcedInstanceCount = paddedVertexCount >> 4;
1306
1386
  }
@@ -1344,6 +1424,7 @@ export class GaussianSplattingMesh extends Mesh {
1344
1424
  this._worker.postMessage({ positions, vertexCountPadded }, [positions.buffer]);
1345
1425
  this._worker.onmessage = (e) => {
1346
1426
  this._depthMix = e.data.depthMix;
1427
+ const cameraId = e.data.cameraId;
1347
1428
  const indexMix = new Uint32Array(e.data.depthMix.buffer);
1348
1429
  if (this._splatIndex) {
1349
1430
  for (let j = 0; j < vertexCountPadded; j++) {
@@ -1355,7 +1436,17 @@ export class GaussianSplattingMesh extends Mesh {
1355
1436
  this._updateSubTextures(this._delayedTextureUpdate.centers, this._delayedTextureUpdate.covA, this._delayedTextureUpdate.covB, this._delayedTextureUpdate.colors, 0, textureSize.y, this._delayedTextureUpdate.sh);
1356
1437
  this._delayedTextureUpdate = null;
1357
1438
  }
1358
- this.thinInstanceBufferUpdated("splatIndex");
1439
+ // get mesh for camera and update its instance buffer
1440
+ const cameraViewInfos = this._cameraViewInfos.get(cameraId);
1441
+ if (cameraViewInfos) {
1442
+ if (cameraViewInfos.splatIndexBufferSet) {
1443
+ cameraViewInfos.mesh.thinInstanceBufferUpdated("splatIndex");
1444
+ }
1445
+ else {
1446
+ cameraViewInfos.mesh.thinInstanceSetBuffer("splatIndex", this._splatIndex, 16, false);
1447
+ cameraViewInfos.splatIndexBufferSet = true;
1448
+ }
1449
+ }
1359
1450
  this._canPostToWorker = true;
1360
1451
  this._readyToDisplay = true;
1361
1452
  // sort is dirty when GS is visible for progressive update with a this message arriving but positions were partially filled
@@ -1392,6 +1483,7 @@ GaussianSplattingMesh._SH_C0 = 0.28209479177387814;
1392
1483
  GaussianSplattingMesh._SplatBatchSize = 327680;
1393
1484
  // batch size between 2 yield calls during the PLY to splat conversion.
1394
1485
  GaussianSplattingMesh._PlyConversionBatchSize = 32768;
1486
+ GaussianSplattingMesh._BatchSize = 16; // 16 splats per instance
1395
1487
  /**
1396
1488
  * Set the number of batch (a batch is 16384 splats) after which a display update is performed
1397
1489
  * A value of 0 (default) means display update will not happens before splat is ready.
@@ -1411,6 +1503,7 @@ GaussianSplattingMesh._CreateWorker = function (self) {
1411
1503
  }
1412
1504
  // udpate on view changed
1413
1505
  else {
1506
+ const cameraId = e.data.cameraId;
1414
1507
  const viewProj = e.data.view;
1415
1508
  if (!positions || !viewProj) {
1416
1509
  // Sanity check, it shouldn't happen!
@@ -1431,7 +1524,7 @@ GaussianSplattingMesh._CreateWorker = function (self) {
1431
1524
  floatMix[2 * j + 1] = 10000 + (viewProj[2] * positions[4 * j + 0] + viewProj[6] * positions[4 * j + 1] + viewProj[10] * positions[4 * j + 2]) * depthFactor;
1432
1525
  }
1433
1526
  depthMix.sort();
1434
- self.postMessage({ depthMix }, [depthMix.buffer]);
1527
+ self.postMessage({ depthMix, cameraId }, [depthMix.buffer]);
1435
1528
  }
1436
1529
  };
1437
1530
  };