minerender 2.1.0-alpha.49 → 2.1.0-alpha.50

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.
@@ -3406,16 +3406,16 @@ var init_SceneObject = __esm({
3406
3406
  });
3407
3407
 
3408
3408
  // src/model/ModelCulling.ts
3409
- var import_three17, ModelCulling;
3409
+ var import_three22, ModelCulling;
3410
3410
  var init_ModelCulling = __esm({
3411
3411
  "src/model/ModelCulling.ts"() {
3412
- import_three17 = require("three");
3412
+ import_three22 = require("three");
3413
3413
  init_CubeFace();
3414
3414
  ModelCulling = class {
3415
3415
  static toLocalMask(worldMask, rotation) {
3416
3416
  let localMask = 0;
3417
3417
  for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
3418
- const normal = new import_three17.Vector3(...offset).applyEuler(rotation);
3418
+ const normal = new import_three22.Vector3(...offset).applyEuler(rotation);
3419
3419
  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);
3420
3420
  if (worldFace < 0) return 0;
3421
3421
  if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
@@ -3459,7 +3459,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
3459
3459
  const attributes = {};
3460
3460
  const morphAttributes = {};
3461
3461
  const morphTargetsRelative = geometries[0].morphTargetsRelative;
3462
- const mergedGeometry = new import_three19.BufferGeometry();
3462
+ const mergedGeometry = new import_three24.BufferGeometry();
3463
3463
  let offset = 0;
3464
3464
  for (let i = 0; i < geometries.length; ++i) {
3465
3465
  const geometry = geometries[i];
@@ -3583,7 +3583,7 @@ function mergeBufferAttributes(attributes) {
3583
3583
  array.set(attributes[i].array, offset);
3584
3584
  offset += attributes[i].array.length;
3585
3585
  }
3586
- return new import_three19.BufferAttribute(array, itemSize, normalized);
3586
+ return new import_three24.BufferAttribute(array, itemSize, normalized);
3587
3587
  }
3588
3588
  function interleaveAttributes(attributes) {
3589
3589
  let TypedArray;
@@ -3599,7 +3599,7 @@ function interleaveAttributes(attributes) {
3599
3599
  arrayLength += attribute.array.length;
3600
3600
  stride += attribute.itemSize;
3601
3601
  }
3602
- const interleavedBuffer = new import_three19.InterleavedBuffer(new TypedArray(arrayLength), stride);
3602
+ const interleavedBuffer = new import_three24.InterleavedBuffer(new TypedArray(arrayLength), stride);
3603
3603
  let offset = 0;
3604
3604
  const res = [];
3605
3605
  const getters = ["getX", "getY", "getZ", "getW"];
@@ -3608,7 +3608,7 @@ function interleaveAttributes(attributes) {
3608
3608
  const attribute = attributes[j];
3609
3609
  const itemSize = attribute.itemSize;
3610
3610
  const count = attribute.count;
3611
- const iba = new import_three19.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
3611
+ const iba = new import_three24.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
3612
3612
  res.push(iba);
3613
3613
  offset += itemSize;
3614
3614
  for (let c = 0; c < count; c++) {
@@ -3692,13 +3692,13 @@ function mergeVertices(geometry, tolerance = 1e-4) {
3692
3692
  const name = attributeNames[i];
3693
3693
  const oldAttribute = geometry.getAttribute(name);
3694
3694
  const buffer = new oldAttribute.array.constructor(attrArrays[name]);
3695
- const attribute = new import_three19.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
3695
+ const attribute = new import_three24.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
3696
3696
  result.setAttribute(name, attribute);
3697
3697
  if (name in morphAttrsArrays) {
3698
3698
  for (let j = 0; j < morphAttrsArrays[name].length; j++) {
3699
3699
  const oldMorphAttribute = geometry.morphAttributes[name][j];
3700
3700
  const buffer2 = new oldMorphAttribute.array.constructor(morphAttrsArrays[name][j]);
3701
- const morphAttribute = new import_three19.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
3701
+ const morphAttribute = new import_three24.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
3702
3702
  result.morphAttributes[name][j] = morphAttribute;
3703
3703
  }
3704
3704
  }
@@ -3707,11 +3707,11 @@ function mergeVertices(geometry, tolerance = 1e-4) {
3707
3707
  return result;
3708
3708
  }
3709
3709
  function toTrianglesDrawMode(geometry, drawMode) {
3710
- if (drawMode === import_three19.TrianglesDrawMode) {
3710
+ if (drawMode === import_three24.TrianglesDrawMode) {
3711
3711
  console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
3712
3712
  return geometry;
3713
3713
  }
3714
- if (drawMode === import_three19.TriangleFanDrawMode || drawMode === import_three19.TriangleStripDrawMode) {
3714
+ if (drawMode === import_three24.TriangleFanDrawMode || drawMode === import_three24.TriangleStripDrawMode) {
3715
3715
  let index = geometry.getIndex();
3716
3716
  if (index === null) {
3717
3717
  const indices = [];
@@ -3729,7 +3729,7 @@ function toTrianglesDrawMode(geometry, drawMode) {
3729
3729
  }
3730
3730
  const numberOfTriangles = index.count - 2;
3731
3731
  const newIndices = [];
3732
- if (drawMode === import_three19.TriangleFanDrawMode) {
3732
+ if (drawMode === import_three24.TriangleFanDrawMode) {
3733
3733
  for (let i = 1; i <= numberOfTriangles; i++) {
3734
3734
  newIndices.push(index.getX(0));
3735
3735
  newIndices.push(index.getX(i));
@@ -3765,15 +3765,15 @@ function computeMorphedAttributes(object) {
3765
3765
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
3766
3766
  return null;
3767
3767
  }
3768
- const _vA = new import_three19.Vector3();
3769
- const _vB = new import_three19.Vector3();
3770
- const _vC = new import_three19.Vector3();
3771
- const _tempA = new import_three19.Vector3();
3772
- const _tempB = new import_three19.Vector3();
3773
- const _tempC = new import_three19.Vector3();
3774
- const _morphA = new import_three19.Vector3();
3775
- const _morphB = new import_three19.Vector3();
3776
- const _morphC = new import_three19.Vector3();
3768
+ const _vA = new import_three24.Vector3();
3769
+ const _vB = new import_three24.Vector3();
3770
+ const _vC = new import_three24.Vector3();
3771
+ const _tempA = new import_three24.Vector3();
3772
+ const _tempB = new import_three24.Vector3();
3773
+ const _tempC = new import_three24.Vector3();
3774
+ const _morphA = new import_three24.Vector3();
3775
+ const _morphB = new import_three24.Vector3();
3776
+ const _morphC = new import_three24.Vector3();
3777
3777
  function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
3778
3778
  _vA.fromBufferAttribute(attribute, a2);
3779
3779
  _vB.fromBufferAttribute(attribute, b2);
@@ -3968,8 +3968,8 @@ function computeMorphedAttributes(object) {
3968
3968
  }
3969
3969
  }
3970
3970
  }
3971
- const morphedPositionAttribute = new import_three19.Float32BufferAttribute(modifiedPosition, 3);
3972
- const morphedNormalAttribute = new import_three19.Float32BufferAttribute(modifiedNormal, 3);
3971
+ const morphedPositionAttribute = new import_three24.Float32BufferAttribute(modifiedPosition, 3);
3972
+ const morphedNormalAttribute = new import_three24.Float32BufferAttribute(modifiedNormal, 3);
3973
3973
  return {
3974
3974
  positionAttribute,
3975
3975
  normalAttribute,
@@ -3977,10 +3977,10 @@ function computeMorphedAttributes(object) {
3977
3977
  morphedNormalAttribute
3978
3978
  };
3979
3979
  }
3980
- var import_three19;
3980
+ var import_three24;
3981
3981
  var init_BufferGeometryUtils = __esm({
3982
3982
  "src/three/BufferGeometryUtils.js"() {
3983
- import_three19 = require("three");
3983
+ import_three24 = require("three");
3984
3984
  }
3985
3985
  });
3986
3986
 
@@ -3988,13 +3988,13 @@ var init_BufferGeometryUtils = __esm({
3988
3988
  function isModelObject(obj) {
3989
3989
  return obj.isModelObject;
3990
3990
  }
3991
- var import_three20, import_ts_deepmerge5, p9, _ModelObject, ModelObject;
3991
+ var import_three25, import_ts_deepmerge5, p9, _ModelObject, ModelObject;
3992
3992
  var init_ModelObject = __esm({
3993
3993
  "src/model/scene/ModelObject.ts"() {
3994
3994
  init_SceneObject();
3995
3995
  init_Materials();
3996
3996
  init_UVMapper();
3997
- import_three20 = require("three");
3997
+ import_three25 = require("three");
3998
3998
  init_BufferGeometryUtils();
3999
3999
  init_model();
4000
4000
  import_ts_deepmerge5 = __toESM(require_dist());
@@ -4049,7 +4049,7 @@ var init_ModelObject = __esm({
4049
4049
  elGeo.clearGroups();
4050
4050
  }
4051
4051
  if (this.options.uvLockRotation) {
4052
- UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three20.Euler(...this.options.uvLockRotation));
4052
+ UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three25.Euler(...this.options.uvLockRotation));
4053
4053
  }
4054
4054
  if (this.options.tints) {
4055
4055
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
@@ -4058,19 +4058,19 @@ var init_ModelObject = __esm({
4058
4058
  if (tintIndex === void 0 || tintIndex < 0) continue;
4059
4059
  const tint = this.options.tints[tintIndex];
4060
4060
  if (tint === void 0) continue;
4061
- const color = new import_three20.Color(tint);
4061
+ const color = new import_three25.Color(tint);
4062
4062
  for (let vertex = 0; vertex < 4; vertex++) {
4063
4063
  color.toArray(colors, (faceIndex * 4 + vertex) * 3);
4064
4064
  }
4065
4065
  }
4066
- elGeo.setAttribute("color", new import_three20.BufferAttribute(colors, 3));
4066
+ elGeo.setAttribute("color", new import_three25.BufferAttribute(colors, 3));
4067
4067
  }
4068
- elGeo.applyMatrix4(new import_three20.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
4069
- elGeo.applyMatrix4(new import_three20.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
4068
+ elGeo.applyMatrix4(new import_three25.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
4069
+ elGeo.applyMatrix4(new import_three25.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
4070
4070
  if (el.rotation) {
4071
4071
  applyElementRotation(el.rotation, elGeo);
4072
4072
  }
4073
- elGeo.applyMatrix4(new import_three20.Matrix4().makeTranslation(-8, -8, -8));
4073
+ elGeo.applyMatrix4(new import_three25.Matrix4().makeTranslation(-8, -8, -8));
4074
4074
  if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
4075
4075
  if (this.options.mergeMeshes) {
4076
4076
  allGeos.push(elGeo);
@@ -4092,7 +4092,7 @@ var init_ModelObject = __esm({
4092
4092
  if (allGeos.length > 0) {
4093
4093
  combinedGeo = mergeBufferGeometries(allGeos);
4094
4094
  } else {
4095
- combinedGeo = new import_three20.BoxGeometry(16, 16, 16);
4095
+ combinedGeo = new import_three25.BoxGeometry(16, 16, 16);
4096
4096
  if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
4097
4097
  }
4098
4098
  combinedGeo.computeBoundingBox();
@@ -4202,7 +4202,7 @@ function ownHeight(sample) {
4202
4202
  return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
4203
4203
  }
4204
4204
  function createFluidGeometry(kind, sample) {
4205
- const geometry = new import_three21.BufferGeometry();
4205
+ const geometry = new import_three26.BufferGeometry();
4206
4206
  const positions = [], normals = [], uvs = [], indices = [];
4207
4207
  const self = sample(0, 0, 0);
4208
4208
  const height = (x, z) => {
@@ -4301,16 +4301,16 @@ function createFluidGeometry(kind, sample) {
4301
4301
  1
4302
4302
  );
4303
4303
  }
4304
- geometry.setAttribute("position", new import_three21.Float32BufferAttribute(positions, 3));
4305
- geometry.setAttribute("normal", new import_three21.Float32BufferAttribute(normals, 3));
4306
- geometry.setAttribute("uv", new import_three21.Float32BufferAttribute(uvs, 2));
4304
+ geometry.setAttribute("position", new import_three26.Float32BufferAttribute(positions, 3));
4305
+ geometry.setAttribute("normal", new import_three26.Float32BufferAttribute(normals, 3));
4306
+ geometry.setAttribute("uv", new import_three26.Float32BufferAttribute(uvs, 2));
4307
4307
  geometry.setIndex(indices);
4308
4308
  return geometry;
4309
4309
  }
4310
- var import_three21, fluidRules, HORIZONTAL, EPSILON;
4310
+ var import_three26, fluidRules, HORIZONTAL, EPSILON;
4311
4311
  var init_FluidGeometry = __esm({
4312
4312
  "src/model/fluid/FluidGeometry.ts"() {
4313
- import_three21 = require("three");
4313
+ import_three26 = require("three");
4314
4314
  init_fluidBlocks();
4315
4315
  fluidRules = fluidBlocks_default;
4316
4316
  HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]];
@@ -4339,10 +4339,10 @@ function sampleFluid(kind, sample) {
4339
4339
  }
4340
4340
  return { key: key.join(""), sample: (x, y, z) => cells[(y + 1) * 9 + (z + 1) * 3 + x + 1] };
4341
4341
  }
4342
- var import_three22, FluidModelObject;
4342
+ var import_three27, FluidModelObject;
4343
4343
  var init_FluidModelObject = __esm({
4344
4344
  "src/model/fluid/FluidModelObject.ts"() {
4345
- import_three22 = require("three");
4345
+ import_three27 = require("three");
4346
4346
  init_AssetKey();
4347
4347
  init_Materials();
4348
4348
  init_ModelObject();
@@ -4375,10 +4375,10 @@ var init_FluidModelObject = __esm({
4375
4375
  }
4376
4376
  }
4377
4377
  geometry.clearGroups();
4378
- const color = new import_three22.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
4378
+ const color = new import_three27.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
4379
4379
  const colors = new Float32Array(geometry.getAttribute("position").count * 3);
4380
4380
  for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
4381
- geometry.setAttribute("color", new import_three22.BufferAttribute(colors, 3));
4381
+ geometry.setAttribute("color", new import_three27.BufferAttribute(colors, 3));
4382
4382
  geometry.computeBoundingBox();
4383
4383
  geometry.computeBoundingSphere();
4384
4384
  if (this.options.instanceMeshes) {
@@ -4392,7 +4392,7 @@ var init_FluidModelObject = __esm({
4392
4392
  super.applyTextures();
4393
4393
  this.iterateAllMeshes((mesh) => {
4394
4394
  const material = mesh.material;
4395
- material.side = import_three22.DoubleSide;
4395
+ material.side = import_three27.DoubleSide;
4396
4396
  material.forceSinglePass = true;
4397
4397
  material.depthWrite = !material.transparent;
4398
4398
  });
@@ -4480,6 +4480,7 @@ __export(index_browser_exports, {
4480
4480
  RequestError: () => RequestError,
4481
4481
  Requests: () => Requests,
4482
4482
  SKIN_PARTS: () => SKIN_PARTS,
4483
+ SceneExporter: () => SceneExporter,
4483
4484
  SceneInspector: () => SceneInspector,
4484
4485
  SceneObject: () => SceneObject,
4485
4486
  SceneStats: () => SceneStats,
@@ -4569,7 +4570,8 @@ __export(index_browser_exports, {
4569
4570
  timingStart: () => timingStart,
4570
4571
  toDegrees: () => toDegrees,
4571
4572
  toRadians: () => toRadians,
4572
- toTrianglesDrawMode: () => toTrianglesDrawMode
4573
+ toTrianglesDrawMode: () => toTrianglesDrawMode,
4574
+ trimCanvas: () => trimCanvas
4573
4575
  });
4574
4576
  module.exports = __toCommonJS(index_browser_exports);
4575
4577
 
@@ -4949,6 +4951,37 @@ init_PersistentCache();
4949
4951
  init_CanvasCompat();
4950
4952
  init_CanvasImage();
4951
4953
 
4954
+ // src/canvas/trimCanvas.ts
4955
+ init_CanvasCompat();
4956
+ function trimCanvas(source) {
4957
+ if (source.width === 0 || source.height === 0) return createCanvas(1, 1);
4958
+ const canvas = createCanvas(source.width, source.height);
4959
+ const context = canvas.getContext("2d");
4960
+ if (!context) throw new Error("Image export requires a 2D canvas context");
4961
+ context.drawImage(source, 0, 0);
4962
+ const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;
4963
+ let left = canvas.width, top = canvas.height, right = -1, bottom = -1;
4964
+ for (let y = 0; y < canvas.height; y++) {
4965
+ for (let x = 0; x < canvas.width; x++) {
4966
+ if (pixels[(y * canvas.width + x) * 4 + 3] === 0) continue;
4967
+ left = Math.min(left, x);
4968
+ top = Math.min(top, y);
4969
+ right = Math.max(right, x);
4970
+ bottom = Math.max(bottom, y);
4971
+ }
4972
+ }
4973
+ if (right < left) {
4974
+ canvas.width = canvas.height = 1;
4975
+ return canvas;
4976
+ }
4977
+ const width = right - left + 1, height = bottom - top + 1;
4978
+ const cropped = context.getImageData(left, top, width, height);
4979
+ canvas.width = width;
4980
+ canvas.height = height;
4981
+ context.putImageData(cropped, 0, 0);
4982
+ return canvas;
4983
+ }
4984
+
4952
4985
  // src/entity/scene/EntityObject.ts
4953
4986
  init_SceneObject();
4954
4987
  init_Caching();
@@ -5070,6 +5103,2510 @@ function isEntityObject(obj) {
5070
5103
  // src/error/index.ts
5071
5104
  init_MineRenderError();
5072
5105
 
5106
+ // src/export/SceneExporter.ts
5107
+ var import_three18 = require("three");
5108
+
5109
+ // ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
5110
+ var import_three14 = require("three");
5111
+ var OBJExporter = class {
5112
+ parse(object) {
5113
+ let output = "";
5114
+ let indexVertex = 0;
5115
+ let indexVertexUvs = 0;
5116
+ let indexNormals = 0;
5117
+ const vertex = new import_three14.Vector3();
5118
+ const color = new import_three14.Color();
5119
+ const normal = new import_three14.Vector3();
5120
+ const uv = new import_three14.Vector2();
5121
+ const face = [];
5122
+ function parseMesh(mesh) {
5123
+ let nbVertex = 0;
5124
+ let nbNormals = 0;
5125
+ let nbVertexUvs = 0;
5126
+ const geometry = mesh.geometry;
5127
+ const normalMatrixWorld = new import_three14.Matrix3();
5128
+ const vertices = geometry.getAttribute("position");
5129
+ const normals = geometry.getAttribute("normal");
5130
+ const uvs = geometry.getAttribute("uv");
5131
+ const indices = geometry.getIndex();
5132
+ output += "o " + mesh.name + "\n";
5133
+ if (mesh.material && mesh.material.name) {
5134
+ output += "usemtl " + mesh.material.name + "\n";
5135
+ }
5136
+ if (vertices !== void 0) {
5137
+ for (let i = 0, l = vertices.count; i < l; i++, nbVertex++) {
5138
+ vertex.fromBufferAttribute(vertices, i);
5139
+ vertex.applyMatrix4(mesh.matrixWorld);
5140
+ output += "v " + vertex.x + " " + vertex.y + " " + vertex.z + "\n";
5141
+ }
5142
+ }
5143
+ if (uvs !== void 0) {
5144
+ for (let i = 0, l = uvs.count; i < l; i++, nbVertexUvs++) {
5145
+ uv.fromBufferAttribute(uvs, i);
5146
+ output += "vt " + uv.x + " " + uv.y + "\n";
5147
+ }
5148
+ }
5149
+ if (normals !== void 0) {
5150
+ normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
5151
+ for (let i = 0, l = normals.count; i < l; i++, nbNormals++) {
5152
+ normal.fromBufferAttribute(normals, i);
5153
+ normal.applyMatrix3(normalMatrixWorld).normalize();
5154
+ output += "vn " + normal.x + " " + normal.y + " " + normal.z + "\n";
5155
+ }
5156
+ }
5157
+ if (indices !== null) {
5158
+ for (let i = 0, l = indices.count; i < l; i += 3) {
5159
+ for (let m = 0; m < 3; m++) {
5160
+ const j = indices.getX(i + m) + 1;
5161
+ face[m] = indexVertex + j + (normals || uvs ? "/" + (uvs ? indexVertexUvs + j : "") + (normals ? "/" + (indexNormals + j) : "") : "");
5162
+ }
5163
+ output += "f " + face.join(" ") + "\n";
5164
+ }
5165
+ } else {
5166
+ for (let i = 0, l = vertices.count; i < l; i += 3) {
5167
+ for (let m = 0; m < 3; m++) {
5168
+ const j = i + m + 1;
5169
+ face[m] = indexVertex + j + (normals || uvs ? "/" + (uvs ? indexVertexUvs + j : "") + (normals ? "/" + (indexNormals + j) : "") : "");
5170
+ }
5171
+ output += "f " + face.join(" ") + "\n";
5172
+ }
5173
+ }
5174
+ indexVertex += nbVertex;
5175
+ indexVertexUvs += nbVertexUvs;
5176
+ indexNormals += nbNormals;
5177
+ }
5178
+ function parseLine(line) {
5179
+ let nbVertex = 0;
5180
+ const geometry = line.geometry;
5181
+ const type = line.type;
5182
+ const vertices = geometry.getAttribute("position");
5183
+ output += "o " + line.name + "\n";
5184
+ if (vertices !== void 0) {
5185
+ for (let i = 0, l = vertices.count; i < l; i++, nbVertex++) {
5186
+ vertex.fromBufferAttribute(vertices, i);
5187
+ vertex.applyMatrix4(line.matrixWorld);
5188
+ output += "v " + vertex.x + " " + vertex.y + " " + vertex.z + "\n";
5189
+ }
5190
+ }
5191
+ if (type === "Line") {
5192
+ output += "l ";
5193
+ for (let j = 1, l = vertices.count; j <= l; j++) {
5194
+ output += indexVertex + j + " ";
5195
+ }
5196
+ output += "\n";
5197
+ }
5198
+ if (type === "LineSegments") {
5199
+ for (let j = 1, k = j + 1, l = vertices.count; j < l; j += 2, k = j + 1) {
5200
+ output += "l " + (indexVertex + j) + " " + (indexVertex + k) + "\n";
5201
+ }
5202
+ }
5203
+ indexVertex += nbVertex;
5204
+ }
5205
+ function parsePoints(points) {
5206
+ let nbVertex = 0;
5207
+ const geometry = points.geometry;
5208
+ const vertices = geometry.getAttribute("position");
5209
+ const colors = geometry.getAttribute("color");
5210
+ output += "o " + points.name + "\n";
5211
+ if (vertices !== void 0) {
5212
+ for (let i = 0, l = vertices.count; i < l; i++, nbVertex++) {
5213
+ vertex.fromBufferAttribute(vertices, i);
5214
+ vertex.applyMatrix4(points.matrixWorld);
5215
+ output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
5216
+ if (colors !== void 0) {
5217
+ color.fromBufferAttribute(colors, i).convertLinearToSRGB();
5218
+ output += " " + color.r + " " + color.g + " " + color.b;
5219
+ }
5220
+ output += "\n";
5221
+ }
5222
+ output += "p ";
5223
+ for (let j = 1, l = vertices.count; j <= l; j++) {
5224
+ output += indexVertex + j + " ";
5225
+ }
5226
+ output += "\n";
5227
+ }
5228
+ indexVertex += nbVertex;
5229
+ }
5230
+ object.traverse(function(child) {
5231
+ if (child.isMesh === true) {
5232
+ parseMesh(child);
5233
+ }
5234
+ if (child.isLine === true) {
5235
+ parseLine(child);
5236
+ }
5237
+ if (child.isPoints === true) {
5238
+ parsePoints(child);
5239
+ }
5240
+ });
5241
+ return output;
5242
+ }
5243
+ };
5244
+
5245
+ // ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
5246
+ var import_three15 = require("three");
5247
+ var PLYExporter = class {
5248
+ parse(object, onDone, options = {}) {
5249
+ function traverseMeshes(cb) {
5250
+ object.traverse(function(child) {
5251
+ if (child.isMesh === true || child.isPoints) {
5252
+ const mesh = child;
5253
+ const geometry = mesh.geometry;
5254
+ if (geometry.hasAttribute("position") === true) {
5255
+ cb(mesh, geometry);
5256
+ }
5257
+ }
5258
+ });
5259
+ }
5260
+ const defaultOptions = {
5261
+ binary: false,
5262
+ excludeAttributes: [],
5263
+ // normal, uv, color, index
5264
+ littleEndian: false
5265
+ };
5266
+ options = Object.assign(defaultOptions, options);
5267
+ const excludeAttributes = options.excludeAttributes;
5268
+ let includeIndices = true;
5269
+ let includeNormals = false;
5270
+ let includeColors = false;
5271
+ let includeUVs = false;
5272
+ let vertexCount = 0;
5273
+ let faceCount = 0;
5274
+ object.traverse(function(child) {
5275
+ if (child.isMesh === true) {
5276
+ const mesh = child;
5277
+ const geometry = mesh.geometry;
5278
+ const vertices = geometry.getAttribute("position");
5279
+ const normals = geometry.getAttribute("normal");
5280
+ const uvs = geometry.getAttribute("uv");
5281
+ const colors = geometry.getAttribute("color");
5282
+ const indices = geometry.getIndex();
5283
+ if (vertices === void 0) {
5284
+ return;
5285
+ }
5286
+ vertexCount += vertices.count;
5287
+ faceCount += indices ? indices.count / 3 : vertices.count / 3;
5288
+ if (normals !== void 0) includeNormals = true;
5289
+ if (uvs !== void 0) includeUVs = true;
5290
+ if (colors !== void 0) includeColors = true;
5291
+ } else if (child.isPoints) {
5292
+ const mesh = child;
5293
+ const geometry = mesh.geometry;
5294
+ const vertices = geometry.getAttribute("position");
5295
+ const normals = geometry.getAttribute("normal");
5296
+ const colors = geometry.getAttribute("color");
5297
+ vertexCount += vertices.count;
5298
+ if (normals !== void 0) includeNormals = true;
5299
+ if (colors !== void 0) includeColors = true;
5300
+ includeIndices = false;
5301
+ }
5302
+ });
5303
+ const tempColor = new import_three15.Color();
5304
+ includeIndices = includeIndices && excludeAttributes.indexOf("index") === -1;
5305
+ includeNormals = includeNormals && excludeAttributes.indexOf("normal") === -1;
5306
+ includeColors = includeColors && excludeAttributes.indexOf("color") === -1;
5307
+ includeUVs = includeUVs && excludeAttributes.indexOf("uv") === -1;
5308
+ if (includeIndices && faceCount !== Math.floor(faceCount)) {
5309
+ console.error(
5310
+ "PLYExporter: Failed to generate a valid PLY file with triangle indices because the number of indices is not divisible by 3."
5311
+ );
5312
+ return null;
5313
+ }
5314
+ const indexByteCount = 4;
5315
+ let header = `ply
5316
+ format ${options.binary ? options.littleEndian ? "binary_little_endian" : "binary_big_endian" : "ascii"} 1.0
5317
+ element vertex ${vertexCount}
5318
+ property float x
5319
+ property float y
5320
+ property float z
5321
+ `;
5322
+ if (includeNormals === true) {
5323
+ header += "property float nx\nproperty float ny\nproperty float nz\n";
5324
+ }
5325
+ if (includeUVs === true) {
5326
+ header += "property float s\nproperty float t\n";
5327
+ }
5328
+ if (includeColors === true) {
5329
+ header += "property uchar red\nproperty uchar green\nproperty uchar blue\n";
5330
+ }
5331
+ if (includeIndices === true) {
5332
+ header += `element face ${faceCount}
5333
+ property list uchar int vertex_index
5334
+ `;
5335
+ }
5336
+ header += "end_header\n";
5337
+ const vertex = new import_three15.Vector3();
5338
+ const normalMatrixWorld = new import_three15.Matrix3();
5339
+ let result = null;
5340
+ if (options.binary === true) {
5341
+ const headerBin = new TextEncoder().encode(header);
5342
+ const vertexListLength = vertexCount * (4 * 3 + (includeNormals ? 4 * 3 : 0) + (includeColors ? 3 : 0) + (includeUVs ? 4 * 2 : 0));
5343
+ const faceListLength = includeIndices ? faceCount * (indexByteCount * 3 + 1) : 0;
5344
+ const output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
5345
+ new Uint8Array(output.buffer).set(headerBin, 0);
5346
+ let vOffset = headerBin.length;
5347
+ let fOffset = headerBin.length + vertexListLength;
5348
+ let writtenVertices = 0;
5349
+ traverseMeshes(function(mesh, geometry) {
5350
+ const vertices = geometry.getAttribute("position");
5351
+ const normals = geometry.getAttribute("normal");
5352
+ const uvs = geometry.getAttribute("uv");
5353
+ const colors = geometry.getAttribute("color");
5354
+ const indices = geometry.getIndex();
5355
+ normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
5356
+ for (let i = 0, l = vertices.count; i < l; i++) {
5357
+ vertex.fromBufferAttribute(vertices, i);
5358
+ vertex.applyMatrix4(mesh.matrixWorld);
5359
+ output.setFloat32(vOffset, vertex.x, options.littleEndian);
5360
+ vOffset += 4;
5361
+ output.setFloat32(vOffset, vertex.y, options.littleEndian);
5362
+ vOffset += 4;
5363
+ output.setFloat32(vOffset, vertex.z, options.littleEndian);
5364
+ vOffset += 4;
5365
+ if (includeNormals === true) {
5366
+ if (normals != null) {
5367
+ vertex.fromBufferAttribute(normals, i);
5368
+ vertex.applyMatrix3(normalMatrixWorld).normalize();
5369
+ output.setFloat32(vOffset, vertex.x, options.littleEndian);
5370
+ vOffset += 4;
5371
+ output.setFloat32(vOffset, vertex.y, options.littleEndian);
5372
+ vOffset += 4;
5373
+ output.setFloat32(vOffset, vertex.z, options.littleEndian);
5374
+ vOffset += 4;
5375
+ } else {
5376
+ output.setFloat32(vOffset, 0, options.littleEndian);
5377
+ vOffset += 4;
5378
+ output.setFloat32(vOffset, 0, options.littleEndian);
5379
+ vOffset += 4;
5380
+ output.setFloat32(vOffset, 0, options.littleEndian);
5381
+ vOffset += 4;
5382
+ }
5383
+ }
5384
+ if (includeUVs === true) {
5385
+ if (uvs != null) {
5386
+ output.setFloat32(vOffset, uvs.getX(i), options.littleEndian);
5387
+ vOffset += 4;
5388
+ output.setFloat32(vOffset, uvs.getY(i), options.littleEndian);
5389
+ vOffset += 4;
5390
+ } else {
5391
+ output.setFloat32(vOffset, 0, options.littleEndian);
5392
+ vOffset += 4;
5393
+ output.setFloat32(vOffset, 0, options.littleEndian);
5394
+ vOffset += 4;
5395
+ }
5396
+ }
5397
+ if (includeColors === true) {
5398
+ if (colors != null) {
5399
+ tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
5400
+ output.setUint8(vOffset, Math.floor(tempColor.r * 255));
5401
+ vOffset += 1;
5402
+ output.setUint8(vOffset, Math.floor(tempColor.g * 255));
5403
+ vOffset += 1;
5404
+ output.setUint8(vOffset, Math.floor(tempColor.b * 255));
5405
+ vOffset += 1;
5406
+ } else {
5407
+ output.setUint8(vOffset, 255);
5408
+ vOffset += 1;
5409
+ output.setUint8(vOffset, 255);
5410
+ vOffset += 1;
5411
+ output.setUint8(vOffset, 255);
5412
+ vOffset += 1;
5413
+ }
5414
+ }
5415
+ }
5416
+ if (includeIndices === true) {
5417
+ if (indices !== null) {
5418
+ for (let i = 0, l = indices.count; i < l; i += 3) {
5419
+ output.setUint8(fOffset, 3);
5420
+ fOffset += 1;
5421
+ output.setUint32(fOffset, indices.getX(i + 0) + writtenVertices, options.littleEndian);
5422
+ fOffset += indexByteCount;
5423
+ output.setUint32(fOffset, indices.getX(i + 1) + writtenVertices, options.littleEndian);
5424
+ fOffset += indexByteCount;
5425
+ output.setUint32(fOffset, indices.getX(i + 2) + writtenVertices, options.littleEndian);
5426
+ fOffset += indexByteCount;
5427
+ }
5428
+ } else {
5429
+ for (let i = 0, l = vertices.count; i < l; i += 3) {
5430
+ output.setUint8(fOffset, 3);
5431
+ fOffset += 1;
5432
+ output.setUint32(fOffset, writtenVertices + i, options.littleEndian);
5433
+ fOffset += indexByteCount;
5434
+ output.setUint32(fOffset, writtenVertices + i + 1, options.littleEndian);
5435
+ fOffset += indexByteCount;
5436
+ output.setUint32(fOffset, writtenVertices + i + 2, options.littleEndian);
5437
+ fOffset += indexByteCount;
5438
+ }
5439
+ }
5440
+ }
5441
+ writtenVertices += vertices.count;
5442
+ });
5443
+ result = output.buffer;
5444
+ } else {
5445
+ let writtenVertices = 0;
5446
+ let vertexList = "";
5447
+ let faceList = "";
5448
+ traverseMeshes(function(mesh, geometry) {
5449
+ const vertices = geometry.getAttribute("position");
5450
+ const normals = geometry.getAttribute("normal");
5451
+ const uvs = geometry.getAttribute("uv");
5452
+ const colors = geometry.getAttribute("color");
5453
+ const indices = geometry.getIndex();
5454
+ normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
5455
+ for (let i = 0, l = vertices.count; i < l; i++) {
5456
+ vertex.fromBufferAttribute(vertices, i);
5457
+ vertex.applyMatrix4(mesh.matrixWorld);
5458
+ let line = vertex.x + " " + vertex.y + " " + vertex.z;
5459
+ if (includeNormals === true) {
5460
+ if (normals != null) {
5461
+ vertex.fromBufferAttribute(normals, i);
5462
+ vertex.applyMatrix3(normalMatrixWorld).normalize();
5463
+ line += " " + vertex.x + " " + vertex.y + " " + vertex.z;
5464
+ } else {
5465
+ line += " 0 0 0";
5466
+ }
5467
+ }
5468
+ if (includeUVs === true) {
5469
+ if (uvs != null) {
5470
+ line += " " + uvs.getX(i) + " " + uvs.getY(i);
5471
+ } else {
5472
+ line += " 0 0";
5473
+ }
5474
+ }
5475
+ if (includeColors === true) {
5476
+ if (colors != null) {
5477
+ tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
5478
+ line += " " + Math.floor(tempColor.r * 255) + " " + Math.floor(tempColor.g * 255) + " " + Math.floor(tempColor.b * 255);
5479
+ } else {
5480
+ line += " 255 255 255";
5481
+ }
5482
+ }
5483
+ vertexList += line + "\n";
5484
+ }
5485
+ if (includeIndices === true) {
5486
+ if (indices !== null) {
5487
+ for (let i = 0, l = indices.count; i < l; i += 3) {
5488
+ faceList += `3 ${indices.getX(i + 0) + writtenVertices}`;
5489
+ faceList += ` ${indices.getX(i + 1) + writtenVertices}`;
5490
+ faceList += ` ${indices.getX(i + 2) + writtenVertices}
5491
+ `;
5492
+ }
5493
+ } else {
5494
+ for (let i = 0, l = vertices.count; i < l; i += 3) {
5495
+ faceList += `3 ${writtenVertices + i} ${writtenVertices + i + 1} ${writtenVertices + i + 2}
5496
+ `;
5497
+ }
5498
+ }
5499
+ faceCount += indices ? indices.count / 3 : vertices.count / 3;
5500
+ }
5501
+ writtenVertices += vertices.count;
5502
+ });
5503
+ result = `${header}${vertexList}${includeIndices ? `${faceList}
5504
+ ` : "\n"}`;
5505
+ }
5506
+ if (typeof onDone === "function") requestAnimationFrame(() => onDone(result));
5507
+ return result;
5508
+ }
5509
+ };
5510
+
5511
+ // ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
5512
+ var import_three17 = require("three");
5513
+
5514
+ // ../../node_modules/three/examples/jsm/utils/TextureUtils.js
5515
+ var import_three16 = require("three");
5516
+ var _renderer;
5517
+ var fullscreenQuadGeometry;
5518
+ var fullscreenQuadMaterial;
5519
+ var fullscreenQuad;
5520
+ function decompress(texture, maxTextureSize = Infinity, renderer = null) {
5521
+ if (!fullscreenQuadGeometry) fullscreenQuadGeometry = new import_three16.PlaneGeometry(2, 2, 1, 1);
5522
+ if (!fullscreenQuadMaterial) fullscreenQuadMaterial = new import_three16.ShaderMaterial({
5523
+ uniforms: { blitTexture: new import_three16.Uniform(texture) },
5524
+ vertexShader: `
5525
+ varying vec2 vUv;
5526
+ void main(){
5527
+ vUv = uv;
5528
+ gl_Position = vec4(position.xy * 1.0,0.,.999999);
5529
+ }`,
5530
+ fragmentShader: `
5531
+ uniform sampler2D blitTexture;
5532
+ varying vec2 vUv;
5533
+
5534
+ void main(){
5535
+ gl_FragColor = vec4(vUv.xy, 0, 1);
5536
+
5537
+ #ifdef IS_SRGB
5538
+ gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
5539
+ #else
5540
+ gl_FragColor = texture2D( blitTexture, vUv);
5541
+ #endif
5542
+ }`
5543
+ });
5544
+ fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
5545
+ fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == import_three16.SRGBColorSpace;
5546
+ fullscreenQuadMaterial.needsUpdate = true;
5547
+ if (!fullscreenQuad) {
5548
+ fullscreenQuad = new import_three16.Mesh(fullscreenQuadGeometry, fullscreenQuadMaterial);
5549
+ fullscreenQuad.frustrumCulled = false;
5550
+ }
5551
+ const _camera = new import_three16.PerspectiveCamera();
5552
+ const _scene = new import_three16.Scene();
5553
+ _scene.add(fullscreenQuad);
5554
+ if (!renderer) {
5555
+ renderer = _renderer = new import_three16.WebGLRenderer({ antialias: false });
5556
+ }
5557
+ renderer.setSize(Math.min(texture.image.width, maxTextureSize), Math.min(texture.image.height, maxTextureSize));
5558
+ renderer.clear();
5559
+ renderer.render(_scene, _camera);
5560
+ const readableTexture = new import_three16.Texture(renderer.domElement);
5561
+ readableTexture.minFilter = texture.minFilter;
5562
+ readableTexture.magFilter = texture.magFilter;
5563
+ readableTexture.wrapS = texture.wrapS;
5564
+ readableTexture.wrapT = texture.wrapT;
5565
+ readableTexture.name = texture.name;
5566
+ if (_renderer) {
5567
+ _renderer.dispose();
5568
+ _renderer = null;
5569
+ }
5570
+ return readableTexture;
5571
+ }
5572
+
5573
+ // ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
5574
+ var KHR_mesh_quantization_ExtraAttrTypes = {
5575
+ POSITION: [
5576
+ "byte",
5577
+ "byte normalized",
5578
+ "unsigned byte",
5579
+ "unsigned byte normalized",
5580
+ "short",
5581
+ "short normalized",
5582
+ "unsigned short",
5583
+ "unsigned short normalized"
5584
+ ],
5585
+ NORMAL: [
5586
+ "byte normalized",
5587
+ "short normalized"
5588
+ ],
5589
+ TANGENT: [
5590
+ "byte normalized",
5591
+ "short normalized"
5592
+ ],
5593
+ TEXCOORD: [
5594
+ "byte",
5595
+ "byte normalized",
5596
+ "unsigned byte",
5597
+ "short",
5598
+ "short normalized",
5599
+ "unsigned short"
5600
+ ]
5601
+ };
5602
+ var GLTFExporter = class {
5603
+ constructor() {
5604
+ this.pluginCallbacks = [];
5605
+ this.register(function(writer) {
5606
+ return new GLTFLightExtension(writer);
5607
+ });
5608
+ this.register(function(writer) {
5609
+ return new GLTFMaterialsUnlitExtension(writer);
5610
+ });
5611
+ this.register(function(writer) {
5612
+ return new GLTFMaterialsTransmissionExtension(writer);
5613
+ });
5614
+ this.register(function(writer) {
5615
+ return new GLTFMaterialsVolumeExtension(writer);
5616
+ });
5617
+ this.register(function(writer) {
5618
+ return new GLTFMaterialsIorExtension(writer);
5619
+ });
5620
+ this.register(function(writer) {
5621
+ return new GLTFMaterialsSpecularExtension(writer);
5622
+ });
5623
+ this.register(function(writer) {
5624
+ return new GLTFMaterialsClearcoatExtension(writer);
5625
+ });
5626
+ this.register(function(writer) {
5627
+ return new GLTFMaterialsIridescenceExtension(writer);
5628
+ });
5629
+ this.register(function(writer) {
5630
+ return new GLTFMaterialsSheenExtension(writer);
5631
+ });
5632
+ this.register(function(writer) {
5633
+ return new GLTFMaterialsAnisotropyExtension(writer);
5634
+ });
5635
+ this.register(function(writer) {
5636
+ return new GLTFMaterialsEmissiveStrengthExtension(writer);
5637
+ });
5638
+ this.register(function(writer) {
5639
+ return new GLTFMeshGpuInstancing(writer);
5640
+ });
5641
+ }
5642
+ register(callback) {
5643
+ if (this.pluginCallbacks.indexOf(callback) === -1) {
5644
+ this.pluginCallbacks.push(callback);
5645
+ }
5646
+ return this;
5647
+ }
5648
+ unregister(callback) {
5649
+ if (this.pluginCallbacks.indexOf(callback) !== -1) {
5650
+ this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
5651
+ }
5652
+ return this;
5653
+ }
5654
+ /**
5655
+ * Parse scenes and generate GLTF output
5656
+ * @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
5657
+ * @param {Function} onDone Callback on completed
5658
+ * @param {Function} onError Callback on errors
5659
+ * @param {Object} options options
5660
+ */
5661
+ parse(input, onDone, onError, options) {
5662
+ const writer = new GLTFWriter();
5663
+ const plugins = [];
5664
+ for (let i = 0, il = this.pluginCallbacks.length; i < il; i++) {
5665
+ plugins.push(this.pluginCallbacks[i](writer));
5666
+ }
5667
+ writer.setPlugins(plugins);
5668
+ writer.write(input, onDone, options).catch(onError);
5669
+ }
5670
+ parseAsync(input, options) {
5671
+ const scope = this;
5672
+ return new Promise(function(resolve, reject) {
5673
+ scope.parse(input, resolve, reject, options);
5674
+ });
5675
+ }
5676
+ };
5677
+ var WEBGL_CONSTANTS = {
5678
+ POINTS: 0,
5679
+ LINES: 1,
5680
+ LINE_LOOP: 2,
5681
+ LINE_STRIP: 3,
5682
+ TRIANGLES: 4,
5683
+ TRIANGLE_STRIP: 5,
5684
+ TRIANGLE_FAN: 6,
5685
+ BYTE: 5120,
5686
+ UNSIGNED_BYTE: 5121,
5687
+ SHORT: 5122,
5688
+ UNSIGNED_SHORT: 5123,
5689
+ INT: 5124,
5690
+ UNSIGNED_INT: 5125,
5691
+ FLOAT: 5126,
5692
+ ARRAY_BUFFER: 34962,
5693
+ ELEMENT_ARRAY_BUFFER: 34963,
5694
+ NEAREST: 9728,
5695
+ LINEAR: 9729,
5696
+ NEAREST_MIPMAP_NEAREST: 9984,
5697
+ LINEAR_MIPMAP_NEAREST: 9985,
5698
+ NEAREST_MIPMAP_LINEAR: 9986,
5699
+ LINEAR_MIPMAP_LINEAR: 9987,
5700
+ CLAMP_TO_EDGE: 33071,
5701
+ MIRRORED_REPEAT: 33648,
5702
+ REPEAT: 10497
5703
+ };
5704
+ var KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
5705
+ var THREE_TO_WEBGL = {};
5706
+ THREE_TO_WEBGL[import_three17.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
5707
+ THREE_TO_WEBGL[import_three17.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
5708
+ THREE_TO_WEBGL[import_three17.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
5709
+ THREE_TO_WEBGL[import_three17.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
5710
+ THREE_TO_WEBGL[import_three17.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
5711
+ THREE_TO_WEBGL[import_three17.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
5712
+ THREE_TO_WEBGL[import_three17.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
5713
+ THREE_TO_WEBGL[import_three17.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
5714
+ THREE_TO_WEBGL[import_three17.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
5715
+ var PATH_PROPERTIES = {
5716
+ scale: "scale",
5717
+ position: "translation",
5718
+ quaternion: "rotation",
5719
+ morphTargetInfluences: "weights"
5720
+ };
5721
+ var DEFAULT_SPECULAR_COLOR = new import_three17.Color();
5722
+ var GLB_HEADER_BYTES = 12;
5723
+ var GLB_HEADER_MAGIC = 1179937895;
5724
+ var GLB_VERSION = 2;
5725
+ var GLB_CHUNK_PREFIX_BYTES = 8;
5726
+ var GLB_CHUNK_TYPE_JSON = 1313821514;
5727
+ var GLB_CHUNK_TYPE_BIN = 5130562;
5728
+ function equalArray(array1, array2) {
5729
+ return array1.length === array2.length && array1.every(function(element, index) {
5730
+ return element === array2[index];
5731
+ });
5732
+ }
5733
+ function stringToArrayBuffer(text) {
5734
+ return new TextEncoder().encode(text).buffer;
5735
+ }
5736
+ function isIdentityMatrix(matrix) {
5737
+ return equalArray(matrix.elements, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
5738
+ }
5739
+ function getMinMax(attribute, start, count) {
5740
+ const output = {
5741
+ min: new Array(attribute.itemSize).fill(Number.POSITIVE_INFINITY),
5742
+ max: new Array(attribute.itemSize).fill(Number.NEGATIVE_INFINITY)
5743
+ };
5744
+ for (let i = start; i < start + count; i++) {
5745
+ for (let a = 0; a < attribute.itemSize; a++) {
5746
+ let value;
5747
+ if (attribute.itemSize > 4) {
5748
+ value = attribute.array[i * attribute.itemSize + a];
5749
+ } else {
5750
+ if (a === 0) value = attribute.getX(i);
5751
+ else if (a === 1) value = attribute.getY(i);
5752
+ else if (a === 2) value = attribute.getZ(i);
5753
+ else if (a === 3) value = attribute.getW(i);
5754
+ if (attribute.normalized === true) {
5755
+ value = import_three17.MathUtils.normalize(value, attribute.array);
5756
+ }
5757
+ }
5758
+ output.min[a] = Math.min(output.min[a], value);
5759
+ output.max[a] = Math.max(output.max[a], value);
5760
+ }
5761
+ }
5762
+ return output;
5763
+ }
5764
+ function getPaddedBufferSize(bufferSize) {
5765
+ return Math.ceil(bufferSize / 4) * 4;
5766
+ }
5767
+ function getPaddedArrayBuffer(arrayBuffer, paddingByte = 0) {
5768
+ const paddedLength = getPaddedBufferSize(arrayBuffer.byteLength);
5769
+ if (paddedLength !== arrayBuffer.byteLength) {
5770
+ const array = new Uint8Array(paddedLength);
5771
+ array.set(new Uint8Array(arrayBuffer));
5772
+ if (paddingByte !== 0) {
5773
+ for (let i = arrayBuffer.byteLength; i < paddedLength; i++) {
5774
+ array[i] = paddingByte;
5775
+ }
5776
+ }
5777
+ return array.buffer;
5778
+ }
5779
+ return arrayBuffer;
5780
+ }
5781
+ function getCanvas() {
5782
+ if (typeof document === "undefined" && typeof OffscreenCanvas !== "undefined") {
5783
+ return new OffscreenCanvas(1, 1);
5784
+ }
5785
+ return document.createElement("canvas");
5786
+ }
5787
+ function getToBlobPromise(canvas, mimeType) {
5788
+ if (canvas.toBlob !== void 0) {
5789
+ return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
5790
+ }
5791
+ let quality;
5792
+ if (mimeType === "image/jpeg") {
5793
+ quality = 0.92;
5794
+ } else if (mimeType === "image/webp") {
5795
+ quality = 0.8;
5796
+ }
5797
+ return canvas.convertToBlob({
5798
+ type: mimeType,
5799
+ quality
5800
+ });
5801
+ }
5802
+ var GLTFWriter = class {
5803
+ constructor() {
5804
+ this.plugins = [];
5805
+ this.options = {};
5806
+ this.pending = [];
5807
+ this.buffers = [];
5808
+ this.byteOffset = 0;
5809
+ this.buffers = [];
5810
+ this.nodeMap = /* @__PURE__ */ new Map();
5811
+ this.skins = [];
5812
+ this.extensionsUsed = {};
5813
+ this.extensionsRequired = {};
5814
+ this.uids = /* @__PURE__ */ new Map();
5815
+ this.uid = 0;
5816
+ this.json = {
5817
+ asset: {
5818
+ version: "2.0",
5819
+ generator: "THREE.GLTFExporter"
5820
+ }
5821
+ };
5822
+ this.cache = {
5823
+ meshes: /* @__PURE__ */ new Map(),
5824
+ attributes: /* @__PURE__ */ new Map(),
5825
+ attributesNormalized: /* @__PURE__ */ new Map(),
5826
+ materials: /* @__PURE__ */ new Map(),
5827
+ textures: /* @__PURE__ */ new Map(),
5828
+ images: /* @__PURE__ */ new Map()
5829
+ };
5830
+ }
5831
+ setPlugins(plugins) {
5832
+ this.plugins = plugins;
5833
+ }
5834
+ /**
5835
+ * Parse scenes and generate GLTF output
5836
+ * @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
5837
+ * @param {Function} onDone Callback on completed
5838
+ * @param {Object} options options
5839
+ */
5840
+ async write(input, onDone, options = {}) {
5841
+ this.options = Object.assign({
5842
+ // default options
5843
+ binary: false,
5844
+ trs: false,
5845
+ onlyVisible: true,
5846
+ maxTextureSize: Infinity,
5847
+ animations: [],
5848
+ includeCustomExtensions: false
5849
+ }, options);
5850
+ if (this.options.animations.length > 0) {
5851
+ this.options.trs = true;
5852
+ }
5853
+ this.processInput(input);
5854
+ await Promise.all(this.pending);
5855
+ const writer = this;
5856
+ const buffers = writer.buffers;
5857
+ const json = writer.json;
5858
+ options = writer.options;
5859
+ const extensionsUsed = writer.extensionsUsed;
5860
+ const extensionsRequired = writer.extensionsRequired;
5861
+ const blob = new Blob(buffers, { type: "application/octet-stream" });
5862
+ const extensionsUsedList = Object.keys(extensionsUsed);
5863
+ const extensionsRequiredList = Object.keys(extensionsRequired);
5864
+ if (extensionsUsedList.length > 0) json.extensionsUsed = extensionsUsedList;
5865
+ if (extensionsRequiredList.length > 0) json.extensionsRequired = extensionsRequiredList;
5866
+ if (json.buffers && json.buffers.length > 0) json.buffers[0].byteLength = blob.size;
5867
+ if (options.binary === true) {
5868
+ const reader = new FileReader();
5869
+ reader.readAsArrayBuffer(blob);
5870
+ reader.onloadend = function() {
5871
+ const binaryChunk = getPaddedArrayBuffer(reader.result);
5872
+ const binaryChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
5873
+ binaryChunkPrefix.setUint32(0, binaryChunk.byteLength, true);
5874
+ binaryChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_BIN, true);
5875
+ const jsonChunk = getPaddedArrayBuffer(stringToArrayBuffer(JSON.stringify(json)), 32);
5876
+ const jsonChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
5877
+ jsonChunkPrefix.setUint32(0, jsonChunk.byteLength, true);
5878
+ jsonChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_JSON, true);
5879
+ const header = new ArrayBuffer(GLB_HEADER_BYTES);
5880
+ const headerView = new DataView(header);
5881
+ headerView.setUint32(0, GLB_HEADER_MAGIC, true);
5882
+ headerView.setUint32(4, GLB_VERSION, true);
5883
+ const totalByteLength = GLB_HEADER_BYTES + jsonChunkPrefix.byteLength + jsonChunk.byteLength + binaryChunkPrefix.byteLength + binaryChunk.byteLength;
5884
+ headerView.setUint32(8, totalByteLength, true);
5885
+ const glbBlob = new Blob([
5886
+ header,
5887
+ jsonChunkPrefix,
5888
+ jsonChunk,
5889
+ binaryChunkPrefix,
5890
+ binaryChunk
5891
+ ], { type: "application/octet-stream" });
5892
+ const glbReader = new FileReader();
5893
+ glbReader.readAsArrayBuffer(glbBlob);
5894
+ glbReader.onloadend = function() {
5895
+ onDone(glbReader.result);
5896
+ };
5897
+ };
5898
+ } else {
5899
+ if (json.buffers && json.buffers.length > 0) {
5900
+ const reader = new FileReader();
5901
+ reader.readAsDataURL(blob);
5902
+ reader.onloadend = function() {
5903
+ const base64data = reader.result;
5904
+ json.buffers[0].uri = base64data;
5905
+ onDone(json);
5906
+ };
5907
+ } else {
5908
+ onDone(json);
5909
+ }
5910
+ }
5911
+ }
5912
+ /**
5913
+ * Serializes a userData.
5914
+ *
5915
+ * @param {THREE.Object3D|THREE.Material} object
5916
+ * @param {Object} objectDef
5917
+ */
5918
+ serializeUserData(object, objectDef) {
5919
+ if (Object.keys(object.userData).length === 0) return;
5920
+ const options = this.options;
5921
+ const extensionsUsed = this.extensionsUsed;
5922
+ try {
5923
+ const json = JSON.parse(JSON.stringify(object.userData));
5924
+ if (options.includeCustomExtensions && json.gltfExtensions) {
5925
+ if (objectDef.extensions === void 0) objectDef.extensions = {};
5926
+ for (const extensionName in json.gltfExtensions) {
5927
+ objectDef.extensions[extensionName] = json.gltfExtensions[extensionName];
5928
+ extensionsUsed[extensionName] = true;
5929
+ }
5930
+ delete json.gltfExtensions;
5931
+ }
5932
+ if (Object.keys(json).length > 0) objectDef.extras = json;
5933
+ } catch (error) {
5934
+ console.warn("THREE.GLTFExporter: userData of '" + object.name + "' won't be serialized because of JSON.stringify error - " + error.message);
5935
+ }
5936
+ }
5937
+ /**
5938
+ * Returns ids for buffer attributes.
5939
+ * @param {Object} object
5940
+ * @return {Integer}
5941
+ */
5942
+ getUID(attribute, isRelativeCopy = false) {
5943
+ if (this.uids.has(attribute) === false) {
5944
+ const uids2 = /* @__PURE__ */ new Map();
5945
+ uids2.set(true, this.uid++);
5946
+ uids2.set(false, this.uid++);
5947
+ this.uids.set(attribute, uids2);
5948
+ }
5949
+ const uids = this.uids.get(attribute);
5950
+ return uids.get(isRelativeCopy);
5951
+ }
5952
+ /**
5953
+ * Checks if normal attribute values are normalized.
5954
+ *
5955
+ * @param {BufferAttribute} normal
5956
+ * @returns {Boolean}
5957
+ */
5958
+ isNormalizedNormalAttribute(normal) {
5959
+ const cache = this.cache;
5960
+ if (cache.attributesNormalized.has(normal)) return false;
5961
+ const v = new import_three17.Vector3();
5962
+ for (let i = 0, il = normal.count; i < il; i++) {
5963
+ if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
5964
+ }
5965
+ return true;
5966
+ }
5967
+ /**
5968
+ * Creates normalized normal buffer attribute.
5969
+ *
5970
+ * @param {BufferAttribute} normal
5971
+ * @returns {BufferAttribute}
5972
+ *
5973
+ */
5974
+ createNormalizedNormalAttribute(normal) {
5975
+ const cache = this.cache;
5976
+ if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
5977
+ const attribute = normal.clone();
5978
+ const v = new import_three17.Vector3();
5979
+ for (let i = 0, il = attribute.count; i < il; i++) {
5980
+ v.fromBufferAttribute(attribute, i);
5981
+ if (v.x === 0 && v.y === 0 && v.z === 0) {
5982
+ v.setX(1);
5983
+ } else {
5984
+ v.normalize();
5985
+ }
5986
+ attribute.setXYZ(i, v.x, v.y, v.z);
5987
+ }
5988
+ cache.attributesNormalized.set(normal, attribute);
5989
+ return attribute;
5990
+ }
5991
+ /**
5992
+ * Applies a texture transform, if present, to the map definition. Requires
5993
+ * the KHR_texture_transform extension.
5994
+ *
5995
+ * @param {Object} mapDef
5996
+ * @param {THREE.Texture} texture
5997
+ */
5998
+ applyTextureTransform(mapDef, texture) {
5999
+ let didTransform = false;
6000
+ const transformDef = {};
6001
+ if (texture.offset.x !== 0 || texture.offset.y !== 0) {
6002
+ transformDef.offset = texture.offset.toArray();
6003
+ didTransform = true;
6004
+ }
6005
+ if (texture.rotation !== 0) {
6006
+ transformDef.rotation = texture.rotation;
6007
+ didTransform = true;
6008
+ }
6009
+ if (texture.repeat.x !== 1 || texture.repeat.y !== 1) {
6010
+ transformDef.scale = texture.repeat.toArray();
6011
+ didTransform = true;
6012
+ }
6013
+ if (didTransform) {
6014
+ mapDef.extensions = mapDef.extensions || {};
6015
+ mapDef.extensions["KHR_texture_transform"] = transformDef;
6016
+ this.extensionsUsed["KHR_texture_transform"] = true;
6017
+ }
6018
+ }
6019
+ buildMetalRoughTexture(metalnessMap, roughnessMap) {
6020
+ if (metalnessMap === roughnessMap) return metalnessMap;
6021
+ function getEncodingConversion(map) {
6022
+ if (map.colorSpace === import_three17.SRGBColorSpace) {
6023
+ return function SRGBToLinear(c) {
6024
+ return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
6025
+ };
6026
+ }
6027
+ return function LinearToLinear(c) {
6028
+ return c;
6029
+ };
6030
+ }
6031
+ console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
6032
+ if (metalnessMap instanceof import_three17.CompressedTexture) {
6033
+ metalnessMap = decompress(metalnessMap);
6034
+ }
6035
+ if (roughnessMap instanceof import_three17.CompressedTexture) {
6036
+ roughnessMap = decompress(roughnessMap);
6037
+ }
6038
+ const metalness = metalnessMap ? metalnessMap.image : null;
6039
+ const roughness = roughnessMap ? roughnessMap.image : null;
6040
+ const width = Math.max(metalness ? metalness.width : 0, roughness ? roughness.width : 0);
6041
+ const height = Math.max(metalness ? metalness.height : 0, roughness ? roughness.height : 0);
6042
+ const canvas = getCanvas();
6043
+ canvas.width = width;
6044
+ canvas.height = height;
6045
+ const context = canvas.getContext("2d");
6046
+ context.fillStyle = "#00ffff";
6047
+ context.fillRect(0, 0, width, height);
6048
+ const composite = context.getImageData(0, 0, width, height);
6049
+ if (metalness) {
6050
+ context.drawImage(metalness, 0, 0, width, height);
6051
+ const convert = getEncodingConversion(metalnessMap);
6052
+ const data = context.getImageData(0, 0, width, height).data;
6053
+ for (let i = 2; i < data.length; i += 4) {
6054
+ composite.data[i] = convert(data[i] / 256) * 256;
6055
+ }
6056
+ }
6057
+ if (roughness) {
6058
+ context.drawImage(roughness, 0, 0, width, height);
6059
+ const convert = getEncodingConversion(roughnessMap);
6060
+ const data = context.getImageData(0, 0, width, height).data;
6061
+ for (let i = 1; i < data.length; i += 4) {
6062
+ composite.data[i] = convert(data[i] / 256) * 256;
6063
+ }
6064
+ }
6065
+ context.putImageData(composite, 0, 0);
6066
+ const reference = metalnessMap || roughnessMap;
6067
+ const texture = reference.clone();
6068
+ texture.source = new import_three17.Source(canvas);
6069
+ texture.colorSpace = import_three17.NoColorSpace;
6070
+ texture.channel = (metalnessMap || roughnessMap).channel;
6071
+ if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
6072
+ console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
6073
+ }
6074
+ return texture;
6075
+ }
6076
+ /**
6077
+ * Process a buffer to append to the default one.
6078
+ * @param {ArrayBuffer} buffer
6079
+ * @return {Integer}
6080
+ */
6081
+ processBuffer(buffer) {
6082
+ const json = this.json;
6083
+ const buffers = this.buffers;
6084
+ if (!json.buffers) json.buffers = [{ byteLength: 0 }];
6085
+ buffers.push(buffer);
6086
+ return 0;
6087
+ }
6088
+ /**
6089
+ * Process and generate a BufferView
6090
+ * @param {BufferAttribute} attribute
6091
+ * @param {number} componentType
6092
+ * @param {number} start
6093
+ * @param {number} count
6094
+ * @param {number} target (Optional) Target usage of the BufferView
6095
+ * @return {Object}
6096
+ */
6097
+ processBufferView(attribute, componentType, start, count, target) {
6098
+ const json = this.json;
6099
+ if (!json.bufferViews) json.bufferViews = [];
6100
+ let componentSize;
6101
+ switch (componentType) {
6102
+ case WEBGL_CONSTANTS.BYTE:
6103
+ case WEBGL_CONSTANTS.UNSIGNED_BYTE:
6104
+ componentSize = 1;
6105
+ break;
6106
+ case WEBGL_CONSTANTS.SHORT:
6107
+ case WEBGL_CONSTANTS.UNSIGNED_SHORT:
6108
+ componentSize = 2;
6109
+ break;
6110
+ default:
6111
+ componentSize = 4;
6112
+ }
6113
+ const byteLength = getPaddedBufferSize(count * attribute.itemSize * componentSize);
6114
+ const dataView = new DataView(new ArrayBuffer(byteLength));
6115
+ let offset = 0;
6116
+ for (let i = start; i < start + count; i++) {
6117
+ for (let a = 0; a < attribute.itemSize; a++) {
6118
+ let value;
6119
+ if (attribute.itemSize > 4) {
6120
+ value = attribute.array[i * attribute.itemSize + a];
6121
+ } else {
6122
+ if (a === 0) value = attribute.getX(i);
6123
+ else if (a === 1) value = attribute.getY(i);
6124
+ else if (a === 2) value = attribute.getZ(i);
6125
+ else if (a === 3) value = attribute.getW(i);
6126
+ if (attribute.normalized === true) {
6127
+ value = import_three17.MathUtils.normalize(value, attribute.array);
6128
+ }
6129
+ }
6130
+ if (componentType === WEBGL_CONSTANTS.FLOAT) {
6131
+ dataView.setFloat32(offset, value, true);
6132
+ } else if (componentType === WEBGL_CONSTANTS.INT) {
6133
+ dataView.setInt32(offset, value, true);
6134
+ } else if (componentType === WEBGL_CONSTANTS.UNSIGNED_INT) {
6135
+ dataView.setUint32(offset, value, true);
6136
+ } else if (componentType === WEBGL_CONSTANTS.SHORT) {
6137
+ dataView.setInt16(offset, value, true);
6138
+ } else if (componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT) {
6139
+ dataView.setUint16(offset, value, true);
6140
+ } else if (componentType === WEBGL_CONSTANTS.BYTE) {
6141
+ dataView.setInt8(offset, value);
6142
+ } else if (componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE) {
6143
+ dataView.setUint8(offset, value);
6144
+ }
6145
+ offset += componentSize;
6146
+ }
6147
+ }
6148
+ const bufferViewDef = {
6149
+ buffer: this.processBuffer(dataView.buffer),
6150
+ byteOffset: this.byteOffset,
6151
+ byteLength
6152
+ };
6153
+ if (target !== void 0) bufferViewDef.target = target;
6154
+ if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
6155
+ bufferViewDef.byteStride = attribute.itemSize * componentSize;
6156
+ }
6157
+ this.byteOffset += byteLength;
6158
+ json.bufferViews.push(bufferViewDef);
6159
+ const output = {
6160
+ id: json.bufferViews.length - 1,
6161
+ byteLength: 0
6162
+ };
6163
+ return output;
6164
+ }
6165
+ /**
6166
+ * Process and generate a BufferView from an image Blob.
6167
+ * @param {Blob} blob
6168
+ * @return {Promise<Integer>}
6169
+ */
6170
+ processBufferViewImage(blob) {
6171
+ const writer = this;
6172
+ const json = writer.json;
6173
+ if (!json.bufferViews) json.bufferViews = [];
6174
+ return new Promise(function(resolve) {
6175
+ const reader = new FileReader();
6176
+ reader.readAsArrayBuffer(blob);
6177
+ reader.onloadend = function() {
6178
+ const buffer = getPaddedArrayBuffer(reader.result);
6179
+ const bufferViewDef = {
6180
+ buffer: writer.processBuffer(buffer),
6181
+ byteOffset: writer.byteOffset,
6182
+ byteLength: buffer.byteLength
6183
+ };
6184
+ writer.byteOffset += buffer.byteLength;
6185
+ resolve(json.bufferViews.push(bufferViewDef) - 1);
6186
+ };
6187
+ });
6188
+ }
6189
+ /**
6190
+ * Process attribute to generate an accessor
6191
+ * @param {BufferAttribute} attribute Attribute to process
6192
+ * @param {THREE.BufferGeometry} geometry (Optional) Geometry used for truncated draw range
6193
+ * @param {Integer} start (Optional)
6194
+ * @param {Integer} count (Optional)
6195
+ * @return {Integer|null} Index of the processed accessor on the "accessors" array
6196
+ */
6197
+ processAccessor(attribute, geometry, start, count) {
6198
+ const json = this.json;
6199
+ const types = {
6200
+ 1: "SCALAR",
6201
+ 2: "VEC2",
6202
+ 3: "VEC3",
6203
+ 4: "VEC4",
6204
+ 9: "MAT3",
6205
+ 16: "MAT4"
6206
+ };
6207
+ let componentType;
6208
+ if (attribute.array.constructor === Float32Array) {
6209
+ componentType = WEBGL_CONSTANTS.FLOAT;
6210
+ } else if (attribute.array.constructor === Int32Array) {
6211
+ componentType = WEBGL_CONSTANTS.INT;
6212
+ } else if (attribute.array.constructor === Uint32Array) {
6213
+ componentType = WEBGL_CONSTANTS.UNSIGNED_INT;
6214
+ } else if (attribute.array.constructor === Int16Array) {
6215
+ componentType = WEBGL_CONSTANTS.SHORT;
6216
+ } else if (attribute.array.constructor === Uint16Array) {
6217
+ componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT;
6218
+ } else if (attribute.array.constructor === Int8Array) {
6219
+ componentType = WEBGL_CONSTANTS.BYTE;
6220
+ } else if (attribute.array.constructor === Uint8Array) {
6221
+ componentType = WEBGL_CONSTANTS.UNSIGNED_BYTE;
6222
+ } else {
6223
+ throw new Error("THREE.GLTFExporter: Unsupported bufferAttribute component type: " + attribute.array.constructor.name);
6224
+ }
6225
+ if (start === void 0) start = 0;
6226
+ if (count === void 0 || count === Infinity) count = attribute.count;
6227
+ if (count === 0) return null;
6228
+ const minMax = getMinMax(attribute, start, count);
6229
+ let bufferViewTarget;
6230
+ if (geometry !== void 0) {
6231
+ bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
6232
+ }
6233
+ const bufferView = this.processBufferView(attribute, componentType, start, count, bufferViewTarget);
6234
+ const accessorDef = {
6235
+ bufferView: bufferView.id,
6236
+ byteOffset: bufferView.byteOffset,
6237
+ componentType,
6238
+ count,
6239
+ max: minMax.max,
6240
+ min: minMax.min,
6241
+ type: types[attribute.itemSize]
6242
+ };
6243
+ if (attribute.normalized === true) accessorDef.normalized = true;
6244
+ if (!json.accessors) json.accessors = [];
6245
+ return json.accessors.push(accessorDef) - 1;
6246
+ }
6247
+ /**
6248
+ * Process image
6249
+ * @param {Image} image to process
6250
+ * @param {Integer} format of the image (RGBAFormat)
6251
+ * @param {Boolean} flipY before writing out the image
6252
+ * @param {String} mimeType export format
6253
+ * @return {Integer} Index of the processed texture in the "images" array
6254
+ */
6255
+ processImage(image, format, flipY, mimeType = "image/png") {
6256
+ if (image !== null) {
6257
+ const writer = this;
6258
+ const cache = writer.cache;
6259
+ const json = writer.json;
6260
+ const options = writer.options;
6261
+ const pending = writer.pending;
6262
+ if (!cache.images.has(image)) cache.images.set(image, {});
6263
+ const cachedImages = cache.images.get(image);
6264
+ const key = mimeType + ":flipY/" + flipY.toString();
6265
+ if (cachedImages[key] !== void 0) return cachedImages[key];
6266
+ if (!json.images) json.images = [];
6267
+ const imageDef = { mimeType };
6268
+ const canvas = getCanvas();
6269
+ canvas.width = Math.min(image.width, options.maxTextureSize);
6270
+ canvas.height = Math.min(image.height, options.maxTextureSize);
6271
+ const ctx = canvas.getContext("2d");
6272
+ if (flipY === true) {
6273
+ ctx.translate(0, canvas.height);
6274
+ ctx.scale(1, -1);
6275
+ }
6276
+ if (image.data !== void 0) {
6277
+ if (format !== import_three17.RGBAFormat) {
6278
+ console.error("GLTFExporter: Only RGBAFormat is supported.", format);
6279
+ }
6280
+ if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
6281
+ console.warn("GLTFExporter: Image size is bigger than maxTextureSize", image);
6282
+ }
6283
+ const data = new Uint8ClampedArray(image.height * image.width * 4);
6284
+ for (let i = 0; i < data.length; i += 4) {
6285
+ data[i + 0] = image.data[i + 0];
6286
+ data[i + 1] = image.data[i + 1];
6287
+ data[i + 2] = image.data[i + 2];
6288
+ data[i + 3] = image.data[i + 3];
6289
+ }
6290
+ ctx.putImageData(new ImageData(data, image.width, image.height), 0, 0);
6291
+ } else {
6292
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
6293
+ }
6294
+ if (options.binary === true) {
6295
+ pending.push(
6296
+ getToBlobPromise(canvas, mimeType).then((blob) => writer.processBufferViewImage(blob)).then((bufferViewIndex) => {
6297
+ imageDef.bufferView = bufferViewIndex;
6298
+ })
6299
+ );
6300
+ } else {
6301
+ if (canvas.toDataURL !== void 0) {
6302
+ imageDef.uri = canvas.toDataURL(mimeType);
6303
+ } else {
6304
+ pending.push(
6305
+ getToBlobPromise(canvas, mimeType).then((blob) => new FileReader().readAsDataURL(blob)).then((dataURL) => {
6306
+ imageDef.uri = dataURL;
6307
+ })
6308
+ );
6309
+ }
6310
+ }
6311
+ const index = json.images.push(imageDef) - 1;
6312
+ cachedImages[key] = index;
6313
+ return index;
6314
+ } else {
6315
+ throw new Error("THREE.GLTFExporter: No valid image data found. Unable to process texture.");
6316
+ }
6317
+ }
6318
+ /**
6319
+ * Process sampler
6320
+ * @param {Texture} map Texture to process
6321
+ * @return {Integer} Index of the processed texture in the "samplers" array
6322
+ */
6323
+ processSampler(map) {
6324
+ const json = this.json;
6325
+ if (!json.samplers) json.samplers = [];
6326
+ const samplerDef = {
6327
+ magFilter: THREE_TO_WEBGL[map.magFilter],
6328
+ minFilter: THREE_TO_WEBGL[map.minFilter],
6329
+ wrapS: THREE_TO_WEBGL[map.wrapS],
6330
+ wrapT: THREE_TO_WEBGL[map.wrapT]
6331
+ };
6332
+ return json.samplers.push(samplerDef) - 1;
6333
+ }
6334
+ /**
6335
+ * Process texture
6336
+ * @param {Texture} map Map to process
6337
+ * @return {Integer} Index of the processed texture in the "textures" array
6338
+ */
6339
+ processTexture(map) {
6340
+ const writer = this;
6341
+ const options = writer.options;
6342
+ const cache = this.cache;
6343
+ const json = this.json;
6344
+ if (cache.textures.has(map)) return cache.textures.get(map);
6345
+ if (!json.textures) json.textures = [];
6346
+ if (map instanceof import_three17.CompressedTexture) {
6347
+ map = decompress(map, options.maxTextureSize);
6348
+ }
6349
+ let mimeType = map.userData.mimeType;
6350
+ if (mimeType === "image/webp") mimeType = "image/png";
6351
+ const textureDef = {
6352
+ sampler: this.processSampler(map),
6353
+ source: this.processImage(map.image, map.format, map.flipY, mimeType)
6354
+ };
6355
+ if (map.name) textureDef.name = map.name;
6356
+ this._invokeAll(function(ext) {
6357
+ ext.writeTexture && ext.writeTexture(map, textureDef);
6358
+ });
6359
+ const index = json.textures.push(textureDef) - 1;
6360
+ cache.textures.set(map, index);
6361
+ return index;
6362
+ }
6363
+ /**
6364
+ * Process material
6365
+ * @param {THREE.Material} material Material to process
6366
+ * @return {Integer|null} Index of the processed material in the "materials" array
6367
+ */
6368
+ processMaterial(material) {
6369
+ const cache = this.cache;
6370
+ const json = this.json;
6371
+ if (cache.materials.has(material)) return cache.materials.get(material);
6372
+ if (material.isShaderMaterial) {
6373
+ console.warn("GLTFExporter: THREE.ShaderMaterial not supported.");
6374
+ return null;
6375
+ }
6376
+ if (!json.materials) json.materials = [];
6377
+ const materialDef = { pbrMetallicRoughness: {} };
6378
+ if (material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true) {
6379
+ console.warn("GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.");
6380
+ }
6381
+ const color = material.color.toArray().concat([material.opacity]);
6382
+ if (!equalArray(color, [1, 1, 1, 1])) {
6383
+ materialDef.pbrMetallicRoughness.baseColorFactor = color;
6384
+ }
6385
+ if (material.isMeshStandardMaterial) {
6386
+ materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
6387
+ materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
6388
+ } else {
6389
+ materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
6390
+ materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
6391
+ }
6392
+ if (material.metalnessMap || material.roughnessMap) {
6393
+ const metalRoughTexture = this.buildMetalRoughTexture(material.metalnessMap, material.roughnessMap);
6394
+ const metalRoughMapDef = {
6395
+ index: this.processTexture(metalRoughTexture),
6396
+ channel: metalRoughTexture.channel
6397
+ };
6398
+ this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
6399
+ materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
6400
+ }
6401
+ if (material.map) {
6402
+ const baseColorMapDef = {
6403
+ index: this.processTexture(material.map),
6404
+ texCoord: material.map.channel
6405
+ };
6406
+ this.applyTextureTransform(baseColorMapDef, material.map);
6407
+ materialDef.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
6408
+ }
6409
+ if (material.emissive) {
6410
+ const emissive = material.emissive;
6411
+ const maxEmissiveComponent = Math.max(emissive.r, emissive.g, emissive.b);
6412
+ if (maxEmissiveComponent > 0) {
6413
+ materialDef.emissiveFactor = material.emissive.toArray();
6414
+ }
6415
+ if (material.emissiveMap) {
6416
+ const emissiveMapDef = {
6417
+ index: this.processTexture(material.emissiveMap),
6418
+ texCoord: material.emissiveMap.channel
6419
+ };
6420
+ this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
6421
+ materialDef.emissiveTexture = emissiveMapDef;
6422
+ }
6423
+ }
6424
+ if (material.normalMap) {
6425
+ const normalMapDef = {
6426
+ index: this.processTexture(material.normalMap),
6427
+ texCoord: material.normalMap.channel
6428
+ };
6429
+ if (material.normalScale && material.normalScale.x !== 1) {
6430
+ normalMapDef.scale = material.normalScale.x;
6431
+ }
6432
+ this.applyTextureTransform(normalMapDef, material.normalMap);
6433
+ materialDef.normalTexture = normalMapDef;
6434
+ }
6435
+ if (material.aoMap) {
6436
+ const occlusionMapDef = {
6437
+ index: this.processTexture(material.aoMap),
6438
+ texCoord: material.aoMap.channel
6439
+ };
6440
+ if (material.aoMapIntensity !== 1) {
6441
+ occlusionMapDef.strength = material.aoMapIntensity;
6442
+ }
6443
+ this.applyTextureTransform(occlusionMapDef, material.aoMap);
6444
+ materialDef.occlusionTexture = occlusionMapDef;
6445
+ }
6446
+ if (material.transparent) {
6447
+ materialDef.alphaMode = "BLEND";
6448
+ } else {
6449
+ if (material.alphaTest > 0) {
6450
+ materialDef.alphaMode = "MASK";
6451
+ materialDef.alphaCutoff = material.alphaTest;
6452
+ }
6453
+ }
6454
+ if (material.side === import_three17.DoubleSide) materialDef.doubleSided = true;
6455
+ if (material.name !== "") materialDef.name = material.name;
6456
+ this.serializeUserData(material, materialDef);
6457
+ this._invokeAll(function(ext) {
6458
+ ext.writeMaterial && ext.writeMaterial(material, materialDef);
6459
+ });
6460
+ const index = json.materials.push(materialDef) - 1;
6461
+ cache.materials.set(material, index);
6462
+ return index;
6463
+ }
6464
+ /**
6465
+ * Process mesh
6466
+ * @param {THREE.Mesh} mesh Mesh to process
6467
+ * @return {Integer|null} Index of the processed mesh in the "meshes" array
6468
+ */
6469
+ processMesh(mesh) {
6470
+ const cache = this.cache;
6471
+ const json = this.json;
6472
+ const meshCacheKeyParts = [mesh.geometry.uuid];
6473
+ if (Array.isArray(mesh.material)) {
6474
+ for (let i = 0, l = mesh.material.length; i < l; i++) {
6475
+ meshCacheKeyParts.push(mesh.material[i].uuid);
6476
+ }
6477
+ } else {
6478
+ meshCacheKeyParts.push(mesh.material.uuid);
6479
+ }
6480
+ const meshCacheKey = meshCacheKeyParts.join(":");
6481
+ if (cache.meshes.has(meshCacheKey)) return cache.meshes.get(meshCacheKey);
6482
+ const geometry = mesh.geometry;
6483
+ let mode;
6484
+ if (mesh.isLineSegments) {
6485
+ mode = WEBGL_CONSTANTS.LINES;
6486
+ } else if (mesh.isLineLoop) {
6487
+ mode = WEBGL_CONSTANTS.LINE_LOOP;
6488
+ } else if (mesh.isLine) {
6489
+ mode = WEBGL_CONSTANTS.LINE_STRIP;
6490
+ } else if (mesh.isPoints) {
6491
+ mode = WEBGL_CONSTANTS.POINTS;
6492
+ } else {
6493
+ mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES;
6494
+ }
6495
+ const meshDef = {};
6496
+ const attributes = {};
6497
+ const primitives = [];
6498
+ const targets = [];
6499
+ const nameConversion = {
6500
+ uv: "TEXCOORD_0",
6501
+ uv1: "TEXCOORD_1",
6502
+ uv2: "TEXCOORD_2",
6503
+ uv3: "TEXCOORD_3",
6504
+ color: "COLOR_0",
6505
+ skinWeight: "WEIGHTS_0",
6506
+ skinIndex: "JOINTS_0"
6507
+ };
6508
+ const originalNormal = geometry.getAttribute("normal");
6509
+ if (originalNormal !== void 0 && !this.isNormalizedNormalAttribute(originalNormal)) {
6510
+ console.warn("THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.");
6511
+ geometry.setAttribute("normal", this.createNormalizedNormalAttribute(originalNormal));
6512
+ }
6513
+ let modifiedAttribute = null;
6514
+ for (let attributeName in geometry.attributes) {
6515
+ if (attributeName.slice(0, 5) === "morph") continue;
6516
+ const attribute = geometry.attributes[attributeName];
6517
+ attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
6518
+ const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
6519
+ if (!validVertexAttributes.test(attributeName)) attributeName = "_" + attributeName;
6520
+ if (cache.attributes.has(this.getUID(attribute))) {
6521
+ attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
6522
+ continue;
6523
+ }
6524
+ modifiedAttribute = null;
6525
+ const array = attribute.array;
6526
+ if (attributeName === "JOINTS_0" && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
6527
+ console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
6528
+ modifiedAttribute = new import_three17.BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
6529
+ }
6530
+ const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
6531
+ if (accessor !== null) {
6532
+ if (!attributeName.startsWith("_")) {
6533
+ this.detectMeshQuantization(attributeName, attribute);
6534
+ }
6535
+ attributes[attributeName] = accessor;
6536
+ cache.attributes.set(this.getUID(attribute), accessor);
6537
+ }
6538
+ }
6539
+ if (originalNormal !== void 0) geometry.setAttribute("normal", originalNormal);
6540
+ if (Object.keys(attributes).length === 0) return null;
6541
+ if (mesh.morphTargetInfluences !== void 0 && mesh.morphTargetInfluences.length > 0) {
6542
+ const weights = [];
6543
+ const targetNames = [];
6544
+ const reverseDictionary = {};
6545
+ if (mesh.morphTargetDictionary !== void 0) {
6546
+ for (const key in mesh.morphTargetDictionary) {
6547
+ reverseDictionary[mesh.morphTargetDictionary[key]] = key;
6548
+ }
6549
+ }
6550
+ for (let i = 0; i < mesh.morphTargetInfluences.length; ++i) {
6551
+ const target = {};
6552
+ let warned = false;
6553
+ for (const attributeName in geometry.morphAttributes) {
6554
+ if (attributeName !== "position" && attributeName !== "normal") {
6555
+ if (!warned) {
6556
+ console.warn("GLTFExporter: Only POSITION and NORMAL morph are supported.");
6557
+ warned = true;
6558
+ }
6559
+ continue;
6560
+ }
6561
+ const attribute = geometry.morphAttributes[attributeName][i];
6562
+ const gltfAttributeName = attributeName.toUpperCase();
6563
+ const baseAttribute = geometry.attributes[attributeName];
6564
+ if (cache.attributes.has(this.getUID(attribute, true))) {
6565
+ target[gltfAttributeName] = cache.attributes.get(this.getUID(attribute, true));
6566
+ continue;
6567
+ }
6568
+ const relativeAttribute = attribute.clone();
6569
+ if (!geometry.morphTargetsRelative) {
6570
+ for (let j = 0, jl = attribute.count; j < jl; j++) {
6571
+ for (let a = 0; a < attribute.itemSize; a++) {
6572
+ if (a === 0) relativeAttribute.setX(j, attribute.getX(j) - baseAttribute.getX(j));
6573
+ if (a === 1) relativeAttribute.setY(j, attribute.getY(j) - baseAttribute.getY(j));
6574
+ if (a === 2) relativeAttribute.setZ(j, attribute.getZ(j) - baseAttribute.getZ(j));
6575
+ if (a === 3) relativeAttribute.setW(j, attribute.getW(j) - baseAttribute.getW(j));
6576
+ }
6577
+ }
6578
+ }
6579
+ target[gltfAttributeName] = this.processAccessor(relativeAttribute, geometry);
6580
+ cache.attributes.set(this.getUID(baseAttribute, true), target[gltfAttributeName]);
6581
+ }
6582
+ targets.push(target);
6583
+ weights.push(mesh.morphTargetInfluences[i]);
6584
+ if (mesh.morphTargetDictionary !== void 0) targetNames.push(reverseDictionary[i]);
6585
+ }
6586
+ meshDef.weights = weights;
6587
+ if (targetNames.length > 0) {
6588
+ meshDef.extras = {};
6589
+ meshDef.extras.targetNames = targetNames;
6590
+ }
6591
+ }
6592
+ const isMultiMaterial = Array.isArray(mesh.material);
6593
+ if (isMultiMaterial && geometry.groups.length === 0) return null;
6594
+ const materials = isMultiMaterial ? mesh.material : [mesh.material];
6595
+ const groups = isMultiMaterial ? geometry.groups : [{ materialIndex: 0, start: void 0, count: void 0 }];
6596
+ for (let i = 0, il = groups.length; i < il; i++) {
6597
+ const primitive = {
6598
+ mode,
6599
+ attributes
6600
+ };
6601
+ this.serializeUserData(geometry, primitive);
6602
+ if (targets.length > 0) primitive.targets = targets;
6603
+ if (geometry.index !== null) {
6604
+ let cacheKey = this.getUID(geometry.index);
6605
+ if (groups[i].start !== void 0 || groups[i].count !== void 0) {
6606
+ cacheKey += ":" + groups[i].start + ":" + groups[i].count;
6607
+ }
6608
+ if (cache.attributes.has(cacheKey)) {
6609
+ primitive.indices = cache.attributes.get(cacheKey);
6610
+ } else {
6611
+ primitive.indices = this.processAccessor(geometry.index, geometry, groups[i].start, groups[i].count);
6612
+ cache.attributes.set(cacheKey, primitive.indices);
6613
+ }
6614
+ if (primitive.indices === null) delete primitive.indices;
6615
+ }
6616
+ const material = this.processMaterial(materials[groups[i].materialIndex]);
6617
+ if (material !== null) primitive.material = material;
6618
+ primitives.push(primitive);
6619
+ }
6620
+ meshDef.primitives = primitives;
6621
+ if (!json.meshes) json.meshes = [];
6622
+ this._invokeAll(function(ext) {
6623
+ ext.writeMesh && ext.writeMesh(mesh, meshDef);
6624
+ });
6625
+ const index = json.meshes.push(meshDef) - 1;
6626
+ cache.meshes.set(meshCacheKey, index);
6627
+ return index;
6628
+ }
6629
+ /**
6630
+ * If a vertex attribute with a
6631
+ * [non-standard data type](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview)
6632
+ * is used, it is checked whether it is a valid data type according to the
6633
+ * [KHR_mesh_quantization](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md)
6634
+ * extension.
6635
+ * In this case the extension is automatically added to the list of used extensions.
6636
+ *
6637
+ * @param {string} attributeName
6638
+ * @param {THREE.BufferAttribute} attribute
6639
+ */
6640
+ detectMeshQuantization(attributeName, attribute) {
6641
+ if (this.extensionsUsed[KHR_MESH_QUANTIZATION]) return;
6642
+ let attrType = void 0;
6643
+ switch (attribute.array.constructor) {
6644
+ case Int8Array:
6645
+ attrType = "byte";
6646
+ break;
6647
+ case Uint8Array:
6648
+ attrType = "unsigned byte";
6649
+ break;
6650
+ case Int16Array:
6651
+ attrType = "short";
6652
+ break;
6653
+ case Uint16Array:
6654
+ attrType = "unsigned short";
6655
+ break;
6656
+ default:
6657
+ return;
6658
+ }
6659
+ if (attribute.normalized) attrType += " normalized";
6660
+ const attrNamePrefix = attributeName.split("_", 1)[0];
6661
+ if (KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix] && KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix].includes(attrType)) {
6662
+ this.extensionsUsed[KHR_MESH_QUANTIZATION] = true;
6663
+ this.extensionsRequired[KHR_MESH_QUANTIZATION] = true;
6664
+ }
6665
+ }
6666
+ /**
6667
+ * Process camera
6668
+ * @param {THREE.Camera} camera Camera to process
6669
+ * @return {Integer} Index of the processed mesh in the "camera" array
6670
+ */
6671
+ processCamera(camera) {
6672
+ const json = this.json;
6673
+ if (!json.cameras) json.cameras = [];
6674
+ const isOrtho = camera.isOrthographicCamera;
6675
+ const cameraDef = {
6676
+ type: isOrtho ? "orthographic" : "perspective"
6677
+ };
6678
+ if (isOrtho) {
6679
+ cameraDef.orthographic = {
6680
+ xmag: camera.right * 2,
6681
+ ymag: camera.top * 2,
6682
+ zfar: camera.far <= 0 ? 1e-3 : camera.far,
6683
+ znear: camera.near < 0 ? 0 : camera.near
6684
+ };
6685
+ } else {
6686
+ cameraDef.perspective = {
6687
+ aspectRatio: camera.aspect,
6688
+ yfov: import_three17.MathUtils.degToRad(camera.fov),
6689
+ zfar: camera.far <= 0 ? 1e-3 : camera.far,
6690
+ znear: camera.near < 0 ? 0 : camera.near
6691
+ };
6692
+ }
6693
+ if (camera.name !== "") cameraDef.name = camera.type;
6694
+ return json.cameras.push(cameraDef) - 1;
6695
+ }
6696
+ /**
6697
+ * Creates glTF animation entry from AnimationClip object.
6698
+ *
6699
+ * Status:
6700
+ * - Only properties listed in PATH_PROPERTIES may be animated.
6701
+ *
6702
+ * @param {THREE.AnimationClip} clip
6703
+ * @param {THREE.Object3D} root
6704
+ * @return {number|null}
6705
+ */
6706
+ processAnimation(clip, root) {
6707
+ const json = this.json;
6708
+ const nodeMap = this.nodeMap;
6709
+ if (!json.animations) json.animations = [];
6710
+ clip = GLTFExporter.Utils.mergeMorphTargetTracks(clip.clone(), root);
6711
+ const tracks = clip.tracks;
6712
+ const channels = [];
6713
+ const samplers = [];
6714
+ for (let i = 0; i < tracks.length; ++i) {
6715
+ const track = tracks[i];
6716
+ const trackBinding = import_three17.PropertyBinding.parseTrackName(track.name);
6717
+ let trackNode = import_three17.PropertyBinding.findNode(root, trackBinding.nodeName);
6718
+ const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
6719
+ if (trackBinding.objectName === "bones") {
6720
+ if (trackNode.isSkinnedMesh === true) {
6721
+ trackNode = trackNode.skeleton.getBoneByName(trackBinding.objectIndex);
6722
+ } else {
6723
+ trackNode = void 0;
6724
+ }
6725
+ }
6726
+ if (!trackNode || !trackProperty) {
6727
+ console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
6728
+ return null;
6729
+ }
6730
+ const inputItemSize = 1;
6731
+ let outputItemSize = track.values.length / track.times.length;
6732
+ if (trackProperty === PATH_PROPERTIES.morphTargetInfluences) {
6733
+ outputItemSize /= trackNode.morphTargetInfluences.length;
6734
+ }
6735
+ let interpolation;
6736
+ if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
6737
+ interpolation = "CUBICSPLINE";
6738
+ outputItemSize /= 3;
6739
+ } else if (track.getInterpolation() === import_three17.InterpolateDiscrete) {
6740
+ interpolation = "STEP";
6741
+ } else {
6742
+ interpolation = "LINEAR";
6743
+ }
6744
+ samplers.push({
6745
+ input: this.processAccessor(new import_three17.BufferAttribute(track.times, inputItemSize)),
6746
+ output: this.processAccessor(new import_three17.BufferAttribute(track.values, outputItemSize)),
6747
+ interpolation
6748
+ });
6749
+ channels.push({
6750
+ sampler: samplers.length - 1,
6751
+ target: {
6752
+ node: nodeMap.get(trackNode),
6753
+ path: trackProperty
6754
+ }
6755
+ });
6756
+ }
6757
+ json.animations.push({
6758
+ name: clip.name || "clip_" + json.animations.length,
6759
+ samplers,
6760
+ channels
6761
+ });
6762
+ return json.animations.length - 1;
6763
+ }
6764
+ /**
6765
+ * @param {THREE.Object3D} object
6766
+ * @return {number|null}
6767
+ */
6768
+ processSkin(object) {
6769
+ const json = this.json;
6770
+ const nodeMap = this.nodeMap;
6771
+ const node = json.nodes[nodeMap.get(object)];
6772
+ const skeleton = object.skeleton;
6773
+ if (skeleton === void 0) return null;
6774
+ const rootJoint = object.skeleton.bones[0];
6775
+ if (rootJoint === void 0) return null;
6776
+ const joints = [];
6777
+ const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
6778
+ const temporaryBoneInverse = new import_three17.Matrix4();
6779
+ for (let i = 0; i < skeleton.bones.length; ++i) {
6780
+ joints.push(nodeMap.get(skeleton.bones[i]));
6781
+ temporaryBoneInverse.copy(skeleton.boneInverses[i]);
6782
+ temporaryBoneInverse.multiply(object.bindMatrix).toArray(inverseBindMatrices, i * 16);
6783
+ }
6784
+ if (json.skins === void 0) json.skins = [];
6785
+ json.skins.push({
6786
+ inverseBindMatrices: this.processAccessor(new import_three17.BufferAttribute(inverseBindMatrices, 16)),
6787
+ joints,
6788
+ skeleton: nodeMap.get(rootJoint)
6789
+ });
6790
+ const skinIndex = node.skin = json.skins.length - 1;
6791
+ return skinIndex;
6792
+ }
6793
+ /**
6794
+ * Process Object3D node
6795
+ * @param {THREE.Object3D} node Object3D to processNode
6796
+ * @return {Integer} Index of the node in the nodes list
6797
+ */
6798
+ processNode(object) {
6799
+ const json = this.json;
6800
+ const options = this.options;
6801
+ const nodeMap = this.nodeMap;
6802
+ if (!json.nodes) json.nodes = [];
6803
+ const nodeDef = {};
6804
+ if (options.trs) {
6805
+ const rotation = object.quaternion.toArray();
6806
+ const position = object.position.toArray();
6807
+ const scale = object.scale.toArray();
6808
+ if (!equalArray(rotation, [0, 0, 0, 1])) {
6809
+ nodeDef.rotation = rotation;
6810
+ }
6811
+ if (!equalArray(position, [0, 0, 0])) {
6812
+ nodeDef.translation = position;
6813
+ }
6814
+ if (!equalArray(scale, [1, 1, 1])) {
6815
+ nodeDef.scale = scale;
6816
+ }
6817
+ } else {
6818
+ if (object.matrixAutoUpdate) {
6819
+ object.updateMatrix();
6820
+ }
6821
+ if (isIdentityMatrix(object.matrix) === false) {
6822
+ nodeDef.matrix = object.matrix.elements;
6823
+ }
6824
+ }
6825
+ if (object.name !== "") nodeDef.name = String(object.name);
6826
+ this.serializeUserData(object, nodeDef);
6827
+ if (object.isMesh || object.isLine || object.isPoints) {
6828
+ const meshIndex = this.processMesh(object);
6829
+ if (meshIndex !== null) nodeDef.mesh = meshIndex;
6830
+ } else if (object.isCamera) {
6831
+ nodeDef.camera = this.processCamera(object);
6832
+ }
6833
+ if (object.isSkinnedMesh) this.skins.push(object);
6834
+ if (object.children.length > 0) {
6835
+ const children = [];
6836
+ for (let i = 0, l = object.children.length; i < l; i++) {
6837
+ const child = object.children[i];
6838
+ if (child.visible || options.onlyVisible === false) {
6839
+ const nodeIndex2 = this.processNode(child);
6840
+ if (nodeIndex2 !== null) children.push(nodeIndex2);
6841
+ }
6842
+ }
6843
+ if (children.length > 0) nodeDef.children = children;
6844
+ }
6845
+ this._invokeAll(function(ext) {
6846
+ ext.writeNode && ext.writeNode(object, nodeDef);
6847
+ });
6848
+ const nodeIndex = json.nodes.push(nodeDef) - 1;
6849
+ nodeMap.set(object, nodeIndex);
6850
+ return nodeIndex;
6851
+ }
6852
+ /**
6853
+ * Process Scene
6854
+ * @param {Scene} node Scene to process
6855
+ */
6856
+ processScene(scene) {
6857
+ const json = this.json;
6858
+ const options = this.options;
6859
+ if (!json.scenes) {
6860
+ json.scenes = [];
6861
+ json.scene = 0;
6862
+ }
6863
+ const sceneDef = {};
6864
+ if (scene.name !== "") sceneDef.name = scene.name;
6865
+ json.scenes.push(sceneDef);
6866
+ const nodes = [];
6867
+ for (let i = 0, l = scene.children.length; i < l; i++) {
6868
+ const child = scene.children[i];
6869
+ if (child.visible || options.onlyVisible === false) {
6870
+ const nodeIndex = this.processNode(child);
6871
+ if (nodeIndex !== null) nodes.push(nodeIndex);
6872
+ }
6873
+ }
6874
+ if (nodes.length > 0) sceneDef.nodes = nodes;
6875
+ this.serializeUserData(scene, sceneDef);
6876
+ }
6877
+ /**
6878
+ * Creates a Scene to hold a list of objects and parse it
6879
+ * @param {Array} objects List of objects to process
6880
+ */
6881
+ processObjects(objects) {
6882
+ const scene = new import_three17.Scene();
6883
+ scene.name = "AuxScene";
6884
+ for (let i = 0; i < objects.length; i++) {
6885
+ scene.children.push(objects[i]);
6886
+ }
6887
+ this.processScene(scene);
6888
+ }
6889
+ /**
6890
+ * @param {THREE.Object3D|Array<THREE.Object3D>} input
6891
+ */
6892
+ processInput(input) {
6893
+ const options = this.options;
6894
+ input = input instanceof Array ? input : [input];
6895
+ this._invokeAll(function(ext) {
6896
+ ext.beforeParse && ext.beforeParse(input);
6897
+ });
6898
+ const objectsWithoutScene = [];
6899
+ for (let i = 0; i < input.length; i++) {
6900
+ if (input[i] instanceof import_three17.Scene) {
6901
+ this.processScene(input[i]);
6902
+ } else {
6903
+ objectsWithoutScene.push(input[i]);
6904
+ }
6905
+ }
6906
+ if (objectsWithoutScene.length > 0) this.processObjects(objectsWithoutScene);
6907
+ for (let i = 0; i < this.skins.length; ++i) {
6908
+ this.processSkin(this.skins[i]);
6909
+ }
6910
+ for (let i = 0; i < options.animations.length; ++i) {
6911
+ this.processAnimation(options.animations[i], input[0]);
6912
+ }
6913
+ this._invokeAll(function(ext) {
6914
+ ext.afterParse && ext.afterParse(input);
6915
+ });
6916
+ }
6917
+ _invokeAll(func) {
6918
+ for (let i = 0, il = this.plugins.length; i < il; i++) {
6919
+ func(this.plugins[i]);
6920
+ }
6921
+ }
6922
+ };
6923
+ var GLTFLightExtension = class {
6924
+ constructor(writer) {
6925
+ this.writer = writer;
6926
+ this.name = "KHR_lights_punctual";
6927
+ }
6928
+ writeNode(light, nodeDef) {
6929
+ if (!light.isLight) return;
6930
+ if (!light.isDirectionalLight && !light.isPointLight && !light.isSpotLight) {
6931
+ console.warn("THREE.GLTFExporter: Only directional, point, and spot lights are supported.", light);
6932
+ return;
6933
+ }
6934
+ const writer = this.writer;
6935
+ const json = writer.json;
6936
+ const extensionsUsed = writer.extensionsUsed;
6937
+ const lightDef = {};
6938
+ if (light.name) lightDef.name = light.name;
6939
+ lightDef.color = light.color.toArray();
6940
+ lightDef.intensity = light.intensity;
6941
+ if (light.isDirectionalLight) {
6942
+ lightDef.type = "directional";
6943
+ } else if (light.isPointLight) {
6944
+ lightDef.type = "point";
6945
+ if (light.distance > 0) lightDef.range = light.distance;
6946
+ } else if (light.isSpotLight) {
6947
+ lightDef.type = "spot";
6948
+ if (light.distance > 0) lightDef.range = light.distance;
6949
+ lightDef.spot = {};
6950
+ lightDef.spot.innerConeAngle = (1 - light.penumbra) * light.angle;
6951
+ lightDef.spot.outerConeAngle = light.angle;
6952
+ }
6953
+ if (light.decay !== void 0 && light.decay !== 2) {
6954
+ console.warn("THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, and expects light.decay=2.");
6955
+ }
6956
+ if (light.target && (light.target.parent !== light || light.target.position.x !== 0 || light.target.position.y !== 0 || light.target.position.z !== -1)) {
6957
+ console.warn("THREE.GLTFExporter: Light direction may be lost. For best results, make light.target a child of the light with position 0,0,-1.");
6958
+ }
6959
+ if (!extensionsUsed[this.name]) {
6960
+ json.extensions = json.extensions || {};
6961
+ json.extensions[this.name] = { lights: [] };
6962
+ extensionsUsed[this.name] = true;
6963
+ }
6964
+ const lights = json.extensions[this.name].lights;
6965
+ lights.push(lightDef);
6966
+ nodeDef.extensions = nodeDef.extensions || {};
6967
+ nodeDef.extensions[this.name] = { light: lights.length - 1 };
6968
+ }
6969
+ };
6970
+ var GLTFMaterialsUnlitExtension = class {
6971
+ constructor(writer) {
6972
+ this.writer = writer;
6973
+ this.name = "KHR_materials_unlit";
6974
+ }
6975
+ writeMaterial(material, materialDef) {
6976
+ if (!material.isMeshBasicMaterial) return;
6977
+ const writer = this.writer;
6978
+ const extensionsUsed = writer.extensionsUsed;
6979
+ materialDef.extensions = materialDef.extensions || {};
6980
+ materialDef.extensions[this.name] = {};
6981
+ extensionsUsed[this.name] = true;
6982
+ materialDef.pbrMetallicRoughness.metallicFactor = 0;
6983
+ materialDef.pbrMetallicRoughness.roughnessFactor = 0.9;
6984
+ }
6985
+ };
6986
+ var GLTFMaterialsClearcoatExtension = class {
6987
+ constructor(writer) {
6988
+ this.writer = writer;
6989
+ this.name = "KHR_materials_clearcoat";
6990
+ }
6991
+ writeMaterial(material, materialDef) {
6992
+ if (!material.isMeshPhysicalMaterial || material.clearcoat === 0) return;
6993
+ const writer = this.writer;
6994
+ const extensionsUsed = writer.extensionsUsed;
6995
+ const extensionDef = {};
6996
+ extensionDef.clearcoatFactor = material.clearcoat;
6997
+ if (material.clearcoatMap) {
6998
+ const clearcoatMapDef = {
6999
+ index: writer.processTexture(material.clearcoatMap),
7000
+ texCoord: material.clearcoatMap.channel
7001
+ };
7002
+ writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
7003
+ extensionDef.clearcoatTexture = clearcoatMapDef;
7004
+ }
7005
+ extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
7006
+ if (material.clearcoatRoughnessMap) {
7007
+ const clearcoatRoughnessMapDef = {
7008
+ index: writer.processTexture(material.clearcoatRoughnessMap),
7009
+ texCoord: material.clearcoatRoughnessMap.channel
7010
+ };
7011
+ writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
7012
+ extensionDef.clearcoatRoughnessTexture = clearcoatRoughnessMapDef;
7013
+ }
7014
+ if (material.clearcoatNormalMap) {
7015
+ const clearcoatNormalMapDef = {
7016
+ index: writer.processTexture(material.clearcoatNormalMap),
7017
+ texCoord: material.clearcoatNormalMap.channel
7018
+ };
7019
+ writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
7020
+ extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
7021
+ }
7022
+ materialDef.extensions = materialDef.extensions || {};
7023
+ materialDef.extensions[this.name] = extensionDef;
7024
+ extensionsUsed[this.name] = true;
7025
+ }
7026
+ };
7027
+ var GLTFMaterialsIridescenceExtension = class {
7028
+ constructor(writer) {
7029
+ this.writer = writer;
7030
+ this.name = "KHR_materials_iridescence";
7031
+ }
7032
+ writeMaterial(material, materialDef) {
7033
+ if (!material.isMeshPhysicalMaterial || material.iridescence === 0) return;
7034
+ const writer = this.writer;
7035
+ const extensionsUsed = writer.extensionsUsed;
7036
+ const extensionDef = {};
7037
+ extensionDef.iridescenceFactor = material.iridescence;
7038
+ if (material.iridescenceMap) {
7039
+ const iridescenceMapDef = {
7040
+ index: writer.processTexture(material.iridescenceMap),
7041
+ texCoord: material.iridescenceMap.channel
7042
+ };
7043
+ writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
7044
+ extensionDef.iridescenceTexture = iridescenceMapDef;
7045
+ }
7046
+ extensionDef.iridescenceIor = material.iridescenceIOR;
7047
+ extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[0];
7048
+ extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
7049
+ if (material.iridescenceThicknessMap) {
7050
+ const iridescenceThicknessMapDef = {
7051
+ index: writer.processTexture(material.iridescenceThicknessMap),
7052
+ texCoord: material.iridescenceThicknessMap.channel
7053
+ };
7054
+ writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
7055
+ extensionDef.iridescenceThicknessTexture = iridescenceThicknessMapDef;
7056
+ }
7057
+ materialDef.extensions = materialDef.extensions || {};
7058
+ materialDef.extensions[this.name] = extensionDef;
7059
+ extensionsUsed[this.name] = true;
7060
+ }
7061
+ };
7062
+ var GLTFMaterialsTransmissionExtension = class {
7063
+ constructor(writer) {
7064
+ this.writer = writer;
7065
+ this.name = "KHR_materials_transmission";
7066
+ }
7067
+ writeMaterial(material, materialDef) {
7068
+ if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7069
+ const writer = this.writer;
7070
+ const extensionsUsed = writer.extensionsUsed;
7071
+ const extensionDef = {};
7072
+ extensionDef.transmissionFactor = material.transmission;
7073
+ if (material.transmissionMap) {
7074
+ const transmissionMapDef = {
7075
+ index: writer.processTexture(material.transmissionMap),
7076
+ texCoord: material.transmissionMap.channel
7077
+ };
7078
+ writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
7079
+ extensionDef.transmissionTexture = transmissionMapDef;
7080
+ }
7081
+ materialDef.extensions = materialDef.extensions || {};
7082
+ materialDef.extensions[this.name] = extensionDef;
7083
+ extensionsUsed[this.name] = true;
7084
+ }
7085
+ };
7086
+ var GLTFMaterialsVolumeExtension = class {
7087
+ constructor(writer) {
7088
+ this.writer = writer;
7089
+ this.name = "KHR_materials_volume";
7090
+ }
7091
+ writeMaterial(material, materialDef) {
7092
+ if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
7093
+ const writer = this.writer;
7094
+ const extensionsUsed = writer.extensionsUsed;
7095
+ const extensionDef = {};
7096
+ extensionDef.thicknessFactor = material.thickness;
7097
+ if (material.thicknessMap) {
7098
+ const thicknessMapDef = {
7099
+ index: writer.processTexture(material.thicknessMap),
7100
+ texCoord: material.thicknessMap.channel
7101
+ };
7102
+ writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
7103
+ extensionDef.thicknessTexture = thicknessMapDef;
7104
+ }
7105
+ extensionDef.attenuationDistance = material.attenuationDistance;
7106
+ extensionDef.attenuationColor = material.attenuationColor.toArray();
7107
+ materialDef.extensions = materialDef.extensions || {};
7108
+ materialDef.extensions[this.name] = extensionDef;
7109
+ extensionsUsed[this.name] = true;
7110
+ }
7111
+ };
7112
+ var GLTFMaterialsIorExtension = class {
7113
+ constructor(writer) {
7114
+ this.writer = writer;
7115
+ this.name = "KHR_materials_ior";
7116
+ }
7117
+ writeMaterial(material, materialDef) {
7118
+ if (!material.isMeshPhysicalMaterial || material.ior === 1.5) return;
7119
+ const writer = this.writer;
7120
+ const extensionsUsed = writer.extensionsUsed;
7121
+ const extensionDef = {};
7122
+ extensionDef.ior = material.ior;
7123
+ materialDef.extensions = materialDef.extensions || {};
7124
+ materialDef.extensions[this.name] = extensionDef;
7125
+ extensionsUsed[this.name] = true;
7126
+ }
7127
+ };
7128
+ var GLTFMaterialsSpecularExtension = class {
7129
+ constructor(writer) {
7130
+ this.writer = writer;
7131
+ this.name = "KHR_materials_specular";
7132
+ }
7133
+ writeMaterial(material, materialDef) {
7134
+ if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorTexture) return;
7135
+ const writer = this.writer;
7136
+ const extensionsUsed = writer.extensionsUsed;
7137
+ const extensionDef = {};
7138
+ if (material.specularIntensityMap) {
7139
+ const specularIntensityMapDef = {
7140
+ index: writer.processTexture(material.specularIntensityMap),
7141
+ texCoord: material.specularIntensityMap.channel
7142
+ };
7143
+ writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
7144
+ extensionDef.specularTexture = specularIntensityMapDef;
7145
+ }
7146
+ if (material.specularColorMap) {
7147
+ const specularColorMapDef = {
7148
+ index: writer.processTexture(material.specularColorMap),
7149
+ texCoord: material.specularColorMap.channel
7150
+ };
7151
+ writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
7152
+ extensionDef.specularColorTexture = specularColorMapDef;
7153
+ }
7154
+ extensionDef.specularFactor = material.specularIntensity;
7155
+ extensionDef.specularColorFactor = material.specularColor.toArray();
7156
+ materialDef.extensions = materialDef.extensions || {};
7157
+ materialDef.extensions[this.name] = extensionDef;
7158
+ extensionsUsed[this.name] = true;
7159
+ }
7160
+ };
7161
+ var GLTFMaterialsSheenExtension = class {
7162
+ constructor(writer) {
7163
+ this.writer = writer;
7164
+ this.name = "KHR_materials_sheen";
7165
+ }
7166
+ writeMaterial(material, materialDef) {
7167
+ if (!material.isMeshPhysicalMaterial || material.sheen == 0) return;
7168
+ const writer = this.writer;
7169
+ const extensionsUsed = writer.extensionsUsed;
7170
+ const extensionDef = {};
7171
+ if (material.sheenRoughnessMap) {
7172
+ const sheenRoughnessMapDef = {
7173
+ index: writer.processTexture(material.sheenRoughnessMap),
7174
+ texCoord: material.sheenRoughnessMap.channel
7175
+ };
7176
+ writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
7177
+ extensionDef.sheenRoughnessTexture = sheenRoughnessMapDef;
7178
+ }
7179
+ if (material.sheenColorMap) {
7180
+ const sheenColorMapDef = {
7181
+ index: writer.processTexture(material.sheenColorMap),
7182
+ texCoord: material.sheenColorMap.channel
7183
+ };
7184
+ writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
7185
+ extensionDef.sheenColorTexture = sheenColorMapDef;
7186
+ }
7187
+ extensionDef.sheenRoughnessFactor = material.sheenRoughness;
7188
+ extensionDef.sheenColorFactor = material.sheenColor.toArray();
7189
+ materialDef.extensions = materialDef.extensions || {};
7190
+ materialDef.extensions[this.name] = extensionDef;
7191
+ extensionsUsed[this.name] = true;
7192
+ }
7193
+ };
7194
+ var GLTFMaterialsAnisotropyExtension = class {
7195
+ constructor(writer) {
7196
+ this.writer = writer;
7197
+ this.name = "KHR_materials_anisotropy";
7198
+ }
7199
+ writeMaterial(material, materialDef) {
7200
+ if (!material.isMeshPhysicalMaterial || material.anisotropy == 0) return;
7201
+ const writer = this.writer;
7202
+ const extensionsUsed = writer.extensionsUsed;
7203
+ const extensionDef = {};
7204
+ if (material.anisotropyMap) {
7205
+ const anisotropyMapDef = { index: writer.processTexture(material.anisotropyMap) };
7206
+ writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
7207
+ extensionDef.anisotropyTexture = anisotropyMapDef;
7208
+ }
7209
+ extensionDef.anisotropyStrength = material.anisotropy;
7210
+ extensionDef.anisotropyRotation = material.anisotropyRotation;
7211
+ materialDef.extensions = materialDef.extensions || {};
7212
+ materialDef.extensions[this.name] = extensionDef;
7213
+ extensionsUsed[this.name] = true;
7214
+ }
7215
+ };
7216
+ var GLTFMaterialsEmissiveStrengthExtension = class {
7217
+ constructor(writer) {
7218
+ this.writer = writer;
7219
+ this.name = "KHR_materials_emissive_strength";
7220
+ }
7221
+ writeMaterial(material, materialDef) {
7222
+ if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1) return;
7223
+ const writer = this.writer;
7224
+ const extensionsUsed = writer.extensionsUsed;
7225
+ const extensionDef = {};
7226
+ extensionDef.emissiveStrength = material.emissiveIntensity;
7227
+ materialDef.extensions = materialDef.extensions || {};
7228
+ materialDef.extensions[this.name] = extensionDef;
7229
+ extensionsUsed[this.name] = true;
7230
+ }
7231
+ };
7232
+ var GLTFMeshGpuInstancing = class {
7233
+ constructor(writer) {
7234
+ this.writer = writer;
7235
+ this.name = "EXT_mesh_gpu_instancing";
7236
+ }
7237
+ writeNode(object, nodeDef) {
7238
+ if (!object.isInstancedMesh) return;
7239
+ const writer = this.writer;
7240
+ const mesh = object;
7241
+ const translationAttr = new Float32Array(mesh.count * 3);
7242
+ const rotationAttr = new Float32Array(mesh.count * 4);
7243
+ const scaleAttr = new Float32Array(mesh.count * 3);
7244
+ const matrix = new import_three17.Matrix4();
7245
+ const position = new import_three17.Vector3();
7246
+ const quaternion = new import_three17.Quaternion();
7247
+ const scale = new import_three17.Vector3();
7248
+ for (let i = 0; i < mesh.count; i++) {
7249
+ mesh.getMatrixAt(i, matrix);
7250
+ matrix.decompose(position, quaternion, scale);
7251
+ position.toArray(translationAttr, i * 3);
7252
+ quaternion.toArray(rotationAttr, i * 4);
7253
+ scale.toArray(scaleAttr, i * 3);
7254
+ }
7255
+ const attributes = {
7256
+ TRANSLATION: writer.processAccessor(new import_three17.BufferAttribute(translationAttr, 3)),
7257
+ ROTATION: writer.processAccessor(new import_three17.BufferAttribute(rotationAttr, 4)),
7258
+ SCALE: writer.processAccessor(new import_three17.BufferAttribute(scaleAttr, 3))
7259
+ };
7260
+ if (mesh.instanceColor)
7261
+ attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
7262
+ nodeDef.extensions = nodeDef.extensions || {};
7263
+ nodeDef.extensions[this.name] = { attributes };
7264
+ writer.extensionsUsed[this.name] = true;
7265
+ writer.extensionsRequired[this.name] = true;
7266
+ }
7267
+ };
7268
+ GLTFExporter.Utils = {
7269
+ insertKeyframe: function(track, time) {
7270
+ const tolerance = 1e-3;
7271
+ const valueSize = track.getValueSize();
7272
+ const times = new track.TimeBufferType(track.times.length + 1);
7273
+ const values = new track.ValueBufferType(track.values.length + valueSize);
7274
+ const interpolant = track.createInterpolant(new track.ValueBufferType(valueSize));
7275
+ let index;
7276
+ if (track.times.length === 0) {
7277
+ times[0] = time;
7278
+ for (let i = 0; i < valueSize; i++) {
7279
+ values[i] = 0;
7280
+ }
7281
+ index = 0;
7282
+ } else if (time < track.times[0]) {
7283
+ if (Math.abs(track.times[0] - time) < tolerance) return 0;
7284
+ times[0] = time;
7285
+ times.set(track.times, 1);
7286
+ values.set(interpolant.evaluate(time), 0);
7287
+ values.set(track.values, valueSize);
7288
+ index = 0;
7289
+ } else if (time > track.times[track.times.length - 1]) {
7290
+ if (Math.abs(track.times[track.times.length - 1] - time) < tolerance) {
7291
+ return track.times.length - 1;
7292
+ }
7293
+ times[times.length - 1] = time;
7294
+ times.set(track.times, 0);
7295
+ values.set(track.values, 0);
7296
+ values.set(interpolant.evaluate(time), track.values.length);
7297
+ index = times.length - 1;
7298
+ } else {
7299
+ for (let i = 0; i < track.times.length; i++) {
7300
+ if (Math.abs(track.times[i] - time) < tolerance) return i;
7301
+ if (track.times[i] < time && track.times[i + 1] > time) {
7302
+ times.set(track.times.slice(0, i + 1), 0);
7303
+ times[i + 1] = time;
7304
+ times.set(track.times.slice(i + 1), i + 2);
7305
+ values.set(track.values.slice(0, (i + 1) * valueSize), 0);
7306
+ values.set(interpolant.evaluate(time), (i + 1) * valueSize);
7307
+ values.set(track.values.slice((i + 1) * valueSize), (i + 2) * valueSize);
7308
+ index = i + 1;
7309
+ break;
7310
+ }
7311
+ }
7312
+ }
7313
+ track.times = times;
7314
+ track.values = values;
7315
+ return index;
7316
+ },
7317
+ mergeMorphTargetTracks: function(clip, root) {
7318
+ const tracks = [];
7319
+ const mergedTracks = {};
7320
+ const sourceTracks = clip.tracks;
7321
+ for (let i = 0; i < sourceTracks.length; ++i) {
7322
+ let sourceTrack = sourceTracks[i];
7323
+ const sourceTrackBinding = import_three17.PropertyBinding.parseTrackName(sourceTrack.name);
7324
+ const sourceTrackNode = import_three17.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
7325
+ if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
7326
+ tracks.push(sourceTrack);
7327
+ continue;
7328
+ }
7329
+ if (sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete && sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear) {
7330
+ if (sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
7331
+ throw new Error("THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.");
7332
+ }
7333
+ console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
7334
+ sourceTrack = sourceTrack.clone();
7335
+ sourceTrack.setInterpolation(import_three17.InterpolateLinear);
7336
+ }
7337
+ const targetCount = sourceTrackNode.morphTargetInfluences.length;
7338
+ const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
7339
+ if (targetIndex === void 0) {
7340
+ throw new Error("THREE.GLTFExporter: Morph target name not found: " + sourceTrackBinding.propertyIndex);
7341
+ }
7342
+ let mergedTrack;
7343
+ if (mergedTracks[sourceTrackNode.uuid] === void 0) {
7344
+ mergedTrack = sourceTrack.clone();
7345
+ const values = new mergedTrack.ValueBufferType(targetCount * mergedTrack.times.length);
7346
+ for (let j = 0; j < mergedTrack.times.length; j++) {
7347
+ values[j * targetCount + targetIndex] = mergedTrack.values[j];
7348
+ }
7349
+ mergedTrack.name = (sourceTrackBinding.nodeName || "") + ".morphTargetInfluences";
7350
+ mergedTrack.values = values;
7351
+ mergedTracks[sourceTrackNode.uuid] = mergedTrack;
7352
+ tracks.push(mergedTrack);
7353
+ continue;
7354
+ }
7355
+ const sourceInterpolant = sourceTrack.createInterpolant(new sourceTrack.ValueBufferType(1));
7356
+ mergedTrack = mergedTracks[sourceTrackNode.uuid];
7357
+ for (let j = 0; j < mergedTrack.times.length; j++) {
7358
+ mergedTrack.values[j * targetCount + targetIndex] = sourceInterpolant.evaluate(mergedTrack.times[j]);
7359
+ }
7360
+ for (let j = 0; j < sourceTrack.times.length; j++) {
7361
+ const keyframeIndex = this.insertKeyframe(mergedTrack, sourceTrack.times[j]);
7362
+ mergedTrack.values[keyframeIndex * targetCount + targetIndex] = sourceTrack.values[j];
7363
+ }
7364
+ }
7365
+ clip.tracks = tracks;
7366
+ return clip;
7367
+ }
7368
+ };
7369
+
7370
+ // src/export/SceneExporter.ts
7371
+ init_MineRenderError();
7372
+ init_DisplayTransforms();
7373
+ init_CanvasCompat();
7374
+ var SceneExporter = class {
7375
+ /** Returns OBJ geometry with normals and UVs; material files and textures are not included. */
7376
+ static toObj(root) {
7377
+ const snapshot = createSnapshot(root, false);
7378
+ try {
7379
+ return new OBJExporter().parse(snapshot.scene);
7380
+ } finally {
7381
+ snapshot.dispose();
7382
+ }
7383
+ }
7384
+ /** Returns PLY geometry with vertex colors and UVs; texture images are not included. */
7385
+ static toPLY(root, options) {
7386
+ const snapshot = createSnapshot(root, false, true);
7387
+ try {
7388
+ const result = new PLYExporter().parse(snapshot.scene, void 0, options);
7389
+ if (result === null) throw new MineRenderError("The scene could not be exported as PLY");
7390
+ return result;
7391
+ } finally {
7392
+ snapshot.dispose();
7393
+ }
7394
+ }
7395
+ /**
7396
+ * Exports a static glTF/GLB snapshot in a browser. Atlas textures and vertex tints are retained;
7397
+ * MineRender's custom directional lighting is not baked into the exported materials.
7398
+ */
7399
+ static async toGLTF(root, options = {}) {
7400
+ if (typeof document === "undefined" || typeof FileReader === "undefined") {
7401
+ throw new MineRenderError("glTF export requires a browser with canvas and FileReader support");
7402
+ }
7403
+ if (options.maxTextureSize !== void 0 && !(options.maxTextureSize >= 1)) {
7404
+ throw new MineRenderError("maxTextureSize must be at least 1 pixel");
7405
+ }
7406
+ const snapshot = createSnapshot(root, true);
7407
+ try {
7408
+ return await new GLTFExporter().parseAsync(snapshot.scene, {
7409
+ binary: options.binary ?? false,
7410
+ maxTextureSize: options.maxTextureSize ?? Infinity
7411
+ });
7412
+ } finally {
7413
+ snapshot.dispose();
7414
+ }
7415
+ }
7416
+ };
7417
+ function localMatrix(object) {
7418
+ return object.matrixAutoUpdate ? new import_three18.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
7419
+ }
7420
+ function createSnapshot(root, gltf, bakeColors = false) {
7421
+ const scene = new import_three18.Scene();
7422
+ const geometries = [];
7423
+ const materials = [];
7424
+ const textures = [];
7425
+ const textureCopies = /* @__PURE__ */ new Map();
7426
+ const dispose = () => {
7427
+ for (const geometry of geometries) geometry.dispose();
7428
+ for (const material of materials) material.dispose();
7429
+ for (const texture of textures) texture.dispose();
7430
+ };
7431
+ const copyMaterial = (source, geometry) => {
7432
+ let material;
7433
+ const shader = source;
7434
+ if (shader.isShaderMaterial && gltf) {
7435
+ const uniforms = shader.uniforms;
7436
+ if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
7437
+ throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
7438
+ }
7439
+ material = new import_three18.MeshBasicMaterial({
7440
+ map: uniforms.map.value,
7441
+ vertexColors: source.vertexColors,
7442
+ transparent: source.transparent,
7443
+ side: source.side,
7444
+ alphaTest: 0.01,
7445
+ depthWrite: source.depthWrite
7446
+ });
7447
+ material.name = source.name;
7448
+ } else if (shader.isShaderMaterial) {
7449
+ material = new import_three18.MeshBasicMaterial({ vertexColors: source.vertexColors });
7450
+ material.name = source.name;
7451
+ } else {
7452
+ const copySource = Object.create(source);
7453
+ copySource.userData = {};
7454
+ material = source.clone.call(copySource);
7455
+ }
7456
+ materials.push(material);
7457
+ if (gltf) {
7458
+ selectAlphaMode(material, geometry);
7459
+ for (const [key, value] of Object.entries(material)) {
7460
+ if (value?.isDataTexture) {
7461
+ let texture = textureCopies.get(value);
7462
+ if (!texture) {
7463
+ texture = copyDataTexture(value);
7464
+ textureCopies.set(value, texture);
7465
+ textures.push(texture);
7466
+ }
7467
+ material[key] = texture;
7468
+ }
7469
+ }
7470
+ }
7471
+ return material;
7472
+ };
7473
+ const addMesh = (mesh, world, instanceColor) => {
7474
+ if (world.determinant() === 0 || !mesh.geometry.getAttribute("position")) return;
7475
+ const source = mesh.geometry;
7476
+ const count = source.index?.count ?? source.getAttribute("position").count;
7477
+ const groups = Array.isArray(mesh.material) ? source.groups : [{ start: 0, count, materialIndex: 0 }];
7478
+ for (const group of groups) {
7479
+ const sourceMaterial = Array.isArray(mesh.material) ? mesh.material[group.materialIndex ?? 0] : mesh.material;
7480
+ if (!sourceMaterial?.visible) continue;
7481
+ const start = Math.max(group.start, source.drawRange.start);
7482
+ const end = Math.min(count, group.start + group.count, source.drawRange.start + source.drawRange.count);
7483
+ const indices = [];
7484
+ for (let i = start; i + 2 < end; i += 3) {
7485
+ for (let corner = 0; corner < 3; corner++) indices.push(source.index?.getX(i + corner) ?? i + corner);
7486
+ }
7487
+ if (!indices.length) continue;
7488
+ let geometry = source.clone();
7489
+ geometry.setIndex(indices);
7490
+ if (new Set(indices).size < geometry.getAttribute("position").count) {
7491
+ const compact = geometry.toNonIndexed();
7492
+ geometry.dispose();
7493
+ geometry = compact;
7494
+ }
7495
+ geometries.push(geometry);
7496
+ geometry.userData = {};
7497
+ geometry.clearGroups();
7498
+ geometry.setDrawRange(0, Infinity);
7499
+ DisplayTransforms.apply(geometry, world);
7500
+ const material = copyMaterial(sourceMaterial, geometry);
7501
+ if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
7502
+ if (bakeColors || instanceColor) {
7503
+ const tint = (material.color ?? new import_three18.Color()).clone();
7504
+ if (instanceColor) tint.multiply(instanceColor);
7505
+ if (bakeColors) {
7506
+ const original = geometry.getAttribute("color");
7507
+ const colors = new import_three18.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
7508
+ for (let i = 0; i < colors.count; i++) {
7509
+ colors.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
7510
+ }
7511
+ geometry.setAttribute("color", colors);
7512
+ } else if (material.color) {
7513
+ material.color.copy(tint);
7514
+ }
7515
+ }
7516
+ const copy = new import_three18.Mesh(geometry, material);
7517
+ copy.name = mesh.name;
7518
+ copy.renderOrder = mesh.renderOrder;
7519
+ scene.add(copy);
7520
+ }
7521
+ };
7522
+ const visit = (object, parentWorld) => {
7523
+ if (!object.visible) return;
7524
+ const world = parentWorld.clone().multiply(localMatrix(object));
7525
+ const mesh = object;
7526
+ if (mesh.isMesh) {
7527
+ const instanced = mesh;
7528
+ if (instanced.isInstancedMesh) {
7529
+ for (let i = 0; i < instanced.count; i++) {
7530
+ const matrix = new import_three18.Matrix4();
7531
+ instanced.getMatrixAt(i, matrix);
7532
+ const color = instanced.instanceColor ? new import_three18.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
7533
+ addMesh(mesh, world.clone().multiply(matrix), color);
7534
+ }
7535
+ } else {
7536
+ addMesh(mesh, world);
7537
+ }
7538
+ }
7539
+ for (const child of object.children) visit(child, world);
7540
+ };
7541
+ try {
7542
+ const ancestors = [];
7543
+ for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
7544
+ const world = new import_three18.Matrix4();
7545
+ for (const ancestor of ancestors) {
7546
+ if (!ancestor.visible) return { scene, dispose };
7547
+ world.multiply(localMatrix(ancestor));
7548
+ }
7549
+ visit(root, world);
7550
+ return { scene, dispose };
7551
+ } catch (error) {
7552
+ dispose();
7553
+ throw error;
7554
+ }
7555
+ }
7556
+ function selectAlphaMode(material, geometry) {
7557
+ const texture = material.map;
7558
+ if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !== import_three18.RGBAFormat || texture.type !== import_three18.UnsignedByteType || texture.wrapS !== import_three18.ClampToEdgeWrapping || texture.wrapT !== import_three18.ClampToEdgeWrapping || texture.magFilter !== import_three18.NearestFilter || texture.minFilter !== import_three18.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;
7559
+ const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
7560
+ const colors = geometry.getAttribute("color");
7561
+ if (!uv || material.vertexColors && colors?.itemSize === 4) return;
7562
+ const { data, width, height } = texture.image;
7563
+ if (!data || width < 1 || height < 1 || data.length < width * height * 4) return;
7564
+ const count = geometry.index?.count ?? uv.count;
7565
+ let holes = false;
7566
+ for (let i = 0; i + 2 < count; i += 3) {
7567
+ let minU = Infinity, maxU = -Infinity, minV = Infinity, maxV = -Infinity;
7568
+ for (let corner = 0; corner < 3; corner++) {
7569
+ const index = geometry.index?.getX(i + corner) ?? i + corner;
7570
+ const u = uv.getX(index), v = texture.flipY ? 1 - uv.getY(index) : uv.getY(index);
7571
+ if (!Number.isFinite(u) || !Number.isFinite(v)) return;
7572
+ minU = Math.min(minU, u);
7573
+ maxU = Math.max(maxU, u);
7574
+ minV = Math.min(minV, v);
7575
+ maxV = Math.max(maxV, v);
7576
+ }
7577
+ const minX = Math.max(0, Math.min(width - 1, Math.floor(minU * width)));
7578
+ const maxX = Math.max(minX, Math.min(width - 1, Math.ceil(maxU * width) - 1));
7579
+ const minY = Math.max(0, Math.min(height - 1, Math.floor(minV * height)));
7580
+ const maxY = Math.max(minY, Math.min(height - 1, Math.ceil(maxV * height) - 1));
7581
+ for (let y = minY; y <= maxY; y++) {
7582
+ for (let x = minX; x <= maxX; x++) {
7583
+ const alpha = data[(y * width + x) * 4 + 3];
7584
+ if (alpha === 255) continue;
7585
+ if (alpha !== 0 && alpha / 255 >= material.alphaTest) return;
7586
+ holes = true;
7587
+ }
7588
+ }
7589
+ }
7590
+ material.transparent = false;
7591
+ if (holes && material.alphaTest === 0) material.alphaTest = 1 / 255;
7592
+ }
7593
+ function copyDataTexture(source) {
7594
+ const image = source.image;
7595
+ if (source.format !== import_three18.RGBAFormat || source.type !== import_three18.UnsignedByteType) {
7596
+ throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
7597
+ }
7598
+ const canvas = createCanvas(image.width, image.height);
7599
+ const context = canvas.getContext("2d");
7600
+ if (!context) throw new MineRenderError("glTF export could not create a 2D canvas context");
7601
+ const pixels = context.createImageData(image.width, image.height);
7602
+ pixels.data.set(image.data);
7603
+ context.putImageData(pixels, 0, 0);
7604
+ const copySource = Object.create(source);
7605
+ copySource.userData = {};
7606
+ copySource.source = new import_three18.Source(canvas);
7607
+ return new import_three18.Texture().copy(copySource);
7608
+ }
7609
+
5073
7610
  // src/gui/GuiHelper.ts
5074
7611
  var GuiHelper = class {
5075
7612
  static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
@@ -5079,7 +7616,7 @@ var GuiHelper = class {
5079
7616
  };
5080
7617
 
5081
7618
  // src/gui/scene/GuiObject.ts
5082
- var import_three14 = require("three");
7619
+ var import_three19 = require("three");
5083
7620
  init_AssetKey();
5084
7621
  init_ModelTextures();
5085
7622
  init_Caching();
@@ -5091,7 +7628,7 @@ var GuiObject = class extends SceneObject {
5091
7628
  this.textureLayers = textureLayers;
5092
7629
  this.isGuiObject = true;
5093
7630
  /** Local bounds in GUI pixels, with y growing down from the origin. */
5094
- this.bounds = new import_three14.Box2();
7631
+ this.bounds = new import_three19.Box2();
5095
7632
  this.geometries = /* @__PURE__ */ new Set();
5096
7633
  this.ownedMaterials = /* @__PURE__ */ new Set();
5097
7634
  this.initialized = false;
@@ -5106,7 +7643,7 @@ var GuiObject = class extends SceneObject {
5106
7643
  const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
5107
7644
  const [width, height] = layer.size ?? [cropWidth, cropHeight];
5108
7645
  const [x, y] = layer.position ?? [0, 0];
5109
- const geometry = new import_three14.PlaneGeometry(width, height);
7646
+ const geometry = new import_three19.PlaneGeometry(width, height);
5110
7647
  this.geometries.add(geometry);
5111
7648
  const uv = geometry.getAttribute("uv");
5112
7649
  for (let i = 0; i < uv.count; i++) {
@@ -5116,13 +7653,13 @@ var GuiObject = class extends SceneObject {
5116
7653
  1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
5117
7654
  );
5118
7655
  }
5119
- const mesh = new import_three14.Mesh(geometry, material);
7656
+ const mesh = new import_three19.Mesh(geometry, material);
5120
7657
  mesh.name = `mesh:${layer.name ?? index}`;
5121
7658
  mesh.position.set(x + width / 2, -y - height / 2, 0);
5122
7659
  mesh.renderOrder = index;
5123
7660
  this.add(mesh);
5124
- this.bounds.expandByPoint(new import_three14.Vector2(x, y));
5125
- this.bounds.expandByPoint(new import_three14.Vector2(x + width, y + height));
7661
+ this.bounds.expandByPoint(new import_three19.Vector2(x, y));
7662
+ this.bounds.expandByPoint(new import_three19.Vector2(x + width, y + height));
5126
7663
  }
5127
7664
  this.initialized = true;
5128
7665
  this.notifyDirty();
@@ -5169,7 +7706,7 @@ function isGuiObject(obj) {
5169
7706
  init_image();
5170
7707
 
5171
7708
  // src/inspector/SceneInspector.ts
5172
- var import_three15 = require("three");
7709
+ var import_three20 = require("three");
5173
7710
  init_SceneObject();
5174
7711
  init_util();
5175
7712
  init_log();
@@ -5179,11 +7716,11 @@ var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
5179
7716
  var SceneInspector = class {
5180
7717
  constructor(renderer) {
5181
7718
  this.renderer = renderer;
5182
- this.mouse = new import_three15.Vector2();
7719
+ this.mouse = new import_three20.Vector2();
5183
7720
  this.listeners = new AbortController();
5184
7721
  this.objectInfoContainer = document.createElement("div");
5185
7722
  this.objectControlsContainer = document.createElement("div");
5186
- this.raycaster = new import_three15.Raycaster();
7723
+ this.raycaster = new import_three20.Raycaster();
5187
7724
  this.init();
5188
7725
  }
5189
7726
  init() {
@@ -5599,7 +8136,7 @@ init_ModelGenerator();
5599
8136
  init_ModelMerger();
5600
8137
 
5601
8138
  // src/model/block/BlockStateResolver.ts
5602
- var import_three18 = require("three");
8139
+ var import_three23 = require("three");
5603
8140
  init_BlockStates();
5604
8141
  init_MineRenderError();
5605
8142
  init_util();
@@ -5677,7 +8214,7 @@ var BlockStateResolver = class {
5677
8214
  return variants[variants.length - 1];
5678
8215
  }
5679
8216
  static rotation(variant) {
5680
- const rotation = new import_three18.Euler();
8217
+ const rotation = new import_three23.Euler();
5681
8218
  if (typeof variant.x !== "undefined") {
5682
8219
  rotation.x = toRadians(clampRotationDegrees(variant.x));
5683
8220
  }
@@ -5784,7 +8321,7 @@ init_SceneObject();
5784
8321
  init_ModelObject();
5785
8322
  init_Models();
5786
8323
  var import_ts_deepmerge6 = __toESM(require_dist());
5787
- var import_three23 = require("three");
8324
+ var import_three28 = require("three");
5788
8325
  init_MineRenderError();
5789
8326
  init_InstanceReference();
5790
8327
  init_AssetKey();
@@ -5848,12 +8385,12 @@ var _BlockObject = class _BlockObject extends SceneObject {
5848
8385
  getModelCullMask(model, worldMask) {
5849
8386
  const object = isInstanceReference(model) ? model.instanceable : model;
5850
8387
  if (object.options.displayPosition) return 0;
5851
- const position = new import_three23.Vector3();
5852
- const rotation = new import_three23.Quaternion();
5853
- const scale = new import_three23.Vector3();
8388
+ const position = new import_three28.Vector3();
8389
+ const rotation = new import_three28.Quaternion();
8390
+ const scale = new import_three28.Vector3();
5854
8391
  this.getModelMatrix(model).decompose(position, rotation, scale);
5855
- if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three23.Vector3(1, 1, 1)) > 1e-10) return 0;
5856
- return ModelCulling.toLocalMask(worldMask, new import_three23.Euler().setFromQuaternion(rotation));
8392
+ if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three28.Vector3(1, 1, 1)) > 1e-10) return 0;
8393
+ return ModelCulling.toLocalMask(worldMask, new import_three28.Euler().setFromQuaternion(rotation));
5857
8394
  }
5858
8395
  async setCullMask(worldMask) {
5859
8396
  worldMask &= 63;
@@ -5915,7 +8452,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
5915
8452
  () => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
5916
8453
  );
5917
8454
  const previous = this._fluidModel;
5918
- const matrix = previous ? this.getModelMatrix(previous) : new import_three23.Matrix4().makeTranslation(...this.position.toArray());
8455
+ const matrix = previous ? this.getModelMatrix(previous) : new import_three28.Matrix4().makeTranslation(...this.position.toArray());
5919
8456
  if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
5920
8457
  else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
5921
8458
  this._models = this._models.filter((model) => model !== previous);
@@ -6046,7 +8583,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
6046
8583
  setPositionRotationScaleAt(index, position, rotation, scale) {
6047
8584
  super.setPositionRotationScaleAt(index, position, rotation, scale);
6048
8585
  }
6049
- getMatrixAt(index, matrix = new import_three23.Matrix4()) {
8586
+ getMatrixAt(index, matrix = new import_three28.Matrix4()) {
6050
8587
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
6051
8588
  const child = this._models[0];
6052
8589
  if (child && isModelObject(child)) {
@@ -7916,7 +10453,7 @@ init_ModelObject();
7916
10453
  init_nbt();
7917
10454
 
7918
10455
  // src/renderer/MineRenderScene.ts
7919
- var import_three25 = require("three");
10456
+ var import_three30 = require("three");
7920
10457
  init_SceneObject();
7921
10458
  var import_ts_deepmerge8 = __toESM(require_dist());
7922
10459
  init_ModelObject();
@@ -8649,7 +11186,7 @@ var import_ts_deepmerge7 = __toESM(require_dist());
8649
11186
  init_util();
8650
11187
 
8651
11188
  // src/skin/SkinTextures.ts
8652
- var import_three24 = require("three");
11189
+ var import_three29 = require("three");
8653
11190
  init_Caching();
8654
11191
  init_CacheKey();
8655
11192
  init_MineRenderError();
@@ -8733,11 +11270,11 @@ var SkinTextures = class {
8733
11270
  });
8734
11271
  }
8735
11272
  static createMaterial(pixels, width, height, transparent = true) {
8736
- const texture = Textures.initTextureProps(new import_three24.DataTexture(pixels, width, height));
8737
- texture.colorSpace = import_three24.SRGBColorSpace;
11273
+ const texture = Textures.initTextureProps(new import_three29.DataTexture(pixels, width, height));
11274
+ texture.colorSpace = import_three29.SRGBColorSpace;
8738
11275
  texture.flipY = true;
8739
11276
  texture.needsUpdate = true;
8740
- return new import_three24.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three24.DoubleSide : import_three24.FrontSide, alphaTest: transparent ? 0.1 : 0 });
11277
+ return new import_three29.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three29.DoubleSide : import_three29.FrontSide, alphaTest: transparent ? 0.1 : 0 });
8741
11278
  }
8742
11279
  static isSlim(image, scale) {
8743
11280
  for (const [x, y] of [[46, 52], [54, 20]]) {
@@ -8964,7 +11501,7 @@ var SkinObject = class extends SceneObject {
8964
11501
  };
8965
11502
 
8966
11503
  // src/renderer/MineRenderScene.ts
8967
- var _MineRenderScene = class _MineRenderScene extends import_three25.Scene {
11504
+ var _MineRenderScene = class _MineRenderScene extends import_three30.Scene {
8968
11505
  constructor(options) {
8969
11506
  super();
8970
11507
  this.isMineRenderScene = true;
@@ -9096,7 +11633,7 @@ function isMineRenderScene(obj) {
9096
11633
  }
9097
11634
 
9098
11635
  // src/renderer/Renderer.ts
9099
- var import_three27 = require("three");
11636
+ var import_three32 = require("three");
9100
11637
  var import_ts_deepmerge9 = __toESM(require_dist());
9101
11638
  var import_stats = __toESM(require("stats.js"));
9102
11639
  var import_postprocessing = require("postprocessing");
@@ -9104,11 +11641,11 @@ init_util();
9104
11641
  init_three();
9105
11642
 
9106
11643
  // src/three/OrbitControls.js
9107
- var import_three26 = require("three");
11644
+ var import_three31 = require("three");
9108
11645
  var _changeEvent = { type: "change" };
9109
11646
  var _startEvent = { type: "start" };
9110
11647
  var _endEvent = { type: "end" };
9111
- var OrbitControls = class extends import_three26.EventDispatcher {
11648
+ var OrbitControls = class extends import_three31.EventDispatcher {
9112
11649
  constructor(object, domElement) {
9113
11650
  super();
9114
11651
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
@@ -9117,7 +11654,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9117
11654
  this.domElement = domElement;
9118
11655
  this.domElement.style.touchAction = "none";
9119
11656
  this.enabled = true;
9120
- this.target = new import_three26.Vector3();
11657
+ this.target = new import_three31.Vector3();
9121
11658
  this.minDistance = 0;
9122
11659
  this.maxDistance = Infinity;
9123
11660
  this.minZoom = 0;
@@ -9139,8 +11676,8 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9139
11676
  this.autoRotate = false;
9140
11677
  this.autoRotateSpeed = 2;
9141
11678
  this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
9142
- this.mouseButtons = { LEFT: import_three26.MOUSE.ROTATE, MIDDLE: import_three26.MOUSE.DOLLY, RIGHT: import_three26.MOUSE.PAN };
9143
- this.touches = { ONE: import_three26.TOUCH.ROTATE, TWO: import_three26.TOUCH.DOLLY_PAN };
11679
+ this.mouseButtons = { LEFT: import_three31.MOUSE.ROTATE, MIDDLE: import_three31.MOUSE.DOLLY, RIGHT: import_three31.MOUSE.PAN };
11680
+ this.touches = { ONE: import_three31.TOUCH.ROTATE, TWO: import_three31.TOUCH.DOLLY_PAN };
9144
11681
  this.target0 = this.target.clone();
9145
11682
  this.position0 = this.object.position.clone();
9146
11683
  this.zoom0 = this.object.zoom;
@@ -9169,11 +11706,11 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9169
11706
  state = STATE.NONE;
9170
11707
  };
9171
11708
  this.update = function() {
9172
- const offset = new import_three26.Vector3();
9173
- const quat = new import_three26.Quaternion().setFromUnitVectors(object.up, new import_three26.Vector3(0, 1, 0));
11709
+ const offset = new import_three31.Vector3();
11710
+ const quat = new import_three31.Quaternion().setFromUnitVectors(object.up, new import_three31.Vector3(0, 1, 0));
9174
11711
  const quatInverse = quat.clone().invert();
9175
- const lastPosition = new import_three26.Vector3();
9176
- const lastQuaternion = new import_three26.Quaternion();
11712
+ const lastPosition = new import_three31.Vector3();
11713
+ const lastQuaternion = new import_three31.Quaternion();
9177
11714
  const twoPI = 2 * Math.PI;
9178
11715
  return function update() {
9179
11716
  const position = scope.object.position;
@@ -9259,20 +11796,20 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9259
11796
  };
9260
11797
  let state = STATE.NONE;
9261
11798
  const EPS = 1e-6;
9262
- const spherical = new import_three26.Spherical();
9263
- const sphericalDelta = new import_three26.Spherical();
11799
+ const spherical = new import_three31.Spherical();
11800
+ const sphericalDelta = new import_three31.Spherical();
9264
11801
  let scale = 1;
9265
- const panOffset = new import_three26.Vector3();
11802
+ const panOffset = new import_three31.Vector3();
9266
11803
  let zoomChanged = false;
9267
- const rotateStart = new import_three26.Vector2();
9268
- const rotateEnd = new import_three26.Vector2();
9269
- const rotateDelta = new import_three26.Vector2();
9270
- const panStart = new import_three26.Vector2();
9271
- const panEnd = new import_three26.Vector2();
9272
- const panDelta = new import_three26.Vector2();
9273
- const dollyStart = new import_three26.Vector2();
9274
- const dollyEnd = new import_three26.Vector2();
9275
- const dollyDelta = new import_three26.Vector2();
11804
+ const rotateStart = new import_three31.Vector2();
11805
+ const rotateEnd = new import_three31.Vector2();
11806
+ const rotateDelta = new import_three31.Vector2();
11807
+ const panStart = new import_three31.Vector2();
11808
+ const panEnd = new import_three31.Vector2();
11809
+ const panDelta = new import_three31.Vector2();
11810
+ const dollyStart = new import_three31.Vector2();
11811
+ const dollyEnd = new import_three31.Vector2();
11812
+ const dollyDelta = new import_three31.Vector2();
9276
11813
  const pointers = [];
9277
11814
  const pointerPositions = {};
9278
11815
  function getAutoRotationAngle() {
@@ -9288,7 +11825,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9288
11825
  sphericalDelta.phi -= angle;
9289
11826
  }
9290
11827
  const panLeft = function() {
9291
- const v = new import_three26.Vector3();
11828
+ const v = new import_three31.Vector3();
9292
11829
  return function panLeft2(distance, objectMatrix) {
9293
11830
  v.setFromMatrixColumn(objectMatrix, 0);
9294
11831
  v.multiplyScalar(-distance);
@@ -9296,7 +11833,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9296
11833
  };
9297
11834
  }();
9298
11835
  const panUp = function() {
9299
- const v = new import_three26.Vector3();
11836
+ const v = new import_three31.Vector3();
9300
11837
  return function panUp2(distance, objectMatrix) {
9301
11838
  if (scope.screenSpacePanning === true) {
9302
11839
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -9309,7 +11846,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9309
11846
  };
9310
11847
  }();
9311
11848
  const pan = function() {
9312
- const offset = new import_three26.Vector3();
11849
+ const offset = new import_three31.Vector3();
9313
11850
  return function pan2(deltaX, deltaY) {
9314
11851
  const element = scope.domElement;
9315
11852
  if (scope.object.isPerspectiveCamera) {
@@ -9558,12 +12095,12 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9558
12095
  mouseAction = -1;
9559
12096
  }
9560
12097
  switch (mouseAction) {
9561
- case import_three26.MOUSE.DOLLY:
12098
+ case import_three31.MOUSE.DOLLY:
9562
12099
  if (scope.enableZoom === false) return;
9563
12100
  handleMouseDownDolly(event);
9564
12101
  state = STATE.DOLLY;
9565
12102
  break;
9566
- case import_three26.MOUSE.ROTATE:
12103
+ case import_three31.MOUSE.ROTATE:
9567
12104
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
9568
12105
  if (scope.enablePan === false) return;
9569
12106
  handleMouseDownPan(event);
@@ -9574,7 +12111,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9574
12111
  state = STATE.ROTATE;
9575
12112
  }
9576
12113
  break;
9577
- case import_three26.MOUSE.PAN:
12114
+ case import_three31.MOUSE.PAN:
9578
12115
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
9579
12116
  if (scope.enableRotate === false) return;
9580
12117
  handleMouseDownRotate(event);
@@ -9630,12 +12167,12 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9630
12167
  switch (pointers.length) {
9631
12168
  case 1:
9632
12169
  switch (scope.touches.ONE) {
9633
- case import_three26.TOUCH.ROTATE:
12170
+ case import_three31.TOUCH.ROTATE:
9634
12171
  if (scope.enableRotate === false) return;
9635
12172
  handleTouchStartRotate();
9636
12173
  state = STATE.TOUCH_ROTATE;
9637
12174
  break;
9638
- case import_three26.TOUCH.PAN:
12175
+ case import_three31.TOUCH.PAN:
9639
12176
  if (scope.enablePan === false) return;
9640
12177
  handleTouchStartPan();
9641
12178
  state = STATE.TOUCH_PAN;
@@ -9646,12 +12183,12 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9646
12183
  break;
9647
12184
  case 2:
9648
12185
  switch (scope.touches.TWO) {
9649
- case import_three26.TOUCH.DOLLY_PAN:
12186
+ case import_three31.TOUCH.DOLLY_PAN:
9650
12187
  if (scope.enableZoom === false && scope.enablePan === false) return;
9651
12188
  handleTouchStartDollyPan();
9652
12189
  state = STATE.TOUCH_DOLLY_PAN;
9653
12190
  break;
9654
- case import_three26.TOUCH.DOLLY_ROTATE:
12191
+ case import_three31.TOUCH.DOLLY_ROTATE:
9655
12192
  if (scope.enableZoom === false && scope.enableRotate === false) return;
9656
12193
  handleTouchStartDollyRotate();
9657
12194
  state = STATE.TOUCH_DOLLY_ROTATE;
@@ -9718,7 +12255,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
9718
12255
  function trackPointer(event) {
9719
12256
  let position = pointerPositions[event.pointerId];
9720
12257
  if (position === void 0) {
9721
- position = new import_three26.Vector2();
12258
+ position = new import_three31.Vector2();
9722
12259
  pointerPositions[event.pointerId] = position;
9723
12260
  }
9724
12261
  position.set(event.pageX, event.pageY);
@@ -9738,10 +12275,10 @@ var MapControls = class extends OrbitControls {
9738
12275
  constructor(object, domElement) {
9739
12276
  super(object, domElement);
9740
12277
  this.screenSpacePanning = false;
9741
- this.mouseButtons.LEFT = import_three26.MOUSE.PAN;
9742
- this.mouseButtons.RIGHT = import_three26.MOUSE.ROTATE;
9743
- this.touches.ONE = import_three26.TOUCH.PAN;
9744
- this.touches.TWO = import_three26.TOUCH.DOLLY_ROTATE;
12278
+ this.mouseButtons.LEFT = import_three31.MOUSE.PAN;
12279
+ this.mouseButtons.RIGHT = import_three31.MOUSE.ROTATE;
12280
+ this.touches.ONE = import_three31.TOUCH.PAN;
12281
+ this.touches.TWO = import_three31.TOUCH.DOLLY_ROTATE;
9745
12282
  }
9746
12283
  };
9747
12284
 
@@ -9782,14 +12319,14 @@ var _Renderer = class _Renderer {
9782
12319
  switch (this.options.camera.type) {
9783
12320
  case "perspective":
9784
12321
  default:
9785
- return new import_three27.PerspectiveCamera(
12322
+ return new import_three32.PerspectiveCamera(
9786
12323
  this.options.camera.perspective.fov,
9787
12324
  this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
9788
12325
  this.options.camera.near,
9789
12326
  this.options.camera.far
9790
12327
  );
9791
12328
  case "orthographic":
9792
- return new import_three27.OrthographicCamera(
12329
+ return new import_three32.OrthographicCamera(
9793
12330
  this.options.camera.orthographic.left ?? this.viewWidth / -2,
9794
12331
  this.options.camera.orthographic.right ?? this.viewWidth / 2,
9795
12332
  this.options.camera.orthographic.top ?? this.viewHeight / 2,
@@ -9800,7 +12337,7 @@ var _Renderer = class _Renderer {
9800
12337
  }
9801
12338
  }
9802
12339
  createRenderer() {
9803
- const renderer = new import_three27.WebGLRenderer({
12340
+ const renderer = new import_three32.WebGLRenderer({
9804
12341
  antialias: this.options.render.antialias,
9805
12342
  alpha: true,
9806
12343
  powerPreference: "high-performance",
@@ -9808,8 +12345,8 @@ var _Renderer = class _Renderer {
9808
12345
  });
9809
12346
  renderer.setClearColor(0, 0);
9810
12347
  renderer.shadowMap.enabled = true;
9811
- renderer.shadowMap.type = import_three27.PCFSoftShadowMap;
9812
- renderer.outputColorSpace = import_three27.SRGBColorSpace;
12348
+ renderer.shadowMap.type = import_three32.PCFSoftShadowMap;
12349
+ renderer.outputColorSpace = import_three32.SRGBColorSpace;
9813
12350
  renderer.setPixelRatio(this.options.render.pixelRatio ?? 1);
9814
12351
  renderer.setSize(this.viewWidth, this.viewHeight);
9815
12352
  return renderer;
@@ -9844,20 +12381,20 @@ var _Renderer = class _Renderer {
9844
12381
  window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
9845
12382
  }
9846
12383
  if (this.options.debug.grid) {
9847
- const gridHelper = new import_three27.GridHelper(128, 16);
12384
+ const gridHelper = new import_three32.GridHelper(128, 16);
9848
12385
  this._debugHelpers.push(gridHelper);
9849
12386
  this.scene.add(gridHelper);
9850
- const gridHelper2 = new import_three27.GridHelper(128, 16);
12387
+ const gridHelper2 = new import_three32.GridHelper(128, 16);
9851
12388
  this._debugHelpers.push(gridHelper2);
9852
12389
  gridHelper2.rotation.x = 90 * (Math.PI / 180);
9853
12390
  this.scene.add(gridHelper2);
9854
- const gridHelper3 = new import_three27.GridHelper(128, 16);
12391
+ const gridHelper3 = new import_three32.GridHelper(128, 16);
9855
12392
  this._debugHelpers.push(gridHelper3);
9856
12393
  gridHelper3.rotation.z = 90 * (Math.PI / 180);
9857
12394
  this.scene.add(gridHelper3);
9858
12395
  }
9859
12396
  if (this.options.debug.axes) {
9860
- const axesHelper = new import_three27.AxesHelper(64);
12397
+ const axesHelper = new import_three32.AxesHelper(64);
9861
12398
  this._debugHelpers.push(axesHelper);
9862
12399
  this.scene.add(axesHelper);
9863
12400
  }
@@ -10001,6 +12538,9 @@ var _Renderer = class _Renderer {
10001
12538
  if (next !== void 0 && t + 0.1 < next) return;
10002
12539
  this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
10003
12540
  }
12541
+ this.drawFrame();
12542
+ }
12543
+ drawFrame() {
10004
12544
  if (this._stats) {
10005
12545
  this._stats.begin();
10006
12546
  }
@@ -10015,8 +12555,28 @@ var _Renderer = class _Renderer {
10015
12555
  }
10016
12556
  }
10017
12557
  //</editor-fold>
10018
- toImage() {
10019
- return this.renderer.domElement.toDataURL();
12558
+ /**
12559
+ * Renders a fresh frame and returns an image data URL, including while the animation loop is stopped.
12560
+ * Trimming removes transparent borders; an empty image becomes one transparent pixel.
12561
+ * MIME type support and lossy quality (0–1) follow the canvas encoder.
12562
+ */
12563
+ toImage(trim = false, mime = "image/png", quality) {
12564
+ if (this._disposed) throw new Error("Cannot export an image from a disposed renderer");
12565
+ if (this._controls?.enabled) {
12566
+ this._controls.update();
12567
+ }
12568
+ this.drawFrame();
12569
+ const canvas = trim ? trimCanvas(this.renderer.domElement) : this.renderer.domElement;
12570
+ return canvas.toDataURL(mime, quality);
12571
+ }
12572
+ toObj() {
12573
+ return SceneExporter.toObj(this.scene);
12574
+ }
12575
+ toPLY(options) {
12576
+ return SceneExporter.toPLY(this.scene, options);
12577
+ }
12578
+ toGLTF(options) {
12579
+ return SceneExporter.toGLTF(this.scene, options);
10020
12580
  }
10021
12581
  ///
10022
12582
  get attachedToBody() {
@@ -10061,8 +12621,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
10061
12621
  top: void 0,
10062
12622
  bottom: void 0
10063
12623
  },
10064
- position: new import_three27.Vector3(50, 50, 50),
10065
- lookingAt: new import_three27.Vector3(0, 0, 0)
12624
+ position: new import_three32.Vector3(50, 50, 50),
12625
+ lookingAt: new import_three32.Vector3(0, 0, 0)
10066
12626
  },
10067
12627
  render: {
10068
12628
  fpsLimit: 60,
@@ -10526,19 +13086,19 @@ var AnvilParser = class {
10526
13086
  };
10527
13087
 
10528
13088
  // src/world/Chunk.ts
10529
- var import_three32 = require("three");
13089
+ var import_three37 = require("three");
10530
13090
  init_BlockStates();
10531
13091
  init_AssetKey();
10532
13092
 
10533
13093
  // src/world/MineRenderWorld.ts
10534
- var import_three30 = require("three");
13094
+ var import_three35 = require("three");
10535
13095
  init_BatchedExecutor();
10536
13096
  init_AssetKey();
10537
13097
  init_BlockStates();
10538
13098
  init_CubeFace();
10539
13099
 
10540
13100
  // src/world/SectionModels.ts
10541
- var import_three29 = require("three");
13101
+ var import_three34 = require("three");
10542
13102
  init_AssetKey();
10543
13103
  init_Models();
10544
13104
  init_CubeFace();
@@ -10604,12 +13164,12 @@ var SectionModels = class {
10604
13164
  });
10605
13165
  await object.init();
10606
13166
  const geometry = object.children[0].geometry;
10607
- geometry.applyMatrix4(new import_three29.Matrix4().makeRotationFromEuler(rotation));
13167
+ geometry.applyMatrix4(new import_three34.Matrix4().makeRotationFromEuler(rotation));
10608
13168
  object.clear();
10609
13169
  const cullFaces = CUBE_FACES.map((face) => {
10610
13170
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
10611
13171
  if (local < 0) return 0;
10612
- const normal = new import_three29.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
13172
+ const normal = new import_three34.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
10613
13173
  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);
10614
13174
  return 1 << world;
10615
13175
  });
@@ -10639,20 +13199,20 @@ var MineRenderWorld = class {
10639
13199
  }
10640
13200
  getBlockAt(posOrX, y, z) {
10641
13201
  if (typeof posOrX == "number") {
10642
- return this.getBlockAt(new import_three30.Vector3(posOrX, y, z));
13202
+ return this.getBlockAt(new import_three35.Vector3(posOrX, y, z));
10643
13203
  }
10644
13204
  if (isTripleArray(posOrX)) {
10645
- return this.getBlockAt(new import_three30.Vector3(posOrX[0], posOrX[1], posOrX[2]));
13205
+ return this.getBlockAt(new import_three35.Vector3(posOrX[0], posOrX[1], posOrX[2]));
10646
13206
  }
10647
13207
  this.validatePosBounds(posOrX);
10648
13208
  return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
10649
13209
  }
10650
13210
  async setBlockAt(posOrX, yOrBlock, z, block) {
10651
13211
  if (typeof posOrX == "number") {
10652
- return this.setBlockAt(new import_three30.Vector3(posOrX, yOrBlock, z), block);
13212
+ return this.setBlockAt(new import_three35.Vector3(posOrX, yOrBlock, z), block);
10653
13213
  }
10654
13214
  if (isTripleArray(posOrX)) {
10655
- return this.setBlockAt(new import_three30.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
13215
+ return this.setBlockAt(new import_three35.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
10656
13216
  }
10657
13217
  return this.placeBlock(posOrX, yOrBlock);
10658
13218
  }
@@ -10673,7 +13233,7 @@ var MineRenderWorld = class {
10673
13233
  const collect = async (positions2) => {
10674
13234
  for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
10675
13235
  };
10676
- const place = (block) => this.placeBlock(new import_three30.Vector3(...block.position), block, collect);
13236
+ const place = (block) => this.placeBlock(new import_three35.Vector3(...block.position), block, collect);
10677
13237
  const keys = /* @__PURE__ */ new Map();
10678
13238
  for (const block of multiblock.blocks) {
10679
13239
  if (Chunk.isAir(block)) continue;
@@ -10751,13 +13311,13 @@ var MineRenderWorld = class {
10751
13311
  for (const pos of positions) {
10752
13312
  this.pendingCulling.set(pos.toArray().join(","), pos.clone());
10753
13313
  for (const offset of CUBE_FACE_OFFSETS) {
10754
- const neighbor = pos.clone().add(new import_three30.Vector3(...offset));
13314
+ const neighbor = pos.clone().add(new import_three35.Vector3(...offset));
10755
13315
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
10756
13316
  }
10757
13317
  for (let y = -1; y <= 1; y++) {
10758
13318
  for (let z = -1; z <= 1; z++) {
10759
13319
  for (let x = -1; x <= 1; x++) {
10760
- const neighbor = pos.clone().add(new import_three30.Vector3(x, y, z));
13320
+ const neighbor = pos.clone().add(new import_three35.Vector3(x, y, z));
10761
13321
  if (this.getBlockAt(neighbor)?.object?.fluidKind) {
10762
13322
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
10763
13323
  }
@@ -10779,7 +13339,7 @@ var MineRenderWorld = class {
10779
13339
  if (!block) continue;
10780
13340
  if (block.object?.fluidKind) {
10781
13341
  await block.object.updateFluid((x, y, z) => {
10782
- const neighbor = pos.clone().add(new import_three30.Vector3(x, y, z));
13342
+ const neighbor = pos.clone().add(new import_three35.Vector3(x, y, z));
10783
13343
  const section = this.getChunkAt(neighbor);
10784
13344
  const object = section?.getBlockAt(neighbor)?.object;
10785
13345
  return {
@@ -10791,7 +13351,7 @@ var MineRenderWorld = class {
10791
13351
  }
10792
13352
  let mask = 0;
10793
13353
  for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
10794
- const neighbor = pos.clone().add(new import_three30.Vector3(...offset));
13354
+ const neighbor = pos.clone().add(new import_three35.Vector3(...offset));
10795
13355
  if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
10796
13356
  mask |= 1 << face;
10797
13357
  }
@@ -10825,14 +13385,14 @@ var MineRenderWorld = class {
10825
13385
  return this._chunks.get(this.worldPosToChunkKey(pos));
10826
13386
  }
10827
13387
  static worldToScenePosition(pos) {
10828
- return new import_three30.Vector3(
13388
+ return new import_three35.Vector3(
10829
13389
  pos.x * 16,
10830
13390
  pos.y * 16,
10831
13391
  pos.z * 16
10832
13392
  );
10833
13393
  }
10834
13394
  static sceneToWorldPosition(pos) {
10835
- return new import_three30.Vector3(
13395
+ return new import_three35.Vector3(
10836
13396
  pos.x / 16,
10837
13397
  pos.y / 16,
10838
13398
  pos.z / 16
@@ -10852,10 +13412,10 @@ var MineRenderWorld = class {
10852
13412
  };
10853
13413
 
10854
13414
  // src/world/SectionMesh.ts
10855
- var import_three31 = require("three");
13415
+ var import_three36 = require("three");
10856
13416
  init_CanvasCompat();
10857
13417
  init_Materials();
10858
- var SectionMesh = class _SectionMesh extends import_three31.Group {
13418
+ var SectionMesh = class _SectionMesh extends import_three36.Group {
10859
13419
  constructor() {
10860
13420
  super(...arguments);
10861
13421
  this.ownedMeshes = [];
@@ -10928,18 +13488,18 @@ var SectionMesh = class _SectionMesh extends import_three31.Group {
10928
13488
  for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
10929
13489
  }
10930
13490
  }
10931
- const geometry = new import_three31.BufferGeometry();
10932
- geometry.setAttribute("position", new import_three31.Float32BufferAttribute(positions, 3));
10933
- geometry.setAttribute("normal", new import_three31.Float32BufferAttribute(normals, 3));
10934
- geometry.setAttribute("uv", new import_three31.Float32BufferAttribute(uvs, 2));
10935
- geometry.setAttribute("color", new import_three31.Float32BufferAttribute(colors, 3));
13491
+ const geometry = new import_three36.BufferGeometry();
13492
+ geometry.setAttribute("position", new import_three36.Float32BufferAttribute(positions, 3));
13493
+ geometry.setAttribute("normal", new import_three36.Float32BufferAttribute(normals, 3));
13494
+ geometry.setAttribute("uv", new import_three36.Float32BufferAttribute(uvs, 2));
13495
+ geometry.setAttribute("color", new import_three36.Float32BufferAttribute(colors, 3));
10936
13496
  geometry.setIndex(indices);
10937
13497
  geometry.computeBoundingBox();
10938
13498
  geometry.computeBoundingSphere();
10939
13499
  const material = Materials.createShadedCanvasMaterial(canvas, false);
10940
13500
  material.vertexColors = true;
10941
13501
  const texture = material.uniforms?.map?.value ?? material.map;
10942
- const mesh = new import_three31.Mesh(geometry, material);
13502
+ const mesh = new import_three36.Mesh(geometry, material);
10943
13503
  section.add(mesh);
10944
13504
  section.ownedMeshes.push({ mesh, texture });
10945
13505
  }
@@ -10973,10 +13533,10 @@ var Chunk = class _Chunk {
10973
13533
  }
10974
13534
  getBlockAt(posOrX, y, z) {
10975
13535
  if (typeof posOrX == "number") {
10976
- return this.getBlockAt(new import_three32.Vector3(posOrX, y, z));
13536
+ return this.getBlockAt(new import_three37.Vector3(posOrX, y, z));
10977
13537
  }
10978
13538
  if (isTripleArray(posOrX)) {
10979
- return this.getBlockAt(new import_three32.Vector3(posOrX[0], posOrX[1], posOrX[2]));
13539
+ return this.getBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]));
10980
13540
  }
10981
13541
  const pos = this.worldPosToChunkPos(posOrX);
10982
13542
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -10984,10 +13544,10 @@ var Chunk = class _Chunk {
10984
13544
  }
10985
13545
  async setBlockAt(posOrX, yOrBlock, z, block) {
10986
13546
  if (typeof posOrX == "number") {
10987
- return this.setBlockAt(new import_three32.Vector3(posOrX, yOrBlock, z), block);
13547
+ return this.setBlockAt(new import_three37.Vector3(posOrX, yOrBlock, z), block);
10988
13548
  }
10989
13549
  if (isTripleArray(posOrX)) {
10990
- return this.setBlockAt(new import_three32.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
13550
+ return this.setBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
10991
13551
  }
10992
13552
  const worldPos = posOrX;
10993
13553
  const pos = this.worldPosToChunkPos(worldPos);
@@ -11072,7 +13632,7 @@ var Chunk = class _Chunk {
11072
13632
  }
11073
13633
  async clear(onBlocksChanged = this.onBlocksChanged) {
11074
13634
  const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
11075
- new import_three32.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
13635
+ new import_three37.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
11076
13636
  ));
11077
13637
  for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
11078
13638
  this.sectionBlocks.clear();
@@ -11096,14 +13656,14 @@ var Chunk = class _Chunk {
11096
13656
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
11097
13657
  }
11098
13658
  worldPosToChunkPos(pos) {
11099
- return new import_three32.Vector3(
13659
+ return new import_three37.Vector3(
11100
13660
  pos.x - this.x * 16,
11101
13661
  pos.y - this.y * 16,
11102
13662
  pos.z - this.z * 16
11103
13663
  );
11104
13664
  }
11105
13665
  chunkPosToWorldPos(pos) {
11106
- return new import_three32.Vector3(
13666
+ return new import_three37.Vector3(
11107
13667
  this.x * 16 + pos.x,
11108
13668
  this.y * 16 + pos.y,
11109
13669
  this.z * 16 + pos.z