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.
@@ -4036,6 +4036,7 @@ var init_SceneObject = __esm({
4036
4036
  dispose() {
4037
4037
  this.disposeAndRemoveAllChildren();
4038
4038
  this.notifyDirty();
4039
+ super.dispose();
4039
4040
  }
4040
4041
  disposeAndRemoveAllChildren() {
4041
4042
  if (this.instanceMesh) {
@@ -4249,6 +4250,7 @@ var init_EntityObject = __esm({
4249
4250
  else matrix.makeRotationFromEuler(new import_three14.Euler(...op.rotate, "ZYX"));
4250
4251
  modelRoot.matrix.multiply(matrix);
4251
4252
  }
4253
+ modelRoot.matrixWorldNeedsUpdate = true;
4252
4254
  modelRoot.matrixAutoUpdate = false;
4253
4255
  } else if (this.options.flip ?? true) {
4254
4256
  modelRoot.scale.set(-1, -1, 1);
@@ -4344,7 +4346,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
4344
4346
  const attributes = {};
4345
4347
  const morphAttributes = {};
4346
4348
  const morphTargetsRelative = geometries[0].morphTargetsRelative;
4347
- const mergedGeometry = new import_three21.BufferGeometry();
4349
+ const mergedGeometry = new import_three20.BufferGeometry();
4348
4350
  let offset = 0;
4349
4351
  for (let i = 0; i < geometries.length; ++i) {
4350
4352
  const geometry = geometries[i];
@@ -4468,7 +4470,7 @@ function mergeBufferAttributes(attributes) {
4468
4470
  array.set(attributes[i].array, offset);
4469
4471
  offset += attributes[i].array.length;
4470
4472
  }
4471
- return new import_three21.BufferAttribute(array, itemSize, normalized);
4473
+ return new import_three20.BufferAttribute(array, itemSize, normalized);
4472
4474
  }
4473
4475
  function interleaveAttributes(attributes) {
4474
4476
  let TypedArray;
@@ -4484,7 +4486,7 @@ function interleaveAttributes(attributes) {
4484
4486
  arrayLength += attribute.array.length;
4485
4487
  stride += attribute.itemSize;
4486
4488
  }
4487
- const interleavedBuffer = new import_three21.InterleavedBuffer(new TypedArray(arrayLength), stride);
4489
+ const interleavedBuffer = new import_three20.InterleavedBuffer(new TypedArray(arrayLength), stride);
4488
4490
  let offset = 0;
4489
4491
  const res = [];
4490
4492
  const getters = ["getX", "getY", "getZ", "getW"];
@@ -4493,7 +4495,7 @@ function interleaveAttributes(attributes) {
4493
4495
  const attribute = attributes[j];
4494
4496
  const itemSize = attribute.itemSize;
4495
4497
  const count = attribute.count;
4496
- const iba = new import_three21.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
4498
+ const iba = new import_three20.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
4497
4499
  res.push(iba);
4498
4500
  offset += itemSize;
4499
4501
  for (let c = 0; c < count; c++) {
@@ -4577,13 +4579,13 @@ function mergeVertices(geometry, tolerance = 1e-4) {
4577
4579
  const name = attributeNames[i];
4578
4580
  const oldAttribute = geometry.getAttribute(name);
4579
4581
  const buffer = new oldAttribute.array.constructor(attrArrays[name]);
4580
- const attribute = new import_three21.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
4582
+ const attribute = new import_three20.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
4581
4583
  result.setAttribute(name, attribute);
4582
4584
  if (name in morphAttrsArrays) {
4583
4585
  for (let j = 0; j < morphAttrsArrays[name].length; j++) {
4584
4586
  const oldMorphAttribute = geometry.morphAttributes[name][j];
4585
4587
  const buffer2 = new oldMorphAttribute.array.constructor(morphAttrsArrays[name][j]);
4586
- const morphAttribute = new import_three21.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
4588
+ const morphAttribute = new import_three20.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
4587
4589
  result.morphAttributes[name][j] = morphAttribute;
4588
4590
  }
4589
4591
  }
@@ -4592,11 +4594,11 @@ function mergeVertices(geometry, tolerance = 1e-4) {
4592
4594
  return result;
4593
4595
  }
4594
4596
  function toTrianglesDrawMode(geometry, drawMode) {
4595
- if (drawMode === import_three21.TrianglesDrawMode) {
4597
+ if (drawMode === import_three20.TrianglesDrawMode) {
4596
4598
  console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
4597
4599
  return geometry;
4598
4600
  }
4599
- if (drawMode === import_three21.TriangleFanDrawMode || drawMode === import_three21.TriangleStripDrawMode) {
4601
+ if (drawMode === import_three20.TriangleFanDrawMode || drawMode === import_three20.TriangleStripDrawMode) {
4600
4602
  let index = geometry.getIndex();
4601
4603
  if (index === null) {
4602
4604
  const indices = [];
@@ -4614,7 +4616,7 @@ function toTrianglesDrawMode(geometry, drawMode) {
4614
4616
  }
4615
4617
  const numberOfTriangles = index.count - 2;
4616
4618
  const newIndices = [];
4617
- if (drawMode === import_three21.TriangleFanDrawMode) {
4619
+ if (drawMode === import_three20.TriangleFanDrawMode) {
4618
4620
  for (let i = 1; i <= numberOfTriangles; i++) {
4619
4621
  newIndices.push(index.getX(0));
4620
4622
  newIndices.push(index.getX(i));
@@ -4650,15 +4652,15 @@ function computeMorphedAttributes(object) {
4650
4652
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
4651
4653
  return null;
4652
4654
  }
4653
- const _vA = new import_three21.Vector3();
4654
- const _vB = new import_three21.Vector3();
4655
- const _vC = new import_three21.Vector3();
4656
- const _tempA = new import_three21.Vector3();
4657
- const _tempB = new import_three21.Vector3();
4658
- const _tempC = new import_three21.Vector3();
4659
- const _morphA = new import_three21.Vector3();
4660
- const _morphB = new import_three21.Vector3();
4661
- const _morphC = new import_three21.Vector3();
4655
+ const _vA = new import_three20.Vector3();
4656
+ const _vB = new import_three20.Vector3();
4657
+ const _vC = new import_three20.Vector3();
4658
+ const _tempA = new import_three20.Vector3();
4659
+ const _tempB = new import_three20.Vector3();
4660
+ const _tempC = new import_three20.Vector3();
4661
+ const _morphA = new import_three20.Vector3();
4662
+ const _morphB = new import_three20.Vector3();
4663
+ const _morphC = new import_three20.Vector3();
4662
4664
  function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4663
4665
  _vA.fromBufferAttribute(attribute, a2);
4664
4666
  _vB.fromBufferAttribute(attribute, b2);
@@ -4853,8 +4855,8 @@ function computeMorphedAttributes(object) {
4853
4855
  }
4854
4856
  }
4855
4857
  }
4856
- const morphedPositionAttribute = new import_three21.Float32BufferAttribute(modifiedPosition, 3);
4857
- const morphedNormalAttribute = new import_three21.Float32BufferAttribute(modifiedNormal, 3);
4858
+ const morphedPositionAttribute = new import_three20.Float32BufferAttribute(modifiedPosition, 3);
4859
+ const morphedNormalAttribute = new import_three20.Float32BufferAttribute(modifiedNormal, 3);
4858
4860
  return {
4859
4861
  positionAttribute,
4860
4862
  normalAttribute,
@@ -4862,24 +4864,24 @@ function computeMorphedAttributes(object) {
4862
4864
  morphedNormalAttribute
4863
4865
  };
4864
4866
  }
4865
- var import_three21;
4867
+ var import_three20;
4866
4868
  var init_BufferGeometryUtils = __esm({
4867
4869
  "src/three/BufferGeometryUtils.js"() {
4868
- import_three21 = require("three");
4870
+ import_three20 = require("three");
4869
4871
  }
4870
4872
  });
4871
4873
 
4872
4874
  // src/model/ModelCulling.ts
4873
- var import_three22, ModelCulling;
4875
+ var import_three21, ModelCulling;
4874
4876
  var init_ModelCulling = __esm({
4875
4877
  "src/model/ModelCulling.ts"() {
4876
- import_three22 = require("three");
4878
+ import_three21 = require("three");
4877
4879
  init_CubeFace();
4878
4880
  ModelCulling = class {
4879
4881
  static toLocalMask(worldMask, rotation) {
4880
4882
  let localMask = 0;
4881
4883
  for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
4882
- const normal = new import_three22.Vector3(...offset).applyEuler(rotation);
4884
+ const normal = new import_three21.Vector3(...offset).applyEuler(rotation);
4883
4885
  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);
4884
4886
  if (worldFace < 0) return 0;
4885
4887
  if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
@@ -4912,10 +4914,10 @@ var init_ModelCulling = __esm({
4912
4914
  });
4913
4915
 
4914
4916
  // src/model/SpecialItems.ts
4915
- var import_three23, SpecialItems;
4917
+ var import_three22, SpecialItems;
4916
4918
  var init_SpecialItems = __esm({
4917
4919
  "src/model/SpecialItems.ts"() {
4918
- import_three23 = require("three");
4920
+ import_three22 = require("three");
4919
4921
  init_AssetKey();
4920
4922
  init_Entities();
4921
4923
  SpecialItems = class {
@@ -4943,7 +4945,7 @@ var init_SpecialItems = __esm({
4943
4945
  case "minecraft:chest":
4944
4946
  case "chest": {
4945
4947
  const angle = -(special.openness ?? 0) * Math.PI / 2;
4946
- const chest = await load("chest", texture(special.texture, "chest"), new import_three23.Matrix4(), {
4948
+ const chest = await load("chest", texture(special.texture, "chest"), new import_three22.Matrix4(), {
4947
4949
  lid: [angle, 0, 0],
4948
4950
  lock: [angle, 0, 0]
4949
4951
  });
@@ -4952,11 +4954,11 @@ var init_SpecialItems = __esm({
4952
4954
  }
4953
4955
  case "minecraft:bed":
4954
4956
  case "bed": {
4955
- 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));
4957
+ 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));
4956
4958
  const key = texture(special.texture, "bed");
4957
4959
  return Promise.all([
4958
4960
  load("bed_head", key, transform),
4959
- load("bed_foot", key, new import_three23.Matrix4().makeTranslation(0, 0, -16).multiply(transform))
4961
+ load("bed_foot", key, new import_three22.Matrix4().makeTranslation(0, 0, -16).multiply(transform))
4960
4962
  ]);
4961
4963
  }
4962
4964
  case "minecraft:head":
@@ -4981,7 +4983,7 @@ var init_SpecialItems = __esm({
4981
4983
  return [await load(
4982
4984
  id,
4983
4985
  special.texture ? texture(special.texture, "") : void 0,
4984
- new import_three23.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three23.Matrix4().makeScale(-1, -1, 1)),
4986
+ new import_three22.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three22.Matrix4().makeScale(-1, -1, 1)),
4985
4987
  rotations
4986
4988
  )];
4987
4989
  }
@@ -5109,13 +5111,13 @@ var init_ItemTints = __esm({
5109
5111
  function isModelObject(obj) {
5110
5112
  return obj.isModelObject;
5111
5113
  }
5112
- var import_three24, import_ts_deepmerge5, p7, ModelObject;
5114
+ var import_three23, import_ts_deepmerge5, p7, ModelObject;
5113
5115
  var init_ModelObject = __esm({
5114
5116
  "src/model/scene/ModelObject.ts"() {
5115
5117
  init_SceneObject();
5116
5118
  init_Materials();
5117
5119
  init_UVMapper();
5118
- import_three24 = require("three");
5120
+ import_three23 = require("three");
5119
5121
  init_BufferGeometryUtils();
5120
5122
  init_model();
5121
5123
  import_ts_deepmerge5 = __toESM(require_dist());
@@ -5150,12 +5152,13 @@ var init_ModelObject = __esm({
5150
5152
  const special = this.originalModel.special;
5151
5153
  if (special) {
5152
5154
  const parts = await SpecialItems.getParts(special, this.originalModel.key?.root);
5153
- const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new import_three24.Matrix4();
5154
- transform.multiply(new import_three24.Matrix4().makeTranslation(-8, -8, -8));
5155
+ const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new import_three23.Matrix4();
5156
+ transform.multiply(new import_three23.Matrix4().makeTranslation(-8, -8, -8));
5155
5157
  try {
5156
5158
  for (const part of parts) {
5157
5159
  const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5158
5160
  object.matrix.copy(transform).multiply(part.transform);
5161
+ object.matrixWorldNeedsUpdate = true;
5159
5162
  object.matrixAutoUpdate = false;
5160
5163
  this.add(object);
5161
5164
  await object.init();
@@ -5213,7 +5216,7 @@ var init_ModelObject = __esm({
5213
5216
  elGeo.clearGroups();
5214
5217
  }
5215
5218
  if (this.options.uvLockRotation) {
5216
- UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three24.Euler(...this.options.uvLockRotation));
5219
+ UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three23.Euler(...this.options.uvLockRotation));
5217
5220
  }
5218
5221
  if (this.options.tints) {
5219
5222
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
@@ -5222,19 +5225,19 @@ var init_ModelObject = __esm({
5222
5225
  if (tintIndex === void 0 || tintIndex < 0) continue;
5223
5226
  const tint = this.options.tints[tintIndex];
5224
5227
  if (tint === void 0) continue;
5225
- const color = new import_three24.Color(tint);
5228
+ const color = new import_three23.Color(tint);
5226
5229
  for (let vertex = 0; vertex < 4; vertex++) {
5227
5230
  color.toArray(colors, (faceIndex * 4 + vertex) * 3);
5228
5231
  }
5229
5232
  }
5230
- elGeo.setAttribute("color", new import_three24.BufferAttribute(colors, 3));
5233
+ elGeo.setAttribute("color", new import_three23.BufferAttribute(colors, 3));
5231
5234
  }
5232
- 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));
5233
- elGeo.applyMatrix4(new import_three24.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
5235
+ 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));
5236
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
5234
5237
  if (el.rotation) {
5235
5238
  applyElementRotation(el.rotation, elGeo);
5236
5239
  }
5237
- elGeo.applyMatrix4(new import_three24.Matrix4().makeTranslation(-8, -8, -8));
5240
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation(-8, -8, -8));
5238
5241
  if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
5239
5242
  if (this.options.mergeMeshes) {
5240
5243
  allGeos.push(elGeo);
@@ -5256,7 +5259,7 @@ var init_ModelObject = __esm({
5256
5259
  if (allGeos.length > 0) {
5257
5260
  combinedGeo = mergeBufferGeometries(allGeos);
5258
5261
  } else {
5259
- combinedGeo = new import_three24.BoxGeometry(16, 16, 16);
5262
+ combinedGeo = new import_three23.BoxGeometry(16, 16, 16);
5260
5263
  if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
5261
5264
  }
5262
5265
  combinedGeo.computeBoundingBox();
@@ -5366,7 +5369,7 @@ function ownHeight(sample) {
5366
5369
  return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
5367
5370
  }
5368
5371
  function createFluidGeometry(kind, sample) {
5369
- const geometry = new import_three29.BufferGeometry();
5372
+ const geometry = new import_three28.BufferGeometry();
5370
5373
  const positions = [], normals = [], uvs = [], indices = [];
5371
5374
  const self = sample(0, 0, 0);
5372
5375
  const height = (x, z) => {
@@ -5465,16 +5468,16 @@ function createFluidGeometry(kind, sample) {
5465
5468
  1
5466
5469
  );
5467
5470
  }
5468
- geometry.setAttribute("position", new import_three29.Float32BufferAttribute(positions, 3));
5469
- geometry.setAttribute("normal", new import_three29.Float32BufferAttribute(normals, 3));
5470
- geometry.setAttribute("uv", new import_three29.Float32BufferAttribute(uvs, 2));
5471
+ geometry.setAttribute("position", new import_three28.Float32BufferAttribute(positions, 3));
5472
+ geometry.setAttribute("normal", new import_three28.Float32BufferAttribute(normals, 3));
5473
+ geometry.setAttribute("uv", new import_three28.Float32BufferAttribute(uvs, 2));
5471
5474
  geometry.setIndex(indices);
5472
5475
  return geometry;
5473
5476
  }
5474
- var import_three29, fluidRules, HORIZONTAL, EPSILON;
5477
+ var import_three28, fluidRules, HORIZONTAL, EPSILON;
5475
5478
  var init_FluidGeometry = __esm({
5476
5479
  "src/model/fluid/FluidGeometry.ts"() {
5477
- import_three29 = require("three");
5480
+ import_three28 = require("three");
5478
5481
  init_fluidBlocks();
5479
5482
  fluidRules = fluidBlocks_default;
5480
5483
  HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]];
@@ -5503,10 +5506,10 @@ function sampleFluid(kind, sample) {
5503
5506
  }
5504
5507
  return { key: key.join(""), sample: (x, y, z) => cells[(y + 1) * 9 + (z + 1) * 3 + x + 1] };
5505
5508
  }
5506
- var import_three30, FluidModelObject;
5509
+ var import_three29, FluidModelObject;
5507
5510
  var init_FluidModelObject = __esm({
5508
5511
  "src/model/fluid/FluidModelObject.ts"() {
5509
- import_three30 = require("three");
5512
+ import_three29 = require("three");
5510
5513
  init_AssetKey();
5511
5514
  init_Materials();
5512
5515
  init_ModelObject();
@@ -5539,10 +5542,10 @@ var init_FluidModelObject = __esm({
5539
5542
  }
5540
5543
  }
5541
5544
  geometry.clearGroups();
5542
- const color = new import_three30.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
5545
+ const color = new import_three29.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
5543
5546
  const colors = new Float32Array(geometry.getAttribute("position").count * 3);
5544
5547
  for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
5545
- geometry.setAttribute("color", new import_three30.BufferAttribute(colors, 3));
5548
+ geometry.setAttribute("color", new import_three29.BufferAttribute(colors, 3));
5546
5549
  geometry.computeBoundingBox();
5547
5550
  geometry.computeBoundingSphere();
5548
5551
  if (this.options.instanceMeshes) {
@@ -5556,7 +5559,7 @@ var init_FluidModelObject = __esm({
5556
5559
  super.applyTextures();
5557
5560
  this.iterateAllMeshes((mesh) => {
5558
5561
  const material = mesh.material;
5559
- material.side = import_three30.DoubleSide;
5562
+ material.side = import_three29.DoubleSide;
5560
5563
  material.forceSinglePass = true;
5561
5564
  material.depthWrite = !material.transparent;
5562
5565
  });
@@ -6004,11 +6007,19 @@ init_EntityObject();
6004
6007
  init_MineRenderError();
6005
6008
 
6006
6009
  // src/export/SceneExporter.ts
6007
- var import_three20 = require("three");
6010
+ var import_three19 = require("three");
6008
6011
 
6009
6012
  // ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
6010
6013
  var import_three16 = require("three");
6011
6014
  var OBJExporter = class {
6015
+ /**
6016
+ * Parses the given 3D object and generates the OBJ output.
6017
+ *
6018
+ * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
6019
+ *
6020
+ * @param {Object3D} object - The 3D object to export.
6021
+ * @return {string} The exported OBJ.
6022
+ */
6012
6023
  parse(object) {
6013
6024
  let output = "";
6014
6025
  let indexVertex = 0;
@@ -6114,7 +6125,8 @@ var OBJExporter = class {
6114
6125
  vertex.applyMatrix4(points.matrixWorld);
6115
6126
  output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
6116
6127
  if (colors !== void 0) {
6117
- color.fromBufferAttribute(colors, i).convertLinearToSRGB();
6128
+ color.fromBufferAttribute(colors, i);
6129
+ import_three16.ColorManagement.workingToColorSpace(color, import_three16.SRGBColorSpace);
6118
6130
  output += " " + color.r + " " + color.g + " " + color.b;
6119
6131
  }
6120
6132
  output += "\n";
@@ -6145,6 +6157,16 @@ var OBJExporter = class {
6145
6157
  // ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
6146
6158
  var import_three17 = require("three");
6147
6159
  var PLYExporter = class {
6160
+ /**
6161
+ * Parses the given 3D object and generates the PLY output.
6162
+ *
6163
+ * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
6164
+ *
6165
+ * @param {Object3D} object - The 3D object to export.
6166
+ * @param {PLYExporter~OnDone} onDone - A callback function that is executed when the export has finished.
6167
+ * @param {PLYExporter~Options} options - The export options.
6168
+ * @return {?(string|ArrayBuffer)} The exported PLY.
6169
+ */
6148
6170
  parse(object, onDone, options = {}) {
6149
6171
  function traverseMeshes(cb) {
6150
6172
  object.traverse(function(child) {
@@ -6161,14 +6183,23 @@ var PLYExporter = class {
6161
6183
  binary: false,
6162
6184
  excludeAttributes: [],
6163
6185
  // normal, uv, color, index
6164
- littleEndian: false
6186
+ littleEndian: false,
6187
+ customPropertyMapping: {}
6165
6188
  };
6166
6189
  options = Object.assign(defaultOptions, options);
6167
6190
  const excludeAttributes = options.excludeAttributes;
6191
+ const customPropertyMapping = options.customPropertyMapping;
6192
+ const customAttributeNames = Object.keys(customPropertyMapping);
6168
6193
  let includeIndices = true;
6169
6194
  let includeNormals = false;
6170
6195
  let includeColors = false;
6171
6196
  let includeUVs = false;
6197
+ let positionType = "float";
6198
+ let normalType = "float";
6199
+ let uvType = "float";
6200
+ let colorType = "uchar";
6201
+ const customTypes = {};
6202
+ for (const name of customAttributeNames) customTypes[name] = "float";
6172
6203
  let vertexCount = 0;
6173
6204
  let faceCount = 0;
6174
6205
  object.traverse(function(child) {
@@ -6185,9 +6216,23 @@ var PLYExporter = class {
6185
6216
  }
6186
6217
  vertexCount += vertices.count;
6187
6218
  faceCount += indices ? indices.count / 3 : vertices.count / 3;
6188
- if (normals !== void 0) includeNormals = true;
6189
- if (uvs !== void 0) includeUVs = true;
6190
- if (colors !== void 0) includeColors = true;
6219
+ positionType = getPlyType(vertices.array);
6220
+ if (normals !== void 0) {
6221
+ includeNormals = true;
6222
+ normalType = getPlyType(normals.array);
6223
+ }
6224
+ if (uvs !== void 0) {
6225
+ includeUVs = true;
6226
+ uvType = getPlyType(uvs.array);
6227
+ }
6228
+ if (colors !== void 0) {
6229
+ includeColors = true;
6230
+ colorType = getPlyType(colors.array);
6231
+ }
6232
+ for (const name of customAttributeNames) {
6233
+ const attr = geometry.getAttribute(name);
6234
+ if (attr !== void 0) customTypes[name] = getPlyType(attr.array);
6235
+ }
6191
6236
  } else if (child.isPoints) {
6192
6237
  const mesh = child;
6193
6238
  const geometry = mesh.geometry;
@@ -6195,8 +6240,19 @@ var PLYExporter = class {
6195
6240
  const normals = geometry.getAttribute("normal");
6196
6241
  const colors = geometry.getAttribute("color");
6197
6242
  vertexCount += vertices.count;
6198
- if (normals !== void 0) includeNormals = true;
6199
- if (colors !== void 0) includeColors = true;
6243
+ positionType = getPlyType(vertices.array);
6244
+ if (normals !== void 0) {
6245
+ includeNormals = true;
6246
+ normalType = getPlyType(normals.array);
6247
+ }
6248
+ if (colors !== void 0) {
6249
+ includeColors = true;
6250
+ colorType = getPlyType(colors.array);
6251
+ }
6252
+ for (const name of customAttributeNames) {
6253
+ const attr = geometry.getAttribute(name);
6254
+ if (attr !== void 0) customTypes[name] = getPlyType(attr.array);
6255
+ }
6200
6256
  includeIndices = false;
6201
6257
  }
6202
6258
  });
@@ -6215,18 +6271,33 @@ var PLYExporter = class {
6215
6271
  let header = `ply
6216
6272
  format ${options.binary ? options.littleEndian ? "binary_little_endian" : "binary_big_endian" : "ascii"} 1.0
6217
6273
  element vertex ${vertexCount}
6218
- property float x
6219
- property float y
6220
- property float z
6274
+ property ${positionType} x
6275
+ property ${positionType} y
6276
+ property ${positionType} z
6221
6277
  `;
6222
6278
  if (includeNormals === true) {
6223
- header += "property float nx\nproperty float ny\nproperty float nz\n";
6279
+ header += `property ${normalType} nx
6280
+ property ${normalType} ny
6281
+ property ${normalType} nz
6282
+ `;
6224
6283
  }
6225
6284
  if (includeUVs === true) {
6226
- header += "property float s\nproperty float t\n";
6285
+ header += `property ${uvType} s
6286
+ property ${uvType} t
6287
+ `;
6227
6288
  }
6228
6289
  if (includeColors === true) {
6229
- header += "property uchar red\nproperty uchar green\nproperty uchar blue\n";
6290
+ header += `property ${colorType} red
6291
+ property ${colorType} green
6292
+ property ${colorType} blue
6293
+ `;
6294
+ }
6295
+ for (const name of customAttributeNames) {
6296
+ const type = customTypes[name];
6297
+ for (const propName of customPropertyMapping[name]) {
6298
+ header += `property ${type} ${propName}
6299
+ `;
6300
+ }
6230
6301
  }
6231
6302
  if (includeIndices === true) {
6232
6303
  header += `element face ${faceCount}
@@ -6239,7 +6310,23 @@ property list uchar int vertex_index
6239
6310
  let result = null;
6240
6311
  if (options.binary === true) {
6241
6312
  const headerBin = new TextEncoder().encode(header);
6242
- const vertexListLength = vertexCount * (4 * 3 + (includeNormals ? 4 * 3 : 0) + (includeColors ? 3 : 0) + (includeUVs ? 4 * 2 : 0));
6313
+ const posWriter = getBinaryWriter(positionType);
6314
+ const normalWriter = includeNormals ? getBinaryWriter(normalType) : null;
6315
+ const uvWriter = includeUVs ? getBinaryWriter(uvType) : null;
6316
+ const colorWriter = includeColors ? getBinaryWriter(colorType) : null;
6317
+ const colorIsFloat = isFloatType(colorType);
6318
+ const colorScale = getColorScale(colorType);
6319
+ const customWriters = {};
6320
+ const customIsFloat = {};
6321
+ let customStride = 0;
6322
+ for (const name of customAttributeNames) {
6323
+ const type = customTypes[name];
6324
+ const writer = getBinaryWriter(type);
6325
+ customWriters[name] = writer;
6326
+ customIsFloat[name] = isFloatType(type);
6327
+ customStride += customPropertyMapping[name].length * writer.size;
6328
+ }
6329
+ const vertexListLength = vertexCount * (3 * posWriter.size + (includeNormals ? 3 * normalWriter.size : 0) + (includeUVs ? 2 * uvWriter.size : 0) + (includeColors ? 3 * colorWriter.size : 0) + customStride);
6243
6330
  const faceListLength = includeIndices ? faceCount * (indexByteCount * 3 + 1) : 0;
6244
6331
  const output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
6245
6332
  new Uint8Array(output.buffer).set(headerBin, 0);
@@ -6256,60 +6343,76 @@ property list uchar int vertex_index
6256
6343
  for (let i = 0, l = vertices.count; i < l; i++) {
6257
6344
  vertex.fromBufferAttribute(vertices, i);
6258
6345
  vertex.applyMatrix4(mesh.matrixWorld);
6259
- output.setFloat32(vOffset, vertex.x, options.littleEndian);
6260
- vOffset += 4;
6261
- output.setFloat32(vOffset, vertex.y, options.littleEndian);
6262
- vOffset += 4;
6263
- output.setFloat32(vOffset, vertex.z, options.littleEndian);
6264
- vOffset += 4;
6346
+ posWriter.write(output, vOffset, vertex.x, options.littleEndian);
6347
+ vOffset += posWriter.size;
6348
+ posWriter.write(output, vOffset, vertex.y, options.littleEndian);
6349
+ vOffset += posWriter.size;
6350
+ posWriter.write(output, vOffset, vertex.z, options.littleEndian);
6351
+ vOffset += posWriter.size;
6265
6352
  if (includeNormals === true) {
6266
6353
  if (normals != null) {
6267
6354
  vertex.fromBufferAttribute(normals, i);
6268
6355
  vertex.applyMatrix3(normalMatrixWorld).normalize();
6269
- output.setFloat32(vOffset, vertex.x, options.littleEndian);
6270
- vOffset += 4;
6271
- output.setFloat32(vOffset, vertex.y, options.littleEndian);
6272
- vOffset += 4;
6273
- output.setFloat32(vOffset, vertex.z, options.littleEndian);
6274
- vOffset += 4;
6356
+ normalWriter.write(output, vOffset, vertex.x, options.littleEndian);
6357
+ vOffset += normalWriter.size;
6358
+ normalWriter.write(output, vOffset, vertex.y, options.littleEndian);
6359
+ vOffset += normalWriter.size;
6360
+ normalWriter.write(output, vOffset, vertex.z, options.littleEndian);
6361
+ vOffset += normalWriter.size;
6275
6362
  } else {
6276
- output.setFloat32(vOffset, 0, options.littleEndian);
6277
- vOffset += 4;
6278
- output.setFloat32(vOffset, 0, options.littleEndian);
6279
- vOffset += 4;
6280
- output.setFloat32(vOffset, 0, options.littleEndian);
6281
- vOffset += 4;
6363
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6364
+ vOffset += normalWriter.size;
6365
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6366
+ vOffset += normalWriter.size;
6367
+ normalWriter.write(output, vOffset, 0, options.littleEndian);
6368
+ vOffset += normalWriter.size;
6282
6369
  }
6283
6370
  }
6284
6371
  if (includeUVs === true) {
6285
6372
  if (uvs != null) {
6286
- output.setFloat32(vOffset, uvs.getX(i), options.littleEndian);
6287
- vOffset += 4;
6288
- output.setFloat32(vOffset, uvs.getY(i), options.littleEndian);
6289
- vOffset += 4;
6373
+ uvWriter.write(output, vOffset, uvs.getX(i), options.littleEndian);
6374
+ vOffset += uvWriter.size;
6375
+ uvWriter.write(output, vOffset, uvs.getY(i), options.littleEndian);
6376
+ vOffset += uvWriter.size;
6290
6377
  } else {
6291
- output.setFloat32(vOffset, 0, options.littleEndian);
6292
- vOffset += 4;
6293
- output.setFloat32(vOffset, 0, options.littleEndian);
6294
- vOffset += 4;
6378
+ uvWriter.write(output, vOffset, 0, options.littleEndian);
6379
+ vOffset += uvWriter.size;
6380
+ uvWriter.write(output, vOffset, 0, options.littleEndian);
6381
+ vOffset += uvWriter.size;
6295
6382
  }
6296
6383
  }
6297
6384
  if (includeColors === true) {
6298
6385
  if (colors != null) {
6299
- tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
6300
- output.setUint8(vOffset, Math.floor(tempColor.r * 255));
6301
- vOffset += 1;
6302
- output.setUint8(vOffset, Math.floor(tempColor.g * 255));
6303
- vOffset += 1;
6304
- output.setUint8(vOffset, Math.floor(tempColor.b * 255));
6305
- vOffset += 1;
6386
+ tempColor.fromBufferAttribute(colors, i);
6387
+ import_three17.ColorManagement.workingToColorSpace(tempColor, import_three17.SRGBColorSpace);
6388
+ const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
6389
+ const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
6390
+ const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
6391
+ colorWriter.write(output, vOffset, r, options.littleEndian);
6392
+ vOffset += colorWriter.size;
6393
+ colorWriter.write(output, vOffset, g, options.littleEndian);
6394
+ vOffset += colorWriter.size;
6395
+ colorWriter.write(output, vOffset, b, options.littleEndian);
6396
+ vOffset += colorWriter.size;
6306
6397
  } else {
6307
- output.setUint8(vOffset, 255);
6308
- vOffset += 1;
6309
- output.setUint8(vOffset, 255);
6310
- vOffset += 1;
6311
- output.setUint8(vOffset, 255);
6312
- vOffset += 1;
6398
+ const white = colorIsFloat ? 1 : colorScale;
6399
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6400
+ vOffset += colorWriter.size;
6401
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6402
+ vOffset += colorWriter.size;
6403
+ colorWriter.write(output, vOffset, white, options.littleEndian);
6404
+ vOffset += colorWriter.size;
6405
+ }
6406
+ }
6407
+ for (const name of customAttributeNames) {
6408
+ const writer = customWriters[name];
6409
+ const propCount = customPropertyMapping[name].length;
6410
+ const attr = geometry.getAttribute(name);
6411
+ const isFloat = customIsFloat[name];
6412
+ for (let c = 0; c < propCount; c++) {
6413
+ const raw = attr != null ? getAttributeComponent(attr, i, c) : 0;
6414
+ writer.write(output, vOffset, isFloat ? raw : Math.round(raw), options.littleEndian);
6415
+ vOffset += writer.size;
6313
6416
  }
6314
6417
  }
6315
6418
  }
@@ -6345,6 +6448,14 @@ property list uchar int vertex_index
6345
6448
  let writtenVertices = 0;
6346
6449
  let vertexList = "";
6347
6450
  let faceList = "";
6451
+ const positionIsFloat = isFloatType(positionType);
6452
+ const normalIsFloat = isFloatType(normalType);
6453
+ const uvIsFloat = isFloatType(uvType);
6454
+ const colorIsFloat = isFloatType(colorType);
6455
+ const colorScale = getColorScale(colorType);
6456
+ const customIsFloat = {};
6457
+ for (const name of customAttributeNames) customIsFloat[name] = isFloatType(customTypes[name]);
6458
+ const encode = (v, isFloat) => isFloat ? v : Math.round(v);
6348
6459
  traverseMeshes(function(mesh, geometry) {
6349
6460
  const vertices = geometry.getAttribute("position");
6350
6461
  const normals = geometry.getAttribute("normal");
@@ -6355,29 +6466,43 @@ property list uchar int vertex_index
6355
6466
  for (let i = 0, l = vertices.count; i < l; i++) {
6356
6467
  vertex.fromBufferAttribute(vertices, i);
6357
6468
  vertex.applyMatrix4(mesh.matrixWorld);
6358
- let line = vertex.x + " " + vertex.y + " " + vertex.z;
6469
+ let line = encode(vertex.x, positionIsFloat) + " " + encode(vertex.y, positionIsFloat) + " " + encode(vertex.z, positionIsFloat);
6359
6470
  if (includeNormals === true) {
6360
6471
  if (normals != null) {
6361
6472
  vertex.fromBufferAttribute(normals, i);
6362
6473
  vertex.applyMatrix3(normalMatrixWorld).normalize();
6363
- line += " " + vertex.x + " " + vertex.y + " " + vertex.z;
6474
+ line += " " + encode(vertex.x, normalIsFloat) + " " + encode(vertex.y, normalIsFloat) + " " + encode(vertex.z, normalIsFloat);
6364
6475
  } else {
6365
6476
  line += " 0 0 0";
6366
6477
  }
6367
6478
  }
6368
6479
  if (includeUVs === true) {
6369
6480
  if (uvs != null) {
6370
- line += " " + uvs.getX(i) + " " + uvs.getY(i);
6481
+ line += " " + encode(uvs.getX(i), uvIsFloat) + " " + encode(uvs.getY(i), uvIsFloat);
6371
6482
  } else {
6372
6483
  line += " 0 0";
6373
6484
  }
6374
6485
  }
6375
6486
  if (includeColors === true) {
6376
6487
  if (colors != null) {
6377
- tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
6378
- line += " " + Math.floor(tempColor.r * 255) + " " + Math.floor(tempColor.g * 255) + " " + Math.floor(tempColor.b * 255);
6488
+ tempColor.fromBufferAttribute(colors, i);
6489
+ import_three17.ColorManagement.workingToColorSpace(tempColor, import_three17.SRGBColorSpace);
6490
+ const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
6491
+ const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
6492
+ const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
6493
+ line += ` ${r} ${g} ${b}`;
6379
6494
  } else {
6380
- line += " 255 255 255";
6495
+ const white = colorIsFloat ? 1 : colorScale;
6496
+ line += ` ${white} ${white} ${white}`;
6497
+ }
6498
+ }
6499
+ for (const name of customAttributeNames) {
6500
+ const propCount = customPropertyMapping[name].length;
6501
+ const attr = geometry.getAttribute(name);
6502
+ const isFloat = customIsFloat[name];
6503
+ for (let c = 0; c < propCount; c++) {
6504
+ const raw = attr != null ? getAttributeComponent(attr, i, c) : 0;
6505
+ line += " " + encode(raw, isFloat);
6381
6506
  }
6382
6507
  }
6383
6508
  vertexList += line + "\n";
@@ -6407,70 +6532,65 @@ property list uchar int vertex_index
6407
6532
  return result;
6408
6533
  }
6409
6534
  };
6410
-
6411
- // ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
6412
- var import_three19 = require("three");
6413
-
6414
- // ../../node_modules/three/examples/jsm/utils/TextureUtils.js
6415
- var import_three18 = require("three");
6416
- var _renderer;
6417
- var fullscreenQuadGeometry;
6418
- var fullscreenQuadMaterial;
6419
- var fullscreenQuad;
6420
- function decompress(texture, maxTextureSize = Infinity, renderer = null) {
6421
- if (!fullscreenQuadGeometry) fullscreenQuadGeometry = new import_three18.PlaneGeometry(2, 2, 1, 1);
6422
- if (!fullscreenQuadMaterial) fullscreenQuadMaterial = new import_three18.ShaderMaterial({
6423
- uniforms: { blitTexture: new import_three18.Uniform(texture) },
6424
- vertexShader: `
6425
- varying vec2 vUv;
6426
- void main(){
6427
- vUv = uv;
6428
- gl_Position = vec4(position.xy * 1.0,0.,.999999);
6429
- }`,
6430
- fragmentShader: `
6431
- uniform sampler2D blitTexture;
6432
- varying vec2 vUv;
6433
-
6434
- void main(){
6435
- gl_FragColor = vec4(vUv.xy, 0, 1);
6436
-
6437
- #ifdef IS_SRGB
6438
- gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
6439
- #else
6440
- gl_FragColor = texture2D( blitTexture, vUv);
6441
- #endif
6442
- }`
6443
- });
6444
- fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
6445
- fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == import_three18.SRGBColorSpace;
6446
- fullscreenQuadMaterial.needsUpdate = true;
6447
- if (!fullscreenQuad) {
6448
- fullscreenQuad = new import_three18.Mesh(fullscreenQuadGeometry, fullscreenQuadMaterial);
6449
- fullscreenQuad.frustrumCulled = false;
6450
- }
6451
- const _camera = new import_three18.PerspectiveCamera();
6452
- const _scene = new import_three18.Scene();
6453
- _scene.add(fullscreenQuad);
6454
- if (!renderer) {
6455
- renderer = _renderer = new import_three18.WebGLRenderer({ antialias: false });
6456
- }
6457
- renderer.setSize(Math.min(texture.image.width, maxTextureSize), Math.min(texture.image.height, maxTextureSize));
6458
- renderer.clear();
6459
- renderer.render(_scene, _camera);
6460
- const readableTexture = new import_three18.Texture(renderer.domElement);
6461
- readableTexture.minFilter = texture.minFilter;
6462
- readableTexture.magFilter = texture.magFilter;
6463
- readableTexture.wrapS = texture.wrapS;
6464
- readableTexture.wrapT = texture.wrapT;
6465
- readableTexture.name = texture.name;
6466
- if (_renderer) {
6467
- _renderer.dispose();
6468
- _renderer = null;
6469
- }
6470
- return readableTexture;
6535
+ function getPlyType(array) {
6536
+ if (array instanceof Int8Array) return "char";
6537
+ if (array instanceof Uint8Array || array instanceof Uint8ClampedArray) return "uchar";
6538
+ if (array instanceof Int16Array) return "short";
6539
+ if (array instanceof Uint16Array) return "ushort";
6540
+ if (array instanceof Int32Array) return "int";
6541
+ if (array instanceof Uint32Array) return "uint";
6542
+ if (array instanceof Float32Array) return "float";
6543
+ if (array instanceof Float64Array) return "double";
6544
+ return "float";
6545
+ }
6546
+ function getBinaryWriter(type) {
6547
+ switch (type) {
6548
+ case "char":
6549
+ return { write: (dv, at, v) => dv.setInt8(at, v), size: 1 };
6550
+ case "uchar":
6551
+ return { write: (dv, at, v) => dv.setUint8(at, v), size: 1 };
6552
+ case "short":
6553
+ return { write: (dv, at, v, le) => dv.setInt16(at, v, le), size: 2 };
6554
+ case "ushort":
6555
+ return { write: (dv, at, v, le) => dv.setUint16(at, v, le), size: 2 };
6556
+ case "int":
6557
+ return { write: (dv, at, v, le) => dv.setInt32(at, v, le), size: 4 };
6558
+ case "uint":
6559
+ return { write: (dv, at, v, le) => dv.setUint32(at, v, le), size: 4 };
6560
+ case "float":
6561
+ return { write: (dv, at, v, le) => dv.setFloat32(at, v, le), size: 4 };
6562
+ case "double":
6563
+ return { write: (dv, at, v, le) => dv.setFloat64(at, v, le), size: 8 };
6564
+ }
6565
+ }
6566
+ function isFloatType(type) {
6567
+ return type === "float" || type === "double";
6568
+ }
6569
+ function getAttributeComponent(attr, i, c) {
6570
+ switch (c) {
6571
+ case 0:
6572
+ return attr.getX(i);
6573
+ case 1:
6574
+ return attr.getY(i);
6575
+ case 2:
6576
+ return attr.getZ(i);
6577
+ case 3:
6578
+ return attr.getW(i);
6579
+ }
6580
+ }
6581
+ function getColorScale(type) {
6582
+ switch (type) {
6583
+ case "uchar":
6584
+ return 255;
6585
+ case "ushort":
6586
+ return 65535;
6587
+ default:
6588
+ return 1;
6589
+ }
6471
6590
  }
6472
6591
 
6473
6592
  // ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
6593
+ var import_three18 = require("three");
6474
6594
  var KHR_mesh_quantization_ExtraAttrTypes = {
6475
6595
  POSITION: [
6476
6596
  "byte",
@@ -6500,7 +6620,11 @@ var KHR_mesh_quantization_ExtraAttrTypes = {
6500
6620
  ]
6501
6621
  };
6502
6622
  var GLTFExporter = class {
6623
+ /**
6624
+ * Constructs a new glTF exporter.
6625
+ */
6503
6626
  constructor() {
6627
+ this.textureUtils = null;
6504
6628
  this.pluginCallbacks = [];
6505
6629
  this.register(function(writer) {
6506
6630
  return new GLTFLightExtension(writer);
@@ -6523,6 +6647,9 @@ var GLTFExporter = class {
6523
6647
  this.register(function(writer) {
6524
6648
  return new GLTFMaterialsClearcoatExtension(writer);
6525
6649
  });
6650
+ this.register(function(writer) {
6651
+ return new GLTFMaterialsDispersionExtension(writer);
6652
+ });
6526
6653
  this.register(function(writer) {
6527
6654
  return new GLTFMaterialsIridescenceExtension(writer);
6528
6655
  });
@@ -6535,16 +6662,33 @@ var GLTFExporter = class {
6535
6662
  this.register(function(writer) {
6536
6663
  return new GLTFMaterialsEmissiveStrengthExtension(writer);
6537
6664
  });
6665
+ this.register(function(writer) {
6666
+ return new GLTFMaterialsBumpExtension(writer);
6667
+ });
6538
6668
  this.register(function(writer) {
6539
6669
  return new GLTFMeshGpuInstancing(writer);
6540
6670
  });
6541
6671
  }
6672
+ /**
6673
+ * Registers a plugin callback. This API is internally used to implement the various
6674
+ * glTF extensions but can also used by third-party code to add additional logic
6675
+ * to the exporter.
6676
+ *
6677
+ * @param {function(writer:GLTFWriter)} callback - The callback function to register.
6678
+ * @return {GLTFExporter} A reference to this exporter.
6679
+ */
6542
6680
  register(callback) {
6543
6681
  if (this.pluginCallbacks.indexOf(callback) === -1) {
6544
6682
  this.pluginCallbacks.push(callback);
6545
6683
  }
6546
6684
  return this;
6547
6685
  }
6686
+ /**
6687
+ * Unregisters a plugin callback.
6688
+ *
6689
+ * @param {Function} callback - The callback function to unregister.
6690
+ * @return {GLTFExporter} A reference to this exporter.
6691
+ */
6548
6692
  unregister(callback) {
6549
6693
  if (this.pluginCallbacks.indexOf(callback) !== -1) {
6550
6694
  this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
@@ -6552,11 +6696,25 @@ var GLTFExporter = class {
6552
6696
  return this;
6553
6697
  }
6554
6698
  /**
6555
- * Parse scenes and generate GLTF output
6556
- * @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
6557
- * @param {Function} onDone Callback on completed
6558
- * @param {Function} onError Callback on errors
6559
- * @param {Object} options options
6699
+ * Sets the texture utils for this exporter. Only relevant when compressed textures have to be exported.
6700
+ *
6701
+ * Depending on whether you use {@link WebGLRenderer} or {@link WebGPURenderer}, you must inject the
6702
+ * corresponding texture utils {@link module:WebGLTextureUtils} or {@link module:WebGPUTextureUtils}.
6703
+ *
6704
+ * @param {WebGLTextureUtils|WebGPUTextureUtils} utils - The texture utils.
6705
+ * @return {GLTFExporter} A reference to this exporter.
6706
+ */
6707
+ setTextureUtils(utils) {
6708
+ this.textureUtils = utils;
6709
+ return this;
6710
+ }
6711
+ /**
6712
+ * Parses the given scenes and generates the glTF output.
6713
+ *
6714
+ * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
6715
+ * @param {GLTFExporter~OnDone} onDone - A callback function that is executed when the export has finished.
6716
+ * @param {GLTFExporter~OnError} onError - A callback function that is executed when an error happens.
6717
+ * @param {GLTFExporter~Options} options - options
6560
6718
  */
6561
6719
  parse(input, onDone, onError, options) {
6562
6720
  const writer = new GLTFWriter();
@@ -6565,8 +6723,16 @@ var GLTFExporter = class {
6565
6723
  plugins.push(this.pluginCallbacks[i](writer));
6566
6724
  }
6567
6725
  writer.setPlugins(plugins);
6568
- writer.write(input, onDone, options).catch(onError);
6726
+ writer.setTextureUtils(this.textureUtils);
6727
+ writer.writeAsync(input, onDone, options).catch(onError);
6569
6728
  }
6729
+ /**
6730
+ * Async version of {@link GLTFExporter#parse}.
6731
+ *
6732
+ * @param {Scene|Array<Scene>} input - A scene or an array of scenes.
6733
+ * @param {GLTFExporter~Options} options - options.
6734
+ * @return {Promise<ArrayBuffer|string>} A Promise that resolved with the exported glTF data.
6735
+ */
6570
6736
  parseAsync(input, options) {
6571
6737
  const scope = this;
6572
6738
  return new Promise(function(resolve, reject) {
@@ -6603,22 +6769,22 @@ var WEBGL_CONSTANTS = {
6603
6769
  };
6604
6770
  var KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
6605
6771
  var THREE_TO_WEBGL = {};
6606
- THREE_TO_WEBGL[import_three19.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
6607
- THREE_TO_WEBGL[import_three19.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
6608
- THREE_TO_WEBGL[import_three19.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
6609
- THREE_TO_WEBGL[import_three19.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
6610
- THREE_TO_WEBGL[import_three19.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
6611
- THREE_TO_WEBGL[import_three19.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
6612
- THREE_TO_WEBGL[import_three19.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
6613
- THREE_TO_WEBGL[import_three19.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
6614
- THREE_TO_WEBGL[import_three19.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
6772
+ THREE_TO_WEBGL[import_three18.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
6773
+ THREE_TO_WEBGL[import_three18.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
6774
+ THREE_TO_WEBGL[import_three18.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
6775
+ THREE_TO_WEBGL[import_three18.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
6776
+ THREE_TO_WEBGL[import_three18.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
6777
+ THREE_TO_WEBGL[import_three18.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
6778
+ THREE_TO_WEBGL[import_three18.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
6779
+ THREE_TO_WEBGL[import_three18.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
6780
+ THREE_TO_WEBGL[import_three18.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
6615
6781
  var PATH_PROPERTIES = {
6616
6782
  scale: "scale",
6617
6783
  position: "translation",
6618
6784
  quaternion: "rotation",
6619
6785
  morphTargetInfluences: "weights"
6620
6786
  };
6621
- var DEFAULT_SPECULAR_COLOR = new import_three19.Color();
6787
+ var DEFAULT_SPECULAR_COLOR = new import_three18.Color();
6622
6788
  var GLB_HEADER_BYTES = 12;
6623
6789
  var GLB_HEADER_MAGIC = 1179937895;
6624
6790
  var GLB_VERSION = 2;
@@ -6652,7 +6818,7 @@ function getMinMax(attribute, start, count) {
6652
6818
  else if (a === 2) value = attribute.getZ(i);
6653
6819
  else if (a === 3) value = attribute.getW(i);
6654
6820
  if (attribute.normalized === true) {
6655
- value = import_three19.MathUtils.normalize(value, attribute.array);
6821
+ value = import_three18.MathUtils.normalize(value, attribute.array);
6656
6822
  }
6657
6823
  }
6658
6824
  output.min[a] = Math.min(output.min[a], value);
@@ -6685,19 +6851,20 @@ function getCanvas() {
6685
6851
  return document.createElement("canvas");
6686
6852
  }
6687
6853
  function getToBlobPromise(canvas, mimeType) {
6688
- if (canvas.toBlob !== void 0) {
6854
+ if (typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas) {
6855
+ let quality;
6856
+ if (mimeType === "image/jpeg") {
6857
+ quality = 0.92;
6858
+ } else if (mimeType === "image/webp") {
6859
+ quality = 0.8;
6860
+ }
6861
+ return canvas.convertToBlob({
6862
+ type: mimeType,
6863
+ quality
6864
+ });
6865
+ } else {
6689
6866
  return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
6690
6867
  }
6691
- let quality;
6692
- if (mimeType === "image/jpeg") {
6693
- quality = 0.92;
6694
- } else if (mimeType === "image/webp") {
6695
- quality = 0.8;
6696
- }
6697
- return canvas.convertToBlob({
6698
- type: mimeType,
6699
- quality
6700
- });
6701
6868
  }
6702
6869
  var GLTFWriter = class {
6703
6870
  constructor() {
@@ -6716,7 +6883,7 @@ var GLTFWriter = class {
6716
6883
  this.json = {
6717
6884
  asset: {
6718
6885
  version: "2.0",
6719
- generator: "THREE.GLTFExporter"
6886
+ generator: "THREE.GLTFExporter r" + import_three18.REVISION
6720
6887
  }
6721
6888
  };
6722
6889
  this.cache = {
@@ -6725,19 +6892,25 @@ var GLTFWriter = class {
6725
6892
  attributesNormalized: /* @__PURE__ */ new Map(),
6726
6893
  materials: /* @__PURE__ */ new Map(),
6727
6894
  textures: /* @__PURE__ */ new Map(),
6728
- images: /* @__PURE__ */ new Map()
6895
+ images: /* @__PURE__ */ new Map(),
6896
+ normalMaps: /* @__PURE__ */ new Map()
6729
6897
  };
6898
+ this.textureUtils = null;
6730
6899
  }
6731
6900
  setPlugins(plugins) {
6732
6901
  this.plugins = plugins;
6733
6902
  }
6903
+ setTextureUtils(utils) {
6904
+ this.textureUtils = utils;
6905
+ }
6734
6906
  /**
6735
6907
  * Parse scenes and generate GLTF output
6736
- * @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
6737
- * @param {Function} onDone Callback on completed
6738
- * @param {Object} options options
6908
+ *
6909
+ * @param {Scene|Array<Scene>} input Scene or Array of THREE.Scenes
6910
+ * @param {Function} onDone Callback on completed
6911
+ * @param {Object} options options
6739
6912
  */
6740
- async write(input, onDone, options = {}) {
6913
+ async writeAsync(input, onDone, options = {}) {
6741
6914
  this.options = Object.assign({
6742
6915
  // default options
6743
6916
  binary: false,
@@ -6745,12 +6918,13 @@ var GLTFWriter = class {
6745
6918
  onlyVisible: true,
6746
6919
  maxTextureSize: Infinity,
6747
6920
  animations: [],
6748
- includeCustomExtensions: false
6921
+ includeCustomExtensions: false,
6922
+ copyright: null
6749
6923
  }, options);
6750
6924
  if (this.options.animations.length > 0) {
6751
6925
  this.options.trs = true;
6752
6926
  }
6753
- this.processInput(input);
6927
+ await this.processInputAsync(input);
6754
6928
  await Promise.all(this.pending);
6755
6929
  const writer = this;
6756
6930
  const buffers = writer.buffers;
@@ -6764,6 +6938,7 @@ var GLTFWriter = class {
6764
6938
  if (extensionsUsedList.length > 0) json.extensionsUsed = extensionsUsedList;
6765
6939
  if (extensionsRequiredList.length > 0) json.extensionsRequired = extensionsRequiredList;
6766
6940
  if (json.buffers && json.buffers.length > 0) json.buffers[0].byteLength = blob.size;
6941
+ if (options.copyright) json.asset.copyright = options.copyright;
6767
6942
  if (options.binary === true) {
6768
6943
  const reader = new FileReader();
6769
6944
  reader.readAsArrayBuffer(blob);
@@ -6812,7 +6987,7 @@ var GLTFWriter = class {
6812
6987
  /**
6813
6988
  * Serializes a userData.
6814
6989
  *
6815
- * @param {THREE.Object3D|THREE.Material} object
6990
+ * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry|THREE.AnimationClip} object
6816
6991
  * @param {Object} objectDef
6817
6992
  */
6818
6993
  serializeUserData(object, objectDef) {
@@ -6836,8 +7011,10 @@ var GLTFWriter = class {
6836
7011
  }
6837
7012
  /**
6838
7013
  * Returns ids for buffer attributes.
6839
- * @param {Object} object
6840
- * @return {Integer}
7014
+ *
7015
+ * @param {Object} attribute
7016
+ * @param {boolean} [isRelativeCopy=false]
7017
+ * @return {number} An integer
6841
7018
  */
6842
7019
  getUID(attribute, isRelativeCopy = false) {
6843
7020
  if (this.uids.has(attribute) === false) {
@@ -6853,12 +7030,12 @@ var GLTFWriter = class {
6853
7030
  * Checks if normal attribute values are normalized.
6854
7031
  *
6855
7032
  * @param {BufferAttribute} normal
6856
- * @returns {Boolean}
7033
+ * @returns {boolean}
6857
7034
  */
6858
7035
  isNormalizedNormalAttribute(normal) {
6859
7036
  const cache = this.cache;
6860
7037
  if (cache.attributesNormalized.has(normal)) return false;
6861
- const v = new import_three19.Vector3();
7038
+ const v = new import_three18.Vector3();
6862
7039
  for (let i = 0, il = normal.count; i < il; i++) {
6863
7040
  if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
6864
7041
  }
@@ -6875,7 +7052,7 @@ var GLTFWriter = class {
6875
7052
  const cache = this.cache;
6876
7053
  if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
6877
7054
  const attribute = normal.clone();
6878
- const v = new import_three19.Vector3();
7055
+ const v = new import_three18.Vector3();
6879
7056
  for (let i = 0, il = attribute.count; i < il; i++) {
6880
7057
  v.fromBufferAttribute(attribute, i);
6881
7058
  if (v.x === 0 && v.y === 0 && v.z === 0) {
@@ -6916,10 +7093,10 @@ var GLTFWriter = class {
6916
7093
  this.extensionsUsed["KHR_texture_transform"] = true;
6917
7094
  }
6918
7095
  }
6919
- buildMetalRoughTexture(metalnessMap, roughnessMap) {
7096
+ async buildMetalRoughTextureAsync(metalnessMap, roughnessMap) {
6920
7097
  if (metalnessMap === roughnessMap) return metalnessMap;
6921
7098
  function getEncodingConversion(map) {
6922
- if (map.colorSpace === import_three19.SRGBColorSpace) {
7099
+ if (map.colorSpace === import_three18.SRGBColorSpace) {
6923
7100
  return function SRGBToLinear(c) {
6924
7101
  return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
6925
7102
  };
@@ -6928,12 +7105,11 @@ var GLTFWriter = class {
6928
7105
  return c;
6929
7106
  };
6930
7107
  }
6931
- console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
6932
- if (metalnessMap instanceof import_three19.CompressedTexture) {
6933
- metalnessMap = decompress(metalnessMap);
7108
+ if (metalnessMap instanceof import_three18.CompressedTexture) {
7109
+ metalnessMap = await this.decompressTextureAsync(metalnessMap);
6934
7110
  }
6935
- if (roughnessMap instanceof import_three19.CompressedTexture) {
6936
- roughnessMap = decompress(roughnessMap);
7111
+ if (roughnessMap instanceof import_three18.CompressedTexture) {
7112
+ roughnessMap = await this.decompressTextureAsync(roughnessMap);
6937
7113
  }
6938
7114
  const metalness = metalnessMap ? metalnessMap.image : null;
6939
7115
  const roughness = roughnessMap ? roughnessMap.image : null;
@@ -6942,7 +7118,9 @@ var GLTFWriter = class {
6942
7118
  const canvas = getCanvas();
6943
7119
  canvas.width = width;
6944
7120
  canvas.height = height;
6945
- const context = canvas.getContext("2d");
7121
+ const context = canvas.getContext("2d", {
7122
+ willReadFrequently: true
7123
+ });
6946
7124
  context.fillStyle = "#00ffff";
6947
7125
  context.fillRect(0, 0, width, height);
6948
7126
  const composite = context.getImageData(0, 0, width, height);
@@ -6965,18 +7143,60 @@ var GLTFWriter = class {
6965
7143
  context.putImageData(composite, 0, 0);
6966
7144
  const reference = metalnessMap || roughnessMap;
6967
7145
  const texture = reference.clone();
6968
- texture.source = new import_three19.Source(canvas);
6969
- texture.colorSpace = import_three19.NoColorSpace;
7146
+ texture.source = new import_three18.TextureSource(canvas);
7147
+ texture.colorSpace = import_three18.NoColorSpace;
6970
7148
  texture.channel = (metalnessMap || roughnessMap).channel;
6971
7149
  if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
6972
7150
  console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
6973
7151
  }
7152
+ console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
7153
+ return texture;
7154
+ }
7155
+ /**
7156
+ * Builds a copy of the given normal map with the red and/or green channels
7157
+ * inverted (`color = 255 - color`). This is used to bake the sign of
7158
+ * `material.normalScale` and the tangent-space convention into the texture,
7159
+ * since glTF only supports OpenGL-style normal maps with a univariate,
7160
+ * positive scale.
7161
+ *
7162
+ * @param {THREE.Texture} normalMap The source normal map.
7163
+ * @param {boolean} flipX Whether to invert the red channel (normal X).
7164
+ * @param {boolean} flipY Whether to invert the green channel (normal Y).
7165
+ * @return {Promise<THREE.Texture>} The derived normal map texture.
7166
+ */
7167
+ async buildNormalMapTextureAsync(normalMap, flipX, flipY) {
7168
+ if (normalMap instanceof import_three18.CompressedTexture) {
7169
+ normalMap = await this.decompressTextureAsync(normalMap);
7170
+ }
7171
+ const image = normalMap.image;
7172
+ const canvas = getCanvas();
7173
+ canvas.width = image.width;
7174
+ canvas.height = image.height;
7175
+ const context = canvas.getContext("2d", {
7176
+ willReadFrequently: true
7177
+ });
7178
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
7179
+ const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
7180
+ const data = imageData.data;
7181
+ for (let i = 0; i < data.length; i += 4) {
7182
+ if (flipX) data[i + 0] = 255 - data[i + 0];
7183
+ if (flipY) data[i + 1] = 255 - data[i + 1];
7184
+ }
7185
+ context.putImageData(imageData, 0, 0);
7186
+ const texture = normalMap.clone();
7187
+ texture.source = new import_three18.TextureSource(canvas);
6974
7188
  return texture;
6975
7189
  }
7190
+ async decompressTextureAsync(texture, maxTextureSize = Infinity) {
7191
+ if (this.textureUtils === null) {
7192
+ throw new Error("THREE.GLTFExporter: setTextureUtils() must be called to process compressed textures.");
7193
+ }
7194
+ return await this.textureUtils.decompress(texture, maxTextureSize);
7195
+ }
6976
7196
  /**
6977
7197
  * Process a buffer to append to the default one.
6978
- * @param {ArrayBuffer} buffer
6979
- * @return {Integer}
7198
+ * @param {ArrayBuffer} buffer
7199
+ * @return {0}
6980
7200
  */
6981
7201
  processBuffer(buffer) {
6982
7202
  const json = this.json;
@@ -6987,11 +7207,11 @@ var GLTFWriter = class {
6987
7207
  }
6988
7208
  /**
6989
7209
  * Process and generate a BufferView
6990
- * @param {BufferAttribute} attribute
6991
- * @param {number} componentType
6992
- * @param {number} start
6993
- * @param {number} count
6994
- * @param {number} target (Optional) Target usage of the BufferView
7210
+ * @param {BufferAttribute} attribute
7211
+ * @param {number} componentType
7212
+ * @param {number} start
7213
+ * @param {number} count
7214
+ * @param {number} [target] Target usage of the BufferView
6995
7215
  * @return {Object}
6996
7216
  */
6997
7217
  processBufferView(attribute, componentType, start, count, target) {
@@ -7010,7 +7230,11 @@ var GLTFWriter = class {
7010
7230
  default:
7011
7231
  componentSize = 4;
7012
7232
  }
7013
- const byteLength = getPaddedBufferSize(count * attribute.itemSize * componentSize);
7233
+ let byteStride = attribute.itemSize * componentSize;
7234
+ if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
7235
+ byteStride = Math.ceil(byteStride / 4) * 4;
7236
+ }
7237
+ const byteLength = getPaddedBufferSize(count * byteStride);
7014
7238
  const dataView = new DataView(new ArrayBuffer(byteLength));
7015
7239
  let offset = 0;
7016
7240
  for (let i = start; i < start + count; i++) {
@@ -7024,7 +7248,7 @@ var GLTFWriter = class {
7024
7248
  else if (a === 2) value = attribute.getZ(i);
7025
7249
  else if (a === 3) value = attribute.getW(i);
7026
7250
  if (attribute.normalized === true) {
7027
- value = import_three19.MathUtils.normalize(value, attribute.array);
7251
+ value = import_three18.MathUtils.normalize(value, attribute.array);
7028
7252
  }
7029
7253
  }
7030
7254
  if (componentType === WEBGL_CONSTANTS.FLOAT) {
@@ -7044,6 +7268,9 @@ var GLTFWriter = class {
7044
7268
  }
7045
7269
  offset += componentSize;
7046
7270
  }
7271
+ if (offset % byteStride !== 0) {
7272
+ offset += byteStride - offset % byteStride;
7273
+ }
7047
7274
  }
7048
7275
  const bufferViewDef = {
7049
7276
  buffer: this.processBuffer(dataView.buffer),
@@ -7052,7 +7279,7 @@ var GLTFWriter = class {
7052
7279
  };
7053
7280
  if (target !== void 0) bufferViewDef.target = target;
7054
7281
  if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
7055
- bufferViewDef.byteStride = attribute.itemSize * componentSize;
7282
+ bufferViewDef.byteStride = byteStride;
7056
7283
  }
7057
7284
  this.byteOffset += byteLength;
7058
7285
  json.bufferViews.push(bufferViewDef);
@@ -7065,7 +7292,7 @@ var GLTFWriter = class {
7065
7292
  /**
7066
7293
  * Process and generate a BufferView from an image Blob.
7067
7294
  * @param {Blob} blob
7068
- * @return {Promise<Integer>}
7295
+ * @return {Promise<number>} An integer
7069
7296
  */
7070
7297
  processBufferViewImage(blob) {
7071
7298
  const writer = this;
@@ -7088,11 +7315,11 @@ var GLTFWriter = class {
7088
7315
  }
7089
7316
  /**
7090
7317
  * Process attribute to generate an accessor
7091
- * @param {BufferAttribute} attribute Attribute to process
7092
- * @param {THREE.BufferGeometry} geometry (Optional) Geometry used for truncated draw range
7093
- * @param {Integer} start (Optional)
7094
- * @param {Integer} count (Optional)
7095
- * @return {Integer|null} Index of the processed accessor on the "accessors" array
7318
+ * @param {BufferAttribute} attribute Attribute to process
7319
+ * @param {?BufferGeometry} [geometry] Geometry used for truncated draw range
7320
+ * @param {number} [start=0]
7321
+ * @param {number} [count=Infinity]
7322
+ * @return {?number} Index of the processed accessor on the "accessors" array
7096
7323
  */
7097
7324
  processAccessor(attribute, geometry, start, count) {
7098
7325
  const json = this.json;
@@ -7146,11 +7373,11 @@ var GLTFWriter = class {
7146
7373
  }
7147
7374
  /**
7148
7375
  * Process image
7149
- * @param {Image} image to process
7150
- * @param {Integer} format of the image (RGBAFormat)
7151
- * @param {Boolean} flipY before writing out the image
7152
- * @param {String} mimeType export format
7153
- * @return {Integer} Index of the processed texture in the "images" array
7376
+ * @param {Image} image to process
7377
+ * @param {number} format Identifier of the format (RGBAFormat)
7378
+ * @param {boolean} flipY before writing out the image
7379
+ * @param {string} mimeType export format
7380
+ * @return {number} Index of the processed texture in the "images" array
7154
7381
  */
7155
7382
  processImage(image, format, flipY, mimeType = "image/png") {
7156
7383
  if (image !== null) {
@@ -7168,13 +7395,15 @@ var GLTFWriter = class {
7168
7395
  const canvas = getCanvas();
7169
7396
  canvas.width = Math.min(image.width, options.maxTextureSize);
7170
7397
  canvas.height = Math.min(image.height, options.maxTextureSize);
7171
- const ctx = canvas.getContext("2d");
7398
+ const ctx = canvas.getContext("2d", {
7399
+ willReadFrequently: true
7400
+ });
7172
7401
  if (flipY === true) {
7173
7402
  ctx.translate(0, canvas.height);
7174
7403
  ctx.scale(1, -1);
7175
7404
  }
7176
7405
  if (image.data !== void 0) {
7177
- if (format !== import_three19.RGBAFormat) {
7406
+ if (format !== import_three18.RGBAFormat) {
7178
7407
  console.error("GLTFExporter: Only RGBAFormat is supported.", format);
7179
7408
  }
7180
7409
  if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
@@ -7189,7 +7418,11 @@ var GLTFWriter = class {
7189
7418
  }
7190
7419
  ctx.putImageData(new ImageData(data, image.width, image.height), 0, 0);
7191
7420
  } else {
7192
- ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
7421
+ 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) {
7422
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
7423
+ } else {
7424
+ throw new Error("THREE.GLTFExporter: Invalid image type. Use HTMLImageElement, HTMLCanvasElement, ImageBitmap or OffscreenCanvas.");
7425
+ }
7193
7426
  }
7194
7427
  if (options.binary === true) {
7195
7428
  pending.push(
@@ -7198,15 +7431,7 @@ var GLTFWriter = class {
7198
7431
  })
7199
7432
  );
7200
7433
  } else {
7201
- if (canvas.toDataURL !== void 0) {
7202
- imageDef.uri = canvas.toDataURL(mimeType);
7203
- } else {
7204
- pending.push(
7205
- getToBlobPromise(canvas, mimeType).then((blob) => new FileReader().readAsDataURL(blob)).then((dataURL) => {
7206
- imageDef.uri = dataURL;
7207
- })
7208
- );
7209
- }
7434
+ imageDef.uri = import_three18.ImageUtils.getDataURL(canvas, mimeType);
7210
7435
  }
7211
7436
  const index = json.images.push(imageDef) - 1;
7212
7437
  cachedImages[key] = index;
@@ -7217,8 +7442,8 @@ var GLTFWriter = class {
7217
7442
  }
7218
7443
  /**
7219
7444
  * Process sampler
7220
- * @param {Texture} map Texture to process
7221
- * @return {Integer} Index of the processed texture in the "samplers" array
7445
+ * @param {Texture} map Texture to process
7446
+ * @return {number} Index of the processed texture in the "samplers" array
7222
7447
  */
7223
7448
  processSampler(map) {
7224
7449
  const json = this.json;
@@ -7233,28 +7458,37 @@ var GLTFWriter = class {
7233
7458
  }
7234
7459
  /**
7235
7460
  * Process texture
7236
- * @param {Texture} map Map to process
7237
- * @return {Integer} Index of the processed texture in the "textures" array
7461
+ * @param {Texture} map Map to process
7462
+ * @return {Promise<number>} Index of the processed texture in the "textures" array
7238
7463
  */
7239
- processTexture(map) {
7464
+ async processTextureAsync(map) {
7240
7465
  const writer = this;
7241
7466
  const options = writer.options;
7242
7467
  const cache = this.cache;
7243
7468
  const json = this.json;
7244
7469
  if (cache.textures.has(map)) return cache.textures.get(map);
7245
7470
  if (!json.textures) json.textures = [];
7246
- if (map instanceof import_three19.CompressedTexture) {
7247
- map = decompress(map, options.maxTextureSize);
7471
+ if (map instanceof import_three18.CompressedTexture) {
7472
+ map = await this.decompressTextureAsync(map, options.maxTextureSize);
7248
7473
  }
7249
- let mimeType = map.userData.mimeType;
7250
- if (mimeType === "image/webp") mimeType = "image/png";
7474
+ const mimeType = map.userData.mimeType;
7475
+ const imageIndex = this.processImage(map.image, map.format, map.flipY, mimeType);
7251
7476
  const textureDef = {
7252
- sampler: this.processSampler(map),
7253
- source: this.processImage(map.image, map.format, map.flipY, mimeType)
7477
+ sampler: this.processSampler(map)
7254
7478
  };
7479
+ if (mimeType === "image/webp") {
7480
+ textureDef.extensions = textureDef.extensions || {};
7481
+ textureDef.extensions["EXT_texture_webp"] = {
7482
+ source: imageIndex
7483
+ };
7484
+ this.extensionsUsed["EXT_texture_webp"] = true;
7485
+ this.extensionsRequired["EXT_texture_webp"] = true;
7486
+ } else {
7487
+ textureDef.source = imageIndex;
7488
+ }
7255
7489
  if (map.name) textureDef.name = map.name;
7256
- this._invokeAll(function(ext) {
7257
- ext.writeTexture && ext.writeTexture(map, textureDef);
7490
+ await this._invokeAllAsync(async function(ext) {
7491
+ ext.writeTexture && await ext.writeTexture(map, textureDef);
7258
7492
  });
7259
7493
  const index = json.textures.push(textureDef) - 1;
7260
7494
  cache.textures.set(map, index);
@@ -7262,13 +7496,16 @@ var GLTFWriter = class {
7262
7496
  }
7263
7497
  /**
7264
7498
  * Process material
7265
- * @param {THREE.Material} material Material to process
7266
- * @return {Integer|null} Index of the processed material in the "materials" array
7499
+ * @param {THREE.Material} material Material to process
7500
+ * @param {THREE.BufferGeometry} [geometry] Geometry the material is used with.
7501
+ * @return {Promise<?number>} Index of the processed material in the "materials" array
7267
7502
  */
7268
- processMaterial(material) {
7503
+ async processMaterialAsync(material, geometry) {
7269
7504
  const cache = this.cache;
7270
7505
  const json = this.json;
7271
- if (cache.materials.has(material)) return cache.materials.get(material);
7506
+ const hasTangent = geometry !== void 0 && geometry.hasAttribute("tangent");
7507
+ const cacheKey = material.normalMap ? material.uuid + ":" + hasTangent : material.uuid;
7508
+ if (cache.materials.has(cacheKey)) return cache.materials.get(cacheKey);
7272
7509
  if (material.isShaderMaterial) {
7273
7510
  console.warn("GLTFExporter: THREE.ShaderMaterial not supported.");
7274
7511
  return null;
@@ -7286,21 +7523,21 @@ var GLTFWriter = class {
7286
7523
  materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
7287
7524
  materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
7288
7525
  } else {
7289
- materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
7290
- materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
7526
+ materialDef.pbrMetallicRoughness.metallicFactor = 0;
7527
+ materialDef.pbrMetallicRoughness.roughnessFactor = 1;
7291
7528
  }
7292
7529
  if (material.metalnessMap || material.roughnessMap) {
7293
- const metalRoughTexture = this.buildMetalRoughTexture(material.metalnessMap, material.roughnessMap);
7530
+ const metalRoughTexture = await this.buildMetalRoughTextureAsync(material.metalnessMap, material.roughnessMap);
7294
7531
  const metalRoughMapDef = {
7295
- index: this.processTexture(metalRoughTexture),
7296
- channel: metalRoughTexture.channel
7532
+ index: await this.processTextureAsync(metalRoughTexture),
7533
+ texCoord: metalRoughTexture.channel
7297
7534
  };
7298
7535
  this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
7299
7536
  materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
7300
7537
  }
7301
7538
  if (material.map) {
7302
7539
  const baseColorMapDef = {
7303
- index: this.processTexture(material.map),
7540
+ index: await this.processTextureAsync(material.map),
7304
7541
  texCoord: material.map.channel
7305
7542
  };
7306
7543
  this.applyTextureTransform(baseColorMapDef, material.map);
@@ -7314,7 +7551,7 @@ var GLTFWriter = class {
7314
7551
  }
7315
7552
  if (material.emissiveMap) {
7316
7553
  const emissiveMapDef = {
7317
- index: this.processTexture(material.emissiveMap),
7554
+ index: await this.processTextureAsync(material.emissiveMap),
7318
7555
  texCoord: material.emissiveMap.channel
7319
7556
  };
7320
7557
  this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
@@ -7322,19 +7559,32 @@ var GLTFWriter = class {
7322
7559
  }
7323
7560
  }
7324
7561
  if (material.normalMap) {
7562
+ const normalScale = material.normalScale;
7563
+ const flipX = normalScale.x < 0;
7564
+ const flipY = hasTangent ? normalScale.y < 0 : normalScale.y > 0;
7565
+ let normalMap = material.normalMap;
7566
+ if (flipX || flipY) {
7567
+ if (cache.normalMaps.has(material.normalMap) === false) cache.normalMaps.set(material.normalMap, {});
7568
+ const cachedVariants = cache.normalMaps.get(material.normalMap);
7569
+ const cacheKey2 = `${flipX}:${flipY}`;
7570
+ if (cachedVariants[cacheKey2] === void 0) {
7571
+ cachedVariants[cacheKey2] = await this.buildNormalMapTextureAsync(material.normalMap, flipX, flipY);
7572
+ }
7573
+ normalMap = cachedVariants[cacheKey2];
7574
+ }
7325
7575
  const normalMapDef = {
7326
- index: this.processTexture(material.normalMap),
7576
+ index: await this.processTextureAsync(normalMap),
7327
7577
  texCoord: material.normalMap.channel
7328
7578
  };
7329
- if (material.normalScale && material.normalScale.x !== 1) {
7330
- normalMapDef.scale = material.normalScale.x;
7579
+ if (Math.abs(normalScale.x) !== 1) {
7580
+ normalMapDef.scale = Math.abs(normalScale.x);
7331
7581
  }
7332
7582
  this.applyTextureTransform(normalMapDef, material.normalMap);
7333
7583
  materialDef.normalTexture = normalMapDef;
7334
7584
  }
7335
7585
  if (material.aoMap) {
7336
7586
  const occlusionMapDef = {
7337
- index: this.processTexture(material.aoMap),
7587
+ index: await this.processTextureAsync(material.aoMap),
7338
7588
  texCoord: material.aoMap.channel
7339
7589
  };
7340
7590
  if (material.aoMapIntensity !== 1) {
@@ -7351,22 +7601,22 @@ var GLTFWriter = class {
7351
7601
  materialDef.alphaCutoff = material.alphaTest;
7352
7602
  }
7353
7603
  }
7354
- if (material.side === import_three19.DoubleSide) materialDef.doubleSided = true;
7604
+ if (material.side === import_three18.DoubleSide) materialDef.doubleSided = true;
7355
7605
  if (material.name !== "") materialDef.name = material.name;
7356
7606
  this.serializeUserData(material, materialDef);
7357
- this._invokeAll(function(ext) {
7358
- ext.writeMaterial && ext.writeMaterial(material, materialDef);
7607
+ await this._invokeAllAsync(async function(ext) {
7608
+ ext.writeMaterialAsync && await ext.writeMaterialAsync(material, materialDef);
7359
7609
  });
7360
7610
  const index = json.materials.push(materialDef) - 1;
7361
- cache.materials.set(material, index);
7611
+ cache.materials.set(cacheKey, index);
7362
7612
  return index;
7363
7613
  }
7364
7614
  /**
7365
7615
  * Process mesh
7366
- * @param {THREE.Mesh} mesh Mesh to process
7367
- * @return {Integer|null} Index of the processed mesh in the "meshes" array
7616
+ * @param {THREE.Mesh} mesh Mesh to process
7617
+ * @return {Promise<?number>} Index of the processed mesh in the "meshes" array
7368
7618
  */
7369
- processMesh(mesh) {
7619
+ async processMeshAsync(mesh) {
7370
7620
  const cache = this.cache;
7371
7621
  const json = this.json;
7372
7622
  const meshCacheKeyParts = [mesh.geometry.uuid];
@@ -7416,7 +7666,7 @@ var GLTFWriter = class {
7416
7666
  const attribute = geometry.attributes[attributeName];
7417
7667
  attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
7418
7668
  const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
7419
- if (!validVertexAttributes.test(attributeName)) attributeName = "_" + attributeName;
7669
+ if (!validVertexAttributes.test(attributeName) && !attributeName.startsWith("_")) attributeName = "_" + attributeName;
7420
7670
  if (cache.attributes.has(this.getUID(attribute))) {
7421
7671
  attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
7422
7672
  continue;
@@ -7425,7 +7675,10 @@ var GLTFWriter = class {
7425
7675
  const array = attribute.array;
7426
7676
  if (attributeName === "JOINTS_0" && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
7427
7677
  console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
7428
- modifiedAttribute = new import_three19.BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
7678
+ modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute(attribute, Uint16Array);
7679
+ } else if ((array instanceof Uint32Array || array instanceof Int32Array) && !attributeName.startsWith("_")) {
7680
+ console.warn(`GLTFExporter: Attribute "${attributeName}" converted to type FLOAT.`);
7681
+ modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute(attribute, Float32Array);
7429
7682
  }
7430
7683
  const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
7431
7684
  if (accessor !== null) {
@@ -7491,6 +7744,15 @@ var GLTFWriter = class {
7491
7744
  }
7492
7745
  const isMultiMaterial = Array.isArray(mesh.material);
7493
7746
  if (isMultiMaterial && geometry.groups.length === 0) return null;
7747
+ let didForceIndices = false;
7748
+ if (isMultiMaterial && geometry.index === null) {
7749
+ const indices = [];
7750
+ for (let i = 0, il = geometry.attributes.position.count; i < il; i++) {
7751
+ indices[i] = i;
7752
+ }
7753
+ geometry.setIndex(indices);
7754
+ didForceIndices = true;
7755
+ }
7494
7756
  const materials = isMultiMaterial ? mesh.material : [mesh.material];
7495
7757
  const groups = isMultiMaterial ? geometry.groups : [{ materialIndex: 0, start: void 0, count: void 0 }];
7496
7758
  for (let i = 0, il = groups.length; i < il; i++) {
@@ -7513,13 +7775,16 @@ var GLTFWriter = class {
7513
7775
  }
7514
7776
  if (primitive.indices === null) delete primitive.indices;
7515
7777
  }
7516
- const material = this.processMaterial(materials[groups[i].materialIndex]);
7778
+ const material = await this.processMaterialAsync(materials[groups[i].materialIndex], geometry);
7517
7779
  if (material !== null) primitive.material = material;
7518
7780
  primitives.push(primitive);
7519
7781
  }
7782
+ if (didForceIndices === true) {
7783
+ geometry.setIndex(null);
7784
+ }
7520
7785
  meshDef.primitives = primitives;
7521
7786
  if (!json.meshes) json.meshes = [];
7522
- this._invokeAll(function(ext) {
7787
+ await this._invokeAllAsync(function(ext) {
7523
7788
  ext.writeMesh && ext.writeMesh(mesh, meshDef);
7524
7789
  });
7525
7790
  const index = json.meshes.push(meshDef) - 1;
@@ -7565,8 +7830,8 @@ var GLTFWriter = class {
7565
7830
  }
7566
7831
  /**
7567
7832
  * Process camera
7568
- * @param {THREE.Camera} camera Camera to process
7569
- * @return {Integer} Index of the processed mesh in the "camera" array
7833
+ * @param {THREE.Camera} camera Camera to process
7834
+ * @return {number} Index of the processed mesh in the "camera" array
7570
7835
  */
7571
7836
  processCamera(camera) {
7572
7837
  const json = this.json;
@@ -7585,7 +7850,7 @@ var GLTFWriter = class {
7585
7850
  } else {
7586
7851
  cameraDef.perspective = {
7587
7852
  aspectRatio: camera.aspect,
7588
- yfov: import_three19.MathUtils.degToRad(camera.fov),
7853
+ yfov: import_three18.MathUtils.degToRad(camera.fov),
7589
7854
  zfar: camera.far <= 0 ? 1e-3 : camera.far,
7590
7855
  znear: camera.near < 0 ? 0 : camera.near
7591
7856
  };
@@ -7601,7 +7866,7 @@ var GLTFWriter = class {
7601
7866
  *
7602
7867
  * @param {THREE.AnimationClip} clip
7603
7868
  * @param {THREE.Object3D} root
7604
- * @return {number|null}
7869
+ * @return {?number}
7605
7870
  */
7606
7871
  processAnimation(clip, root) {
7607
7872
  const json = this.json;
@@ -7613,8 +7878,8 @@ var GLTFWriter = class {
7613
7878
  const samplers = [];
7614
7879
  for (let i = 0; i < tracks.length; ++i) {
7615
7880
  const track = tracks[i];
7616
- const trackBinding = import_three19.PropertyBinding.parseTrackName(track.name);
7617
- let trackNode = import_three19.PropertyBinding.findNode(root, trackBinding.nodeName);
7881
+ const trackBinding = import_three18.PropertyBinding.parseTrackName(track.name);
7882
+ let trackNode = import_three18.PropertyBinding.findNode(root, trackBinding.nodeName);
7618
7883
  const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
7619
7884
  if (trackBinding.objectName === "bones") {
7620
7885
  if (trackNode.isSkinnedMesh === true) {
@@ -7625,7 +7890,7 @@ var GLTFWriter = class {
7625
7890
  }
7626
7891
  if (!trackNode || !trackProperty) {
7627
7892
  console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
7628
- return null;
7893
+ continue;
7629
7894
  }
7630
7895
  const inputItemSize = 1;
7631
7896
  let outputItemSize = track.values.length / track.times.length;
@@ -7636,14 +7901,14 @@ var GLTFWriter = class {
7636
7901
  if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
7637
7902
  interpolation = "CUBICSPLINE";
7638
7903
  outputItemSize /= 3;
7639
- } else if (track.getInterpolation() === import_three19.InterpolateDiscrete) {
7904
+ } else if (track.getInterpolation() === import_three18.InterpolateDiscrete) {
7640
7905
  interpolation = "STEP";
7641
7906
  } else {
7642
7907
  interpolation = "LINEAR";
7643
7908
  }
7644
7909
  samplers.push({
7645
- input: this.processAccessor(new import_three19.BufferAttribute(track.times, inputItemSize)),
7646
- output: this.processAccessor(new import_three19.BufferAttribute(track.values, outputItemSize)),
7910
+ input: this.processAccessor(new import_three18.BufferAttribute(track.times, inputItemSize)),
7911
+ output: this.processAccessor(new import_three18.BufferAttribute(track.values, outputItemSize)),
7647
7912
  interpolation
7648
7913
  });
7649
7914
  channels.push({
@@ -7654,16 +7919,18 @@ var GLTFWriter = class {
7654
7919
  }
7655
7920
  });
7656
7921
  }
7657
- json.animations.push({
7922
+ const animationDef = {
7658
7923
  name: clip.name || "clip_" + json.animations.length,
7659
7924
  samplers,
7660
7925
  channels
7661
- });
7926
+ };
7927
+ this.serializeUserData(clip, animationDef);
7928
+ json.animations.push(animationDef);
7662
7929
  return json.animations.length - 1;
7663
7930
  }
7664
7931
  /**
7665
7932
  * @param {THREE.Object3D} object
7666
- * @return {number|null}
7933
+ * @return {?number}
7667
7934
  */
7668
7935
  processSkin(object) {
7669
7936
  const json = this.json;
@@ -7675,7 +7942,7 @@ var GLTFWriter = class {
7675
7942
  if (rootJoint === void 0) return null;
7676
7943
  const joints = [];
7677
7944
  const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
7678
- const temporaryBoneInverse = new import_three19.Matrix4();
7945
+ const temporaryBoneInverse = new import_three18.Matrix4();
7679
7946
  for (let i = 0; i < skeleton.bones.length; ++i) {
7680
7947
  joints.push(nodeMap.get(skeleton.bones[i]));
7681
7948
  temporaryBoneInverse.copy(skeleton.boneInverses[i]);
@@ -7683,7 +7950,7 @@ var GLTFWriter = class {
7683
7950
  }
7684
7951
  if (json.skins === void 0) json.skins = [];
7685
7952
  json.skins.push({
7686
- inverseBindMatrices: this.processAccessor(new import_three19.BufferAttribute(inverseBindMatrices, 16)),
7953
+ inverseBindMatrices: this.processAccessor(new import_three18.BufferAttribute(inverseBindMatrices, 16)),
7687
7954
  joints,
7688
7955
  skeleton: nodeMap.get(rootJoint)
7689
7956
  });
@@ -7692,14 +7959,17 @@ var GLTFWriter = class {
7692
7959
  }
7693
7960
  /**
7694
7961
  * Process Object3D node
7695
- * @param {THREE.Object3D} node Object3D to processNode
7696
- * @return {Integer} Index of the node in the nodes list
7962
+ * @param {THREE.Object3D} object Object3D to processNodeAsync
7963
+ * @return {Promise<number>} Index of the node in the nodes list
7697
7964
  */
7698
- processNode(object) {
7965
+ async processNodeAsync(object) {
7699
7966
  const json = this.json;
7700
7967
  const options = this.options;
7701
7968
  const nodeMap = this.nodeMap;
7702
7969
  if (!json.nodes) json.nodes = [];
7970
+ if (object.pivot !== null) {
7971
+ return await this._processNodeWithPivotAsync(object);
7972
+ }
7703
7973
  const nodeDef = {};
7704
7974
  if (options.trs) {
7705
7975
  const rotation = object.quaternion.toArray();
@@ -7725,35 +7995,98 @@ var GLTFWriter = class {
7725
7995
  if (object.name !== "") nodeDef.name = String(object.name);
7726
7996
  this.serializeUserData(object, nodeDef);
7727
7997
  if (object.isMesh || object.isLine || object.isPoints) {
7728
- const meshIndex = this.processMesh(object);
7998
+ const meshIndex = await this.processMeshAsync(object);
7729
7999
  if (meshIndex !== null) nodeDef.mesh = meshIndex;
7730
8000
  } else if (object.isCamera) {
7731
8001
  nodeDef.camera = this.processCamera(object);
7732
8002
  }
7733
8003
  if (object.isSkinnedMesh) this.skins.push(object);
8004
+ const nodeIndex = json.nodes.push(nodeDef) - 1;
8005
+ nodeMap.set(object, nodeIndex);
7734
8006
  if (object.children.length > 0) {
7735
8007
  const children = [];
7736
8008
  for (let i = 0, l = object.children.length; i < l; i++) {
7737
8009
  const child = object.children[i];
7738
8010
  if (child.visible || options.onlyVisible === false) {
7739
- const nodeIndex2 = this.processNode(child);
7740
- if (nodeIndex2 !== null) children.push(nodeIndex2);
8011
+ const childNodeIndex = await this.processNodeAsync(child);
8012
+ if (childNodeIndex !== null) children.push(childNodeIndex);
7741
8013
  }
7742
8014
  }
7743
8015
  if (children.length > 0) nodeDef.children = children;
7744
8016
  }
7745
- this._invokeAll(function(ext) {
8017
+ await this._invokeAllAsync(function(ext) {
7746
8018
  ext.writeNode && ext.writeNode(object, nodeDef);
7747
8019
  });
7748
- const nodeIndex = json.nodes.push(nodeDef) - 1;
7749
- nodeMap.set(object, nodeIndex);
7750
8020
  return nodeIndex;
7751
8021
  }
8022
+ /**
8023
+ * Process Object3D node with pivot using container approach
8024
+ * @param {THREE.Object3D} object Object3D with pivot
8025
+ * @return {Promise<number>} Index of the container node
8026
+ */
8027
+ async _processNodeWithPivotAsync(object) {
8028
+ const json = this.json;
8029
+ const options = this.options;
8030
+ const nodeMap = this.nodeMap;
8031
+ const pivot = object.pivot;
8032
+ const containerDef = {};
8033
+ const rotation = object.quaternion.toArray();
8034
+ const position = [
8035
+ object.position.x + pivot.x,
8036
+ object.position.y + pivot.y,
8037
+ object.position.z + pivot.z
8038
+ ];
8039
+ const scale = object.scale.toArray();
8040
+ if (!equalArray(rotation, [0, 0, 0, 1])) {
8041
+ containerDef.rotation = rotation;
8042
+ }
8043
+ if (!equalArray(position, [0, 0, 0])) {
8044
+ containerDef.translation = position;
8045
+ }
8046
+ if (!equalArray(scale, [1, 1, 1])) {
8047
+ containerDef.scale = scale;
8048
+ }
8049
+ containerDef.extras = { pivot: pivot.toArray() };
8050
+ if (object.name !== "") containerDef.name = String(object.name);
8051
+ this.serializeUserData(object, containerDef);
8052
+ const containerIndex = json.nodes.push(containerDef) - 1;
8053
+ nodeMap.set(object, containerIndex);
8054
+ const childDef = {};
8055
+ const childPosition = [-pivot.x, -pivot.y, -pivot.z];
8056
+ if (!equalArray(childPosition, [0, 0, 0])) {
8057
+ childDef.translation = childPosition;
8058
+ }
8059
+ if (object.isMesh || object.isLine || object.isPoints) {
8060
+ const meshIndex = await this.processMeshAsync(object);
8061
+ if (meshIndex !== null) childDef.mesh = meshIndex;
8062
+ } else if (object.isCamera) {
8063
+ childDef.camera = this.processCamera(object);
8064
+ }
8065
+ if (object.isSkinnedMesh) this.skins.push(object);
8066
+ const childIndex = json.nodes.push(childDef) - 1;
8067
+ const containerChildren = [childIndex];
8068
+ if (object.children.length > 0) {
8069
+ const grandchildren = [];
8070
+ for (let i = 0, l = object.children.length; i < l; i++) {
8071
+ const child = object.children[i];
8072
+ if (child.visible || options.onlyVisible === false) {
8073
+ const childNodeIndex = await this.processNodeAsync(child);
8074
+ if (childNodeIndex !== null) grandchildren.push(childNodeIndex);
8075
+ }
8076
+ }
8077
+ if (grandchildren.length > 0) childDef.children = grandchildren;
8078
+ }
8079
+ containerDef.children = containerChildren;
8080
+ await this._invokeAllAsync(function(ext) {
8081
+ ext.writeNode && ext.writeNode(object, containerDef);
8082
+ });
8083
+ return containerIndex;
8084
+ }
7752
8085
  /**
7753
8086
  * Process Scene
7754
- * @param {Scene} node Scene to process
8087
+ * @param {Scene} scene Scene to process
7755
8088
  */
7756
- processScene(scene) {
8089
+ async processSceneAsync(scene) {
7757
8090
  const json = this.json;
7758
8091
  const options = this.options;
7759
8092
  if (!json.scenes) {
@@ -7767,7 +8100,7 @@ var GLTFWriter = class {
7767
8100
  for (let i = 0, l = scene.children.length; i < l; i++) {
7768
8101
  const child = scene.children[i];
7769
8102
  if (child.visible || options.onlyVisible === false) {
7770
- const nodeIndex = this.processNode(child);
8103
+ const nodeIndex = await this.processNodeAsync(child);
7771
8104
  if (nodeIndex !== null) nodes.push(nodeIndex);
7772
8105
  }
7773
8106
  }
@@ -7776,47 +8109,58 @@ var GLTFWriter = class {
7776
8109
  }
7777
8110
  /**
7778
8111
  * Creates a Scene to hold a list of objects and parse it
7779
- * @param {Array} objects List of objects to process
8112
+ * @param {Array<THREE.Object3D>} objects List of objects to process
7780
8113
  */
7781
- processObjects(objects) {
7782
- const scene = new import_three19.Scene();
8114
+ async processObjectsAsync(objects) {
8115
+ const scene = new import_three18.Scene();
7783
8116
  scene.name = "AuxScene";
7784
8117
  for (let i = 0; i < objects.length; i++) {
7785
8118
  scene.children.push(objects[i]);
7786
8119
  }
7787
- this.processScene(scene);
8120
+ await this.processSceneAsync(scene);
7788
8121
  }
7789
8122
  /**
7790
8123
  * @param {THREE.Object3D|Array<THREE.Object3D>} input
7791
8124
  */
7792
- processInput(input) {
8125
+ async processInputAsync(input) {
7793
8126
  const options = this.options;
7794
8127
  input = input instanceof Array ? input : [input];
7795
- this._invokeAll(function(ext) {
8128
+ await this._invokeAllAsync(function(ext) {
7796
8129
  ext.beforeParse && ext.beforeParse(input);
7797
8130
  });
7798
8131
  const objectsWithoutScene = [];
7799
8132
  for (let i = 0; i < input.length; i++) {
7800
- if (input[i] instanceof import_three19.Scene) {
7801
- this.processScene(input[i]);
8133
+ if (input[i] instanceof import_three18.Scene) {
8134
+ await this.processSceneAsync(input[i]);
7802
8135
  } else {
7803
8136
  objectsWithoutScene.push(input[i]);
7804
8137
  }
7805
8138
  }
7806
- if (objectsWithoutScene.length > 0) this.processObjects(objectsWithoutScene);
8139
+ if (objectsWithoutScene.length > 0) {
8140
+ await this.processObjectsAsync(objectsWithoutScene);
8141
+ }
7807
8142
  for (let i = 0; i < this.skins.length; ++i) {
7808
8143
  this.processSkin(this.skins[i]);
7809
8144
  }
7810
- for (let i = 0; i < options.animations.length; ++i) {
7811
- this.processAnimation(options.animations[i], input[0]);
8145
+ if (input.length === 1) {
8146
+ for (let i = 0; i < options.animations.length; ++i) {
8147
+ this.processAnimation(options.animations[i], input[0]);
8148
+ }
8149
+ } else {
8150
+ for (let i = 0; i < input.length; i++) {
8151
+ const animations = options.animations[i] || [];
8152
+ for (let j = 0; j < animations.length; ++j) {
8153
+ this.processAnimation(animations[j], input[i]);
8154
+ }
8155
+ }
7812
8156
  }
7813
- this._invokeAll(function(ext) {
8157
+ await this._invokeAllAsync(function(ext) {
7814
8158
  ext.afterParse && ext.afterParse(input);
7815
8159
  });
7816
8160
  }
7817
- _invokeAll(func) {
8161
+ async _invokeAllAsync(func) {
7818
8162
  for (let i = 0, il = this.plugins.length; i < il; i++) {
7819
- func(this.plugins[i]);
8163
+ await func(this.plugins[i]);
7820
8164
  }
7821
8165
  }
7822
8166
  };
@@ -7872,7 +8216,7 @@ var GLTFMaterialsUnlitExtension = class {
7872
8216
  this.writer = writer;
7873
8217
  this.name = "KHR_materials_unlit";
7874
8218
  }
7875
- writeMaterial(material, materialDef) {
8219
+ async writeMaterialAsync(material, materialDef) {
7876
8220
  if (!material.isMeshBasicMaterial) return;
7877
8221
  const writer = this.writer;
7878
8222
  const extensionsUsed = writer.extensionsUsed;
@@ -7888,7 +8232,7 @@ var GLTFMaterialsClearcoatExtension = class {
7888
8232
  this.writer = writer;
7889
8233
  this.name = "KHR_materials_clearcoat";
7890
8234
  }
7891
- writeMaterial(material, materialDef) {
8235
+ async writeMaterialAsync(material, materialDef) {
7892
8236
  if (!material.isMeshPhysicalMaterial || material.clearcoat === 0) return;
7893
8237
  const writer = this.writer;
7894
8238
  const extensionsUsed = writer.extensionsUsed;
@@ -7896,7 +8240,7 @@ var GLTFMaterialsClearcoatExtension = class {
7896
8240
  extensionDef.clearcoatFactor = material.clearcoat;
7897
8241
  if (material.clearcoatMap) {
7898
8242
  const clearcoatMapDef = {
7899
- index: writer.processTexture(material.clearcoatMap),
8243
+ index: await writer.processTextureAsync(material.clearcoatMap),
7900
8244
  texCoord: material.clearcoatMap.channel
7901
8245
  };
7902
8246
  writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
@@ -7905,7 +8249,7 @@ var GLTFMaterialsClearcoatExtension = class {
7905
8249
  extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
7906
8250
  if (material.clearcoatRoughnessMap) {
7907
8251
  const clearcoatRoughnessMapDef = {
7908
- index: writer.processTexture(material.clearcoatRoughnessMap),
8252
+ index: await writer.processTextureAsync(material.clearcoatRoughnessMap),
7909
8253
  texCoord: material.clearcoatRoughnessMap.channel
7910
8254
  };
7911
8255
  writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
@@ -7913,9 +8257,10 @@ var GLTFMaterialsClearcoatExtension = class {
7913
8257
  }
7914
8258
  if (material.clearcoatNormalMap) {
7915
8259
  const clearcoatNormalMapDef = {
7916
- index: writer.processTexture(material.clearcoatNormalMap),
8260
+ index: await writer.processTextureAsync(material.clearcoatNormalMap),
7917
8261
  texCoord: material.clearcoatNormalMap.channel
7918
8262
  };
8263
+ if (material.clearcoatNormalScale.x !== 1) clearcoatNormalMapDef.scale = material.clearcoatNormalScale.x;
7919
8264
  writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
7920
8265
  extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
7921
8266
  }
@@ -7924,12 +8269,28 @@ var GLTFMaterialsClearcoatExtension = class {
7924
8269
  extensionsUsed[this.name] = true;
7925
8270
  }
7926
8271
  };
8272
+ var GLTFMaterialsDispersionExtension = class {
8273
+ constructor(writer) {
8274
+ this.writer = writer;
8275
+ this.name = "KHR_materials_dispersion";
8276
+ }
8277
+ async writeMaterialAsync(material, materialDef) {
8278
+ if (!material.isMeshPhysicalMaterial || material.dispersion === 0) return;
8279
+ const writer = this.writer;
8280
+ const extensionsUsed = writer.extensionsUsed;
8281
+ const extensionDef = {};
8282
+ extensionDef.dispersion = material.dispersion;
8283
+ materialDef.extensions = materialDef.extensions || {};
8284
+ materialDef.extensions[this.name] = extensionDef;
8285
+ extensionsUsed[this.name] = true;
8286
+ }
8287
+ };
7927
8288
  var GLTFMaterialsIridescenceExtension = class {
7928
8289
  constructor(writer) {
7929
8290
  this.writer = writer;
7930
8291
  this.name = "KHR_materials_iridescence";
7931
8292
  }
7932
- writeMaterial(material, materialDef) {
8293
+ async writeMaterialAsync(material, materialDef) {
7933
8294
  if (!material.isMeshPhysicalMaterial || material.iridescence === 0) return;
7934
8295
  const writer = this.writer;
7935
8296
  const extensionsUsed = writer.extensionsUsed;
@@ -7937,7 +8298,7 @@ var GLTFMaterialsIridescenceExtension = class {
7937
8298
  extensionDef.iridescenceFactor = material.iridescence;
7938
8299
  if (material.iridescenceMap) {
7939
8300
  const iridescenceMapDef = {
7940
- index: writer.processTexture(material.iridescenceMap),
8301
+ index: await writer.processTextureAsync(material.iridescenceMap),
7941
8302
  texCoord: material.iridescenceMap.channel
7942
8303
  };
7943
8304
  writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
@@ -7948,7 +8309,7 @@ var GLTFMaterialsIridescenceExtension = class {
7948
8309
  extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
7949
8310
  if (material.iridescenceThicknessMap) {
7950
8311
  const iridescenceThicknessMapDef = {
7951
- index: writer.processTexture(material.iridescenceThicknessMap),
8312
+ index: await writer.processTextureAsync(material.iridescenceThicknessMap),
7952
8313
  texCoord: material.iridescenceThicknessMap.channel
7953
8314
  };
7954
8315
  writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
@@ -7964,7 +8325,7 @@ var GLTFMaterialsTransmissionExtension = class {
7964
8325
  this.writer = writer;
7965
8326
  this.name = "KHR_materials_transmission";
7966
8327
  }
7967
- writeMaterial(material, materialDef) {
8328
+ async writeMaterialAsync(material, materialDef) {
7968
8329
  if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7969
8330
  const writer = this.writer;
7970
8331
  const extensionsUsed = writer.extensionsUsed;
@@ -7972,7 +8333,7 @@ var GLTFMaterialsTransmissionExtension = class {
7972
8333
  extensionDef.transmissionFactor = material.transmission;
7973
8334
  if (material.transmissionMap) {
7974
8335
  const transmissionMapDef = {
7975
- index: writer.processTexture(material.transmissionMap),
8336
+ index: await writer.processTextureAsync(material.transmissionMap),
7976
8337
  texCoord: material.transmissionMap.channel
7977
8338
  };
7978
8339
  writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
@@ -7988,7 +8349,7 @@ var GLTFMaterialsVolumeExtension = class {
7988
8349
  this.writer = writer;
7989
8350
  this.name = "KHR_materials_volume";
7990
8351
  }
7991
- writeMaterial(material, materialDef) {
8352
+ async writeMaterialAsync(material, materialDef) {
7992
8353
  if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7993
8354
  const writer = this.writer;
7994
8355
  const extensionsUsed = writer.extensionsUsed;
@@ -7996,13 +8357,15 @@ var GLTFMaterialsVolumeExtension = class {
7996
8357
  extensionDef.thicknessFactor = material.thickness;
7997
8358
  if (material.thicknessMap) {
7998
8359
  const thicknessMapDef = {
7999
- index: writer.processTexture(material.thicknessMap),
8360
+ index: await writer.processTextureAsync(material.thicknessMap),
8000
8361
  texCoord: material.thicknessMap.channel
8001
8362
  };
8002
8363
  writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
8003
8364
  extensionDef.thicknessTexture = thicknessMapDef;
8004
8365
  }
8005
- extensionDef.attenuationDistance = material.attenuationDistance;
8366
+ if (material.attenuationDistance !== Infinity) {
8367
+ extensionDef.attenuationDistance = material.attenuationDistance;
8368
+ }
8006
8369
  extensionDef.attenuationColor = material.attenuationColor.toArray();
8007
8370
  materialDef.extensions = materialDef.extensions || {};
8008
8371
  materialDef.extensions[this.name] = extensionDef;
@@ -8014,7 +8377,7 @@ var GLTFMaterialsIorExtension = class {
8014
8377
  this.writer = writer;
8015
8378
  this.name = "KHR_materials_ior";
8016
8379
  }
8017
- writeMaterial(material, materialDef) {
8380
+ async writeMaterialAsync(material, materialDef) {
8018
8381
  if (!material.isMeshPhysicalMaterial || material.ior === 1.5) return;
8019
8382
  const writer = this.writer;
8020
8383
  const extensionsUsed = writer.extensionsUsed;
@@ -8030,14 +8393,14 @@ var GLTFMaterialsSpecularExtension = class {
8030
8393
  this.writer = writer;
8031
8394
  this.name = "KHR_materials_specular";
8032
8395
  }
8033
- writeMaterial(material, materialDef) {
8034
- if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorTexture) return;
8396
+ async writeMaterialAsync(material, materialDef) {
8397
+ if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorMap) return;
8035
8398
  const writer = this.writer;
8036
8399
  const extensionsUsed = writer.extensionsUsed;
8037
8400
  const extensionDef = {};
8038
8401
  if (material.specularIntensityMap) {
8039
8402
  const specularIntensityMapDef = {
8040
- index: writer.processTexture(material.specularIntensityMap),
8403
+ index: await writer.processTextureAsync(material.specularIntensityMap),
8041
8404
  texCoord: material.specularIntensityMap.channel
8042
8405
  };
8043
8406
  writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
@@ -8045,7 +8408,7 @@ var GLTFMaterialsSpecularExtension = class {
8045
8408
  }
8046
8409
  if (material.specularColorMap) {
8047
8410
  const specularColorMapDef = {
8048
- index: writer.processTexture(material.specularColorMap),
8411
+ index: await writer.processTextureAsync(material.specularColorMap),
8049
8412
  texCoord: material.specularColorMap.channel
8050
8413
  };
8051
8414
  writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
@@ -8063,14 +8426,14 @@ var GLTFMaterialsSheenExtension = class {
8063
8426
  this.writer = writer;
8064
8427
  this.name = "KHR_materials_sheen";
8065
8428
  }
8066
- writeMaterial(material, materialDef) {
8429
+ async writeMaterialAsync(material, materialDef) {
8067
8430
  if (!material.isMeshPhysicalMaterial || material.sheen == 0) return;
8068
8431
  const writer = this.writer;
8069
8432
  const extensionsUsed = writer.extensionsUsed;
8070
8433
  const extensionDef = {};
8071
8434
  if (material.sheenRoughnessMap) {
8072
8435
  const sheenRoughnessMapDef = {
8073
- index: writer.processTexture(material.sheenRoughnessMap),
8436
+ index: await writer.processTextureAsync(material.sheenRoughnessMap),
8074
8437
  texCoord: material.sheenRoughnessMap.channel
8075
8438
  };
8076
8439
  writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
@@ -8078,7 +8441,7 @@ var GLTFMaterialsSheenExtension = class {
8078
8441
  }
8079
8442
  if (material.sheenColorMap) {
8080
8443
  const sheenColorMapDef = {
8081
- index: writer.processTexture(material.sheenColorMap),
8444
+ index: await writer.processTextureAsync(material.sheenColorMap),
8082
8445
  texCoord: material.sheenColorMap.channel
8083
8446
  };
8084
8447
  writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
@@ -8096,13 +8459,13 @@ var GLTFMaterialsAnisotropyExtension = class {
8096
8459
  this.writer = writer;
8097
8460
  this.name = "KHR_materials_anisotropy";
8098
8461
  }
8099
- writeMaterial(material, materialDef) {
8462
+ async writeMaterialAsync(material, materialDef) {
8100
8463
  if (!material.isMeshPhysicalMaterial || material.anisotropy == 0) return;
8101
8464
  const writer = this.writer;
8102
8465
  const extensionsUsed = writer.extensionsUsed;
8103
8466
  const extensionDef = {};
8104
8467
  if (material.anisotropyMap) {
8105
- const anisotropyMapDef = { index: writer.processTexture(material.anisotropyMap) };
8468
+ const anisotropyMapDef = { index: await writer.processTextureAsync(material.anisotropyMap) };
8106
8469
  writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
8107
8470
  extensionDef.anisotropyTexture = anisotropyMapDef;
8108
8471
  }
@@ -8118,7 +8481,7 @@ var GLTFMaterialsEmissiveStrengthExtension = class {
8118
8481
  this.writer = writer;
8119
8482
  this.name = "KHR_materials_emissive_strength";
8120
8483
  }
8121
- writeMaterial(material, materialDef) {
8484
+ async writeMaterialAsync(material, materialDef) {
8122
8485
  if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1) return;
8123
8486
  const writer = this.writer;
8124
8487
  const extensionsUsed = writer.extensionsUsed;
@@ -8129,6 +8492,30 @@ var GLTFMaterialsEmissiveStrengthExtension = class {
8129
8492
  extensionsUsed[this.name] = true;
8130
8493
  }
8131
8494
  };
8495
+ var GLTFMaterialsBumpExtension = class {
8496
+ constructor(writer) {
8497
+ this.writer = writer;
8498
+ this.name = "EXT_materials_bump";
8499
+ }
8500
+ async writeMaterialAsync(material, materialDef) {
8501
+ if (!material.isMeshStandardMaterial || material.bumpScale === 1 && !material.bumpMap) return;
8502
+ const writer = this.writer;
8503
+ const extensionsUsed = writer.extensionsUsed;
8504
+ const extensionDef = {};
8505
+ if (material.bumpMap) {
8506
+ const bumpMapDef = {
8507
+ index: await writer.processTextureAsync(material.bumpMap),
8508
+ texCoord: material.bumpMap.channel
8509
+ };
8510
+ writer.applyTextureTransform(bumpMapDef, material.bumpMap);
8511
+ extensionDef.bumpTexture = bumpMapDef;
8512
+ }
8513
+ extensionDef.bumpFactor = material.bumpScale;
8514
+ materialDef.extensions = materialDef.extensions || {};
8515
+ materialDef.extensions[this.name] = extensionDef;
8516
+ extensionsUsed[this.name] = true;
8517
+ }
8518
+ };
8132
8519
  var GLTFMeshGpuInstancing = class {
8133
8520
  constructor(writer) {
8134
8521
  this.writer = writer;
@@ -8141,10 +8528,10 @@ var GLTFMeshGpuInstancing = class {
8141
8528
  const translationAttr = new Float32Array(mesh.count * 3);
8142
8529
  const rotationAttr = new Float32Array(mesh.count * 4);
8143
8530
  const scaleAttr = new Float32Array(mesh.count * 3);
8144
- const matrix = new import_three19.Matrix4();
8145
- const position = new import_three19.Vector3();
8146
- const quaternion = new import_three19.Quaternion();
8147
- const scale = new import_three19.Vector3();
8531
+ const matrix = new import_three18.Matrix4();
8532
+ const position = new import_three18.Vector3();
8533
+ const quaternion = new import_three18.Quaternion();
8534
+ const scale = new import_three18.Vector3();
8148
8535
  for (let i = 0; i < mesh.count; i++) {
8149
8536
  mesh.getMatrixAt(i, matrix);
8150
8537
  matrix.decompose(position, quaternion, scale);
@@ -8153,9 +8540,9 @@ var GLTFMeshGpuInstancing = class {
8153
8540
  scale.toArray(scaleAttr, i * 3);
8154
8541
  }
8155
8542
  const attributes = {
8156
- TRANSLATION: writer.processAccessor(new import_three19.BufferAttribute(translationAttr, 3)),
8157
- ROTATION: writer.processAccessor(new import_three19.BufferAttribute(rotationAttr, 4)),
8158
- SCALE: writer.processAccessor(new import_three19.BufferAttribute(scaleAttr, 3))
8543
+ TRANSLATION: writer.processAccessor(new import_three18.BufferAttribute(translationAttr, 3)),
8544
+ ROTATION: writer.processAccessor(new import_three18.BufferAttribute(rotationAttr, 4)),
8545
+ SCALE: writer.processAccessor(new import_three18.BufferAttribute(scaleAttr, 3))
8159
8546
  };
8160
8547
  if (mesh.instanceColor)
8161
8548
  attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
@@ -8220,8 +8607,8 @@ GLTFExporter.Utils = {
8220
8607
  const sourceTracks = clip.tracks;
8221
8608
  for (let i = 0; i < sourceTracks.length; ++i) {
8222
8609
  let sourceTrack = sourceTracks[i];
8223
- const sourceTrackBinding = import_three19.PropertyBinding.parseTrackName(sourceTrack.name);
8224
- const sourceTrackNode = import_three19.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
8610
+ const sourceTrackBinding = import_three18.PropertyBinding.parseTrackName(sourceTrack.name);
8611
+ const sourceTrackNode = import_three18.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
8225
8612
  if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
8226
8613
  tracks.push(sourceTrack);
8227
8614
  continue;
@@ -8232,7 +8619,7 @@ GLTFExporter.Utils = {
8232
8619
  }
8233
8620
  console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
8234
8621
  sourceTrack = sourceTrack.clone();
8235
- sourceTrack.setInterpolation(import_three19.InterpolateLinear);
8622
+ sourceTrack.setInterpolation(import_three18.InterpolateLinear);
8236
8623
  }
8237
8624
  const targetCount = sourceTrackNode.morphTargetInfluences.length;
8238
8625
  const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
@@ -8264,6 +8651,19 @@ GLTFExporter.Utils = {
8264
8651
  }
8265
8652
  clip.tracks = tracks;
8266
8653
  return clip;
8654
+ },
8655
+ toTypedBufferAttribute: function(srcAttribute, TypedArray) {
8656
+ const dstAttribute = new import_three18.BufferAttribute(new TypedArray(srcAttribute.count * srcAttribute.itemSize), srcAttribute.itemSize, false);
8657
+ if (!srcAttribute.normalized && !srcAttribute.isInterleavedBufferAttribute) {
8658
+ dstAttribute.array.set(srcAttribute.array);
8659
+ return dstAttribute;
8660
+ }
8661
+ for (let i = 0, il = srcAttribute.count; i < il; i++) {
8662
+ for (let j = 0; j < srcAttribute.itemSize; j++) {
8663
+ dstAttribute.setComponent(i, j, srcAttribute.getComponent(i, j));
8664
+ }
8665
+ }
8666
+ return dstAttribute;
8267
8667
  }
8268
8668
  };
8269
8669
 
@@ -8315,10 +8715,10 @@ var SceneExporter = class {
8315
8715
  }
8316
8716
  };
8317
8717
  function localMatrix(object) {
8318
- return object.matrixAutoUpdate ? new import_three20.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8718
+ return object.matrixAutoUpdate ? new import_three19.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8319
8719
  }
8320
8720
  function createSnapshot(root, gltf, bakeColors = false) {
8321
- const scene = new import_three20.Scene();
8721
+ const scene = new import_three19.Scene();
8322
8722
  const geometries = [];
8323
8723
  const materials = [];
8324
8724
  const textures = [];
@@ -8336,7 +8736,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8336
8736
  if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
8337
8737
  throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
8338
8738
  }
8339
- material = new import_three20.MeshBasicMaterial({
8739
+ material = new import_three19.MeshBasicMaterial({
8340
8740
  map: uniforms.map.value,
8341
8741
  vertexColors: source.vertexColors,
8342
8742
  transparent: source.transparent,
@@ -8346,7 +8746,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8346
8746
  });
8347
8747
  material.name = source.name;
8348
8748
  } else if (shader.isShaderMaterial) {
8349
- material = new import_three20.MeshBasicMaterial({ vertexColors: source.vertexColors });
8749
+ material = new import_three19.MeshBasicMaterial({ vertexColors: source.vertexColors });
8350
8750
  material.name = source.name;
8351
8751
  } else {
8352
8752
  const copySource = Object.create(source);
@@ -8400,11 +8800,11 @@ function createSnapshot(root, gltf, bakeColors = false) {
8400
8800
  const material = copyMaterial(sourceMaterial, geometry);
8401
8801
  if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
8402
8802
  if (bakeColors || instanceColor) {
8403
- const tint = (material.color ?? new import_three20.Color()).clone();
8803
+ const tint = (material.color ?? new import_three19.Color()).clone();
8404
8804
  if (instanceColor) tint.multiply(instanceColor);
8405
8805
  if (bakeColors) {
8406
8806
  const original = geometry.getAttribute("color");
8407
- const colors = new import_three20.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
8807
+ const colors = new import_three19.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
8408
8808
  for (let i = 0; i < colors.count; i++) {
8409
8809
  colors.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
8410
8810
  }
@@ -8413,7 +8813,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8413
8813
  material.color.copy(tint);
8414
8814
  }
8415
8815
  }
8416
- const copy = new import_three20.Mesh(geometry, material);
8816
+ const copy = new import_three19.Mesh(geometry, material);
8417
8817
  copy.name = mesh.name;
8418
8818
  copy.renderOrder = mesh.renderOrder;
8419
8819
  scene.add(copy);
@@ -8427,9 +8827,9 @@ function createSnapshot(root, gltf, bakeColors = false) {
8427
8827
  const instanced = mesh;
8428
8828
  if (instanced.isInstancedMesh) {
8429
8829
  for (let i = 0; i < instanced.count; i++) {
8430
- const matrix = new import_three20.Matrix4();
8830
+ const matrix = new import_three19.Matrix4();
8431
8831
  instanced.getMatrixAt(i, matrix);
8432
- const color = instanced.instanceColor ? new import_three20.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
8832
+ const color = instanced.instanceColor ? new import_three19.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
8433
8833
  addMesh(mesh, world.clone().multiply(matrix), color);
8434
8834
  }
8435
8835
  } else {
@@ -8441,7 +8841,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8441
8841
  try {
8442
8842
  const ancestors = [];
8443
8843
  for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
8444
- const world = new import_three20.Matrix4();
8844
+ const world = new import_three19.Matrix4();
8445
8845
  for (const ancestor of ancestors) {
8446
8846
  if (!ancestor.visible) return { scene, dispose };
8447
8847
  world.multiply(localMatrix(ancestor));
@@ -8455,7 +8855,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8455
8855
  }
8456
8856
  function selectAlphaMode(material, geometry) {
8457
8857
  const texture = material.map;
8458
- 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;
8858
+ 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;
8459
8859
  const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
8460
8860
  const colors = geometry.getAttribute("color");
8461
8861
  if (!uv || material.vertexColors && colors?.itemSize === 4) return;
@@ -8492,7 +8892,7 @@ function selectAlphaMode(material, geometry) {
8492
8892
  }
8493
8893
  function copyDataTexture(source) {
8494
8894
  const image = source.image;
8495
- if (source.format !== import_three20.RGBAFormat || source.type !== import_three20.UnsignedByteType) {
8895
+ if (!image.data || source.format !== import_three19.RGBAFormat || source.type !== import_three19.UnsignedByteType) {
8496
8896
  throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
8497
8897
  }
8498
8898
  const canvas = createCanvas2(image.width, image.height);
@@ -8503,8 +8903,8 @@ function copyDataTexture(source) {
8503
8903
  context.putImageData(pixels, 0, 0);
8504
8904
  const copySource = Object.create(source);
8505
8905
  copySource.userData = {};
8506
- copySource.source = new import_three20.Source(canvas);
8507
- return new import_three20.Texture().copy(copySource);
8906
+ copySource.source = new import_three19.TextureSource(canvas);
8907
+ return new import_three19.Texture().copy(copySource);
8508
8908
  }
8509
8909
 
8510
8910
  // src/gui/GuiHelper.ts
@@ -8574,7 +8974,7 @@ var GuiHelper = class {
8574
8974
  };
8575
8975
 
8576
8976
  // src/gui/scene/GuiObject.ts
8577
- var import_three25 = require("three");
8977
+ var import_three24 = require("three");
8578
8978
  init_AssetKey();
8579
8979
  init_ModelTextures();
8580
8980
  init_Models();
@@ -8590,7 +8990,7 @@ var GuiObject = class extends SceneObject {
8590
8990
  this.textureLayers = textureLayers;
8591
8991
  this.isGuiObject = true;
8592
8992
  /** Local bounds in GUI pixels, with y growing down from the origin. */
8593
- this.bounds = new import_three25.Box2();
8993
+ this.bounds = new import_three24.Box2();
8594
8994
  this.geometries = /* @__PURE__ */ new Set();
8595
8995
  this.ownedMaterials = /* @__PURE__ */ new Set();
8596
8996
  this.initialized = false;
@@ -8608,17 +9008,17 @@ var GuiObject = class extends SceneObject {
8608
9008
  item.scale.set(width2 / 16, height2 / 16, width2 / 16);
8609
9009
  item.updateWorldMatrix(true, true);
8610
9010
  const inverse = this.matrixWorld.clone().invert();
8611
- const bounds = new import_three25.Box3();
9011
+ const bounds = new import_three24.Box3();
8612
9012
  item.iterateAllMeshes((mesh2) => {
8613
9013
  mesh2.geometry.computeBoundingBox();
8614
- bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new import_three25.Matrix4().multiplyMatrices(inverse, mesh2.matrixWorld)));
9014
+ bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new import_three24.Matrix4().multiplyMatrices(inverse, mesh2.matrixWorld)));
8615
9015
  });
8616
9016
  item.position.z = depth - bounds.min.z;
8617
9017
  depth += bounds.max.z - bounds.min.z + 0.01;
8618
- this.bounds.expandByPoint(new import_three25.Vector2(x, y));
8619
- this.bounds.expandByPoint(new import_three25.Vector2(x + width2, y + height2));
8620
- this.bounds.expandByPoint(new import_three25.Vector2(bounds.min.x, -bounds.max.y));
8621
- this.bounds.expandByPoint(new import_three25.Vector2(bounds.max.x, -bounds.min.y));
9018
+ this.bounds.expandByPoint(new import_three24.Vector2(x, y));
9019
+ this.bounds.expandByPoint(new import_three24.Vector2(x + width2, y + height2));
9020
+ this.bounds.expandByPoint(new import_three24.Vector2(bounds.min.x, -bounds.max.y));
9021
+ this.bounds.expandByPoint(new import_three24.Vector2(bounds.max.x, -bounds.min.y));
8622
9022
  continue;
8623
9023
  }
8624
9024
  const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
@@ -8626,7 +9026,7 @@ var GuiObject = class extends SceneObject {
8626
9026
  const image = material.map.image;
8627
9027
  const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
8628
9028
  const [width, height] = layer.size ?? [cropWidth, cropHeight];
8629
- const geometry = new import_three25.PlaneGeometry(width, height);
9029
+ const geometry = new import_three24.PlaneGeometry(width, height);
8630
9030
  this.geometries.add(geometry);
8631
9031
  const uv = geometry.getAttribute("uv");
8632
9032
  for (let i = 0; i < uv.count; i++) {
@@ -8636,13 +9036,13 @@ var GuiObject = class extends SceneObject {
8636
9036
  1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
8637
9037
  );
8638
9038
  }
8639
- const mesh = new import_three25.Mesh(geometry, material);
9039
+ const mesh = new import_three24.Mesh(geometry, material);
8640
9040
  mesh.name = `mesh:${layer.name ?? index}`;
8641
9041
  mesh.position.set(x + width / 2, -y - height / 2, depth);
8642
9042
  mesh.renderOrder = index;
8643
9043
  this.add(mesh);
8644
- this.bounds.expandByPoint(new import_three25.Vector2(x, y));
8645
- this.bounds.expandByPoint(new import_three25.Vector2(x + width, y + height));
9044
+ this.bounds.expandByPoint(new import_three24.Vector2(x, y));
9045
+ this.bounds.expandByPoint(new import_three24.Vector2(x + width, y + height));
8646
9046
  depth += 0.01;
8647
9047
  }
8648
9048
  for (const child of this.children) child.position.z -= depth - 0.01;
@@ -8717,7 +9117,7 @@ function isGuiObject(obj) {
8717
9117
  init_image();
8718
9118
 
8719
9119
  // src/inspector/SceneInspector.ts
8720
- var import_three26 = require("three");
9120
+ var import_three25 = require("three");
8721
9121
  init_SceneObject();
8722
9122
  init_util();
8723
9123
  init_log();
@@ -8727,11 +9127,11 @@ var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
8727
9127
  var SceneInspector = class {
8728
9128
  constructor(renderer) {
8729
9129
  this.renderer = renderer;
8730
- this.mouse = new import_three26.Vector2();
9130
+ this.mouse = new import_three25.Vector2();
8731
9131
  this.listeners = new AbortController();
8732
9132
  this.objectInfoContainer = document.createElement("div");
8733
9133
  this.objectControlsContainer = document.createElement("div");
8734
- this.raycaster = new import_three26.Raycaster();
9134
+ this.raycaster = new import_three25.Raycaster();
8735
9135
  this.init();
8736
9136
  }
8737
9137
  init() {
@@ -9134,7 +9534,7 @@ init_ModelMerger();
9134
9534
  init_SpecialItems();
9135
9535
 
9136
9536
  // src/model/block/BlockStateResolver.ts
9137
- var import_three28 = require("three");
9537
+ var import_three27 = require("three");
9138
9538
  init_BlockStates();
9139
9539
  init_MineRenderError();
9140
9540
  init_util();
@@ -9212,7 +9612,7 @@ var BlockStateResolver = class {
9212
9612
  return variants[variants.length - 1];
9213
9613
  }
9214
9614
  static rotation(variant) {
9215
- const rotation = new import_three28.Euler();
9615
+ const rotation = new import_three27.Euler();
9216
9616
  if (typeof variant.x !== "undefined") {
9217
9617
  rotation.x = toRadians(clampRotationDegrees(variant.x));
9218
9618
  }
@@ -9304,7 +9704,7 @@ init_SceneObject();
9304
9704
  init_ModelObject();
9305
9705
  init_Models();
9306
9706
  var import_ts_deepmerge6 = __toESM(require_dist());
9307
- var import_three31 = require("three");
9707
+ var import_three30 = require("three");
9308
9708
  init_MineRenderError();
9309
9709
  init_InstanceReference();
9310
9710
  init_AssetKey();
@@ -9326,7 +9726,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9326
9726
  this._models = [];
9327
9727
  this._cullMask = 0;
9328
9728
  this._entities = [];
9329
- this._entityPlacement = new import_three31.Matrix4();
9729
+ this._entityPlacement = new import_three30.Matrix4();
9330
9730
  this._entityGeneration = 0;
9331
9731
  this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
9332
9732
  }
@@ -9427,7 +9827,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9427
9827
  return true;
9428
9828
  }
9429
9829
  placeEntities() {
9430
- const matrix = new import_three31.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
9830
+ const matrix = new import_three30.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
9431
9831
  for (const entity of this._entities) {
9432
9832
  matrix.decompose(entity.position, entity.quaternion, entity.scale);
9433
9833
  }
@@ -9449,12 +9849,12 @@ var BlockObject = class _BlockObject extends SceneObject {
9449
9849
  getModelCullMask(model, worldMask) {
9450
9850
  const object = isInstanceReference(model) ? model.instanceable : model;
9451
9851
  if (object.options.displayPosition) return 0;
9452
- const position = new import_three31.Vector3();
9453
- const rotation = new import_three31.Quaternion();
9454
- const scale = new import_three31.Vector3();
9852
+ const position = new import_three30.Vector3();
9853
+ const rotation = new import_three30.Quaternion();
9854
+ const scale = new import_three30.Vector3();
9455
9855
  this.getModelMatrix(model).decompose(position, rotation, scale);
9456
- if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three31.Vector3(1, 1, 1)) > 1e-10) return 0;
9457
- return ModelCulling.toLocalMask(worldMask, new import_three31.Euler().setFromQuaternion(rotation));
9856
+ if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three30.Vector3(1, 1, 1)) > 1e-10) return 0;
9857
+ return ModelCulling.toLocalMask(worldMask, new import_three30.Euler().setFromQuaternion(rotation));
9458
9858
  }
9459
9859
  async setCullMask(worldMask) {
9460
9860
  worldMask &= 63;
@@ -9478,6 +9878,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9478
9878
  replacement.setMatrix(matrix);
9479
9879
  } else {
9480
9880
  replacement.matrix.copy(matrix);
9881
+ replacement.matrixWorldNeedsUpdate = true;
9481
9882
  matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
9482
9883
  replacement.matrixAutoUpdate = object.matrixAutoUpdate;
9483
9884
  replacement.visible = object.visible;
@@ -9519,7 +9920,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9519
9920
  () => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
9520
9921
  );
9521
9922
  const previous = this._fluidModel;
9522
- const matrix = previous ? this.getModelMatrix(previous) : new import_three31.Matrix4().makeTranslation(...this.position.toArray());
9923
+ const matrix = previous ? this.getModelMatrix(previous) : new import_three30.Matrix4().makeTranslation(...this.position.toArray());
9523
9924
  if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
9524
9925
  else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
9525
9926
  this._models = this._models.filter((model) => model !== previous);
@@ -9661,7 +10062,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9661
10062
  setPositionRotationScaleAt(index, position, rotation, scale) {
9662
10063
  super.setPositionRotationScaleAt(index, position, rotation, scale);
9663
10064
  }
9664
- getMatrixAt(index, matrix = new import_three31.Matrix4()) {
10065
+ getMatrixAt(index, matrix = new import_three30.Matrix4()) {
9665
10066
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
9666
10067
  const child = this._models[0];
9667
10068
  if (child && isModelObject(child)) {
@@ -11533,7 +11934,7 @@ init_ModelObject();
11533
11934
  init_nbt();
11534
11935
 
11535
11936
  // src/renderer/MineRenderScene.ts
11536
- var import_three33 = require("three");
11937
+ var import_three32 = require("three");
11537
11938
  init_SceneObject();
11538
11939
  var import_ts_deepmerge8 = __toESM(require_dist());
11539
11940
  init_ModelObject();
@@ -12266,7 +12667,7 @@ var import_ts_deepmerge7 = __toESM(require_dist());
12266
12667
  init_util();
12267
12668
 
12268
12669
  // src/skin/SkinTextures.ts
12269
- var import_three32 = require("three");
12670
+ var import_three31 = require("three");
12270
12671
  init_Caching();
12271
12672
  init_CacheKey();
12272
12673
  init_MineRenderError();
@@ -12350,11 +12751,11 @@ var SkinTextures = class {
12350
12751
  });
12351
12752
  }
12352
12753
  static createMaterial(pixels, width, height, transparent = true) {
12353
- const texture = Textures.initTextureProps(new import_three32.DataTexture(pixels, width, height));
12354
- texture.colorSpace = import_three32.SRGBColorSpace;
12754
+ const texture = Textures.initTextureProps(new import_three31.DataTexture(pixels, width, height));
12755
+ texture.colorSpace = import_three31.SRGBColorSpace;
12355
12756
  texture.flipY = true;
12356
12757
  texture.needsUpdate = true;
12357
- return new import_three32.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three32.DoubleSide : import_three32.FrontSide, alphaTest: transparent ? 0.1 : 0 });
12758
+ return new import_three31.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three31.DoubleSide : import_three31.FrontSide, alphaTest: transparent ? 0.1 : 0 });
12358
12759
  }
12359
12760
  static isSlim(image, scale) {
12360
12761
  for (const [x, y] of [[46, 52], [54, 20]]) {
@@ -12584,7 +12985,7 @@ var SkinObject = class extends SceneObject {
12584
12985
  // src/renderer/MineRenderScene.ts
12585
12986
  init_EntityObject();
12586
12987
  init_ItemTints();
12587
- var MineRenderScene = class _MineRenderScene extends import_three33.Scene {
12988
+ var MineRenderScene = class _MineRenderScene extends import_three32.Scene {
12588
12989
  constructor(options) {
12589
12990
  super();
12590
12991
  this.isMineRenderScene = true;
@@ -12630,12 +13031,13 @@ var MineRenderScene = class _MineRenderScene extends import_three33.Scene {
12630
13031
  }
12631
13032
  updateObjectRegistration(object, attached) {
12632
13033
  if (this.observedObjects.has(object) === attached) return;
13034
+ const observable = object;
12633
13035
  if (attached) {
12634
13036
  this.observedObjects.add(object);
12635
- object.addEventListener("change", this.onObjectChange);
13037
+ observable.addEventListener("change", this.onObjectChange);
12636
13038
  } else {
12637
13039
  this.observedObjects.delete(object);
12638
- object.removeEventListener("change", this.onObjectChange);
13040
+ observable.removeEventListener("change", this.onObjectChange);
12639
13041
  }
12640
13042
  const change = attached ? 1 : -1;
12641
13043
  this.stats.objectCount += change;
@@ -12713,7 +13115,7 @@ function isMineRenderScene(obj) {
12713
13115
  }
12714
13116
 
12715
13117
  // src/renderer/Renderer.ts
12716
- var import_three35 = require("three");
13118
+ var import_three34 = require("three");
12717
13119
  var import_ts_deepmerge9 = __toESM(require_dist());
12718
13120
  var import_stats = __toESM(require("stats.js"));
12719
13121
  var import_postprocessing = require("postprocessing");
@@ -12722,11 +13124,11 @@ init_Model();
12722
13124
  init_three();
12723
13125
 
12724
13126
  // src/three/OrbitControls.js
12725
- var import_three34 = require("three");
13127
+ var import_three33 = require("three");
12726
13128
  var _changeEvent = { type: "change" };
12727
13129
  var _startEvent = { type: "start" };
12728
13130
  var _endEvent = { type: "end" };
12729
- var OrbitControls = class extends import_three34.EventDispatcher {
13131
+ var OrbitControls = class extends import_three33.EventDispatcher {
12730
13132
  constructor(object, domElement) {
12731
13133
  super();
12732
13134
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
@@ -12735,7 +13137,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12735
13137
  this.domElement = domElement;
12736
13138
  this.domElement.style.touchAction = "none";
12737
13139
  this.enabled = true;
12738
- this.target = new import_three34.Vector3();
13140
+ this.target = new import_three33.Vector3();
12739
13141
  this.minDistance = 0;
12740
13142
  this.maxDistance = Infinity;
12741
13143
  this.minZoom = 0;
@@ -12757,8 +13159,8 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12757
13159
  this.autoRotate = false;
12758
13160
  this.autoRotateSpeed = 2;
12759
13161
  this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
12760
- this.mouseButtons = { LEFT: import_three34.MOUSE.ROTATE, MIDDLE: import_three34.MOUSE.DOLLY, RIGHT: import_three34.MOUSE.PAN };
12761
- this.touches = { ONE: import_three34.TOUCH.ROTATE, TWO: import_three34.TOUCH.DOLLY_PAN };
13162
+ this.mouseButtons = { LEFT: import_three33.MOUSE.ROTATE, MIDDLE: import_three33.MOUSE.DOLLY, RIGHT: import_three33.MOUSE.PAN };
13163
+ this.touches = { ONE: import_three33.TOUCH.ROTATE, TWO: import_three33.TOUCH.DOLLY_PAN };
12762
13164
  this.target0 = this.target.clone();
12763
13165
  this.position0 = this.object.position.clone();
12764
13166
  this.zoom0 = this.object.zoom;
@@ -12787,11 +13189,11 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12787
13189
  state = STATE.NONE;
12788
13190
  };
12789
13191
  this.update = function() {
12790
- const offset = new import_three34.Vector3();
12791
- const quat = new import_three34.Quaternion().setFromUnitVectors(object.up, new import_three34.Vector3(0, 1, 0));
13192
+ const offset = new import_three33.Vector3();
13193
+ const quat = new import_three33.Quaternion().setFromUnitVectors(object.up, new import_three33.Vector3(0, 1, 0));
12792
13194
  const quatInverse = quat.clone().invert();
12793
- const lastPosition = new import_three34.Vector3();
12794
- const lastQuaternion = new import_three34.Quaternion();
13195
+ const lastPosition = new import_three33.Vector3();
13196
+ const lastQuaternion = new import_three33.Quaternion();
12795
13197
  const twoPI = 2 * Math.PI;
12796
13198
  return function update() {
12797
13199
  const position = scope.object.position;
@@ -12877,20 +13279,20 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12877
13279
  };
12878
13280
  let state = STATE.NONE;
12879
13281
  const EPS = 1e-6;
12880
- const spherical = new import_three34.Spherical();
12881
- const sphericalDelta = new import_three34.Spherical();
13282
+ const spherical = new import_three33.Spherical();
13283
+ const sphericalDelta = new import_three33.Spherical();
12882
13284
  let scale = 1;
12883
- const panOffset = new import_three34.Vector3();
13285
+ const panOffset = new import_three33.Vector3();
12884
13286
  let zoomChanged = false;
12885
- const rotateStart = new import_three34.Vector2();
12886
- const rotateEnd = new import_three34.Vector2();
12887
- const rotateDelta = new import_three34.Vector2();
12888
- const panStart = new import_three34.Vector2();
12889
- const panEnd = new import_three34.Vector2();
12890
- const panDelta = new import_three34.Vector2();
12891
- const dollyStart = new import_three34.Vector2();
12892
- const dollyEnd = new import_three34.Vector2();
12893
- const dollyDelta = new import_three34.Vector2();
13287
+ const rotateStart = new import_three33.Vector2();
13288
+ const rotateEnd = new import_three33.Vector2();
13289
+ const rotateDelta = new import_three33.Vector2();
13290
+ const panStart = new import_three33.Vector2();
13291
+ const panEnd = new import_three33.Vector2();
13292
+ const panDelta = new import_three33.Vector2();
13293
+ const dollyStart = new import_three33.Vector2();
13294
+ const dollyEnd = new import_three33.Vector2();
13295
+ const dollyDelta = new import_three33.Vector2();
12894
13296
  const pointers = [];
12895
13297
  const pointerPositions = {};
12896
13298
  function getAutoRotationAngle() {
@@ -12906,7 +13308,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12906
13308
  sphericalDelta.phi -= angle;
12907
13309
  }
12908
13310
  const panLeft = function() {
12909
- const v = new import_three34.Vector3();
13311
+ const v = new import_three33.Vector3();
12910
13312
  return function panLeft2(distance, objectMatrix) {
12911
13313
  v.setFromMatrixColumn(objectMatrix, 0);
12912
13314
  v.multiplyScalar(-distance);
@@ -12914,7 +13316,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12914
13316
  };
12915
13317
  }();
12916
13318
  const panUp = function() {
12917
- const v = new import_three34.Vector3();
13319
+ const v = new import_three33.Vector3();
12918
13320
  return function panUp2(distance, objectMatrix) {
12919
13321
  if (scope.screenSpacePanning === true) {
12920
13322
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -12927,7 +13329,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
12927
13329
  };
12928
13330
  }();
12929
13331
  const pan = function() {
12930
- const offset = new import_three34.Vector3();
13332
+ const offset = new import_three33.Vector3();
12931
13333
  return function pan2(deltaX, deltaY) {
12932
13334
  const element = scope.domElement;
12933
13335
  if (scope.object.isPerspectiveCamera) {
@@ -13176,12 +13578,12 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13176
13578
  mouseAction = -1;
13177
13579
  }
13178
13580
  switch (mouseAction) {
13179
- case import_three34.MOUSE.DOLLY:
13581
+ case import_three33.MOUSE.DOLLY:
13180
13582
  if (scope.enableZoom === false) return;
13181
13583
  handleMouseDownDolly(event);
13182
13584
  state = STATE.DOLLY;
13183
13585
  break;
13184
- case import_three34.MOUSE.ROTATE:
13586
+ case import_three33.MOUSE.ROTATE:
13185
13587
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
13186
13588
  if (scope.enablePan === false) return;
13187
13589
  handleMouseDownPan(event);
@@ -13192,7 +13594,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13192
13594
  state = STATE.ROTATE;
13193
13595
  }
13194
13596
  break;
13195
- case import_three34.MOUSE.PAN:
13597
+ case import_three33.MOUSE.PAN:
13196
13598
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
13197
13599
  if (scope.enableRotate === false) return;
13198
13600
  handleMouseDownRotate(event);
@@ -13248,12 +13650,12 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13248
13650
  switch (pointers.length) {
13249
13651
  case 1:
13250
13652
  switch (scope.touches.ONE) {
13251
- case import_three34.TOUCH.ROTATE:
13653
+ case import_three33.TOUCH.ROTATE:
13252
13654
  if (scope.enableRotate === false) return;
13253
13655
  handleTouchStartRotate();
13254
13656
  state = STATE.TOUCH_ROTATE;
13255
13657
  break;
13256
- case import_three34.TOUCH.PAN:
13658
+ case import_three33.TOUCH.PAN:
13257
13659
  if (scope.enablePan === false) return;
13258
13660
  handleTouchStartPan();
13259
13661
  state = STATE.TOUCH_PAN;
@@ -13264,12 +13666,12 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13264
13666
  break;
13265
13667
  case 2:
13266
13668
  switch (scope.touches.TWO) {
13267
- case import_three34.TOUCH.DOLLY_PAN:
13669
+ case import_three33.TOUCH.DOLLY_PAN:
13268
13670
  if (scope.enableZoom === false && scope.enablePan === false) return;
13269
13671
  handleTouchStartDollyPan();
13270
13672
  state = STATE.TOUCH_DOLLY_PAN;
13271
13673
  break;
13272
- case import_three34.TOUCH.DOLLY_ROTATE:
13674
+ case import_three33.TOUCH.DOLLY_ROTATE:
13273
13675
  if (scope.enableZoom === false && scope.enableRotate === false) return;
13274
13676
  handleTouchStartDollyRotate();
13275
13677
  state = STATE.TOUCH_DOLLY_ROTATE;
@@ -13336,7 +13738,7 @@ var OrbitControls = class extends import_three34.EventDispatcher {
13336
13738
  function trackPointer(event) {
13337
13739
  let position = pointerPositions[event.pointerId];
13338
13740
  if (position === void 0) {
13339
- position = new import_three34.Vector2();
13741
+ position = new import_three33.Vector2();
13340
13742
  pointerPositions[event.pointerId] = position;
13341
13743
  }
13342
13744
  position.set(event.pageX, event.pageY);
@@ -13356,10 +13758,10 @@ var MapControls = class extends OrbitControls {
13356
13758
  constructor(object, domElement) {
13357
13759
  super(object, domElement);
13358
13760
  this.screenSpacePanning = false;
13359
- this.mouseButtons.LEFT = import_three34.MOUSE.PAN;
13360
- this.mouseButtons.RIGHT = import_three34.MOUSE.ROTATE;
13361
- this.touches.ONE = import_three34.TOUCH.PAN;
13362
- this.touches.TWO = import_three34.TOUCH.DOLLY_ROTATE;
13761
+ this.mouseButtons.LEFT = import_three33.MOUSE.PAN;
13762
+ this.mouseButtons.RIGHT = import_three33.MOUSE.ROTATE;
13763
+ this.touches.ONE = import_three33.TOUCH.PAN;
13764
+ this.touches.TWO = import_three33.TOUCH.DOLLY_ROTATE;
13363
13765
  }
13364
13766
  };
13365
13767
 
@@ -13418,8 +13820,8 @@ var Renderer = class _Renderer {
13418
13820
  top: void 0,
13419
13821
  bottom: void 0
13420
13822
  },
13421
- position: new import_three35.Vector3(50, 50, 50),
13422
- lookingAt: new import_three35.Vector3(0, 0, 0)
13823
+ position: new import_three34.Vector3(50, 50, 50),
13824
+ lookingAt: new import_three34.Vector3(0, 0, 0)
13423
13825
  },
13424
13826
  render: {
13425
13827
  fpsLimit: 60,
@@ -13450,14 +13852,14 @@ var Renderer = class _Renderer {
13450
13852
  switch (this.options.camera.type) {
13451
13853
  case "perspective":
13452
13854
  default:
13453
- return new import_three35.PerspectiveCamera(
13855
+ return new import_three34.PerspectiveCamera(
13454
13856
  this.options.camera.perspective.fov,
13455
13857
  this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
13456
13858
  this.options.camera.near,
13457
13859
  this.options.camera.far
13458
13860
  );
13459
13861
  case "orthographic":
13460
- return new import_three35.OrthographicCamera(
13862
+ return new import_three34.OrthographicCamera(
13461
13863
  this.options.camera.orthographic.left ?? this.viewWidth / -2,
13462
13864
  this.options.camera.orthographic.right ?? this.viewWidth / 2,
13463
13865
  this.options.camera.orthographic.top ?? this.viewHeight / 2,
@@ -13468,7 +13870,7 @@ var Renderer = class _Renderer {
13468
13870
  }
13469
13871
  }
13470
13872
  createRenderer() {
13471
- const renderer = new import_three35.WebGLRenderer({
13873
+ const renderer = new import_three34.WebGLRenderer({
13472
13874
  antialias: this.options.render.antialias,
13473
13875
  alpha: true,
13474
13876
  powerPreference: "high-performance",
@@ -13476,8 +13878,8 @@ var Renderer = class _Renderer {
13476
13878
  });
13477
13879
  renderer.setClearColor(0, 0);
13478
13880
  renderer.shadowMap.enabled = true;
13479
- renderer.shadowMap.type = import_three35.PCFSoftShadowMap;
13480
- renderer.outputColorSpace = import_three35.SRGBColorSpace;
13881
+ renderer.shadowMap.type = import_three34.PCFShadowMap;
13882
+ renderer.outputColorSpace = import_three34.SRGBColorSpace;
13481
13883
  renderer.setPixelRatio(this.options.render.pixelRatio ?? 1);
13482
13884
  renderer.setSize(this.viewWidth, this.viewHeight);
13483
13885
  return renderer;
@@ -13512,20 +13914,20 @@ var Renderer = class _Renderer {
13512
13914
  window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
13513
13915
  }
13514
13916
  if (this.options.debug.grid) {
13515
- const gridHelper = new import_three35.GridHelper(128, 16);
13917
+ const gridHelper = new import_three34.GridHelper(128, 16);
13516
13918
  this._debugHelpers.push(gridHelper);
13517
13919
  this.scene.add(gridHelper);
13518
- const gridHelper2 = new import_three35.GridHelper(128, 16);
13920
+ const gridHelper2 = new import_three34.GridHelper(128, 16);
13519
13921
  this._debugHelpers.push(gridHelper2);
13520
13922
  gridHelper2.rotation.x = 90 * (Math.PI / 180);
13521
13923
  this.scene.add(gridHelper2);
13522
- const gridHelper3 = new import_three35.GridHelper(128, 16);
13924
+ const gridHelper3 = new import_three34.GridHelper(128, 16);
13523
13925
  this._debugHelpers.push(gridHelper3);
13524
13926
  gridHelper3.rotation.z = 90 * (Math.PI / 180);
13525
13927
  this.scene.add(gridHelper3);
13526
13928
  }
13527
13929
  if (this.options.debug.axes) {
13528
- const axesHelper = new import_three35.AxesHelper(64);
13930
+ const axesHelper = new import_three34.AxesHelper(64);
13529
13931
  this._debugHelpers.push(axesHelper);
13530
13932
  this.scene.add(axesHelper);
13531
13933
  }
@@ -14211,12 +14613,12 @@ var AnvilParser = class {
14211
14613
  };
14212
14614
 
14213
14615
  // src/world/Chunk.ts
14214
- var import_three40 = require("three");
14616
+ var import_three39 = require("three");
14215
14617
  init_BlockStates();
14216
14618
  init_AssetKey();
14217
14619
 
14218
14620
  // src/world/MineRenderWorld.ts
14219
- var import_three38 = require("three");
14621
+ var import_three37 = require("three");
14220
14622
  init_Model();
14221
14623
  init_BatchedExecutor();
14222
14624
  init_AssetKey();
@@ -14224,7 +14626,7 @@ init_BlockStates();
14224
14626
  init_CubeFace();
14225
14627
 
14226
14628
  // src/world/SectionModels.ts
14227
- var import_three37 = require("three");
14629
+ var import_three36 = require("three");
14228
14630
  init_AssetKey();
14229
14631
  init_Models();
14230
14632
  init_CubeFace();
@@ -14290,12 +14692,12 @@ var SectionModels = class {
14290
14692
  });
14291
14693
  await object.init();
14292
14694
  const geometry = object.children[0].geometry;
14293
- geometry.applyMatrix4(new import_three37.Matrix4().makeRotationFromEuler(rotation));
14695
+ geometry.applyMatrix4(new import_three36.Matrix4().makeRotationFromEuler(rotation));
14294
14696
  object.clear();
14295
14697
  const cullFaces = CUBE_FACES.map((face) => {
14296
14698
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
14297
14699
  if (local < 0) return 0;
14298
- const normal = new import_three37.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
14700
+ const normal = new import_three36.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
14299
14701
  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);
14300
14702
  return 1 << world;
14301
14703
  });
@@ -14325,20 +14727,20 @@ var MineRenderWorld = class {
14325
14727
  }
14326
14728
  getBlockAt(posOrX, y, z) {
14327
14729
  if (typeof posOrX == "number") {
14328
- return this.getBlockAt(new import_three38.Vector3(posOrX, y, z));
14730
+ return this.getBlockAt(new import_three37.Vector3(posOrX, y, z));
14329
14731
  }
14330
14732
  if (isTripleArray(posOrX)) {
14331
- return this.getBlockAt(new import_three38.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14733
+ return this.getBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14332
14734
  }
14333
14735
  this.validatePosBounds(posOrX);
14334
14736
  return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
14335
14737
  }
14336
14738
  async setBlockAt(posOrX, yOrBlock, z, block) {
14337
14739
  if (typeof posOrX == "number") {
14338
- return this.setBlockAt(new import_three38.Vector3(posOrX, yOrBlock, z), block);
14740
+ return this.setBlockAt(new import_three37.Vector3(posOrX, yOrBlock, z), block);
14339
14741
  }
14340
14742
  if (isTripleArray(posOrX)) {
14341
- return this.setBlockAt(new import_three38.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14743
+ return this.setBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14342
14744
  }
14343
14745
  return this.placeBlock(posOrX, yOrBlock);
14344
14746
  }
@@ -14349,10 +14751,10 @@ var MineRenderWorld = class {
14349
14751
  }
14350
14752
  async setBlockVisibleAt(posOrX, yOrVisible, z, visible) {
14351
14753
  if (typeof posOrX === "number") {
14352
- return this.setBlockVisibleAt(new import_three38.Vector3(posOrX, yOrVisible, z), visible);
14754
+ return this.setBlockVisibleAt(new import_three37.Vector3(posOrX, yOrVisible, z), visible);
14353
14755
  }
14354
14756
  if (isTripleArray(posOrX)) {
14355
- return this.setBlockVisibleAt(new import_three38.Vector3(...posOrX), yOrVisible);
14757
+ return this.setBlockVisibleAt(new import_three37.Vector3(...posOrX), yOrVisible);
14356
14758
  }
14357
14759
  this.validatePosBounds(posOrX);
14358
14760
  await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
@@ -14369,7 +14771,7 @@ var MineRenderWorld = class {
14369
14771
  const collect = async (positions2) => {
14370
14772
  for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
14371
14773
  };
14372
- const place = (block) => this.placeBlock(new import_three38.Vector3(...block.position), block, collect);
14774
+ const place = (block) => this.placeBlock(new import_three37.Vector3(...block.position), block, collect);
14373
14775
  const keys = /* @__PURE__ */ new Map();
14374
14776
  for (const block of multiblock.blocks) {
14375
14777
  if (Chunk.isAir(block)) continue;
@@ -14447,13 +14849,13 @@ var MineRenderWorld = class {
14447
14849
  for (const pos of positions) {
14448
14850
  this.pendingCulling.set(pos.toArray().join(","), pos.clone());
14449
14851
  for (const offset of CUBE_FACE_OFFSETS) {
14450
- const neighbor = pos.clone().add(new import_three38.Vector3(...offset));
14852
+ const neighbor = pos.clone().add(new import_three37.Vector3(...offset));
14451
14853
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14452
14854
  }
14453
14855
  for (let y = -1; y <= 1; y++) {
14454
14856
  for (let z = -1; z <= 1; z++) {
14455
14857
  for (let x = -1; x <= 1; x++) {
14456
- const neighbor = pos.clone().add(new import_three38.Vector3(x, y, z));
14858
+ const neighbor = pos.clone().add(new import_three37.Vector3(x, y, z));
14457
14859
  if (this.getBlockAt(neighbor)?.object?.fluidKind) {
14458
14860
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14459
14861
  }
@@ -14477,7 +14879,7 @@ var MineRenderWorld = class {
14477
14879
  }
14478
14880
  if (block.object?.fluidKind) {
14479
14881
  await block.object.updateFluid((x, y, z) => {
14480
- const neighbor = pos.clone().add(new import_three38.Vector3(x, y, z));
14882
+ const neighbor = pos.clone().add(new import_three37.Vector3(x, y, z));
14481
14883
  const section = this.getChunkAt(neighbor);
14482
14884
  const object = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
14483
14885
  return {
@@ -14489,7 +14891,7 @@ var MineRenderWorld = class {
14489
14891
  }
14490
14892
  let mask = 0;
14491
14893
  for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
14492
- const neighbor = pos.clone().add(new import_three38.Vector3(...offset));
14894
+ const neighbor = pos.clone().add(new import_three37.Vector3(...offset));
14493
14895
  if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
14494
14896
  mask |= 1 << face;
14495
14897
  }
@@ -14523,14 +14925,14 @@ var MineRenderWorld = class {
14523
14925
  return this._chunks.get(this.worldPosToChunkKey(pos));
14524
14926
  }
14525
14927
  static worldToScenePosition(pos) {
14526
- return new import_three38.Vector3(
14928
+ return new import_three37.Vector3(
14527
14929
  pos.x * 16,
14528
14930
  pos.y * 16,
14529
14931
  pos.z * 16
14530
14932
  );
14531
14933
  }
14532
14934
  static sceneToWorldPosition(pos) {
14533
- return new import_three38.Vector3(
14935
+ return new import_three37.Vector3(
14534
14936
  pos.x / 16,
14535
14937
  pos.y / 16,
14536
14938
  pos.z / 16
@@ -14553,10 +14955,10 @@ var MineRenderWorld = class {
14553
14955
  init_Model();
14554
14956
 
14555
14957
  // src/world/SectionMesh.ts
14556
- var import_three39 = require("three");
14958
+ var import_three38 = require("three");
14557
14959
  init_CanvasCompat();
14558
14960
  init_Materials();
14559
- var SectionMesh = class _SectionMesh extends import_three39.Group {
14961
+ var SectionMesh = class _SectionMesh extends import_three38.Group {
14560
14962
  constructor() {
14561
14963
  super(...arguments);
14562
14964
  this.ownedMeshes = [];
@@ -14629,18 +15031,18 @@ var SectionMesh = class _SectionMesh extends import_three39.Group {
14629
15031
  for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
14630
15032
  }
14631
15033
  }
14632
- const geometry = new import_three39.BufferGeometry();
14633
- geometry.setAttribute("position", new import_three39.Float32BufferAttribute(positions, 3));
14634
- geometry.setAttribute("normal", new import_three39.Float32BufferAttribute(normals, 3));
14635
- geometry.setAttribute("uv", new import_three39.Float32BufferAttribute(uvs, 2));
14636
- geometry.setAttribute("color", new import_three39.Float32BufferAttribute(colors, 3));
15034
+ const geometry = new import_three38.BufferGeometry();
15035
+ geometry.setAttribute("position", new import_three38.Float32BufferAttribute(positions, 3));
15036
+ geometry.setAttribute("normal", new import_three38.Float32BufferAttribute(normals, 3));
15037
+ geometry.setAttribute("uv", new import_three38.Float32BufferAttribute(uvs, 2));
15038
+ geometry.setAttribute("color", new import_three38.Float32BufferAttribute(colors, 3));
14637
15039
  geometry.setIndex(indices);
14638
15040
  geometry.computeBoundingBox();
14639
15041
  geometry.computeBoundingSphere();
14640
15042
  const material = Materials.createShadedCanvasMaterial(canvas, false);
14641
15043
  material.vertexColors = true;
14642
15044
  const texture = material.uniforms?.map?.value ?? material.map;
14643
- const mesh = new import_three39.Mesh(geometry, material);
15045
+ const mesh = new import_three38.Mesh(geometry, material);
14644
15046
  section.add(mesh);
14645
15047
  section.ownedMeshes.push({ mesh, texture });
14646
15048
  }
@@ -14654,6 +15056,7 @@ var SectionMesh = class _SectionMesh extends import_three39.Group {
14654
15056
  texture?.dispose();
14655
15057
  }
14656
15058
  this.removeFromParent();
15059
+ super.dispose();
14657
15060
  }
14658
15061
  };
14659
15062
 
@@ -14675,10 +15078,10 @@ var Chunk = class _Chunk {
14675
15078
  }
14676
15079
  getBlockAt(posOrX, y, z) {
14677
15080
  if (typeof posOrX == "number") {
14678
- return this.getBlockAt(new import_three40.Vector3(posOrX, y, z));
15081
+ return this.getBlockAt(new import_three39.Vector3(posOrX, y, z));
14679
15082
  }
14680
15083
  if (isTripleArray(posOrX)) {
14681
- return this.getBlockAt(new import_three40.Vector3(posOrX[0], posOrX[1], posOrX[2]));
15084
+ return this.getBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14682
15085
  }
14683
15086
  const pos = this.worldPosToChunkPos(posOrX);
14684
15087
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -14686,10 +15089,10 @@ var Chunk = class _Chunk {
14686
15089
  }
14687
15090
  async setBlockAt(posOrX, yOrBlock, z, block) {
14688
15091
  if (typeof posOrX == "number") {
14689
- return this.setBlockAt(new import_three40.Vector3(posOrX, yOrBlock, z), block);
15092
+ return this.setBlockAt(new import_three39.Vector3(posOrX, yOrBlock, z), block);
14690
15093
  }
14691
15094
  if (isTripleArray(posOrX)) {
14692
- return this.setBlockAt(new import_three40.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
15095
+ return this.setBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14693
15096
  }
14694
15097
  const worldPos = posOrX;
14695
15098
  const pos = this.worldPosToChunkPos(worldPos);
@@ -14801,7 +15204,7 @@ var Chunk = class _Chunk {
14801
15204
  }
14802
15205
  async clear(onBlocksChanged = this.onBlocksChanged) {
14803
15206
  const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
14804
- new import_three40.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
15207
+ new import_three39.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
14805
15208
  ));
14806
15209
  for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
14807
15210
  this.sectionBlocks.clear();
@@ -14826,14 +15229,14 @@ var Chunk = class _Chunk {
14826
15229
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
14827
15230
  }
14828
15231
  worldPosToChunkPos(pos) {
14829
- return new import_three40.Vector3(
15232
+ return new import_three39.Vector3(
14830
15233
  pos.x - this.x * 16,
14831
15234
  pos.y - this.y * 16,
14832
15235
  pos.z - this.z * 16
14833
15236
  );
14834
15237
  }
14835
15238
  chunkPosToWorldPos(pos) {
14836
- return new import_three40.Vector3(
15239
+ return new import_three39.Vector3(
14837
15240
  this.x * 16 + pos.x,
14838
15241
  this.y * 16 + pos.y,
14839
15242
  this.z * 16 + pos.z