minerender 2.1.0-alpha.66 → 2.1.0-alpha.68

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.
@@ -3942,6 +3942,7 @@ var init_SceneObject = __esm({
3942
3942
  dispose() {
3943
3943
  this.disposeAndRemoveAllChildren();
3944
3944
  this.notifyDirty();
3945
+ super.dispose();
3945
3946
  }
3946
3947
  disposeAndRemoveAllChildren() {
3947
3948
  if (this.instanceMesh) {
@@ -4159,6 +4160,7 @@ var init_EntityObject = __esm({
4159
4160
  else matrix.makeRotationFromEuler(new import_three14.Euler(...op.rotate, "ZYX"));
4160
4161
  modelRoot.matrix.multiply(matrix);
4161
4162
  }
4163
+ modelRoot.matrixWorldNeedsUpdate = true;
4162
4164
  modelRoot.matrixAutoUpdate = false;
4163
4165
  } else if (this.options.flip ?? true) {
4164
4166
  modelRoot.scale.set(-1, -1, 1);
@@ -5065,6 +5067,7 @@ var init_ModelObject = __esm({
5065
5067
  for (const part of parts) {
5066
5068
  const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5067
5069
  object.matrix.copy(transform).multiply(part.transform);
5070
+ object.matrixWorldNeedsUpdate = true;
5068
5071
  object.matrixAutoUpdate = false;
5069
5072
  this.add(object);
5070
5073
  await object.init();
@@ -5600,6 +5603,7 @@ __export(index_browser_exports, {
5600
5603
  computeTangents: () => computeTangents,
5601
5604
  createCanvas: () => createCanvas,
5602
5605
  createFluidGeometry: () => createFluidGeometry,
5606
+ createGuiTextureGeometry: () => createGuiTextureGeometry,
5603
5607
  createImage: () => createImage,
5604
5608
  entityAnimationTime: () => entityAnimationTime,
5605
5609
  estimateBytesUsed: () => estimateBytesUsed,
@@ -5954,11 +5958,19 @@ init_EntityObject();
5954
5958
  init_MineRenderError();
5955
5959
 
5956
5960
  // src/export/SceneExporter.ts
5957
- var import_three20 = require("three");
5961
+ var import_three19 = require("three");
5958
5962
 
5959
5963
  // ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
5960
5964
  var import_three16 = require("three");
5961
5965
  var OBJExporter = class {
5966
+ /**
5967
+ * Parses the given 3D object and generates the OBJ output.
5968
+ *
5969
+ * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
5970
+ *
5971
+ * @param {Object3D} object - The 3D object to export.
5972
+ * @return {string} The exported OBJ.
5973
+ */
5962
5974
  parse(object) {
5963
5975
  let output = "";
5964
5976
  let indexVertex = 0;
@@ -6064,7 +6076,8 @@ var OBJExporter = class {
6064
6076
  vertex.applyMatrix4(points.matrixWorld);
6065
6077
  output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
6066
6078
  if (colors !== void 0) {
6067
- color.fromBufferAttribute(colors, i).convertLinearToSRGB();
6079
+ color.fromBufferAttribute(colors, i);
6080
+ import_three16.ColorManagement.workingToColorSpace(color, import_three16.SRGBColorSpace);
6068
6081
  output += " " + color.r + " " + color.g + " " + color.b;
6069
6082
  }
6070
6083
  output += "\n";
@@ -6095,6 +6108,16 @@ var OBJExporter = class {
6095
6108
  // ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
6096
6109
  var import_three17 = require("three");
6097
6110
  var PLYExporter = class {
6111
+ /**
6112
+ * Parses the given 3D object and generates the PLY output.
6113
+ *
6114
+ * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
6115
+ *
6116
+ * @param {Object3D} object - The 3D object to export.
6117
+ * @param {PLYExporter~OnDone} onDone - A callback function that is executed when the export has finished.
6118
+ * @param {PLYExporter~Options} options - The export options.
6119
+ * @return {?(string|ArrayBuffer)} The exported PLY.
6120
+ */
6098
6121
  parse(object, onDone, options = {}) {
6099
6122
  function traverseMeshes(cb) {
6100
6123
  object.traverse(function(child) {
@@ -6111,14 +6134,23 @@ var PLYExporter = class {
6111
6134
  binary: false,
6112
6135
  excludeAttributes: [],
6113
6136
  // normal, uv, color, index
6114
- littleEndian: false
6137
+ littleEndian: false,
6138
+ customPropertyMapping: {}
6115
6139
  };
6116
6140
  options = Object.assign(defaultOptions, options);
6117
6141
  const excludeAttributes = options.excludeAttributes;
6142
+ const customPropertyMapping = options.customPropertyMapping;
6143
+ const customAttributeNames = Object.keys(customPropertyMapping);
6118
6144
  let includeIndices = true;
6119
6145
  let includeNormals = false;
6120
6146
  let includeColors = false;
6121
6147
  let includeUVs = false;
6148
+ let positionType = "float";
6149
+ let normalType = "float";
6150
+ let uvType = "float";
6151
+ let colorType = "uchar";
6152
+ const customTypes = {};
6153
+ for (const name of customAttributeNames) customTypes[name] = "float";
6122
6154
  let vertexCount = 0;
6123
6155
  let faceCount = 0;
6124
6156
  object.traverse(function(child) {
@@ -6135,9 +6167,23 @@ var PLYExporter = class {
6135
6167
  }
6136
6168
  vertexCount += vertices.count;
6137
6169
  faceCount += indices ? indices.count / 3 : vertices.count / 3;
6138
- if (normals !== void 0) includeNormals = true;
6139
- if (uvs !== void 0) includeUVs = true;
6140
- if (colors !== void 0) includeColors = true;
6170
+ positionType = getPlyType(vertices.array);
6171
+ if (normals !== void 0) {
6172
+ includeNormals = true;
6173
+ normalType = getPlyType(normals.array);
6174
+ }
6175
+ if (uvs !== void 0) {
6176
+ includeUVs = true;
6177
+ uvType = getPlyType(uvs.array);
6178
+ }
6179
+ if (colors !== void 0) {
6180
+ includeColors = true;
6181
+ colorType = getPlyType(colors.array);
6182
+ }
6183
+ for (const name of customAttributeNames) {
6184
+ const attr = geometry.getAttribute(name);
6185
+ if (attr !== void 0) customTypes[name] = getPlyType(attr.array);
6186
+ }
6141
6187
  } else if (child.isPoints) {
6142
6188
  const mesh = child;
6143
6189
  const geometry = mesh.geometry;
@@ -6145,8 +6191,19 @@ var PLYExporter = class {
6145
6191
  const normals = geometry.getAttribute("normal");
6146
6192
  const colors = geometry.getAttribute("color");
6147
6193
  vertexCount += vertices.count;
6148
- if (normals !== void 0) includeNormals = true;
6149
- if (colors !== void 0) includeColors = true;
6194
+ positionType = getPlyType(vertices.array);
6195
+ if (normals !== void 0) {
6196
+ includeNormals = true;
6197
+ normalType = getPlyType(normals.array);
6198
+ }
6199
+ if (colors !== void 0) {
6200
+ includeColors = true;
6201
+ colorType = getPlyType(colors.array);
6202
+ }
6203
+ for (const name of customAttributeNames) {
6204
+ const attr = geometry.getAttribute(name);
6205
+ if (attr !== void 0) customTypes[name] = getPlyType(attr.array);
6206
+ }
6150
6207
  includeIndices = false;
6151
6208
  }
6152
6209
  });
@@ -6165,18 +6222,33 @@ var PLYExporter = class {
6165
6222
  let header = `ply
6166
6223
  format ${options.binary ? options.littleEndian ? "binary_little_endian" : "binary_big_endian" : "ascii"} 1.0
6167
6224
  element vertex ${vertexCount}
6168
- property float x
6169
- property float y
6170
- property float z
6225
+ property ${positionType} x
6226
+ property ${positionType} y
6227
+ property ${positionType} z
6171
6228
  `;
6172
6229
  if (includeNormals === true) {
6173
- header += "property float nx\nproperty float ny\nproperty float nz\n";
6230
+ header += `property ${normalType} nx
6231
+ property ${normalType} ny
6232
+ property ${normalType} nz
6233
+ `;
6174
6234
  }
6175
6235
  if (includeUVs === true) {
6176
- header += "property float s\nproperty float t\n";
6236
+ header += `property ${uvType} s
6237
+ property ${uvType} t
6238
+ `;
6177
6239
  }
6178
6240
  if (includeColors === true) {
6179
- header += "property uchar red\nproperty uchar green\nproperty uchar blue\n";
6241
+ header += `property ${colorType} red
6242
+ property ${colorType} green
6243
+ property ${colorType} blue
6244
+ `;
6245
+ }
6246
+ for (const name of customAttributeNames) {
6247
+ const type = customTypes[name];
6248
+ for (const propName of customPropertyMapping[name]) {
6249
+ header += `property ${type} ${propName}
6250
+ `;
6251
+ }
6180
6252
  }
6181
6253
  if (includeIndices === true) {
6182
6254
  header += `element face ${faceCount}
@@ -6189,7 +6261,23 @@ property list uchar int vertex_index
6189
6261
  let result = null;
6190
6262
  if (options.binary === true) {
6191
6263
  const headerBin = new TextEncoder().encode(header);
6192
- const vertexListLength = vertexCount * (4 * 3 + (includeNormals ? 4 * 3 : 0) + (includeColors ? 3 : 0) + (includeUVs ? 4 * 2 : 0));
6264
+ const posWriter = getBinaryWriter(positionType);
6265
+ const normalWriter = includeNormals ? getBinaryWriter(normalType) : null;
6266
+ const uvWriter = includeUVs ? getBinaryWriter(uvType) : null;
6267
+ const colorWriter = includeColors ? getBinaryWriter(colorType) : null;
6268
+ const colorIsFloat = isFloatType(colorType);
6269
+ const colorScale = getColorScale(colorType);
6270
+ const customWriters = {};
6271
+ const customIsFloat = {};
6272
+ let customStride = 0;
6273
+ for (const name of customAttributeNames) {
6274
+ const type = customTypes[name];
6275
+ const writer = getBinaryWriter(type);
6276
+ customWriters[name] = writer;
6277
+ customIsFloat[name] = isFloatType(type);
6278
+ customStride += customPropertyMapping[name].length * writer.size;
6279
+ }
6280
+ const vertexListLength = vertexCount * (3 * posWriter.size + (includeNormals ? 3 * normalWriter.size : 0) + (includeUVs ? 2 * uvWriter.size : 0) + (includeColors ? 3 * colorWriter.size : 0) + customStride);
6193
6281
  const faceListLength = includeIndices ? faceCount * (indexByteCount * 3 + 1) : 0;
6194
6282
  const output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
6195
6283
  new Uint8Array(output.buffer).set(headerBin, 0);
@@ -6206,60 +6294,76 @@ property list uchar int vertex_index
6206
6294
  for (let i = 0, l = vertices.count; i < l; i++) {
6207
6295
  vertex.fromBufferAttribute(vertices, i);
6208
6296
  vertex.applyMatrix4(mesh.matrixWorld);
6209
- output.setFloat32(vOffset, vertex.x, options.littleEndian);
6210
- vOffset += 4;
6211
- output.setFloat32(vOffset, vertex.y, options.littleEndian);
6212
- vOffset += 4;
6213
- output.setFloat32(vOffset, vertex.z, options.littleEndian);
6214
- vOffset += 4;
6297
+ posWriter.write(output, vOffset, vertex.x, options.littleEndian);
6298
+ vOffset += posWriter.size;
6299
+ posWriter.write(output, vOffset, vertex.y, options.littleEndian);
6300
+ vOffset += posWriter.size;
6301
+ posWriter.write(output, vOffset, vertex.z, options.littleEndian);
6302
+ vOffset += posWriter.size;
6215
6303
  if (includeNormals === true) {
6216
6304
  if (normals != null) {
6217
6305
  vertex.fromBufferAttribute(normals, i);
6218
6306
  vertex.applyMatrix3(normalMatrixWorld).normalize();
6219
- output.setFloat32(vOffset, vertex.x, options.littleEndian);
6220
- vOffset += 4;
6221
- output.setFloat32(vOffset, vertex.y, options.littleEndian);
6222
- vOffset += 4;
6223
- output.setFloat32(vOffset, vertex.z, options.littleEndian);
6224
- vOffset += 4;
6307
+ normalWriter.write(output, vOffset, vertex.x, options.littleEndian);
6308
+ vOffset += normalWriter.size;
6309
+ normalWriter.write(output, vOffset, vertex.y, options.littleEndian);
6310
+ vOffset += normalWriter.size;
6311
+ normalWriter.write(output, vOffset, vertex.z, options.littleEndian);
6312
+ vOffset += normalWriter.size;
6225
6313
  } else {
6226
- output.setFloat32(vOffset, 0, options.littleEndian);
6227
- vOffset += 4;
6228
- output.setFloat32(vOffset, 0, options.littleEndian);
6229
- vOffset += 4;
6230
- output.setFloat32(vOffset, 0, options.littleEndian);
6231
- vOffset += 4;
6314
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6315
+ vOffset += normalWriter.size;
6316
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6317
+ vOffset += normalWriter.size;
6318
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6319
+ vOffset += normalWriter.size;
6232
6320
  }
6233
6321
  }
6234
6322
  if (includeUVs === true) {
6235
6323
  if (uvs != null) {
6236
- output.setFloat32(vOffset, uvs.getX(i), options.littleEndian);
6237
- vOffset += 4;
6238
- output.setFloat32(vOffset, uvs.getY(i), options.littleEndian);
6239
- vOffset += 4;
6324
+ uvWriter.write(output, vOffset, uvs.getX(i), options.littleEndian);
6325
+ vOffset += uvWriter.size;
6326
+ uvWriter.write(output, vOffset, uvs.getY(i), options.littleEndian);
6327
+ vOffset += uvWriter.size;
6240
6328
  } else {
6241
- output.setFloat32(vOffset, 0, options.littleEndian);
6242
- vOffset += 4;
6243
- output.setFloat32(vOffset, 0, options.littleEndian);
6244
- vOffset += 4;
6329
+ uvWriter.write(output, vOffset, 0, options.littleEndian);
6330
+ vOffset += uvWriter.size;
6331
+ uvWriter.write(output, vOffset, 0, options.littleEndian);
6332
+ vOffset += uvWriter.size;
6245
6333
  }
6246
6334
  }
6247
6335
  if (includeColors === true) {
6248
6336
  if (colors != null) {
6249
- tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
6250
- output.setUint8(vOffset, Math.floor(tempColor.r * 255));
6251
- vOffset += 1;
6252
- output.setUint8(vOffset, Math.floor(tempColor.g * 255));
6253
- vOffset += 1;
6254
- output.setUint8(vOffset, Math.floor(tempColor.b * 255));
6255
- vOffset += 1;
6337
+ tempColor.fromBufferAttribute(colors, i);
6338
+ import_three17.ColorManagement.workingToColorSpace(tempColor, import_three17.SRGBColorSpace);
6339
+ const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
6340
+ const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
6341
+ const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
6342
+ colorWriter.write(output, vOffset, r, options.littleEndian);
6343
+ vOffset += colorWriter.size;
6344
+ colorWriter.write(output, vOffset, g, options.littleEndian);
6345
+ vOffset += colorWriter.size;
6346
+ colorWriter.write(output, vOffset, b, options.littleEndian);
6347
+ vOffset += colorWriter.size;
6256
6348
  } else {
6257
- output.setUint8(vOffset, 255);
6258
- vOffset += 1;
6259
- output.setUint8(vOffset, 255);
6260
- vOffset += 1;
6261
- output.setUint8(vOffset, 255);
6262
- vOffset += 1;
6349
+ const white = colorIsFloat ? 1 : colorScale;
6350
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6351
+ vOffset += colorWriter.size;
6352
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6353
+ vOffset += colorWriter.size;
6354
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6355
+ vOffset += colorWriter.size;
6356
+ }
6357
+ }
6358
+ for (const name of customAttributeNames) {
6359
+ const writer = customWriters[name];
6360
+ const propCount = customPropertyMapping[name].length;
6361
+ const attr = geometry.getAttribute(name);
6362
+ const isFloat = customIsFloat[name];
6363
+ for (let c = 0; c < propCount; c++) {
6364
+ const raw = attr != null ? getAttributeComponent(attr, i, c) : 0;
6365
+ writer.write(output, vOffset, isFloat ? raw : Math.round(raw), options.littleEndian);
6366
+ vOffset += writer.size;
6263
6367
  }
6264
6368
  }
6265
6369
  }
@@ -6295,6 +6399,14 @@ property list uchar int vertex_index
6295
6399
  let writtenVertices = 0;
6296
6400
  let vertexList = "";
6297
6401
  let faceList = "";
6402
+ const positionIsFloat = isFloatType(positionType);
6403
+ const normalIsFloat = isFloatType(normalType);
6404
+ const uvIsFloat = isFloatType(uvType);
6405
+ const colorIsFloat = isFloatType(colorType);
6406
+ const colorScale = getColorScale(colorType);
6407
+ const customIsFloat = {};
6408
+ for (const name of customAttributeNames) customIsFloat[name] = isFloatType(customTypes[name]);
6409
+ const encode = (v, isFloat) => isFloat ? v : Math.round(v);
6298
6410
  traverseMeshes(function(mesh, geometry) {
6299
6411
  const vertices = geometry.getAttribute("position");
6300
6412
  const normals = geometry.getAttribute("normal");
@@ -6305,29 +6417,43 @@ property list uchar int vertex_index
6305
6417
  for (let i = 0, l = vertices.count; i < l; i++) {
6306
6418
  vertex.fromBufferAttribute(vertices, i);
6307
6419
  vertex.applyMatrix4(mesh.matrixWorld);
6308
- let line = vertex.x + " " + vertex.y + " " + vertex.z;
6420
+ let line = encode(vertex.x, positionIsFloat) + " " + encode(vertex.y, positionIsFloat) + " " + encode(vertex.z, positionIsFloat);
6309
6421
  if (includeNormals === true) {
6310
6422
  if (normals != null) {
6311
6423
  vertex.fromBufferAttribute(normals, i);
6312
6424
  vertex.applyMatrix3(normalMatrixWorld).normalize();
6313
- line += " " + vertex.x + " " + vertex.y + " " + vertex.z;
6425
+ line += " " + encode(vertex.x, normalIsFloat) + " " + encode(vertex.y, normalIsFloat) + " " + encode(vertex.z, normalIsFloat);
6314
6426
  } else {
6315
6427
  line += " 0 0 0";
6316
6428
  }
6317
6429
  }
6318
6430
  if (includeUVs === true) {
6319
6431
  if (uvs != null) {
6320
- line += " " + uvs.getX(i) + " " + uvs.getY(i);
6432
+ line += " " + encode(uvs.getX(i), uvIsFloat) + " " + encode(uvs.getY(i), uvIsFloat);
6321
6433
  } else {
6322
6434
  line += " 0 0";
6323
6435
  }
6324
6436
  }
6325
6437
  if (includeColors === true) {
6326
6438
  if (colors != null) {
6327
- tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
6328
- line += " " + Math.floor(tempColor.r * 255) + " " + Math.floor(tempColor.g * 255) + " " + Math.floor(tempColor.b * 255);
6439
+ tempColor.fromBufferAttribute(colors, i);
6440
+ import_three17.ColorManagement.workingToColorSpace(tempColor, import_three17.SRGBColorSpace);
6441
+ const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
6442
+ const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
6443
+ const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
6444
+ line += ` ${r} ${g} ${b}`;
6329
6445
  } else {
6330
- line += " 255 255 255";
6446
+ const white = colorIsFloat ? 1 : colorScale;
6447
+ line += ` ${white} ${white} ${white}`;
6448
+ }
6449
+ }
6450
+ for (const name of customAttributeNames) {
6451
+ const propCount = customPropertyMapping[name].length;
6452
+ const attr = geometry.getAttribute(name);
6453
+ const isFloat = customIsFloat[name];
6454
+ for (let c = 0; c < propCount; c++) {
6455
+ const raw = attr != null ? getAttributeComponent(attr, i, c) : 0;
6456
+ line += " " + encode(raw, isFloat);
6331
6457
  }
6332
6458
  }
6333
6459
  vertexList += line + "\n";
@@ -6357,70 +6483,65 @@ property list uchar int vertex_index
6357
6483
  return result;
6358
6484
  }
6359
6485
  };
6360
-
6361
- // ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
6362
- var import_three19 = require("three");
6363
-
6364
- // ../../node_modules/three/examples/jsm/utils/TextureUtils.js
6365
- var import_three18 = require("three");
6366
- var _renderer;
6367
- var fullscreenQuadGeometry;
6368
- var fullscreenQuadMaterial;
6369
- var fullscreenQuad;
6370
- function decompress(texture, maxTextureSize = Infinity, renderer = null) {
6371
- if (!fullscreenQuadGeometry) fullscreenQuadGeometry = new import_three18.PlaneGeometry(2, 2, 1, 1);
6372
- if (!fullscreenQuadMaterial) fullscreenQuadMaterial = new import_three18.ShaderMaterial({
6373
- uniforms: { blitTexture: new import_three18.Uniform(texture) },
6374
- vertexShader: `
6375
- varying vec2 vUv;
6376
- void main(){
6377
- vUv = uv;
6378
- gl_Position = vec4(position.xy * 1.0,0.,.999999);
6379
- }`,
6380
- fragmentShader: `
6381
- uniform sampler2D blitTexture;
6382
- varying vec2 vUv;
6383
-
6384
- void main(){
6385
- gl_FragColor = vec4(vUv.xy, 0, 1);
6386
-
6387
- #ifdef IS_SRGB
6388
- gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
6389
- #else
6390
- gl_FragColor = texture2D( blitTexture, vUv);
6391
- #endif
6392
- }`
6393
- });
6394
- fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
6395
- fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == import_three18.SRGBColorSpace;
6396
- fullscreenQuadMaterial.needsUpdate = true;
6397
- if (!fullscreenQuad) {
6398
- fullscreenQuad = new import_three18.Mesh(fullscreenQuadGeometry, fullscreenQuadMaterial);
6399
- fullscreenQuad.frustrumCulled = false;
6400
- }
6401
- const _camera = new import_three18.PerspectiveCamera();
6402
- const _scene = new import_three18.Scene();
6403
- _scene.add(fullscreenQuad);
6404
- if (!renderer) {
6405
- renderer = _renderer = new import_three18.WebGLRenderer({ antialias: false });
6406
- }
6407
- renderer.setSize(Math.min(texture.image.width, maxTextureSize), Math.min(texture.image.height, maxTextureSize));
6408
- renderer.clear();
6409
- renderer.render(_scene, _camera);
6410
- const readableTexture = new import_three18.Texture(renderer.domElement);
6411
- readableTexture.minFilter = texture.minFilter;
6412
- readableTexture.magFilter = texture.magFilter;
6413
- readableTexture.wrapS = texture.wrapS;
6414
- readableTexture.wrapT = texture.wrapT;
6415
- readableTexture.name = texture.name;
6416
- if (_renderer) {
6417
- _renderer.dispose();
6418
- _renderer = null;
6419
- }
6420
- return readableTexture;
6486
+ function getPlyType(array) {
6487
+ if (array instanceof Int8Array) return "char";
6488
+ if (array instanceof Uint8Array || array instanceof Uint8ClampedArray) return "uchar";
6489
+ if (array instanceof Int16Array) return "short";
6490
+ if (array instanceof Uint16Array) return "ushort";
6491
+ if (array instanceof Int32Array) return "int";
6492
+ if (array instanceof Uint32Array) return "uint";
6493
+ if (array instanceof Float32Array) return "float";
6494
+ if (array instanceof Float64Array) return "double";
6495
+ return "float";
6496
+ }
6497
+ function getBinaryWriter(type) {
6498
+ switch (type) {
6499
+ case "char":
6500
+ return { write: (dv, at, v) => dv.setInt8(at, v), size: 1 };
6501
+ case "uchar":
6502
+ return { write: (dv, at, v) => dv.setUint8(at, v), size: 1 };
6503
+ case "short":
6504
+ return { write: (dv, at, v, le) => dv.setInt16(at, v, le), size: 2 };
6505
+ case "ushort":
6506
+ return { write: (dv, at, v, le) => dv.setUint16(at, v, le), size: 2 };
6507
+ case "int":
6508
+ return { write: (dv, at, v, le) => dv.setInt32(at, v, le), size: 4 };
6509
+ case "uint":
6510
+ return { write: (dv, at, v, le) => dv.setUint32(at, v, le), size: 4 };
6511
+ case "float":
6512
+ return { write: (dv, at, v, le) => dv.setFloat32(at, v, le), size: 4 };
6513
+ case "double":
6514
+ return { write: (dv, at, v, le) => dv.setFloat64(at, v, le), size: 8 };
6515
+ }
6516
+ }
6517
+ function isFloatType(type) {
6518
+ return type === "float" || type === "double";
6519
+ }
6520
+ function getAttributeComponent(attr, i, c) {
6521
+ switch (c) {
6522
+ case 0:
6523
+ return attr.getX(i);
6524
+ case 1:
6525
+ return attr.getY(i);
6526
+ case 2:
6527
+ return attr.getZ(i);
6528
+ case 3:
6529
+ return attr.getW(i);
6530
+ }
6531
+ }
6532
+ function getColorScale(type) {
6533
+ switch (type) {
6534
+ case "uchar":
6535
+ return 255;
6536
+ case "ushort":
6537
+ return 65535;
6538
+ default:
6539
+ return 1;
6540
+ }
6421
6541
  }
6422
6542
 
6423
6543
  // ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
6544
+ var import_three18 = require("three");
6424
6545
  var KHR_mesh_quantization_ExtraAttrTypes = {
6425
6546
  POSITION: [
6426
6547
  "byte",
@@ -6450,7 +6571,11 @@ var KHR_mesh_quantization_ExtraAttrTypes = {
6450
6571
  ]
6451
6572
  };
6452
6573
  var GLTFExporter = class {
6574
+ /**
6575
+ * Constructs a new glTF exporter.
6576
+ */
6453
6577
  constructor() {
6578
+ this.textureUtils = null;
6454
6579
  this.pluginCallbacks = [];
6455
6580
  this.register(function(writer) {
6456
6581
  return new GLTFLightExtension(writer);
@@ -6473,6 +6598,9 @@ var GLTFExporter = class {
6473
6598
  this.register(function(writer) {
6474
6599
  return new GLTFMaterialsClearcoatExtension(writer);
6475
6600
  });
6601
+ this.register(function(writer) {
6602
+ return new GLTFMaterialsDispersionExtension(writer);
6603
+ });
6476
6604
  this.register(function(writer) {
6477
6605
  return new GLTFMaterialsIridescenceExtension(writer);
6478
6606
  });
@@ -6485,16 +6613,33 @@ var GLTFExporter = class {
6485
6613
  this.register(function(writer) {
6486
6614
  return new GLTFMaterialsEmissiveStrengthExtension(writer);
6487
6615
  });
6616
+ this.register(function(writer) {
6617
+ return new GLTFMaterialsBumpExtension(writer);
6618
+ });
6488
6619
  this.register(function(writer) {
6489
6620
  return new GLTFMeshGpuInstancing(writer);
6490
6621
  });
6491
6622
  }
6623
+ /**
6624
+ * Registers a plugin callback. This API is internally used to implement the various
6625
+ * glTF extensions but can also used by third-party code to add additional logic
6626
+ * to the exporter.
6627
+ *
6628
+ * @param {function(writer:GLTFWriter)} callback - The callback function to register.
6629
+ * @return {GLTFExporter} A reference to this exporter.
6630
+ */
6492
6631
  register(callback) {
6493
6632
  if (this.pluginCallbacks.indexOf(callback) === -1) {
6494
6633
  this.pluginCallbacks.push(callback);
6495
6634
  }
6496
6635
  return this;
6497
6636
  }
6637
+ /**
6638
+ * Unregisters a plugin callback.
6639
+ *
6640
+ * @param {Function} callback - The callback function to unregister.
6641
+ * @return {GLTFExporter} A reference to this exporter.
6642
+ */
6498
6643
  unregister(callback) {
6499
6644
  if (this.pluginCallbacks.indexOf(callback) !== -1) {
6500
6645
  this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
@@ -6502,11 +6647,25 @@ var GLTFExporter = class {
6502
6647
  return this;
6503
6648
  }
6504
6649
  /**
6505
- * Parse scenes and generate GLTF output
6506
- * @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
6507
- * @param {Function} onDone Callback on completed
6508
- * @param {Function} onError Callback on errors
6509
- * @param {Object} options options
6650
+ * Sets the texture utils for this exporter. Only relevant when compressed textures have to be exported.
6651
+ *
6652
+ * Depending on whether you use {@link WebGLRenderer} or {@link WebGPURenderer}, you must inject the
6653
+ * corresponding texture utils {@link module:WebGLTextureUtils} or {@link module:WebGPUTextureUtils}.
6654
+ *
6655
+ * @param {WebGLTextureUtils|WebGPUTextureUtils} utils - The texture utils.
6656
+ * @return {GLTFExporter} A reference to this exporter.
6657
+ */
6658
+ setTextureUtils(utils) {
6659
+ this.textureUtils = utils;
6660
+ return this;
6661
+ }
6662
+ /**
6663
+ * Parses the given scenes and generates the glTF output.
6664
+ *
6665
+ * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
6666
+ * @param {GLTFExporter~OnDone} onDone - A callback function that is executed when the export has finished.
6667
+ * @param {GLTFExporter~OnError} onError - A callback function that is executed when an error happens.
6668
+ * @param {GLTFExporter~Options} options - options
6510
6669
  */
6511
6670
  parse(input, onDone, onError, options) {
6512
6671
  const writer = new GLTFWriter();
@@ -6515,8 +6674,16 @@ var GLTFExporter = class {
6515
6674
  plugins.push(this.pluginCallbacks[i](writer));
6516
6675
  }
6517
6676
  writer.setPlugins(plugins);
6518
- writer.write(input, onDone, options).catch(onError);
6677
+ writer.setTextureUtils(this.textureUtils);
6678
+ writer.writeAsync(input, onDone, options).catch(onError);
6519
6679
  }
6680
+ /**
6681
+ * Async version of {@link GLTFExporter#parse}.
6682
+ *
6683
+ * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
6684
+ * @param {GLTFExporter~Options} options - options.
6685
+ * @return {Promise<ArrayBuffer|string>} A Promise that resolved with the exported glTF data.
6686
+ */
6520
6687
  parseAsync(input, options) {
6521
6688
  const scope = this;
6522
6689
  return new Promise(function(resolve, reject) {
@@ -6553,22 +6720,22 @@ var WEBGL_CONSTANTS = {
6553
6720
  };
6554
6721
  var KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
6555
6722
  var THREE_TO_WEBGL = {};
6556
- THREE_TO_WEBGL[import_three19.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
6557
- THREE_TO_WEBGL[import_three19.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
6558
- THREE_TO_WEBGL[import_three19.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
6559
- THREE_TO_WEBGL[import_three19.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
6560
- THREE_TO_WEBGL[import_three19.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
6561
- THREE_TO_WEBGL[import_three19.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
6562
- THREE_TO_WEBGL[import_three19.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
6563
- THREE_TO_WEBGL[import_three19.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
6564
- THREE_TO_WEBGL[import_three19.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
6723
+ THREE_TO_WEBGL[import_three18.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
6724
+ THREE_TO_WEBGL[import_three18.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
6725
+ THREE_TO_WEBGL[import_three18.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
6726
+ THREE_TO_WEBGL[import_three18.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
6727
+ THREE_TO_WEBGL[import_three18.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
6728
+ THREE_TO_WEBGL[import_three18.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
6729
+ THREE_TO_WEBGL[import_three18.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
6730
+ THREE_TO_WEBGL[import_three18.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
6731
+ THREE_TO_WEBGL[import_three18.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
6565
6732
  var PATH_PROPERTIES = {
6566
6733
  scale: "scale",
6567
6734
  position: "translation",
6568
6735
  quaternion: "rotation",
6569
6736
  morphTargetInfluences: "weights"
6570
6737
  };
6571
- var DEFAULT_SPECULAR_COLOR = new import_three19.Color();
6738
+ var DEFAULT_SPECULAR_COLOR = new import_three18.Color();
6572
6739
  var GLB_HEADER_BYTES = 12;
6573
6740
  var GLB_HEADER_MAGIC = 1179937895;
6574
6741
  var GLB_VERSION = 2;
@@ -6602,7 +6769,7 @@ function getMinMax(attribute, start, count) {
6602
6769
  else if (a === 2) value = attribute.getZ(i);
6603
6770
  else if (a === 3) value = attribute.getW(i);
6604
6771
  if (attribute.normalized === true) {
6605
- value = import_three19.MathUtils.normalize(value, attribute.array);
6772
+ value = import_three18.MathUtils.normalize(value, attribute.array);
6606
6773
  }
6607
6774
  }
6608
6775
  output.min[a] = Math.min(output.min[a], value);
@@ -6635,19 +6802,20 @@ function getCanvas() {
6635
6802
  return document.createElement("canvas");
6636
6803
  }
6637
6804
  function getToBlobPromise(canvas, mimeType) {
6638
- if (canvas.toBlob !== void 0) {
6805
+ if (typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas) {
6806
+ let quality;
6807
+ if (mimeType === "image/jpeg") {
6808
+ quality = 0.92;
6809
+ } else if (mimeType === "image/webp") {
6810
+ quality = 0.8;
6811
+ }
6812
+ return canvas.convertToBlob({
6813
+ type: mimeType,
6814
+ quality
6815
+ });
6816
+ } else {
6639
6817
  return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
6640
6818
  }
6641
- let quality;
6642
- if (mimeType === "image/jpeg") {
6643
- quality = 0.92;
6644
- } else if (mimeType === "image/webp") {
6645
- quality = 0.8;
6646
- }
6647
- return canvas.convertToBlob({
6648
- type: mimeType,
6649
- quality
6650
- });
6651
6819
  }
6652
6820
  var GLTFWriter = class {
6653
6821
  constructor() {
@@ -6666,7 +6834,7 @@ var GLTFWriter = class {
6666
6834
  this.json = {
6667
6835
  asset: {
6668
6836
  version: "2.0",
6669
- generator: "THREE.GLTFExporter"
6837
+ generator: "THREE.GLTFExporter r" + import_three18.REVISION
6670
6838
  }
6671
6839
  };
6672
6840
  this.cache = {
@@ -6675,19 +6843,25 @@ var GLTFWriter = class {
6675
6843
  attributesNormalized: /* @__PURE__ */ new Map(),
6676
6844
  materials: /* @__PURE__ */ new Map(),
6677
6845
  textures: /* @__PURE__ */ new Map(),
6678
- images: /* @__PURE__ */ new Map()
6846
+ images: /* @__PURE__ */ new Map(),
6847
+ normalMaps: /* @__PURE__ */ new Map()
6679
6848
  };
6849
+ this.textureUtils = null;
6680
6850
  }
6681
6851
  setPlugins(plugins) {
6682
6852
  this.plugins = plugins;
6683
6853
  }
6854
+ setTextureUtils(utils) {
6855
+ this.textureUtils = utils;
6856
+ }
6684
6857
  /**
6685
6858
  * Parse scenes and generate GLTF output
6686
- * @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
6687
- * @param {Function} onDone Callback on completed
6688
- * @param {Object} options options
6859
+ *
6860
+ * @param {Scene|Array<Scene>} input Scene or Array of THREE.Scenes
6861
+ * @param {Function} onDone Callback on completed
6862
+ * @param {Object} options options
6689
6863
  */
6690
- async write(input, onDone, options = {}) {
6864
+ async writeAsync(input, onDone, options = {}) {
6691
6865
  this.options = Object.assign({
6692
6866
  // default options
6693
6867
  binary: false,
@@ -6695,12 +6869,13 @@ var GLTFWriter = class {
6695
6869
  onlyVisible: true,
6696
6870
  maxTextureSize: Infinity,
6697
6871
  animations: [],
6698
- includeCustomExtensions: false
6872
+ includeCustomExtensions: false,
6873
+ copyright: null
6699
6874
  }, options);
6700
6875
  if (this.options.animations.length > 0) {
6701
6876
  this.options.trs = true;
6702
6877
  }
6703
- this.processInput(input);
6878
+ await this.processInputAsync(input);
6704
6879
  await Promise.all(this.pending);
6705
6880
  const writer = this;
6706
6881
  const buffers = writer.buffers;
@@ -6714,6 +6889,7 @@ var GLTFWriter = class {
6714
6889
  if (extensionsUsedList.length > 0) json.extensionsUsed = extensionsUsedList;
6715
6890
  if (extensionsRequiredList.length > 0) json.extensionsRequired = extensionsRequiredList;
6716
6891
  if (json.buffers && json.buffers.length > 0) json.buffers[0].byteLength = blob.size;
6892
+ if (options.copyright) json.asset.copyright = options.copyright;
6717
6893
  if (options.binary === true) {
6718
6894
  const reader = new FileReader();
6719
6895
  reader.readAsArrayBuffer(blob);
@@ -6762,7 +6938,7 @@ var GLTFWriter = class {
6762
6938
  /**
6763
6939
  * Serializes a userData.
6764
6940
  *
6765
- * @param {THREE.Object3D|THREE.Material} object
6941
+ * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry|THREE.AnimationClip} object
6766
6942
  * @param {Object} objectDef
6767
6943
  */
6768
6944
  serializeUserData(object, objectDef) {
@@ -6786,8 +6962,10 @@ var GLTFWriter = class {
6786
6962
  }
6787
6963
  /**
6788
6964
  * Returns ids for buffer attributes.
6789
- * @param {Object} object
6790
- * @return {Integer}
6965
+ *
6966
+ * @param {Object} attribute
6967
+ * @param {boolean} [isRelativeCopy=false]
6968
+ * @return {number} An integer
6791
6969
  */
6792
6970
  getUID(attribute, isRelativeCopy = false) {
6793
6971
  if (this.uids.has(attribute) === false) {
@@ -6803,12 +6981,12 @@ var GLTFWriter = class {
6803
6981
  * Checks if normal attribute values are normalized.
6804
6982
  *
6805
6983
  * @param {BufferAttribute} normal
6806
- * @returns {Boolean}
6984
+ * @returns {boolean}
6807
6985
  */
6808
6986
  isNormalizedNormalAttribute(normal) {
6809
6987
  const cache = this.cache;
6810
6988
  if (cache.attributesNormalized.has(normal)) return false;
6811
- const v = new import_three19.Vector3();
6989
+ const v = new import_three18.Vector3();
6812
6990
  for (let i = 0, il = normal.count; i < il; i++) {
6813
6991
  if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
6814
6992
  }
@@ -6825,7 +7003,7 @@ var GLTFWriter = class {
6825
7003
  const cache = this.cache;
6826
7004
  if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
6827
7005
  const attribute = normal.clone();
6828
- const v = new import_three19.Vector3();
7006
+ const v = new import_three18.Vector3();
6829
7007
  for (let i = 0, il = attribute.count; i < il; i++) {
6830
7008
  v.fromBufferAttribute(attribute, i);
6831
7009
  if (v.x === 0 && v.y === 0 && v.z === 0) {
@@ -6866,10 +7044,10 @@ var GLTFWriter = class {
6866
7044
  this.extensionsUsed["KHR_texture_transform"] = true;
6867
7045
  }
6868
7046
  }
6869
- buildMetalRoughTexture(metalnessMap, roughnessMap) {
7047
+ async buildMetalRoughTextureAsync(metalnessMap, roughnessMap) {
6870
7048
  if (metalnessMap === roughnessMap) return metalnessMap;
6871
7049
  function getEncodingConversion(map) {
6872
- if (map.colorSpace === import_three19.SRGBColorSpace) {
7050
+ if (map.colorSpace === import_three18.SRGBColorSpace) {
6873
7051
  return function SRGBToLinear(c) {
6874
7052
  return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
6875
7053
  };
@@ -6878,12 +7056,11 @@ var GLTFWriter = class {
6878
7056
  return c;
6879
7057
  };
6880
7058
  }
6881
- console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
6882
- if (metalnessMap instanceof import_three19.CompressedTexture) {
6883
- metalnessMap = decompress(metalnessMap);
7059
+ if (metalnessMap instanceof import_three18.CompressedTexture) {
7060
+ metalnessMap = await this.decompressTextureAsync(metalnessMap);
6884
7061
  }
6885
- if (roughnessMap instanceof import_three19.CompressedTexture) {
6886
- roughnessMap = decompress(roughnessMap);
7062
+ if (roughnessMap instanceof import_three18.CompressedTexture) {
7063
+ roughnessMap = await this.decompressTextureAsync(roughnessMap);
6887
7064
  }
6888
7065
  const metalness = metalnessMap ? metalnessMap.image : null;
6889
7066
  const roughness = roughnessMap ? roughnessMap.image : null;
@@ -6892,7 +7069,9 @@ var GLTFWriter = class {
6892
7069
  const canvas = getCanvas();
6893
7070
  canvas.width = width;
6894
7071
  canvas.height = height;
6895
- const context = canvas.getContext("2d");
7072
+ const context = canvas.getContext("2d", {
7073
+ willReadFrequently: true
7074
+ });
6896
7075
  context.fillStyle = "#00ffff";
6897
7076
  context.fillRect(0, 0, width, height);
6898
7077
  const composite = context.getImageData(0, 0, width, height);
@@ -6915,18 +7094,60 @@ var GLTFWriter = class {
6915
7094
  context.putImageData(composite, 0, 0);
6916
7095
  const reference = metalnessMap || roughnessMap;
6917
7096
  const texture = reference.clone();
6918
- texture.source = new import_three19.Source(canvas);
6919
- texture.colorSpace = import_three19.NoColorSpace;
7097
+ texture.source = new import_three18.TextureSource(canvas);
7098
+ texture.colorSpace = import_three18.NoColorSpace;
6920
7099
  texture.channel = (metalnessMap || roughnessMap).channel;
6921
7100
  if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
6922
7101
  console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
6923
7102
  }
7103
+ console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
7104
+ return texture;
7105
+ }
7106
+ /**
7107
+ * Builds a copy of the given normal map with the red and/or green channels
7108
+ * inverted (`color = 255 - color`). This is used to bake the sign of
7109
+ * `material.normalScale` and the tangent-space convention into the texture,
7110
+ * since glTF only supports OpenGL-style normal maps with a univariate,
7111
+ * positive scale.
7112
+ *
7113
+ * @param {THREE.Texture} normalMap The source normal map.
7114
+ * @param {boolean} flipX Whether to invert the red channel (normal X).
7115
+ * @param {boolean} flipY Whether to invert the green channel (normal Y).
7116
+ * @return {Promise<THREE.Texture>} The derived normal map texture.
7117
+ */
7118
+ async buildNormalMapTextureAsync(normalMap, flipX, flipY) {
7119
+ if (normalMap instanceof import_three18.CompressedTexture) {
7120
+ normalMap = await this.decompressTextureAsync(normalMap);
7121
+ }
7122
+ const image = normalMap.image;
7123
+ const canvas = getCanvas();
7124
+ canvas.width = image.width;
7125
+ canvas.height = image.height;
7126
+ const context = canvas.getContext("2d", {
7127
+ willReadFrequently: true
7128
+ });
7129
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
7130
+ const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
7131
+ const data = imageData.data;
7132
+ for (let i = 0; i < data.length; i += 4) {
7133
+ if (flipX) data[i + 0] = 255 - data[i + 0];
7134
+ if (flipY) data[i + 1] = 255 - data[i + 1];
7135
+ }
7136
+ context.putImageData(imageData, 0, 0);
7137
+ const texture = normalMap.clone();
7138
+ texture.source = new import_three18.TextureSource(canvas);
6924
7139
  return texture;
6925
7140
  }
7141
+ async decompressTextureAsync(texture, maxTextureSize = Infinity) {
7142
+ if (this.textureUtils === null) {
7143
+ throw new Error("THREE.GLTFExporter: setTextureUtils() must be called to process compressed textures.");
7144
+ }
7145
+ return await this.textureUtils.decompress(texture, maxTextureSize);
7146
+ }
6926
7147
  /**
6927
7148
  * Process a buffer to append to the default one.
6928
- * @param {ArrayBuffer} buffer
6929
- * @return {Integer}
7149
+ * @param {ArrayBuffer} buffer
7150
+ * @return {0}
6930
7151
  */
6931
7152
  processBuffer(buffer) {
6932
7153
  const json = this.json;
@@ -6937,11 +7158,11 @@ var GLTFWriter = class {
6937
7158
  }
6938
7159
  /**
6939
7160
  * Process and generate a BufferView
6940
- * @param {BufferAttribute} attribute
6941
- * @param {number} componentType
6942
- * @param {number} start
6943
- * @param {number} count
6944
- * @param {number} target (Optional) Target usage of the BufferView
7161
+ * @param {BufferAttribute} attribute
7162
+ * @param {number} componentType
7163
+ * @param {number} start
7164
+ * @param {number} count
7165
+ * @param {number} [target] Target usage of the BufferView
6945
7166
  * @return {Object}
6946
7167
  */
6947
7168
  processBufferView(attribute, componentType, start, count, target) {
@@ -6960,7 +7181,11 @@ var GLTFWriter = class {
6960
7181
  default:
6961
7182
  componentSize = 4;
6962
7183
  }
6963
- const byteLength = getPaddedBufferSize(count * attribute.itemSize * componentSize);
7184
+ let byteStride = attribute.itemSize * componentSize;
7185
+ if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
7186
+ byteStride = Math.ceil(byteStride / 4) * 4;
7187
+ }
7188
+ const byteLength = getPaddedBufferSize(count * byteStride);
6964
7189
  const dataView = new DataView(new ArrayBuffer(byteLength));
6965
7190
  let offset = 0;
6966
7191
  for (let i = start; i < start + count; i++) {
@@ -6974,7 +7199,7 @@ var GLTFWriter = class {
6974
7199
  else if (a === 2) value = attribute.getZ(i);
6975
7200
  else if (a === 3) value = attribute.getW(i);
6976
7201
  if (attribute.normalized === true) {
6977
- value = import_three19.MathUtils.normalize(value, attribute.array);
7202
+ value = import_three18.MathUtils.normalize(value, attribute.array);
6978
7203
  }
6979
7204
  }
6980
7205
  if (componentType === WEBGL_CONSTANTS.FLOAT) {
@@ -6994,6 +7219,9 @@ var GLTFWriter = class {
6994
7219
  }
6995
7220
  offset += componentSize;
6996
7221
  }
7222
+ if (offset % byteStride !== 0) {
7223
+ offset += byteStride - offset % byteStride;
7224
+ }
6997
7225
  }
6998
7226
  const bufferViewDef = {
6999
7227
  buffer: this.processBuffer(dataView.buffer),
@@ -7002,7 +7230,7 @@ var GLTFWriter = class {
7002
7230
  };
7003
7231
  if (target !== void 0) bufferViewDef.target = target;
7004
7232
  if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
7005
- bufferViewDef.byteStride = attribute.itemSize * componentSize;
7233
+ bufferViewDef.byteStride = byteStride;
7006
7234
  }
7007
7235
  this.byteOffset += byteLength;
7008
7236
  json.bufferViews.push(bufferViewDef);
@@ -7015,7 +7243,7 @@ var GLTFWriter = class {
7015
7243
  /**
7016
7244
  * Process and generate a BufferView from an image Blob.
7017
7245
  * @param {Blob} blob
7018
- * @return {Promise<Integer>}
7246
+ * @return {Promise<number>} An integer
7019
7247
  */
7020
7248
  processBufferViewImage(blob) {
7021
7249
  const writer = this;
@@ -7038,11 +7266,11 @@ var GLTFWriter = class {
7038
7266
  }
7039
7267
  /**
7040
7268
  * Process attribute to generate an accessor
7041
- * @param {BufferAttribute} attribute Attribute to process
7042
- * @param {THREE.BufferGeometry} geometry (Optional) Geometry used for truncated draw range
7043
- * @param {Integer} start (Optional)
7044
- * @param {Integer} count (Optional)
7045
- * @return {Integer|null} Index of the processed accessor on the "accessors" array
7269
+ * @param {BufferAttribute} attribute Attribute to process
7270
+ * @param {?BufferGeometry} [geometry] Geometry used for truncated draw range
7271
+ * @param {number} [start=0]
7272
+ * @param {number} [count=Infinity]
7273
+ * @return {?number} Index of the processed accessor on the "accessors" array
7046
7274
  */
7047
7275
  processAccessor(attribute, geometry, start, count) {
7048
7276
  const json = this.json;
@@ -7096,11 +7324,11 @@ var GLTFWriter = class {
7096
7324
  }
7097
7325
  /**
7098
7326
  * Process image
7099
- * @param {Image} image to process
7100
- * @param {Integer} format of the image (RGBAFormat)
7101
- * @param {Boolean} flipY before writing out the image
7102
- * @param {String} mimeType export format
7103
- * @return {Integer} Index of the processed texture in the "images" array
7327
+ * @param {Image} image to process
7328
+ * @param {number} format Identifier of the format (RGBAFormat)
7329
+ * @param {boolean} flipY before writing out the image
7330
+ * @param {string} mimeType export format
7331
+ * @return {number} Index of the processed texture in the "images" array
7104
7332
  */
7105
7333
  processImage(image, format, flipY, mimeType = "image/png") {
7106
7334
  if (image !== null) {
@@ -7118,13 +7346,15 @@ var GLTFWriter = class {
7118
7346
  const canvas = getCanvas();
7119
7347
  canvas.width = Math.min(image.width, options.maxTextureSize);
7120
7348
  canvas.height = Math.min(image.height, options.maxTextureSize);
7121
- const ctx = canvas.getContext("2d");
7349
+ const ctx = canvas.getContext("2d", {
7350
+ willReadFrequently: true
7351
+ });
7122
7352
  if (flipY === true) {
7123
7353
  ctx.translate(0, canvas.height);
7124
7354
  ctx.scale(1, -1);
7125
7355
  }
7126
7356
  if (image.data !== void 0) {
7127
- if (format !== import_three19.RGBAFormat) {
7357
+ if (format !== import_three18.RGBAFormat) {
7128
7358
  console.error("GLTFExporter: Only RGBAFormat is supported.", format);
7129
7359
  }
7130
7360
  if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
@@ -7139,7 +7369,11 @@ var GLTFWriter = class {
7139
7369
  }
7140
7370
  ctx.putImageData(new ImageData(data, image.width, image.height), 0, 0);
7141
7371
  } else {
7142
- ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
7372
+ if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap || typeof OffscreenCanvas !== "undefined" && image instanceof OffscreenCanvas) {
7373
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
7374
+ } else {
7375
+ throw new Error("THREE.GLTFExporter: Invalid image type. Use HTMLImageElement, HTMLCanvasElement, ImageBitmap or OffscreenCanvas.");
7376
+ }
7143
7377
  }
7144
7378
  if (options.binary === true) {
7145
7379
  pending.push(
@@ -7148,15 +7382,7 @@ var GLTFWriter = class {
7148
7382
  })
7149
7383
  );
7150
7384
  } else {
7151
- if (canvas.toDataURL !== void 0) {
7152
- imageDef.uri = canvas.toDataURL(mimeType);
7153
- } else {
7154
- pending.push(
7155
- getToBlobPromise(canvas, mimeType).then((blob) => new FileReader().readAsDataURL(blob)).then((dataURL) => {
7156
- imageDef.uri = dataURL;
7157
- })
7158
- );
7159
- }
7385
+ imageDef.uri = import_three18.ImageUtils.getDataURL(canvas, mimeType);
7160
7386
  }
7161
7387
  const index = json.images.push(imageDef) - 1;
7162
7388
  cachedImages[key] = index;
@@ -7167,8 +7393,8 @@ var GLTFWriter = class {
7167
7393
  }
7168
7394
  /**
7169
7395
  * Process sampler
7170
- * @param {Texture} map Texture to process
7171
- * @return {Integer} Index of the processed texture in the "samplers" array
7396
+ * @param {Texture} map Texture to process
7397
+ * @return {number} Index of the processed texture in the "samplers" array
7172
7398
  */
7173
7399
  processSampler(map) {
7174
7400
  const json = this.json;
@@ -7183,28 +7409,37 @@ var GLTFWriter = class {
7183
7409
  }
7184
7410
  /**
7185
7411
  * Process texture
7186
- * @param {Texture} map Map to process
7187
- * @return {Integer} Index of the processed texture in the "textures" array
7412
+ * @param {Texture} map Map to process
7413
+ * @return {Promise<number>} Index of the processed texture in the "textures" array
7188
7414
  */
7189
- processTexture(map) {
7415
+ async processTextureAsync(map) {
7190
7416
  const writer = this;
7191
7417
  const options = writer.options;
7192
7418
  const cache = this.cache;
7193
7419
  const json = this.json;
7194
7420
  if (cache.textures.has(map)) return cache.textures.get(map);
7195
7421
  if (!json.textures) json.textures = [];
7196
- if (map instanceof import_three19.CompressedTexture) {
7197
- map = decompress(map, options.maxTextureSize);
7422
+ if (map instanceof import_three18.CompressedTexture) {
7423
+ map = await this.decompressTextureAsync(map, options.maxTextureSize);
7198
7424
  }
7199
- let mimeType = map.userData.mimeType;
7200
- if (mimeType === "image/webp") mimeType = "image/png";
7425
+ const mimeType = map.userData.mimeType;
7426
+ const imageIndex = this.processImage(map.image, map.format, map.flipY, mimeType);
7201
7427
  const textureDef = {
7202
- sampler: this.processSampler(map),
7203
- source: this.processImage(map.image, map.format, map.flipY, mimeType)
7428
+ sampler: this.processSampler(map)
7204
7429
  };
7430
+ if (mimeType === "image/webp") {
7431
+ textureDef.extensions = textureDef.extensions || {};
7432
+ textureDef.extensions["EXT_texture_webp"] = {
7433
+ source: imageIndex
7434
+ };
7435
+ this.extensionsUsed["EXT_texture_webp"] = true;
7436
+ this.extensionsRequired["EXT_texture_webp"] = true;
7437
+ } else {
7438
+ textureDef.source = imageIndex;
7439
+ }
7205
7440
  if (map.name) textureDef.name = map.name;
7206
- this._invokeAll(function(ext) {
7207
- ext.writeTexture && ext.writeTexture(map, textureDef);
7441
+ await this._invokeAllAsync(async function(ext) {
7442
+ ext.writeTexture && await ext.writeTexture(map, textureDef);
7208
7443
  });
7209
7444
  const index = json.textures.push(textureDef) - 1;
7210
7445
  cache.textures.set(map, index);
@@ -7212,13 +7447,16 @@ var GLTFWriter = class {
7212
7447
  }
7213
7448
  /**
7214
7449
  * Process material
7215
- * @param {THREE.Material} material Material to process
7216
- * @return {Integer|null} Index of the processed material in the "materials" array
7450
+ * @param {THREE.Material} material Material to process
7451
+ * @param {THREE.BufferGeometry} [geometry] Geometry the material is used with.
7452
+ * @return {Promise<?number>} Index of the processed material in the "materials" array
7217
7453
  */
7218
- processMaterial(material) {
7454
+ async processMaterialAsync(material, geometry) {
7219
7455
  const cache = this.cache;
7220
7456
  const json = this.json;
7221
- if (cache.materials.has(material)) return cache.materials.get(material);
7457
+ const hasTangent = geometry !== void 0 && geometry.hasAttribute("tangent");
7458
+ const cacheKey = material.normalMap ? material.uuid + ":" + hasTangent : material.uuid;
7459
+ if (cache.materials.has(cacheKey)) return cache.materials.get(cacheKey);
7222
7460
  if (material.isShaderMaterial) {
7223
7461
  console.warn("GLTFExporter: THREE.ShaderMaterial not supported.");
7224
7462
  return null;
@@ -7236,21 +7474,21 @@ var GLTFWriter = class {
7236
7474
  materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
7237
7475
  materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
7238
7476
  } else {
7239
- materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
7240
- materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
7477
+ materialDef.pbrMetallicRoughness.metallicFactor = 0;
7478
+ materialDef.pbrMetallicRoughness.roughnessFactor = 1;
7241
7479
  }
7242
7480
  if (material.metalnessMap || material.roughnessMap) {
7243
- const metalRoughTexture = this.buildMetalRoughTexture(material.metalnessMap, material.roughnessMap);
7481
+ const metalRoughTexture = await this.buildMetalRoughTextureAsync(material.metalnessMap, material.roughnessMap);
7244
7482
  const metalRoughMapDef = {
7245
- index: this.processTexture(metalRoughTexture),
7246
- channel: metalRoughTexture.channel
7483
+ index: await this.processTextureAsync(metalRoughTexture),
7484
+ texCoord: metalRoughTexture.channel
7247
7485
  };
7248
7486
  this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
7249
7487
  materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
7250
7488
  }
7251
7489
  if (material.map) {
7252
7490
  const baseColorMapDef = {
7253
- index: this.processTexture(material.map),
7491
+ index: await this.processTextureAsync(material.map),
7254
7492
  texCoord: material.map.channel
7255
7493
  };
7256
7494
  this.applyTextureTransform(baseColorMapDef, material.map);
@@ -7264,7 +7502,7 @@ var GLTFWriter = class {
7264
7502
  }
7265
7503
  if (material.emissiveMap) {
7266
7504
  const emissiveMapDef = {
7267
- index: this.processTexture(material.emissiveMap),
7505
+ index: await this.processTextureAsync(material.emissiveMap),
7268
7506
  texCoord: material.emissiveMap.channel
7269
7507
  };
7270
7508
  this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
@@ -7272,19 +7510,32 @@ var GLTFWriter = class {
7272
7510
  }
7273
7511
  }
7274
7512
  if (material.normalMap) {
7513
+ const normalScale = material.normalScale;
7514
+ const flipX = normalScale.x < 0;
7515
+ const flipY = hasTangent ? normalScale.y < 0 : normalScale.y > 0;
7516
+ let normalMap = material.normalMap;
7517
+ if (flipX || flipY) {
7518
+ if (cache.normalMaps.has(material.normalMap) === false) cache.normalMaps.set(material.normalMap, {});
7519
+ const cachedVariants = cache.normalMaps.get(material.normalMap);
7520
+ const cacheKey2 = `${flipX}:${flipY}`;
7521
+ if (cachedVariants[cacheKey2] === void 0) {
7522
+ cachedVariants[cacheKey2] = await this.buildNormalMapTextureAsync(material.normalMap, flipX, flipY);
7523
+ }
7524
+ normalMap = cachedVariants[cacheKey2];
7525
+ }
7275
7526
  const normalMapDef = {
7276
- index: this.processTexture(material.normalMap),
7527
+ index: await this.processTextureAsync(normalMap),
7277
7528
  texCoord: material.normalMap.channel
7278
7529
  };
7279
- if (material.normalScale && material.normalScale.x !== 1) {
7280
- normalMapDef.scale = material.normalScale.x;
7530
+ if (Math.abs(normalScale.x) !== 1) {
7531
+ normalMapDef.scale = Math.abs(normalScale.x);
7281
7532
  }
7282
7533
  this.applyTextureTransform(normalMapDef, material.normalMap);
7283
7534
  materialDef.normalTexture = normalMapDef;
7284
7535
  }
7285
7536
  if (material.aoMap) {
7286
7537
  const occlusionMapDef = {
7287
- index: this.processTexture(material.aoMap),
7538
+ index: await this.processTextureAsync(material.aoMap),
7288
7539
  texCoord: material.aoMap.channel
7289
7540
  };
7290
7541
  if (material.aoMapIntensity !== 1) {
@@ -7301,22 +7552,22 @@ var GLTFWriter = class {
7301
7552
  materialDef.alphaCutoff = material.alphaTest;
7302
7553
  }
7303
7554
  }
7304
- if (material.side === import_three19.DoubleSide) materialDef.doubleSided = true;
7555
+ if (material.side === import_three18.DoubleSide) materialDef.doubleSided = true;
7305
7556
  if (material.name !== "") materialDef.name = material.name;
7306
7557
  this.serializeUserData(material, materialDef);
7307
- this._invokeAll(function(ext) {
7308
- ext.writeMaterial && ext.writeMaterial(material, materialDef);
7558
+ await this._invokeAllAsync(async function(ext) {
7559
+ ext.writeMaterialAsync && await ext.writeMaterialAsync(material, materialDef);
7309
7560
  });
7310
7561
  const index = json.materials.push(materialDef) - 1;
7311
- cache.materials.set(material, index);
7562
+ cache.materials.set(cacheKey, index);
7312
7563
  return index;
7313
7564
  }
7314
7565
  /**
7315
7566
  * Process mesh
7316
- * @param {THREE.Mesh} mesh Mesh to process
7317
- * @return {Integer|null} Index of the processed mesh in the "meshes" array
7567
+ * @param {THREE.Mesh} mesh Mesh to process
7568
+ * @return {Promise<?number>} Index of the processed mesh in the "meshes" array
7318
7569
  */
7319
- processMesh(mesh) {
7570
+ async processMeshAsync(mesh) {
7320
7571
  const cache = this.cache;
7321
7572
  const json = this.json;
7322
7573
  const meshCacheKeyParts = [mesh.geometry.uuid];
@@ -7366,7 +7617,7 @@ var GLTFWriter = class {
7366
7617
  const attribute = geometry.attributes[attributeName];
7367
7618
  attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
7368
7619
  const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
7369
- if (!validVertexAttributes.test(attributeName)) attributeName = "_" + attributeName;
7620
+ if (!validVertexAttributes.test(attributeName) && !attributeName.startsWith("_")) attributeName = "_" + attributeName;
7370
7621
  if (cache.attributes.has(this.getUID(attribute))) {
7371
7622
  attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
7372
7623
  continue;
@@ -7375,7 +7626,10 @@ var GLTFWriter = class {
7375
7626
  const array = attribute.array;
7376
7627
  if (attributeName === "JOINTS_0" && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
7377
7628
  console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
7378
- modifiedAttribute = new import_three19.BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
7629
+ modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute(attribute, Uint16Array);
7630
+ } else if ((array instanceof Uint32Array || array instanceof Int32Array) && !attributeName.startsWith("_")) {
7631
+ console.warn(`GLTFExporter: Attribute "${attributeName}" converted to type FLOAT.`);
7632
+ modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute(attribute, Float32Array);
7379
7633
  }
7380
7634
  const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
7381
7635
  if (accessor !== null) {
@@ -7441,6 +7695,15 @@ var GLTFWriter = class {
7441
7695
  }
7442
7696
  const isMultiMaterial = Array.isArray(mesh.material);
7443
7697
  if (isMultiMaterial && geometry.groups.length === 0) return null;
7698
+ let didForceIndices = false;
7699
+ if (isMultiMaterial && geometry.index === null) {
7700
+ const indices = [];
7701
+ for (let i = 0, il = geometry.attributes.position.count; i < il; i++) {
7702
+ indices[i] = i;
7703
+ }
7704
+ geometry.setIndex(indices);
7705
+ didForceIndices = true;
7706
+ }
7444
7707
  const materials = isMultiMaterial ? mesh.material : [mesh.material];
7445
7708
  const groups = isMultiMaterial ? geometry.groups : [{ materialIndex: 0, start: void 0, count: void 0 }];
7446
7709
  for (let i = 0, il = groups.length; i < il; i++) {
@@ -7463,13 +7726,16 @@ var GLTFWriter = class {
7463
7726
  }
7464
7727
  if (primitive.indices === null) delete primitive.indices;
7465
7728
  }
7466
- const material = this.processMaterial(materials[groups[i].materialIndex]);
7729
+ const material = await this.processMaterialAsync(materials[groups[i].materialIndex], geometry);
7467
7730
  if (material !== null) primitive.material = material;
7468
7731
  primitives.push(primitive);
7469
7732
  }
7733
+ if (didForceIndices === true) {
7734
+ geometry.setIndex(null);
7735
+ }
7470
7736
  meshDef.primitives = primitives;
7471
7737
  if (!json.meshes) json.meshes = [];
7472
- this._invokeAll(function(ext) {
7738
+ await this._invokeAllAsync(function(ext) {
7473
7739
  ext.writeMesh && ext.writeMesh(mesh, meshDef);
7474
7740
  });
7475
7741
  const index = json.meshes.push(meshDef) - 1;
@@ -7515,8 +7781,8 @@ var GLTFWriter = class {
7515
7781
  }
7516
7782
  /**
7517
7783
  * Process camera
7518
- * @param {THREE.Camera} camera Camera to process
7519
- * @return {Integer} Index of the processed mesh in the "camera" array
7784
+ * @param {THREE.Camera} camera Camera to process
7785
+ * @return {number} Index of the processed mesh in the "camera" array
7520
7786
  */
7521
7787
  processCamera(camera) {
7522
7788
  const json = this.json;
@@ -7535,7 +7801,7 @@ var GLTFWriter = class {
7535
7801
  } else {
7536
7802
  cameraDef.perspective = {
7537
7803
  aspectRatio: camera.aspect,
7538
- yfov: import_three19.MathUtils.degToRad(camera.fov),
7804
+ yfov: import_three18.MathUtils.degToRad(camera.fov),
7539
7805
  zfar: camera.far <= 0 ? 1e-3 : camera.far,
7540
7806
  znear: camera.near < 0 ? 0 : camera.near
7541
7807
  };
@@ -7551,7 +7817,7 @@ var GLTFWriter = class {
7551
7817
  *
7552
7818
  * @param {THREE.AnimationClip} clip
7553
7819
  * @param {THREE.Object3D} root
7554
- * @return {number|null}
7820
+ * @return {?number}
7555
7821
  */
7556
7822
  processAnimation(clip, root) {
7557
7823
  const json = this.json;
@@ -7563,8 +7829,8 @@ var GLTFWriter = class {
7563
7829
  const samplers = [];
7564
7830
  for (let i = 0; i < tracks.length; ++i) {
7565
7831
  const track = tracks[i];
7566
- const trackBinding = import_three19.PropertyBinding.parseTrackName(track.name);
7567
- let trackNode = import_three19.PropertyBinding.findNode(root, trackBinding.nodeName);
7832
+ const trackBinding = import_three18.PropertyBinding.parseTrackName(track.name);
7833
+ let trackNode = import_three18.PropertyBinding.findNode(root, trackBinding.nodeName);
7568
7834
  const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
7569
7835
  if (trackBinding.objectName === "bones") {
7570
7836
  if (trackNode.isSkinnedMesh === true) {
@@ -7575,7 +7841,7 @@ var GLTFWriter = class {
7575
7841
  }
7576
7842
  if (!trackNode || !trackProperty) {
7577
7843
  console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
7578
- return null;
7844
+ continue;
7579
7845
  }
7580
7846
  const inputItemSize = 1;
7581
7847
  let outputItemSize = track.values.length / track.times.length;
@@ -7586,14 +7852,14 @@ var GLTFWriter = class {
7586
7852
  if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
7587
7853
  interpolation = "CUBICSPLINE";
7588
7854
  outputItemSize /= 3;
7589
- } else if (track.getInterpolation() === import_three19.InterpolateDiscrete) {
7855
+ } else if (track.getInterpolation() === import_three18.InterpolateDiscrete) {
7590
7856
  interpolation = "STEP";
7591
7857
  } else {
7592
7858
  interpolation = "LINEAR";
7593
7859
  }
7594
7860
  samplers.push({
7595
- input: this.processAccessor(new import_three19.BufferAttribute(track.times, inputItemSize)),
7596
- output: this.processAccessor(new import_three19.BufferAttribute(track.values, outputItemSize)),
7861
+ input: this.processAccessor(new import_three18.BufferAttribute(track.times, inputItemSize)),
7862
+ output: this.processAccessor(new import_three18.BufferAttribute(track.values, outputItemSize)),
7597
7863
  interpolation
7598
7864
  });
7599
7865
  channels.push({
@@ -7604,16 +7870,18 @@ var GLTFWriter = class {
7604
7870
  }
7605
7871
  });
7606
7872
  }
7607
- json.animations.push({
7873
+ const animationDef = {
7608
7874
  name: clip.name || "clip_" + json.animations.length,
7609
7875
  samplers,
7610
7876
  channels
7611
- });
7877
+ };
7878
+ this.serializeUserData(clip, animationDef);
7879
+ json.animations.push(animationDef);
7612
7880
  return json.animations.length - 1;
7613
7881
  }
7614
7882
  /**
7615
7883
  * @param {THREE.Object3D} object
7616
- * @return {number|null}
7884
+ * @return {?number}
7617
7885
  */
7618
7886
  processSkin(object) {
7619
7887
  const json = this.json;
@@ -7625,7 +7893,7 @@ var GLTFWriter = class {
7625
7893
  if (rootJoint === void 0) return null;
7626
7894
  const joints = [];
7627
7895
  const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
7628
- const temporaryBoneInverse = new import_three19.Matrix4();
7896
+ const temporaryBoneInverse = new import_three18.Matrix4();
7629
7897
  for (let i = 0; i < skeleton.bones.length; ++i) {
7630
7898
  joints.push(nodeMap.get(skeleton.bones[i]));
7631
7899
  temporaryBoneInverse.copy(skeleton.boneInverses[i]);
@@ -7633,7 +7901,7 @@ var GLTFWriter = class {
7633
7901
  }
7634
7902
  if (json.skins === void 0) json.skins = [];
7635
7903
  json.skins.push({
7636
- inverseBindMatrices: this.processAccessor(new import_three19.BufferAttribute(inverseBindMatrices, 16)),
7904
+ inverseBindMatrices: this.processAccessor(new import_three18.BufferAttribute(inverseBindMatrices, 16)),
7637
7905
  joints,
7638
7906
  skeleton: nodeMap.get(rootJoint)
7639
7907
  });
@@ -7642,14 +7910,17 @@ var GLTFWriter = class {
7642
7910
  }
7643
7911
  /**
7644
7912
  * Process Object3D node
7645
- * @param {THREE.Object3D} node Object3D to processNode
7646
- * @return {Integer} Index of the node in the nodes list
7913
+ * @param {THREE.Object3D} object Object3D to processNodeAsync
7914
+ * @return {Promise<number>} Index of the node in the nodes list
7647
7915
  */
7648
- processNode(object) {
7916
+ async processNodeAsync(object) {
7649
7917
  const json = this.json;
7650
7918
  const options = this.options;
7651
7919
  const nodeMap = this.nodeMap;
7652
7920
  if (!json.nodes) json.nodes = [];
7921
+ if (object.pivot !== null) {
7922
+ return await this._processNodeWithPivotAsync(object);
7923
+ }
7653
7924
  const nodeDef = {};
7654
7925
  if (options.trs) {
7655
7926
  const rotation = object.quaternion.toArray();
@@ -7675,35 +7946,98 @@ var GLTFWriter = class {
7675
7946
  if (object.name !== "") nodeDef.name = String(object.name);
7676
7947
  this.serializeUserData(object, nodeDef);
7677
7948
  if (object.isMesh || object.isLine || object.isPoints) {
7678
- const meshIndex = this.processMesh(object);
7949
+ const meshIndex = await this.processMeshAsync(object);
7679
7950
  if (meshIndex !== null) nodeDef.mesh = meshIndex;
7680
7951
  } else if (object.isCamera) {
7681
7952
  nodeDef.camera = this.processCamera(object);
7682
7953
  }
7683
7954
  if (object.isSkinnedMesh) this.skins.push(object);
7955
+ const nodeIndex = json.nodes.push(nodeDef) - 1;
7956
+ nodeMap.set(object, nodeIndex);
7684
7957
  if (object.children.length > 0) {
7685
7958
  const children = [];
7686
7959
  for (let i = 0, l = object.children.length; i < l; i++) {
7687
7960
  const child = object.children[i];
7688
7961
  if (child.visible || options.onlyVisible === false) {
7689
- const nodeIndex2 = this.processNode(child);
7690
- if (nodeIndex2 !== null) children.push(nodeIndex2);
7962
+ const childNodeIndex = await this.processNodeAsync(child);
7963
+ if (childNodeIndex !== null) children.push(childNodeIndex);
7691
7964
  }
7692
7965
  }
7693
7966
  if (children.length > 0) nodeDef.children = children;
7694
7967
  }
7695
- this._invokeAll(function(ext) {
7968
+ await this._invokeAllAsync(function(ext) {
7696
7969
  ext.writeNode && ext.writeNode(object, nodeDef);
7697
7970
  });
7698
- const nodeIndex = json.nodes.push(nodeDef) - 1;
7699
- nodeMap.set(object, nodeIndex);
7700
7971
  return nodeIndex;
7701
7972
  }
7973
+ /**
7974
+ * Process Object3D node with pivot using container approach
7975
+ * @param {THREE.Object3D} object Object3D with pivot
7976
+ * @return {Promise<number>} Index of the container node
7977
+ */
7978
+ async _processNodeWithPivotAsync(object) {
7979
+ const json = this.json;
7980
+ const options = this.options;
7981
+ const nodeMap = this.nodeMap;
7982
+ const pivot = object.pivot;
7983
+ const containerDef = {};
7984
+ const rotation = object.quaternion.toArray();
7985
+ const position = [
7986
+ object.position.x + pivot.x,
7987
+ object.position.y + pivot.y,
7988
+ object.position.z + pivot.z
7989
+ ];
7990
+ const scale = object.scale.toArray();
7991
+ if (!equalArray(rotation, [0, 0, 0, 1])) {
7992
+ containerDef.rotation = rotation;
7993
+ }
7994
+ if (!equalArray(position, [0, 0, 0])) {
7995
+ containerDef.translation = position;
7996
+ }
7997
+ if (!equalArray(scale, [1, 1, 1])) {
7998
+ containerDef.scale = scale;
7999
+ }
8000
+ containerDef.extras = { pivot: pivot.toArray() };
8001
+ if (object.name !== "") containerDef.name = String(object.name);
8002
+ this.serializeUserData(object, containerDef);
8003
+ const containerIndex = json.nodes.push(containerDef) - 1;
8004
+ nodeMap.set(object, containerIndex);
8005
+ const childDef = {};
8006
+ const childPosition = [-pivot.x, -pivot.y, -pivot.z];
8007
+ if (!equalArray(childPosition, [0, 0, 0])) {
8008
+ childDef.translation = childPosition;
8009
+ }
8010
+ if (object.isMesh || object.isLine || object.isPoints) {
8011
+ const meshIndex = await this.processMeshAsync(object);
8012
+ if (meshIndex !== null) childDef.mesh = meshIndex;
8013
+ } else if (object.isCamera) {
8014
+ childDef.camera = this.processCamera(object);
8015
+ }
8016
+ if (object.isSkinnedMesh) this.skins.push(object);
8017
+ const childIndex = json.nodes.push(childDef) - 1;
8018
+ const containerChildren = [childIndex];
8019
+ if (object.children.length > 0) {
8020
+ const grandchildren = [];
8021
+ for (let i = 0, l = object.children.length; i < l; i++) {
8022
+ const child = object.children[i];
8023
+ if (child.visible || options.onlyVisible === false) {
8024
+ const childNodeIndex = await this.processNodeAsync(child);
8025
+ if (childNodeIndex !== null) grandchildren.push(childNodeIndex);
8026
+ }
8027
+ }
8028
+ if (grandchildren.length > 0) childDef.children = grandchildren;
8029
+ }
8030
+ containerDef.children = containerChildren;
8031
+ await this._invokeAllAsync(function(ext) {
8032
+ ext.writeNode && ext.writeNode(object, containerDef);
8033
+ });
8034
+ return containerIndex;
8035
+ }
7702
8036
  /**
7703
8037
  * Process Scene
7704
- * @param {Scene} node Scene to process
8038
+ * @param {Scene} scene Scene to process
7705
8039
  */
7706
- processScene(scene) {
8040
+ async processSceneAsync(scene) {
7707
8041
  const json = this.json;
7708
8042
  const options = this.options;
7709
8043
  if (!json.scenes) {
@@ -7717,7 +8051,7 @@ var GLTFWriter = class {
7717
8051
  for (let i = 0, l = scene.children.length; i < l; i++) {
7718
8052
  const child = scene.children[i];
7719
8053
  if (child.visible || options.onlyVisible === false) {
7720
- const nodeIndex = this.processNode(child);
8054
+ const nodeIndex = await this.processNodeAsync(child);
7721
8055
  if (nodeIndex !== null) nodes.push(nodeIndex);
7722
8056
  }
7723
8057
  }
@@ -7726,47 +8060,58 @@ var GLTFWriter = class {
7726
8060
  }
7727
8061
  /**
7728
8062
  * Creates a Scene to hold a list of objects and parse it
7729
- * @param {Array} objects List of objects to process
8063
+ * @param {Array<THREE.Object3D>} objects List of objects to process
7730
8064
  */
7731
- processObjects(objects) {
7732
- const scene = new import_three19.Scene();
8065
+ async processObjectsAsync(objects) {
8066
+ const scene = new import_three18.Scene();
7733
8067
  scene.name = "AuxScene";
7734
8068
  for (let i = 0; i < objects.length; i++) {
7735
8069
  scene.children.push(objects[i]);
7736
8070
  }
7737
- this.processScene(scene);
8071
+ await this.processSceneAsync(scene);
7738
8072
  }
7739
8073
  /**
7740
8074
  * @param {THREE.Object3D|Array<THREE.Object3D>} input
7741
8075
  */
7742
- processInput(input) {
8076
+ async processInputAsync(input) {
7743
8077
  const options = this.options;
7744
8078
  input = input instanceof Array ? input : [input];
7745
- this._invokeAll(function(ext) {
8079
+ await this._invokeAllAsync(function(ext) {
7746
8080
  ext.beforeParse && ext.beforeParse(input);
7747
8081
  });
7748
8082
  const objectsWithoutScene = [];
7749
8083
  for (let i = 0; i < input.length; i++) {
7750
- if (input[i] instanceof import_three19.Scene) {
7751
- this.processScene(input[i]);
8084
+ if (input[i] instanceof import_three18.Scene) {
8085
+ await this.processSceneAsync(input[i]);
7752
8086
  } else {
7753
8087
  objectsWithoutScene.push(input[i]);
7754
8088
  }
7755
8089
  }
7756
- if (objectsWithoutScene.length > 0) this.processObjects(objectsWithoutScene);
8090
+ if (objectsWithoutScene.length > 0) {
8091
+ await this.processObjectsAsync(objectsWithoutScene);
8092
+ }
7757
8093
  for (let i = 0; i < this.skins.length; ++i) {
7758
8094
  this.processSkin(this.skins[i]);
7759
8095
  }
7760
- for (let i = 0; i < options.animations.length; ++i) {
7761
- this.processAnimation(options.animations[i], input[0]);
8096
+ if (input.length === 1) {
8097
+ for (let i = 0; i < options.animations.length; ++i) {
8098
+ this.processAnimation(options.animations[i], input[0]);
8099
+ }
8100
+ } else {
8101
+ for (let i = 0; i < input.length; i++) {
8102
+ const animations = options.animations[i] || [];
8103
+ for (let j = 0; j < animations.length; ++j) {
8104
+ this.processAnimation(animations[j], input[i]);
8105
+ }
8106
+ }
7762
8107
  }
7763
- this._invokeAll(function(ext) {
8108
+ await this._invokeAllAsync(function(ext) {
7764
8109
  ext.afterParse && ext.afterParse(input);
7765
8110
  });
7766
8111
  }
7767
- _invokeAll(func) {
8112
+ async _invokeAllAsync(func) {
7768
8113
  for (let i = 0, il = this.plugins.length; i < il; i++) {
7769
- func(this.plugins[i]);
8114
+ await func(this.plugins[i]);
7770
8115
  }
7771
8116
  }
7772
8117
  };
@@ -7822,7 +8167,7 @@ var GLTFMaterialsUnlitExtension = class {
7822
8167
  this.writer = writer;
7823
8168
  this.name = "KHR_materials_unlit";
7824
8169
  }
7825
- writeMaterial(material, materialDef) {
8170
+ async writeMaterialAsync(material, materialDef) {
7826
8171
  if (!material.isMeshBasicMaterial) return;
7827
8172
  const writer = this.writer;
7828
8173
  const extensionsUsed = writer.extensionsUsed;
@@ -7838,7 +8183,7 @@ var GLTFMaterialsClearcoatExtension = class {
7838
8183
  this.writer = writer;
7839
8184
  this.name = "KHR_materials_clearcoat";
7840
8185
  }
7841
- writeMaterial(material, materialDef) {
8186
+ async writeMaterialAsync(material, materialDef) {
7842
8187
  if (!material.isMeshPhysicalMaterial || material.clearcoat === 0) return;
7843
8188
  const writer = this.writer;
7844
8189
  const extensionsUsed = writer.extensionsUsed;
@@ -7846,7 +8191,7 @@ var GLTFMaterialsClearcoatExtension = class {
7846
8191
  extensionDef.clearcoatFactor = material.clearcoat;
7847
8192
  if (material.clearcoatMap) {
7848
8193
  const clearcoatMapDef = {
7849
- index: writer.processTexture(material.clearcoatMap),
8194
+ index: await writer.processTextureAsync(material.clearcoatMap),
7850
8195
  texCoord: material.clearcoatMap.channel
7851
8196
  };
7852
8197
  writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
@@ -7855,7 +8200,7 @@ var GLTFMaterialsClearcoatExtension = class {
7855
8200
  extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
7856
8201
  if (material.clearcoatRoughnessMap) {
7857
8202
  const clearcoatRoughnessMapDef = {
7858
- index: writer.processTexture(material.clearcoatRoughnessMap),
8203
+ index: await writer.processTextureAsync(material.clearcoatRoughnessMap),
7859
8204
  texCoord: material.clearcoatRoughnessMap.channel
7860
8205
  };
7861
8206
  writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
@@ -7863,9 +8208,10 @@ var GLTFMaterialsClearcoatExtension = class {
7863
8208
  }
7864
8209
  if (material.clearcoatNormalMap) {
7865
8210
  const clearcoatNormalMapDef = {
7866
- index: writer.processTexture(material.clearcoatNormalMap),
8211
+ index: await writer.processTextureAsync(material.clearcoatNormalMap),
7867
8212
  texCoord: material.clearcoatNormalMap.channel
7868
8213
  };
8214
+ if (material.clearcoatNormalScale.x !== 1) clearcoatNormalMapDef.scale = material.clearcoatNormalScale.x;
7869
8215
  writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
7870
8216
  extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
7871
8217
  }
@@ -7874,12 +8220,28 @@ var GLTFMaterialsClearcoatExtension = class {
7874
8220
  extensionsUsed[this.name] = true;
7875
8221
  }
7876
8222
  };
8223
+ var GLTFMaterialsDispersionExtension = class {
8224
+ constructor(writer) {
8225
+ this.writer = writer;
8226
+ this.name = "KHR_materials_dispersion";
8227
+ }
8228
+ async writeMaterialAsync(material, materialDef) {
8229
+ if (!material.isMeshPhysicalMaterial || material.dispersion === 0) return;
8230
+ const writer = this.writer;
8231
+ const extensionsUsed = writer.extensionsUsed;
8232
+ const extensionDef = {};
8233
+ extensionDef.dispersion = material.dispersion;
8234
+ materialDef.extensions = materialDef.extensions || {};
8235
+ materialDef.extensions[this.name] = extensionDef;
8236
+ extensionsUsed[this.name] = true;
8237
+ }
8238
+ };
7877
8239
  var GLTFMaterialsIridescenceExtension = class {
7878
8240
  constructor(writer) {
7879
8241
  this.writer = writer;
7880
8242
  this.name = "KHR_materials_iridescence";
7881
8243
  }
7882
- writeMaterial(material, materialDef) {
8244
+ async writeMaterialAsync(material, materialDef) {
7883
8245
  if (!material.isMeshPhysicalMaterial || material.iridescence === 0) return;
7884
8246
  const writer = this.writer;
7885
8247
  const extensionsUsed = writer.extensionsUsed;
@@ -7887,7 +8249,7 @@ var GLTFMaterialsIridescenceExtension = class {
7887
8249
  extensionDef.iridescenceFactor = material.iridescence;
7888
8250
  if (material.iridescenceMap) {
7889
8251
  const iridescenceMapDef = {
7890
- index: writer.processTexture(material.iridescenceMap),
8252
+ index: await writer.processTextureAsync(material.iridescenceMap),
7891
8253
  texCoord: material.iridescenceMap.channel
7892
8254
  };
7893
8255
  writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
@@ -7898,7 +8260,7 @@ var GLTFMaterialsIridescenceExtension = class {
7898
8260
  extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
7899
8261
  if (material.iridescenceThicknessMap) {
7900
8262
  const iridescenceThicknessMapDef = {
7901
- index: writer.processTexture(material.iridescenceThicknessMap),
8263
+ index: await writer.processTextureAsync(material.iridescenceThicknessMap),
7902
8264
  texCoord: material.iridescenceThicknessMap.channel
7903
8265
  };
7904
8266
  writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
@@ -7914,7 +8276,7 @@ var GLTFMaterialsTransmissionExtension = class {
7914
8276
  this.writer = writer;
7915
8277
  this.name = "KHR_materials_transmission";
7916
8278
  }
7917
- writeMaterial(material, materialDef) {
8279
+ async writeMaterialAsync(material, materialDef) {
7918
8280
  if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7919
8281
  const writer = this.writer;
7920
8282
  const extensionsUsed = writer.extensionsUsed;
@@ -7922,7 +8284,7 @@ var GLTFMaterialsTransmissionExtension = class {
7922
8284
  extensionDef.transmissionFactor = material.transmission;
7923
8285
  if (material.transmissionMap) {
7924
8286
  const transmissionMapDef = {
7925
- index: writer.processTexture(material.transmissionMap),
8287
+ index: await writer.processTextureAsync(material.transmissionMap),
7926
8288
  texCoord: material.transmissionMap.channel
7927
8289
  };
7928
8290
  writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
@@ -7938,7 +8300,7 @@ var GLTFMaterialsVolumeExtension = class {
7938
8300
  this.writer = writer;
7939
8301
  this.name = "KHR_materials_volume";
7940
8302
  }
7941
- writeMaterial(material, materialDef) {
8303
+ async writeMaterialAsync(material, materialDef) {
7942
8304
  if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7943
8305
  const writer = this.writer;
7944
8306
  const extensionsUsed = writer.extensionsUsed;
@@ -7946,13 +8308,15 @@ var GLTFMaterialsVolumeExtension = class {
7946
8308
  extensionDef.thicknessFactor = material.thickness;
7947
8309
  if (material.thicknessMap) {
7948
8310
  const thicknessMapDef = {
7949
- index: writer.processTexture(material.thicknessMap),
8311
+ index: await writer.processTextureAsync(material.thicknessMap),
7950
8312
  texCoord: material.thicknessMap.channel
7951
8313
  };
7952
8314
  writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
7953
8315
  extensionDef.thicknessTexture = thicknessMapDef;
7954
8316
  }
7955
- extensionDef.attenuationDistance = material.attenuationDistance;
8317
+ if (material.attenuationDistance !== Infinity) {
8318
+ extensionDef.attenuationDistance = material.attenuationDistance;
8319
+ }
7956
8320
  extensionDef.attenuationColor = material.attenuationColor.toArray();
7957
8321
  materialDef.extensions = materialDef.extensions || {};
7958
8322
  materialDef.extensions[this.name] = extensionDef;
@@ -7964,7 +8328,7 @@ var GLTFMaterialsIorExtension = class {
7964
8328
  this.writer = writer;
7965
8329
  this.name = "KHR_materials_ior";
7966
8330
  }
7967
- writeMaterial(material, materialDef) {
8331
+ async writeMaterialAsync(material, materialDef) {
7968
8332
  if (!material.isMeshPhysicalMaterial || material.ior === 1.5) return;
7969
8333
  const writer = this.writer;
7970
8334
  const extensionsUsed = writer.extensionsUsed;
@@ -7980,14 +8344,14 @@ var GLTFMaterialsSpecularExtension = class {
7980
8344
  this.writer = writer;
7981
8345
  this.name = "KHR_materials_specular";
7982
8346
  }
7983
- writeMaterial(material, materialDef) {
7984
- if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorTexture) return;
8347
+ async writeMaterialAsync(material, materialDef) {
8348
+ if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorMap) return;
7985
8349
  const writer = this.writer;
7986
8350
  const extensionsUsed = writer.extensionsUsed;
7987
8351
  const extensionDef = {};
7988
8352
  if (material.specularIntensityMap) {
7989
8353
  const specularIntensityMapDef = {
7990
- index: writer.processTexture(material.specularIntensityMap),
8354
+ index: await writer.processTextureAsync(material.specularIntensityMap),
7991
8355
  texCoord: material.specularIntensityMap.channel
7992
8356
  };
7993
8357
  writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
@@ -7995,7 +8359,7 @@ var GLTFMaterialsSpecularExtension = class {
7995
8359
  }
7996
8360
  if (material.specularColorMap) {
7997
8361
  const specularColorMapDef = {
7998
- index: writer.processTexture(material.specularColorMap),
8362
+ index: await writer.processTextureAsync(material.specularColorMap),
7999
8363
  texCoord: material.specularColorMap.channel
8000
8364
  };
8001
8365
  writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
@@ -8013,14 +8377,14 @@ var GLTFMaterialsSheenExtension = class {
8013
8377
  this.writer = writer;
8014
8378
  this.name = "KHR_materials_sheen";
8015
8379
  }
8016
- writeMaterial(material, materialDef) {
8380
+ async writeMaterialAsync(material, materialDef) {
8017
8381
  if (!material.isMeshPhysicalMaterial || material.sheen == 0) return;
8018
8382
  const writer = this.writer;
8019
8383
  const extensionsUsed = writer.extensionsUsed;
8020
8384
  const extensionDef = {};
8021
8385
  if (material.sheenRoughnessMap) {
8022
8386
  const sheenRoughnessMapDef = {
8023
- index: writer.processTexture(material.sheenRoughnessMap),
8387
+ index: await writer.processTextureAsync(material.sheenRoughnessMap),
8024
8388
  texCoord: material.sheenRoughnessMap.channel
8025
8389
  };
8026
8390
  writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
@@ -8028,7 +8392,7 @@ var GLTFMaterialsSheenExtension = class {
8028
8392
  }
8029
8393
  if (material.sheenColorMap) {
8030
8394
  const sheenColorMapDef = {
8031
- index: writer.processTexture(material.sheenColorMap),
8395
+ index: await writer.processTextureAsync(material.sheenColorMap),
8032
8396
  texCoord: material.sheenColorMap.channel
8033
8397
  };
8034
8398
  writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
@@ -8046,13 +8410,13 @@ var GLTFMaterialsAnisotropyExtension = class {
8046
8410
  this.writer = writer;
8047
8411
  this.name = "KHR_materials_anisotropy";
8048
8412
  }
8049
- writeMaterial(material, materialDef) {
8413
+ async writeMaterialAsync(material, materialDef) {
8050
8414
  if (!material.isMeshPhysicalMaterial || material.anisotropy == 0) return;
8051
8415
  const writer = this.writer;
8052
8416
  const extensionsUsed = writer.extensionsUsed;
8053
8417
  const extensionDef = {};
8054
8418
  if (material.anisotropyMap) {
8055
- const anisotropyMapDef = { index: writer.processTexture(material.anisotropyMap) };
8419
+ const anisotropyMapDef = { index: await writer.processTextureAsync(material.anisotropyMap) };
8056
8420
  writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
8057
8421
  extensionDef.anisotropyTexture = anisotropyMapDef;
8058
8422
  }
@@ -8068,7 +8432,7 @@ var GLTFMaterialsEmissiveStrengthExtension = class {
8068
8432
  this.writer = writer;
8069
8433
  this.name = "KHR_materials_emissive_strength";
8070
8434
  }
8071
- writeMaterial(material, materialDef) {
8435
+ async writeMaterialAsync(material, materialDef) {
8072
8436
  if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1) return;
8073
8437
  const writer = this.writer;
8074
8438
  const extensionsUsed = writer.extensionsUsed;
@@ -8079,6 +8443,30 @@ var GLTFMaterialsEmissiveStrengthExtension = class {
8079
8443
  extensionsUsed[this.name] = true;
8080
8444
  }
8081
8445
  };
8446
+ var GLTFMaterialsBumpExtension = class {
8447
+ constructor(writer) {
8448
+ this.writer = writer;
8449
+ this.name = "EXT_materials_bump";
8450
+ }
8451
+ async writeMaterialAsync(material, materialDef) {
8452
+ if (!material.isMeshStandardMaterial || material.bumpScale === 1 && !material.bumpMap) return;
8453
+ const writer = this.writer;
8454
+ const extensionsUsed = writer.extensionsUsed;
8455
+ const extensionDef = {};
8456
+ if (material.bumpMap) {
8457
+ const bumpMapDef = {
8458
+ index: await writer.processTextureAsync(material.bumpMap),
8459
+ texCoord: material.bumpMap.channel
8460
+ };
8461
+ writer.applyTextureTransform(bumpMapDef, material.bumpMap);
8462
+ extensionDef.bumpTexture = bumpMapDef;
8463
+ }
8464
+ extensionDef.bumpFactor = material.bumpScale;
8465
+ materialDef.extensions = materialDef.extensions || {};
8466
+ materialDef.extensions[this.name] = extensionDef;
8467
+ extensionsUsed[this.name] = true;
8468
+ }
8469
+ };
8082
8470
  var GLTFMeshGpuInstancing = class {
8083
8471
  constructor(writer) {
8084
8472
  this.writer = writer;
@@ -8091,10 +8479,10 @@ var GLTFMeshGpuInstancing = class {
8091
8479
  const translationAttr = new Float32Array(mesh.count * 3);
8092
8480
  const rotationAttr = new Float32Array(mesh.count * 4);
8093
8481
  const scaleAttr = new Float32Array(mesh.count * 3);
8094
- const matrix = new import_three19.Matrix4();
8095
- const position = new import_three19.Vector3();
8096
- const quaternion = new import_three19.Quaternion();
8097
- const scale = new import_three19.Vector3();
8482
+ const matrix = new import_three18.Matrix4();
8483
+ const position = new import_three18.Vector3();
8484
+ const quaternion = new import_three18.Quaternion();
8485
+ const scale = new import_three18.Vector3();
8098
8486
  for (let i = 0; i < mesh.count; i++) {
8099
8487
  mesh.getMatrixAt(i, matrix);
8100
8488
  matrix.decompose(position, quaternion, scale);
@@ -8103,9 +8491,9 @@ var GLTFMeshGpuInstancing = class {
8103
8491
  scale.toArray(scaleAttr, i * 3);
8104
8492
  }
8105
8493
  const attributes = {
8106
- TRANSLATION: writer.processAccessor(new import_three19.BufferAttribute(translationAttr, 3)),
8107
- ROTATION: writer.processAccessor(new import_three19.BufferAttribute(rotationAttr, 4)),
8108
- SCALE: writer.processAccessor(new import_three19.BufferAttribute(scaleAttr, 3))
8494
+ TRANSLATION: writer.processAccessor(new import_three18.BufferAttribute(translationAttr, 3)),
8495
+ ROTATION: writer.processAccessor(new import_three18.BufferAttribute(rotationAttr, 4)),
8496
+ SCALE: writer.processAccessor(new import_three18.BufferAttribute(scaleAttr, 3))
8109
8497
  };
8110
8498
  if (mesh.instanceColor)
8111
8499
  attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
@@ -8170,8 +8558,8 @@ GLTFExporter.Utils = {
8170
8558
  const sourceTracks = clip.tracks;
8171
8559
  for (let i = 0; i < sourceTracks.length; ++i) {
8172
8560
  let sourceTrack = sourceTracks[i];
8173
- const sourceTrackBinding = import_three19.PropertyBinding.parseTrackName(sourceTrack.name);
8174
- const sourceTrackNode = import_three19.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
8561
+ const sourceTrackBinding = import_three18.PropertyBinding.parseTrackName(sourceTrack.name);
8562
+ const sourceTrackNode = import_three18.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
8175
8563
  if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
8176
8564
  tracks.push(sourceTrack);
8177
8565
  continue;
@@ -8182,7 +8570,7 @@ GLTFExporter.Utils = {
8182
8570
  }
8183
8571
  console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
8184
8572
  sourceTrack = sourceTrack.clone();
8185
- sourceTrack.setInterpolation(import_three19.InterpolateLinear);
8573
+ sourceTrack.setInterpolation(import_three18.InterpolateLinear);
8186
8574
  }
8187
8575
  const targetCount = sourceTrackNode.morphTargetInfluences.length;
8188
8576
  const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
@@ -8214,6 +8602,19 @@ GLTFExporter.Utils = {
8214
8602
  }
8215
8603
  clip.tracks = tracks;
8216
8604
  return clip;
8605
+ },
8606
+ toTypedBufferAttribute: function(srcAttribute, TypedArray) {
8607
+ const dstAttribute = new import_three18.BufferAttribute(new TypedArray(srcAttribute.count * srcAttribute.itemSize), srcAttribute.itemSize, false);
8608
+ if (!srcAttribute.normalized && !srcAttribute.isInterleavedBufferAttribute) {
8609
+ dstAttribute.array.set(srcAttribute.array);
8610
+ return dstAttribute;
8611
+ }
8612
+ for (let i = 0, il = srcAttribute.count; i < il; i++) {
8613
+ for (let j = 0; j < srcAttribute.itemSize; j++) {
8614
+ dstAttribute.setComponent(i, j, srcAttribute.getComponent(i, j));
8615
+ }
8616
+ }
8617
+ return dstAttribute;
8217
8618
  }
8218
8619
  };
8219
8620
 
@@ -8265,10 +8666,10 @@ var SceneExporter = class {
8265
8666
  }
8266
8667
  };
8267
8668
  function localMatrix(object) {
8268
- return object.matrixAutoUpdate ? new import_three20.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8669
+ return object.matrixAutoUpdate ? new import_three19.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8269
8670
  }
8270
8671
  function createSnapshot(root, gltf, bakeColors = false) {
8271
- const scene = new import_three20.Scene();
8672
+ const scene = new import_three19.Scene();
8272
8673
  const geometries = [];
8273
8674
  const materials = [];
8274
8675
  const textures = [];
@@ -8286,7 +8687,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8286
8687
  if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
8287
8688
  throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
8288
8689
  }
8289
- material = new import_three20.MeshBasicMaterial({
8690
+ material = new import_three19.MeshBasicMaterial({
8290
8691
  map: uniforms.map.value,
8291
8692
  vertexColors: source.vertexColors,
8292
8693
  transparent: source.transparent,
@@ -8296,7 +8697,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8296
8697
  });
8297
8698
  material.name = source.name;
8298
8699
  } else if (shader.isShaderMaterial) {
8299
- material = new import_three20.MeshBasicMaterial({ vertexColors: source.vertexColors });
8700
+ material = new import_three19.MeshBasicMaterial({ vertexColors: source.vertexColors });
8300
8701
  material.name = source.name;
8301
8702
  } else {
8302
8703
  const copySource = Object.create(source);
@@ -8350,11 +8751,11 @@ function createSnapshot(root, gltf, bakeColors = false) {
8350
8751
  const material = copyMaterial(sourceMaterial, geometry);
8351
8752
  if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
8352
8753
  if (bakeColors || instanceColor) {
8353
- const tint = (material.color ?? new import_three20.Color()).clone();
8754
+ const tint = (material.color ?? new import_three19.Color()).clone();
8354
8755
  if (instanceColor) tint.multiply(instanceColor);
8355
8756
  if (bakeColors) {
8356
8757
  const original = geometry.getAttribute("color");
8357
- const colors = new import_three20.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
8758
+ const colors = new import_three19.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
8358
8759
  for (let i = 0; i < colors.count; i++) {
8359
8760
  colors.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
8360
8761
  }
@@ -8363,7 +8764,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8363
8764
  material.color.copy(tint);
8364
8765
  }
8365
8766
  }
8366
- const copy = new import_three20.Mesh(geometry, material);
8767
+ const copy = new import_three19.Mesh(geometry, material);
8367
8768
  copy.name = mesh.name;
8368
8769
  copy.renderOrder = mesh.renderOrder;
8369
8770
  scene.add(copy);
@@ -8377,9 +8778,9 @@ function createSnapshot(root, gltf, bakeColors = false) {
8377
8778
  const instanced = mesh;
8378
8779
  if (instanced.isInstancedMesh) {
8379
8780
  for (let i = 0; i < instanced.count; i++) {
8380
- const matrix = new import_three20.Matrix4();
8781
+ const matrix = new import_three19.Matrix4();
8381
8782
  instanced.getMatrixAt(i, matrix);
8382
- const color = instanced.instanceColor ? new import_three20.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
8783
+ const color = instanced.instanceColor ? new import_three19.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
8383
8784
  addMesh(mesh, world.clone().multiply(matrix), color);
8384
8785
  }
8385
8786
  } else {
@@ -8391,7 +8792,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8391
8792
  try {
8392
8793
  const ancestors = [];
8393
8794
  for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
8394
- const world = new import_three20.Matrix4();
8795
+ const world = new import_three19.Matrix4();
8395
8796
  for (const ancestor of ancestors) {
8396
8797
  if (!ancestor.visible) return { scene, dispose };
8397
8798
  world.multiply(localMatrix(ancestor));
@@ -8405,7 +8806,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8405
8806
  }
8406
8807
  function selectAlphaMode(material, geometry) {
8407
8808
  const texture = material.map;
8408
- if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !== import_three20.RGBAFormat || texture.type !== import_three20.UnsignedByteType || texture.wrapS !== import_three20.ClampToEdgeWrapping || texture.wrapT !== import_three20.ClampToEdgeWrapping || texture.magFilter !== import_three20.NearestFilter || texture.minFilter !== import_three20.NearestFilter || texture.anisotropy > 1 || texture.offset.x !== 0 || texture.offset.y !== 0 || texture.repeat.x !== 1 || texture.repeat.y !== 1 || texture.rotation !== 0 || !texture.matrixAutoUpdate && !texture.matrix.elements.every((value, i) => value === (i % 4 === 0 ? 1 : 0))) return;
8809
+ if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !== import_three19.RGBAFormat || texture.type !== import_three19.UnsignedByteType || texture.wrapS !== import_three19.ClampToEdgeWrapping || texture.wrapT !== import_three19.ClampToEdgeWrapping || texture.magFilter !== import_three19.NearestFilter || texture.minFilter !== import_three19.NearestFilter || texture.anisotropy > 1 || texture.offset.x !== 0 || texture.offset.y !== 0 || texture.repeat.x !== 1 || texture.repeat.y !== 1 || texture.rotation !== 0 || !texture.matrixAutoUpdate && !texture.matrix.elements.every((value, i) => value === (i % 4 === 0 ? 1 : 0))) return;
8409
8810
  const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
8410
8811
  const colors = geometry.getAttribute("color");
8411
8812
  if (!uv || material.vertexColors && colors?.itemSize === 4) return;
@@ -8442,7 +8843,7 @@ function selectAlphaMode(material, geometry) {
8442
8843
  }
8443
8844
  function copyDataTexture(source) {
8444
8845
  const image = source.image;
8445
- if (source.format !== import_three20.RGBAFormat || source.type !== import_three20.UnsignedByteType) {
8846
+ if (!image.data || source.format !== import_three19.RGBAFormat || source.type !== import_three19.UnsignedByteType) {
8446
8847
  throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
8447
8848
  }
8448
8849
  const canvas = createCanvas(image.width, image.height);
@@ -8453,8 +8854,8 @@ function copyDataTexture(source) {
8453
8854
  context.putImageData(pixels, 0, 0);
8454
8855
  const copySource = Object.create(source);
8455
8856
  copySource.userData = {};
8456
- copySource.source = new import_three20.Source(canvas);
8457
- return new import_three20.Texture().copy(copySource);
8857
+ copySource.source = new import_three19.TextureSource(canvas);
8858
+ return new import_three19.Texture().copy(copySource);
8458
8859
  }
8459
8860
 
8460
8861
  // src/gui/GuiHelper.ts
@@ -8523,6 +8924,85 @@ var GuiHelper = class {
8523
8924
  }
8524
8925
  };
8525
8926
 
8927
+ // src/gui/GuiTextureGeometry.ts
8928
+ var import_three20 = require("three");
8929
+ function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop, scaling) {
8930
+ if (crop || !scaling || scaling.type === "stretch") {
8931
+ const [x, y, w, h] = crop ?? [0, 0, imageWidth, imageHeight];
8932
+ const geometry = new import_three20.PlaneGeometry(width, height);
8933
+ const uv = geometry.getAttribute("uv");
8934
+ for (let i = 0; i < uv.count; i++) {
8935
+ uv.setXY(
8936
+ i,
8937
+ (x + uv.getX(i) * w) / imageWidth,
8938
+ 1 - (y + (1 - uv.getY(i)) * h) / imageHeight
8939
+ );
8940
+ }
8941
+ return geometry;
8942
+ }
8943
+ const sw = scaling.width, sh = scaling.height;
8944
+ if (![sw, sh].every((value) => Number.isInteger(value) && value > 0)) {
8945
+ throw new Error("GUI sprite dimensions must be positive integers");
8946
+ }
8947
+ if (![width, height].every((value) => Number.isFinite(value) && value >= 0)) {
8948
+ throw new Error("GUI output dimensions must be finite and nonnegative");
8949
+ }
8950
+ const positions = [], uvs = [], normals = [], indices = [];
8951
+ function quad(x, y, w, h, u, v, uw, vh) {
8952
+ if (w <= 0 || h <= 0) return;
8953
+ const index = positions.length / 3;
8954
+ const left = x - width / 2, top = height / 2 - y;
8955
+ positions.push(left, top, 0, left + w, top, 0, left, top - h, 0, left + w, top - h, 0);
8956
+ uvs.push(
8957
+ u / sw,
8958
+ 1 - v / sh,
8959
+ (u + uw) / sw,
8960
+ 1 - v / sh,
8961
+ u / sw,
8962
+ 1 - (v + vh) / sh,
8963
+ (u + uw) / sw,
8964
+ 1 - (v + vh) / sh
8965
+ );
8966
+ normals.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1);
8967
+ indices.push(index, index + 2, index + 1, index + 2, index + 3, index + 1);
8968
+ }
8969
+ function tile(x, y, w, h, u, v, tw, th) {
8970
+ for (let dy = 0; dy < h; dy += th) {
8971
+ for (let dx = 0; dx < w; dx += tw) {
8972
+ const cw = Math.min(tw, w - dx), ch = Math.min(th, h - dy);
8973
+ quad(x + dx, y + dy, cw, ch, u, v, cw, ch);
8974
+ }
8975
+ }
8976
+ }
8977
+ if (scaling.type === "tile") {
8978
+ tile(0, 0, width, height, 0, 0, sw, sh);
8979
+ } else {
8980
+ let segments = function(size, sourceSize, start, end) {
8981
+ if (size === sourceSize) return [[0, size, 0, sourceSize]];
8982
+ start = Math.min(start, Math.floor(size / 2));
8983
+ end = Math.min(end, Math.floor(size / 2));
8984
+ return [
8985
+ [0, start, 0, start],
8986
+ [start, size - start - end, start, sourceSize - start - end],
8987
+ [size - end, end, sourceSize - end, end]
8988
+ ];
8989
+ };
8990
+ const border = typeof scaling.border === "number" ? { left: scaling.border, top: scaling.border, right: scaling.border, bottom: scaling.border } : scaling.border;
8991
+ if (!border || typeof scaling.border === "number" && scaling.border <= 0 || ![border.left, border.top, border.right, border.bottom].every((value) => Number.isInteger(value) && value >= 0) || border.left + border.right >= sw || border.top + border.bottom >= sh) {
8992
+ throw new Error("GUI nine-slice borders must be nonnegative integers with a nonempty center");
8993
+ }
8994
+ const columns = segments(width, sw, border.left, border.right);
8995
+ const rows = segments(height, sh, border.top, border.bottom);
8996
+ for (const [y, h, v, vh] of rows) {
8997
+ for (const [x, w, u, uw] of columns) {
8998
+ if (w <= 0 || h <= 0) continue;
8999
+ (scaling.stretch_inner ? quad : tile)(x, y, w, h, u, v, uw, vh);
9000
+ }
9001
+ }
9002
+ }
9003
+ return new import_three20.BufferGeometry().setAttribute("position", new import_three20.Float32BufferAttribute(positions, 3)).setAttribute("normal", new import_three20.Float32BufferAttribute(normals, 3)).setAttribute("uv", new import_three20.Float32BufferAttribute(uvs, 2)).setIndex(indices);
9004
+ }
9005
+
8526
9006
  // src/gui/scene/GuiObject.ts
8527
9007
  var import_three25 = require("three");
8528
9008
  init_AssetKey();
@@ -8574,18 +9054,10 @@ var GuiObject = class extends SceneObject {
8574
9054
  const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
8575
9055
  const material = await this.loadMaterial(key);
8576
9056
  const image = material.map.image;
8577
- const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
8578
- const [width, height] = layer.size ?? [cropWidth, cropHeight];
8579
- const geometry = new import_three25.PlaneGeometry(width, height);
9057
+ const scaling = layer.crop ? void 0 : (await ModelTextures.getMeta(key))?.gui?.scaling;
9058
+ const [width, height] = layer.size ?? (layer.crop ? layer.crop.slice(2) : scaling && scaling.type !== "stretch" ? [scaling.width, scaling.height] : [image.width, image.height]);
9059
+ const geometry = createGuiTextureGeometry(width, height, image.width, image.height, layer.crop, scaling);
8580
9060
  this.geometries.add(geometry);
8581
- const uv = geometry.getAttribute("uv");
8582
- for (let i = 0; i < uv.count; i++) {
8583
- uv.setXY(
8584
- i,
8585
- (cropX + uv.getX(i) * cropWidth) / image.width,
8586
- 1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
8587
- );
8588
- }
8589
9061
  const mesh = new import_three25.Mesh(geometry, material);
8590
9062
  mesh.name = `mesh:${layer.name ?? index}`;
8591
9063
  mesh.position.set(x + width / 2, -y - height / 2, depth);
@@ -9423,6 +9895,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9423
9895
  replacement.setMatrix(matrix);
9424
9896
  } else {
9425
9897
  replacement.matrix.copy(matrix);
9898
+ replacement.matrixWorldNeedsUpdate = true;
9426
9899
  matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
9427
9900
  replacement.matrixAutoUpdate = object.matrixAutoUpdate;
9428
9901
  replacement.visible = object.visible;
@@ -12576,12 +13049,13 @@ var _MineRenderScene = class _MineRenderScene extends import_three33.Scene {
12576
13049
  }
12577
13050
  updateObjectRegistration(object, attached) {
12578
13051
  if (this.observedObjects.has(object) === attached) return;
13052
+ const observable = object;
12579
13053
  if (attached) {
12580
13054
  this.observedObjects.add(object);
12581
- object.addEventListener("change", this.onObjectChange);
13055
+ observable.addEventListener("change", this.onObjectChange);
12582
13056
  } else {
12583
13057
  this.observedObjects.delete(object);
12584
- object.removeEventListener("change", this.onObjectChange);
13058
+ observable.removeEventListener("change", this.onObjectChange);
12585
13059
  }
12586
13060
  const change = attached ? 1 : -1;
12587
13061
  this.stats.objectCount += change;
@@ -13384,7 +13858,7 @@ var _Renderer = class _Renderer {
13384
13858
  });
13385
13859
  renderer.setClearColor(0, 0);
13386
13860
  renderer.shadowMap.enabled = true;
13387
- renderer.shadowMap.type = import_three35.PCFSoftShadowMap;
13861
+ renderer.shadowMap.type = import_three35.PCFShadowMap;
13388
13862
  renderer.outputColorSpace = import_three35.SRGBColorSpace;
13389
13863
  renderer.setPixelRatio(this.options.render.pixelRatio ?? 1);
13390
13864
  renderer.setSize(this.viewWidth, this.viewHeight);
@@ -14601,6 +15075,7 @@ var SectionMesh = class _SectionMesh extends import_three39.Group {
14601
15075
  texture?.dispose();
14602
15076
  }
14603
15077
  this.removeFromParent();
15078
+ super.dispose();
14604
15079
  }
14605
15080
  };
14606
15081