minerender 2.1.0-alpha.66 → 2.1.0-alpha.67

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);
@@ -4256,7 +4258,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
4256
4258
  const attributes = {};
4257
4259
  const morphAttributes = {};
4258
4260
  const morphTargetsRelative = geometries[0].morphTargetsRelative;
4259
- const mergedGeometry = new import_three21.BufferGeometry();
4261
+ const mergedGeometry = new import_three20.BufferGeometry();
4260
4262
  let offset = 0;
4261
4263
  for (let i = 0; i < geometries.length; ++i) {
4262
4264
  const geometry = geometries[i];
@@ -4380,7 +4382,7 @@ function mergeBufferAttributes(attributes) {
4380
4382
  array.set(attributes[i].array, offset);
4381
4383
  offset += attributes[i].array.length;
4382
4384
  }
4383
- return new import_three21.BufferAttribute(array, itemSize, normalized);
4385
+ return new import_three20.BufferAttribute(array, itemSize, normalized);
4384
4386
  }
4385
4387
  function interleaveAttributes(attributes) {
4386
4388
  let TypedArray;
@@ -4396,7 +4398,7 @@ function interleaveAttributes(attributes) {
4396
4398
  arrayLength += attribute.array.length;
4397
4399
  stride += attribute.itemSize;
4398
4400
  }
4399
- const interleavedBuffer = new import_three21.InterleavedBuffer(new TypedArray(arrayLength), stride);
4401
+ const interleavedBuffer = new import_three20.InterleavedBuffer(new TypedArray(arrayLength), stride);
4400
4402
  let offset = 0;
4401
4403
  const res = [];
4402
4404
  const getters = ["getX", "getY", "getZ", "getW"];
@@ -4405,7 +4407,7 @@ function interleaveAttributes(attributes) {
4405
4407
  const attribute = attributes[j];
4406
4408
  const itemSize = attribute.itemSize;
4407
4409
  const count = attribute.count;
4408
- const iba = new import_three21.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
4410
+ const iba = new import_three20.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
4409
4411
  res.push(iba);
4410
4412
  offset += itemSize;
4411
4413
  for (let c = 0; c < count; c++) {
@@ -4489,13 +4491,13 @@ function mergeVertices(geometry, tolerance = 1e-4) {
4489
4491
  const name = attributeNames[i];
4490
4492
  const oldAttribute = geometry.getAttribute(name);
4491
4493
  const buffer = new oldAttribute.array.constructor(attrArrays[name]);
4492
- const attribute = new import_three21.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
4494
+ const attribute = new import_three20.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
4493
4495
  result.setAttribute(name, attribute);
4494
4496
  if (name in morphAttrsArrays) {
4495
4497
  for (let j = 0; j < morphAttrsArrays[name].length; j++) {
4496
4498
  const oldMorphAttribute = geometry.morphAttributes[name][j];
4497
4499
  const buffer2 = new oldMorphAttribute.array.constructor(morphAttrsArrays[name][j]);
4498
- const morphAttribute = new import_three21.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
4500
+ const morphAttribute = new import_three20.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
4499
4501
  result.morphAttributes[name][j] = morphAttribute;
4500
4502
  }
4501
4503
  }
@@ -4504,11 +4506,11 @@ function mergeVertices(geometry, tolerance = 1e-4) {
4504
4506
  return result;
4505
4507
  }
4506
4508
  function toTrianglesDrawMode(geometry, drawMode) {
4507
- if (drawMode === import_three21.TrianglesDrawMode) {
4509
+ if (drawMode === import_three20.TrianglesDrawMode) {
4508
4510
  console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
4509
4511
  return geometry;
4510
4512
  }
4511
- if (drawMode === import_three21.TriangleFanDrawMode || drawMode === import_three21.TriangleStripDrawMode) {
4513
+ if (drawMode === import_three20.TriangleFanDrawMode || drawMode === import_three20.TriangleStripDrawMode) {
4512
4514
  let index = geometry.getIndex();
4513
4515
  if (index === null) {
4514
4516
  const indices = [];
@@ -4526,7 +4528,7 @@ function toTrianglesDrawMode(geometry, drawMode) {
4526
4528
  }
4527
4529
  const numberOfTriangles = index.count - 2;
4528
4530
  const newIndices = [];
4529
- if (drawMode === import_three21.TriangleFanDrawMode) {
4531
+ if (drawMode === import_three20.TriangleFanDrawMode) {
4530
4532
  for (let i = 1; i <= numberOfTriangles; i++) {
4531
4533
  newIndices.push(index.getX(0));
4532
4534
  newIndices.push(index.getX(i));
@@ -4562,15 +4564,15 @@ function computeMorphedAttributes(object) {
4562
4564
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
4563
4565
  return null;
4564
4566
  }
4565
- const _vA = new import_three21.Vector3();
4566
- const _vB = new import_three21.Vector3();
4567
- const _vC = new import_three21.Vector3();
4568
- const _tempA = new import_three21.Vector3();
4569
- const _tempB = new import_three21.Vector3();
4570
- const _tempC = new import_three21.Vector3();
4571
- const _morphA = new import_three21.Vector3();
4572
- const _morphB = new import_three21.Vector3();
4573
- const _morphC = new import_three21.Vector3();
4567
+ const _vA = new import_three20.Vector3();
4568
+ const _vB = new import_three20.Vector3();
4569
+ const _vC = new import_three20.Vector3();
4570
+ const _tempA = new import_three20.Vector3();
4571
+ const _tempB = new import_three20.Vector3();
4572
+ const _tempC = new import_three20.Vector3();
4573
+ const _morphA = new import_three20.Vector3();
4574
+ const _morphB = new import_three20.Vector3();
4575
+ const _morphC = new import_three20.Vector3();
4574
4576
  function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4575
4577
  _vA.fromBufferAttribute(attribute, a2);
4576
4578
  _vB.fromBufferAttribute(attribute, b2);
@@ -4765,8 +4767,8 @@ function computeMorphedAttributes(object) {
4765
4767
  }
4766
4768
  }
4767
4769
  }
4768
- const morphedPositionAttribute = new import_three21.Float32BufferAttribute(modifiedPosition, 3);
4769
- const morphedNormalAttribute = new import_three21.Float32BufferAttribute(modifiedNormal, 3);
4770
+ const morphedPositionAttribute = new import_three20.Float32BufferAttribute(modifiedPosition, 3);
4771
+ const morphedNormalAttribute = new import_three20.Float32BufferAttribute(modifiedNormal, 3);
4770
4772
  return {
4771
4773
  positionAttribute,
4772
4774
  normalAttribute,
@@ -4774,24 +4776,24 @@ function computeMorphedAttributes(object) {
4774
4776
  morphedNormalAttribute
4775
4777
  };
4776
4778
  }
4777
- var import_three21;
4779
+ var import_three20;
4778
4780
  var init_BufferGeometryUtils = __esm({
4779
4781
  "src/three/BufferGeometryUtils.js"() {
4780
- import_three21 = require("three");
4782
+ import_three20 = require("three");
4781
4783
  }
4782
4784
  });
4783
4785
 
4784
4786
  // src/model/ModelCulling.ts
4785
- var import_three22, ModelCulling;
4787
+ var import_three21, ModelCulling;
4786
4788
  var init_ModelCulling = __esm({
4787
4789
  "src/model/ModelCulling.ts"() {
4788
- import_three22 = require("three");
4790
+ import_three21 = require("three");
4789
4791
  init_CubeFace();
4790
4792
  ModelCulling = class {
4791
4793
  static toLocalMask(worldMask, rotation) {
4792
4794
  let localMask = 0;
4793
4795
  for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
4794
- const normal = new import_three22.Vector3(...offset).applyEuler(rotation);
4796
+ const normal = new import_three21.Vector3(...offset).applyEuler(rotation);
4795
4797
  const worldFace = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
4796
4798
  if (worldFace < 0) return 0;
4797
4799
  if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
@@ -4824,10 +4826,10 @@ var init_ModelCulling = __esm({
4824
4826
  });
4825
4827
 
4826
4828
  // src/model/SpecialItems.ts
4827
- var import_three23, SpecialItems;
4829
+ var import_three22, SpecialItems;
4828
4830
  var init_SpecialItems = __esm({
4829
4831
  "src/model/SpecialItems.ts"() {
4830
- import_three23 = require("three");
4832
+ import_three22 = require("three");
4831
4833
  init_AssetKey();
4832
4834
  init_Entities();
4833
4835
  SpecialItems = class {
@@ -4855,7 +4857,7 @@ var init_SpecialItems = __esm({
4855
4857
  case "minecraft:chest":
4856
4858
  case "chest": {
4857
4859
  const angle = -(special.openness ?? 0) * Math.PI / 2;
4858
- const chest = await load("chest", texture(special.texture, "chest"), new import_three23.Matrix4(), {
4860
+ const chest = await load("chest", texture(special.texture, "chest"), new import_three22.Matrix4(), {
4859
4861
  lid: [angle, 0, 0],
4860
4862
  lock: [angle, 0, 0]
4861
4863
  });
@@ -4864,11 +4866,11 @@ var init_SpecialItems = __esm({
4864
4866
  }
4865
4867
  case "minecraft:bed":
4866
4868
  case "bed": {
4867
- const transform = new import_three23.Matrix4().makeTranslation(0, 9, 0).multiply(new import_three23.Matrix4().makeRotationX(Math.PI / 2)).multiply(new import_three23.Matrix4().makeTranslation(8, 8, 8)).multiply(new import_three23.Matrix4().makeRotationZ(Math.PI)).multiply(new import_three23.Matrix4().makeTranslation(-8, -8, -8));
4869
+ const transform = new import_three22.Matrix4().makeTranslation(0, 9, 0).multiply(new import_three22.Matrix4().makeRotationX(Math.PI / 2)).multiply(new import_three22.Matrix4().makeTranslation(8, 8, 8)).multiply(new import_three22.Matrix4().makeRotationZ(Math.PI)).multiply(new import_three22.Matrix4().makeTranslation(-8, -8, -8));
4868
4870
  const key = texture(special.texture, "bed");
4869
4871
  return Promise.all([
4870
4872
  load("bed_head", key, transform),
4871
- load("bed_foot", key, new import_three23.Matrix4().makeTranslation(0, 0, -16).multiply(transform))
4873
+ load("bed_foot", key, new import_three22.Matrix4().makeTranslation(0, 0, -16).multiply(transform))
4872
4874
  ]);
4873
4875
  }
4874
4876
  case "minecraft:head":
@@ -4893,7 +4895,7 @@ var init_SpecialItems = __esm({
4893
4895
  return [await load(
4894
4896
  id,
4895
4897
  special.texture ? texture(special.texture, "") : void 0,
4896
- new import_three23.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three23.Matrix4().makeScale(-1, -1, 1)),
4898
+ new import_three22.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three22.Matrix4().makeScale(-1, -1, 1)),
4897
4899
  rotations
4898
4900
  )];
4899
4901
  }
@@ -5021,13 +5023,13 @@ var init_ItemTints = __esm({
5021
5023
  function isModelObject(obj) {
5022
5024
  return obj.isModelObject;
5023
5025
  }
5024
- var import_three24, import_ts_deepmerge5, p7, _ModelObject, ModelObject;
5026
+ var import_three23, import_ts_deepmerge5, p7, _ModelObject, ModelObject;
5025
5027
  var init_ModelObject = __esm({
5026
5028
  "src/model/scene/ModelObject.ts"() {
5027
5029
  init_SceneObject();
5028
5030
  init_Materials();
5029
5031
  init_UVMapper();
5030
- import_three24 = require("three");
5032
+ import_three23 = require("three");
5031
5033
  init_BufferGeometryUtils();
5032
5034
  init_model();
5033
5035
  import_ts_deepmerge5 = __toESM(require_dist());
@@ -5059,12 +5061,13 @@ var init_ModelObject = __esm({
5059
5061
  const special = this.originalModel.special;
5060
5062
  if (special) {
5061
5063
  const parts = await SpecialItems.getParts(special, this.originalModel.key?.root);
5062
- const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new import_three24.Matrix4();
5063
- transform.multiply(new import_three24.Matrix4().makeTranslation(-8, -8, -8));
5064
+ const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new import_three23.Matrix4();
5065
+ transform.multiply(new import_three23.Matrix4().makeTranslation(-8, -8, -8));
5064
5066
  try {
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();
@@ -5122,7 +5125,7 @@ var init_ModelObject = __esm({
5122
5125
  elGeo.clearGroups();
5123
5126
  }
5124
5127
  if (this.options.uvLockRotation) {
5125
- UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three24.Euler(...this.options.uvLockRotation));
5128
+ UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three23.Euler(...this.options.uvLockRotation));
5126
5129
  }
5127
5130
  if (this.options.tints) {
5128
5131
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
@@ -5131,19 +5134,19 @@ var init_ModelObject = __esm({
5131
5134
  if (tintIndex === void 0 || tintIndex < 0) continue;
5132
5135
  const tint = this.options.tints[tintIndex];
5133
5136
  if (tint === void 0) continue;
5134
- const color = new import_three24.Color(tint);
5137
+ const color = new import_three23.Color(tint);
5135
5138
  for (let vertex = 0; vertex < 4; vertex++) {
5136
5139
  color.toArray(colors, (faceIndex * 4 + vertex) * 3);
5137
5140
  }
5138
5141
  }
5139
- elGeo.setAttribute("color", new import_three24.BufferAttribute(colors, 3));
5142
+ elGeo.setAttribute("color", new import_three23.BufferAttribute(colors, 3));
5140
5143
  }
5141
- elGeo.applyMatrix4(new import_three24.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
5142
- elGeo.applyMatrix4(new import_three24.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
5144
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
5145
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
5143
5146
  if (el.rotation) {
5144
5147
  applyElementRotation(el.rotation, elGeo);
5145
5148
  }
5146
- elGeo.applyMatrix4(new import_three24.Matrix4().makeTranslation(-8, -8, -8));
5149
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation(-8, -8, -8));
5147
5150
  if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
5148
5151
  if (this.options.mergeMeshes) {
5149
5152
  allGeos.push(elGeo);
@@ -5165,7 +5168,7 @@ var init_ModelObject = __esm({
5165
5168
  if (allGeos.length > 0) {
5166
5169
  combinedGeo = mergeBufferGeometries(allGeos);
5167
5170
  } else {
5168
- combinedGeo = new import_three24.BoxGeometry(16, 16, 16);
5171
+ combinedGeo = new import_three23.BoxGeometry(16, 16, 16);
5169
5172
  if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
5170
5173
  }
5171
5174
  combinedGeo.computeBoundingBox();
@@ -5277,7 +5280,7 @@ function ownHeight(sample) {
5277
5280
  return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
5278
5281
  }
5279
5282
  function createFluidGeometry(kind, sample) {
5280
- const geometry = new import_three29.BufferGeometry();
5283
+ const geometry = new import_three28.BufferGeometry();
5281
5284
  const positions = [], normals = [], uvs = [], indices = [];
5282
5285
  const self = sample(0, 0, 0);
5283
5286
  const height = (x, z) => {
@@ -5376,16 +5379,16 @@ function createFluidGeometry(kind, sample) {
5376
5379
  1
5377
5380
  );
5378
5381
  }
5379
- geometry.setAttribute("position", new import_three29.Float32BufferAttribute(positions, 3));
5380
- geometry.setAttribute("normal", new import_three29.Float32BufferAttribute(normals, 3));
5381
- geometry.setAttribute("uv", new import_three29.Float32BufferAttribute(uvs, 2));
5382
+ geometry.setAttribute("position", new import_three28.Float32BufferAttribute(positions, 3));
5383
+ geometry.setAttribute("normal", new import_three28.Float32BufferAttribute(normals, 3));
5384
+ geometry.setAttribute("uv", new import_three28.Float32BufferAttribute(uvs, 2));
5382
5385
  geometry.setIndex(indices);
5383
5386
  return geometry;
5384
5387
  }
5385
- var import_three29, fluidRules, HORIZONTAL, EPSILON;
5388
+ var import_three28, fluidRules, HORIZONTAL, EPSILON;
5386
5389
  var init_FluidGeometry = __esm({
5387
5390
  "src/model/fluid/FluidGeometry.ts"() {
5388
- import_three29 = require("three");
5391
+ import_three28 = require("three");
5389
5392
  init_fluidBlocks();
5390
5393
  fluidRules = fluidBlocks_default;
5391
5394
  HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]];
@@ -5414,10 +5417,10 @@ function sampleFluid(kind, sample) {
5414
5417
  }
5415
5418
  return { key: key.join(""), sample: (x, y, z) => cells[(y + 1) * 9 + (z + 1) * 3 + x + 1] };
5416
5419
  }
5417
- var import_three30, FluidModelObject;
5420
+ var import_three29, FluidModelObject;
5418
5421
  var init_FluidModelObject = __esm({
5419
5422
  "src/model/fluid/FluidModelObject.ts"() {
5420
- import_three30 = require("three");
5423
+ import_three29 = require("three");
5421
5424
  init_AssetKey();
5422
5425
  init_Materials();
5423
5426
  init_ModelObject();
@@ -5450,10 +5453,10 @@ var init_FluidModelObject = __esm({
5450
5453
  }
5451
5454
  }
5452
5455
  geometry.clearGroups();
5453
- const color = new import_three30.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
5456
+ const color = new import_three29.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
5454
5457
  const colors = new Float32Array(geometry.getAttribute("position").count * 3);
5455
5458
  for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
5456
- geometry.setAttribute("color", new import_three30.BufferAttribute(colors, 3));
5459
+ geometry.setAttribute("color", new import_three29.BufferAttribute(colors, 3));
5457
5460
  geometry.computeBoundingBox();
5458
5461
  geometry.computeBoundingSphere();
5459
5462
  if (this.options.instanceMeshes) {
@@ -5467,7 +5470,7 @@ var init_FluidModelObject = __esm({
5467
5470
  super.applyTextures();
5468
5471
  this.iterateAllMeshes((mesh) => {
5469
5472
  const material = mesh.material;
5470
- material.side = import_three30.DoubleSide;
5473
+ material.side = import_three29.DoubleSide;
5471
5474
  material.forceSinglePass = true;
5472
5475
  material.depthWrite = !material.transparent;
5473
5476
  });
@@ -5954,11 +5957,19 @@ init_EntityObject();
5954
5957
  init_MineRenderError();
5955
5958
 
5956
5959
  // src/export/SceneExporter.ts
5957
- var import_three20 = require("three");
5960
+ var import_three19 = require("three");
5958
5961
 
5959
5962
  // ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
5960
5963
  var import_three16 = require("three");
5961
5964
  var OBJExporter = class {
5965
+ /**
5966
+ * Parses the given 3D object and generates the OBJ output.
5967
+ *
5968
+ * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
5969
+ *
5970
+ * @param {Object3D} object - The 3D object to export.
5971
+ * @return {string} The exported OBJ.
5972
+ */
5962
5973
  parse(object) {
5963
5974
  let output = "";
5964
5975
  let indexVertex = 0;
@@ -6064,7 +6075,8 @@ var OBJExporter = class {
6064
6075
  vertex.applyMatrix4(points.matrixWorld);
6065
6076
  output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
6066
6077
  if (colors !== void 0) {
6067
- color.fromBufferAttribute(colors, i).convertLinearToSRGB();
6078
+ color.fromBufferAttribute(colors, i);
6079
+ import_three16.ColorManagement.workingToColorSpace(color, import_three16.SRGBColorSpace);
6068
6080
  output += " " + color.r + " " + color.g + " " + color.b;
6069
6081
  }
6070
6082
  output += "\n";
@@ -6095,6 +6107,16 @@ var OBJExporter = class {
6095
6107
  // ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
6096
6108
  var import_three17 = require("three");
6097
6109
  var PLYExporter = class {
6110
+ /**
6111
+ * Parses the given 3D object and generates the PLY output.
6112
+ *
6113
+ * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
6114
+ *
6115
+ * @param {Object3D} object - The 3D object to export.
6116
+ * @param {PLYExporter~OnDone} onDone - A callback function that is executed when the export has finished.
6117
+ * @param {PLYExporter~Options} options - The export options.
6118
+ * @return {?(string|ArrayBuffer)} The exported PLY.
6119
+ */
6098
6120
  parse(object, onDone, options = {}) {
6099
6121
  function traverseMeshes(cb) {
6100
6122
  object.traverse(function(child) {
@@ -6111,14 +6133,23 @@ var PLYExporter = class {
6111
6133
  binary: false,
6112
6134
  excludeAttributes: [],
6113
6135
  // normal, uv, color, index
6114
- littleEndian: false
6136
+ littleEndian: false,
6137
+ customPropertyMapping: {}
6115
6138
  };
6116
6139
  options = Object.assign(defaultOptions, options);
6117
6140
  const excludeAttributes = options.excludeAttributes;
6141
+ const customPropertyMapping = options.customPropertyMapping;
6142
+ const customAttributeNames = Object.keys(customPropertyMapping);
6118
6143
  let includeIndices = true;
6119
6144
  let includeNormals = false;
6120
6145
  let includeColors = false;
6121
6146
  let includeUVs = false;
6147
+ let positionType = "float";
6148
+ let normalType = "float";
6149
+ let uvType = "float";
6150
+ let colorType = "uchar";
6151
+ const customTypes = {};
6152
+ for (const name of customAttributeNames) customTypes[name] = "float";
6122
6153
  let vertexCount = 0;
6123
6154
  let faceCount = 0;
6124
6155
  object.traverse(function(child) {
@@ -6135,9 +6166,23 @@ var PLYExporter = class {
6135
6166
  }
6136
6167
  vertexCount += vertices.count;
6137
6168
  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;
6169
+ positionType = getPlyType(vertices.array);
6170
+ if (normals !== void 0) {
6171
+ includeNormals = true;
6172
+ normalType = getPlyType(normals.array);
6173
+ }
6174
+ if (uvs !== void 0) {
6175
+ includeUVs = true;
6176
+ uvType = getPlyType(uvs.array);
6177
+ }
6178
+ if (colors !== void 0) {
6179
+ includeColors = true;
6180
+ colorType = getPlyType(colors.array);
6181
+ }
6182
+ for (const name of customAttributeNames) {
6183
+ const attr = geometry.getAttribute(name);
6184
+ if (attr !== void 0) customTypes[name] = getPlyType(attr.array);
6185
+ }
6141
6186
  } else if (child.isPoints) {
6142
6187
  const mesh = child;
6143
6188
  const geometry = mesh.geometry;
@@ -6145,8 +6190,19 @@ var PLYExporter = class {
6145
6190
  const normals = geometry.getAttribute("normal");
6146
6191
  const colors = geometry.getAttribute("color");
6147
6192
  vertexCount += vertices.count;
6148
- if (normals !== void 0) includeNormals = true;
6149
- if (colors !== void 0) includeColors = true;
6193
+ positionType = getPlyType(vertices.array);
6194
+ if (normals !== void 0) {
6195
+ includeNormals = true;
6196
+ normalType = getPlyType(normals.array);
6197
+ }
6198
+ if (colors !== void 0) {
6199
+ includeColors = true;
6200
+ colorType = getPlyType(colors.array);
6201
+ }
6202
+ for (const name of customAttributeNames) {
6203
+ const attr = geometry.getAttribute(name);
6204
+ if (attr !== void 0) customTypes[name] = getPlyType(attr.array);
6205
+ }
6150
6206
  includeIndices = false;
6151
6207
  }
6152
6208
  });
@@ -6165,18 +6221,33 @@ var PLYExporter = class {
6165
6221
  let header = `ply
6166
6222
  format ${options.binary ? options.littleEndian ? "binary_little_endian" : "binary_big_endian" : "ascii"} 1.0
6167
6223
  element vertex ${vertexCount}
6168
- property float x
6169
- property float y
6170
- property float z
6224
+ property ${positionType} x
6225
+ property ${positionType} y
6226
+ property ${positionType} z
6171
6227
  `;
6172
6228
  if (includeNormals === true) {
6173
- header += "property float nx\nproperty float ny\nproperty float nz\n";
6229
+ header += `property ${normalType} nx
6230
+ property ${normalType} ny
6231
+ property ${normalType} nz
6232
+ `;
6174
6233
  }
6175
6234
  if (includeUVs === true) {
6176
- header += "property float s\nproperty float t\n";
6235
+ header += `property ${uvType} s
6236
+ property ${uvType} t
6237
+ `;
6177
6238
  }
6178
6239
  if (includeColors === true) {
6179
- header += "property uchar red\nproperty uchar green\nproperty uchar blue\n";
6240
+ header += `property ${colorType} red
6241
+ property ${colorType} green
6242
+ property ${colorType} blue
6243
+ `;
6244
+ }
6245
+ for (const name of customAttributeNames) {
6246
+ const type = customTypes[name];
6247
+ for (const propName of customPropertyMapping[name]) {
6248
+ header += `property ${type} ${propName}
6249
+ `;
6250
+ }
6180
6251
  }
6181
6252
  if (includeIndices === true) {
6182
6253
  header += `element face ${faceCount}
@@ -6189,7 +6260,23 @@ property list uchar int vertex_index
6189
6260
  let result = null;
6190
6261
  if (options.binary === true) {
6191
6262
  const headerBin = new TextEncoder().encode(header);
6192
- const vertexListLength = vertexCount * (4 * 3 + (includeNormals ? 4 * 3 : 0) + (includeColors ? 3 : 0) + (includeUVs ? 4 * 2 : 0));
6263
+ const posWriter = getBinaryWriter(positionType);
6264
+ const normalWriter = includeNormals ? getBinaryWriter(normalType) : null;
6265
+ const uvWriter = includeUVs ? getBinaryWriter(uvType) : null;
6266
+ const colorWriter = includeColors ? getBinaryWriter(colorType) : null;
6267
+ const colorIsFloat = isFloatType(colorType);
6268
+ const colorScale = getColorScale(colorType);
6269
+ const customWriters = {};
6270
+ const customIsFloat = {};
6271
+ let customStride = 0;
6272
+ for (const name of customAttributeNames) {
6273
+ const type = customTypes[name];
6274
+ const writer = getBinaryWriter(type);
6275
+ customWriters[name] = writer;
6276
+ customIsFloat[name] = isFloatType(type);
6277
+ customStride += customPropertyMapping[name].length * writer.size;
6278
+ }
6279
+ const vertexListLength = vertexCount * (3 * posWriter.size + (includeNormals ? 3 * normalWriter.size : 0) + (includeUVs ? 2 * uvWriter.size : 0) + (includeColors ? 3 * colorWriter.size : 0) + customStride);
6193
6280
  const faceListLength = includeIndices ? faceCount * (indexByteCount * 3 + 1) : 0;
6194
6281
  const output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
6195
6282
  new Uint8Array(output.buffer).set(headerBin, 0);
@@ -6206,60 +6293,76 @@ property list uchar int vertex_index
6206
6293
  for (let i = 0, l = vertices.count; i < l; i++) {
6207
6294
  vertex.fromBufferAttribute(vertices, i);
6208
6295
  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;
6296
+ posWriter.write(output, vOffset, vertex.x, options.littleEndian);
6297
+ vOffset += posWriter.size;
6298
+ posWriter.write(output, vOffset, vertex.y, options.littleEndian);
6299
+ vOffset += posWriter.size;
6300
+ posWriter.write(output, vOffset, vertex.z, options.littleEndian);
6301
+ vOffset += posWriter.size;
6215
6302
  if (includeNormals === true) {
6216
6303
  if (normals != null) {
6217
6304
  vertex.fromBufferAttribute(normals, i);
6218
6305
  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;
6306
+ normalWriter.write(output, vOffset, vertex.x, options.littleEndian);
6307
+ vOffset += normalWriter.size;
6308
+ normalWriter.write(output, vOffset, vertex.y, options.littleEndian);
6309
+ vOffset += normalWriter.size;
6310
+ normalWriter.write(output, vOffset, vertex.z, options.littleEndian);
6311
+ vOffset += normalWriter.size;
6225
6312
  } 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;
6313
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6314
+ vOffset += normalWriter.size;
6315
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6316
+ vOffset += normalWriter.size;
6317
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6318
+ vOffset += normalWriter.size;
6232
6319
  }
6233
6320
  }
6234
6321
  if (includeUVs === true) {
6235
6322
  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;
6323
+ uvWriter.write(output, vOffset, uvs.getX(i), options.littleEndian);
6324
+ vOffset += uvWriter.size;
6325
+ uvWriter.write(output, vOffset, uvs.getY(i), options.littleEndian);
6326
+ vOffset += uvWriter.size;
6240
6327
  } else {
6241
- output.setFloat32(vOffset, 0, options.littleEndian);
6242
- vOffset += 4;
6243
- output.setFloat32(vOffset, 0, options.littleEndian);
6244
- vOffset += 4;
6328
+ uvWriter.write(output, vOffset, 0, options.littleEndian);
6329
+ vOffset += uvWriter.size;
6330
+ uvWriter.write(output, vOffset, 0, options.littleEndian);
6331
+ vOffset += uvWriter.size;
6245
6332
  }
6246
6333
  }
6247
6334
  if (includeColors === true) {
6248
6335
  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;
6336
+ tempColor.fromBufferAttribute(colors, i);
6337
+ import_three17.ColorManagement.workingToColorSpace(tempColor, import_three17.SRGBColorSpace);
6338
+ const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
6339
+ const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
6340
+ const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
6341
+ colorWriter.write(output, vOffset, r, options.littleEndian);
6342
+ vOffset += colorWriter.size;
6343
+ colorWriter.write(output, vOffset, g, options.littleEndian);
6344
+ vOffset += colorWriter.size;
6345
+ colorWriter.write(output, vOffset, b, options.littleEndian);
6346
+ vOffset += colorWriter.size;
6256
6347
  } 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;
6348
+ const white = colorIsFloat ? 1 : colorScale;
6349
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6350
+ vOffset += colorWriter.size;
6351
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6352
+ vOffset += colorWriter.size;
6353
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6354
+ vOffset += colorWriter.size;
6355
+ }
6356
+ }
6357
+ for (const name of customAttributeNames) {
6358
+ const writer = customWriters[name];
6359
+ const propCount = customPropertyMapping[name].length;
6360
+ const attr = geometry.getAttribute(name);
6361
+ const isFloat = customIsFloat[name];
6362
+ for (let c = 0; c < propCount; c++) {
6363
+ const raw = attr != null ? getAttributeComponent(attr, i, c) : 0;
6364
+ writer.write(output, vOffset, isFloat ? raw : Math.round(raw), options.littleEndian);
6365
+ vOffset += writer.size;
6263
6366
  }
6264
6367
  }
6265
6368
  }
@@ -6295,6 +6398,14 @@ property list uchar int vertex_index
6295
6398
  let writtenVertices = 0;
6296
6399
  let vertexList = "";
6297
6400
  let faceList = "";
6401
+ const positionIsFloat = isFloatType(positionType);
6402
+ const normalIsFloat = isFloatType(normalType);
6403
+ const uvIsFloat = isFloatType(uvType);
6404
+ const colorIsFloat = isFloatType(colorType);
6405
+ const colorScale = getColorScale(colorType);
6406
+ const customIsFloat = {};
6407
+ for (const name of customAttributeNames) customIsFloat[name] = isFloatType(customTypes[name]);
6408
+ const encode = (v, isFloat) => isFloat ? v : Math.round(v);
6298
6409
  traverseMeshes(function(mesh, geometry) {
6299
6410
  const vertices = geometry.getAttribute("position");
6300
6411
  const normals = geometry.getAttribute("normal");
@@ -6305,29 +6416,43 @@ property list uchar int vertex_index
6305
6416
  for (let i = 0, l = vertices.count; i < l; i++) {
6306
6417
  vertex.fromBufferAttribute(vertices, i);
6307
6418
  vertex.applyMatrix4(mesh.matrixWorld);
6308
- let line = vertex.x + " " + vertex.y + " " + vertex.z;
6419
+ let line = encode(vertex.x, positionIsFloat) + " " + encode(vertex.y, positionIsFloat) + " " + encode(vertex.z, positionIsFloat);
6309
6420
  if (includeNormals === true) {
6310
6421
  if (normals != null) {
6311
6422
  vertex.fromBufferAttribute(normals, i);
6312
6423
  vertex.applyMatrix3(normalMatrixWorld).normalize();
6313
- line += " " + vertex.x + " " + vertex.y + " " + vertex.z;
6424
+ line += " " + encode(vertex.x, normalIsFloat) + " " + encode(vertex.y, normalIsFloat) + " " + encode(vertex.z, normalIsFloat);
6314
6425
  } else {
6315
6426
  line += " 0 0 0";
6316
6427
  }
6317
6428
  }
6318
6429
  if (includeUVs === true) {
6319
6430
  if (uvs != null) {
6320
- line += " " + uvs.getX(i) + " " + uvs.getY(i);
6431
+ line += " " + encode(uvs.getX(i), uvIsFloat) + " " + encode(uvs.getY(i), uvIsFloat);
6321
6432
  } else {
6322
6433
  line += " 0 0";
6323
6434
  }
6324
6435
  }
6325
6436
  if (includeColors === true) {
6326
6437
  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);
6438
+ tempColor.fromBufferAttribute(colors, i);
6439
+ import_three17.ColorManagement.workingToColorSpace(tempColor, import_three17.SRGBColorSpace);
6440
+ const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
6441
+ const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
6442
+ const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
6443
+ line += ` ${r} ${g} ${b}`;
6329
6444
  } else {
6330
- line += " 255 255 255";
6445
+ const white = colorIsFloat ? 1 : colorScale;
6446
+ line += ` ${white} ${white} ${white}`;
6447
+ }
6448
+ }
6449
+ for (const name of customAttributeNames) {
6450
+ const propCount = customPropertyMapping[name].length;
6451
+ const attr = geometry.getAttribute(name);
6452
+ const isFloat = customIsFloat[name];
6453
+ for (let c = 0; c < propCount; c++) {
6454
+ const raw = attr != null ? getAttributeComponent(attr, i, c) : 0;
6455
+ line += " " + encode(raw, isFloat);
6331
6456
  }
6332
6457
  }
6333
6458
  vertexList += line + "\n";
@@ -6357,70 +6482,65 @@ property list uchar int vertex_index
6357
6482
  return result;
6358
6483
  }
6359
6484
  };
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;
6485
+ function getPlyType(array) {
6486
+ if (array instanceof Int8Array) return "char";
6487
+ if (array instanceof Uint8Array || array instanceof Uint8ClampedArray) return "uchar";
6488
+ if (array instanceof Int16Array) return "short";
6489
+ if (array instanceof Uint16Array) return "ushort";
6490
+ if (array instanceof Int32Array) return "int";
6491
+ if (array instanceof Uint32Array) return "uint";
6492
+ if (array instanceof Float32Array) return "float";
6493
+ if (array instanceof Float64Array) return "double";
6494
+ return "float";
6495
+ }
6496
+ function getBinaryWriter(type) {
6497
+ switch (type) {
6498
+ case "char":
6499
+ return { write: (dv, at, v) => dv.setInt8(at, v), size: 1 };
6500
+ case "uchar":
6501
+ return { write: (dv, at, v) => dv.setUint8(at, v), size: 1 };
6502
+ case "short":
6503
+ return { write: (dv, at, v, le) => dv.setInt16(at, v, le), size: 2 };
6504
+ case "ushort":
6505
+ return { write: (dv, at, v, le) => dv.setUint16(at, v, le), size: 2 };
6506
+ case "int":
6507
+ return { write: (dv, at, v, le) => dv.setInt32(at, v, le), size: 4 };
6508
+ case "uint":
6509
+ return { write: (dv, at, v, le) => dv.setUint32(at, v, le), size: 4 };
6510
+ case "float":
6511
+ return { write: (dv, at, v, le) => dv.setFloat32(at, v, le), size: 4 };
6512
+ case "double":
6513
+ return { write: (dv, at, v, le) => dv.setFloat64(at, v, le), size: 8 };
6514
+ }
6515
+ }
6516
+ function isFloatType(type) {
6517
+ return type === "float" || type === "double";
6518
+ }
6519
+ function getAttributeComponent(attr, i, c) {
6520
+ switch (c) {
6521
+ case 0:
6522
+ return attr.getX(i);
6523
+ case 1:
6524
+ return attr.getY(i);
6525
+ case 2:
6526
+ return attr.getZ(i);
6527
+ case 3:
6528
+ return attr.getW(i);
6529
+ }
6530
+ }
6531
+ function getColorScale(type) {
6532
+ switch (type) {
6533
+ case "uchar":
6534
+ return 255;
6535
+ case "ushort":
6536
+ return 65535;
6537
+ default:
6538
+ return 1;
6539
+ }
6421
6540
  }
6422
6541
 
6423
6542
  // ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
6543
+ var import_three18 = require("three");
6424
6544
  var KHR_mesh_quantization_ExtraAttrTypes = {
6425
6545
  POSITION: [
6426
6546
  "byte",
@@ -6450,7 +6570,11 @@ var KHR_mesh_quantization_ExtraAttrTypes = {
6450
6570
  ]
6451
6571
  };
6452
6572
  var GLTFExporter = class {
6573
+ /**
6574
+ * Constructs a new glTF exporter.
6575
+ */
6453
6576
  constructor() {
6577
+ this.textureUtils = null;
6454
6578
  this.pluginCallbacks = [];
6455
6579
  this.register(function(writer) {
6456
6580
  return new GLTFLightExtension(writer);
@@ -6473,6 +6597,9 @@ var GLTFExporter = class {
6473
6597
  this.register(function(writer) {
6474
6598
  return new GLTFMaterialsClearcoatExtension(writer);
6475
6599
  });
6600
+ this.register(function(writer) {
6601
+ return new GLTFMaterialsDispersionExtension(writer);
6602
+ });
6476
6603
  this.register(function(writer) {
6477
6604
  return new GLTFMaterialsIridescenceExtension(writer);
6478
6605
  });
@@ -6485,16 +6612,33 @@ var GLTFExporter = class {
6485
6612
  this.register(function(writer) {
6486
6613
  return new GLTFMaterialsEmissiveStrengthExtension(writer);
6487
6614
  });
6615
+ this.register(function(writer) {
6616
+ return new GLTFMaterialsBumpExtension(writer);
6617
+ });
6488
6618
  this.register(function(writer) {
6489
6619
  return new GLTFMeshGpuInstancing(writer);
6490
6620
  });
6491
6621
  }
6622
+ /**
6623
+ * Registers a plugin callback. This API is internally used to implement the various
6624
+ * glTF extensions but can also used by third-party code to add additional logic
6625
+ * to the exporter.
6626
+ *
6627
+ * @param {function(writer:GLTFWriter)} callback - The callback function to register.
6628
+ * @return {GLTFExporter} A reference to this exporter.
6629
+ */
6492
6630
  register(callback) {
6493
6631
  if (this.pluginCallbacks.indexOf(callback) === -1) {
6494
6632
  this.pluginCallbacks.push(callback);
6495
6633
  }
6496
6634
  return this;
6497
6635
  }
6636
+ /**
6637
+ * Unregisters a plugin callback.
6638
+ *
6639
+ * @param {Function} callback - The callback function to unregister.
6640
+ * @return {GLTFExporter} A reference to this exporter.
6641
+ */
6498
6642
  unregister(callback) {
6499
6643
  if (this.pluginCallbacks.indexOf(callback) !== -1) {
6500
6644
  this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
@@ -6502,11 +6646,25 @@ var GLTFExporter = class {
6502
6646
  return this;
6503
6647
  }
6504
6648
  /**
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
6649
+ * Sets the texture utils for this exporter. Only relevant when compressed textures have to be exported.
6650
+ *
6651
+ * Depending on whether you use {@link WebGLRenderer} or {@link WebGPURenderer}, you must inject the
6652
+ * corresponding texture utils {@link module:WebGLTextureUtils} or {@link module:WebGPUTextureUtils}.
6653
+ *
6654
+ * @param {WebGLTextureUtils|WebGPUTextureUtils} utils - The texture utils.
6655
+ * @return {GLTFExporter} A reference to this exporter.
6656
+ */
6657
+ setTextureUtils(utils) {
6658
+ this.textureUtils = utils;
6659
+ return this;
6660
+ }
6661
+ /**
6662
+ * Parses the given scenes and generates the glTF output.
6663
+ *
6664
+ * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
6665
+ * @param {GLTFExporter~OnDone} onDone - A callback function that is executed when the export has finished.
6666
+ * @param {GLTFExporter~OnError} onError - A callback function that is executed when an error happens.
6667
+ * @param {GLTFExporter~Options} options - options
6510
6668
  */
6511
6669
  parse(input, onDone, onError, options) {
6512
6670
  const writer = new GLTFWriter();
@@ -6515,8 +6673,16 @@ var GLTFExporter = class {
6515
6673
  plugins.push(this.pluginCallbacks[i](writer));
6516
6674
  }
6517
6675
  writer.setPlugins(plugins);
6518
- writer.write(input, onDone, options).catch(onError);
6676
+ writer.setTextureUtils(this.textureUtils);
6677
+ writer.writeAsync(input, onDone, options).catch(onError);
6519
6678
  }
6679
+ /**
6680
+ * Async version of {@link GLTFExporter#parse}.
6681
+ *
6682
+ * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
6683
+ * @param {GLTFExporter~Options} options - options.
6684
+ * @return {Promise<ArrayBuffer|string>} A Promise that resolved with the exported glTF data.
6685
+ */
6520
6686
  parseAsync(input, options) {
6521
6687
  const scope = this;
6522
6688
  return new Promise(function(resolve, reject) {
@@ -6553,22 +6719,22 @@ var WEBGL_CONSTANTS = {
6553
6719
  };
6554
6720
  var KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
6555
6721
  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;
6722
+ THREE_TO_WEBGL[import_three18.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
6723
+ THREE_TO_WEBGL[import_three18.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
6724
+ THREE_TO_WEBGL[import_three18.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
6725
+ THREE_TO_WEBGL[import_three18.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
6726
+ THREE_TO_WEBGL[import_three18.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
6727
+ THREE_TO_WEBGL[import_three18.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
6728
+ THREE_TO_WEBGL[import_three18.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
6729
+ THREE_TO_WEBGL[import_three18.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
6730
+ THREE_TO_WEBGL[import_three18.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
6565
6731
  var PATH_PROPERTIES = {
6566
6732
  scale: "scale",
6567
6733
  position: "translation",
6568
6734
  quaternion: "rotation",
6569
6735
  morphTargetInfluences: "weights"
6570
6736
  };
6571
- var DEFAULT_SPECULAR_COLOR = new import_three19.Color();
6737
+ var DEFAULT_SPECULAR_COLOR = new import_three18.Color();
6572
6738
  var GLB_HEADER_BYTES = 12;
6573
6739
  var GLB_HEADER_MAGIC = 1179937895;
6574
6740
  var GLB_VERSION = 2;
@@ -6602,7 +6768,7 @@ function getMinMax(attribute, start, count) {
6602
6768
  else if (a === 2) value = attribute.getZ(i);
6603
6769
  else if (a === 3) value = attribute.getW(i);
6604
6770
  if (attribute.normalized === true) {
6605
- value = import_three19.MathUtils.normalize(value, attribute.array);
6771
+ value = import_three18.MathUtils.normalize(value, attribute.array);
6606
6772
  }
6607
6773
  }
6608
6774
  output.min[a] = Math.min(output.min[a], value);
@@ -6635,19 +6801,20 @@ function getCanvas() {
6635
6801
  return document.createElement("canvas");
6636
6802
  }
6637
6803
  function getToBlobPromise(canvas, mimeType) {
6638
- if (canvas.toBlob !== void 0) {
6804
+ if (typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas) {
6805
+ let quality;
6806
+ if (mimeType === "image/jpeg") {
6807
+ quality = 0.92;
6808
+ } else if (mimeType === "image/webp") {
6809
+ quality = 0.8;
6810
+ }
6811
+ return canvas.convertToBlob({
6812
+ type: mimeType,
6813
+ quality
6814
+ });
6815
+ } else {
6639
6816
  return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
6640
6817
  }
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
6818
  }
6652
6819
  var GLTFWriter = class {
6653
6820
  constructor() {
@@ -6666,7 +6833,7 @@ var GLTFWriter = class {
6666
6833
  this.json = {
6667
6834
  asset: {
6668
6835
  version: "2.0",
6669
- generator: "THREE.GLTFExporter"
6836
+ generator: "THREE.GLTFExporter r" + import_three18.REVISION
6670
6837
  }
6671
6838
  };
6672
6839
  this.cache = {
@@ -6675,19 +6842,25 @@ var GLTFWriter = class {
6675
6842
  attributesNormalized: /* @__PURE__ */ new Map(),
6676
6843
  materials: /* @__PURE__ */ new Map(),
6677
6844
  textures: /* @__PURE__ */ new Map(),
6678
- images: /* @__PURE__ */ new Map()
6845
+ images: /* @__PURE__ */ new Map(),
6846
+ normalMaps: /* @__PURE__ */ new Map()
6679
6847
  };
6848
+ this.textureUtils = null;
6680
6849
  }
6681
6850
  setPlugins(plugins) {
6682
6851
  this.plugins = plugins;
6683
6852
  }
6853
+ setTextureUtils(utils) {
6854
+ this.textureUtils = utils;
6855
+ }
6684
6856
  /**
6685
6857
  * 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
6858
+ *
6859
+ * @param {Scene|Array<Scene>} input Scene or Array of THREE.Scenes
6860
+ * @param {Function} onDone Callback on completed
6861
+ * @param {Object} options options
6689
6862
  */
6690
- async write(input, onDone, options = {}) {
6863
+ async writeAsync(input, onDone, options = {}) {
6691
6864
  this.options = Object.assign({
6692
6865
  // default options
6693
6866
  binary: false,
@@ -6695,12 +6868,13 @@ var GLTFWriter = class {
6695
6868
  onlyVisible: true,
6696
6869
  maxTextureSize: Infinity,
6697
6870
  animations: [],
6698
- includeCustomExtensions: false
6871
+ includeCustomExtensions: false,
6872
+ copyright: null
6699
6873
  }, options);
6700
6874
  if (this.options.animations.length > 0) {
6701
6875
  this.options.trs = true;
6702
6876
  }
6703
- this.processInput(input);
6877
+ await this.processInputAsync(input);
6704
6878
  await Promise.all(this.pending);
6705
6879
  const writer = this;
6706
6880
  const buffers = writer.buffers;
@@ -6714,6 +6888,7 @@ var GLTFWriter = class {
6714
6888
  if (extensionsUsedList.length > 0) json.extensionsUsed = extensionsUsedList;
6715
6889
  if (extensionsRequiredList.length > 0) json.extensionsRequired = extensionsRequiredList;
6716
6890
  if (json.buffers && json.buffers.length > 0) json.buffers[0].byteLength = blob.size;
6891
+ if (options.copyright) json.asset.copyright = options.copyright;
6717
6892
  if (options.binary === true) {
6718
6893
  const reader = new FileReader();
6719
6894
  reader.readAsArrayBuffer(blob);
@@ -6762,7 +6937,7 @@ var GLTFWriter = class {
6762
6937
  /**
6763
6938
  * Serializes a userData.
6764
6939
  *
6765
- * @param {THREE.Object3D|THREE.Material} object
6940
+ * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry|THREE.AnimationClip} object
6766
6941
  * @param {Object} objectDef
6767
6942
  */
6768
6943
  serializeUserData(object, objectDef) {
@@ -6786,8 +6961,10 @@ var GLTFWriter = class {
6786
6961
  }
6787
6962
  /**
6788
6963
  * Returns ids for buffer attributes.
6789
- * @param {Object} object
6790
- * @return {Integer}
6964
+ *
6965
+ * @param {Object} attribute
6966
+ * @param {boolean} [isRelativeCopy=false]
6967
+ * @return {number} An integer
6791
6968
  */
6792
6969
  getUID(attribute, isRelativeCopy = false) {
6793
6970
  if (this.uids.has(attribute) === false) {
@@ -6803,12 +6980,12 @@ var GLTFWriter = class {
6803
6980
  * Checks if normal attribute values are normalized.
6804
6981
  *
6805
6982
  * @param {BufferAttribute} normal
6806
- * @returns {Boolean}
6983
+ * @returns {boolean}
6807
6984
  */
6808
6985
  isNormalizedNormalAttribute(normal) {
6809
6986
  const cache = this.cache;
6810
6987
  if (cache.attributesNormalized.has(normal)) return false;
6811
- const v = new import_three19.Vector3();
6988
+ const v = new import_three18.Vector3();
6812
6989
  for (let i = 0, il = normal.count; i < il; i++) {
6813
6990
  if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
6814
6991
  }
@@ -6825,7 +7002,7 @@ var GLTFWriter = class {
6825
7002
  const cache = this.cache;
6826
7003
  if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
6827
7004
  const attribute = normal.clone();
6828
- const v = new import_three19.Vector3();
7005
+ const v = new import_three18.Vector3();
6829
7006
  for (let i = 0, il = attribute.count; i < il; i++) {
6830
7007
  v.fromBufferAttribute(attribute, i);
6831
7008
  if (v.x === 0 && v.y === 0 && v.z === 0) {
@@ -6866,10 +7043,10 @@ var GLTFWriter = class {
6866
7043
  this.extensionsUsed["KHR_texture_transform"] = true;
6867
7044
  }
6868
7045
  }
6869
- buildMetalRoughTexture(metalnessMap, roughnessMap) {
7046
+ async buildMetalRoughTextureAsync(metalnessMap, roughnessMap) {
6870
7047
  if (metalnessMap === roughnessMap) return metalnessMap;
6871
7048
  function getEncodingConversion(map) {
6872
- if (map.colorSpace === import_three19.SRGBColorSpace) {
7049
+ if (map.colorSpace === import_three18.SRGBColorSpace) {
6873
7050
  return function SRGBToLinear(c) {
6874
7051
  return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
6875
7052
  };
@@ -6878,12 +7055,11 @@ var GLTFWriter = class {
6878
7055
  return c;
6879
7056
  };
6880
7057
  }
6881
- console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
6882
- if (metalnessMap instanceof import_three19.CompressedTexture) {
6883
- metalnessMap = decompress(metalnessMap);
7058
+ if (metalnessMap instanceof import_three18.CompressedTexture) {
7059
+ metalnessMap = await this.decompressTextureAsync(metalnessMap);
6884
7060
  }
6885
- if (roughnessMap instanceof import_three19.CompressedTexture) {
6886
- roughnessMap = decompress(roughnessMap);
7061
+ if (roughnessMap instanceof import_three18.CompressedTexture) {
7062
+ roughnessMap = await this.decompressTextureAsync(roughnessMap);
6887
7063
  }
6888
7064
  const metalness = metalnessMap ? metalnessMap.image : null;
6889
7065
  const roughness = roughnessMap ? roughnessMap.image : null;
@@ -6892,7 +7068,9 @@ var GLTFWriter = class {
6892
7068
  const canvas = getCanvas();
6893
7069
  canvas.width = width;
6894
7070
  canvas.height = height;
6895
- const context = canvas.getContext("2d");
7071
+ const context = canvas.getContext("2d", {
7072
+ willReadFrequently: true
7073
+ });
6896
7074
  context.fillStyle = "#00ffff";
6897
7075
  context.fillRect(0, 0, width, height);
6898
7076
  const composite = context.getImageData(0, 0, width, height);
@@ -6915,18 +7093,60 @@ var GLTFWriter = class {
6915
7093
  context.putImageData(composite, 0, 0);
6916
7094
  const reference = metalnessMap || roughnessMap;
6917
7095
  const texture = reference.clone();
6918
- texture.source = new import_three19.Source(canvas);
6919
- texture.colorSpace = import_three19.NoColorSpace;
7096
+ texture.source = new import_three18.TextureSource(canvas);
7097
+ texture.colorSpace = import_three18.NoColorSpace;
6920
7098
  texture.channel = (metalnessMap || roughnessMap).channel;
6921
7099
  if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
6922
7100
  console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
6923
7101
  }
7102
+ console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
7103
+ return texture;
7104
+ }
7105
+ /**
7106
+ * Builds a copy of the given normal map with the red and/or green channels
7107
+ * inverted (`color = 255 - color`). This is used to bake the sign of
7108
+ * `material.normalScale` and the tangent-space convention into the texture,
7109
+ * since glTF only supports OpenGL-style normal maps with a univariate,
7110
+ * positive scale.
7111
+ *
7112
+ * @param {THREE.Texture} normalMap The source normal map.
7113
+ * @param {boolean} flipX Whether to invert the red channel (normal X).
7114
+ * @param {boolean} flipY Whether to invert the green channel (normal Y).
7115
+ * @return {Promise<THREE.Texture>} The derived normal map texture.
7116
+ */
7117
+ async buildNormalMapTextureAsync(normalMap, flipX, flipY) {
7118
+ if (normalMap instanceof import_three18.CompressedTexture) {
7119
+ normalMap = await this.decompressTextureAsync(normalMap);
7120
+ }
7121
+ const image = normalMap.image;
7122
+ const canvas = getCanvas();
7123
+ canvas.width = image.width;
7124
+ canvas.height = image.height;
7125
+ const context = canvas.getContext("2d", {
7126
+ willReadFrequently: true
7127
+ });
7128
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
7129
+ const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
7130
+ const data = imageData.data;
7131
+ for (let i = 0; i < data.length; i += 4) {
7132
+ if (flipX) data[i + 0] = 255 - data[i + 0];
7133
+ if (flipY) data[i + 1] = 255 - data[i + 1];
7134
+ }
7135
+ context.putImageData(imageData, 0, 0);
7136
+ const texture = normalMap.clone();
7137
+ texture.source = new import_three18.TextureSource(canvas);
6924
7138
  return texture;
6925
7139
  }
7140
+ async decompressTextureAsync(texture, maxTextureSize = Infinity) {
7141
+ if (this.textureUtils === null) {
7142
+ throw new Error("THREE.GLTFExporter: setTextureUtils() must be called to process compressed textures.");
7143
+ }
7144
+ return await this.textureUtils.decompress(texture, maxTextureSize);
7145
+ }
6926
7146
  /**
6927
7147
  * Process a buffer to append to the default one.
6928
- * @param {ArrayBuffer} buffer
6929
- * @return {Integer}
7148
+ * @param {ArrayBuffer} buffer
7149
+ * @return {0}
6930
7150
  */
6931
7151
  processBuffer(buffer) {
6932
7152
  const json = this.json;
@@ -6937,11 +7157,11 @@ var GLTFWriter = class {
6937
7157
  }
6938
7158
  /**
6939
7159
  * 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
7160
+ * @param {BufferAttribute} attribute
7161
+ * @param {number} componentType
7162
+ * @param {number} start
7163
+ * @param {number} count
7164
+ * @param {number} [target] Target usage of the BufferView
6945
7165
  * @return {Object}
6946
7166
  */
6947
7167
  processBufferView(attribute, componentType, start, count, target) {
@@ -6960,7 +7180,11 @@ var GLTFWriter = class {
6960
7180
  default:
6961
7181
  componentSize = 4;
6962
7182
  }
6963
- const byteLength = getPaddedBufferSize(count * attribute.itemSize * componentSize);
7183
+ let byteStride = attribute.itemSize * componentSize;
7184
+ if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
7185
+ byteStride = Math.ceil(byteStride / 4) * 4;
7186
+ }
7187
+ const byteLength = getPaddedBufferSize(count * byteStride);
6964
7188
  const dataView = new DataView(new ArrayBuffer(byteLength));
6965
7189
  let offset = 0;
6966
7190
  for (let i = start; i < start + count; i++) {
@@ -6974,7 +7198,7 @@ var GLTFWriter = class {
6974
7198
  else if (a === 2) value = attribute.getZ(i);
6975
7199
  else if (a === 3) value = attribute.getW(i);
6976
7200
  if (attribute.normalized === true) {
6977
- value = import_three19.MathUtils.normalize(value, attribute.array);
7201
+ value = import_three18.MathUtils.normalize(value, attribute.array);
6978
7202
  }
6979
7203
  }
6980
7204
  if (componentType === WEBGL_CONSTANTS.FLOAT) {
@@ -6994,6 +7218,9 @@ var GLTFWriter = class {
6994
7218
  }
6995
7219
  offset += componentSize;
6996
7220
  }
7221
+ if (offset % byteStride !== 0) {
7222
+ offset += byteStride - offset % byteStride;
7223
+ }
6997
7224
  }
6998
7225
  const bufferViewDef = {
6999
7226
  buffer: this.processBuffer(dataView.buffer),
@@ -7002,7 +7229,7 @@ var GLTFWriter = class {
7002
7229
  };
7003
7230
  if (target !== void 0) bufferViewDef.target = target;
7004
7231
  if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
7005
- bufferViewDef.byteStride = attribute.itemSize * componentSize;
7232
+ bufferViewDef.byteStride = byteStride;
7006
7233
  }
7007
7234
  this.byteOffset += byteLength;
7008
7235
  json.bufferViews.push(bufferViewDef);
@@ -7015,7 +7242,7 @@ var GLTFWriter = class {
7015
7242
  /**
7016
7243
  * Process and generate a BufferView from an image Blob.
7017
7244
  * @param {Blob} blob
7018
- * @return {Promise<Integer>}
7245
+ * @return {Promise<number>} An integer
7019
7246
  */
7020
7247
  processBufferViewImage(blob) {
7021
7248
  const writer = this;
@@ -7038,11 +7265,11 @@ var GLTFWriter = class {
7038
7265
  }
7039
7266
  /**
7040
7267
  * 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
7268
+ * @param {BufferAttribute} attribute Attribute to process
7269
+ * @param {?BufferGeometry} [geometry] Geometry used for truncated draw range
7270
+ * @param {number} [start=0]
7271
+ * @param {number} [count=Infinity]
7272
+ * @return {?number} Index of the processed accessor on the "accessors" array
7046
7273
  */
7047
7274
  processAccessor(attribute, geometry, start, count) {
7048
7275
  const json = this.json;
@@ -7096,11 +7323,11 @@ var GLTFWriter = class {
7096
7323
  }
7097
7324
  /**
7098
7325
  * 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
7326
+ * @param {Image} image to process
7327
+ * @param {number} format Identifier of the format (RGBAFormat)
7328
+ * @param {boolean} flipY before writing out the image
7329
+ * @param {string} mimeType export format
7330
+ * @return {number} Index of the processed texture in the "images" array
7104
7331
  */
7105
7332
  processImage(image, format, flipY, mimeType = "image/png") {
7106
7333
  if (image !== null) {
@@ -7118,13 +7345,15 @@ var GLTFWriter = class {
7118
7345
  const canvas = getCanvas();
7119
7346
  canvas.width = Math.min(image.width, options.maxTextureSize);
7120
7347
  canvas.height = Math.min(image.height, options.maxTextureSize);
7121
- const ctx = canvas.getContext("2d");
7348
+ const ctx = canvas.getContext("2d", {
7349
+ willReadFrequently: true
7350
+ });
7122
7351
  if (flipY === true) {
7123
7352
  ctx.translate(0, canvas.height);
7124
7353
  ctx.scale(1, -1);
7125
7354
  }
7126
7355
  if (image.data !== void 0) {
7127
- if (format !== import_three19.RGBAFormat) {
7356
+ if (format !== import_three18.RGBAFormat) {
7128
7357
  console.error("GLTFExporter: Only RGBAFormat is supported.", format);
7129
7358
  }
7130
7359
  if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
@@ -7139,7 +7368,11 @@ var GLTFWriter = class {
7139
7368
  }
7140
7369
  ctx.putImageData(new ImageData(data, image.width, image.height), 0, 0);
7141
7370
  } else {
7142
- ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
7371
+ 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) {
7372
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
7373
+ } else {
7374
+ throw new Error("THREE.GLTFExporter: Invalid image type. Use HTMLImageElement, HTMLCanvasElement, ImageBitmap or OffscreenCanvas.");
7375
+ }
7143
7376
  }
7144
7377
  if (options.binary === true) {
7145
7378
  pending.push(
@@ -7148,15 +7381,7 @@ var GLTFWriter = class {
7148
7381
  })
7149
7382
  );
7150
7383
  } 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
- }
7384
+ imageDef.uri = import_three18.ImageUtils.getDataURL(canvas, mimeType);
7160
7385
  }
7161
7386
  const index = json.images.push(imageDef) - 1;
7162
7387
  cachedImages[key] = index;
@@ -7167,8 +7392,8 @@ var GLTFWriter = class {
7167
7392
  }
7168
7393
  /**
7169
7394
  * Process sampler
7170
- * @param {Texture} map Texture to process
7171
- * @return {Integer} Index of the processed texture in the "samplers" array
7395
+ * @param {Texture} map Texture to process
7396
+ * @return {number} Index of the processed texture in the "samplers" array
7172
7397
  */
7173
7398
  processSampler(map) {
7174
7399
  const json = this.json;
@@ -7183,28 +7408,37 @@ var GLTFWriter = class {
7183
7408
  }
7184
7409
  /**
7185
7410
  * Process texture
7186
- * @param {Texture} map Map to process
7187
- * @return {Integer} Index of the processed texture in the "textures" array
7411
+ * @param {Texture} map Map to process
7412
+ * @return {Promise<number>} Index of the processed texture in the "textures" array
7188
7413
  */
7189
- processTexture(map) {
7414
+ async processTextureAsync(map) {
7190
7415
  const writer = this;
7191
7416
  const options = writer.options;
7192
7417
  const cache = this.cache;
7193
7418
  const json = this.json;
7194
7419
  if (cache.textures.has(map)) return cache.textures.get(map);
7195
7420
  if (!json.textures) json.textures = [];
7196
- if (map instanceof import_three19.CompressedTexture) {
7197
- map = decompress(map, options.maxTextureSize);
7421
+ if (map instanceof import_three18.CompressedTexture) {
7422
+ map = await this.decompressTextureAsync(map, options.maxTextureSize);
7198
7423
  }
7199
- let mimeType = map.userData.mimeType;
7200
- if (mimeType === "image/webp") mimeType = "image/png";
7424
+ const mimeType = map.userData.mimeType;
7425
+ const imageIndex = this.processImage(map.image, map.format, map.flipY, mimeType);
7201
7426
  const textureDef = {
7202
- sampler: this.processSampler(map),
7203
- source: this.processImage(map.image, map.format, map.flipY, mimeType)
7427
+ sampler: this.processSampler(map)
7204
7428
  };
7429
+ if (mimeType === "image/webp") {
7430
+ textureDef.extensions = textureDef.extensions || {};
7431
+ textureDef.extensions["EXT_texture_webp"] = {
7432
+ source: imageIndex
7433
+ };
7434
+ this.extensionsUsed["EXT_texture_webp"] = true;
7435
+ this.extensionsRequired["EXT_texture_webp"] = true;
7436
+ } else {
7437
+ textureDef.source = imageIndex;
7438
+ }
7205
7439
  if (map.name) textureDef.name = map.name;
7206
- this._invokeAll(function(ext) {
7207
- ext.writeTexture && ext.writeTexture(map, textureDef);
7440
+ await this._invokeAllAsync(async function(ext) {
7441
+ ext.writeTexture && await ext.writeTexture(map, textureDef);
7208
7442
  });
7209
7443
  const index = json.textures.push(textureDef) - 1;
7210
7444
  cache.textures.set(map, index);
@@ -7212,13 +7446,16 @@ var GLTFWriter = class {
7212
7446
  }
7213
7447
  /**
7214
7448
  * Process material
7215
- * @param {THREE.Material} material Material to process
7216
- * @return {Integer|null} Index of the processed material in the "materials" array
7449
+ * @param {THREE.Material} material Material to process
7450
+ * @param {THREE.BufferGeometry} [geometry] Geometry the material is used with.
7451
+ * @return {Promise<?number>} Index of the processed material in the "materials" array
7217
7452
  */
7218
- processMaterial(material) {
7453
+ async processMaterialAsync(material, geometry) {
7219
7454
  const cache = this.cache;
7220
7455
  const json = this.json;
7221
- if (cache.materials.has(material)) return cache.materials.get(material);
7456
+ const hasTangent = geometry !== void 0 && geometry.hasAttribute("tangent");
7457
+ const cacheKey = material.normalMap ? material.uuid + ":" + hasTangent : material.uuid;
7458
+ if (cache.materials.has(cacheKey)) return cache.materials.get(cacheKey);
7222
7459
  if (material.isShaderMaterial) {
7223
7460
  console.warn("GLTFExporter: THREE.ShaderMaterial not supported.");
7224
7461
  return null;
@@ -7236,21 +7473,21 @@ var GLTFWriter = class {
7236
7473
  materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
7237
7474
  materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
7238
7475
  } else {
7239
- materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
7240
- materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
7476
+ materialDef.pbrMetallicRoughness.metallicFactor = 0;
7477
+ materialDef.pbrMetallicRoughness.roughnessFactor = 1;
7241
7478
  }
7242
7479
  if (material.metalnessMap || material.roughnessMap) {
7243
- const metalRoughTexture = this.buildMetalRoughTexture(material.metalnessMap, material.roughnessMap);
7480
+ const metalRoughTexture = await this.buildMetalRoughTextureAsync(material.metalnessMap, material.roughnessMap);
7244
7481
  const metalRoughMapDef = {
7245
- index: this.processTexture(metalRoughTexture),
7246
- channel: metalRoughTexture.channel
7482
+ index: await this.processTextureAsync(metalRoughTexture),
7483
+ texCoord: metalRoughTexture.channel
7247
7484
  };
7248
7485
  this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
7249
7486
  materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
7250
7487
  }
7251
7488
  if (material.map) {
7252
7489
  const baseColorMapDef = {
7253
- index: this.processTexture(material.map),
7490
+ index: await this.processTextureAsync(material.map),
7254
7491
  texCoord: material.map.channel
7255
7492
  };
7256
7493
  this.applyTextureTransform(baseColorMapDef, material.map);
@@ -7264,7 +7501,7 @@ var GLTFWriter = class {
7264
7501
  }
7265
7502
  if (material.emissiveMap) {
7266
7503
  const emissiveMapDef = {
7267
- index: this.processTexture(material.emissiveMap),
7504
+ index: await this.processTextureAsync(material.emissiveMap),
7268
7505
  texCoord: material.emissiveMap.channel
7269
7506
  };
7270
7507
  this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
@@ -7272,19 +7509,32 @@ var GLTFWriter = class {
7272
7509
  }
7273
7510
  }
7274
7511
  if (material.normalMap) {
7512
+ const normalScale = material.normalScale;
7513
+ const flipX = normalScale.x < 0;
7514
+ const flipY = hasTangent ? normalScale.y < 0 : normalScale.y > 0;
7515
+ let normalMap = material.normalMap;
7516
+ if (flipX || flipY) {
7517
+ if (cache.normalMaps.has(material.normalMap) === false) cache.normalMaps.set(material.normalMap, {});
7518
+ const cachedVariants = cache.normalMaps.get(material.normalMap);
7519
+ const cacheKey2 = `${flipX}:${flipY}`;
7520
+ if (cachedVariants[cacheKey2] === void 0) {
7521
+ cachedVariants[cacheKey2] = await this.buildNormalMapTextureAsync(material.normalMap, flipX, flipY);
7522
+ }
7523
+ normalMap = cachedVariants[cacheKey2];
7524
+ }
7275
7525
  const normalMapDef = {
7276
- index: this.processTexture(material.normalMap),
7526
+ index: await this.processTextureAsync(normalMap),
7277
7527
  texCoord: material.normalMap.channel
7278
7528
  };
7279
- if (material.normalScale && material.normalScale.x !== 1) {
7280
- normalMapDef.scale = material.normalScale.x;
7529
+ if (Math.abs(normalScale.x) !== 1) {
7530
+ normalMapDef.scale = Math.abs(normalScale.x);
7281
7531
  }
7282
7532
  this.applyTextureTransform(normalMapDef, material.normalMap);
7283
7533
  materialDef.normalTexture = normalMapDef;
7284
7534
  }
7285
7535
  if (material.aoMap) {
7286
7536
  const occlusionMapDef = {
7287
- index: this.processTexture(material.aoMap),
7537
+ index: await this.processTextureAsync(material.aoMap),
7288
7538
  texCoord: material.aoMap.channel
7289
7539
  };
7290
7540
  if (material.aoMapIntensity !== 1) {
@@ -7301,22 +7551,22 @@ var GLTFWriter = class {
7301
7551
  materialDef.alphaCutoff = material.alphaTest;
7302
7552
  }
7303
7553
  }
7304
- if (material.side === import_three19.DoubleSide) materialDef.doubleSided = true;
7554
+ if (material.side === import_three18.DoubleSide) materialDef.doubleSided = true;
7305
7555
  if (material.name !== "") materialDef.name = material.name;
7306
7556
  this.serializeUserData(material, materialDef);
7307
- this._invokeAll(function(ext) {
7308
- ext.writeMaterial && ext.writeMaterial(material, materialDef);
7557
+ await this._invokeAllAsync(async function(ext) {
7558
+ ext.writeMaterialAsync && await ext.writeMaterialAsync(material, materialDef);
7309
7559
  });
7310
7560
  const index = json.materials.push(materialDef) - 1;
7311
- cache.materials.set(material, index);
7561
+ cache.materials.set(cacheKey, index);
7312
7562
  return index;
7313
7563
  }
7314
7564
  /**
7315
7565
  * Process mesh
7316
- * @param {THREE.Mesh} mesh Mesh to process
7317
- * @return {Integer|null} Index of the processed mesh in the "meshes" array
7566
+ * @param {THREE.Mesh} mesh Mesh to process
7567
+ * @return {Promise<?number>} Index of the processed mesh in the "meshes" array
7318
7568
  */
7319
- processMesh(mesh) {
7569
+ async processMeshAsync(mesh) {
7320
7570
  const cache = this.cache;
7321
7571
  const json = this.json;
7322
7572
  const meshCacheKeyParts = [mesh.geometry.uuid];
@@ -7366,7 +7616,7 @@ var GLTFWriter = class {
7366
7616
  const attribute = geometry.attributes[attributeName];
7367
7617
  attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
7368
7618
  const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
7369
- if (!validVertexAttributes.test(attributeName)) attributeName = "_" + attributeName;
7619
+ if (!validVertexAttributes.test(attributeName) && !attributeName.startsWith("_")) attributeName = "_" + attributeName;
7370
7620
  if (cache.attributes.has(this.getUID(attribute))) {
7371
7621
  attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
7372
7622
  continue;
@@ -7375,7 +7625,10 @@ var GLTFWriter = class {
7375
7625
  const array = attribute.array;
7376
7626
  if (attributeName === "JOINTS_0" && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
7377
7627
  console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
7378
- modifiedAttribute = new import_three19.BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
7628
+ modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute(attribute, Uint16Array);
7629
+ } else if ((array instanceof Uint32Array || array instanceof Int32Array) && !attributeName.startsWith("_")) {
7630
+ console.warn(`GLTFExporter: Attribute "${attributeName}" converted to type FLOAT.`);
7631
+ modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute(attribute, Float32Array);
7379
7632
  }
7380
7633
  const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
7381
7634
  if (accessor !== null) {
@@ -7441,6 +7694,15 @@ var GLTFWriter = class {
7441
7694
  }
7442
7695
  const isMultiMaterial = Array.isArray(mesh.material);
7443
7696
  if (isMultiMaterial && geometry.groups.length === 0) return null;
7697
+ let didForceIndices = false;
7698
+ if (isMultiMaterial && geometry.index === null) {
7699
+ const indices = [];
7700
+ for (let i = 0, il = geometry.attributes.position.count; i < il; i++) {
7701
+ indices[i] = i;
7702
+ }
7703
+ geometry.setIndex(indices);
7704
+ didForceIndices = true;
7705
+ }
7444
7706
  const materials = isMultiMaterial ? mesh.material : [mesh.material];
7445
7707
  const groups = isMultiMaterial ? geometry.groups : [{ materialIndex: 0, start: void 0, count: void 0 }];
7446
7708
  for (let i = 0, il = groups.length; i < il; i++) {
@@ -7463,13 +7725,16 @@ var GLTFWriter = class {
7463
7725
  }
7464
7726
  if (primitive.indices === null) delete primitive.indices;
7465
7727
  }
7466
- const material = this.processMaterial(materials[groups[i].materialIndex]);
7728
+ const material = await this.processMaterialAsync(materials[groups[i].materialIndex], geometry);
7467
7729
  if (material !== null) primitive.material = material;
7468
7730
  primitives.push(primitive);
7469
7731
  }
7732
+ if (didForceIndices === true) {
7733
+ geometry.setIndex(null);
7734
+ }
7470
7735
  meshDef.primitives = primitives;
7471
7736
  if (!json.meshes) json.meshes = [];
7472
- this._invokeAll(function(ext) {
7737
+ await this._invokeAllAsync(function(ext) {
7473
7738
  ext.writeMesh && ext.writeMesh(mesh, meshDef);
7474
7739
  });
7475
7740
  const index = json.meshes.push(meshDef) - 1;
@@ -7515,8 +7780,8 @@ var GLTFWriter = class {
7515
7780
  }
7516
7781
  /**
7517
7782
  * Process camera
7518
- * @param {THREE.Camera} camera Camera to process
7519
- * @return {Integer} Index of the processed mesh in the "camera" array
7783
+ * @param {THREE.Camera} camera Camera to process
7784
+ * @return {number} Index of the processed mesh in the "camera" array
7520
7785
  */
7521
7786
  processCamera(camera) {
7522
7787
  const json = this.json;
@@ -7535,7 +7800,7 @@ var GLTFWriter = class {
7535
7800
  } else {
7536
7801
  cameraDef.perspective = {
7537
7802
  aspectRatio: camera.aspect,
7538
- yfov: import_three19.MathUtils.degToRad(camera.fov),
7803
+ yfov: import_three18.MathUtils.degToRad(camera.fov),
7539
7804
  zfar: camera.far <= 0 ? 1e-3 : camera.far,
7540
7805
  znear: camera.near < 0 ? 0 : camera.near
7541
7806
  };
@@ -7551,7 +7816,7 @@ var GLTFWriter = class {
7551
7816
  *
7552
7817
  * @param {THREE.AnimationClip} clip
7553
7818
  * @param {THREE.Object3D} root
7554
- * @return {number|null}
7819
+ * @return {?number}
7555
7820
  */
7556
7821
  processAnimation(clip, root) {
7557
7822
  const json = this.json;
@@ -7563,8 +7828,8 @@ var GLTFWriter = class {
7563
7828
  const samplers = [];
7564
7829
  for (let i = 0; i < tracks.length; ++i) {
7565
7830
  const track = tracks[i];
7566
- const trackBinding = import_three19.PropertyBinding.parseTrackName(track.name);
7567
- let trackNode = import_three19.PropertyBinding.findNode(root, trackBinding.nodeName);
7831
+ const trackBinding = import_three18.PropertyBinding.parseTrackName(track.name);
7832
+ let trackNode = import_three18.PropertyBinding.findNode(root, trackBinding.nodeName);
7568
7833
  const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
7569
7834
  if (trackBinding.objectName === "bones") {
7570
7835
  if (trackNode.isSkinnedMesh === true) {
@@ -7575,7 +7840,7 @@ var GLTFWriter = class {
7575
7840
  }
7576
7841
  if (!trackNode || !trackProperty) {
7577
7842
  console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
7578
- return null;
7843
+ continue;
7579
7844
  }
7580
7845
  const inputItemSize = 1;
7581
7846
  let outputItemSize = track.values.length / track.times.length;
@@ -7586,14 +7851,14 @@ var GLTFWriter = class {
7586
7851
  if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
7587
7852
  interpolation = "CUBICSPLINE";
7588
7853
  outputItemSize /= 3;
7589
- } else if (track.getInterpolation() === import_three19.InterpolateDiscrete) {
7854
+ } else if (track.getInterpolation() === import_three18.InterpolateDiscrete) {
7590
7855
  interpolation = "STEP";
7591
7856
  } else {
7592
7857
  interpolation = "LINEAR";
7593
7858
  }
7594
7859
  samplers.push({
7595
- input: this.processAccessor(new import_three19.BufferAttribute(track.times, inputItemSize)),
7596
- output: this.processAccessor(new import_three19.BufferAttribute(track.values, outputItemSize)),
7860
+ input: this.processAccessor(new import_three18.BufferAttribute(track.times, inputItemSize)),
7861
+ output: this.processAccessor(new import_three18.BufferAttribute(track.values, outputItemSize)),
7597
7862
  interpolation
7598
7863
  });
7599
7864
  channels.push({
@@ -7604,16 +7869,18 @@ var GLTFWriter = class {
7604
7869
  }
7605
7870
  });
7606
7871
  }
7607
- json.animations.push({
7872
+ const animationDef = {
7608
7873
  name: clip.name || "clip_" + json.animations.length,
7609
7874
  samplers,
7610
7875
  channels
7611
- });
7876
+ };
7877
+ this.serializeUserData(clip, animationDef);
7878
+ json.animations.push(animationDef);
7612
7879
  return json.animations.length - 1;
7613
7880
  }
7614
7881
  /**
7615
7882
  * @param {THREE.Object3D} object
7616
- * @return {number|null}
7883
+ * @return {?number}
7617
7884
  */
7618
7885
  processSkin(object) {
7619
7886
  const json = this.json;
@@ -7625,7 +7892,7 @@ var GLTFWriter = class {
7625
7892
  if (rootJoint === void 0) return null;
7626
7893
  const joints = [];
7627
7894
  const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
7628
- const temporaryBoneInverse = new import_three19.Matrix4();
7895
+ const temporaryBoneInverse = new import_three18.Matrix4();
7629
7896
  for (let i = 0; i < skeleton.bones.length; ++i) {
7630
7897
  joints.push(nodeMap.get(skeleton.bones[i]));
7631
7898
  temporaryBoneInverse.copy(skeleton.boneInverses[i]);
@@ -7633,7 +7900,7 @@ var GLTFWriter = class {
7633
7900
  }
7634
7901
  if (json.skins === void 0) json.skins = [];
7635
7902
  json.skins.push({
7636
- inverseBindMatrices: this.processAccessor(new import_three19.BufferAttribute(inverseBindMatrices, 16)),
7903
+ inverseBindMatrices: this.processAccessor(new import_three18.BufferAttribute(inverseBindMatrices, 16)),
7637
7904
  joints,
7638
7905
  skeleton: nodeMap.get(rootJoint)
7639
7906
  });
@@ -7642,14 +7909,17 @@ var GLTFWriter = class {
7642
7909
  }
7643
7910
  /**
7644
7911
  * Process Object3D node
7645
- * @param {THREE.Object3D} node Object3D to processNode
7646
- * @return {Integer} Index of the node in the nodes list
7912
+ * @param {THREE.Object3D} object Object3D to processNodeAsync
7913
+ * @return {Promise<number>} Index of the node in the nodes list
7647
7914
  */
7648
- processNode(object) {
7915
+ async processNodeAsync(object) {
7649
7916
  const json = this.json;
7650
7917
  const options = this.options;
7651
7918
  const nodeMap = this.nodeMap;
7652
7919
  if (!json.nodes) json.nodes = [];
7920
+ if (object.pivot !== null) {
7921
+ return await this._processNodeWithPivotAsync(object);
7922
+ }
7653
7923
  const nodeDef = {};
7654
7924
  if (options.trs) {
7655
7925
  const rotation = object.quaternion.toArray();
@@ -7675,35 +7945,98 @@ var GLTFWriter = class {
7675
7945
  if (object.name !== "") nodeDef.name = String(object.name);
7676
7946
  this.serializeUserData(object, nodeDef);
7677
7947
  if (object.isMesh || object.isLine || object.isPoints) {
7678
- const meshIndex = this.processMesh(object);
7948
+ const meshIndex = await this.processMeshAsync(object);
7679
7949
  if (meshIndex !== null) nodeDef.mesh = meshIndex;
7680
7950
  } else if (object.isCamera) {
7681
7951
  nodeDef.camera = this.processCamera(object);
7682
7952
  }
7683
7953
  if (object.isSkinnedMesh) this.skins.push(object);
7954
+ const nodeIndex = json.nodes.push(nodeDef) - 1;
7955
+ nodeMap.set(object, nodeIndex);
7684
7956
  if (object.children.length > 0) {
7685
7957
  const children = [];
7686
7958
  for (let i = 0, l = object.children.length; i < l; i++) {
7687
7959
  const child = object.children[i];
7688
7960
  if (child.visible || options.onlyVisible === false) {
7689
- const nodeIndex2 = this.processNode(child);
7690
- if (nodeIndex2 !== null) children.push(nodeIndex2);
7961
+ const childNodeIndex = await this.processNodeAsync(child);
7962
+ if (childNodeIndex !== null) children.push(childNodeIndex);
7691
7963
  }
7692
7964
  }
7693
7965
  if (children.length > 0) nodeDef.children = children;
7694
7966
  }
7695
- this._invokeAll(function(ext) {
7967
+ await this._invokeAllAsync(function(ext) {
7696
7968
  ext.writeNode && ext.writeNode(object, nodeDef);
7697
7969
  });
7698
- const nodeIndex = json.nodes.push(nodeDef) - 1;
7699
- nodeMap.set(object, nodeIndex);
7700
7970
  return nodeIndex;
7701
7971
  }
7972
+ /**
7973
+ * Process Object3D node with pivot using container approach
7974
+ * @param {THREE.Object3D} object Object3D with pivot
7975
+ * @return {Promise<number>} Index of the container node
7976
+ */
7977
+ async _processNodeWithPivotAsync(object) {
7978
+ const json = this.json;
7979
+ const options = this.options;
7980
+ const nodeMap = this.nodeMap;
7981
+ const pivot = object.pivot;
7982
+ const containerDef = {};
7983
+ const rotation = object.quaternion.toArray();
7984
+ const position = [
7985
+ object.position.x + pivot.x,
7986
+ object.position.y + pivot.y,
7987
+ object.position.z + pivot.z
7988
+ ];
7989
+ const scale = object.scale.toArray();
7990
+ if (!equalArray(rotation, [0, 0, 0, 1])) {
7991
+ containerDef.rotation = rotation;
7992
+ }
7993
+ if (!equalArray(position, [0, 0, 0])) {
7994
+ containerDef.translation = position;
7995
+ }
7996
+ if (!equalArray(scale, [1, 1, 1])) {
7997
+ containerDef.scale = scale;
7998
+ }
7999
+ containerDef.extras = { pivot: pivot.toArray() };
8000
+ if (object.name !== "") containerDef.name = String(object.name);
8001
+ this.serializeUserData(object, containerDef);
8002
+ const containerIndex = json.nodes.push(containerDef) - 1;
8003
+ nodeMap.set(object, containerIndex);
8004
+ const childDef = {};
8005
+ const childPosition = [-pivot.x, -pivot.y, -pivot.z];
8006
+ if (!equalArray(childPosition, [0, 0, 0])) {
8007
+ childDef.translation = childPosition;
8008
+ }
8009
+ if (object.isMesh || object.isLine || object.isPoints) {
8010
+ const meshIndex = await this.processMeshAsync(object);
8011
+ if (meshIndex !== null) childDef.mesh = meshIndex;
8012
+ } else if (object.isCamera) {
8013
+ childDef.camera = this.processCamera(object);
8014
+ }
8015
+ if (object.isSkinnedMesh) this.skins.push(object);
8016
+ const childIndex = json.nodes.push(childDef) - 1;
8017
+ const containerChildren = [childIndex];
8018
+ if (object.children.length > 0) {
8019
+ const grandchildren = [];
8020
+ for (let i = 0, l = object.children.length; i < l; i++) {
8021
+ const child = object.children[i];
8022
+ if (child.visible || options.onlyVisible === false) {
8023
+ const childNodeIndex = await this.processNodeAsync(child);
8024
+ if (childNodeIndex !== null) grandchildren.push(childNodeIndex);
8025
+ }
8026
+ }
8027
+ if (grandchildren.length > 0) childDef.children = grandchildren;
8028
+ }
8029
+ containerDef.children = containerChildren;
8030
+ await this._invokeAllAsync(function(ext) {
8031
+ ext.writeNode && ext.writeNode(object, containerDef);
8032
+ });
8033
+ return containerIndex;
8034
+ }
7702
8035
  /**
7703
8036
  * Process Scene
7704
- * @param {Scene} node Scene to process
8037
+ * @param {Scene} scene Scene to process
7705
8038
  */
7706
- processScene(scene) {
8039
+ async processSceneAsync(scene) {
7707
8040
  const json = this.json;
7708
8041
  const options = this.options;
7709
8042
  if (!json.scenes) {
@@ -7717,7 +8050,7 @@ var GLTFWriter = class {
7717
8050
  for (let i = 0, l = scene.children.length; i < l; i++) {
7718
8051
  const child = scene.children[i];
7719
8052
  if (child.visible || options.onlyVisible === false) {
7720
- const nodeIndex = this.processNode(child);
8053
+ const nodeIndex = await this.processNodeAsync(child);
7721
8054
  if (nodeIndex !== null) nodes.push(nodeIndex);
7722
8055
  }
7723
8056
  }
@@ -7726,47 +8059,58 @@ var GLTFWriter = class {
7726
8059
  }
7727
8060
  /**
7728
8061
  * Creates a Scene to hold a list of objects and parse it
7729
- * @param {Array} objects List of objects to process
8062
+ * @param {Array<THREE.Object3D>} objects List of objects to process
7730
8063
  */
7731
- processObjects(objects) {
7732
- const scene = new import_three19.Scene();
8064
+ async processObjectsAsync(objects) {
8065
+ const scene = new import_three18.Scene();
7733
8066
  scene.name = "AuxScene";
7734
8067
  for (let i = 0; i < objects.length; i++) {
7735
8068
  scene.children.push(objects[i]);
7736
8069
  }
7737
- this.processScene(scene);
8070
+ await this.processSceneAsync(scene);
7738
8071
  }
7739
8072
  /**
7740
8073
  * @param {THREE.Object3D|Array<THREE.Object3D>} input
7741
8074
  */
7742
- processInput(input) {
8075
+ async processInputAsync(input) {
7743
8076
  const options = this.options;
7744
8077
  input = input instanceof Array ? input : [input];
7745
- this._invokeAll(function(ext) {
8078
+ await this._invokeAllAsync(function(ext) {
7746
8079
  ext.beforeParse && ext.beforeParse(input);
7747
8080
  });
7748
8081
  const objectsWithoutScene = [];
7749
8082
  for (let i = 0; i < input.length; i++) {
7750
- if (input[i] instanceof import_three19.Scene) {
7751
- this.processScene(input[i]);
8083
+ if (input[i] instanceof import_three18.Scene) {
8084
+ await this.processSceneAsync(input[i]);
7752
8085
  } else {
7753
8086
  objectsWithoutScene.push(input[i]);
7754
8087
  }
7755
8088
  }
7756
- if (objectsWithoutScene.length > 0) this.processObjects(objectsWithoutScene);
8089
+ if (objectsWithoutScene.length > 0) {
8090
+ await this.processObjectsAsync(objectsWithoutScene);
8091
+ }
7757
8092
  for (let i = 0; i < this.skins.length; ++i) {
7758
8093
  this.processSkin(this.skins[i]);
7759
8094
  }
7760
- for (let i = 0; i < options.animations.length; ++i) {
7761
- this.processAnimation(options.animations[i], input[0]);
8095
+ if (input.length === 1) {
8096
+ for (let i = 0; i < options.animations.length; ++i) {
8097
+ this.processAnimation(options.animations[i], input[0]);
8098
+ }
8099
+ } else {
8100
+ for (let i = 0; i < input.length; i++) {
8101
+ const animations = options.animations[i] || [];
8102
+ for (let j = 0; j < animations.length; ++j) {
8103
+ this.processAnimation(animations[j], input[i]);
8104
+ }
8105
+ }
7762
8106
  }
7763
- this._invokeAll(function(ext) {
8107
+ await this._invokeAllAsync(function(ext) {
7764
8108
  ext.afterParse && ext.afterParse(input);
7765
8109
  });
7766
8110
  }
7767
- _invokeAll(func) {
8111
+ async _invokeAllAsync(func) {
7768
8112
  for (let i = 0, il = this.plugins.length; i < il; i++) {
7769
- func(this.plugins[i]);
8113
+ await func(this.plugins[i]);
7770
8114
  }
7771
8115
  }
7772
8116
  };
@@ -7822,7 +8166,7 @@ var GLTFMaterialsUnlitExtension = class {
7822
8166
  this.writer = writer;
7823
8167
  this.name = "KHR_materials_unlit";
7824
8168
  }
7825
- writeMaterial(material, materialDef) {
8169
+ async writeMaterialAsync(material, materialDef) {
7826
8170
  if (!material.isMeshBasicMaterial) return;
7827
8171
  const writer = this.writer;
7828
8172
  const extensionsUsed = writer.extensionsUsed;
@@ -7838,7 +8182,7 @@ var GLTFMaterialsClearcoatExtension = class {
7838
8182
  this.writer = writer;
7839
8183
  this.name = "KHR_materials_clearcoat";
7840
8184
  }
7841
- writeMaterial(material, materialDef) {
8185
+ async writeMaterialAsync(material, materialDef) {
7842
8186
  if (!material.isMeshPhysicalMaterial || material.clearcoat === 0) return;
7843
8187
  const writer = this.writer;
7844
8188
  const extensionsUsed = writer.extensionsUsed;
@@ -7846,7 +8190,7 @@ var GLTFMaterialsClearcoatExtension = class {
7846
8190
  extensionDef.clearcoatFactor = material.clearcoat;
7847
8191
  if (material.clearcoatMap) {
7848
8192
  const clearcoatMapDef = {
7849
- index: writer.processTexture(material.clearcoatMap),
8193
+ index: await writer.processTextureAsync(material.clearcoatMap),
7850
8194
  texCoord: material.clearcoatMap.channel
7851
8195
  };
7852
8196
  writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
@@ -7855,7 +8199,7 @@ var GLTFMaterialsClearcoatExtension = class {
7855
8199
  extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
7856
8200
  if (material.clearcoatRoughnessMap) {
7857
8201
  const clearcoatRoughnessMapDef = {
7858
- index: writer.processTexture(material.clearcoatRoughnessMap),
8202
+ index: await writer.processTextureAsync(material.clearcoatRoughnessMap),
7859
8203
  texCoord: material.clearcoatRoughnessMap.channel
7860
8204
  };
7861
8205
  writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
@@ -7863,9 +8207,10 @@ var GLTFMaterialsClearcoatExtension = class {
7863
8207
  }
7864
8208
  if (material.clearcoatNormalMap) {
7865
8209
  const clearcoatNormalMapDef = {
7866
- index: writer.processTexture(material.clearcoatNormalMap),
8210
+ index: await writer.processTextureAsync(material.clearcoatNormalMap),
7867
8211
  texCoord: material.clearcoatNormalMap.channel
7868
8212
  };
8213
+ if (material.clearcoatNormalScale.x !== 1) clearcoatNormalMapDef.scale = material.clearcoatNormalScale.x;
7869
8214
  writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
7870
8215
  extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
7871
8216
  }
@@ -7874,12 +8219,28 @@ var GLTFMaterialsClearcoatExtension = class {
7874
8219
  extensionsUsed[this.name] = true;
7875
8220
  }
7876
8221
  };
8222
+ var GLTFMaterialsDispersionExtension = class {
8223
+ constructor(writer) {
8224
+ this.writer = writer;
8225
+ this.name = "KHR_materials_dispersion";
8226
+ }
8227
+ async writeMaterialAsync(material, materialDef) {
8228
+ if (!material.isMeshPhysicalMaterial || material.dispersion === 0) return;
8229
+ const writer = this.writer;
8230
+ const extensionsUsed = writer.extensionsUsed;
8231
+ const extensionDef = {};
8232
+ extensionDef.dispersion = material.dispersion;
8233
+ materialDef.extensions = materialDef.extensions || {};
8234
+ materialDef.extensions[this.name] = extensionDef;
8235
+ extensionsUsed[this.name] = true;
8236
+ }
8237
+ };
7877
8238
  var GLTFMaterialsIridescenceExtension = class {
7878
8239
  constructor(writer) {
7879
8240
  this.writer = writer;
7880
8241
  this.name = "KHR_materials_iridescence";
7881
8242
  }
7882
- writeMaterial(material, materialDef) {
8243
+ async writeMaterialAsync(material, materialDef) {
7883
8244
  if (!material.isMeshPhysicalMaterial || material.iridescence === 0) return;
7884
8245
  const writer = this.writer;
7885
8246
  const extensionsUsed = writer.extensionsUsed;
@@ -7887,7 +8248,7 @@ var GLTFMaterialsIridescenceExtension = class {
7887
8248
  extensionDef.iridescenceFactor = material.iridescence;
7888
8249
  if (material.iridescenceMap) {
7889
8250
  const iridescenceMapDef = {
7890
- index: writer.processTexture(material.iridescenceMap),
8251
+ index: await writer.processTextureAsync(material.iridescenceMap),
7891
8252
  texCoord: material.iridescenceMap.channel
7892
8253
  };
7893
8254
  writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
@@ -7898,7 +8259,7 @@ var GLTFMaterialsIridescenceExtension = class {
7898
8259
  extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
7899
8260
  if (material.iridescenceThicknessMap) {
7900
8261
  const iridescenceThicknessMapDef = {
7901
- index: writer.processTexture(material.iridescenceThicknessMap),
8262
+ index: await writer.processTextureAsync(material.iridescenceThicknessMap),
7902
8263
  texCoord: material.iridescenceThicknessMap.channel
7903
8264
  };
7904
8265
  writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
@@ -7914,7 +8275,7 @@ var GLTFMaterialsTransmissionExtension = class {
7914
8275
  this.writer = writer;
7915
8276
  this.name = "KHR_materials_transmission";
7916
8277
  }
7917
- writeMaterial(material, materialDef) {
8278
+ async writeMaterialAsync(material, materialDef) {
7918
8279
  if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7919
8280
  const writer = this.writer;
7920
8281
  const extensionsUsed = writer.extensionsUsed;
@@ -7922,7 +8283,7 @@ var GLTFMaterialsTransmissionExtension = class {
7922
8283
  extensionDef.transmissionFactor = material.transmission;
7923
8284
  if (material.transmissionMap) {
7924
8285
  const transmissionMapDef = {
7925
- index: writer.processTexture(material.transmissionMap),
8286
+ index: await writer.processTextureAsync(material.transmissionMap),
7926
8287
  texCoord: material.transmissionMap.channel
7927
8288
  };
7928
8289
  writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
@@ -7938,7 +8299,7 @@ var GLTFMaterialsVolumeExtension = class {
7938
8299
  this.writer = writer;
7939
8300
  this.name = "KHR_materials_volume";
7940
8301
  }
7941
- writeMaterial(material, materialDef) {
8302
+ async writeMaterialAsync(material, materialDef) {
7942
8303
  if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7943
8304
  const writer = this.writer;
7944
8305
  const extensionsUsed = writer.extensionsUsed;
@@ -7946,13 +8307,15 @@ var GLTFMaterialsVolumeExtension = class {
7946
8307
  extensionDef.thicknessFactor = material.thickness;
7947
8308
  if (material.thicknessMap) {
7948
8309
  const thicknessMapDef = {
7949
- index: writer.processTexture(material.thicknessMap),
8310
+ index: await writer.processTextureAsync(material.thicknessMap),
7950
8311
  texCoord: material.thicknessMap.channel
7951
8312
  };
7952
8313
  writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
7953
8314
  extensionDef.thicknessTexture = thicknessMapDef;
7954
8315
  }
7955
- extensionDef.attenuationDistance = material.attenuationDistance;
8316
+ if (material.attenuationDistance !== Infinity) {
8317
+ extensionDef.attenuationDistance = material.attenuationDistance;
8318
+ }
7956
8319
  extensionDef.attenuationColor = material.attenuationColor.toArray();
7957
8320
  materialDef.extensions = materialDef.extensions || {};
7958
8321
  materialDef.extensions[this.name] = extensionDef;
@@ -7964,7 +8327,7 @@ var GLTFMaterialsIorExtension = class {
7964
8327
  this.writer = writer;
7965
8328
  this.name = "KHR_materials_ior";
7966
8329
  }
7967
- writeMaterial(material, materialDef) {
8330
+ async writeMaterialAsync(material, materialDef) {
7968
8331
  if (!material.isMeshPhysicalMaterial || material.ior === 1.5) return;
7969
8332
  const writer = this.writer;
7970
8333
  const extensionsUsed = writer.extensionsUsed;
@@ -7980,14 +8343,14 @@ var GLTFMaterialsSpecularExtension = class {
7980
8343
  this.writer = writer;
7981
8344
  this.name = "KHR_materials_specular";
7982
8345
  }
7983
- writeMaterial(material, materialDef) {
7984
- if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorTexture) return;
8346
+ async writeMaterialAsync(material, materialDef) {
8347
+ if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorMap) return;
7985
8348
  const writer = this.writer;
7986
8349
  const extensionsUsed = writer.extensionsUsed;
7987
8350
  const extensionDef = {};
7988
8351
  if (material.specularIntensityMap) {
7989
8352
  const specularIntensityMapDef = {
7990
- index: writer.processTexture(material.specularIntensityMap),
8353
+ index: await writer.processTextureAsync(material.specularIntensityMap),
7991
8354
  texCoord: material.specularIntensityMap.channel
7992
8355
  };
7993
8356
  writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
@@ -7995,7 +8358,7 @@ var GLTFMaterialsSpecularExtension = class {
7995
8358
  }
7996
8359
  if (material.specularColorMap) {
7997
8360
  const specularColorMapDef = {
7998
- index: writer.processTexture(material.specularColorMap),
8361
+ index: await writer.processTextureAsync(material.specularColorMap),
7999
8362
  texCoord: material.specularColorMap.channel
8000
8363
  };
8001
8364
  writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
@@ -8013,14 +8376,14 @@ var GLTFMaterialsSheenExtension = class {
8013
8376
  this.writer = writer;
8014
8377
  this.name = "KHR_materials_sheen";
8015
8378
  }
8016
- writeMaterial(material, materialDef) {
8379
+ async writeMaterialAsync(material, materialDef) {
8017
8380
  if (!material.isMeshPhysicalMaterial || material.sheen == 0) return;
8018
8381
  const writer = this.writer;
8019
8382
  const extensionsUsed = writer.extensionsUsed;
8020
8383
  const extensionDef = {};
8021
8384
  if (material.sheenRoughnessMap) {
8022
8385
  const sheenRoughnessMapDef = {
8023
- index: writer.processTexture(material.sheenRoughnessMap),
8386
+ index: await writer.processTextureAsync(material.sheenRoughnessMap),
8024
8387
  texCoord: material.sheenRoughnessMap.channel
8025
8388
  };
8026
8389
  writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
@@ -8028,7 +8391,7 @@ var GLTFMaterialsSheenExtension = class {
8028
8391
  }
8029
8392
  if (material.sheenColorMap) {
8030
8393
  const sheenColorMapDef = {
8031
- index: writer.processTexture(material.sheenColorMap),
8394
+ index: await writer.processTextureAsync(material.sheenColorMap),
8032
8395
  texCoord: material.sheenColorMap.channel
8033
8396
  };
8034
8397
  writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
@@ -8046,13 +8409,13 @@ var GLTFMaterialsAnisotropyExtension = class {
8046
8409
  this.writer = writer;
8047
8410
  this.name = "KHR_materials_anisotropy";
8048
8411
  }
8049
- writeMaterial(material, materialDef) {
8412
+ async writeMaterialAsync(material, materialDef) {
8050
8413
  if (!material.isMeshPhysicalMaterial || material.anisotropy == 0) return;
8051
8414
  const writer = this.writer;
8052
8415
  const extensionsUsed = writer.extensionsUsed;
8053
8416
  const extensionDef = {};
8054
8417
  if (material.anisotropyMap) {
8055
- const anisotropyMapDef = { index: writer.processTexture(material.anisotropyMap) };
8418
+ const anisotropyMapDef = { index: await writer.processTextureAsync(material.anisotropyMap) };
8056
8419
  writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
8057
8420
  extensionDef.anisotropyTexture = anisotropyMapDef;
8058
8421
  }
@@ -8068,7 +8431,7 @@ var GLTFMaterialsEmissiveStrengthExtension = class {
8068
8431
  this.writer = writer;
8069
8432
  this.name = "KHR_materials_emissive_strength";
8070
8433
  }
8071
- writeMaterial(material, materialDef) {
8434
+ async writeMaterialAsync(material, materialDef) {
8072
8435
  if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1) return;
8073
8436
  const writer = this.writer;
8074
8437
  const extensionsUsed = writer.extensionsUsed;
@@ -8079,6 +8442,30 @@ var GLTFMaterialsEmissiveStrengthExtension = class {
8079
8442
  extensionsUsed[this.name] = true;
8080
8443
  }
8081
8444
  };
8445
+ var GLTFMaterialsBumpExtension = class {
8446
+ constructor(writer) {
8447
+ this.writer = writer;
8448
+ this.name = "EXT_materials_bump";
8449
+ }
8450
+ async writeMaterialAsync(material, materialDef) {
8451
+ if (!material.isMeshStandardMaterial || material.bumpScale === 1 && !material.bumpMap) return;
8452
+ const writer = this.writer;
8453
+ const extensionsUsed = writer.extensionsUsed;
8454
+ const extensionDef = {};
8455
+ if (material.bumpMap) {
8456
+ const bumpMapDef = {
8457
+ index: await writer.processTextureAsync(material.bumpMap),
8458
+ texCoord: material.bumpMap.channel
8459
+ };
8460
+ writer.applyTextureTransform(bumpMapDef, material.bumpMap);
8461
+ extensionDef.bumpTexture = bumpMapDef;
8462
+ }
8463
+ extensionDef.bumpFactor = material.bumpScale;
8464
+ materialDef.extensions = materialDef.extensions || {};
8465
+ materialDef.extensions[this.name] = extensionDef;
8466
+ extensionsUsed[this.name] = true;
8467
+ }
8468
+ };
8082
8469
  var GLTFMeshGpuInstancing = class {
8083
8470
  constructor(writer) {
8084
8471
  this.writer = writer;
@@ -8091,10 +8478,10 @@ var GLTFMeshGpuInstancing = class {
8091
8478
  const translationAttr = new Float32Array(mesh.count * 3);
8092
8479
  const rotationAttr = new Float32Array(mesh.count * 4);
8093
8480
  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();
8481
+ const matrix = new import_three18.Matrix4();
8482
+ const position = new import_three18.Vector3();
8483
+ const quaternion = new import_three18.Quaternion();
8484
+ const scale = new import_three18.Vector3();
8098
8485
  for (let i = 0; i < mesh.count; i++) {
8099
8486
  mesh.getMatrixAt(i, matrix);
8100
8487
  matrix.decompose(position, quaternion, scale);
@@ -8103,9 +8490,9 @@ var GLTFMeshGpuInstancing = class {
8103
8490
  scale.toArray(scaleAttr, i * 3);
8104
8491
  }
8105
8492
  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))
8493
+ TRANSLATION: writer.processAccessor(new import_three18.BufferAttribute(translationAttr, 3)),
8494
+ ROTATION: writer.processAccessor(new import_three18.BufferAttribute(rotationAttr, 4)),
8495
+ SCALE: writer.processAccessor(new import_three18.BufferAttribute(scaleAttr, 3))
8109
8496
  };
8110
8497
  if (mesh.instanceColor)
8111
8498
  attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
@@ -8170,8 +8557,8 @@ GLTFExporter.Utils = {
8170
8557
  const sourceTracks = clip.tracks;
8171
8558
  for (let i = 0; i < sourceTracks.length; ++i) {
8172
8559
  let sourceTrack = sourceTracks[i];
8173
- const sourceTrackBinding = import_three19.PropertyBinding.parseTrackName(sourceTrack.name);
8174
- const sourceTrackNode = import_three19.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
8560
+ const sourceTrackBinding = import_three18.PropertyBinding.parseTrackName(sourceTrack.name);
8561
+ const sourceTrackNode = import_three18.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
8175
8562
  if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
8176
8563
  tracks.push(sourceTrack);
8177
8564
  continue;
@@ -8182,7 +8569,7 @@ GLTFExporter.Utils = {
8182
8569
  }
8183
8570
  console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
8184
8571
  sourceTrack = sourceTrack.clone();
8185
- sourceTrack.setInterpolation(import_three19.InterpolateLinear);
8572
+ sourceTrack.setInterpolation(import_three18.InterpolateLinear);
8186
8573
  }
8187
8574
  const targetCount = sourceTrackNode.morphTargetInfluences.length;
8188
8575
  const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
@@ -8214,6 +8601,19 @@ GLTFExporter.Utils = {
8214
8601
  }
8215
8602
  clip.tracks = tracks;
8216
8603
  return clip;
8604
+ },
8605
+ toTypedBufferAttribute: function(srcAttribute, TypedArray) {
8606
+ const dstAttribute = new import_three18.BufferAttribute(new TypedArray(srcAttribute.count * srcAttribute.itemSize), srcAttribute.itemSize, false);
8607
+ if (!srcAttribute.normalized && !srcAttribute.isInterleavedBufferAttribute) {
8608
+ dstAttribute.array.set(srcAttribute.array);
8609
+ return dstAttribute;
8610
+ }
8611
+ for (let i = 0, il = srcAttribute.count; i < il; i++) {
8612
+ for (let j = 0; j < srcAttribute.itemSize; j++) {
8613
+ dstAttribute.setComponent(i, j, srcAttribute.getComponent(i, j));
8614
+ }
8615
+ }
8616
+ return dstAttribute;
8217
8617
  }
8218
8618
  };
8219
8619
 
@@ -8265,10 +8665,10 @@ var SceneExporter = class {
8265
8665
  }
8266
8666
  };
8267
8667
  function localMatrix(object) {
8268
- return object.matrixAutoUpdate ? new import_three20.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8668
+ return object.matrixAutoUpdate ? new import_three19.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8269
8669
  }
8270
8670
  function createSnapshot(root, gltf, bakeColors = false) {
8271
- const scene = new import_three20.Scene();
8671
+ const scene = new import_three19.Scene();
8272
8672
  const geometries = [];
8273
8673
  const materials = [];
8274
8674
  const textures = [];
@@ -8286,7 +8686,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8286
8686
  if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
8287
8687
  throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
8288
8688
  }
8289
- material = new import_three20.MeshBasicMaterial({
8689
+ material = new import_three19.MeshBasicMaterial({
8290
8690
  map: uniforms.map.value,
8291
8691
  vertexColors: source.vertexColors,
8292
8692
  transparent: source.transparent,
@@ -8296,7 +8696,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8296
8696
  });
8297
8697
  material.name = source.name;
8298
8698
  } else if (shader.isShaderMaterial) {
8299
- material = new import_three20.MeshBasicMaterial({ vertexColors: source.vertexColors });
8699
+ material = new import_three19.MeshBasicMaterial({ vertexColors: source.vertexColors });
8300
8700
  material.name = source.name;
8301
8701
  } else {
8302
8702
  const copySource = Object.create(source);
@@ -8350,11 +8750,11 @@ function createSnapshot(root, gltf, bakeColors = false) {
8350
8750
  const material = copyMaterial(sourceMaterial, geometry);
8351
8751
  if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
8352
8752
  if (bakeColors || instanceColor) {
8353
- const tint = (material.color ?? new import_three20.Color()).clone();
8753
+ const tint = (material.color ?? new import_three19.Color()).clone();
8354
8754
  if (instanceColor) tint.multiply(instanceColor);
8355
8755
  if (bakeColors) {
8356
8756
  const original = geometry.getAttribute("color");
8357
- const colors = new import_three20.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
8757
+ const colors = new import_three19.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
8358
8758
  for (let i = 0; i < colors.count; i++) {
8359
8759
  colors.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
8360
8760
  }
@@ -8363,7 +8763,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8363
8763
  material.color.copy(tint);
8364
8764
  }
8365
8765
  }
8366
- const copy = new import_three20.Mesh(geometry, material);
8766
+ const copy = new import_three19.Mesh(geometry, material);
8367
8767
  copy.name = mesh.name;
8368
8768
  copy.renderOrder = mesh.renderOrder;
8369
8769
  scene.add(copy);
@@ -8377,9 +8777,9 @@ function createSnapshot(root, gltf, bakeColors = false) {
8377
8777
  const instanced = mesh;
8378
8778
  if (instanced.isInstancedMesh) {
8379
8779
  for (let i = 0; i < instanced.count; i++) {
8380
- const matrix = new import_three20.Matrix4();
8780
+ const matrix = new import_three19.Matrix4();
8381
8781
  instanced.getMatrixAt(i, matrix);
8382
- const color = instanced.instanceColor ? new import_three20.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
8782
+ const color = instanced.instanceColor ? new import_three19.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
8383
8783
  addMesh(mesh, world.clone().multiply(matrix), color);
8384
8784
  }
8385
8785
  } else {
@@ -8391,7 +8791,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8391
8791
  try {
8392
8792
  const ancestors = [];
8393
8793
  for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
8394
- const world = new import_three20.Matrix4();
8794
+ const world = new import_three19.Matrix4();
8395
8795
  for (const ancestor of ancestors) {
8396
8796
  if (!ancestor.visible) return { scene, dispose };
8397
8797
  world.multiply(localMatrix(ancestor));
@@ -8405,7 +8805,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8405
8805
  }
8406
8806
  function selectAlphaMode(material, geometry) {
8407
8807
  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;
8808
+ 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
8809
  const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
8410
8810
  const colors = geometry.getAttribute("color");
8411
8811
  if (!uv || material.vertexColors && colors?.itemSize === 4) return;
@@ -8442,7 +8842,7 @@ function selectAlphaMode(material, geometry) {
8442
8842
  }
8443
8843
  function copyDataTexture(source) {
8444
8844
  const image = source.image;
8445
- if (source.format !== import_three20.RGBAFormat || source.type !== import_three20.UnsignedByteType) {
8845
+ if (!image.data || source.format !== import_three19.RGBAFormat || source.type !== import_three19.UnsignedByteType) {
8446
8846
  throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
8447
8847
  }
8448
8848
  const canvas = createCanvas(image.width, image.height);
@@ -8453,8 +8853,8 @@ function copyDataTexture(source) {
8453
8853
  context.putImageData(pixels, 0, 0);
8454
8854
  const copySource = Object.create(source);
8455
8855
  copySource.userData = {};
8456
- copySource.source = new import_three20.Source(canvas);
8457
- return new import_three20.Texture().copy(copySource);
8856
+ copySource.source = new import_three19.TextureSource(canvas);
8857
+ return new import_three19.Texture().copy(copySource);
8458
8858
  }
8459
8859
 
8460
8860
  // src/gui/GuiHelper.ts
@@ -8524,7 +8924,7 @@ var GuiHelper = class {
8524
8924
  };
8525
8925
 
8526
8926
  // src/gui/scene/GuiObject.ts
8527
- var import_three25 = require("three");
8927
+ var import_three24 = require("three");
8528
8928
  init_AssetKey();
8529
8929
  init_ModelTextures();
8530
8930
  init_Models();
@@ -8540,7 +8940,7 @@ var GuiObject = class extends SceneObject {
8540
8940
  this.textureLayers = textureLayers;
8541
8941
  this.isGuiObject = true;
8542
8942
  /** Local bounds in GUI pixels, with y growing down from the origin. */
8543
- this.bounds = new import_three25.Box2();
8943
+ this.bounds = new import_three24.Box2();
8544
8944
  this.geometries = /* @__PURE__ */ new Set();
8545
8945
  this.ownedMaterials = /* @__PURE__ */ new Set();
8546
8946
  this.initialized = false;
@@ -8558,17 +8958,17 @@ var GuiObject = class extends SceneObject {
8558
8958
  item.scale.set(width2 / 16, height2 / 16, width2 / 16);
8559
8959
  item.updateWorldMatrix(true, true);
8560
8960
  const inverse = this.matrixWorld.clone().invert();
8561
- const bounds = new import_three25.Box3();
8961
+ const bounds = new import_three24.Box3();
8562
8962
  item.iterateAllMeshes((mesh2) => {
8563
8963
  mesh2.geometry.computeBoundingBox();
8564
- bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new import_three25.Matrix4().multiplyMatrices(inverse, mesh2.matrixWorld)));
8964
+ bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new import_three24.Matrix4().multiplyMatrices(inverse, mesh2.matrixWorld)));
8565
8965
  });
8566
8966
  item.position.z = depth - bounds.min.z;
8567
8967
  depth += bounds.max.z - bounds.min.z + 0.01;
8568
- this.bounds.expandByPoint(new import_three25.Vector2(x, y));
8569
- this.bounds.expandByPoint(new import_three25.Vector2(x + width2, y + height2));
8570
- this.bounds.expandByPoint(new import_three25.Vector2(bounds.min.x, -bounds.max.y));
8571
- this.bounds.expandByPoint(new import_three25.Vector2(bounds.max.x, -bounds.min.y));
8968
+ this.bounds.expandByPoint(new import_three24.Vector2(x, y));
8969
+ this.bounds.expandByPoint(new import_three24.Vector2(x + width2, y + height2));
8970
+ this.bounds.expandByPoint(new import_three24.Vector2(bounds.min.x, -bounds.max.y));
8971
+ this.bounds.expandByPoint(new import_three24.Vector2(bounds.max.x, -bounds.min.y));
8572
8972
  continue;
8573
8973
  }
8574
8974
  const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
@@ -8576,7 +8976,7 @@ var GuiObject = class extends SceneObject {
8576
8976
  const image = material.map.image;
8577
8977
  const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
8578
8978
  const [width, height] = layer.size ?? [cropWidth, cropHeight];
8579
- const geometry = new import_three25.PlaneGeometry(width, height);
8979
+ const geometry = new import_three24.PlaneGeometry(width, height);
8580
8980
  this.geometries.add(geometry);
8581
8981
  const uv = geometry.getAttribute("uv");
8582
8982
  for (let i = 0; i < uv.count; i++) {
@@ -8586,13 +8986,13 @@ var GuiObject = class extends SceneObject {
8586
8986
  1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
8587
8987
  );
8588
8988
  }
8589
- const mesh = new import_three25.Mesh(geometry, material);
8989
+ const mesh = new import_three24.Mesh(geometry, material);
8590
8990
  mesh.name = `mesh:${layer.name ?? index}`;
8591
8991
  mesh.position.set(x + width / 2, -y - height / 2, depth);
8592
8992
  mesh.renderOrder = index;
8593
8993
  this.add(mesh);
8594
- this.bounds.expandByPoint(new import_three25.Vector2(x, y));
8595
- this.bounds.expandByPoint(new import_three25.Vector2(x + width, y + height));
8994
+ this.bounds.expandByPoint(new import_three24.Vector2(x, y));
8995
+ this.bounds.expandByPoint(new import_three24.Vector2(x + width, y + height));
8596
8996
  depth += 0.01;
8597
8997
  }
8598
8998
  for (const child of this.children) child.position.z -= depth - 0.01;
@@ -8667,7 +9067,7 @@ function isGuiObject(obj) {
8667
9067
  init_image();
8668
9068
 
8669
9069
  // src/inspector/SceneInspector.ts
8670
- var import_three26 = require("three");
9070
+ var import_three25 = require("three");
8671
9071
  init_SceneObject();
8672
9072
  init_util();
8673
9073
  init_log();
@@ -8677,11 +9077,11 @@ var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
8677
9077
  var SceneInspector = class {
8678
9078
  constructor(renderer) {
8679
9079
  this.renderer = renderer;
8680
- this.mouse = new import_three26.Vector2();
9080
+ this.mouse = new import_three25.Vector2();
8681
9081
  this.listeners = new AbortController();
8682
9082
  this.objectInfoContainer = document.createElement("div");
8683
9083
  this.objectControlsContainer = document.createElement("div");
8684
- this.raycaster = new import_three26.Raycaster();
9084
+ this.raycaster = new import_three25.Raycaster();
8685
9085
  this.init();
8686
9086
  }
8687
9087
  init() {
@@ -9084,7 +9484,7 @@ init_ModelMerger();
9084
9484
  init_SpecialItems();
9085
9485
 
9086
9486
  // src/model/block/BlockStateResolver.ts
9087
- var import_three28 = require("three");
9487
+ var import_three27 = require("three");
9088
9488
  init_BlockStates();
9089
9489
  init_MineRenderError();
9090
9490
  init_util();
@@ -9162,7 +9562,7 @@ var BlockStateResolver = class {
9162
9562
  return variants[variants.length - 1];
9163
9563
  }
9164
9564
  static rotation(variant) {
9165
- const rotation = new import_three28.Euler();
9565
+ const rotation = new import_three27.Euler();
9166
9566
  if (typeof variant.x !== "undefined") {
9167
9567
  rotation.x = toRadians(clampRotationDegrees(variant.x));
9168
9568
  }
@@ -9254,7 +9654,7 @@ init_SceneObject();
9254
9654
  init_ModelObject();
9255
9655
  init_Models();
9256
9656
  var import_ts_deepmerge6 = __toESM(require_dist());
9257
- var import_three31 = require("three");
9657
+ var import_three30 = require("three");
9258
9658
  init_MineRenderError();
9259
9659
  init_InstanceReference();
9260
9660
  init_AssetKey();
@@ -9276,7 +9676,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9276
9676
  this._models = [];
9277
9677
  this._cullMask = 0;
9278
9678
  this._entities = [];
9279
- this._entityPlacement = new import_three31.Matrix4();
9679
+ this._entityPlacement = new import_three30.Matrix4();
9280
9680
  this._entityGeneration = 0;
9281
9681
  this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
9282
9682
  }
@@ -9372,7 +9772,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9372
9772
  return true;
9373
9773
  }
9374
9774
  placeEntities() {
9375
- const matrix = new import_three31.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
9775
+ const matrix = new import_three30.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
9376
9776
  for (const entity of this._entities) {
9377
9777
  matrix.decompose(entity.position, entity.quaternion, entity.scale);
9378
9778
  }
@@ -9394,12 +9794,12 @@ var _BlockObject = class _BlockObject extends SceneObject {
9394
9794
  getModelCullMask(model, worldMask) {
9395
9795
  const object = isInstanceReference(model) ? model.instanceable : model;
9396
9796
  if (object.options.displayPosition) return 0;
9397
- const position = new import_three31.Vector3();
9398
- const rotation = new import_three31.Quaternion();
9399
- const scale = new import_three31.Vector3();
9797
+ const position = new import_three30.Vector3();
9798
+ const rotation = new import_three30.Quaternion();
9799
+ const scale = new import_three30.Vector3();
9400
9800
  this.getModelMatrix(model).decompose(position, rotation, scale);
9401
- if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three31.Vector3(1, 1, 1)) > 1e-10) return 0;
9402
- return ModelCulling.toLocalMask(worldMask, new import_three31.Euler().setFromQuaternion(rotation));
9801
+ if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three30.Vector3(1, 1, 1)) > 1e-10) return 0;
9802
+ return ModelCulling.toLocalMask(worldMask, new import_three30.Euler().setFromQuaternion(rotation));
9403
9803
  }
9404
9804
  async setCullMask(worldMask) {
9405
9805
  worldMask &= 63;
@@ -9423,6 +9823,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9423
9823
  replacement.setMatrix(matrix);
9424
9824
  } else {
9425
9825
  replacement.matrix.copy(matrix);
9826
+ replacement.matrixWorldNeedsUpdate = true;
9426
9827
  matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
9427
9828
  replacement.matrixAutoUpdate = object.matrixAutoUpdate;
9428
9829
  replacement.visible = object.visible;
@@ -9464,7 +9865,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9464
9865
  () => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
9465
9866
  );
9466
9867
  const previous = this._fluidModel;
9467
- const matrix = previous ? this.getModelMatrix(previous) : new import_three31.Matrix4().makeTranslation(...this.position.toArray());
9868
+ const matrix = previous ? this.getModelMatrix(previous) : new import_three30.Matrix4().makeTranslation(...this.position.toArray());
9468
9869
  if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
9469
9870
  else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
9470
9871
  this._models = this._models.filter((model) => model !== previous);
@@ -9606,7 +10007,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9606
10007
  setPositionRotationScaleAt(index, position, rotation, scale) {
9607
10008
  super.setPositionRotationScaleAt(index, position, rotation, scale);
9608
10009
  }
9609
- getMatrixAt(index, matrix = new import_three31.Matrix4()) {
10010
+ getMatrixAt(index, matrix = new import_three30.Matrix4()) {
9610
10011
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
9611
10012
  const child = this._models[0];
9612
10013
  if (child && isModelObject(child)) {
@@ -11482,7 +11883,7 @@ init_ModelObject();
11482
11883
  init_nbt();
11483
11884
 
11484
11885
  // src/renderer/MineRenderScene.ts
11485
- var import_three33 = require("three");
11886
+ var import_three32 = require("three");
11486
11887
  init_SceneObject();
11487
11888
  var import_ts_deepmerge8 = __toESM(require_dist());
11488
11889
  init_ModelObject();
@@ -12215,7 +12616,7 @@ var import_ts_deepmerge7 = __toESM(require_dist());
12215
12616
  init_util();
12216
12617
 
12217
12618
  // src/skin/SkinTextures.ts
12218
- var import_three32 = require("three");
12619
+ var import_three31 = require("three");
12219
12620
  init_Caching();
12220
12621
  init_CacheKey();
12221
12622
  init_MineRenderError();
@@ -12299,11 +12700,11 @@ var SkinTextures = class {
12299
12700
  });
12300
12701
  }
12301
12702
  static createMaterial(pixels, width, height, transparent = true) {
12302
- const texture = Textures.initTextureProps(new import_three32.DataTexture(pixels, width, height));
12303
- texture.colorSpace = import_three32.SRGBColorSpace;
12703
+ const texture = Textures.initTextureProps(new import_three31.DataTexture(pixels, width, height));
12704
+ texture.colorSpace = import_three31.SRGBColorSpace;
12304
12705
  texture.flipY = true;
12305
12706
  texture.needsUpdate = true;
12306
- return new import_three32.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three32.DoubleSide : import_three32.FrontSide, alphaTest: transparent ? 0.1 : 0 });
12707
+ return new import_three31.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three31.DoubleSide : import_three31.FrontSide, alphaTest: transparent ? 0.1 : 0 });
12307
12708
  }
12308
12709
  static isSlim(image, scale) {
12309
12710
  for (const [x, y] of [[46, 52], [54, 20]]) {
@@ -12533,7 +12934,7 @@ var SkinObject = class extends SceneObject {
12533
12934
  // src/renderer/MineRenderScene.ts
12534
12935
  init_EntityObject();
12535
12936
  init_ItemTints();
12536
- var _MineRenderScene = class _MineRenderScene extends import_three33.Scene {
12937
+ var _MineRenderScene = class _MineRenderScene extends import_three32.Scene {
12537
12938
  constructor(options) {
12538
12939
  super();
12539
12940
  this.isMineRenderScene = true;
@@ -12576,12 +12977,13 @@ var _MineRenderScene = class _MineRenderScene extends import_three33.Scene {
12576
12977
  }
12577
12978
  updateObjectRegistration(object, attached) {
12578
12979
  if (this.observedObjects.has(object) === attached) return;
12980
+ const observable = object;
12579
12981
  if (attached) {
12580
12982
  this.observedObjects.add(object);
12581
- object.addEventListener("change", this.onObjectChange);
12983
+ observable.addEventListener("change", this.onObjectChange);
12582
12984
  } else {
12583
12985
  this.observedObjects.delete(object);
12584
- object.removeEventListener("change", this.onObjectChange);
12986
+ observable.removeEventListener("change", this.onObjectChange);
12585
12987
  }
12586
12988
  const change = attached ? 1 : -1;
12587
12989
  this.stats.objectCount += change;
@@ -12661,7 +13063,7 @@ function isMineRenderScene(obj) {
12661
13063
  }
12662
13064
 
12663
13065
  // src/renderer/Renderer.ts
12664
- var import_three35 = require("three");
13066
+ var import_three34 = require("three");
12665
13067
  var import_ts_deepmerge9 = __toESM(require_dist());
12666
13068
  var import_stats = __toESM(require("stats.js"));
12667
13069
  var import_postprocessing = require("postprocessing");
@@ -12670,11 +13072,11 @@ init_Model();
12670
13072
  init_three();
12671
13073
 
12672
13074
  // src/three/OrbitControls.js
12673
- var import_three34 = require("three");
13075
+ var import_three33 = require("three");
12674
13076
  var _changeEvent = { type: "change" };
12675
13077
  var _startEvent = { type: "start" };
12676
13078
  var _endEvent = { type: "end" };
12677
- var OrbitControls = class extends import_three34.EventDispatcher {
13079
+ var OrbitControls = class extends import_three33.EventDispatcher {
12678
13080
  constructor(object, domElement) {
12679
13081
  super();
12680
13082
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
@@ -12683,7 +13085,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12683
13085
  this.domElement = domElement;
12684
13086
  this.domElement.style.touchAction = "none";
12685
13087
  this.enabled = true;
12686
- this.target = new import_three34.Vector3();
13088
+ this.target = new import_three33.Vector3();
12687
13089
  this.minDistance = 0;
12688
13090
  this.maxDistance = Infinity;
12689
13091
  this.minZoom = 0;
@@ -12705,8 +13107,8 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12705
13107
  this.autoRotate = false;
12706
13108
  this.autoRotateSpeed = 2;
12707
13109
  this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
12708
- this.mouseButtons = { LEFT: import_three34.MOUSE.ROTATE, MIDDLE: import_three34.MOUSE.DOLLY, RIGHT: import_three34.MOUSE.PAN };
12709
- this.touches = { ONE: import_three34.TOUCH.ROTATE, TWO: import_three34.TOUCH.DOLLY_PAN };
13110
+ this.mouseButtons = { LEFT: import_three33.MOUSE.ROTATE, MIDDLE: import_three33.MOUSE.DOLLY, RIGHT: import_three33.MOUSE.PAN };
13111
+ this.touches = { ONE: import_three33.TOUCH.ROTATE, TWO: import_three33.TOUCH.DOLLY_PAN };
12710
13112
  this.target0 = this.target.clone();
12711
13113
  this.position0 = this.object.position.clone();
12712
13114
  this.zoom0 = this.object.zoom;
@@ -12735,11 +13137,11 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12735
13137
  state = STATE.NONE;
12736
13138
  };
12737
13139
  this.update = function() {
12738
- const offset = new import_three34.Vector3();
12739
- const quat = new import_three34.Quaternion().setFromUnitVectors(object.up, new import_three34.Vector3(0, 1, 0));
13140
+ const offset = new import_three33.Vector3();
13141
+ const quat = new import_three33.Quaternion().setFromUnitVectors(object.up, new import_three33.Vector3(0, 1, 0));
12740
13142
  const quatInverse = quat.clone().invert();
12741
- const lastPosition = new import_three34.Vector3();
12742
- const lastQuaternion = new import_three34.Quaternion();
13143
+ const lastPosition = new import_three33.Vector3();
13144
+ const lastQuaternion = new import_three33.Quaternion();
12743
13145
  const twoPI = 2 * Math.PI;
12744
13146
  return function update() {
12745
13147
  const position = scope.object.position;
@@ -12825,20 +13227,20 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12825
13227
  };
12826
13228
  let state = STATE.NONE;
12827
13229
  const EPS = 1e-6;
12828
- const spherical = new import_three34.Spherical();
12829
- const sphericalDelta = new import_three34.Spherical();
13230
+ const spherical = new import_three33.Spherical();
13231
+ const sphericalDelta = new import_three33.Spherical();
12830
13232
  let scale = 1;
12831
- const panOffset = new import_three34.Vector3();
13233
+ const panOffset = new import_three33.Vector3();
12832
13234
  let zoomChanged = false;
12833
- const rotateStart = new import_three34.Vector2();
12834
- const rotateEnd = new import_three34.Vector2();
12835
- const rotateDelta = new import_three34.Vector2();
12836
- const panStart = new import_three34.Vector2();
12837
- const panEnd = new import_three34.Vector2();
12838
- const panDelta = new import_three34.Vector2();
12839
- const dollyStart = new import_three34.Vector2();
12840
- const dollyEnd = new import_three34.Vector2();
12841
- const dollyDelta = new import_three34.Vector2();
13235
+ const rotateStart = new import_three33.Vector2();
13236
+ const rotateEnd = new import_three33.Vector2();
13237
+ const rotateDelta = new import_three33.Vector2();
13238
+ const panStart = new import_three33.Vector2();
13239
+ const panEnd = new import_three33.Vector2();
13240
+ const panDelta = new import_three33.Vector2();
13241
+ const dollyStart = new import_three33.Vector2();
13242
+ const dollyEnd = new import_three33.Vector2();
13243
+ const dollyDelta = new import_three33.Vector2();
12842
13244
  const pointers = [];
12843
13245
  const pointerPositions = {};
12844
13246
  function getAutoRotationAngle() {
@@ -12854,7 +13256,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12854
13256
  sphericalDelta.phi -= angle;
12855
13257
  }
12856
13258
  const panLeft = function() {
12857
- const v = new import_three34.Vector3();
13259
+ const v = new import_three33.Vector3();
12858
13260
  return function panLeft2(distance, objectMatrix) {
12859
13261
  v.setFromMatrixColumn(objectMatrix, 0);
12860
13262
  v.multiplyScalar(-distance);
@@ -12862,7 +13264,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12862
13264
  };
12863
13265
  }();
12864
13266
  const panUp = function() {
12865
- const v = new import_three34.Vector3();
13267
+ const v = new import_three33.Vector3();
12866
13268
  return function panUp2(distance, objectMatrix) {
12867
13269
  if (scope.screenSpacePanning === true) {
12868
13270
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -12875,7 +13277,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12875
13277
  };
12876
13278
  }();
12877
13279
  const pan = function() {
12878
- const offset = new import_three34.Vector3();
13280
+ const offset = new import_three33.Vector3();
12879
13281
  return function pan2(deltaX, deltaY) {
12880
13282
  const element = scope.domElement;
12881
13283
  if (scope.object.isPerspectiveCamera) {
@@ -13124,12 +13526,12 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13124
13526
  mouseAction = -1;
13125
13527
  }
13126
13528
  switch (mouseAction) {
13127
- case import_three34.MOUSE.DOLLY:
13529
+ case import_three33.MOUSE.DOLLY:
13128
13530
  if (scope.enableZoom === false) return;
13129
13531
  handleMouseDownDolly(event);
13130
13532
  state = STATE.DOLLY;
13131
13533
  break;
13132
- case import_three34.MOUSE.ROTATE:
13534
+ case import_three33.MOUSE.ROTATE:
13133
13535
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
13134
13536
  if (scope.enablePan === false) return;
13135
13537
  handleMouseDownPan(event);
@@ -13140,7 +13542,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13140
13542
  state = STATE.ROTATE;
13141
13543
  }
13142
13544
  break;
13143
- case import_three34.MOUSE.PAN:
13545
+ case import_three33.MOUSE.PAN:
13144
13546
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
13145
13547
  if (scope.enableRotate === false) return;
13146
13548
  handleMouseDownRotate(event);
@@ -13196,12 +13598,12 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13196
13598
  switch (pointers.length) {
13197
13599
  case 1:
13198
13600
  switch (scope.touches.ONE) {
13199
- case import_three34.TOUCH.ROTATE:
13601
+ case import_three33.TOUCH.ROTATE:
13200
13602
  if (scope.enableRotate === false) return;
13201
13603
  handleTouchStartRotate();
13202
13604
  state = STATE.TOUCH_ROTATE;
13203
13605
  break;
13204
- case import_three34.TOUCH.PAN:
13606
+ case import_three33.TOUCH.PAN:
13205
13607
  if (scope.enablePan === false) return;
13206
13608
  handleTouchStartPan();
13207
13609
  state = STATE.TOUCH_PAN;
@@ -13212,12 +13614,12 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13212
13614
  break;
13213
13615
  case 2:
13214
13616
  switch (scope.touches.TWO) {
13215
- case import_three34.TOUCH.DOLLY_PAN:
13617
+ case import_three33.TOUCH.DOLLY_PAN:
13216
13618
  if (scope.enableZoom === false && scope.enablePan === false) return;
13217
13619
  handleTouchStartDollyPan();
13218
13620
  state = STATE.TOUCH_DOLLY_PAN;
13219
13621
  break;
13220
- case import_three34.TOUCH.DOLLY_ROTATE:
13622
+ case import_three33.TOUCH.DOLLY_ROTATE:
13221
13623
  if (scope.enableZoom === false && scope.enableRotate === false) return;
13222
13624
  handleTouchStartDollyRotate();
13223
13625
  state = STATE.TOUCH_DOLLY_ROTATE;
@@ -13284,7 +13686,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13284
13686
  function trackPointer(event) {
13285
13687
  let position = pointerPositions[event.pointerId];
13286
13688
  if (position === void 0) {
13287
- position = new import_three34.Vector2();
13689
+ position = new import_three33.Vector2();
13288
13690
  pointerPositions[event.pointerId] = position;
13289
13691
  }
13290
13692
  position.set(event.pageX, event.pageY);
@@ -13304,10 +13706,10 @@ var MapControls = class extends OrbitControls {
13304
13706
  constructor(object, domElement) {
13305
13707
  super(object, domElement);
13306
13708
  this.screenSpacePanning = false;
13307
- this.mouseButtons.LEFT = import_three34.MOUSE.PAN;
13308
- this.mouseButtons.RIGHT = import_three34.MOUSE.ROTATE;
13309
- this.touches.ONE = import_three34.TOUCH.PAN;
13310
- this.touches.TWO = import_three34.TOUCH.DOLLY_ROTATE;
13709
+ this.mouseButtons.LEFT = import_three33.MOUSE.PAN;
13710
+ this.mouseButtons.RIGHT = import_three33.MOUSE.ROTATE;
13711
+ this.touches.ONE = import_three33.TOUCH.PAN;
13712
+ this.touches.TWO = import_three33.TOUCH.DOLLY_ROTATE;
13311
13713
  }
13312
13714
  };
13313
13715
 
@@ -13358,14 +13760,14 @@ var _Renderer = class _Renderer {
13358
13760
  switch (this.options.camera.type) {
13359
13761
  case "perspective":
13360
13762
  default:
13361
- return new import_three35.PerspectiveCamera(
13763
+ return new import_three34.PerspectiveCamera(
13362
13764
  this.options.camera.perspective.fov,
13363
13765
  this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
13364
13766
  this.options.camera.near,
13365
13767
  this.options.camera.far
13366
13768
  );
13367
13769
  case "orthographic":
13368
- return new import_three35.OrthographicCamera(
13770
+ return new import_three34.OrthographicCamera(
13369
13771
  this.options.camera.orthographic.left ?? this.viewWidth / -2,
13370
13772
  this.options.camera.orthographic.right ?? this.viewWidth / 2,
13371
13773
  this.options.camera.orthographic.top ?? this.viewHeight / 2,
@@ -13376,7 +13778,7 @@ var _Renderer = class _Renderer {
13376
13778
  }
13377
13779
  }
13378
13780
  createRenderer() {
13379
- const renderer = new import_three35.WebGLRenderer({
13781
+ const renderer = new import_three34.WebGLRenderer({
13380
13782
  antialias: this.options.render.antialias,
13381
13783
  alpha: true,
13382
13784
  powerPreference: "high-performance",
@@ -13384,8 +13786,8 @@ var _Renderer = class _Renderer {
13384
13786
  });
13385
13787
  renderer.setClearColor(0, 0);
13386
13788
  renderer.shadowMap.enabled = true;
13387
- renderer.shadowMap.type = import_three35.PCFSoftShadowMap;
13388
- renderer.outputColorSpace = import_three35.SRGBColorSpace;
13789
+ renderer.shadowMap.type = import_three34.PCFShadowMap;
13790
+ renderer.outputColorSpace = import_three34.SRGBColorSpace;
13389
13791
  renderer.setPixelRatio(this.options.render.pixelRatio ?? 1);
13390
13792
  renderer.setSize(this.viewWidth, this.viewHeight);
13391
13793
  return renderer;
@@ -13420,20 +13822,20 @@ var _Renderer = class _Renderer {
13420
13822
  window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
13421
13823
  }
13422
13824
  if (this.options.debug.grid) {
13423
- const gridHelper = new import_three35.GridHelper(128, 16);
13825
+ const gridHelper = new import_three34.GridHelper(128, 16);
13424
13826
  this._debugHelpers.push(gridHelper);
13425
13827
  this.scene.add(gridHelper);
13426
- const gridHelper2 = new import_three35.GridHelper(128, 16);
13828
+ const gridHelper2 = new import_three34.GridHelper(128, 16);
13427
13829
  this._debugHelpers.push(gridHelper2);
13428
13830
  gridHelper2.rotation.x = 90 * (Math.PI / 180);
13429
13831
  this.scene.add(gridHelper2);
13430
- const gridHelper3 = new import_three35.GridHelper(128, 16);
13832
+ const gridHelper3 = new import_three34.GridHelper(128, 16);
13431
13833
  this._debugHelpers.push(gridHelper3);
13432
13834
  gridHelper3.rotation.z = 90 * (Math.PI / 180);
13433
13835
  this.scene.add(gridHelper3);
13434
13836
  }
13435
13837
  if (this.options.debug.axes) {
13436
- const axesHelper = new import_three35.AxesHelper(64);
13838
+ const axesHelper = new import_three34.AxesHelper(64);
13437
13839
  this._debugHelpers.push(axesHelper);
13438
13840
  this.scene.add(axesHelper);
13439
13841
  }
@@ -13692,8 +14094,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
13692
14094
  top: void 0,
13693
14095
  bottom: void 0
13694
14096
  },
13695
- position: new import_three35.Vector3(50, 50, 50),
13696
- lookingAt: new import_three35.Vector3(0, 0, 0)
14097
+ position: new import_three34.Vector3(50, 50, 50),
14098
+ lookingAt: new import_three34.Vector3(0, 0, 0)
13697
14099
  },
13698
14100
  render: {
13699
14101
  fpsLimit: 60,
@@ -14158,12 +14560,12 @@ var AnvilParser = class {
14158
14560
  };
14159
14561
 
14160
14562
  // src/world/Chunk.ts
14161
- var import_three40 = require("three");
14563
+ var import_three39 = require("three");
14162
14564
  init_BlockStates();
14163
14565
  init_AssetKey();
14164
14566
 
14165
14567
  // src/world/MineRenderWorld.ts
14166
- var import_three38 = require("three");
14568
+ var import_three37 = require("three");
14167
14569
  init_Model();
14168
14570
  init_BatchedExecutor();
14169
14571
  init_AssetKey();
@@ -14171,7 +14573,7 @@ init_BlockStates();
14171
14573
  init_CubeFace();
14172
14574
 
14173
14575
  // src/world/SectionModels.ts
14174
- var import_three37 = require("three");
14576
+ var import_three36 = require("three");
14175
14577
  init_AssetKey();
14176
14578
  init_Models();
14177
14579
  init_CubeFace();
@@ -14237,12 +14639,12 @@ var SectionModels = class {
14237
14639
  });
14238
14640
  await object.init();
14239
14641
  const geometry = object.children[0].geometry;
14240
- geometry.applyMatrix4(new import_three37.Matrix4().makeRotationFromEuler(rotation));
14642
+ geometry.applyMatrix4(new import_three36.Matrix4().makeRotationFromEuler(rotation));
14241
14643
  object.clear();
14242
14644
  const cullFaces = CUBE_FACES.map((face) => {
14243
14645
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
14244
14646
  if (local < 0) return 0;
14245
- const normal = new import_three37.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
14647
+ const normal = new import_three36.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
14246
14648
  const world = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
14247
14649
  return 1 << world;
14248
14650
  });
@@ -14272,20 +14674,20 @@ var MineRenderWorld = class {
14272
14674
  }
14273
14675
  getBlockAt(posOrX, y, z) {
14274
14676
  if (typeof posOrX == "number") {
14275
- return this.getBlockAt(new import_three38.Vector3(posOrX, y, z));
14677
+ return this.getBlockAt(new import_three37.Vector3(posOrX, y, z));
14276
14678
  }
14277
14679
  if (isTripleArray(posOrX)) {
14278
- return this.getBlockAt(new import_three38.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14680
+ return this.getBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14279
14681
  }
14280
14682
  this.validatePosBounds(posOrX);
14281
14683
  return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
14282
14684
  }
14283
14685
  async setBlockAt(posOrX, yOrBlock, z, block) {
14284
14686
  if (typeof posOrX == "number") {
14285
- return this.setBlockAt(new import_three38.Vector3(posOrX, yOrBlock, z), block);
14687
+ return this.setBlockAt(new import_three37.Vector3(posOrX, yOrBlock, z), block);
14286
14688
  }
14287
14689
  if (isTripleArray(posOrX)) {
14288
- return this.setBlockAt(new import_three38.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14690
+ return this.setBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14289
14691
  }
14290
14692
  return this.placeBlock(posOrX, yOrBlock);
14291
14693
  }
@@ -14296,10 +14698,10 @@ var MineRenderWorld = class {
14296
14698
  }
14297
14699
  async setBlockVisibleAt(posOrX, yOrVisible, z, visible) {
14298
14700
  if (typeof posOrX === "number") {
14299
- return this.setBlockVisibleAt(new import_three38.Vector3(posOrX, yOrVisible, z), visible);
14701
+ return this.setBlockVisibleAt(new import_three37.Vector3(posOrX, yOrVisible, z), visible);
14300
14702
  }
14301
14703
  if (isTripleArray(posOrX)) {
14302
- return this.setBlockVisibleAt(new import_three38.Vector3(...posOrX), yOrVisible);
14704
+ return this.setBlockVisibleAt(new import_three37.Vector3(...posOrX), yOrVisible);
14303
14705
  }
14304
14706
  this.validatePosBounds(posOrX);
14305
14707
  await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
@@ -14316,7 +14718,7 @@ var MineRenderWorld = class {
14316
14718
  const collect = async (positions2) => {
14317
14719
  for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
14318
14720
  };
14319
- const place = (block) => this.placeBlock(new import_three38.Vector3(...block.position), block, collect);
14721
+ const place = (block) => this.placeBlock(new import_three37.Vector3(...block.position), block, collect);
14320
14722
  const keys = /* @__PURE__ */ new Map();
14321
14723
  for (const block of multiblock.blocks) {
14322
14724
  if (Chunk.isAir(block)) continue;
@@ -14394,13 +14796,13 @@ var MineRenderWorld = class {
14394
14796
  for (const pos of positions) {
14395
14797
  this.pendingCulling.set(pos.toArray().join(","), pos.clone());
14396
14798
  for (const offset of CUBE_FACE_OFFSETS) {
14397
- const neighbor = pos.clone().add(new import_three38.Vector3(...offset));
14799
+ const neighbor = pos.clone().add(new import_three37.Vector3(...offset));
14398
14800
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14399
14801
  }
14400
14802
  for (let y = -1; y <= 1; y++) {
14401
14803
  for (let z = -1; z <= 1; z++) {
14402
14804
  for (let x = -1; x <= 1; x++) {
14403
- const neighbor = pos.clone().add(new import_three38.Vector3(x, y, z));
14805
+ const neighbor = pos.clone().add(new import_three37.Vector3(x, y, z));
14404
14806
  if (this.getBlockAt(neighbor)?.object?.fluidKind) {
14405
14807
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14406
14808
  }
@@ -14424,7 +14826,7 @@ var MineRenderWorld = class {
14424
14826
  }
14425
14827
  if (block.object?.fluidKind) {
14426
14828
  await block.object.updateFluid((x, y, z) => {
14427
- const neighbor = pos.clone().add(new import_three38.Vector3(x, y, z));
14829
+ const neighbor = pos.clone().add(new import_three37.Vector3(x, y, z));
14428
14830
  const section = this.getChunkAt(neighbor);
14429
14831
  const object = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
14430
14832
  return {
@@ -14436,7 +14838,7 @@ var MineRenderWorld = class {
14436
14838
  }
14437
14839
  let mask = 0;
14438
14840
  for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
14439
- const neighbor = pos.clone().add(new import_three38.Vector3(...offset));
14841
+ const neighbor = pos.clone().add(new import_three37.Vector3(...offset));
14440
14842
  if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
14441
14843
  mask |= 1 << face;
14442
14844
  }
@@ -14470,14 +14872,14 @@ var MineRenderWorld = class {
14470
14872
  return this._chunks.get(this.worldPosToChunkKey(pos));
14471
14873
  }
14472
14874
  static worldToScenePosition(pos) {
14473
- return new import_three38.Vector3(
14875
+ return new import_three37.Vector3(
14474
14876
  pos.x * 16,
14475
14877
  pos.y * 16,
14476
14878
  pos.z * 16
14477
14879
  );
14478
14880
  }
14479
14881
  static sceneToWorldPosition(pos) {
14480
- return new import_three38.Vector3(
14882
+ return new import_three37.Vector3(
14481
14883
  pos.x / 16,
14482
14884
  pos.y / 16,
14483
14885
  pos.z / 16
@@ -14500,10 +14902,10 @@ var MineRenderWorld = class {
14500
14902
  init_Model();
14501
14903
 
14502
14904
  // src/world/SectionMesh.ts
14503
- var import_three39 = require("three");
14905
+ var import_three38 = require("three");
14504
14906
  init_CanvasCompat();
14505
14907
  init_Materials();
14506
- var SectionMesh = class _SectionMesh extends import_three39.Group {
14908
+ var SectionMesh = class _SectionMesh extends import_three38.Group {
14507
14909
  constructor() {
14508
14910
  super(...arguments);
14509
14911
  this.ownedMeshes = [];
@@ -14576,18 +14978,18 @@ var SectionMesh = class _SectionMesh extends import_three39.Group {
14576
14978
  for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
14577
14979
  }
14578
14980
  }
14579
- const geometry = new import_three39.BufferGeometry();
14580
- geometry.setAttribute("position", new import_three39.Float32BufferAttribute(positions, 3));
14581
- geometry.setAttribute("normal", new import_three39.Float32BufferAttribute(normals, 3));
14582
- geometry.setAttribute("uv", new import_three39.Float32BufferAttribute(uvs, 2));
14583
- geometry.setAttribute("color", new import_three39.Float32BufferAttribute(colors, 3));
14981
+ const geometry = new import_three38.BufferGeometry();
14982
+ geometry.setAttribute("position", new import_three38.Float32BufferAttribute(positions, 3));
14983
+ geometry.setAttribute("normal", new import_three38.Float32BufferAttribute(normals, 3));
14984
+ geometry.setAttribute("uv", new import_three38.Float32BufferAttribute(uvs, 2));
14985
+ geometry.setAttribute("color", new import_three38.Float32BufferAttribute(colors, 3));
14584
14986
  geometry.setIndex(indices);
14585
14987
  geometry.computeBoundingBox();
14586
14988
  geometry.computeBoundingSphere();
14587
14989
  const material = Materials.createShadedCanvasMaterial(canvas, false);
14588
14990
  material.vertexColors = true;
14589
14991
  const texture = material.uniforms?.map?.value ?? material.map;
14590
- const mesh = new import_three39.Mesh(geometry, material);
14992
+ const mesh = new import_three38.Mesh(geometry, material);
14591
14993
  section.add(mesh);
14592
14994
  section.ownedMeshes.push({ mesh, texture });
14593
14995
  }
@@ -14601,6 +15003,7 @@ var SectionMesh = class _SectionMesh extends import_three39.Group {
14601
15003
  texture?.dispose();
14602
15004
  }
14603
15005
  this.removeFromParent();
15006
+ super.dispose();
14604
15007
  }
14605
15008
  };
14606
15009
 
@@ -14622,10 +15025,10 @@ var Chunk = class _Chunk {
14622
15025
  }
14623
15026
  getBlockAt(posOrX, y, z) {
14624
15027
  if (typeof posOrX == "number") {
14625
- return this.getBlockAt(new import_three40.Vector3(posOrX, y, z));
15028
+ return this.getBlockAt(new import_three39.Vector3(posOrX, y, z));
14626
15029
  }
14627
15030
  if (isTripleArray(posOrX)) {
14628
- return this.getBlockAt(new import_three40.Vector3(posOrX[0], posOrX[1], posOrX[2]));
15031
+ return this.getBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14629
15032
  }
14630
15033
  const pos = this.worldPosToChunkPos(posOrX);
14631
15034
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -14633,10 +15036,10 @@ var Chunk = class _Chunk {
14633
15036
  }
14634
15037
  async setBlockAt(posOrX, yOrBlock, z, block) {
14635
15038
  if (typeof posOrX == "number") {
14636
- return this.setBlockAt(new import_three40.Vector3(posOrX, yOrBlock, z), block);
15039
+ return this.setBlockAt(new import_three39.Vector3(posOrX, yOrBlock, z), block);
14637
15040
  }
14638
15041
  if (isTripleArray(posOrX)) {
14639
- return this.setBlockAt(new import_three40.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
15042
+ return this.setBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14640
15043
  }
14641
15044
  const worldPos = posOrX;
14642
15045
  const pos = this.worldPosToChunkPos(worldPos);
@@ -14748,7 +15151,7 @@ var Chunk = class _Chunk {
14748
15151
  }
14749
15152
  async clear(onBlocksChanged = this.onBlocksChanged) {
14750
15153
  const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
14751
- new import_three40.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
15154
+ new import_three39.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
14752
15155
  ));
14753
15156
  for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
14754
15157
  this.sectionBlocks.clear();
@@ -14773,14 +15176,14 @@ var Chunk = class _Chunk {
14773
15176
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
14774
15177
  }
14775
15178
  worldPosToChunkPos(pos) {
14776
- return new import_three40.Vector3(
15179
+ return new import_three39.Vector3(
14777
15180
  pos.x - this.x * 16,
14778
15181
  pos.y - this.y * 16,
14779
15182
  pos.z - this.z * 16
14780
15183
  );
14781
15184
  }
14782
15185
  chunkPosToWorldPos(pos) {
14783
- return new import_three40.Vector3(
15186
+ return new import_three39.Vector3(
14784
15187
  this.x * 16 + pos.x,
14785
15188
  this.y * 16 + pos.y,
14786
15189
  this.z * 16 + pos.z