@rings-webgpu/core 1.0.26 → 1.0.28

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.
@@ -2113,7 +2113,7 @@ function GetShader(name) {
2113
2113
  }
2114
2114
 
2115
2115
  var __defProp$2 = Object.defineProperty;
2116
- var __decorateClass$m = (decorators, target, key, kind) => {
2116
+ var __decorateClass$o = (decorators, target, key, kind) => {
2117
2117
  var result = void 0 ;
2118
2118
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
2119
2119
  if (decorator = decorators[i])
@@ -2216,10 +2216,10 @@ const _Struct = class _Struct {
2216
2216
  return struct.__size;
2217
2217
  }
2218
2218
  };
2219
- __decorateClass$m([
2219
+ __decorateClass$o([
2220
2220
  NonSerialize
2221
2221
  ], _Struct.prototype, "__refection");
2222
- __decorateClass$m([
2222
+ __decorateClass$o([
2223
2223
  NonSerialize
2224
2224
  ], _Struct.prototype, "__size");
2225
2225
  let Struct = _Struct;
@@ -20489,6 +20489,10 @@ class RenderShaderPass extends ShaderPassBase {
20489
20489
  this.vsEntryPoint = vsEntryPoint;
20490
20490
  this.fsEntryPoint = fsEntryPoint;
20491
20491
  }
20492
+ setUniformArray(name, value) {
20493
+ super.setUniformArray(name, value);
20494
+ this.materialDataUniformBuffer.onChange();
20495
+ }
20492
20496
  setUniform(name, value) {
20493
20497
  super.setUniform(name, value);
20494
20498
  this.materialDataUniformBuffer.onChange();
@@ -20757,16 +20761,21 @@ class RenderShaderPass extends ShaderPassBase {
20757
20761
  if (buffer) {
20758
20762
  if (buffer.bufferType == GPUBufferType.MaterialDataUniformGPUBuffer) {
20759
20763
  let uniforms = [];
20760
- for (let i = 0; i < refs.dataFields.length; i++) {
20761
- const field = refs.dataFields[i];
20762
- if (!this.uniforms[field.name]) {
20763
- console.error(
20764
- `shader-${this.vsName}:${this.fsName} ${field.name}is empty`
20765
- );
20764
+ if (refs.dataFields) {
20765
+ for (let i = 0; i < refs.dataFields.length; i++) {
20766
+ const field = refs.dataFields[i];
20767
+ if (!this.uniforms[field.name]) {
20768
+ console.error(
20769
+ `shader-${this.vsName}:${this.fsName} ${field.name}is empty`
20770
+ );
20771
+ } else {
20772
+ uniforms.push(this.uniforms[field.name]);
20773
+ }
20766
20774
  }
20767
- uniforms.push(this.uniforms[field.name]);
20768
20775
  }
20769
- this.materialDataUniformBuffer.initDataUniform(uniforms);
20776
+ if (uniforms.length > 0) {
20777
+ this.materialDataUniformBuffer.initDataUniform(uniforms);
20778
+ }
20770
20779
  }
20771
20780
  let entry = {
20772
20781
  binding: refs.binding,
@@ -21956,9 +21965,9 @@ class OctreeEntity {
21956
21965
  }
21957
21966
 
21958
21967
  var __defProp$1 = Object.defineProperty;
21959
- var __getOwnPropDesc$l = Object.getOwnPropertyDescriptor;
21960
- var __decorateClass$l = (decorators, target, key, kind) => {
21961
- var result = __getOwnPropDesc$l(target, key) ;
21968
+ var __getOwnPropDesc$n = Object.getOwnPropertyDescriptor;
21969
+ var __decorateClass$n = (decorators, target, key, kind) => {
21970
+ var result = __getOwnPropDesc$n(target, key) ;
21962
21971
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
21963
21972
  if (decorator = decorators[i])
21964
21973
  result = (decorator(target, key, result) ) || result;
@@ -22556,13 +22565,13 @@ class RenderNode extends ComponentBase {
22556
22565
  this._combineShaderRefection = void 0;
22557
22566
  }
22558
22567
  }
22559
- __decorateClass$l([
22568
+ __decorateClass$n([
22560
22569
  EditorInspector
22561
22570
  ], RenderNode.prototype, "materials");
22562
- __decorateClass$l([
22571
+ __decorateClass$n([
22563
22572
  EditorInspector
22564
22573
  ], RenderNode.prototype, "castShadow");
22565
- __decorateClass$l([
22574
+ __decorateClass$n([
22566
22575
  EditorInspector
22567
22576
  ], RenderNode.prototype, "castGI");
22568
22577
 
@@ -22783,7 +22792,7 @@ const GSplat_VS = (
22783
22792
  @location(1) vTexCoord: vec2<f32>,
22784
22793
  };
22785
22794
 
22786
- // Textures (like PlayCanvas)
22795
+ // Textures
22787
22796
  @group(1) @binding(1) var splatColor: texture_2d<f32>;
22788
22797
  @group(1) @binding(2) var transformA: texture_2d<u32>;
22789
22798
  @group(1) @binding(3) var transformB: texture_2d<f32>;
@@ -22880,7 +22889,7 @@ const GSplat_VS = (
22880
22889
  return vec4f(v1.x, -v1.y, v2.x, -v2.y);
22881
22890
  }
22882
22891
 
22883
- // ===== SPLAT MAIN VS (from PlayCanvas gsplat-material.js) =====
22892
+ // ===== SPLAT MAIN VS =====
22884
22893
 
22885
22894
  @vertex
22886
22895
  fn VertMain(
@@ -23229,9 +23238,9 @@ class Shader {
23229
23238
  }
23230
23239
  }
23231
23240
 
23232
- var __getOwnPropDesc$k = Object.getOwnPropertyDescriptor;
23233
- var __decorateClass$k = (decorators, target, key, kind) => {
23234
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$k(target, key) : target;
23241
+ var __getOwnPropDesc$m = Object.getOwnPropertyDescriptor;
23242
+ var __decorateClass$m = (decorators, target, key, kind) => {
23243
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$m(target, key) : target;
23235
23244
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
23236
23245
  if (decorator = decorators[i])
23237
23246
  result = (decorator(result)) || result;
@@ -23263,7 +23272,7 @@ let GSplatShader = class extends Shader {
23263
23272
  pass.setUniform("pixelCull", new Float32Array([2, 0, 0, 0]));
23264
23273
  }
23265
23274
  };
23266
- GSplatShader = __decorateClass$k([
23275
+ GSplatShader = __decorateClass$m([
23267
23276
  RegisterShader(GSplatShader, "GSplatShader")
23268
23277
  ], GSplatShader);
23269
23278
 
@@ -24046,7 +24055,7 @@ class Uint8ArrayTexture extends Texture {
24046
24055
  size: data.byteLength,
24047
24056
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
24048
24057
  });
24049
- device.queue.writeBuffer(textureDataBuffer, 0, data);
24058
+ device.queue.writeBuffer(textureDataBuffer, 0, data.buffer);
24050
24059
  const commandEncoder = GPUContext.beginCommandEncoder();
24051
24060
  commandEncoder.copyBufferToTexture(
24052
24061
  {
@@ -24078,7 +24087,7 @@ class Uint8ArrayTexture extends Texture {
24078
24087
  size: data.byteLength,
24079
24088
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
24080
24089
  });
24081
- device.queue.writeBuffer(textureDataBuffer, 0, data);
24090
+ device.queue.writeBuffer(textureDataBuffer, 0, data.buffer);
24082
24091
  const commandEncoder = GPUContext.beginCommandEncoder();
24083
24092
  commandEncoder.copyBufferToTexture(
24084
24093
  {
@@ -24280,9 +24289,9 @@ class Float16ArrayTexture extends Texture {
24280
24289
  }
24281
24290
  }
24282
24291
 
24283
- var __getOwnPropDesc$j = Object.getOwnPropertyDescriptor;
24284
- var __decorateClass$j = (decorators, target, key, kind) => {
24285
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$j(target, key) : target;
24292
+ var __getOwnPropDesc$l = Object.getOwnPropertyDescriptor;
24293
+ var __decorateClass$l = (decorators, target, key, kind) => {
24294
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$l(target, key) : target;
24286
24295
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
24287
24296
  if (decorator = decorators[i])
24288
24297
  result = (decorator(result)) || result;
@@ -25081,10 +25090,689 @@ let GSplatRenderer = class extends RenderNode {
25081
25090
  super.destroy(force);
25082
25091
  }
25083
25092
  };
25084
- GSplatRenderer = __decorateClass$j([
25093
+ GSplatRenderer = __decorateClass$l([
25085
25094
  RegisterComponent(GSplatRenderer, "GSplatRenderer")
25086
25095
  ], GSplatRenderer);
25087
25096
 
25097
+ const PointCloud_VS = (
25098
+ /* wgsl */
25099
+ `
25100
+ #include "GlobalUniform"
25101
+
25102
+ const ALPHA_THRESHOLD: f32 = 0.00392156863;
25103
+
25104
+ struct MaterialUniform {
25105
+ modelMatrix: mat4x4<f32>,
25106
+ tex_params: vec4<f32>,
25107
+ pointParams: vec4<f32>,
25108
+ };
25109
+ @group(1) @binding(0) var<uniform> materialUniform: MaterialUniform;
25110
+
25111
+ struct VSOut {
25112
+ @builtin(position) member: vec4<f32>,
25113
+ @location(0) vColor: vec4<f32>,
25114
+ @location(1) vTexCoord: vec2<f32>,
25115
+ };
25116
+
25117
+ @group(1) @binding(1) var pointColor: texture_2d<f32>;
25118
+ @group(1) @binding(2) var pointPosition: texture_2d<f32>;
25119
+ @group(1) @binding(3) var pointOrder: texture_2d<u32>;
25120
+
25121
+ fn discardPoint() -> VSOut {
25122
+ var o: VSOut;
25123
+ o.member = vec4f(0.0, 0.0, 2.0, 1.0);
25124
+ o.vColor = vec4f(0.0);
25125
+ o.vTexCoord = vec2f(0.0);
25126
+ return o;
25127
+ }
25128
+
25129
+ fn calcPointUV(orderId: u32, textureWidth: u32, numPoints: u32) -> vec2<i32> {
25130
+ let pointId = orderId;
25131
+ return vec2<i32>(
25132
+ i32(pointId % textureWidth),
25133
+ i32(pointId / textureWidth)
25134
+ );
25135
+ }
25136
+
25137
+ @vertex
25138
+ fn VertMain(
25139
+ @builtin(vertex_index) vid: u32,
25140
+ @builtin(instance_index) iid: u32,
25141
+ @location(0) position: vec3<f32>
25142
+ ) -> VSOut {
25143
+ let batchSize = max(1u, u32(materialUniform.pointParams.w));
25144
+ let orderId = iid * batchSize + u32(position.z);
25145
+
25146
+ let textureWidth = max(1u, u32(materialUniform.tex_params.y));
25147
+ let numPoints = max(1u, u32(materialUniform.tex_params.x));
25148
+ let safeOrderId = min(orderId, numPoints - 1u);
25149
+
25150
+ let pointUV = calcPointUV(safeOrderId, textureWidth, numPoints);
25151
+ let color = textureLoad(pointColor, pointUV, 0);
25152
+
25153
+ let posData = textureLoad(pointPosition, pointUV, 0);
25154
+ let pointPos = vec3f(
25155
+ posData.x,
25156
+ posData.y,
25157
+ posData.z
25158
+ );
25159
+
25160
+ let matrix_model = materialUniform.modelMatrix;
25161
+ let matrix_view = globalUniform.viewMat;
25162
+ let matrix_projection = globalUniform.projMat;
25163
+ let model_view = matrix_view * matrix_model;
25164
+
25165
+ let centerClip = matrix_projection * (model_view * vec4f(pointPos, 1.0));
25166
+
25167
+ let inv_w = 1.0 / centerClip.w;
25168
+ let ndc = centerClip.xyz * inv_w;
25169
+ if (ndc.x < -1.0 || ndc.x > 1.0 ||
25170
+ ndc.y < -1.0 || ndc.y > 1.0 ||
25171
+ ndc.z < 0.0 || ndc.z > 1.0) {
25172
+ return discardPoint();
25173
+ }
25174
+
25175
+ let viewPos = model_view * vec4f(pointPos, 1.0);
25176
+ if (viewPos.z <= 0.0) {
25177
+ return discardPoint();
25178
+ }
25179
+
25180
+ let pointSize = materialUniform.tex_params.w;
25181
+ let viewport = vec2f(globalUniform.windowWidth, globalUniform.windowHeight);
25182
+ let safeViewport = max(viewport, vec2f(1.0, 1.0));
25183
+ let inv_viewport = 2.0 / safeViewport;
25184
+ let offsetNDC = position.xy * pointSize * 0.5 * inv_viewport;
25185
+ let offsetClip = vec4f(offsetNDC * centerClip.w, 0.0, 0.0);
25186
+
25187
+ var o: VSOut;
25188
+ o.member = centerClip + offsetClip;
25189
+ o.vColor = color;
25190
+ o.vTexCoord = position.xy;
25191
+ return o;
25192
+ }
25193
+ `
25194
+ );
25195
+ const PointCloud_FS = (
25196
+ /* wgsl */
25197
+ `
25198
+ #include "FragmentOutput"
25199
+
25200
+ const ALPHA_THRESHOLD: f32 = 0.00392156863;
25201
+
25202
+ struct MaterialUniform {
25203
+ modelMatrix: mat4x4<f32>,
25204
+ tex_params: vec4<f32>,
25205
+ pointParams: vec4<f32>,
25206
+ };
25207
+ @group(1) @binding(0) var<uniform> materialUniform: MaterialUniform;
25208
+
25209
+ @fragment
25210
+ fn FragMain(
25211
+ @location(0) vColor: vec4<f32>,
25212
+ @location(1) vTexCoord: vec2<f32>
25213
+ ) -> FragmentOutput {
25214
+ var o: FragmentOutput;
25215
+
25216
+ let pointShape = materialUniform.pointParams.x;
25217
+ let distSq = dot(vTexCoord, vTexCoord);
25218
+ let isCircle = pointShape > 0.5;
25219
+ let discardPixel = isCircle && distSq > 1.0;
25220
+
25221
+ if (discardPixel) {
25222
+ discard;
25223
+ }
25224
+
25225
+ o.color = vColor;
25226
+ o.gBuffer = vec4f(0.0);
25227
+ return o;
25228
+ }
25229
+ `
25230
+ );
25231
+
25232
+ var __getOwnPropDesc$k = Object.getOwnPropertyDescriptor;
25233
+ var __decorateClass$k = (decorators, target, key, kind) => {
25234
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$k(target, key) : target;
25235
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
25236
+ if (decorator = decorators[i])
25237
+ result = (decorator(result)) || result;
25238
+ return result;
25239
+ };
25240
+ let PointCloudShader = class extends Shader {
25241
+ constructor() {
25242
+ super();
25243
+ ShaderLib.register("pointcloud_vs_dc", PointCloud_VS);
25244
+ ShaderLib.register("pointcloud_fs_dc", PointCloud_FS);
25245
+ const pass = new RenderShaderPass("pointcloud_vs_dc", "pointcloud_fs_dc");
25246
+ pass.passType = PassType.COLOR;
25247
+ pass.setShaderEntry("VertMain", "FragMain");
25248
+ pass.topology = GPUPrimitiveTopology.triangle_list;
25249
+ pass.depthWriteEnabled = false;
25250
+ pass.cullMode = GPUCullMode.none;
25251
+ pass.shaderState.transparent = true;
25252
+ pass.shaderState.blendMode = BlendMode.NORMAL;
25253
+ pass.shaderState.writeMasks = [15, 15];
25254
+ pass.shaderState.castReflection = false;
25255
+ this.addRenderPass(pass);
25256
+ this.setDefault();
25257
+ }
25258
+ setDefault() {
25259
+ const pass = this.getDefaultColorShader();
25260
+ const identityMatrix = new Matrix4();
25261
+ pass.setUniform("modelMatrix", identityMatrix.rawData);
25262
+ pass.setUniformArray("tex_params", new Float32Array([0, 0, 0, 4]));
25263
+ pass.setUniformArray("pointParams", new Float32Array([0, 0, 0, 128]));
25264
+ }
25265
+ };
25266
+ PointCloudShader = __decorateClass$k([
25267
+ RegisterShader(PointCloudShader, "PointCloudShader")
25268
+ ], PointCloudShader);
25269
+
25270
+ class PointCloudMaterial extends Material {
25271
+ _texParams = new Float32Array([0, 0, 0, 4]);
25272
+ _pointParamsArray = new Float32Array([0, 0, 0, 128]);
25273
+ constructor() {
25274
+ super();
25275
+ this.shader = new PointCloudShader();
25276
+ }
25277
+ /**
25278
+ * Set point cloud textures
25279
+ * @param pointPosition Position texture (RGB = xyz)
25280
+ * @param pointColor Color texture (RGBA)
25281
+ * @param texParams Texture parameters [numPoints, texWidth, validCount, pointSize]
25282
+ * @param pointOrder Optional sorting texture (R32U format)
25283
+ */
25284
+ setPointTextures(pointPosition, pointColor, texParams, pointOrder) {
25285
+ const pass = this.shader.getDefaultColorShader();
25286
+ if (!pass.getUniform("modelMatrix")) {
25287
+ const identityMatrix = new Matrix4();
25288
+ pass.setUniform("modelMatrix", identityMatrix.rawData);
25289
+ }
25290
+ pass.setTexture("pointColor", pointColor);
25291
+ pass.setTexture("pointPosition", pointPosition);
25292
+ this._texParams[0] = texParams[0];
25293
+ this._texParams[1] = texParams[1];
25294
+ this._texParams[2] = texParams[2];
25295
+ this._texParams[3] = texParams[3];
25296
+ pass.setUniformArray("tex_params", this._texParams);
25297
+ pass.setUniformArray("pointParams", this._pointParamsArray);
25298
+ if (pointOrder) {
25299
+ pass.setTexture("pointOrder", pointOrder);
25300
+ }
25301
+ pass.shaderState.depthCompare = GPUCompareFunction.less;
25302
+ }
25303
+ /**
25304
+ * Set the model matrix for transforming points to world space
25305
+ * @param matrix Model transformation matrix
25306
+ */
25307
+ setTransformMatrix(matrix) {
25308
+ const pass = this.shader.getDefaultColorShader();
25309
+ pass.setUniform("modelMatrix", matrix.rawData);
25310
+ }
25311
+ /**
25312
+ * Set point size in pixels
25313
+ * @param size Point size in pixels (default: 4.0)
25314
+ */
25315
+ setPointSize(size) {
25316
+ this._texParams[3] = Math.max(0.1, size);
25317
+ const pass = this.shader.getDefaultColorShader();
25318
+ pass.setUniformArray("tex_params", this._texParams);
25319
+ }
25320
+ /**
25321
+ * Set point shape
25322
+ * @param shape Point shape: 'square' or 'circle'
25323
+ */
25324
+ setPointShape(shape) {
25325
+ this._pointParamsArray[0] = shape === "circle" ? 1 : 0;
25326
+ const pass = this.shader.getDefaultColorShader();
25327
+ pass.setUniformArray("pointParams", this._pointParamsArray);
25328
+ }
25329
+ enableDebugFullScreen(enabled) {
25330
+ this._pointParamsArray[1] = enabled ? 1 : 0;
25331
+ const pass = this.shader.getDefaultColorShader();
25332
+ pass.setUniformArray("pointParams", this._pointParamsArray);
25333
+ }
25334
+ /**
25335
+ * Set batch size for instanced rendering
25336
+ * @param batchSize Number of points per draw call (default: 128)
25337
+ */
25338
+ setBatchSize(batchSize) {
25339
+ this._pointParamsArray[3] = Math.max(1, batchSize | 0);
25340
+ const pass = this.shader.getDefaultColorShader();
25341
+ pass.setUniformArray("pointParams", this._pointParamsArray);
25342
+ }
25343
+ }
25344
+
25345
+ class PointCloudGeometry extends GeometryBase {
25346
+ batchSize;
25347
+ constructor(batchSize = 128) {
25348
+ super();
25349
+ this.batchSize = batchSize;
25350
+ const meshPositions = new Float32Array(12 * batchSize);
25351
+ for (let i = 0; i < batchSize; ++i) {
25352
+ const baseIdx = i * 12;
25353
+ meshPositions.set([
25354
+ -1,
25355
+ -1,
25356
+ i,
25357
+ 1,
25358
+ -1,
25359
+ i,
25360
+ 1,
25361
+ 1,
25362
+ i,
25363
+ -1,
25364
+ 1,
25365
+ i
25366
+ ], baseIdx);
25367
+ }
25368
+ const meshIndices = new Uint32Array(6 * batchSize);
25369
+ for (let i = 0; i < batchSize; ++i) {
25370
+ const baseVertex = i * 4;
25371
+ const baseIdx = i * 6;
25372
+ meshIndices.set([
25373
+ 0 + baseVertex,
25374
+ 1 + baseVertex,
25375
+ 2 + baseVertex,
25376
+ 0 + baseVertex,
25377
+ 2 + baseVertex,
25378
+ 3 + baseVertex
25379
+ ], baseIdx);
25380
+ }
25381
+ this.setAttribute(VertexAttributeName.position, meshPositions);
25382
+ this.setIndices(meshIndices);
25383
+ this.addSubGeometry({
25384
+ indexStart: 0,
25385
+ indexCount: meshIndices.length,
25386
+ vertexStart: 0,
25387
+ vertexCount: meshPositions.length / 3,
25388
+ firstStart: 0,
25389
+ index: 0,
25390
+ topology: 0
25391
+ });
25392
+ }
25393
+ }
25394
+
25395
+ class Float32ArrayTexture extends Texture {
25396
+ create(width, height, data, filtering = true) {
25397
+ let device = webGPUContext.device;
25398
+ const bytesPerRow = width * 4 * 4;
25399
+ this.format = GPUTextureFormat.rgba32float;
25400
+ let mipmapCount = 1;
25401
+ this.createTextureDescriptor(width, height, mipmapCount, this.format);
25402
+ const textureDataBuffer = device.createBuffer({
25403
+ size: data.byteLength,
25404
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
25405
+ });
25406
+ device.queue.writeBuffer(textureDataBuffer, 0, data.buffer);
25407
+ const commandEncoder = GPUContext.beginCommandEncoder();
25408
+ commandEncoder.copyBufferToTexture(
25409
+ {
25410
+ buffer: textureDataBuffer,
25411
+ bytesPerRow
25412
+ },
25413
+ {
25414
+ texture: this.getGPUTexture()
25415
+ },
25416
+ {
25417
+ width,
25418
+ height,
25419
+ depthOrArrayLayers: 1
25420
+ }
25421
+ );
25422
+ GPUContext.endCommandEncoder(commandEncoder);
25423
+ if (filtering) {
25424
+ this.samplerBindingLayout.type = `non-filtering`;
25425
+ this.textureBindingLayout.sampleType = `unfilterable-float`;
25426
+ }
25427
+ this.gpuSampler = device.createSampler({});
25428
+ return this;
25429
+ }
25430
+ fromBuffer(width, height, textureDataBuffer) {
25431
+ let device = webGPUContext.device;
25432
+ const bytesPerRow = width * 4 * 4;
25433
+ this.format = GPUTextureFormat.rgba32float;
25434
+ this.mipmapCount = 1;
25435
+ this.createTextureDescriptor(width, height, this.mipmapCount, this.format);
25436
+ const commandEncoder = GPUContext.beginCommandEncoder();
25437
+ commandEncoder.copyBufferToTexture(
25438
+ {
25439
+ buffer: textureDataBuffer,
25440
+ bytesPerRow
25441
+ },
25442
+ {
25443
+ texture: this.getGPUTexture()
25444
+ },
25445
+ {
25446
+ width,
25447
+ height,
25448
+ depthOrArrayLayers: 1
25449
+ }
25450
+ );
25451
+ GPUContext.endCommandEncoder(commandEncoder);
25452
+ this.samplerBindingLayout.type = `non-filtering`;
25453
+ this.textureBindingLayout.sampleType = `unfilterable-float`;
25454
+ this.gpuSampler = device.createSampler({});
25455
+ return this;
25456
+ }
25457
+ }
25458
+
25459
+ var __getOwnPropDesc$j = Object.getOwnPropertyDescriptor;
25460
+ var __decorateClass$j = (decorators, target, key, kind) => {
25461
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$j(target, key) : target;
25462
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
25463
+ if (decorator = decorators[i])
25464
+ result = (decorator(result)) || result;
25465
+ return result;
25466
+ };
25467
+ let PointCloudRenderer = class extends RenderNode {
25468
+ count = 0;
25469
+ size = new Vector2();
25470
+ pointColor;
25471
+ pointPosition;
25472
+ pointOrder;
25473
+ texParams;
25474
+ // [numPoints, texWidth, validCount, pointSize]
25475
+ pointCloudMaterial;
25476
+ _positions;
25477
+ get positions() {
25478
+ return this._positions;
25479
+ }
25480
+ _colors;
25481
+ _orderData;
25482
+ _fullCount = 0;
25483
+ get fullCount() {
25484
+ return this._fullCount;
25485
+ }
25486
+ _batchSize = 128;
25487
+ instanceCount = 0;
25488
+ _texturesInitialized = false;
25489
+ _debugFullScreen = false;
25490
+ _centerOffset = new Vector3();
25491
+ get centerOffset() {
25492
+ return this._centerOffset;
25493
+ }
25494
+ constructor() {
25495
+ super();
25496
+ }
25497
+ /**
25498
+ * Initialize point cloud from raw data
25499
+ * @param positions Point positions (xyz per point, Float32Array)
25500
+ * @param colors Point colors (rgba per point, Uint8Array)
25501
+ * @param count Number of points
25502
+ */
25503
+ initFromData(positions, colors, count) {
25504
+ if (!positions || !colors || count <= 0) {
25505
+ console.error("PointCloudRenderer: Invalid input data");
25506
+ return;
25507
+ }
25508
+ if (positions.length < count * 3) {
25509
+ console.error("PointCloudRenderer: Positions array too small");
25510
+ return;
25511
+ }
25512
+ if (colors.length < count * 4) {
25513
+ console.error("PointCloudRenderer: Colors array too small");
25514
+ return;
25515
+ }
25516
+ this.count = count;
25517
+ this._fullCount = count;
25518
+ this.size = this.evalTextureSize(count);
25519
+ this._positions = positions;
25520
+ this._colors = colors;
25521
+ this.centerizePositions();
25522
+ this.buildPositionTexture();
25523
+ this.buildColorTexture();
25524
+ this.texParams = new Float32Array([
25525
+ this.count,
25526
+ this.size.x,
25527
+ this.count,
25528
+ 4
25529
+ ]);
25530
+ this.buildOrderTexture();
25531
+ this.pointCloudMaterial = new PointCloudMaterial();
25532
+ this.geometry = new PointCloudGeometry(this._batchSize);
25533
+ this.materials = [this.pointCloudMaterial];
25534
+ this.instanceCount = Math.ceil(this.count / this._batchSize);
25535
+ }
25536
+ /**
25537
+ * Calculate texture size for given point count
25538
+ * @param count Number of points
25539
+ * @returns Texture dimensions (width, height)
25540
+ */
25541
+ evalTextureSize(count) {
25542
+ let w = Math.ceil(Math.sqrt(count));
25543
+ const align = 64;
25544
+ w = Math.ceil(w / align) * align;
25545
+ const h = Math.ceil(count / w);
25546
+ return new Vector2(w, h);
25547
+ }
25548
+ /**
25549
+ * Centerize positions to improve precision for large values
25550
+ * Subtracts the center point from all positions to keep values near zero
25551
+ */
25552
+ centerizePositions() {
25553
+ if (this.count === 0) return;
25554
+ let sumX = 0, sumY = 0, sumZ = 0;
25555
+ for (let i = 0; i < this.count; i++) {
25556
+ const idx = i * 3;
25557
+ sumX += this._positions[idx + 0];
25558
+ sumY += this._positions[idx + 1];
25559
+ sumZ += this._positions[idx + 2];
25560
+ }
25561
+ const centerX = sumX / this.count;
25562
+ const centerY = sumY / this.count;
25563
+ const centerZ = sumZ / this.count;
25564
+ this._centerOffset.set(centerX, centerY, centerZ);
25565
+ for (let i = 0; i < this.count; i++) {
25566
+ const idx = i * 3;
25567
+ this._positions[idx + 0] -= centerX;
25568
+ this._positions[idx + 1] -= centerY;
25569
+ this._positions[idx + 2] -= centerZ;
25570
+ }
25571
+ this.object3D.localPosition = this._centerOffset;
25572
+ }
25573
+ buildPositionTexture() {
25574
+ const w = this.size.x | 0;
25575
+ const h = this.size.y | 0;
25576
+ const count = this.count;
25577
+ const data = new Float32Array(w * h * 4);
25578
+ for (let i = 0; i < count; i++) {
25579
+ const idx = i * 4;
25580
+ const posIdx = i * 3;
25581
+ data[idx + 0] = this._positions[posIdx + 0];
25582
+ data[idx + 1] = this._positions[posIdx + 1];
25583
+ data[idx + 2] = this._positions[posIdx + 2];
25584
+ data[idx + 3] = 0;
25585
+ }
25586
+ if (count < w * h) {
25587
+ const lastIdx = (count - 1) * 4;
25588
+ for (let i = count; i < w * h; i++) {
25589
+ const idx = i * 4;
25590
+ data[idx + 0] = data[lastIdx + 0];
25591
+ data[idx + 1] = data[lastIdx + 1];
25592
+ data[idx + 2] = data[lastIdx + 2];
25593
+ data[idx + 3] = 0;
25594
+ }
25595
+ }
25596
+ this.pointPosition = new Float32ArrayTexture().create(w, h, data);
25597
+ this.pointPosition.name = "pointPosition";
25598
+ this.pointPosition.minFilter = "nearest";
25599
+ this.pointPosition.magFilter = "nearest";
25600
+ this.pointPosition.addressModeU = "clamp-to-edge";
25601
+ this.pointPosition.addressModeV = "clamp-to-edge";
25602
+ }
25603
+ buildColorTexture() {
25604
+ const w = this.size.x | 0;
25605
+ const h = this.size.y | 0;
25606
+ const count = this.count;
25607
+ const data = new Uint8Array(w * h * 4);
25608
+ for (let i = 0; i < count; i++) {
25609
+ const idx = i * 4;
25610
+ const colorIdx = i * 4;
25611
+ data[idx + 0] = this._colors[colorIdx + 0];
25612
+ data[idx + 1] = this._colors[colorIdx + 1];
25613
+ data[idx + 2] = this._colors[colorIdx + 2];
25614
+ data[idx + 3] = this._colors[colorIdx + 3];
25615
+ }
25616
+ if (count < w * h) {
25617
+ const lastIdx = (count - 1) * 4;
25618
+ for (let i = count; i < w * h; i++) {
25619
+ const idx = i * 4;
25620
+ data[idx + 0] = data[lastIdx + 0];
25621
+ data[idx + 1] = data[lastIdx + 1];
25622
+ data[idx + 2] = data[lastIdx + 2];
25623
+ data[idx + 3] = data[lastIdx + 3];
25624
+ }
25625
+ }
25626
+ this.pointColor = new Uint8ArrayTexture().create(w, h, data, false);
25627
+ this.pointColor.name = "pointColor";
25628
+ this.pointColor.minFilter = "nearest";
25629
+ this.pointColor.magFilter = "nearest";
25630
+ this.pointColor.mipmapFilter = "nearest";
25631
+ this.pointColor.addressModeU = "clamp-to-edge";
25632
+ this.pointColor.addressModeV = "clamp-to-edge";
25633
+ }
25634
+ buildOrderTexture() {
25635
+ const total = this.size.x * this.size.y;
25636
+ this._orderData = new Uint32Array(total);
25637
+ for (let i = 0; i < total; i++) {
25638
+ this._orderData[i] = i < this.count ? i : this.count > 0 ? this.count - 1 : 0;
25639
+ }
25640
+ this.pointOrder = new R32UintTexture().create(this.size.x, this.size.y, this._orderData);
25641
+ this.pointOrder.name = "pointOrder";
25642
+ this.pointOrder.minFilter = "nearest";
25643
+ this.pointOrder.magFilter = "nearest";
25644
+ this.pointOrder.addressModeU = "clamp-to-edge";
25645
+ this.pointOrder.addressModeV = "clamp-to-edge";
25646
+ }
25647
+ /**
25648
+ * Update node before rendering
25649
+ */
25650
+ nodeUpdate(view, passType, renderPassState, clusterLightingBuffer) {
25651
+ const worldMatrix = this.object3D.transform.worldMatrix;
25652
+ this.pointCloudMaterial.setTransformMatrix(worldMatrix);
25653
+ if (!this._texturesInitialized) {
25654
+ this.pointCloudMaterial.setPointTextures(
25655
+ this.pointPosition,
25656
+ this.pointColor,
25657
+ this.texParams,
25658
+ this.pointOrder
25659
+ );
25660
+ this.pointCloudMaterial.setBatchSize(this._batchSize);
25661
+ this.pointCloudMaterial.setPointSize(this.texParams[3]);
25662
+ this.pointCloudMaterial.enableDebugFullScreen(this._debugFullScreen);
25663
+ this._texturesInitialized = true;
25664
+ }
25665
+ super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer);
25666
+ }
25667
+ /**
25668
+ * Render pass
25669
+ */
25670
+ renderPass(view, passType, renderContext) {
25671
+ const encoder = renderContext.encoder;
25672
+ for (let mat of this.materials) {
25673
+ const passes = mat.getPass(passType);
25674
+ if (!passes || passes.length === 0) continue;
25675
+ for (const pass of passes) {
25676
+ if (!pass.pipeline) continue;
25677
+ pass.apply(this.geometry, renderContext.rendererPassState || renderContext);
25678
+ GPUContext.bindPipeline(encoder, pass);
25679
+ GPUContext.bindGeometryBuffer(encoder, this.geometry);
25680
+ const subGeometry = this.geometry.subGeometries[0];
25681
+ const lodInfo = subGeometry.lodLevels[0];
25682
+ if (this.instanceCount > 0) {
25683
+ GPUContext.drawIndexed(
25684
+ encoder,
25685
+ lodInfo.indexCount,
25686
+ this.instanceCount,
25687
+ lodInfo.indexStart,
25688
+ 0,
25689
+ 0
25690
+ );
25691
+ } else {
25692
+ GPUContext.drawIndexed(
25693
+ encoder,
25694
+ lodInfo.indexCount,
25695
+ 1,
25696
+ lodInfo.indexStart,
25697
+ 0,
25698
+ 0
25699
+ );
25700
+ }
25701
+ }
25702
+ }
25703
+ }
25704
+ /**
25705
+ * Set point size in pixels
25706
+ * @param size Point size in pixels
25707
+ */
25708
+ setPointSize(size) {
25709
+ this.texParams[3] = Math.max(0.1, size);
25710
+ if (this.pointCloudMaterial) {
25711
+ this.pointCloudMaterial.setPointSize(size);
25712
+ }
25713
+ }
25714
+ /**
25715
+ * Set point shape
25716
+ * @param shape 'square' or 'circle'
25717
+ */
25718
+ setPointShape(shape) {
25719
+ if (this.pointCloudMaterial) {
25720
+ this.pointCloudMaterial.setPointShape(shape);
25721
+ }
25722
+ }
25723
+ /**
25724
+ * Enable a fullscreen debug quad to validate the render pipeline.
25725
+ */
25726
+ enableDebugFullScreen(enabled) {
25727
+ this._debugFullScreen = enabled;
25728
+ if (this.pointCloudMaterial) {
25729
+ this.pointCloudMaterial.enableDebugFullScreen(enabled);
25730
+ }
25731
+ }
25732
+ /**
25733
+ * Set batch size for instanced rendering
25734
+ * @param batchSize Number of points per draw call
25735
+ */
25736
+ setBatchSize(batchSize) {
25737
+ this._batchSize = Math.max(1, batchSize | 0);
25738
+ if (this.geometry) {
25739
+ const oldGeometry = this.geometry;
25740
+ Reference.getInstance().detached(oldGeometry, this);
25741
+ if (!Reference.getInstance().hasReference(oldGeometry)) {
25742
+ oldGeometry.destroy();
25743
+ }
25744
+ this.geometry = new PointCloudGeometry(this._batchSize);
25745
+ }
25746
+ if (this.pointCloudMaterial) {
25747
+ this.pointCloudMaterial.setBatchSize(this._batchSize);
25748
+ this.pointCloudMaterial.enableDebugFullScreen(this._debugFullScreen);
25749
+ }
25750
+ this.instanceCount = Math.ceil(this.count / this._batchSize);
25751
+ }
25752
+ destroy(force) {
25753
+ if (this.pointColor) {
25754
+ this.pointColor.destroy(force);
25755
+ this.pointColor = null;
25756
+ }
25757
+ if (this.pointPosition) {
25758
+ this.pointPosition.destroy(force);
25759
+ this.pointPosition = null;
25760
+ }
25761
+ if (this.pointOrder) {
25762
+ this.pointOrder.destroy(force);
25763
+ this.pointOrder = null;
25764
+ }
25765
+ this._positions = null;
25766
+ this._colors = null;
25767
+ this._orderData = null;
25768
+ this.texParams = null;
25769
+ super.destroy(force);
25770
+ }
25771
+ };
25772
+ PointCloudRenderer = __decorateClass$j([
25773
+ RegisterComponent(PointCloudRenderer, "PointCloudRenderer")
25774
+ ], PointCloudRenderer);
25775
+
25088
25776
  class BoundUtil {
25089
25777
  static maxVector = new Vector3(
25090
25778
  Number.MAX_VALUE * 0.1,
@@ -25104,6 +25792,36 @@ class BoundUtil {
25104
25792
  new Vector3(),
25105
25793
  new Vector3()
25106
25794
  ];
25795
+ static genPointCloudBounds(obj, bound) {
25796
+ bound ||= new BoundingBox(Vector3.ZERO, Vector3.ZERO);
25797
+ bound.setFromMinMax(this.maxVector, this.minVector);
25798
+ let pointCloudRenderers = obj.getComponents(PointCloudRenderer);
25799
+ if (!pointCloudRenderers) {
25800
+ console.warn("genPointCloudBounds: No PointCloudRenderer found on object");
25801
+ return bound;
25802
+ }
25803
+ for (const pointCloudRenderer of pointCloudRenderers) {
25804
+ const positions = pointCloudRenderer.positions;
25805
+ const count = pointCloudRenderer.fullCount;
25806
+ if (!positions || count === 0) {
25807
+ console.warn("genPointCloudBounds: No position data available");
25808
+ continue;
25809
+ }
25810
+ const matrix = pointCloudRenderer.object3D.transform.worldMatrix;
25811
+ const point = new Vector3();
25812
+ for (let i = 0; i < count; i++) {
25813
+ const idx = i * 3;
25814
+ point.set(
25815
+ positions[idx + 0],
25816
+ positions[idx + 1],
25817
+ positions[idx + 2]
25818
+ );
25819
+ matrix.transformPoint(point, point);
25820
+ bound.expandByPoint(point);
25821
+ }
25822
+ }
25823
+ return bound;
25824
+ }
25107
25825
  static genGSplatBounds(obj, bound) {
25108
25826
  bound ||= new BoundingBox(Vector3.ZERO, Vector3.ZERO);
25109
25827
  bound.setFromMinMax(this.maxVector, this.minVector);
@@ -41425,7 +42143,7 @@ class PostProcessingComponent extends ComponentBase {
41425
42143
  }
41426
42144
  }
41427
42145
 
41428
- const version = "1.0.25";
42146
+ const version = "1.0.27";
41429
42147
 
41430
42148
  class Engine3D {
41431
42149
  /**
@@ -59137,6 +59855,15 @@ function detectGSplatFormat(buffer) {
59137
59855
  return "unknown" /* UNKNOWN */;
59138
59856
  }
59139
59857
 
59858
+ var PlyMode = /* @__PURE__ */ ((PlyMode2) => {
59859
+ PlyMode2[PlyMode2["Splat"] = 0] = "Splat";
59860
+ PlyMode2[PlyMode2["PointCloud"] = 1] = "PointCloud";
59861
+ PlyMode2[PlyMode2["Mesh"] = 2] = "Mesh";
59862
+ return PlyMode2;
59863
+ })(PlyMode || {});
59864
+ const splatProperties = ["x", "y", "z", "scale_0", "scale_1", "scale_2", "opacity", "rot_0", "rot_1", "rot_2", "rot_3"];
59865
+ const splatColorProperties = ["red", "green", "blue", "f_dc_0", "f_dc_1", "f_dc_2"];
59866
+
59140
59867
  function byteSizeOfType(t) {
59141
59868
  switch (t) {
59142
59869
  case "char":
@@ -59212,34 +59939,85 @@ function parsePlyHeader(buffer) {
59212
59939
  const lines = headerText.split(/\r?\n/);
59213
59940
  let format = "";
59214
59941
  let vertexCount = 0;
59942
+ let faceCount = 0;
59215
59943
  const properties = [];
59944
+ const faceProperties = [];
59945
+ const textureFiles = [];
59216
59946
  let inVertexElement = false;
59947
+ let inFaceElement = false;
59217
59948
  for (const line of lines) {
59218
59949
  if (line.startsWith("format ")) {
59219
59950
  format = line.split(/\s+/)[1];
59951
+ } else if (line.startsWith("comment TextureFile ")) {
59952
+ const texturePath = line.substring("comment TextureFile ".length).trim();
59953
+ if (texturePath) {
59954
+ textureFiles.push(texturePath);
59955
+ }
59220
59956
  } else if (line.startsWith("element ")) {
59221
59957
  const toks = line.split(/\s+/);
59222
59958
  inVertexElement = toks[1] === "vertex";
59223
- if (inVertexElement) vertexCount = parseInt(toks[2]);
59959
+ inFaceElement = toks[1] === "face";
59960
+ if (inVertexElement) {
59961
+ vertexCount = parseInt(toks[2]);
59962
+ inFaceElement = false;
59963
+ }
59964
+ if (inFaceElement) {
59965
+ faceCount = parseInt(toks[2]);
59966
+ inVertexElement = false;
59967
+ }
59224
59968
  } else if (inVertexElement && line.startsWith("property ")) {
59225
59969
  const toks = line.split(/\s+/);
59226
59970
  const type = toks[1];
59227
59971
  const name = toks[2];
59228
59972
  properties.push({ name, type });
59973
+ } else if (inFaceElement && line.startsWith("property ")) {
59974
+ const toks = line.split(/\s+/);
59975
+ if (toks[1] === "list") {
59976
+ const countType = toks[2];
59977
+ const itemType = toks[3];
59978
+ const name = toks[4];
59979
+ faceProperties.push({ name, type: `list ${countType} ${itemType}` });
59980
+ } else {
59981
+ const type = toks[1];
59982
+ const name = toks[2];
59983
+ faceProperties.push({ name, type });
59984
+ }
59229
59985
  }
59230
59986
  }
59231
- if (format !== "binary_little_endian") {
59232
- throw new Error("PLY: Only binary_little_endian PLY is supported");
59987
+ if (format !== "binary_little_endian" && format !== "ascii") {
59988
+ throw new Error(`PLY: Unsupported format: ${format}. Only binary_little_endian and ascii are supported.`);
59989
+ }
59990
+ let splatPropertyCount = 0;
59991
+ let splatPropertyColorCount = 0;
59992
+ for (const property of properties) {
59993
+ if (splatProperties.includes(property.name)) {
59994
+ splatPropertyCount++;
59995
+ }
59996
+ if (splatColorProperties.includes(property.name)) {
59997
+ splatPropertyColorCount++;
59998
+ }
59233
59999
  }
59234
60000
  return {
59235
60001
  format,
59236
60002
  vertexCount,
60003
+ faceCount,
59237
60004
  properties,
59238
- headerByteLength: headerText.length
60005
+ faceProperties: faceProperties.length > 0 ? faceProperties : void 0,
60006
+ textureFiles,
60007
+ headerByteLength: headerText.length,
60008
+ mode: faceCount ? PlyMode.Mesh : splatPropertyCount === splatProperties.length && splatPropertyColorCount === 3 ? PlyMode.Splat : PlyMode.PointCloud
59239
60009
  };
59240
60010
  }
59241
60011
  function parsePlyGaussianSplat(buffer) {
59242
60012
  const header = parsePlyHeader(buffer);
60013
+ const { format } = header;
60014
+ if (format === "ascii") {
60015
+ return parsePlyGaussianSplatASCII(buffer, header);
60016
+ } else {
60017
+ return parsePlyGaussianSplatBinary(buffer, header);
60018
+ }
60019
+ }
60020
+ function parsePlyGaussianSplatBinary(buffer, header) {
59243
60021
  const { vertexCount, properties, headerByteLength } = header;
59244
60022
  const payload = new DataView(buffer, headerByteLength);
59245
60023
  const has = (n) => properties.find((p) => p.name === n) != null;
@@ -59361,6 +60139,903 @@ function parsePlyGaussianSplat(buffer) {
59361
60139
  sh: hasSH && shCoeffs ? { order: shOrder, coeffs: shCoeffs } : void 0
59362
60140
  };
59363
60141
  }
60142
+ function parsePlyGaussianSplatASCII(buffer, header) {
60143
+ const { vertexCount, properties } = header;
60144
+ const text = new TextDecoder("utf-8").decode(buffer);
60145
+ const headerEnd = text.indexOf("end_header");
60146
+ if (headerEnd < 0) {
60147
+ throw new Error("PLY: Invalid PLY header");
60148
+ }
60149
+ let bodyStart = headerEnd + "end_header".length;
60150
+ while (bodyStart < text.length && (text[bodyStart] === " " || text[bodyStart] === "\n" || text[bodyStart] === "\r")) {
60151
+ bodyStart++;
60152
+ }
60153
+ const bodyText = text.substring(bodyStart);
60154
+ const tokens = bodyText.split(/\s+/).filter((token) => token.length > 0);
60155
+ let tokenIndex = 0;
60156
+ const has = (n) => properties.find((p) => p.name === n) != null;
60157
+ const propIndex = (n) => properties.findIndex((p) => p.name === n);
60158
+ const parseASCIINumber = (type) => {
60159
+ if (tokenIndex >= tokens.length) {
60160
+ throw new Error("PLY: Unexpected end of file");
60161
+ }
60162
+ const value = tokens[tokenIndex++];
60163
+ switch (type) {
60164
+ case "char":
60165
+ case "uchar":
60166
+ case "short":
60167
+ case "ushort":
60168
+ case "int":
60169
+ case "uint":
60170
+ case "int8":
60171
+ case "uint8":
60172
+ case "int16":
60173
+ case "uint16":
60174
+ case "int32":
60175
+ case "uint32":
60176
+ return parseInt(value);
60177
+ case "float":
60178
+ case "double":
60179
+ case "float32":
60180
+ case "float64":
60181
+ return parseFloat(value);
60182
+ default:
60183
+ return parseFloat(value);
60184
+ }
60185
+ };
60186
+ const position = new Float32Array(vertexCount * 3);
60187
+ const scale = has("scale_0") ? new Float32Array(vertexCount * 3) : void 0;
60188
+ const rotation = has("rot_0") ? new Float32Array(vertexCount * 4) : void 0;
60189
+ const opacity = has("opacity") ? new Float32Array(vertexCount) : void 0;
60190
+ const dcIdx = [propIndex("f_dc_0"), propIndex("f_dc_1"), propIndex("f_dc_2")];
60191
+ const restIndices = [];
60192
+ for (let i = 0; i < properties.length; i++) {
60193
+ if (properties[i].name.startsWith("f_rest_")) restIndices.push(i);
60194
+ }
60195
+ const hasSH = dcIdx[0] >= 0 && dcIdx[1] >= 0 && dcIdx[2] >= 0;
60196
+ let shCoeffs = void 0;
60197
+ let shOrder = 0;
60198
+ if (hasSH) {
60199
+ const coeffsPerColor = 1 + restIndices.length / 3;
60200
+ shOrder = inferSHOrder(coeffsPerColor);
60201
+ shCoeffs = new Float32Array(vertexCount * coeffsPerColor * 3);
60202
+ }
60203
+ const ix = propIndex("x");
60204
+ const iy = propIndex("y");
60205
+ const iz = propIndex("z");
60206
+ if (ix < 0 || iy < 0 || iz < 0) {
60207
+ throw new Error("PLY: Missing x/y/z for vertex");
60208
+ }
60209
+ const s0 = scale ? propIndex("scale_0") : -1;
60210
+ const s1 = scale ? propIndex("scale_1") : -1;
60211
+ const s2 = scale ? propIndex("scale_2") : -1;
60212
+ const r0 = rotation ? propIndex("rot_0") : -1;
60213
+ const r1 = rotation ? propIndex("rot_1") : -1;
60214
+ const r2 = rotation ? propIndex("rot_2") : -1;
60215
+ const r3 = rotation ? propIndex("rot_3") : -1;
60216
+ const oi = opacity ? propIndex("opacity") : -1;
60217
+ for (let v = 0; v < vertexCount; v++) {
60218
+ for (let pIdx = 0; pIdx < properties.length; pIdx++) {
60219
+ const prop = properties[pIdx];
60220
+ const value = parseASCIINumber(prop.type);
60221
+ if (pIdx === ix) {
60222
+ position[v * 3 + 0] = value;
60223
+ } else if (pIdx === iy) {
60224
+ position[v * 3 + 1] = value;
60225
+ } else if (pIdx === iz) {
60226
+ position[v * 3 + 2] = value;
60227
+ }
60228
+ if (scale && pIdx === s0) {
60229
+ scale[v * 3 + 0] = value;
60230
+ } else if (scale && pIdx === s1) {
60231
+ scale[v * 3 + 1] = value;
60232
+ } else if (scale && pIdx === s2) {
60233
+ scale[v * 3 + 2] = value;
60234
+ }
60235
+ if (rotation && pIdx === r0) {
60236
+ rotation[v * 4 + 3] = value;
60237
+ } else if (rotation && pIdx === r1) {
60238
+ rotation[v * 4 + 0] = value;
60239
+ } else if (rotation && pIdx === r2) {
60240
+ rotation[v * 4 + 1] = value;
60241
+ } else if (rotation && pIdx === r3) {
60242
+ rotation[v * 4 + 2] = value;
60243
+ }
60244
+ if (opacity && pIdx === oi) {
60245
+ opacity[v] = value;
60246
+ }
60247
+ if (hasSH && shCoeffs) {
60248
+ const coeffsPerColor = 1 + restIndices.length / 3;
60249
+ const baseIndex = v * coeffsPerColor * 3;
60250
+ if (pIdx === dcIdx[0]) {
60251
+ shCoeffs[baseIndex + 0] = value;
60252
+ } else if (pIdx === dcIdx[1]) {
60253
+ shCoeffs[baseIndex + coeffsPerColor + 0] = value;
60254
+ } else if (pIdx === dcIdx[2]) {
60255
+ shCoeffs[baseIndex + 2 * coeffsPerColor + 0] = value;
60256
+ }
60257
+ for (let i = 0; i < restIndices.length; i += 3) {
60258
+ const ri = restIndices[i + 0];
60259
+ const gi = restIndices[i + 1];
60260
+ const bi = restIndices[i + 2];
60261
+ if (pIdx === ri) {
60262
+ shCoeffs[baseIndex + (i / 3 + 1)] = value;
60263
+ } else if (pIdx === gi) {
60264
+ shCoeffs[baseIndex + coeffsPerColor + (i / 3 + 1)] = value;
60265
+ } else if (pIdx === bi) {
60266
+ shCoeffs[baseIndex + 2 * coeffsPerColor + (i / 3 + 1)] = value;
60267
+ }
60268
+ }
60269
+ }
60270
+ }
60271
+ }
60272
+ return {
60273
+ vertexCount,
60274
+ position,
60275
+ scale,
60276
+ rotation,
60277
+ opacity,
60278
+ sh: hasSH && shCoeffs ? { order: shOrder, coeffs: shCoeffs } : void 0
60279
+ };
60280
+ }
60281
+ function parsePlyMesh(buffer) {
60282
+ const header = parsePlyHeader(buffer);
60283
+ const { format, vertexCount, faceCount, properties, faceProperties, textureFiles, headerByteLength } = header;
60284
+ if (format === "ascii") {
60285
+ return parsePlyMeshASCII(buffer, header);
60286
+ } else {
60287
+ return parsePlyMeshBinary(buffer, header);
60288
+ }
60289
+ }
60290
+ function parsePlyMeshBinary(buffer, header) {
60291
+ const { vertexCount, faceCount, properties, faceProperties, textureFiles, headerByteLength } = header;
60292
+ const payload = new DataView(buffer, headerByteLength);
60293
+ const has = (n) => properties.find((p) => p.name === n) != null;
60294
+ const propIndex = (n) => properties.findIndex((p) => p.name === n);
60295
+ const hasTexcoord = faceProperties?.some((p) => p.name === "texcoord") || false;
60296
+ const hasTexnumber = faceProperties?.some((p) => p.name === "texnumber") || false;
60297
+ faceProperties?.find((p) => p.name === "texcoord");
60298
+ faceProperties?.find((p) => p.name === "texnumber");
60299
+ const position = new Float32Array(vertexCount * 3);
60300
+ const hasNormalData = has("nx") && has("ny") && has("nz");
60301
+ const normal = hasNormalData ? new Float32Array(vertexCount * 3) : new Float32Array(vertexCount * 3);
60302
+ const color = (has("red") || has("r")) && (has("green") || has("g")) && (has("blue") || has("b")) ? new Float32Array(vertexCount * 3) : void 0;
60303
+ const hasVertexUV = (has("u") || has("s")) && (has("v") || has("t"));
60304
+ const uv = hasVertexUV || hasTexcoord ? new Float32Array(vertexCount * 2) : void 0;
60305
+ const faceTexcoords = /* @__PURE__ */ new Map();
60306
+ const faceTexnumbers = hasTexnumber ? new Array(faceCount) : [];
60307
+ const propOffsets = [];
60308
+ let stride = 0;
60309
+ for (const p of properties) {
60310
+ propOffsets.push(stride);
60311
+ stride += byteSizeOfType(p.type);
60312
+ }
60313
+ let base = 0;
60314
+ for (let v = 0; v < vertexCount; v++) {
60315
+ const vOffset = base;
60316
+ const ix = propIndex("x");
60317
+ const iy = propIndex("y");
60318
+ const iz = propIndex("z");
60319
+ if (ix < 0 || iy < 0 || iz < 0) {
60320
+ throw new Error("PLY: Missing x/y/z for vertex");
60321
+ }
60322
+ position[v * 3 + 0] = readByType(payload, vOffset + propOffsets[ix], properties[ix].type);
60323
+ position[v * 3 + 1] = readByType(payload, vOffset + propOffsets[iy], properties[iy].type);
60324
+ position[v * 3 + 2] = readByType(payload, vOffset + propOffsets[iz], properties[iz].type);
60325
+ if (hasNormalData) {
60326
+ const nx = propIndex("nx");
60327
+ const ny = propIndex("ny");
60328
+ const nz = propIndex("nz");
60329
+ normal[v * 3 + 0] = readByType(payload, vOffset + propOffsets[nx], properties[nx].type);
60330
+ normal[v * 3 + 1] = readByType(payload, vOffset + propOffsets[ny], properties[ny].type);
60331
+ normal[v * 3 + 2] = readByType(payload, vOffset + propOffsets[nz], properties[nz].type);
60332
+ }
60333
+ if (color) {
60334
+ const rIdx = propIndex("red") >= 0 ? propIndex("red") : propIndex("r");
60335
+ const gIdx = propIndex("green") >= 0 ? propIndex("green") : propIndex("g");
60336
+ const bIdx = propIndex("blue") >= 0 ? propIndex("blue") : propIndex("b");
60337
+ if (rIdx >= 0 && gIdx >= 0 && bIdx >= 0) {
60338
+ let r = readByType(payload, vOffset + propOffsets[rIdx], properties[rIdx].type);
60339
+ let g = readByType(payload, vOffset + propOffsets[gIdx], properties[gIdx].type);
60340
+ let b = readByType(payload, vOffset + propOffsets[bIdx], properties[bIdx].type);
60341
+ if (properties[rIdx].type === "uchar" || properties[rIdx].type === "uint8") {
60342
+ r /= 255;
60343
+ g /= 255;
60344
+ b /= 255;
60345
+ }
60346
+ color[v * 3 + 0] = r;
60347
+ color[v * 3 + 1] = g;
60348
+ color[v * 3 + 2] = b;
60349
+ }
60350
+ }
60351
+ if (uv) {
60352
+ const uIdx = propIndex("u") >= 0 ? propIndex("u") : propIndex("s");
60353
+ const vIdx = propIndex("v") >= 0 ? propIndex("v") : propIndex("t");
60354
+ if (uIdx >= 0 && vIdx >= 0) {
60355
+ uv[v * 2 + 0] = readByType(payload, vOffset + propOffsets[uIdx], properties[uIdx].type);
60356
+ uv[v * 2 + 1] = readByType(payload, vOffset + propOffsets[vIdx], properties[vIdx].type);
60357
+ }
60358
+ }
60359
+ base += stride;
60360
+ }
60361
+ const indices = [];
60362
+ const triangleTexnumbers = [];
60363
+ const faceVertexUvs = [];
60364
+ let faceBase = base;
60365
+ uv && !hasVertexUV && !hasTexcoord ? new Array(vertexCount).fill(false) : null;
60366
+ for (let f = 0; f < faceCount; f++) {
60367
+ let currentOffset = faceBase;
60368
+ let faceIndices = [];
60369
+ let faceTexcoordArray = void 0;
60370
+ let faceTexnum = 0;
60371
+ let vertexCountInFace = 0;
60372
+ if (!faceProperties || faceProperties.length === 0) {
60373
+ throw new Error("PLY: Face element must have properties");
60374
+ }
60375
+ for (const prop of faceProperties) {
60376
+ if (prop.name === "vertex_indices") {
60377
+ const parts = prop.type.split(" ");
60378
+ if (parts.length !== 3 || parts[0] !== "list") {
60379
+ throw new Error(`PLY: Invalid vertex_indices property type: ${prop.type}`);
60380
+ }
60381
+ const countType = parts[1];
60382
+ const itemType = parts[2];
60383
+ vertexCountInFace = readByType(payload, currentOffset, countType);
60384
+ currentOffset += byteSizeOfType(countType);
60385
+ if (vertexCountInFace < 3) {
60386
+ throw new Error(`PLY: Face ${f} has less than 3 vertices`);
60387
+ }
60388
+ const indexSize = byteSizeOfType(itemType);
60389
+ faceIndices = [];
60390
+ for (let i = 0; i < vertexCountInFace; i++) {
60391
+ const idx = readByType(payload, currentOffset, itemType);
60392
+ faceIndices.push(idx);
60393
+ currentOffset += indexSize;
60394
+ }
60395
+ } else if (prop.name === "texcoord") {
60396
+ const parts = prop.type.split(" ");
60397
+ if (parts.length !== 3 || parts[0] !== "list") {
60398
+ throw new Error(`PLY: Invalid texcoord property type: ${prop.type}`);
60399
+ }
60400
+ const countType = parts[1];
60401
+ const itemType = parts[2];
60402
+ const texcoordCount = readByType(payload, currentOffset, countType);
60403
+ currentOffset += byteSizeOfType(countType);
60404
+ const itemSize = byteSizeOfType(itemType);
60405
+ faceTexcoordArray = new Float32Array(texcoordCount);
60406
+ for (let i = 0; i < texcoordCount; i++) {
60407
+ faceTexcoordArray[i] = readByType(payload, currentOffset, itemType);
60408
+ currentOffset += itemSize;
60409
+ }
60410
+ faceTexcoords.set(f, faceTexcoordArray);
60411
+ } else if (prop.name === "texnumber") {
60412
+ faceTexnum = readByType(payload, currentOffset, prop.type);
60413
+ currentOffset += byteSizeOfType(prop.type);
60414
+ faceTexnumbers[f] = faceTexnum;
60415
+ } else {
60416
+ if (prop.type.startsWith("list ")) {
60417
+ const parts = prop.type.split(" ");
60418
+ if (parts.length === 3) {
60419
+ const countType = parts[1];
60420
+ const itemType = parts[2];
60421
+ const count = readByType(payload, currentOffset, countType);
60422
+ currentOffset += byteSizeOfType(countType);
60423
+ const itemSize = byteSizeOfType(itemType);
60424
+ currentOffset += count * itemSize;
60425
+ }
60426
+ } else {
60427
+ currentOffset += byteSizeOfType(prop.type);
60428
+ }
60429
+ }
60430
+ }
60431
+ faceBase = currentOffset;
60432
+ const texnum = hasTexnumber ? faceTexnumbers[f] ?? 0 : 0;
60433
+ if (vertexCountInFace === 3) {
60434
+ indices.push(faceIndices[0], faceIndices[1], faceIndices[2]);
60435
+ if (hasTexnumber) {
60436
+ triangleTexnumbers.push(texnum);
60437
+ }
60438
+ if (hasTexcoord && faceTexcoordArray && faceTexcoordArray.length >= 6) {
60439
+ faceVertexUvs.push(
60440
+ faceTexcoordArray[0],
60441
+ 1 - faceTexcoordArray[1],
60442
+ // vertex 0
60443
+ faceTexcoordArray[2],
60444
+ 1 - faceTexcoordArray[3],
60445
+ // vertex 1
60446
+ faceTexcoordArray[4],
60447
+ 1 - faceTexcoordArray[5]
60448
+ // vertex 2
60449
+ );
60450
+ }
60451
+ } else {
60452
+ for (let i = 1; i < vertexCountInFace - 1; i++) {
60453
+ indices.push(faceIndices[0], faceIndices[i], faceIndices[i + 1]);
60454
+ if (hasTexnumber) {
60455
+ triangleTexnumbers.push(texnum);
60456
+ }
60457
+ if (hasTexcoord && faceTexcoordArray && faceTexcoordArray.length >= vertexCountInFace * 2) {
60458
+ faceVertexUvs.push(
60459
+ faceTexcoordArray[0],
60460
+ 1 - faceTexcoordArray[1],
60461
+ // vertex 0 (center of fan)
60462
+ faceTexcoordArray[i * 2 + 0],
60463
+ 1 - faceTexcoordArray[i * 2 + 1],
60464
+ // vertex i
60465
+ faceTexcoordArray[(i + 1) * 2 + 0],
60466
+ 1 - faceTexcoordArray[(i + 1) * 2 + 1]
60467
+ // vertex i+1
60468
+ );
60469
+ }
60470
+ }
60471
+ }
60472
+ }
60473
+ if (!hasNormalData) {
60474
+ for (let i = 0; i < vertexCount * 3; i++) {
60475
+ normal[i] = 0;
60476
+ }
60477
+ for (let i = 0; i < indices.length; i += 3) {
60478
+ const i0 = indices[i];
60479
+ const i1 = indices[i + 1];
60480
+ const i2 = indices[i + 2];
60481
+ const v0x = position[i0 * 3 + 0];
60482
+ const v0y = position[i0 * 3 + 1];
60483
+ const v0z = position[i0 * 3 + 2];
60484
+ const v1x = position[i1 * 3 + 0];
60485
+ const v1y = position[i1 * 3 + 1];
60486
+ const v1z = position[i1 * 3 + 2];
60487
+ const v2x = position[i2 * 3 + 0];
60488
+ const v2y = position[i2 * 3 + 1];
60489
+ const v2z = position[i2 * 3 + 2];
60490
+ const edge1x = v1x - v0x;
60491
+ const edge1y = v1y - v0y;
60492
+ const edge1z = v1z - v0z;
60493
+ const edge2x = v2x - v0x;
60494
+ const edge2y = v2y - v0y;
60495
+ const edge2z = v2z - v0z;
60496
+ const nx = edge1y * edge2z - edge1z * edge2y;
60497
+ const ny = edge1z * edge2x - edge1x * edge2z;
60498
+ const nz = edge1x * edge2y - edge1y * edge2x;
60499
+ normal[i0 * 3 + 0] += nx;
60500
+ normal[i0 * 3 + 1] += ny;
60501
+ normal[i0 * 3 + 2] += nz;
60502
+ normal[i1 * 3 + 0] += nx;
60503
+ normal[i1 * 3 + 1] += ny;
60504
+ normal[i1 * 3 + 2] += nz;
60505
+ normal[i2 * 3 + 0] += nx;
60506
+ normal[i2 * 3 + 1] += ny;
60507
+ normal[i2 * 3 + 2] += nz;
60508
+ }
60509
+ for (let v = 0; v < vertexCount; v++) {
60510
+ const nx = normal[v * 3 + 0];
60511
+ const ny = normal[v * 3 + 1];
60512
+ const nz = normal[v * 3 + 2];
60513
+ const length = Math.sqrt(nx * nx + ny * ny + nz * nz);
60514
+ if (length > 1e-5) {
60515
+ normal[v * 3 + 0] = nx / length;
60516
+ normal[v * 3 + 1] = ny / length;
60517
+ normal[v * 3 + 2] = nz / length;
60518
+ } else {
60519
+ normal[v * 3 + 0] = 0;
60520
+ normal[v * 3 + 1] = 1;
60521
+ normal[v * 3 + 2] = 0;
60522
+ }
60523
+ }
60524
+ }
60525
+ let finalPosition = position;
60526
+ let finalNormal = normal;
60527
+ let finalColor = color;
60528
+ let finalUv = void 0;
60529
+ let finalIndices = void 0;
60530
+ if (hasTexcoord && faceVertexUvs.length > 0) {
60531
+ const triangleCount = indices.length / 3;
60532
+ const expandedPosition = new Float32Array(triangleCount * 3 * 3);
60533
+ const expandedNormal = new Float32Array(triangleCount * 3 * 3);
60534
+ const expandedColor = color ? new Float32Array(triangleCount * 3 * 3) : void 0;
60535
+ finalUv = new Float32Array(faceVertexUvs);
60536
+ for (let i = 0; i < triangleCount; i++) {
60537
+ const baseIdx = i * 3;
60538
+ const i0 = indices[baseIdx + 0];
60539
+ const i1 = indices[baseIdx + 1];
60540
+ const i2 = indices[baseIdx + 2];
60541
+ expandedPosition[i * 9 + 0] = position[i0 * 3 + 0];
60542
+ expandedPosition[i * 9 + 1] = position[i0 * 3 + 1];
60543
+ expandedPosition[i * 9 + 2] = position[i0 * 3 + 2];
60544
+ expandedPosition[i * 9 + 3] = position[i1 * 3 + 0];
60545
+ expandedPosition[i * 9 + 4] = position[i1 * 3 + 1];
60546
+ expandedPosition[i * 9 + 5] = position[i1 * 3 + 2];
60547
+ expandedPosition[i * 9 + 6] = position[i2 * 3 + 0];
60548
+ expandedPosition[i * 9 + 7] = position[i2 * 3 + 1];
60549
+ expandedPosition[i * 9 + 8] = position[i2 * 3 + 2];
60550
+ expandedNormal[i * 9 + 0] = normal[i0 * 3 + 0];
60551
+ expandedNormal[i * 9 + 1] = normal[i0 * 3 + 1];
60552
+ expandedNormal[i * 9 + 2] = normal[i0 * 3 + 2];
60553
+ expandedNormal[i * 9 + 3] = normal[i1 * 3 + 0];
60554
+ expandedNormal[i * 9 + 4] = normal[i1 * 3 + 1];
60555
+ expandedNormal[i * 9 + 5] = normal[i1 * 3 + 2];
60556
+ expandedNormal[i * 9 + 6] = normal[i2 * 3 + 0];
60557
+ expandedNormal[i * 9 + 7] = normal[i2 * 3 + 1];
60558
+ expandedNormal[i * 9 + 8] = normal[i2 * 3 + 2];
60559
+ if (expandedColor && color) {
60560
+ expandedColor[i * 9 + 0] = color[i0 * 3 + 0];
60561
+ expandedColor[i * 9 + 1] = color[i0 * 3 + 1];
60562
+ expandedColor[i * 9 + 2] = color[i0 * 3 + 2];
60563
+ expandedColor[i * 9 + 3] = color[i1 * 3 + 0];
60564
+ expandedColor[i * 9 + 4] = color[i1 * 3 + 1];
60565
+ expandedColor[i * 9 + 5] = color[i1 * 3 + 2];
60566
+ expandedColor[i * 9 + 6] = color[i2 * 3 + 0];
60567
+ expandedColor[i * 9 + 7] = color[i2 * 3 + 1];
60568
+ expandedColor[i * 9 + 8] = color[i2 * 3 + 2];
60569
+ }
60570
+ }
60571
+ finalPosition = expandedPosition;
60572
+ finalNormal = expandedNormal;
60573
+ finalColor = expandedColor;
60574
+ const sequentialIndices = new Uint32Array(triangleCount * 3);
60575
+ for (let i = 0; i < triangleCount * 3; i++) {
60576
+ sequentialIndices[i] = i;
60577
+ }
60578
+ finalIndices = sequentialIndices;
60579
+ } else {
60580
+ finalIndices = new Uint32Array(indices);
60581
+ finalUv = uv;
60582
+ }
60583
+ return {
60584
+ vertexCount: hasTexcoord && faceVertexUvs.length > 0 ? finalPosition.length / 3 : vertexCount,
60585
+ faceCount,
60586
+ position: finalPosition,
60587
+ normal: finalNormal,
60588
+ color: finalColor,
60589
+ uv: finalUv,
60590
+ indices: finalIndices,
60591
+ textureFiles: textureFiles.length > 0 ? textureFiles : void 0,
60592
+ triangleTexnumbers: triangleTexnumbers.length > 0 ? triangleTexnumbers : void 0
60593
+ };
60594
+ }
60595
+ function parsePlyMeshASCII(buffer, header) {
60596
+ const { vertexCount, faceCount, properties, faceProperties, textureFiles, headerByteLength } = header;
60597
+ const text = new TextDecoder("utf-8").decode(buffer);
60598
+ const headerEnd = text.indexOf("end_header");
60599
+ if (headerEnd < 0) {
60600
+ throw new Error("PLY: Invalid PLY header");
60601
+ }
60602
+ let bodyStart = headerEnd + "end_header".length;
60603
+ while (bodyStart < text.length && (text[bodyStart] === " " || text[bodyStart] === "\n" || text[bodyStart] === "\r")) {
60604
+ bodyStart++;
60605
+ }
60606
+ const bodyText = text.substring(bodyStart);
60607
+ const tokens = bodyText.split(/\s+/).filter((token) => token.length > 0);
60608
+ let tokenIndex = 0;
60609
+ const has = (n) => properties.find((p) => p.name === n) != null;
60610
+ const parseASCIINumber = (type) => {
60611
+ if (tokenIndex >= tokens.length) {
60612
+ throw new Error("PLY: Unexpected end of file");
60613
+ }
60614
+ const value = tokens[tokenIndex++];
60615
+ switch (type) {
60616
+ case "char":
60617
+ case "uchar":
60618
+ case "short":
60619
+ case "ushort":
60620
+ case "int":
60621
+ case "uint":
60622
+ case "int8":
60623
+ case "uint8":
60624
+ case "int16":
60625
+ case "uint16":
60626
+ case "int32":
60627
+ case "uint32":
60628
+ return parseInt(value);
60629
+ case "float":
60630
+ case "double":
60631
+ case "float32":
60632
+ case "float64":
60633
+ return parseFloat(value);
60634
+ default:
60635
+ return parseFloat(value);
60636
+ }
60637
+ };
60638
+ const position = new Float32Array(vertexCount * 3);
60639
+ const hasNormalData = has("nx") && has("ny") && has("nz");
60640
+ const normal = hasNormalData ? new Float32Array(vertexCount * 3) : new Float32Array(vertexCount * 3);
60641
+ const color = (has("red") || has("r")) && (has("green") || has("g")) && (has("blue") || has("b")) ? new Float32Array(vertexCount * 3) : void 0;
60642
+ const hasVertexUV = (has("u") || has("s")) && (has("v") || has("t"));
60643
+ const hasTexcoord = faceProperties?.some((p) => p.name === "texcoord") || false;
60644
+ const uv = hasVertexUV || hasTexcoord ? new Float32Array(vertexCount * 2) : void 0;
60645
+ const faceTexcoords = /* @__PURE__ */ new Map();
60646
+ const hasTexnumber = faceProperties?.some((p) => p.name === "texnumber") || false;
60647
+ const faceTexnumbers = hasTexnumber ? new Array(faceCount) : [];
60648
+ const indices = [];
60649
+ const triangleTexnumbers = [];
60650
+ const faceVertexUvs = [];
60651
+ const propIndex = (n) => properties.findIndex((p) => p.name === n);
60652
+ const xIdx = propIndex("x");
60653
+ const yIdx = propIndex("y");
60654
+ const zIdx = propIndex("z");
60655
+ const nxIdx = hasNormalData ? propIndex("nx") : -1;
60656
+ const nyIdx = hasNormalData ? propIndex("ny") : -1;
60657
+ const nzIdx = hasNormalData ? propIndex("nz") : -1;
60658
+ const rIdx = color ? propIndex("red") >= 0 ? propIndex("red") : propIndex("r") : -1;
60659
+ const gIdx = color ? propIndex("green") >= 0 ? propIndex("green") : propIndex("g") : -1;
60660
+ const bIdx = color ? propIndex("blue") >= 0 ? propIndex("blue") : propIndex("b") : -1;
60661
+ const uIdx = uv && hasVertexUV ? propIndex("u") >= 0 ? propIndex("u") : propIndex("s") : -1;
60662
+ const vIdx = uv && hasVertexUV ? propIndex("v") >= 0 ? propIndex("v") : propIndex("t") : -1;
60663
+ for (let v = 0; v < vertexCount; v++) {
60664
+ for (let pIdx = 0; pIdx < properties.length; pIdx++) {
60665
+ const prop = properties[pIdx];
60666
+ const value = parseASCIINumber(prop.type);
60667
+ if (pIdx === xIdx) {
60668
+ position[v * 3 + 0] = value;
60669
+ } else if (pIdx === yIdx) {
60670
+ position[v * 3 + 1] = value;
60671
+ } else if (pIdx === zIdx) {
60672
+ position[v * 3 + 2] = value;
60673
+ } else if (pIdx === nxIdx) {
60674
+ normal[v * 3 + 0] = value;
60675
+ } else if (pIdx === nyIdx) {
60676
+ normal[v * 3 + 1] = value;
60677
+ } else if (pIdx === nzIdx) {
60678
+ normal[v * 3 + 2] = value;
60679
+ } else if (pIdx === rIdx && color) {
60680
+ color[v * 3 + 0] = prop.type === "uchar" || prop.type === "uint8" ? value / 255 : value;
60681
+ } else if (pIdx === gIdx && color) {
60682
+ color[v * 3 + 1] = prop.type === "uchar" || prop.type === "uint8" ? value / 255 : value;
60683
+ } else if (pIdx === bIdx && color) {
60684
+ color[v * 3 + 2] = prop.type === "uchar" || prop.type === "uint8" ? value / 255 : value;
60685
+ } else if (pIdx === uIdx && uv) {
60686
+ uv[v * 2 + 0] = value;
60687
+ } else if (pIdx === vIdx && uv) {
60688
+ uv[v * 2 + 1] = value;
60689
+ }
60690
+ }
60691
+ }
60692
+ for (let f = 0; f < faceCount; f++) {
60693
+ let faceIndices = [];
60694
+ let faceTexcoordArray = void 0;
60695
+ let faceTexnum = 0;
60696
+ for (const prop of faceProperties || []) {
60697
+ if (prop.name === "vertex_indices") {
60698
+ const parts = prop.type.split(" ");
60699
+ const countType = parts[1];
60700
+ const itemType = parts[2];
60701
+ const vertexCountInFace2 = parseASCIINumber(countType);
60702
+ faceIndices = [];
60703
+ for (let i = 0; i < vertexCountInFace2; i++) {
60704
+ faceIndices.push(parseASCIINumber(itemType));
60705
+ }
60706
+ } else if (prop.name === "texcoord") {
60707
+ const parts = prop.type.split(" ");
60708
+ const countType = parts[1];
60709
+ const itemType = parts[2];
60710
+ const texcoordCount = parseASCIINumber(countType);
60711
+ faceTexcoordArray = new Float32Array(texcoordCount);
60712
+ for (let i = 0; i < texcoordCount; i++) {
60713
+ faceTexcoordArray[i] = parseASCIINumber(itemType);
60714
+ }
60715
+ faceTexcoords.set(f, faceTexcoordArray);
60716
+ } else if (prop.name === "texnumber") {
60717
+ faceTexnum = parseASCIINumber(prop.type);
60718
+ faceTexnumbers[f] = faceTexnum;
60719
+ }
60720
+ }
60721
+ const vertexCountInFace = faceIndices.length;
60722
+ const texnum = hasTexnumber ? faceTexnumbers[f] ?? 0 : 0;
60723
+ if (vertexCountInFace === 3) {
60724
+ indices.push(faceIndices[0], faceIndices[1], faceIndices[2]);
60725
+ if (hasTexnumber) {
60726
+ triangleTexnumbers.push(texnum);
60727
+ }
60728
+ if (hasTexcoord && faceTexcoordArray && faceTexcoordArray.length >= 6) {
60729
+ faceVertexUvs.push(
60730
+ faceTexcoordArray[0],
60731
+ 1 - faceTexcoordArray[1],
60732
+ faceTexcoordArray[2],
60733
+ 1 - faceTexcoordArray[3],
60734
+ faceTexcoordArray[4],
60735
+ 1 - faceTexcoordArray[5]
60736
+ );
60737
+ }
60738
+ } else {
60739
+ for (let i = 1; i < vertexCountInFace - 1; i++) {
60740
+ indices.push(faceIndices[0], faceIndices[i], faceIndices[i + 1]);
60741
+ if (hasTexnumber) {
60742
+ triangleTexnumbers.push(texnum);
60743
+ }
60744
+ if (hasTexcoord && faceTexcoordArray && faceTexcoordArray.length >= vertexCountInFace * 2) {
60745
+ faceVertexUvs.push(
60746
+ faceTexcoordArray[0],
60747
+ 1 - faceTexcoordArray[1],
60748
+ faceTexcoordArray[i * 2 + 0],
60749
+ 1 - faceTexcoordArray[i * 2 + 1],
60750
+ faceTexcoordArray[(i + 1) * 2 + 0],
60751
+ 1 - faceTexcoordArray[(i + 1) * 2 + 1]
60752
+ );
60753
+ }
60754
+ }
60755
+ }
60756
+ }
60757
+ if (!hasNormalData) {
60758
+ for (let i = 0; i < vertexCount * 3; i++) {
60759
+ normal[i] = 0;
60760
+ }
60761
+ for (let i = 0; i < indices.length; i += 3) {
60762
+ const i0 = indices[i];
60763
+ const i1 = indices[i + 1];
60764
+ const i2 = indices[i + 2];
60765
+ const v0x = position[i0 * 3 + 0];
60766
+ const v0y = position[i0 * 3 + 1];
60767
+ const v0z = position[i0 * 3 + 2];
60768
+ const v1x = position[i1 * 3 + 0];
60769
+ const v1y = position[i1 * 3 + 1];
60770
+ const v1z = position[i1 * 3 + 2];
60771
+ const v2x = position[i2 * 3 + 0];
60772
+ const v2y = position[i2 * 3 + 1];
60773
+ const v2z = position[i2 * 3 + 2];
60774
+ const edge1x = v1x - v0x;
60775
+ const edge1y = v1y - v0y;
60776
+ const edge1z = v1z - v0z;
60777
+ const edge2x = v2x - v0x;
60778
+ const edge2y = v2y - v0y;
60779
+ const edge2z = v2z - v0z;
60780
+ const nx = edge1y * edge2z - edge1z * edge2y;
60781
+ const ny = edge1z * edge2x - edge1x * edge2z;
60782
+ const nz = edge1x * edge2y - edge1y * edge2x;
60783
+ normal[i0 * 3 + 0] += nx;
60784
+ normal[i0 * 3 + 1] += ny;
60785
+ normal[i0 * 3 + 2] += nz;
60786
+ normal[i1 * 3 + 0] += nx;
60787
+ normal[i1 * 3 + 1] += ny;
60788
+ normal[i1 * 3 + 2] += nz;
60789
+ normal[i2 * 3 + 0] += nx;
60790
+ normal[i2 * 3 + 1] += ny;
60791
+ normal[i2 * 3 + 2] += nz;
60792
+ }
60793
+ for (let v = 0; v < vertexCount; v++) {
60794
+ const nx = normal[v * 3 + 0];
60795
+ const ny = normal[v * 3 + 1];
60796
+ const nz = normal[v * 3 + 2];
60797
+ const length = Math.sqrt(nx * nx + ny * ny + nz * nz);
60798
+ if (length > 1e-5) {
60799
+ normal[v * 3 + 0] = nx / length;
60800
+ normal[v * 3 + 1] = ny / length;
60801
+ normal[v * 3 + 2] = nz / length;
60802
+ } else {
60803
+ normal[v * 3 + 0] = 0;
60804
+ normal[v * 3 + 1] = 1;
60805
+ normal[v * 3 + 2] = 0;
60806
+ }
60807
+ }
60808
+ }
60809
+ let finalPosition = position;
60810
+ let finalNormal = normal;
60811
+ let finalColor = color;
60812
+ let finalUv = void 0;
60813
+ let finalIndices = void 0;
60814
+ if (hasTexcoord && faceVertexUvs.length > 0) {
60815
+ const triangleCount = indices.length / 3;
60816
+ const expandedPosition = new Float32Array(triangleCount * 3 * 3);
60817
+ const expandedNormal = new Float32Array(triangleCount * 3 * 3);
60818
+ const expandedColor = color ? new Float32Array(triangleCount * 3 * 3) : void 0;
60819
+ finalUv = new Float32Array(faceVertexUvs);
60820
+ for (let i = 0; i < triangleCount; i++) {
60821
+ const baseIdx = i * 3;
60822
+ const i0 = indices[baseIdx + 0];
60823
+ const i1 = indices[baseIdx + 1];
60824
+ const i2 = indices[baseIdx + 2];
60825
+ expandedPosition[i * 9 + 0] = position[i0 * 3 + 0];
60826
+ expandedPosition[i * 9 + 1] = position[i0 * 3 + 1];
60827
+ expandedPosition[i * 9 + 2] = position[i0 * 3 + 2];
60828
+ expandedPosition[i * 9 + 3] = position[i1 * 3 + 0];
60829
+ expandedPosition[i * 9 + 4] = position[i1 * 3 + 1];
60830
+ expandedPosition[i * 9 + 5] = position[i1 * 3 + 2];
60831
+ expandedPosition[i * 9 + 6] = position[i2 * 3 + 0];
60832
+ expandedPosition[i * 9 + 7] = position[i2 * 3 + 1];
60833
+ expandedPosition[i * 9 + 8] = position[i2 * 3 + 2];
60834
+ expandedNormal[i * 9 + 0] = normal[i0 * 3 + 0];
60835
+ expandedNormal[i * 9 + 1] = normal[i0 * 3 + 1];
60836
+ expandedNormal[i * 9 + 2] = normal[i0 * 3 + 2];
60837
+ expandedNormal[i * 9 + 3] = normal[i1 * 3 + 0];
60838
+ expandedNormal[i * 9 + 4] = normal[i1 * 3 + 1];
60839
+ expandedNormal[i * 9 + 5] = normal[i1 * 3 + 2];
60840
+ expandedNormal[i * 9 + 6] = normal[i2 * 3 + 0];
60841
+ expandedNormal[i * 9 + 7] = normal[i2 * 3 + 1];
60842
+ expandedNormal[i * 9 + 8] = normal[i2 * 3 + 2];
60843
+ if (expandedColor && color) {
60844
+ expandedColor[i * 9 + 0] = color[i0 * 3 + 0];
60845
+ expandedColor[i * 9 + 1] = color[i0 * 3 + 1];
60846
+ expandedColor[i * 9 + 2] = color[i0 * 3 + 2];
60847
+ expandedColor[i * 9 + 3] = color[i1 * 3 + 0];
60848
+ expandedColor[i * 9 + 4] = color[i1 * 3 + 1];
60849
+ expandedColor[i * 9 + 5] = color[i1 * 3 + 2];
60850
+ expandedColor[i * 9 + 6] = color[i2 * 3 + 0];
60851
+ expandedColor[i * 9 + 7] = color[i2 * 3 + 1];
60852
+ expandedColor[i * 9 + 8] = color[i2 * 3 + 2];
60853
+ }
60854
+ }
60855
+ finalPosition = expandedPosition;
60856
+ finalNormal = expandedNormal;
60857
+ finalColor = expandedColor;
60858
+ const sequentialIndices = new Uint32Array(triangleCount * 3);
60859
+ for (let i = 0; i < triangleCount * 3; i++) {
60860
+ sequentialIndices[i] = i;
60861
+ }
60862
+ finalIndices = sequentialIndices;
60863
+ } else {
60864
+ finalIndices = new Uint32Array(indices);
60865
+ finalUv = uv;
60866
+ }
60867
+ return {
60868
+ vertexCount: hasTexcoord && faceVertexUvs.length > 0 ? finalPosition.length / 3 : vertexCount,
60869
+ faceCount,
60870
+ position: finalPosition,
60871
+ normal: finalNormal,
60872
+ color: finalColor,
60873
+ uv: finalUv,
60874
+ indices: finalIndices,
60875
+ textureFiles: textureFiles.length > 0 ? textureFiles : void 0,
60876
+ triangleTexnumbers: triangleTexnumbers.length > 0 ? triangleTexnumbers : void 0
60877
+ };
60878
+ }
60879
+ function parsePlyPointCloud(buffer) {
60880
+ const header = parsePlyHeader(buffer);
60881
+ const { format } = header;
60882
+ if (format === "ascii") {
60883
+ return parsePlyPointCloudASCII(buffer, header);
60884
+ } else {
60885
+ return parsePlyPointCloudBinary(buffer, header);
60886
+ }
60887
+ }
60888
+ function parsePlyPointCloudBinary(buffer, header) {
60889
+ const { vertexCount, properties, headerByteLength } = header;
60890
+ const payload = new DataView(buffer, headerByteLength);
60891
+ const has = (n) => properties.find((p) => p.name === n) != null;
60892
+ const propIndex = (n) => properties.findIndex((p) => p.name === n);
60893
+ const position = new Float32Array(vertexCount * 3);
60894
+ const hasColor = (has("red") || has("r")) && (has("green") || has("g")) && (has("blue") || has("b"));
60895
+ const hasAlpha = has("alpha") || has("a");
60896
+ const color = hasColor ? new Uint8Array(vertexCount * 4) : void 0;
60897
+ const propOffsets = [];
60898
+ let stride = 0;
60899
+ for (const p of properties) {
60900
+ propOffsets.push(stride);
60901
+ stride += byteSizeOfType(p.type);
60902
+ }
60903
+ let base = 0;
60904
+ for (let v = 0; v < vertexCount; v++) {
60905
+ const vOffset = base;
60906
+ const ix = propIndex("x");
60907
+ const iy = propIndex("y");
60908
+ const iz = propIndex("z");
60909
+ if (ix < 0 || iy < 0 || iz < 0) {
60910
+ throw new Error("PLY: Missing x/y/z for vertex");
60911
+ }
60912
+ position[v * 3 + 0] = readByType(payload, vOffset + propOffsets[ix], properties[ix].type);
60913
+ position[v * 3 + 1] = readByType(payload, vOffset + propOffsets[iy], properties[iy].type);
60914
+ position[v * 3 + 2] = readByType(payload, vOffset + propOffsets[iz], properties[iz].type);
60915
+ if (color) {
60916
+ const rIdx = propIndex("red") >= 0 ? propIndex("red") : propIndex("r");
60917
+ const gIdx = propIndex("green") >= 0 ? propIndex("green") : propIndex("g");
60918
+ const bIdx = propIndex("blue") >= 0 ? propIndex("blue") : propIndex("b");
60919
+ const aIdx = hasAlpha ? propIndex("alpha") >= 0 ? propIndex("alpha") : propIndex("a") : -1;
60920
+ if (rIdx >= 0 && gIdx >= 0 && bIdx >= 0) {
60921
+ let r = readByType(payload, vOffset + propOffsets[rIdx], properties[rIdx].type);
60922
+ let g = readByType(payload, vOffset + propOffsets[gIdx], properties[gIdx].type);
60923
+ let b = readByType(payload, vOffset + propOffsets[bIdx], properties[bIdx].type);
60924
+ let a = 255;
60925
+ if (properties[rIdx].type === "float" || properties[rIdx].type === "float32" || properties[rIdx].type === "double" || properties[rIdx].type === "float64") {
60926
+ r = Math.round(r * 255);
60927
+ g = Math.round(g * 255);
60928
+ b = Math.round(b * 255);
60929
+ }
60930
+ if (aIdx >= 0) {
60931
+ a = readByType(payload, vOffset + propOffsets[aIdx], properties[aIdx].type);
60932
+ if (properties[aIdx].type === "float" || properties[aIdx].type === "float32" || properties[aIdx].type === "double" || properties[aIdx].type === "float64") {
60933
+ a = Math.round(a * 255);
60934
+ }
60935
+ }
60936
+ color[v * 4 + 0] = Math.max(0, Math.min(255, r));
60937
+ color[v * 4 + 1] = Math.max(0, Math.min(255, g));
60938
+ color[v * 4 + 2] = Math.max(0, Math.min(255, b));
60939
+ color[v * 4 + 3] = Math.max(0, Math.min(255, a));
60940
+ }
60941
+ }
60942
+ base += stride;
60943
+ }
60944
+ return {
60945
+ vertexCount,
60946
+ position,
60947
+ color
60948
+ };
60949
+ }
60950
+ function parsePlyPointCloudASCII(buffer, header) {
60951
+ const { vertexCount, properties } = header;
60952
+ const text = new TextDecoder("utf-8").decode(buffer);
60953
+ const headerEnd = text.indexOf("end_header");
60954
+ if (headerEnd < 0) {
60955
+ throw new Error("PLY: Invalid PLY header");
60956
+ }
60957
+ let bodyStart = headerEnd + "end_header".length;
60958
+ while (bodyStart < text.length && (text[bodyStart] === " " || text[bodyStart] === "\n" || text[bodyStart] === "\r")) {
60959
+ bodyStart++;
60960
+ }
60961
+ const bodyText = text.substring(bodyStart);
60962
+ const tokens = bodyText.split(/\s+/).filter((token) => token.length > 0);
60963
+ let tokenIndex = 0;
60964
+ const has = (n) => properties.find((p) => p.name === n) != null;
60965
+ const parseASCIINumber = (type) => {
60966
+ if (tokenIndex >= tokens.length) {
60967
+ throw new Error("PLY: Unexpected end of file");
60968
+ }
60969
+ const value = tokens[tokenIndex++];
60970
+ switch (type) {
60971
+ case "char":
60972
+ case "uchar":
60973
+ case "short":
60974
+ case "ushort":
60975
+ case "int":
60976
+ case "uint":
60977
+ case "int8":
60978
+ case "uint8":
60979
+ case "int16":
60980
+ case "uint16":
60981
+ case "int32":
60982
+ case "uint32":
60983
+ return parseInt(value);
60984
+ case "float":
60985
+ case "double":
60986
+ case "float32":
60987
+ case "float64":
60988
+ return parseFloat(value);
60989
+ default:
60990
+ return parseFloat(value);
60991
+ }
60992
+ };
60993
+ const position = new Float32Array(vertexCount * 3);
60994
+ const hasColor = (has("red") || has("r")) && (has("green") || has("g")) && (has("blue") || has("b"));
60995
+ const hasAlpha = has("alpha") || has("a");
60996
+ const color = hasColor ? new Uint8Array(vertexCount * 4) : void 0;
60997
+ const propIndex = (n) => properties.findIndex((p) => p.name === n);
60998
+ const xIdx = propIndex("x");
60999
+ const yIdx = propIndex("y");
61000
+ const zIdx = propIndex("z");
61001
+ const rIdx = hasColor ? propIndex("red") >= 0 ? propIndex("red") : propIndex("r") : -1;
61002
+ const gIdx = hasColor ? propIndex("green") >= 0 ? propIndex("green") : propIndex("g") : -1;
61003
+ const bIdx = hasColor ? propIndex("blue") >= 0 ? propIndex("blue") : propIndex("b") : -1;
61004
+ const aIdx = hasAlpha ? propIndex("alpha") >= 0 ? propIndex("alpha") : propIndex("a") : -1;
61005
+ for (let v = 0; v < vertexCount; v++) {
61006
+ for (let pIdx = 0; pIdx < properties.length; pIdx++) {
61007
+ const prop = properties[pIdx];
61008
+ const value = parseASCIINumber(prop.type);
61009
+ if (pIdx === xIdx) {
61010
+ position[v * 3 + 0] = value;
61011
+ } else if (pIdx === yIdx) {
61012
+ position[v * 3 + 1] = value;
61013
+ } else if (pIdx === zIdx) {
61014
+ position[v * 3 + 2] = value;
61015
+ } else if (pIdx === rIdx && color) {
61016
+ const r = prop.type === "uchar" || prop.type === "uint8" ? value : Math.round(value * 255);
61017
+ color[v * 4 + 0] = Math.max(0, Math.min(255, r));
61018
+ } else if (pIdx === gIdx && color) {
61019
+ const g = prop.type === "uchar" || prop.type === "uint8" ? value : Math.round(value * 255);
61020
+ color[v * 4 + 1] = Math.max(0, Math.min(255, g));
61021
+ } else if (pIdx === bIdx && color) {
61022
+ const b = prop.type === "uchar" || prop.type === "uint8" ? value : Math.round(value * 255);
61023
+ color[v * 4 + 2] = Math.max(0, Math.min(255, b));
61024
+ } else if (pIdx === aIdx && color) {
61025
+ const a = prop.type === "uchar" || prop.type === "uint8" ? value : Math.round(value * 255);
61026
+ color[v * 4 + 3] = Math.max(0, Math.min(255, a));
61027
+ }
61028
+ }
61029
+ if (color && aIdx < 0) {
61030
+ color[v * 4 + 3] = 255;
61031
+ }
61032
+ }
61033
+ return {
61034
+ vertexCount,
61035
+ position,
61036
+ color
61037
+ };
61038
+ }
59364
61039
 
59365
61040
  class GaussianSplatParser extends ParserBase {
59366
61041
  static format = ParserFormat.BIN;
@@ -59469,6 +61144,150 @@ class KHR_lights_punctual {
59469
61144
  class KHR_materials_ior {
59470
61145
  }
59471
61146
 
61147
+ class PlyParser extends ParserBase {
61148
+ static format = ParserFormat.BIN;
61149
+ async parseBuffer(buffer) {
61150
+ const header = parsePlyHeader(buffer);
61151
+ switch (header.mode) {
61152
+ case PlyMode.Splat: {
61153
+ const plyData = parsePlyGaussianSplat(buffer);
61154
+ const asset = {
61155
+ count: plyData.vertexCount,
61156
+ position: plyData.position,
61157
+ rotation: plyData.rotation,
61158
+ scale: plyData.scale,
61159
+ opacity: plyData.opacity,
61160
+ sh: plyData.sh
61161
+ };
61162
+ asset.bbox = computeAABBFromPositions(plyData.position);
61163
+ const gsplatObj = new Object3D();
61164
+ gsplatObj.name = "GaussianSplat";
61165
+ const renderer = gsplatObj.addComponent(GSplatRenderer);
61166
+ renderer.initAsset(asset);
61167
+ this.data = gsplatObj;
61168
+ break;
61169
+ }
61170
+ case PlyMode.PointCloud: {
61171
+ const plyData = parsePlyPointCloud(buffer);
61172
+ const pointCloudObj = new Object3D();
61173
+ pointCloudObj.name = "PLYPointCloud";
61174
+ const pointCloudObjRoot = new Object3D();
61175
+ pointCloudObjRoot.name = "PLYPointCloudRoot";
61176
+ pointCloudObj.addChild(pointCloudObjRoot);
61177
+ const renderer = pointCloudObjRoot.addComponent(PointCloudRenderer);
61178
+ if (plyData.color) {
61179
+ renderer.initFromData(plyData.position, plyData.color, plyData.vertexCount);
61180
+ } else {
61181
+ const defaultColors = new Uint8Array(plyData.vertexCount * 4);
61182
+ defaultColors.fill(255);
61183
+ renderer.initFromData(plyData.position, defaultColors, plyData.vertexCount);
61184
+ }
61185
+ renderer.setPointShape("circle");
61186
+ renderer.setPointSize(4);
61187
+ this.data = pointCloudObj;
61188
+ break;
61189
+ }
61190
+ case PlyMode.Mesh: {
61191
+ const plyData = parsePlyMesh(buffer);
61192
+ const rootObj = new Object3D();
61193
+ rootObj.name = "PLYMesh";
61194
+ const textureGroups = /* @__PURE__ */ new Map();
61195
+ if (plyData.triangleTexnumbers && plyData.triangleTexnumbers.length > 0) {
61196
+ for (let i = 0; i < plyData.triangleTexnumbers.length; i++) {
61197
+ const texnum = plyData.triangleTexnumbers[i];
61198
+ if (!textureGroups.has(texnum)) {
61199
+ textureGroups.set(texnum, []);
61200
+ }
61201
+ textureGroups.get(texnum).push(i);
61202
+ }
61203
+ } else {
61204
+ const triangleCount = plyData.indices.length / 3;
61205
+ const allTriangles = [];
61206
+ for (let i = 0; i < triangleCount; i++) {
61207
+ allTriangles.push(i);
61208
+ }
61209
+ textureGroups.set(0, allTriangles);
61210
+ }
61211
+ const materials = /* @__PURE__ */ new Map();
61212
+ if (plyData.textureFiles && plyData.textureFiles.length > 0) {
61213
+ const promiseList = [];
61214
+ for (let texnum = 0; texnum < plyData.textureFiles.length; texnum++) {
61215
+ const material = new LitMaterial();
61216
+ const texturePath = StringUtil.normalizePath(
61217
+ this.baseUrl + plyData.textureFiles[texnum]
61218
+ );
61219
+ promiseList.push(Engine3D.res.loadTexture(texturePath).then((texture) => {
61220
+ material.baseMap = texture;
61221
+ materials.set(texnum, material);
61222
+ }));
61223
+ }
61224
+ await Promise.all(promiseList);
61225
+ }
61226
+ if (materials.size === 0) {
61227
+ materials.set(0, new LitMaterial());
61228
+ }
61229
+ for (const [texnum, triangleIndices] of textureGroups) {
61230
+ const groupIndices = [];
61231
+ for (const triIdx of triangleIndices) {
61232
+ const baseIdx = triIdx * 3;
61233
+ groupIndices.push(
61234
+ plyData.indices[baseIdx + 0],
61235
+ plyData.indices[baseIdx + 1],
61236
+ plyData.indices[baseIdx + 2]
61237
+ );
61238
+ }
61239
+ const geometry = new GeometryBase();
61240
+ geometry.setAttribute(
61241
+ VertexAttributeName.position,
61242
+ plyData.position
61243
+ );
61244
+ geometry.setAttribute(
61245
+ VertexAttributeName.normal,
61246
+ plyData.normal
61247
+ );
61248
+ if (plyData.uv) {
61249
+ geometry.setAttribute(
61250
+ VertexAttributeName.uv,
61251
+ plyData.uv
61252
+ );
61253
+ }
61254
+ if (plyData.color) {
61255
+ geometry.setAttribute(
61256
+ VertexAttributeName.color,
61257
+ plyData.color
61258
+ );
61259
+ }
61260
+ geometry.setIndices(new Uint32Array(groupIndices));
61261
+ geometry.addSubGeometry({
61262
+ indexStart: 0,
61263
+ indexCount: groupIndices.length,
61264
+ vertexStart: 0,
61265
+ vertexCount: 0,
61266
+ firstStart: 0,
61267
+ index: 0,
61268
+ topology: 0
61269
+ });
61270
+ let material = materials.get(texnum);
61271
+ if (!material) {
61272
+ material = materials.values().next().value || new LitMaterial();
61273
+ }
61274
+ const meshObj = new Object3D();
61275
+ meshObj.name = `PLYMesh_Texture_${texnum}`;
61276
+ const renderer = meshObj.addComponent(MeshRenderer);
61277
+ renderer.geometry = geometry;
61278
+ renderer.material = material;
61279
+ rootObj.addChild(meshObj);
61280
+ }
61281
+ this.data = rootObj;
61282
+ break;
61283
+ }
61284
+ }
61285
+ }
61286
+ verification() {
61287
+ return !!this.data;
61288
+ }
61289
+ }
61290
+
59472
61291
  class PrefabBoneData {
59473
61292
  boneName;
59474
61293
  bonePath;
@@ -67605,69 +69424,6 @@ class TriGeometry extends GeometryBase {
67605
69424
  }
67606
69425
  }
67607
69426
 
67608
- class Float32ArrayTexture extends Texture {
67609
- create(width, height, data, filtering = true) {
67610
- let device = webGPUContext.device;
67611
- const bytesPerRow = width * 4 * 4;
67612
- this.format = GPUTextureFormat.rgba32float;
67613
- let mipmapCount = 1;
67614
- this.createTextureDescriptor(width, height, mipmapCount, this.format);
67615
- const textureDataBuffer = device.createBuffer({
67616
- size: data.byteLength,
67617
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
67618
- });
67619
- device.queue.writeBuffer(textureDataBuffer, 0, data);
67620
- const commandEncoder = GPUContext.beginCommandEncoder();
67621
- commandEncoder.copyBufferToTexture(
67622
- {
67623
- buffer: textureDataBuffer,
67624
- bytesPerRow
67625
- },
67626
- {
67627
- texture: this.getGPUTexture()
67628
- },
67629
- {
67630
- width,
67631
- height,
67632
- depthOrArrayLayers: 1
67633
- }
67634
- );
67635
- GPUContext.endCommandEncoder(commandEncoder);
67636
- if (filtering) {
67637
- this.samplerBindingLayout.type = `non-filtering`;
67638
- this.textureBindingLayout.sampleType = `unfilterable-float`;
67639
- }
67640
- this.gpuSampler = device.createSampler({});
67641
- }
67642
- fromBuffer(width, height, textureDataBuffer) {
67643
- let device = webGPUContext.device;
67644
- const bytesPerRow = width * 4 * 4;
67645
- this.format = GPUTextureFormat.rgba32float;
67646
- this.mipmapCount = 1;
67647
- this.createTextureDescriptor(width, height, this.mipmapCount, this.format);
67648
- const commandEncoder = GPUContext.beginCommandEncoder();
67649
- commandEncoder.copyBufferToTexture(
67650
- {
67651
- buffer: textureDataBuffer,
67652
- bytesPerRow
67653
- },
67654
- {
67655
- texture: this.getGPUTexture()
67656
- },
67657
- {
67658
- width,
67659
- height,
67660
- depthOrArrayLayers: 1
67661
- }
67662
- );
67663
- GPUContext.endCommandEncoder(commandEncoder);
67664
- this.samplerBindingLayout.type = `non-filtering`;
67665
- this.textureBindingLayout.sampleType = `unfilterable-float`;
67666
- this.gpuSampler = device.createSampler({});
67667
- return this;
67668
- }
67669
- }
67670
-
67671
69427
  class SolidColorSky extends LDRTextureCube {
67672
69428
  _internalTexture;
67673
69429
  _minSize = 32;
@@ -69044,4 +70800,4 @@ const __viteBrowserExternal = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.def
69044
70800
  __proto__: null
69045
70801
  }, Symbol.toStringTag, { value: 'Module' }));
69046
70802
 
69047
- export { AccelerateDecelerateInterpolator, AccelerateInterpolator, AnimationCurve, AnimationCurveT, AnimationMonitor, AnimatorComponent, AnimatorEventKeyframe, AnticipateInterpolator, AnticipateOvershootInterpolator, ArrayHas, ArrayItemIndex, AtlasParser, AtmosphericComponent, AtmosphericScatteringSky, AtmosphericScatteringSkySetting, AtmosphericScatteringSky_shader, AttributeAnimCurve, AxisObject, B3DMLoader, B3DMLoaderBase, B3DMParseUtil, B3DMParser, BRDFLUT, BRDFLUTGenerate, BRDF_frag, BatchTable, BiMap, BillboardComponent, BillboardType, BitUtil, BitmapTexture2D, BitmapTexture2DArray, BitmapTextureCube, Blend, BlendFactor, BlendMode, BlendShapeData, BlendShapePropertyData, BloomPost, BlurEffectCreatorBlur_cs, BlurEffectCreatorSample_cs, BlurTexture2DBufferCreator, BounceInterpolator, BoundUtil, BoundingBox, BoundingSphere, BoundingVolume, BoxColliderShape, BoxGeometry, BrdfLut_frag, BsDF_frag, BxDF_frag, BxdfDebug_frag, BytesArray, CEvent, CEventDispatcher, CEventListener, CResizeEvent, CSM, Camera3D, CameraControllerBase, CameraType, CameraUtil, CapsuleColliderShape, CastPointShadowMaterialPass, CastShadowMaterialPass, Clearcoat_frag, ClusterBoundsSource_cs, ClusterConfig, ClusterDebug_frag, ClusterLight, ClusterLightingBuffer, ClusterLightingRender, ClusterLighting_cs, CollectInfo, ColliderComponent, ColliderShape, ColliderShapeType, Color, ColorGradient, ColorLitMaterial, ColorLitShader, ColorPassFragmentOutput, ColorPassRenderer, ColorUtil, ComData, Combine_cs, Common_frag, Common_vert, ComponentBase, ComponentCollect, ComputeGPUBuffer, ComputeShader, Context3D, CubeCamera, CubeMapFaceEnum, CubeSky_Shader, CubicBezierCurve, CubicBezierPath, CubicBezierType, CycleInterpolator, CylinderGeometry, DDGIIrradianceComputePass, DDGIIrradianceGPUBufferReader, DDGIIrradianceVolume, DDGIIrradiance_shader, DDGILightingPass, DDGILighting_shader, DDGIMultiBouncePass, DDGIProbeRenderer, DEGREES_TO_RADIANS, DRACO_DECODER_GLTF_JS, DecelerateInterpolator, Denoising_cs, Depth2DTextureArray, DepthCubeArrayTexture, DepthMaterialPass, DepthOfFieldPost, DepthOfView_cs, DirectLight, DoubleArray, EditorInspector, Engine3D, Entity, EntityBatchCollect, EntityCollect, EnvMap_frag, ErpImage2CubeMap, ErpImage2CubeMapCreateCube_cs, ErpImage2CubeMapRgbe2rgba_cs, ExtrudeGeometry, FAILED, FASTFLOOR, FXAAPost, FXAAShader, FastMathShader, FatLineGeometry, FatLineMaterial, FatLineRenderer, FatLineShader, FatLine_FS, FatLine_VS, FeatureTable, FileLoader, FirstPersonCameraController, Float16ArrayTexture, Float32ArrayTexture, FlyCameraController, FontChar, FontInfo, FontPage, FontParser, ForwardRenderJob, FragmentOutput, FragmentVarying, FrameCache, Frustum, FrustumCSM, FrustumCulling_cs, FullQuad_vert_wgsl, GBufferFrame, GBufferPass, GBufferPost, GBufferStand, GBuffer_pass, GILighting, GIProbeMaterial, GIProbeMaterialType, GIProbeShader, GIRenderCompleteEvent, GIRenderStartEvent, GLBChunk, GLBHeader, GLBParser, GLSLLexer, GLSLLexerToken, GLSLPreprocessor, GLSLSyntax, GLTFBinaryExtension, GLTFMaterial, GLTFParser, GLTFSubParser, GLTFSubParserCamera, GLTFSubParserConverter, GLTFSubParserMaterial, GLTFSubParserMesh, GLTFSubParserSkeleton, GLTFSubParserSkin, GLTFType, GLTF_Accessors, GLTF_Info, GLTF_Light, GLTF_Mesh, GLTF_Node, GLTF_Primitives, GLTF_Scene, GPUAddressMode, GPUBlendFactor, GPUBufferBase, GPUBufferType, GPUCompareFunction, GPUContext, GPUCullMode, GPUFilterMode, GPUPrimitiveTopology, GPUTextureFormat, GPUVertexFormat, GPUVertexStepMode, GSplatFormat, GSplatGeometry, GSplatMaterial, GSplatRenderer, GSplatShader, GSplat_FS, GSplat_VS, GTAOPost, GTAO_cs, GUIAtlasTexture, GUICanvas, GUIConfig, GUIGeometry, GUIGeometryRebuild, GUIMaterial, GUIPassRenderer, GUIPick, GUIPickHelper, GUIQuad, GUIQuadAttrEnum, GUIRenderer, GUIShader, GUISpace, GUISprite, GUITexture, GaussianSplatParser, GenerayRandomDir, GeoJsonParser, GeoJsonUtil, GeoType, GeometryBase, GeometryIndicesBuffer, GeometryUtil, GeometryVertexBuffer, GeometryVertexType, GetComponentClass, GetCountInstanceID, GetRepeat, GetShader, GlassShader, GlobalBindGroup, GlobalBindGroupLayout, GlobalFog, GlobalFog_shader, GlobalIlluminationComponent, GlobalUniform, GlobalUniformGroup, GodRayPost, GodRay_cs, GridObject, HDRTexture, HDRTextureCube, Hair_frag, Hair_shader_op, Hair_shader_tr, HaltonSeq, Horizontal, HoverCameraController, I3DMLoader, I3DMLoaderBase, I3DMParser, IBLEnvMapCreator, IBLEnvMapCreator_cs, IESProfiles, IESProfiles_frag, IKDTreeUserData, ImageType, IndicesGPUBuffer, Inline_vert, InputSystem, InstanceDrawComponent, InstanceUniform, InstancedMesh, Interpolator, InterpolatorEnum, IrradianceDataReaderCompleteEvent, IrradianceVolumeData_frag, Irradiance_frag, IsEditorInspector, IsNonSerialize, Joint, JointPose, JumperInterpolator, KDTreeEntity, KDTreeNode, KDTreeRange, KDTreeSpace, KDTreeUUID, KHR_draco_mesh_compression, KHR_lights_punctual, KHR_materials_clearcoat, KHR_materials_emissive_strength, KHR_materials_ior, KHR_materials_unlit, KMZParser, KV, KelvinUtil, KeyCode, KeyEvent, Keyframe, KeyframeT, LDRTextureCube, LOADED, LOADING, LRUCache, LambertMaterial, Lambert_shader, Light, LightBase, LightData, LightEntries, LightType, LightingFunction_frag, Line, LineClassification, LinearInterpolator, LitMaterial, LitSSSShader, LitShader, Lit_shader, LoaderBase, LoaderEvent, LoaderManager, MAX_VALUE, MIN_VALUE, Material, MaterialDataUniformGPUBuffer, MaterialUtilities, MathShader, MathUtil, Matrix3, Matrix4, MatrixBindGroup, MatrixGPUBuffer, MatrixShader, MemoryDO, MemoryInfo, MergeRGBACreator, MergeRGBA_cs, MeshColliderShape, MeshFilter, MeshRenderer, MinMaxAnimationCurves, MinMaxCurve, MinMaxCurveState, MinMaxPolyCurves, MorePassParser, MorePassShader, MorphTargetBlender, MorphTargetData, MorphTargetFrame, MorphTargetTransformKey, MorphTarget_shader, MouseCode, MultiBouncePass_cs, Navi3DAstar, Navi3DConst, Navi3DEdge, Navi3DFunnel, Navi3DMaskType, Navi3DMesh, Navi3DPoint, Navi3DPoint2D, Navi3DPointFat, Navi3DRouter, Navi3DTriangle, NonSerialize, NormalMap_frag, OAnimationEvent, OBJParser, Object3D, Object3DEvent, Object3DTransformTools, Object3DUtil, ObjectAnimClip, OcclusionSystem, Octree, OctreeEntity, OrbitController, OrderMap, Orientation3D, OutLineBlendColor_cs, OutlineCalcOutline_cs, OutlinePass, OutlinePost, OutlinePostData, OutlinePostManager, OutlinePostSlot, Outline_cs, OvershootInterpolator, PARSING, PBRLItShader, PBRLitSSSShader, PLUGIN_REGISTERED, ParserBase, ParserFormat, ParticleSystemCurveEvalMode, ParticleSystemRandomnessIds, PassGenerate, PassShader, PassType, PhysicMaterialUniform_frag, PickCompute, PickFire, PickGUIEvent3D, PickResult, Picker_cs, PingPong, PipelinePool, Plane3D, PlaneClassification, PlaneGeometry, PointClassification, PointLight, PointLightShadowRenderer, PointShadowCubeCamera, PointerEvent3D, Polynomial, PolynomialCurve, Polynomials, PoolNode, PostBase, PostProcessingComponent, PostRenderer, PreDepthPassRenderer, PreFilteredEnvironment_cs, PreFilteredEnvironment_cs2, PreIntegratedLut, PreIntegratedLutCompute, PrefabAvatarData, PrefabAvatarParser, PrefabBoneData, PrefabMaterialParser, PrefabMeshData, PrefabMeshParser, PrefabNode, PrefabParser, PrefabStringUtil, PrefabTextureData, PrefabTextureParser, Preprocessor, PriorityQueue, Probe, ProbeEntries, ProbeGBufferFrame, ProfilerUtil, PropertyAnimClip, PropertyAnimTag, PropertyAnimation, PropertyAnimationClip, PropertyAnimationClipState, PropertyAnimationEvent, PropertyHelp, QuadAABB, QuadGlsl_fs, QuadGlsl_vs, QuadRoot, QuadShader, QuadTree, QuadTreeCell, Quad_depth2dArray_frag_wgsl, Quad_depth2d_frag_wgsl, Quad_depthCube_frag_wgsl, Quad_frag_wgsl, Quad_vert_wgsl, Quaternion, R32UintTexture, RADIANS_TO_DEGREES, RGBEErrorCode, RGBEHeader, RGBEParser, RTDescriptor, RTFrame, RTResourceConfig, RTResourceMap, Rand, RandomSeed, Ray, RayCastMeshDetail, Reader, Rect, Reference, Reflection, ReflectionCG, ReflectionEntries, ReflectionMaterial, ReflectionRenderer, ReflectionShader, ReflectionShader_shader, RegisterComponent, RegisterShader, RenderContext, RenderLayer, RenderLayerUtil, RenderNode, RenderShaderCollect, RenderShaderCompute, RenderShaderPass, RenderTexture, RendererBase, RendererJob, RendererMap, RendererMask, RendererMaskUtil, RendererPassState, RepeatSE, Res, RotationControlComponents, SHCommon_frag, SN_ArrayConstant, SN_BinaryOperation, SN_Break, SN_CodeBlock, SN_Constant, SN_Continue, SN_Declaration, SN_Discard, SN_DoWhileLoop, SN_Expression, SN_ForLoop, SN_Function, SN_FunctionArgs, SN_FunctionCall, SN_IFBranch, SN_Identifier, SN_IndexOperation, SN_Layout, SN_ParenExpression, SN_Precision, SN_Return, SN_SelectOperation, SN_Struct, SN_TernaryOperation, SN_UnaryOperation, SN_WhileLoop, SSAO_cs, SSGI2_cs, SSGIPost, SSRPost, SSR_BlendColor_cs, SSR_IS_Kernel, SSR_IS_cs, SSR_RayTrace_cs, ScaleControlComponents, Scene3D, Shader, ShaderAttributeInfo, ShaderConverter, ShaderConverterResult, ShaderLib, ShaderPassBase, ShaderReflection, ShaderStage, ShaderState, ShaderUniformInfo, ShaderUtil, ShadingInput, ShadowLightsCollect, ShadowMapPassRenderer, ShadowMapping_frag, Skeleton, SkeletonAnimationClip, SkeletonAnimationClipState, SkeletonAnimationComponent, SkeletonAnimationCompute, SkeletonAnimation_shader, SkeletonBlendComputeArgs, SkeletonPose, SkeletonTransformComputeArgs, SkinnedMeshRenderer, SkinnedMeshRenderer2, SkyGBufferPass, SkyGBuffer_pass, SkyMaterial, SkyRenderer, SkyShader, SolidColorSky, SphereColliderShape, SphereGeometry, SphereReflection, SpotLight, StandShader, StatementNode, StorageGPUBuffer, StringUtil, Struct, StructStorageGPUBuffer, SubGeometry, TAACopyTex_cs, TAAPost, TAASharpTex_cs, TAA_cs, TestComputeLoadBuffer, TextAnchor, TextFieldLayout, TextFieldLine, Texture, TextureCube, TextureCubeFaceData, TextureCubeStdCreator, TextureCubeUtils, TextureMipmapCompute, TextureMipmapGenerator, TextureScaleCompute, ThirdPersonCameraController, Tile, TileSet, TileSetChild, TileSetChildContent, TileSetChildContentMetaData, TileSetRoot, TilesRenderer, Time, TokenType, TorusGeometry, TouchData, TrailGeometry, Transform, TransformAxisEnum, TransformControllerBaseComponent, TransformMode, TransformSpaceMode, TranslationControlComponents, TranslatorContext, TriGeometry, Triangle, UIButton, UIButtonTransition, UIComponentBase, UIEvent, UIImage, UIImageGroup, UIInteractive, UIInteractiveStyle, UIPanel, UIRenderAble, UIShadow, UITextField, UITransform, UNLOADED, UUID, UV, Uint32ArrayTexture, Uint8ArrayTexture, UnLit, UnLitMaterial, UnLitMaterialUniform_frag, UnLitShader, UnLitTexArrayMaterial, UnLitTexArrayShader, UnLitTextureArray, UnLit_frag, UniformGPUBuffer, UniformNode, UniformType, ValueEnumType, ValueOp, ValueParser, ValueSpread, Vector2, Vector3, Vector3Ex, Vector4, VertexAttribute, VertexAttributeIndexShader, VertexAttributeName, VertexAttributeSize, VertexAttributeStride, VertexAttributes_vert, VertexBufferLayout, VertexFormat, VertexGPUBuffer, Vertical, VideoUniform_frag, View3D, ViewPanel, ViewQuad, VirtualTexture, WGS84_FLATTENING, WGS84_HEIGHT, WGS84_RADIUS, WGSLTranslator, WayLines3D, WayPoint3D, WebGPUDescriptorCreator, WorldMatrixUniform, WorldPanel, WrapMode, WrapTimeMode, ZCullingCompute, ZPassShader_cs, ZPassShader_fs, ZPassShader_vs, ZSorterUtil, append, arrayToString, blendComponent, buildCurves, byteSizeOfType, calculateCurveRangesValue, calculateMinMax, castPointShadowMap_vert, clamp, clampRepeat, computeAABBFromPositions, cos, crossProduct, cubicPolynomialRoot, cubicPolynomialRootsGeneric, curvesSupportProcedural, deg2Rad, detectGSplatFormat, directionShadowCastMap_frag, dot, doubleIntegrateSegment, downSample, fastInvSqrt, floorfToIntPos, fonts, generateRandom, generateRandom3, getFloatFromInt, getGLTypeFromTypedArray, getGLTypeFromTypedArrayType, getGlobalRandomSeed, getTypedArray, getTypedArrayTypeFromGLType, grad1, grad2, grad3, grad4, inferSHOrder, integrateSegment, irradianceDataReader, kPI, lerp, lerpByte, lerpColor, lerpVector3, lruPriorityCallback, magnitude, makeAloneSprite, makeGUISprite, makeMatrix44, markUsedSetLeaves, markUsedTiles, markVisibleTiles, matrixMultiply, matrixRotate, matrixRotateY, mergeFunctions, multiplyMatrices4x4REF, normal_distribution, normalizeFast, normalizeSafe, normalizedToByte, normalizedToWord, outlinePostData, outlinePostManager, parsePlyGaussianSplat, parsePlyHeader, perm, post, priorityCallback, quadraticPolynomialRootsGeneric, rad2Deg, random01, randomBarycentricCoord, randomPointBetweenEllipsoid, randomPointBetweenSphere, randomPointInsideCube, randomPointInsideEllipsoid, randomPointInsideUnitCircle, randomPointInsideUnitSphere, randomQuaternion, randomQuaternionUniformDistribution, randomSeed, randomUnitVector, randomUnitVector2, rangedRandomFloat, rangedRandomInt, readByType, readMagicBytes, registerMaterial, repeat, rotMatrix, rotateVectorByQuat, roundfToIntPos, scale, shadowCastMap_frag, shadowCastMap_vert, simplex, sin, snoise1, snoise2, snoise3, snoise4, sqrMagnitude, sqrtImpl, stencilStateFace, swap, textureCompress, threshold, throttle, toHalfFloat, toggleTiles, traverseAncestors, traverseSet, tw, uniform_real_distribution, uniform_real_distribution2, upSample$1 as upSample, webGPUContext, zSorterUtil };
70803
+ export { AccelerateDecelerateInterpolator, AccelerateInterpolator, AnimationCurve, AnimationCurveT, AnimationMonitor, AnimatorComponent, AnimatorEventKeyframe, AnticipateInterpolator, AnticipateOvershootInterpolator, ArrayHas, ArrayItemIndex, AtlasParser, AtmosphericComponent, AtmosphericScatteringSky, AtmosphericScatteringSkySetting, AtmosphericScatteringSky_shader, AttributeAnimCurve, AxisObject, B3DMLoader, B3DMLoaderBase, B3DMParseUtil, B3DMParser, BRDFLUT, BRDFLUTGenerate, BRDF_frag, BatchTable, BiMap, BillboardComponent, BillboardType, BitUtil, BitmapTexture2D, BitmapTexture2DArray, BitmapTextureCube, Blend, BlendFactor, BlendMode, BlendShapeData, BlendShapePropertyData, BloomPost, BlurEffectCreatorBlur_cs, BlurEffectCreatorSample_cs, BlurTexture2DBufferCreator, BounceInterpolator, BoundUtil, BoundingBox, BoundingSphere, BoundingVolume, BoxColliderShape, BoxGeometry, BrdfLut_frag, BsDF_frag, BxDF_frag, BxdfDebug_frag, BytesArray, CEvent, CEventDispatcher, CEventListener, CResizeEvent, CSM, Camera3D, CameraControllerBase, CameraType, CameraUtil, CapsuleColliderShape, CastPointShadowMaterialPass, CastShadowMaterialPass, Clearcoat_frag, ClusterBoundsSource_cs, ClusterConfig, ClusterDebug_frag, ClusterLight, ClusterLightingBuffer, ClusterLightingRender, ClusterLighting_cs, CollectInfo, ColliderComponent, ColliderShape, ColliderShapeType, Color, ColorGradient, ColorLitMaterial, ColorLitShader, ColorPassFragmentOutput, ColorPassRenderer, ColorUtil, ComData, Combine_cs, Common_frag, Common_vert, ComponentBase, ComponentCollect, ComputeGPUBuffer, ComputeShader, Context3D, CubeCamera, CubeMapFaceEnum, CubeSky_Shader, CubicBezierCurve, CubicBezierPath, CubicBezierType, CycleInterpolator, CylinderGeometry, DDGIIrradianceComputePass, DDGIIrradianceGPUBufferReader, DDGIIrradianceVolume, DDGIIrradiance_shader, DDGILightingPass, DDGILighting_shader, DDGIMultiBouncePass, DDGIProbeRenderer, DEGREES_TO_RADIANS, DRACO_DECODER_GLTF_JS, DecelerateInterpolator, Denoising_cs, Depth2DTextureArray, DepthCubeArrayTexture, DepthMaterialPass, DepthOfFieldPost, DepthOfView_cs, DirectLight, DoubleArray, EditorInspector, Engine3D, Entity, EntityBatchCollect, EntityCollect, EnvMap_frag, ErpImage2CubeMap, ErpImage2CubeMapCreateCube_cs, ErpImage2CubeMapRgbe2rgba_cs, ExtrudeGeometry, FAILED, FASTFLOOR, FXAAPost, FXAAShader, FastMathShader, FatLineGeometry, FatLineMaterial, FatLineRenderer, FatLineShader, FatLine_FS, FatLine_VS, FeatureTable, FileLoader, FirstPersonCameraController, Float16ArrayTexture, Float32ArrayTexture, FlyCameraController, FontChar, FontInfo, FontPage, FontParser, ForwardRenderJob, FragmentOutput, FragmentVarying, FrameCache, Frustum, FrustumCSM, FrustumCulling_cs, FullQuad_vert_wgsl, GBufferFrame, GBufferPass, GBufferPost, GBufferStand, GBuffer_pass, GILighting, GIProbeMaterial, GIProbeMaterialType, GIProbeShader, GIRenderCompleteEvent, GIRenderStartEvent, GLBChunk, GLBHeader, GLBParser, GLSLLexer, GLSLLexerToken, GLSLPreprocessor, GLSLSyntax, GLTFBinaryExtension, GLTFMaterial, GLTFParser, GLTFSubParser, GLTFSubParserCamera, GLTFSubParserConverter, GLTFSubParserMaterial, GLTFSubParserMesh, GLTFSubParserSkeleton, GLTFSubParserSkin, GLTFType, GLTF_Accessors, GLTF_Info, GLTF_Light, GLTF_Mesh, GLTF_Node, GLTF_Primitives, GLTF_Scene, GPUAddressMode, GPUBlendFactor, GPUBufferBase, GPUBufferType, GPUCompareFunction, GPUContext, GPUCullMode, GPUFilterMode, GPUPrimitiveTopology, GPUTextureFormat, GPUVertexFormat, GPUVertexStepMode, GSplatFormat, GSplatGeometry, GSplatMaterial, GSplatRenderer, GSplatShader, GSplat_FS, GSplat_VS, GTAOPost, GTAO_cs, GUIAtlasTexture, GUICanvas, GUIConfig, GUIGeometry, GUIGeometryRebuild, GUIMaterial, GUIPassRenderer, GUIPick, GUIPickHelper, GUIQuad, GUIQuadAttrEnum, GUIRenderer, GUIShader, GUISpace, GUISprite, GUITexture, GaussianSplatParser, GenerayRandomDir, GeoJsonParser, GeoJsonUtil, GeoType, GeometryBase, GeometryIndicesBuffer, GeometryUtil, GeometryVertexBuffer, GeometryVertexType, GetComponentClass, GetCountInstanceID, GetRepeat, GetShader, GlassShader, GlobalBindGroup, GlobalBindGroupLayout, GlobalFog, GlobalFog_shader, GlobalIlluminationComponent, GlobalUniform, GlobalUniformGroup, GodRayPost, GodRay_cs, GridObject, HDRTexture, HDRTextureCube, Hair_frag, Hair_shader_op, Hair_shader_tr, HaltonSeq, Horizontal, HoverCameraController, I3DMLoader, I3DMLoaderBase, I3DMParser, IBLEnvMapCreator, IBLEnvMapCreator_cs, IESProfiles, IESProfiles_frag, IKDTreeUserData, ImageType, IndicesGPUBuffer, Inline_vert, InputSystem, InstanceDrawComponent, InstanceUniform, InstancedMesh, Interpolator, InterpolatorEnum, IrradianceDataReaderCompleteEvent, IrradianceVolumeData_frag, Irradiance_frag, IsEditorInspector, IsNonSerialize, Joint, JointPose, JumperInterpolator, KDTreeEntity, KDTreeNode, KDTreeRange, KDTreeSpace, KDTreeUUID, KHR_draco_mesh_compression, KHR_lights_punctual, KHR_materials_clearcoat, KHR_materials_emissive_strength, KHR_materials_ior, KHR_materials_unlit, KMZParser, KV, KelvinUtil, KeyCode, KeyEvent, Keyframe, KeyframeT, LDRTextureCube, LOADED, LOADING, LRUCache, LambertMaterial, Lambert_shader, Light, LightBase, LightData, LightEntries, LightType, LightingFunction_frag, Line, LineClassification, LinearInterpolator, LitMaterial, LitSSSShader, LitShader, Lit_shader, LoaderBase, LoaderEvent, LoaderManager, MAX_VALUE, MIN_VALUE, Material, MaterialDataUniformGPUBuffer, MaterialUtilities, MathShader, MathUtil, Matrix3, Matrix4, MatrixBindGroup, MatrixGPUBuffer, MatrixShader, MemoryDO, MemoryInfo, MergeRGBACreator, MergeRGBA_cs, MeshColliderShape, MeshFilter, MeshRenderer, MinMaxAnimationCurves, MinMaxCurve, MinMaxCurveState, MinMaxPolyCurves, MorePassParser, MorePassShader, MorphTargetBlender, MorphTargetData, MorphTargetFrame, MorphTargetTransformKey, MorphTarget_shader, MouseCode, MultiBouncePass_cs, Navi3DAstar, Navi3DConst, Navi3DEdge, Navi3DFunnel, Navi3DMaskType, Navi3DMesh, Navi3DPoint, Navi3DPoint2D, Navi3DPointFat, Navi3DRouter, Navi3DTriangle, NonSerialize, NormalMap_frag, OAnimationEvent, OBJParser, Object3D, Object3DEvent, Object3DTransformTools, Object3DUtil, ObjectAnimClip, OcclusionSystem, Octree, OctreeEntity, OrbitController, OrderMap, Orientation3D, OutLineBlendColor_cs, OutlineCalcOutline_cs, OutlinePass, OutlinePost, OutlinePostData, OutlinePostManager, OutlinePostSlot, Outline_cs, OvershootInterpolator, PARSING, PBRLItShader, PBRLitSSSShader, PLUGIN_REGISTERED, ParserBase, ParserFormat, ParticleSystemCurveEvalMode, ParticleSystemRandomnessIds, PassGenerate, PassShader, PassType, PhysicMaterialUniform_frag, PickCompute, PickFire, PickGUIEvent3D, PickResult, Picker_cs, PingPong, PipelinePool, Plane3D, PlaneClassification, PlaneGeometry, PlyMode, PlyParser, PointClassification, PointCloudGeometry, PointCloudMaterial, PointCloudRenderer, PointCloudShader, PointCloud_FS, PointCloud_VS, PointLight, PointLightShadowRenderer, PointShadowCubeCamera, PointerEvent3D, Polynomial, PolynomialCurve, Polynomials, PoolNode, PostBase, PostProcessingComponent, PostRenderer, PreDepthPassRenderer, PreFilteredEnvironment_cs, PreFilteredEnvironment_cs2, PreIntegratedLut, PreIntegratedLutCompute, PrefabAvatarData, PrefabAvatarParser, PrefabBoneData, PrefabMaterialParser, PrefabMeshData, PrefabMeshParser, PrefabNode, PrefabParser, PrefabStringUtil, PrefabTextureData, PrefabTextureParser, Preprocessor, PriorityQueue, Probe, ProbeEntries, ProbeGBufferFrame, ProfilerUtil, PropertyAnimClip, PropertyAnimTag, PropertyAnimation, PropertyAnimationClip, PropertyAnimationClipState, PropertyAnimationEvent, PropertyHelp, QuadAABB, QuadGlsl_fs, QuadGlsl_vs, QuadRoot, QuadShader, QuadTree, QuadTreeCell, Quad_depth2dArray_frag_wgsl, Quad_depth2d_frag_wgsl, Quad_depthCube_frag_wgsl, Quad_frag_wgsl, Quad_vert_wgsl, Quaternion, R32UintTexture, RADIANS_TO_DEGREES, RGBEErrorCode, RGBEHeader, RGBEParser, RTDescriptor, RTFrame, RTResourceConfig, RTResourceMap, Rand, RandomSeed, Ray, RayCastMeshDetail, Reader, Rect, Reference, Reflection, ReflectionCG, ReflectionEntries, ReflectionMaterial, ReflectionRenderer, ReflectionShader, ReflectionShader_shader, RegisterComponent, RegisterShader, RenderContext, RenderLayer, RenderLayerUtil, RenderNode, RenderShaderCollect, RenderShaderCompute, RenderShaderPass, RenderTexture, RendererBase, RendererJob, RendererMap, RendererMask, RendererMaskUtil, RendererPassState, RepeatSE, Res, RotationControlComponents, SHCommon_frag, SN_ArrayConstant, SN_BinaryOperation, SN_Break, SN_CodeBlock, SN_Constant, SN_Continue, SN_Declaration, SN_Discard, SN_DoWhileLoop, SN_Expression, SN_ForLoop, SN_Function, SN_FunctionArgs, SN_FunctionCall, SN_IFBranch, SN_Identifier, SN_IndexOperation, SN_Layout, SN_ParenExpression, SN_Precision, SN_Return, SN_SelectOperation, SN_Struct, SN_TernaryOperation, SN_UnaryOperation, SN_WhileLoop, SSAO_cs, SSGI2_cs, SSGIPost, SSRPost, SSR_BlendColor_cs, SSR_IS_Kernel, SSR_IS_cs, SSR_RayTrace_cs, ScaleControlComponents, Scene3D, Shader, ShaderAttributeInfo, ShaderConverter, ShaderConverterResult, ShaderLib, ShaderPassBase, ShaderReflection, ShaderStage, ShaderState, ShaderUniformInfo, ShaderUtil, ShadingInput, ShadowLightsCollect, ShadowMapPassRenderer, ShadowMapping_frag, Skeleton, SkeletonAnimationClip, SkeletonAnimationClipState, SkeletonAnimationComponent, SkeletonAnimationCompute, SkeletonAnimation_shader, SkeletonBlendComputeArgs, SkeletonPose, SkeletonTransformComputeArgs, SkinnedMeshRenderer, SkinnedMeshRenderer2, SkyGBufferPass, SkyGBuffer_pass, SkyMaterial, SkyRenderer, SkyShader, SolidColorSky, SphereColliderShape, SphereGeometry, SphereReflection, SpotLight, StandShader, StatementNode, StorageGPUBuffer, StringUtil, Struct, StructStorageGPUBuffer, SubGeometry, TAACopyTex_cs, TAAPost, TAASharpTex_cs, TAA_cs, TestComputeLoadBuffer, TextAnchor, TextFieldLayout, TextFieldLine, Texture, TextureCube, TextureCubeFaceData, TextureCubeStdCreator, TextureCubeUtils, TextureMipmapCompute, TextureMipmapGenerator, TextureScaleCompute, ThirdPersonCameraController, Tile, TileSet, TileSetChild, TileSetChildContent, TileSetChildContentMetaData, TileSetRoot, TilesRenderer, Time, TokenType, TorusGeometry, TouchData, TrailGeometry, Transform, TransformAxisEnum, TransformControllerBaseComponent, TransformMode, TransformSpaceMode, TranslationControlComponents, TranslatorContext, TriGeometry, Triangle, UIButton, UIButtonTransition, UIComponentBase, UIEvent, UIImage, UIImageGroup, UIInteractive, UIInteractiveStyle, UIPanel, UIRenderAble, UIShadow, UITextField, UITransform, UNLOADED, UUID, UV, Uint32ArrayTexture, Uint8ArrayTexture, UnLit, UnLitMaterial, UnLitMaterialUniform_frag, UnLitShader, UnLitTexArrayMaterial, UnLitTexArrayShader, UnLitTextureArray, UnLit_frag, UniformGPUBuffer, UniformNode, UniformType, ValueEnumType, ValueOp, ValueParser, ValueSpread, Vector2, Vector3, Vector3Ex, Vector4, VertexAttribute, VertexAttributeIndexShader, VertexAttributeName, VertexAttributeSize, VertexAttributeStride, VertexAttributes_vert, VertexBufferLayout, VertexFormat, VertexGPUBuffer, Vertical, VideoUniform_frag, View3D, ViewPanel, ViewQuad, VirtualTexture, WGS84_FLATTENING, WGS84_HEIGHT, WGS84_RADIUS, WGSLTranslator, WayLines3D, WayPoint3D, WebGPUDescriptorCreator, WorldMatrixUniform, WorldPanel, WrapMode, WrapTimeMode, ZCullingCompute, ZPassShader_cs, ZPassShader_fs, ZPassShader_vs, ZSorterUtil, append, arrayToString, blendComponent, buildCurves, byteSizeOfType, calculateCurveRangesValue, calculateMinMax, castPointShadowMap_vert, clamp, clampRepeat, computeAABBFromPositions, cos, crossProduct, cubicPolynomialRoot, cubicPolynomialRootsGeneric, curvesSupportProcedural, deg2Rad, detectGSplatFormat, directionShadowCastMap_frag, dot, doubleIntegrateSegment, downSample, fastInvSqrt, floorfToIntPos, fonts, generateRandom, generateRandom3, getFloatFromInt, getGLTypeFromTypedArray, getGLTypeFromTypedArrayType, getGlobalRandomSeed, getTypedArray, getTypedArrayTypeFromGLType, grad1, grad2, grad3, grad4, inferSHOrder, integrateSegment, irradianceDataReader, kPI, lerp, lerpByte, lerpColor, lerpVector3, lruPriorityCallback, magnitude, makeAloneSprite, makeGUISprite, makeMatrix44, markUsedSetLeaves, markUsedTiles, markVisibleTiles, matrixMultiply, matrixRotate, matrixRotateY, mergeFunctions, multiplyMatrices4x4REF, normal_distribution, normalizeFast, normalizeSafe, normalizedToByte, normalizedToWord, outlinePostData, outlinePostManager, parsePlyGaussianSplat, parsePlyHeader, parsePlyMesh, parsePlyPointCloud, perm, post, priorityCallback, quadraticPolynomialRootsGeneric, rad2Deg, random01, randomBarycentricCoord, randomPointBetweenEllipsoid, randomPointBetweenSphere, randomPointInsideCube, randomPointInsideEllipsoid, randomPointInsideUnitCircle, randomPointInsideUnitSphere, randomQuaternion, randomQuaternionUniformDistribution, randomSeed, randomUnitVector, randomUnitVector2, rangedRandomFloat, rangedRandomInt, readByType, readMagicBytes, registerMaterial, repeat, rotMatrix, rotateVectorByQuat, roundfToIntPos, scale, shadowCastMap_frag, shadowCastMap_vert, simplex, sin, snoise1, snoise2, snoise3, snoise4, splatColorProperties, splatProperties, sqrMagnitude, sqrtImpl, stencilStateFace, swap, textureCompress, threshold, throttle, toHalfFloat, toggleTiles, traverseAncestors, traverseSet, tw, uniform_real_distribution, uniform_real_distribution2, upSample$1 as upSample, webGPUContext, zSorterUtil };