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.
- package/dist/browser/index.d.mts +35 -2
- package/dist/browser/index.d.ts +35 -2
- package/dist/browser/index.js +2712 -152
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +2722 -117
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +2615 -22
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +35 -2
- package/dist/node/index.d.ts +35 -2
- package/dist/node/index.js +2715 -153
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +2722 -117
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.js
CHANGED
|
@@ -3489,16 +3489,16 @@ var init_SceneObject = __esm({
|
|
|
3489
3489
|
});
|
|
3490
3490
|
|
|
3491
3491
|
// src/model/ModelCulling.ts
|
|
3492
|
-
var
|
|
3492
|
+
var import_three22, ModelCulling;
|
|
3493
3493
|
var init_ModelCulling = __esm({
|
|
3494
3494
|
"src/model/ModelCulling.ts"() {
|
|
3495
|
-
|
|
3495
|
+
import_three22 = require("three");
|
|
3496
3496
|
init_CubeFace();
|
|
3497
3497
|
ModelCulling = class {
|
|
3498
3498
|
static toLocalMask(worldMask, rotation) {
|
|
3499
3499
|
let localMask = 0;
|
|
3500
3500
|
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
3501
|
-
const normal = new
|
|
3501
|
+
const normal = new import_three22.Vector3(...offset).applyEuler(rotation);
|
|
3502
3502
|
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);
|
|
3503
3503
|
if (worldFace < 0) return 0;
|
|
3504
3504
|
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
@@ -3542,7 +3542,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
|
|
|
3542
3542
|
const attributes = {};
|
|
3543
3543
|
const morphAttributes = {};
|
|
3544
3544
|
const morphTargetsRelative = geometries[0].morphTargetsRelative;
|
|
3545
|
-
const mergedGeometry = new
|
|
3545
|
+
const mergedGeometry = new import_three24.BufferGeometry();
|
|
3546
3546
|
let offset = 0;
|
|
3547
3547
|
for (let i = 0; i < geometries.length; ++i) {
|
|
3548
3548
|
const geometry = geometries[i];
|
|
@@ -3666,7 +3666,7 @@ function mergeBufferAttributes(attributes) {
|
|
|
3666
3666
|
array.set(attributes[i].array, offset);
|
|
3667
3667
|
offset += attributes[i].array.length;
|
|
3668
3668
|
}
|
|
3669
|
-
return new
|
|
3669
|
+
return new import_three24.BufferAttribute(array, itemSize, normalized);
|
|
3670
3670
|
}
|
|
3671
3671
|
function interleaveAttributes(attributes) {
|
|
3672
3672
|
let TypedArray;
|
|
@@ -3682,7 +3682,7 @@ function interleaveAttributes(attributes) {
|
|
|
3682
3682
|
arrayLength += attribute.array.length;
|
|
3683
3683
|
stride += attribute.itemSize;
|
|
3684
3684
|
}
|
|
3685
|
-
const interleavedBuffer = new
|
|
3685
|
+
const interleavedBuffer = new import_three24.InterleavedBuffer(new TypedArray(arrayLength), stride);
|
|
3686
3686
|
let offset = 0;
|
|
3687
3687
|
const res = [];
|
|
3688
3688
|
const getters = ["getX", "getY", "getZ", "getW"];
|
|
@@ -3691,7 +3691,7 @@ function interleaveAttributes(attributes) {
|
|
|
3691
3691
|
const attribute = attributes[j];
|
|
3692
3692
|
const itemSize = attribute.itemSize;
|
|
3693
3693
|
const count = attribute.count;
|
|
3694
|
-
const iba = new
|
|
3694
|
+
const iba = new import_three24.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
|
|
3695
3695
|
res.push(iba);
|
|
3696
3696
|
offset += itemSize;
|
|
3697
3697
|
for (let c = 0; c < count; c++) {
|
|
@@ -3775,13 +3775,13 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
3775
3775
|
const name = attributeNames[i];
|
|
3776
3776
|
const oldAttribute = geometry.getAttribute(name);
|
|
3777
3777
|
const buffer = new oldAttribute.array.constructor(attrArrays[name]);
|
|
3778
|
-
const attribute = new
|
|
3778
|
+
const attribute = new import_three24.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
|
|
3779
3779
|
result.setAttribute(name, attribute);
|
|
3780
3780
|
if (name in morphAttrsArrays) {
|
|
3781
3781
|
for (let j = 0; j < morphAttrsArrays[name].length; j++) {
|
|
3782
3782
|
const oldMorphAttribute = geometry.morphAttributes[name][j];
|
|
3783
3783
|
const buffer2 = new oldMorphAttribute.array.constructor(morphAttrsArrays[name][j]);
|
|
3784
|
-
const morphAttribute = new
|
|
3784
|
+
const morphAttribute = new import_three24.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
|
|
3785
3785
|
result.morphAttributes[name][j] = morphAttribute;
|
|
3786
3786
|
}
|
|
3787
3787
|
}
|
|
@@ -3790,11 +3790,11 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
3790
3790
|
return result;
|
|
3791
3791
|
}
|
|
3792
3792
|
function toTrianglesDrawMode(geometry, drawMode) {
|
|
3793
|
-
if (drawMode ===
|
|
3793
|
+
if (drawMode === import_three24.TrianglesDrawMode) {
|
|
3794
3794
|
console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
|
|
3795
3795
|
return geometry;
|
|
3796
3796
|
}
|
|
3797
|
-
if (drawMode ===
|
|
3797
|
+
if (drawMode === import_three24.TriangleFanDrawMode || drawMode === import_three24.TriangleStripDrawMode) {
|
|
3798
3798
|
let index = geometry.getIndex();
|
|
3799
3799
|
if (index === null) {
|
|
3800
3800
|
const indices = [];
|
|
@@ -3812,7 +3812,7 @@ function toTrianglesDrawMode(geometry, drawMode) {
|
|
|
3812
3812
|
}
|
|
3813
3813
|
const numberOfTriangles = index.count - 2;
|
|
3814
3814
|
const newIndices = [];
|
|
3815
|
-
if (drawMode ===
|
|
3815
|
+
if (drawMode === import_three24.TriangleFanDrawMode) {
|
|
3816
3816
|
for (let i = 1; i <= numberOfTriangles; i++) {
|
|
3817
3817
|
newIndices.push(index.getX(0));
|
|
3818
3818
|
newIndices.push(index.getX(i));
|
|
@@ -3848,15 +3848,15 @@ function computeMorphedAttributes(object) {
|
|
|
3848
3848
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
3849
3849
|
return null;
|
|
3850
3850
|
}
|
|
3851
|
-
const _vA = new
|
|
3852
|
-
const _vB = new
|
|
3853
|
-
const _vC = new
|
|
3854
|
-
const _tempA = new
|
|
3855
|
-
const _tempB = new
|
|
3856
|
-
const _tempC = new
|
|
3857
|
-
const _morphA = new
|
|
3858
|
-
const _morphB = new
|
|
3859
|
-
const _morphC = new
|
|
3851
|
+
const _vA = new import_three24.Vector3();
|
|
3852
|
+
const _vB = new import_three24.Vector3();
|
|
3853
|
+
const _vC = new import_three24.Vector3();
|
|
3854
|
+
const _tempA = new import_three24.Vector3();
|
|
3855
|
+
const _tempB = new import_three24.Vector3();
|
|
3856
|
+
const _tempC = new import_three24.Vector3();
|
|
3857
|
+
const _morphA = new import_three24.Vector3();
|
|
3858
|
+
const _morphB = new import_three24.Vector3();
|
|
3859
|
+
const _morphC = new import_three24.Vector3();
|
|
3860
3860
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
3861
3861
|
_vA.fromBufferAttribute(attribute, a2);
|
|
3862
3862
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -4051,8 +4051,8 @@ function computeMorphedAttributes(object) {
|
|
|
4051
4051
|
}
|
|
4052
4052
|
}
|
|
4053
4053
|
}
|
|
4054
|
-
const morphedPositionAttribute = new
|
|
4055
|
-
const morphedNormalAttribute = new
|
|
4054
|
+
const morphedPositionAttribute = new import_three24.Float32BufferAttribute(modifiedPosition, 3);
|
|
4055
|
+
const morphedNormalAttribute = new import_three24.Float32BufferAttribute(modifiedNormal, 3);
|
|
4056
4056
|
return {
|
|
4057
4057
|
positionAttribute,
|
|
4058
4058
|
normalAttribute,
|
|
@@ -4060,10 +4060,10 @@ function computeMorphedAttributes(object) {
|
|
|
4060
4060
|
morphedNormalAttribute
|
|
4061
4061
|
};
|
|
4062
4062
|
}
|
|
4063
|
-
var
|
|
4063
|
+
var import_three24;
|
|
4064
4064
|
var init_BufferGeometryUtils = __esm({
|
|
4065
4065
|
"src/three/BufferGeometryUtils.js"() {
|
|
4066
|
-
|
|
4066
|
+
import_three24 = require("three");
|
|
4067
4067
|
}
|
|
4068
4068
|
});
|
|
4069
4069
|
|
|
@@ -4071,13 +4071,13 @@ var init_BufferGeometryUtils = __esm({
|
|
|
4071
4071
|
function isModelObject(obj) {
|
|
4072
4072
|
return obj.isModelObject;
|
|
4073
4073
|
}
|
|
4074
|
-
var
|
|
4074
|
+
var import_three25, import_ts_deepmerge5, p9, ModelObject;
|
|
4075
4075
|
var init_ModelObject = __esm({
|
|
4076
4076
|
"src/model/scene/ModelObject.ts"() {
|
|
4077
4077
|
init_SceneObject();
|
|
4078
4078
|
init_Materials();
|
|
4079
4079
|
init_UVMapper();
|
|
4080
|
-
|
|
4080
|
+
import_three25 = require("three");
|
|
4081
4081
|
init_BufferGeometryUtils();
|
|
4082
4082
|
init_model();
|
|
4083
4083
|
import_ts_deepmerge5 = __toESM(require_dist());
|
|
@@ -4135,7 +4135,7 @@ var init_ModelObject = __esm({
|
|
|
4135
4135
|
elGeo.clearGroups();
|
|
4136
4136
|
}
|
|
4137
4137
|
if (this.options.uvLockRotation) {
|
|
4138
|
-
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new
|
|
4138
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three25.Euler(...this.options.uvLockRotation));
|
|
4139
4139
|
}
|
|
4140
4140
|
if (this.options.tints) {
|
|
4141
4141
|
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
@@ -4144,19 +4144,19 @@ var init_ModelObject = __esm({
|
|
|
4144
4144
|
if (tintIndex === void 0 || tintIndex < 0) continue;
|
|
4145
4145
|
const tint = this.options.tints[tintIndex];
|
|
4146
4146
|
if (tint === void 0) continue;
|
|
4147
|
-
const color = new
|
|
4147
|
+
const color = new import_three25.Color(tint);
|
|
4148
4148
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
4149
4149
|
color.toArray(colors, (faceIndex * 4 + vertex) * 3);
|
|
4150
4150
|
}
|
|
4151
4151
|
}
|
|
4152
|
-
elGeo.setAttribute("color", new
|
|
4152
|
+
elGeo.setAttribute("color", new import_three25.BufferAttribute(colors, 3));
|
|
4153
4153
|
}
|
|
4154
|
-
elGeo.applyMatrix4(new
|
|
4155
|
-
elGeo.applyMatrix4(new
|
|
4154
|
+
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));
|
|
4155
|
+
elGeo.applyMatrix4(new import_three25.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4156
4156
|
if (el.rotation) {
|
|
4157
4157
|
applyElementRotation(el.rotation, elGeo);
|
|
4158
4158
|
}
|
|
4159
|
-
elGeo.applyMatrix4(new
|
|
4159
|
+
elGeo.applyMatrix4(new import_three25.Matrix4().makeTranslation(-8, -8, -8));
|
|
4160
4160
|
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4161
4161
|
if (this.options.mergeMeshes) {
|
|
4162
4162
|
allGeos.push(elGeo);
|
|
@@ -4178,7 +4178,7 @@ var init_ModelObject = __esm({
|
|
|
4178
4178
|
if (allGeos.length > 0) {
|
|
4179
4179
|
combinedGeo = mergeBufferGeometries(allGeos);
|
|
4180
4180
|
} else {
|
|
4181
|
-
combinedGeo = new
|
|
4181
|
+
combinedGeo = new import_three25.BoxGeometry(16, 16, 16);
|
|
4182
4182
|
if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
|
|
4183
4183
|
}
|
|
4184
4184
|
combinedGeo.computeBoundingBox();
|
|
@@ -4286,7 +4286,7 @@ function ownHeight(sample) {
|
|
|
4286
4286
|
return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
|
|
4287
4287
|
}
|
|
4288
4288
|
function createFluidGeometry(kind, sample) {
|
|
4289
|
-
const geometry = new
|
|
4289
|
+
const geometry = new import_three26.BufferGeometry();
|
|
4290
4290
|
const positions = [], normals = [], uvs = [], indices = [];
|
|
4291
4291
|
const self = sample(0, 0, 0);
|
|
4292
4292
|
const height = (x, z) => {
|
|
@@ -4385,16 +4385,16 @@ function createFluidGeometry(kind, sample) {
|
|
|
4385
4385
|
1
|
|
4386
4386
|
);
|
|
4387
4387
|
}
|
|
4388
|
-
geometry.setAttribute("position", new
|
|
4389
|
-
geometry.setAttribute("normal", new
|
|
4390
|
-
geometry.setAttribute("uv", new
|
|
4388
|
+
geometry.setAttribute("position", new import_three26.Float32BufferAttribute(positions, 3));
|
|
4389
|
+
geometry.setAttribute("normal", new import_three26.Float32BufferAttribute(normals, 3));
|
|
4390
|
+
geometry.setAttribute("uv", new import_three26.Float32BufferAttribute(uvs, 2));
|
|
4391
4391
|
geometry.setIndex(indices);
|
|
4392
4392
|
return geometry;
|
|
4393
4393
|
}
|
|
4394
|
-
var
|
|
4394
|
+
var import_three26, fluidRules, HORIZONTAL, EPSILON;
|
|
4395
4395
|
var init_FluidGeometry = __esm({
|
|
4396
4396
|
"src/model/fluid/FluidGeometry.ts"() {
|
|
4397
|
-
|
|
4397
|
+
import_three26 = require("three");
|
|
4398
4398
|
init_fluidBlocks();
|
|
4399
4399
|
fluidRules = fluidBlocks_default;
|
|
4400
4400
|
HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]];
|
|
@@ -4423,10 +4423,10 @@ function sampleFluid(kind, sample) {
|
|
|
4423
4423
|
}
|
|
4424
4424
|
return { key: key.join(""), sample: (x, y, z) => cells[(y + 1) * 9 + (z + 1) * 3 + x + 1] };
|
|
4425
4425
|
}
|
|
4426
|
-
var
|
|
4426
|
+
var import_three27, FluidModelObject;
|
|
4427
4427
|
var init_FluidModelObject = __esm({
|
|
4428
4428
|
"src/model/fluid/FluidModelObject.ts"() {
|
|
4429
|
-
|
|
4429
|
+
import_three27 = require("three");
|
|
4430
4430
|
init_AssetKey();
|
|
4431
4431
|
init_Materials();
|
|
4432
4432
|
init_ModelObject();
|
|
@@ -4459,10 +4459,10 @@ var init_FluidModelObject = __esm({
|
|
|
4459
4459
|
}
|
|
4460
4460
|
}
|
|
4461
4461
|
geometry.clearGroups();
|
|
4462
|
-
const color = new
|
|
4462
|
+
const color = new import_three27.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
|
|
4463
4463
|
const colors = new Float32Array(geometry.getAttribute("position").count * 3);
|
|
4464
4464
|
for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
|
|
4465
|
-
geometry.setAttribute("color", new
|
|
4465
|
+
geometry.setAttribute("color", new import_three27.BufferAttribute(colors, 3));
|
|
4466
4466
|
geometry.computeBoundingBox();
|
|
4467
4467
|
geometry.computeBoundingSphere();
|
|
4468
4468
|
if (this.options.instanceMeshes) {
|
|
@@ -4476,7 +4476,7 @@ var init_FluidModelObject = __esm({
|
|
|
4476
4476
|
super.applyTextures();
|
|
4477
4477
|
this.iterateAllMeshes((mesh) => {
|
|
4478
4478
|
const material = mesh.material;
|
|
4479
|
-
material.side =
|
|
4479
|
+
material.side = import_three27.DoubleSide;
|
|
4480
4480
|
material.forceSinglePass = true;
|
|
4481
4481
|
material.depthWrite = !material.transparent;
|
|
4482
4482
|
});
|
|
@@ -4564,6 +4564,7 @@ __export(index_node_exports, {
|
|
|
4564
4564
|
RequestError: () => RequestError,
|
|
4565
4565
|
Requests: () => Requests,
|
|
4566
4566
|
SKIN_PARTS: () => SKIN_PARTS,
|
|
4567
|
+
SceneExporter: () => SceneExporter,
|
|
4567
4568
|
SceneInspector: () => SceneInspector,
|
|
4568
4569
|
SceneObject: () => SceneObject,
|
|
4569
4570
|
SceneStats: () => SceneStats,
|
|
@@ -4652,7 +4653,8 @@ __export(index_node_exports, {
|
|
|
4652
4653
|
timingStart: () => timingStart,
|
|
4653
4654
|
toDegrees: () => toDegrees,
|
|
4654
4655
|
toRadians: () => toRadians,
|
|
4655
|
-
toTrianglesDrawMode: () => toTrianglesDrawMode
|
|
4656
|
+
toTrianglesDrawMode: () => toTrianglesDrawMode,
|
|
4657
|
+
trimCanvas: () => trimCanvas
|
|
4656
4658
|
});
|
|
4657
4659
|
module.exports = __toCommonJS(index_node_exports);
|
|
4658
4660
|
|
|
@@ -4994,6 +4996,37 @@ init_PersistentCache();
|
|
|
4994
4996
|
init_CanvasCompat();
|
|
4995
4997
|
init_CanvasImage();
|
|
4996
4998
|
|
|
4999
|
+
// src/canvas/trimCanvas.ts
|
|
5000
|
+
init_CanvasCompat();
|
|
5001
|
+
function trimCanvas(source) {
|
|
5002
|
+
if (source.width === 0 || source.height === 0) return createCanvas2(1, 1);
|
|
5003
|
+
const canvas = createCanvas2(source.width, source.height);
|
|
5004
|
+
const context = canvas.getContext("2d");
|
|
5005
|
+
if (!context) throw new Error("Image export requires a 2D canvas context");
|
|
5006
|
+
context.drawImage(source, 0, 0);
|
|
5007
|
+
const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
5008
|
+
let left = canvas.width, top = canvas.height, right = -1, bottom = -1;
|
|
5009
|
+
for (let y = 0; y < canvas.height; y++) {
|
|
5010
|
+
for (let x = 0; x < canvas.width; x++) {
|
|
5011
|
+
if (pixels[(y * canvas.width + x) * 4 + 3] === 0) continue;
|
|
5012
|
+
left = Math.min(left, x);
|
|
5013
|
+
top = Math.min(top, y);
|
|
5014
|
+
right = Math.max(right, x);
|
|
5015
|
+
bottom = Math.max(bottom, y);
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
if (right < left) {
|
|
5019
|
+
canvas.width = canvas.height = 1;
|
|
5020
|
+
return canvas;
|
|
5021
|
+
}
|
|
5022
|
+
const width = right - left + 1, height = bottom - top + 1;
|
|
5023
|
+
const cropped = context.getImageData(left, top, width, height);
|
|
5024
|
+
canvas.width = width;
|
|
5025
|
+
canvas.height = height;
|
|
5026
|
+
context.putImageData(cropped, 0, 0);
|
|
5027
|
+
return canvas;
|
|
5028
|
+
}
|
|
5029
|
+
|
|
4997
5030
|
// src/entity/scene/EntityObject.ts
|
|
4998
5031
|
init_SceneObject();
|
|
4999
5032
|
init_Caching();
|
|
@@ -5116,6 +5149,2510 @@ function isEntityObject(obj) {
|
|
|
5116
5149
|
// src/error/index.ts
|
|
5117
5150
|
init_MineRenderError();
|
|
5118
5151
|
|
|
5152
|
+
// src/export/SceneExporter.ts
|
|
5153
|
+
var import_three18 = require("three");
|
|
5154
|
+
|
|
5155
|
+
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
5156
|
+
var import_three14 = require("three");
|
|
5157
|
+
var OBJExporter = class {
|
|
5158
|
+
parse(object) {
|
|
5159
|
+
let output = "";
|
|
5160
|
+
let indexVertex = 0;
|
|
5161
|
+
let indexVertexUvs = 0;
|
|
5162
|
+
let indexNormals = 0;
|
|
5163
|
+
const vertex = new import_three14.Vector3();
|
|
5164
|
+
const color = new import_three14.Color();
|
|
5165
|
+
const normal = new import_three14.Vector3();
|
|
5166
|
+
const uv = new import_three14.Vector2();
|
|
5167
|
+
const face = [];
|
|
5168
|
+
function parseMesh(mesh) {
|
|
5169
|
+
let nbVertex = 0;
|
|
5170
|
+
let nbNormals = 0;
|
|
5171
|
+
let nbVertexUvs = 0;
|
|
5172
|
+
const geometry = mesh.geometry;
|
|
5173
|
+
const normalMatrixWorld = new import_three14.Matrix3();
|
|
5174
|
+
const vertices = geometry.getAttribute("position");
|
|
5175
|
+
const normals = geometry.getAttribute("normal");
|
|
5176
|
+
const uvs = geometry.getAttribute("uv");
|
|
5177
|
+
const indices = geometry.getIndex();
|
|
5178
|
+
output += "o " + mesh.name + "\n";
|
|
5179
|
+
if (mesh.material && mesh.material.name) {
|
|
5180
|
+
output += "usemtl " + mesh.material.name + "\n";
|
|
5181
|
+
}
|
|
5182
|
+
if (vertices !== void 0) {
|
|
5183
|
+
for (let i = 0, l = vertices.count; i < l; i++, nbVertex++) {
|
|
5184
|
+
vertex.fromBufferAttribute(vertices, i);
|
|
5185
|
+
vertex.applyMatrix4(mesh.matrixWorld);
|
|
5186
|
+
output += "v " + vertex.x + " " + vertex.y + " " + vertex.z + "\n";
|
|
5187
|
+
}
|
|
5188
|
+
}
|
|
5189
|
+
if (uvs !== void 0) {
|
|
5190
|
+
for (let i = 0, l = uvs.count; i < l; i++, nbVertexUvs++) {
|
|
5191
|
+
uv.fromBufferAttribute(uvs, i);
|
|
5192
|
+
output += "vt " + uv.x + " " + uv.y + "\n";
|
|
5193
|
+
}
|
|
5194
|
+
}
|
|
5195
|
+
if (normals !== void 0) {
|
|
5196
|
+
normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
|
|
5197
|
+
for (let i = 0, l = normals.count; i < l; i++, nbNormals++) {
|
|
5198
|
+
normal.fromBufferAttribute(normals, i);
|
|
5199
|
+
normal.applyMatrix3(normalMatrixWorld).normalize();
|
|
5200
|
+
output += "vn " + normal.x + " " + normal.y + " " + normal.z + "\n";
|
|
5201
|
+
}
|
|
5202
|
+
}
|
|
5203
|
+
if (indices !== null) {
|
|
5204
|
+
for (let i = 0, l = indices.count; i < l; i += 3) {
|
|
5205
|
+
for (let m = 0; m < 3; m++) {
|
|
5206
|
+
const j = indices.getX(i + m) + 1;
|
|
5207
|
+
face[m] = indexVertex + j + (normals || uvs ? "/" + (uvs ? indexVertexUvs + j : "") + (normals ? "/" + (indexNormals + j) : "") : "");
|
|
5208
|
+
}
|
|
5209
|
+
output += "f " + face.join(" ") + "\n";
|
|
5210
|
+
}
|
|
5211
|
+
} else {
|
|
5212
|
+
for (let i = 0, l = vertices.count; i < l; i += 3) {
|
|
5213
|
+
for (let m = 0; m < 3; m++) {
|
|
5214
|
+
const j = i + m + 1;
|
|
5215
|
+
face[m] = indexVertex + j + (normals || uvs ? "/" + (uvs ? indexVertexUvs + j : "") + (normals ? "/" + (indexNormals + j) : "") : "");
|
|
5216
|
+
}
|
|
5217
|
+
output += "f " + face.join(" ") + "\n";
|
|
5218
|
+
}
|
|
5219
|
+
}
|
|
5220
|
+
indexVertex += nbVertex;
|
|
5221
|
+
indexVertexUvs += nbVertexUvs;
|
|
5222
|
+
indexNormals += nbNormals;
|
|
5223
|
+
}
|
|
5224
|
+
function parseLine(line) {
|
|
5225
|
+
let nbVertex = 0;
|
|
5226
|
+
const geometry = line.geometry;
|
|
5227
|
+
const type = line.type;
|
|
5228
|
+
const vertices = geometry.getAttribute("position");
|
|
5229
|
+
output += "o " + line.name + "\n";
|
|
5230
|
+
if (vertices !== void 0) {
|
|
5231
|
+
for (let i = 0, l = vertices.count; i < l; i++, nbVertex++) {
|
|
5232
|
+
vertex.fromBufferAttribute(vertices, i);
|
|
5233
|
+
vertex.applyMatrix4(line.matrixWorld);
|
|
5234
|
+
output += "v " + vertex.x + " " + vertex.y + " " + vertex.z + "\n";
|
|
5235
|
+
}
|
|
5236
|
+
}
|
|
5237
|
+
if (type === "Line") {
|
|
5238
|
+
output += "l ";
|
|
5239
|
+
for (let j = 1, l = vertices.count; j <= l; j++) {
|
|
5240
|
+
output += indexVertex + j + " ";
|
|
5241
|
+
}
|
|
5242
|
+
output += "\n";
|
|
5243
|
+
}
|
|
5244
|
+
if (type === "LineSegments") {
|
|
5245
|
+
for (let j = 1, k = j + 1, l = vertices.count; j < l; j += 2, k = j + 1) {
|
|
5246
|
+
output += "l " + (indexVertex + j) + " " + (indexVertex + k) + "\n";
|
|
5247
|
+
}
|
|
5248
|
+
}
|
|
5249
|
+
indexVertex += nbVertex;
|
|
5250
|
+
}
|
|
5251
|
+
function parsePoints(points) {
|
|
5252
|
+
let nbVertex = 0;
|
|
5253
|
+
const geometry = points.geometry;
|
|
5254
|
+
const vertices = geometry.getAttribute("position");
|
|
5255
|
+
const colors = geometry.getAttribute("color");
|
|
5256
|
+
output += "o " + points.name + "\n";
|
|
5257
|
+
if (vertices !== void 0) {
|
|
5258
|
+
for (let i = 0, l = vertices.count; i < l; i++, nbVertex++) {
|
|
5259
|
+
vertex.fromBufferAttribute(vertices, i);
|
|
5260
|
+
vertex.applyMatrix4(points.matrixWorld);
|
|
5261
|
+
output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
|
|
5262
|
+
if (colors !== void 0) {
|
|
5263
|
+
color.fromBufferAttribute(colors, i).convertLinearToSRGB();
|
|
5264
|
+
output += " " + color.r + " " + color.g + " " + color.b;
|
|
5265
|
+
}
|
|
5266
|
+
output += "\n";
|
|
5267
|
+
}
|
|
5268
|
+
output += "p ";
|
|
5269
|
+
for (let j = 1, l = vertices.count; j <= l; j++) {
|
|
5270
|
+
output += indexVertex + j + " ";
|
|
5271
|
+
}
|
|
5272
|
+
output += "\n";
|
|
5273
|
+
}
|
|
5274
|
+
indexVertex += nbVertex;
|
|
5275
|
+
}
|
|
5276
|
+
object.traverse(function(child) {
|
|
5277
|
+
if (child.isMesh === true) {
|
|
5278
|
+
parseMesh(child);
|
|
5279
|
+
}
|
|
5280
|
+
if (child.isLine === true) {
|
|
5281
|
+
parseLine(child);
|
|
5282
|
+
}
|
|
5283
|
+
if (child.isPoints === true) {
|
|
5284
|
+
parsePoints(child);
|
|
5285
|
+
}
|
|
5286
|
+
});
|
|
5287
|
+
return output;
|
|
5288
|
+
}
|
|
5289
|
+
};
|
|
5290
|
+
|
|
5291
|
+
// ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
|
|
5292
|
+
var import_three15 = require("three");
|
|
5293
|
+
var PLYExporter = class {
|
|
5294
|
+
parse(object, onDone, options = {}) {
|
|
5295
|
+
function traverseMeshes(cb) {
|
|
5296
|
+
object.traverse(function(child) {
|
|
5297
|
+
if (child.isMesh === true || child.isPoints) {
|
|
5298
|
+
const mesh = child;
|
|
5299
|
+
const geometry = mesh.geometry;
|
|
5300
|
+
if (geometry.hasAttribute("position") === true) {
|
|
5301
|
+
cb(mesh, geometry);
|
|
5302
|
+
}
|
|
5303
|
+
}
|
|
5304
|
+
});
|
|
5305
|
+
}
|
|
5306
|
+
const defaultOptions = {
|
|
5307
|
+
binary: false,
|
|
5308
|
+
excludeAttributes: [],
|
|
5309
|
+
// normal, uv, color, index
|
|
5310
|
+
littleEndian: false
|
|
5311
|
+
};
|
|
5312
|
+
options = Object.assign(defaultOptions, options);
|
|
5313
|
+
const excludeAttributes = options.excludeAttributes;
|
|
5314
|
+
let includeIndices = true;
|
|
5315
|
+
let includeNormals = false;
|
|
5316
|
+
let includeColors = false;
|
|
5317
|
+
let includeUVs = false;
|
|
5318
|
+
let vertexCount = 0;
|
|
5319
|
+
let faceCount = 0;
|
|
5320
|
+
object.traverse(function(child) {
|
|
5321
|
+
if (child.isMesh === true) {
|
|
5322
|
+
const mesh = child;
|
|
5323
|
+
const geometry = mesh.geometry;
|
|
5324
|
+
const vertices = geometry.getAttribute("position");
|
|
5325
|
+
const normals = geometry.getAttribute("normal");
|
|
5326
|
+
const uvs = geometry.getAttribute("uv");
|
|
5327
|
+
const colors = geometry.getAttribute("color");
|
|
5328
|
+
const indices = geometry.getIndex();
|
|
5329
|
+
if (vertices === void 0) {
|
|
5330
|
+
return;
|
|
5331
|
+
}
|
|
5332
|
+
vertexCount += vertices.count;
|
|
5333
|
+
faceCount += indices ? indices.count / 3 : vertices.count / 3;
|
|
5334
|
+
if (normals !== void 0) includeNormals = true;
|
|
5335
|
+
if (uvs !== void 0) includeUVs = true;
|
|
5336
|
+
if (colors !== void 0) includeColors = true;
|
|
5337
|
+
} else if (child.isPoints) {
|
|
5338
|
+
const mesh = child;
|
|
5339
|
+
const geometry = mesh.geometry;
|
|
5340
|
+
const vertices = geometry.getAttribute("position");
|
|
5341
|
+
const normals = geometry.getAttribute("normal");
|
|
5342
|
+
const colors = geometry.getAttribute("color");
|
|
5343
|
+
vertexCount += vertices.count;
|
|
5344
|
+
if (normals !== void 0) includeNormals = true;
|
|
5345
|
+
if (colors !== void 0) includeColors = true;
|
|
5346
|
+
includeIndices = false;
|
|
5347
|
+
}
|
|
5348
|
+
});
|
|
5349
|
+
const tempColor = new import_three15.Color();
|
|
5350
|
+
includeIndices = includeIndices && excludeAttributes.indexOf("index") === -1;
|
|
5351
|
+
includeNormals = includeNormals && excludeAttributes.indexOf("normal") === -1;
|
|
5352
|
+
includeColors = includeColors && excludeAttributes.indexOf("color") === -1;
|
|
5353
|
+
includeUVs = includeUVs && excludeAttributes.indexOf("uv") === -1;
|
|
5354
|
+
if (includeIndices && faceCount !== Math.floor(faceCount)) {
|
|
5355
|
+
console.error(
|
|
5356
|
+
"PLYExporter: Failed to generate a valid PLY file with triangle indices because the number of indices is not divisible by 3."
|
|
5357
|
+
);
|
|
5358
|
+
return null;
|
|
5359
|
+
}
|
|
5360
|
+
const indexByteCount = 4;
|
|
5361
|
+
let header = `ply
|
|
5362
|
+
format ${options.binary ? options.littleEndian ? "binary_little_endian" : "binary_big_endian" : "ascii"} 1.0
|
|
5363
|
+
element vertex ${vertexCount}
|
|
5364
|
+
property float x
|
|
5365
|
+
property float y
|
|
5366
|
+
property float z
|
|
5367
|
+
`;
|
|
5368
|
+
if (includeNormals === true) {
|
|
5369
|
+
header += "property float nx\nproperty float ny\nproperty float nz\n";
|
|
5370
|
+
}
|
|
5371
|
+
if (includeUVs === true) {
|
|
5372
|
+
header += "property float s\nproperty float t\n";
|
|
5373
|
+
}
|
|
5374
|
+
if (includeColors === true) {
|
|
5375
|
+
header += "property uchar red\nproperty uchar green\nproperty uchar blue\n";
|
|
5376
|
+
}
|
|
5377
|
+
if (includeIndices === true) {
|
|
5378
|
+
header += `element face ${faceCount}
|
|
5379
|
+
property list uchar int vertex_index
|
|
5380
|
+
`;
|
|
5381
|
+
}
|
|
5382
|
+
header += "end_header\n";
|
|
5383
|
+
const vertex = new import_three15.Vector3();
|
|
5384
|
+
const normalMatrixWorld = new import_three15.Matrix3();
|
|
5385
|
+
let result = null;
|
|
5386
|
+
if (options.binary === true) {
|
|
5387
|
+
const headerBin = new TextEncoder().encode(header);
|
|
5388
|
+
const vertexListLength = vertexCount * (4 * 3 + (includeNormals ? 4 * 3 : 0) + (includeColors ? 3 : 0) + (includeUVs ? 4 * 2 : 0));
|
|
5389
|
+
const faceListLength = includeIndices ? faceCount * (indexByteCount * 3 + 1) : 0;
|
|
5390
|
+
const output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
|
|
5391
|
+
new Uint8Array(output.buffer).set(headerBin, 0);
|
|
5392
|
+
let vOffset = headerBin.length;
|
|
5393
|
+
let fOffset = headerBin.length + vertexListLength;
|
|
5394
|
+
let writtenVertices = 0;
|
|
5395
|
+
traverseMeshes(function(mesh, geometry) {
|
|
5396
|
+
const vertices = geometry.getAttribute("position");
|
|
5397
|
+
const normals = geometry.getAttribute("normal");
|
|
5398
|
+
const uvs = geometry.getAttribute("uv");
|
|
5399
|
+
const colors = geometry.getAttribute("color");
|
|
5400
|
+
const indices = geometry.getIndex();
|
|
5401
|
+
normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
|
|
5402
|
+
for (let i = 0, l = vertices.count; i < l; i++) {
|
|
5403
|
+
vertex.fromBufferAttribute(vertices, i);
|
|
5404
|
+
vertex.applyMatrix4(mesh.matrixWorld);
|
|
5405
|
+
output.setFloat32(vOffset, vertex.x, options.littleEndian);
|
|
5406
|
+
vOffset += 4;
|
|
5407
|
+
output.setFloat32(vOffset, vertex.y, options.littleEndian);
|
|
5408
|
+
vOffset += 4;
|
|
5409
|
+
output.setFloat32(vOffset, vertex.z, options.littleEndian);
|
|
5410
|
+
vOffset += 4;
|
|
5411
|
+
if (includeNormals === true) {
|
|
5412
|
+
if (normals != null) {
|
|
5413
|
+
vertex.fromBufferAttribute(normals, i);
|
|
5414
|
+
vertex.applyMatrix3(normalMatrixWorld).normalize();
|
|
5415
|
+
output.setFloat32(vOffset, vertex.x, options.littleEndian);
|
|
5416
|
+
vOffset += 4;
|
|
5417
|
+
output.setFloat32(vOffset, vertex.y, options.littleEndian);
|
|
5418
|
+
vOffset += 4;
|
|
5419
|
+
output.setFloat32(vOffset, vertex.z, options.littleEndian);
|
|
5420
|
+
vOffset += 4;
|
|
5421
|
+
} else {
|
|
5422
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
5423
|
+
vOffset += 4;
|
|
5424
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
5425
|
+
vOffset += 4;
|
|
5426
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
5427
|
+
vOffset += 4;
|
|
5428
|
+
}
|
|
5429
|
+
}
|
|
5430
|
+
if (includeUVs === true) {
|
|
5431
|
+
if (uvs != null) {
|
|
5432
|
+
output.setFloat32(vOffset, uvs.getX(i), options.littleEndian);
|
|
5433
|
+
vOffset += 4;
|
|
5434
|
+
output.setFloat32(vOffset, uvs.getY(i), options.littleEndian);
|
|
5435
|
+
vOffset += 4;
|
|
5436
|
+
} else {
|
|
5437
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
5438
|
+
vOffset += 4;
|
|
5439
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
5440
|
+
vOffset += 4;
|
|
5441
|
+
}
|
|
5442
|
+
}
|
|
5443
|
+
if (includeColors === true) {
|
|
5444
|
+
if (colors != null) {
|
|
5445
|
+
tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
|
|
5446
|
+
output.setUint8(vOffset, Math.floor(tempColor.r * 255));
|
|
5447
|
+
vOffset += 1;
|
|
5448
|
+
output.setUint8(vOffset, Math.floor(tempColor.g * 255));
|
|
5449
|
+
vOffset += 1;
|
|
5450
|
+
output.setUint8(vOffset, Math.floor(tempColor.b * 255));
|
|
5451
|
+
vOffset += 1;
|
|
5452
|
+
} else {
|
|
5453
|
+
output.setUint8(vOffset, 255);
|
|
5454
|
+
vOffset += 1;
|
|
5455
|
+
output.setUint8(vOffset, 255);
|
|
5456
|
+
vOffset += 1;
|
|
5457
|
+
output.setUint8(vOffset, 255);
|
|
5458
|
+
vOffset += 1;
|
|
5459
|
+
}
|
|
5460
|
+
}
|
|
5461
|
+
}
|
|
5462
|
+
if (includeIndices === true) {
|
|
5463
|
+
if (indices !== null) {
|
|
5464
|
+
for (let i = 0, l = indices.count; i < l; i += 3) {
|
|
5465
|
+
output.setUint8(fOffset, 3);
|
|
5466
|
+
fOffset += 1;
|
|
5467
|
+
output.setUint32(fOffset, indices.getX(i + 0) + writtenVertices, options.littleEndian);
|
|
5468
|
+
fOffset += indexByteCount;
|
|
5469
|
+
output.setUint32(fOffset, indices.getX(i + 1) + writtenVertices, options.littleEndian);
|
|
5470
|
+
fOffset += indexByteCount;
|
|
5471
|
+
output.setUint32(fOffset, indices.getX(i + 2) + writtenVertices, options.littleEndian);
|
|
5472
|
+
fOffset += indexByteCount;
|
|
5473
|
+
}
|
|
5474
|
+
} else {
|
|
5475
|
+
for (let i = 0, l = vertices.count; i < l; i += 3) {
|
|
5476
|
+
output.setUint8(fOffset, 3);
|
|
5477
|
+
fOffset += 1;
|
|
5478
|
+
output.setUint32(fOffset, writtenVertices + i, options.littleEndian);
|
|
5479
|
+
fOffset += indexByteCount;
|
|
5480
|
+
output.setUint32(fOffset, writtenVertices + i + 1, options.littleEndian);
|
|
5481
|
+
fOffset += indexByteCount;
|
|
5482
|
+
output.setUint32(fOffset, writtenVertices + i + 2, options.littleEndian);
|
|
5483
|
+
fOffset += indexByteCount;
|
|
5484
|
+
}
|
|
5485
|
+
}
|
|
5486
|
+
}
|
|
5487
|
+
writtenVertices += vertices.count;
|
|
5488
|
+
});
|
|
5489
|
+
result = output.buffer;
|
|
5490
|
+
} else {
|
|
5491
|
+
let writtenVertices = 0;
|
|
5492
|
+
let vertexList = "";
|
|
5493
|
+
let faceList = "";
|
|
5494
|
+
traverseMeshes(function(mesh, geometry) {
|
|
5495
|
+
const vertices = geometry.getAttribute("position");
|
|
5496
|
+
const normals = geometry.getAttribute("normal");
|
|
5497
|
+
const uvs = geometry.getAttribute("uv");
|
|
5498
|
+
const colors = geometry.getAttribute("color");
|
|
5499
|
+
const indices = geometry.getIndex();
|
|
5500
|
+
normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
|
|
5501
|
+
for (let i = 0, l = vertices.count; i < l; i++) {
|
|
5502
|
+
vertex.fromBufferAttribute(vertices, i);
|
|
5503
|
+
vertex.applyMatrix4(mesh.matrixWorld);
|
|
5504
|
+
let line = vertex.x + " " + vertex.y + " " + vertex.z;
|
|
5505
|
+
if (includeNormals === true) {
|
|
5506
|
+
if (normals != null) {
|
|
5507
|
+
vertex.fromBufferAttribute(normals, i);
|
|
5508
|
+
vertex.applyMatrix3(normalMatrixWorld).normalize();
|
|
5509
|
+
line += " " + vertex.x + " " + vertex.y + " " + vertex.z;
|
|
5510
|
+
} else {
|
|
5511
|
+
line += " 0 0 0";
|
|
5512
|
+
}
|
|
5513
|
+
}
|
|
5514
|
+
if (includeUVs === true) {
|
|
5515
|
+
if (uvs != null) {
|
|
5516
|
+
line += " " + uvs.getX(i) + " " + uvs.getY(i);
|
|
5517
|
+
} else {
|
|
5518
|
+
line += " 0 0";
|
|
5519
|
+
}
|
|
5520
|
+
}
|
|
5521
|
+
if (includeColors === true) {
|
|
5522
|
+
if (colors != null) {
|
|
5523
|
+
tempColor.fromBufferAttribute(colors, i).convertLinearToSRGB();
|
|
5524
|
+
line += " " + Math.floor(tempColor.r * 255) + " " + Math.floor(tempColor.g * 255) + " " + Math.floor(tempColor.b * 255);
|
|
5525
|
+
} else {
|
|
5526
|
+
line += " 255 255 255";
|
|
5527
|
+
}
|
|
5528
|
+
}
|
|
5529
|
+
vertexList += line + "\n";
|
|
5530
|
+
}
|
|
5531
|
+
if (includeIndices === true) {
|
|
5532
|
+
if (indices !== null) {
|
|
5533
|
+
for (let i = 0, l = indices.count; i < l; i += 3) {
|
|
5534
|
+
faceList += `3 ${indices.getX(i + 0) + writtenVertices}`;
|
|
5535
|
+
faceList += ` ${indices.getX(i + 1) + writtenVertices}`;
|
|
5536
|
+
faceList += ` ${indices.getX(i + 2) + writtenVertices}
|
|
5537
|
+
`;
|
|
5538
|
+
}
|
|
5539
|
+
} else {
|
|
5540
|
+
for (let i = 0, l = vertices.count; i < l; i += 3) {
|
|
5541
|
+
faceList += `3 ${writtenVertices + i} ${writtenVertices + i + 1} ${writtenVertices + i + 2}
|
|
5542
|
+
`;
|
|
5543
|
+
}
|
|
5544
|
+
}
|
|
5545
|
+
faceCount += indices ? indices.count / 3 : vertices.count / 3;
|
|
5546
|
+
}
|
|
5547
|
+
writtenVertices += vertices.count;
|
|
5548
|
+
});
|
|
5549
|
+
result = `${header}${vertexList}${includeIndices ? `${faceList}
|
|
5550
|
+
` : "\n"}`;
|
|
5551
|
+
}
|
|
5552
|
+
if (typeof onDone === "function") requestAnimationFrame(() => onDone(result));
|
|
5553
|
+
return result;
|
|
5554
|
+
}
|
|
5555
|
+
};
|
|
5556
|
+
|
|
5557
|
+
// ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
|
|
5558
|
+
var import_three17 = require("three");
|
|
5559
|
+
|
|
5560
|
+
// ../../node_modules/three/examples/jsm/utils/TextureUtils.js
|
|
5561
|
+
var import_three16 = require("three");
|
|
5562
|
+
var _renderer;
|
|
5563
|
+
var fullscreenQuadGeometry;
|
|
5564
|
+
var fullscreenQuadMaterial;
|
|
5565
|
+
var fullscreenQuad;
|
|
5566
|
+
function decompress(texture, maxTextureSize = Infinity, renderer = null) {
|
|
5567
|
+
if (!fullscreenQuadGeometry) fullscreenQuadGeometry = new import_three16.PlaneGeometry(2, 2, 1, 1);
|
|
5568
|
+
if (!fullscreenQuadMaterial) fullscreenQuadMaterial = new import_three16.ShaderMaterial({
|
|
5569
|
+
uniforms: { blitTexture: new import_three16.Uniform(texture) },
|
|
5570
|
+
vertexShader: `
|
|
5571
|
+
varying vec2 vUv;
|
|
5572
|
+
void main(){
|
|
5573
|
+
vUv = uv;
|
|
5574
|
+
gl_Position = vec4(position.xy * 1.0,0.,.999999);
|
|
5575
|
+
}`,
|
|
5576
|
+
fragmentShader: `
|
|
5577
|
+
uniform sampler2D blitTexture;
|
|
5578
|
+
varying vec2 vUv;
|
|
5579
|
+
|
|
5580
|
+
void main(){
|
|
5581
|
+
gl_FragColor = vec4(vUv.xy, 0, 1);
|
|
5582
|
+
|
|
5583
|
+
#ifdef IS_SRGB
|
|
5584
|
+
gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
|
|
5585
|
+
#else
|
|
5586
|
+
gl_FragColor = texture2D( blitTexture, vUv);
|
|
5587
|
+
#endif
|
|
5588
|
+
}`
|
|
5589
|
+
});
|
|
5590
|
+
fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
|
|
5591
|
+
fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == import_three16.SRGBColorSpace;
|
|
5592
|
+
fullscreenQuadMaterial.needsUpdate = true;
|
|
5593
|
+
if (!fullscreenQuad) {
|
|
5594
|
+
fullscreenQuad = new import_three16.Mesh(fullscreenQuadGeometry, fullscreenQuadMaterial);
|
|
5595
|
+
fullscreenQuad.frustrumCulled = false;
|
|
5596
|
+
}
|
|
5597
|
+
const _camera = new import_three16.PerspectiveCamera();
|
|
5598
|
+
const _scene = new import_three16.Scene();
|
|
5599
|
+
_scene.add(fullscreenQuad);
|
|
5600
|
+
if (!renderer) {
|
|
5601
|
+
renderer = _renderer = new import_three16.WebGLRenderer({ antialias: false });
|
|
5602
|
+
}
|
|
5603
|
+
renderer.setSize(Math.min(texture.image.width, maxTextureSize), Math.min(texture.image.height, maxTextureSize));
|
|
5604
|
+
renderer.clear();
|
|
5605
|
+
renderer.render(_scene, _camera);
|
|
5606
|
+
const readableTexture = new import_three16.Texture(renderer.domElement);
|
|
5607
|
+
readableTexture.minFilter = texture.minFilter;
|
|
5608
|
+
readableTexture.magFilter = texture.magFilter;
|
|
5609
|
+
readableTexture.wrapS = texture.wrapS;
|
|
5610
|
+
readableTexture.wrapT = texture.wrapT;
|
|
5611
|
+
readableTexture.name = texture.name;
|
|
5612
|
+
if (_renderer) {
|
|
5613
|
+
_renderer.dispose();
|
|
5614
|
+
_renderer = null;
|
|
5615
|
+
}
|
|
5616
|
+
return readableTexture;
|
|
5617
|
+
}
|
|
5618
|
+
|
|
5619
|
+
// ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
|
|
5620
|
+
var KHR_mesh_quantization_ExtraAttrTypes = {
|
|
5621
|
+
POSITION: [
|
|
5622
|
+
"byte",
|
|
5623
|
+
"byte normalized",
|
|
5624
|
+
"unsigned byte",
|
|
5625
|
+
"unsigned byte normalized",
|
|
5626
|
+
"short",
|
|
5627
|
+
"short normalized",
|
|
5628
|
+
"unsigned short",
|
|
5629
|
+
"unsigned short normalized"
|
|
5630
|
+
],
|
|
5631
|
+
NORMAL: [
|
|
5632
|
+
"byte normalized",
|
|
5633
|
+
"short normalized"
|
|
5634
|
+
],
|
|
5635
|
+
TANGENT: [
|
|
5636
|
+
"byte normalized",
|
|
5637
|
+
"short normalized"
|
|
5638
|
+
],
|
|
5639
|
+
TEXCOORD: [
|
|
5640
|
+
"byte",
|
|
5641
|
+
"byte normalized",
|
|
5642
|
+
"unsigned byte",
|
|
5643
|
+
"short",
|
|
5644
|
+
"short normalized",
|
|
5645
|
+
"unsigned short"
|
|
5646
|
+
]
|
|
5647
|
+
};
|
|
5648
|
+
var GLTFExporter = class {
|
|
5649
|
+
constructor() {
|
|
5650
|
+
this.pluginCallbacks = [];
|
|
5651
|
+
this.register(function(writer) {
|
|
5652
|
+
return new GLTFLightExtension(writer);
|
|
5653
|
+
});
|
|
5654
|
+
this.register(function(writer) {
|
|
5655
|
+
return new GLTFMaterialsUnlitExtension(writer);
|
|
5656
|
+
});
|
|
5657
|
+
this.register(function(writer) {
|
|
5658
|
+
return new GLTFMaterialsTransmissionExtension(writer);
|
|
5659
|
+
});
|
|
5660
|
+
this.register(function(writer) {
|
|
5661
|
+
return new GLTFMaterialsVolumeExtension(writer);
|
|
5662
|
+
});
|
|
5663
|
+
this.register(function(writer) {
|
|
5664
|
+
return new GLTFMaterialsIorExtension(writer);
|
|
5665
|
+
});
|
|
5666
|
+
this.register(function(writer) {
|
|
5667
|
+
return new GLTFMaterialsSpecularExtension(writer);
|
|
5668
|
+
});
|
|
5669
|
+
this.register(function(writer) {
|
|
5670
|
+
return new GLTFMaterialsClearcoatExtension(writer);
|
|
5671
|
+
});
|
|
5672
|
+
this.register(function(writer) {
|
|
5673
|
+
return new GLTFMaterialsIridescenceExtension(writer);
|
|
5674
|
+
});
|
|
5675
|
+
this.register(function(writer) {
|
|
5676
|
+
return new GLTFMaterialsSheenExtension(writer);
|
|
5677
|
+
});
|
|
5678
|
+
this.register(function(writer) {
|
|
5679
|
+
return new GLTFMaterialsAnisotropyExtension(writer);
|
|
5680
|
+
});
|
|
5681
|
+
this.register(function(writer) {
|
|
5682
|
+
return new GLTFMaterialsEmissiveStrengthExtension(writer);
|
|
5683
|
+
});
|
|
5684
|
+
this.register(function(writer) {
|
|
5685
|
+
return new GLTFMeshGpuInstancing(writer);
|
|
5686
|
+
});
|
|
5687
|
+
}
|
|
5688
|
+
register(callback) {
|
|
5689
|
+
if (this.pluginCallbacks.indexOf(callback) === -1) {
|
|
5690
|
+
this.pluginCallbacks.push(callback);
|
|
5691
|
+
}
|
|
5692
|
+
return this;
|
|
5693
|
+
}
|
|
5694
|
+
unregister(callback) {
|
|
5695
|
+
if (this.pluginCallbacks.indexOf(callback) !== -1) {
|
|
5696
|
+
this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
|
|
5697
|
+
}
|
|
5698
|
+
return this;
|
|
5699
|
+
}
|
|
5700
|
+
/**
|
|
5701
|
+
* Parse scenes and generate GLTF output
|
|
5702
|
+
* @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
|
|
5703
|
+
* @param {Function} onDone Callback on completed
|
|
5704
|
+
* @param {Function} onError Callback on errors
|
|
5705
|
+
* @param {Object} options options
|
|
5706
|
+
*/
|
|
5707
|
+
parse(input, onDone, onError, options) {
|
|
5708
|
+
const writer = new GLTFWriter();
|
|
5709
|
+
const plugins = [];
|
|
5710
|
+
for (let i = 0, il = this.pluginCallbacks.length; i < il; i++) {
|
|
5711
|
+
plugins.push(this.pluginCallbacks[i](writer));
|
|
5712
|
+
}
|
|
5713
|
+
writer.setPlugins(plugins);
|
|
5714
|
+
writer.write(input, onDone, options).catch(onError);
|
|
5715
|
+
}
|
|
5716
|
+
parseAsync(input, options) {
|
|
5717
|
+
const scope = this;
|
|
5718
|
+
return new Promise(function(resolve, reject) {
|
|
5719
|
+
scope.parse(input, resolve, reject, options);
|
|
5720
|
+
});
|
|
5721
|
+
}
|
|
5722
|
+
};
|
|
5723
|
+
var WEBGL_CONSTANTS = {
|
|
5724
|
+
POINTS: 0,
|
|
5725
|
+
LINES: 1,
|
|
5726
|
+
LINE_LOOP: 2,
|
|
5727
|
+
LINE_STRIP: 3,
|
|
5728
|
+
TRIANGLES: 4,
|
|
5729
|
+
TRIANGLE_STRIP: 5,
|
|
5730
|
+
TRIANGLE_FAN: 6,
|
|
5731
|
+
BYTE: 5120,
|
|
5732
|
+
UNSIGNED_BYTE: 5121,
|
|
5733
|
+
SHORT: 5122,
|
|
5734
|
+
UNSIGNED_SHORT: 5123,
|
|
5735
|
+
INT: 5124,
|
|
5736
|
+
UNSIGNED_INT: 5125,
|
|
5737
|
+
FLOAT: 5126,
|
|
5738
|
+
ARRAY_BUFFER: 34962,
|
|
5739
|
+
ELEMENT_ARRAY_BUFFER: 34963,
|
|
5740
|
+
NEAREST: 9728,
|
|
5741
|
+
LINEAR: 9729,
|
|
5742
|
+
NEAREST_MIPMAP_NEAREST: 9984,
|
|
5743
|
+
LINEAR_MIPMAP_NEAREST: 9985,
|
|
5744
|
+
NEAREST_MIPMAP_LINEAR: 9986,
|
|
5745
|
+
LINEAR_MIPMAP_LINEAR: 9987,
|
|
5746
|
+
CLAMP_TO_EDGE: 33071,
|
|
5747
|
+
MIRRORED_REPEAT: 33648,
|
|
5748
|
+
REPEAT: 10497
|
|
5749
|
+
};
|
|
5750
|
+
var KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
|
|
5751
|
+
var THREE_TO_WEBGL = {};
|
|
5752
|
+
THREE_TO_WEBGL[import_three17.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
|
|
5753
|
+
THREE_TO_WEBGL[import_three17.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
|
|
5754
|
+
THREE_TO_WEBGL[import_three17.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
|
|
5755
|
+
THREE_TO_WEBGL[import_three17.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
|
|
5756
|
+
THREE_TO_WEBGL[import_three17.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
|
|
5757
|
+
THREE_TO_WEBGL[import_three17.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
|
|
5758
|
+
THREE_TO_WEBGL[import_three17.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
|
|
5759
|
+
THREE_TO_WEBGL[import_three17.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
|
|
5760
|
+
THREE_TO_WEBGL[import_three17.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
|
|
5761
|
+
var PATH_PROPERTIES = {
|
|
5762
|
+
scale: "scale",
|
|
5763
|
+
position: "translation",
|
|
5764
|
+
quaternion: "rotation",
|
|
5765
|
+
morphTargetInfluences: "weights"
|
|
5766
|
+
};
|
|
5767
|
+
var DEFAULT_SPECULAR_COLOR = new import_three17.Color();
|
|
5768
|
+
var GLB_HEADER_BYTES = 12;
|
|
5769
|
+
var GLB_HEADER_MAGIC = 1179937895;
|
|
5770
|
+
var GLB_VERSION = 2;
|
|
5771
|
+
var GLB_CHUNK_PREFIX_BYTES = 8;
|
|
5772
|
+
var GLB_CHUNK_TYPE_JSON = 1313821514;
|
|
5773
|
+
var GLB_CHUNK_TYPE_BIN = 5130562;
|
|
5774
|
+
function equalArray(array1, array2) {
|
|
5775
|
+
return array1.length === array2.length && array1.every(function(element, index) {
|
|
5776
|
+
return element === array2[index];
|
|
5777
|
+
});
|
|
5778
|
+
}
|
|
5779
|
+
function stringToArrayBuffer(text) {
|
|
5780
|
+
return new TextEncoder().encode(text).buffer;
|
|
5781
|
+
}
|
|
5782
|
+
function isIdentityMatrix(matrix) {
|
|
5783
|
+
return equalArray(matrix.elements, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
|
|
5784
|
+
}
|
|
5785
|
+
function getMinMax(attribute, start, count) {
|
|
5786
|
+
const output = {
|
|
5787
|
+
min: new Array(attribute.itemSize).fill(Number.POSITIVE_INFINITY),
|
|
5788
|
+
max: new Array(attribute.itemSize).fill(Number.NEGATIVE_INFINITY)
|
|
5789
|
+
};
|
|
5790
|
+
for (let i = start; i < start + count; i++) {
|
|
5791
|
+
for (let a = 0; a < attribute.itemSize; a++) {
|
|
5792
|
+
let value;
|
|
5793
|
+
if (attribute.itemSize > 4) {
|
|
5794
|
+
value = attribute.array[i * attribute.itemSize + a];
|
|
5795
|
+
} else {
|
|
5796
|
+
if (a === 0) value = attribute.getX(i);
|
|
5797
|
+
else if (a === 1) value = attribute.getY(i);
|
|
5798
|
+
else if (a === 2) value = attribute.getZ(i);
|
|
5799
|
+
else if (a === 3) value = attribute.getW(i);
|
|
5800
|
+
if (attribute.normalized === true) {
|
|
5801
|
+
value = import_three17.MathUtils.normalize(value, attribute.array);
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5804
|
+
output.min[a] = Math.min(output.min[a], value);
|
|
5805
|
+
output.max[a] = Math.max(output.max[a], value);
|
|
5806
|
+
}
|
|
5807
|
+
}
|
|
5808
|
+
return output;
|
|
5809
|
+
}
|
|
5810
|
+
function getPaddedBufferSize(bufferSize) {
|
|
5811
|
+
return Math.ceil(bufferSize / 4) * 4;
|
|
5812
|
+
}
|
|
5813
|
+
function getPaddedArrayBuffer(arrayBuffer, paddingByte = 0) {
|
|
5814
|
+
const paddedLength = getPaddedBufferSize(arrayBuffer.byteLength);
|
|
5815
|
+
if (paddedLength !== arrayBuffer.byteLength) {
|
|
5816
|
+
const array = new Uint8Array(paddedLength);
|
|
5817
|
+
array.set(new Uint8Array(arrayBuffer));
|
|
5818
|
+
if (paddingByte !== 0) {
|
|
5819
|
+
for (let i = arrayBuffer.byteLength; i < paddedLength; i++) {
|
|
5820
|
+
array[i] = paddingByte;
|
|
5821
|
+
}
|
|
5822
|
+
}
|
|
5823
|
+
return array.buffer;
|
|
5824
|
+
}
|
|
5825
|
+
return arrayBuffer;
|
|
5826
|
+
}
|
|
5827
|
+
function getCanvas() {
|
|
5828
|
+
if (typeof document === "undefined" && typeof OffscreenCanvas !== "undefined") {
|
|
5829
|
+
return new OffscreenCanvas(1, 1);
|
|
5830
|
+
}
|
|
5831
|
+
return document.createElement("canvas");
|
|
5832
|
+
}
|
|
5833
|
+
function getToBlobPromise(canvas, mimeType) {
|
|
5834
|
+
if (canvas.toBlob !== void 0) {
|
|
5835
|
+
return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
|
|
5836
|
+
}
|
|
5837
|
+
let quality;
|
|
5838
|
+
if (mimeType === "image/jpeg") {
|
|
5839
|
+
quality = 0.92;
|
|
5840
|
+
} else if (mimeType === "image/webp") {
|
|
5841
|
+
quality = 0.8;
|
|
5842
|
+
}
|
|
5843
|
+
return canvas.convertToBlob({
|
|
5844
|
+
type: mimeType,
|
|
5845
|
+
quality
|
|
5846
|
+
});
|
|
5847
|
+
}
|
|
5848
|
+
var GLTFWriter = class {
|
|
5849
|
+
constructor() {
|
|
5850
|
+
this.plugins = [];
|
|
5851
|
+
this.options = {};
|
|
5852
|
+
this.pending = [];
|
|
5853
|
+
this.buffers = [];
|
|
5854
|
+
this.byteOffset = 0;
|
|
5855
|
+
this.buffers = [];
|
|
5856
|
+
this.nodeMap = /* @__PURE__ */ new Map();
|
|
5857
|
+
this.skins = [];
|
|
5858
|
+
this.extensionsUsed = {};
|
|
5859
|
+
this.extensionsRequired = {};
|
|
5860
|
+
this.uids = /* @__PURE__ */ new Map();
|
|
5861
|
+
this.uid = 0;
|
|
5862
|
+
this.json = {
|
|
5863
|
+
asset: {
|
|
5864
|
+
version: "2.0",
|
|
5865
|
+
generator: "THREE.GLTFExporter"
|
|
5866
|
+
}
|
|
5867
|
+
};
|
|
5868
|
+
this.cache = {
|
|
5869
|
+
meshes: /* @__PURE__ */ new Map(),
|
|
5870
|
+
attributes: /* @__PURE__ */ new Map(),
|
|
5871
|
+
attributesNormalized: /* @__PURE__ */ new Map(),
|
|
5872
|
+
materials: /* @__PURE__ */ new Map(),
|
|
5873
|
+
textures: /* @__PURE__ */ new Map(),
|
|
5874
|
+
images: /* @__PURE__ */ new Map()
|
|
5875
|
+
};
|
|
5876
|
+
}
|
|
5877
|
+
setPlugins(plugins) {
|
|
5878
|
+
this.plugins = plugins;
|
|
5879
|
+
}
|
|
5880
|
+
/**
|
|
5881
|
+
* Parse scenes and generate GLTF output
|
|
5882
|
+
* @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
|
|
5883
|
+
* @param {Function} onDone Callback on completed
|
|
5884
|
+
* @param {Object} options options
|
|
5885
|
+
*/
|
|
5886
|
+
async write(input, onDone, options = {}) {
|
|
5887
|
+
this.options = Object.assign({
|
|
5888
|
+
// default options
|
|
5889
|
+
binary: false,
|
|
5890
|
+
trs: false,
|
|
5891
|
+
onlyVisible: true,
|
|
5892
|
+
maxTextureSize: Infinity,
|
|
5893
|
+
animations: [],
|
|
5894
|
+
includeCustomExtensions: false
|
|
5895
|
+
}, options);
|
|
5896
|
+
if (this.options.animations.length > 0) {
|
|
5897
|
+
this.options.trs = true;
|
|
5898
|
+
}
|
|
5899
|
+
this.processInput(input);
|
|
5900
|
+
await Promise.all(this.pending);
|
|
5901
|
+
const writer = this;
|
|
5902
|
+
const buffers = writer.buffers;
|
|
5903
|
+
const json = writer.json;
|
|
5904
|
+
options = writer.options;
|
|
5905
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
5906
|
+
const extensionsRequired = writer.extensionsRequired;
|
|
5907
|
+
const blob = new Blob(buffers, { type: "application/octet-stream" });
|
|
5908
|
+
const extensionsUsedList = Object.keys(extensionsUsed);
|
|
5909
|
+
const extensionsRequiredList = Object.keys(extensionsRequired);
|
|
5910
|
+
if (extensionsUsedList.length > 0) json.extensionsUsed = extensionsUsedList;
|
|
5911
|
+
if (extensionsRequiredList.length > 0) json.extensionsRequired = extensionsRequiredList;
|
|
5912
|
+
if (json.buffers && json.buffers.length > 0) json.buffers[0].byteLength = blob.size;
|
|
5913
|
+
if (options.binary === true) {
|
|
5914
|
+
const reader = new FileReader();
|
|
5915
|
+
reader.readAsArrayBuffer(blob);
|
|
5916
|
+
reader.onloadend = function() {
|
|
5917
|
+
const binaryChunk = getPaddedArrayBuffer(reader.result);
|
|
5918
|
+
const binaryChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
|
|
5919
|
+
binaryChunkPrefix.setUint32(0, binaryChunk.byteLength, true);
|
|
5920
|
+
binaryChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_BIN, true);
|
|
5921
|
+
const jsonChunk = getPaddedArrayBuffer(stringToArrayBuffer(JSON.stringify(json)), 32);
|
|
5922
|
+
const jsonChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
|
|
5923
|
+
jsonChunkPrefix.setUint32(0, jsonChunk.byteLength, true);
|
|
5924
|
+
jsonChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_JSON, true);
|
|
5925
|
+
const header = new ArrayBuffer(GLB_HEADER_BYTES);
|
|
5926
|
+
const headerView = new DataView(header);
|
|
5927
|
+
headerView.setUint32(0, GLB_HEADER_MAGIC, true);
|
|
5928
|
+
headerView.setUint32(4, GLB_VERSION, true);
|
|
5929
|
+
const totalByteLength = GLB_HEADER_BYTES + jsonChunkPrefix.byteLength + jsonChunk.byteLength + binaryChunkPrefix.byteLength + binaryChunk.byteLength;
|
|
5930
|
+
headerView.setUint32(8, totalByteLength, true);
|
|
5931
|
+
const glbBlob = new Blob([
|
|
5932
|
+
header,
|
|
5933
|
+
jsonChunkPrefix,
|
|
5934
|
+
jsonChunk,
|
|
5935
|
+
binaryChunkPrefix,
|
|
5936
|
+
binaryChunk
|
|
5937
|
+
], { type: "application/octet-stream" });
|
|
5938
|
+
const glbReader = new FileReader();
|
|
5939
|
+
glbReader.readAsArrayBuffer(glbBlob);
|
|
5940
|
+
glbReader.onloadend = function() {
|
|
5941
|
+
onDone(glbReader.result);
|
|
5942
|
+
};
|
|
5943
|
+
};
|
|
5944
|
+
} else {
|
|
5945
|
+
if (json.buffers && json.buffers.length > 0) {
|
|
5946
|
+
const reader = new FileReader();
|
|
5947
|
+
reader.readAsDataURL(blob);
|
|
5948
|
+
reader.onloadend = function() {
|
|
5949
|
+
const base64data = reader.result;
|
|
5950
|
+
json.buffers[0].uri = base64data;
|
|
5951
|
+
onDone(json);
|
|
5952
|
+
};
|
|
5953
|
+
} else {
|
|
5954
|
+
onDone(json);
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5957
|
+
}
|
|
5958
|
+
/**
|
|
5959
|
+
* Serializes a userData.
|
|
5960
|
+
*
|
|
5961
|
+
* @param {THREE.Object3D|THREE.Material} object
|
|
5962
|
+
* @param {Object} objectDef
|
|
5963
|
+
*/
|
|
5964
|
+
serializeUserData(object, objectDef) {
|
|
5965
|
+
if (Object.keys(object.userData).length === 0) return;
|
|
5966
|
+
const options = this.options;
|
|
5967
|
+
const extensionsUsed = this.extensionsUsed;
|
|
5968
|
+
try {
|
|
5969
|
+
const json = JSON.parse(JSON.stringify(object.userData));
|
|
5970
|
+
if (options.includeCustomExtensions && json.gltfExtensions) {
|
|
5971
|
+
if (objectDef.extensions === void 0) objectDef.extensions = {};
|
|
5972
|
+
for (const extensionName in json.gltfExtensions) {
|
|
5973
|
+
objectDef.extensions[extensionName] = json.gltfExtensions[extensionName];
|
|
5974
|
+
extensionsUsed[extensionName] = true;
|
|
5975
|
+
}
|
|
5976
|
+
delete json.gltfExtensions;
|
|
5977
|
+
}
|
|
5978
|
+
if (Object.keys(json).length > 0) objectDef.extras = json;
|
|
5979
|
+
} catch (error) {
|
|
5980
|
+
console.warn("THREE.GLTFExporter: userData of '" + object.name + "' won't be serialized because of JSON.stringify error - " + error.message);
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
/**
|
|
5984
|
+
* Returns ids for buffer attributes.
|
|
5985
|
+
* @param {Object} object
|
|
5986
|
+
* @return {Integer}
|
|
5987
|
+
*/
|
|
5988
|
+
getUID(attribute, isRelativeCopy = false) {
|
|
5989
|
+
if (this.uids.has(attribute) === false) {
|
|
5990
|
+
const uids2 = /* @__PURE__ */ new Map();
|
|
5991
|
+
uids2.set(true, this.uid++);
|
|
5992
|
+
uids2.set(false, this.uid++);
|
|
5993
|
+
this.uids.set(attribute, uids2);
|
|
5994
|
+
}
|
|
5995
|
+
const uids = this.uids.get(attribute);
|
|
5996
|
+
return uids.get(isRelativeCopy);
|
|
5997
|
+
}
|
|
5998
|
+
/**
|
|
5999
|
+
* Checks if normal attribute values are normalized.
|
|
6000
|
+
*
|
|
6001
|
+
* @param {BufferAttribute} normal
|
|
6002
|
+
* @returns {Boolean}
|
|
6003
|
+
*/
|
|
6004
|
+
isNormalizedNormalAttribute(normal) {
|
|
6005
|
+
const cache = this.cache;
|
|
6006
|
+
if (cache.attributesNormalized.has(normal)) return false;
|
|
6007
|
+
const v = new import_three17.Vector3();
|
|
6008
|
+
for (let i = 0, il = normal.count; i < il; i++) {
|
|
6009
|
+
if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
|
|
6010
|
+
}
|
|
6011
|
+
return true;
|
|
6012
|
+
}
|
|
6013
|
+
/**
|
|
6014
|
+
* Creates normalized normal buffer attribute.
|
|
6015
|
+
*
|
|
6016
|
+
* @param {BufferAttribute} normal
|
|
6017
|
+
* @returns {BufferAttribute}
|
|
6018
|
+
*
|
|
6019
|
+
*/
|
|
6020
|
+
createNormalizedNormalAttribute(normal) {
|
|
6021
|
+
const cache = this.cache;
|
|
6022
|
+
if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
|
|
6023
|
+
const attribute = normal.clone();
|
|
6024
|
+
const v = new import_three17.Vector3();
|
|
6025
|
+
for (let i = 0, il = attribute.count; i < il; i++) {
|
|
6026
|
+
v.fromBufferAttribute(attribute, i);
|
|
6027
|
+
if (v.x === 0 && v.y === 0 && v.z === 0) {
|
|
6028
|
+
v.setX(1);
|
|
6029
|
+
} else {
|
|
6030
|
+
v.normalize();
|
|
6031
|
+
}
|
|
6032
|
+
attribute.setXYZ(i, v.x, v.y, v.z);
|
|
6033
|
+
}
|
|
6034
|
+
cache.attributesNormalized.set(normal, attribute);
|
|
6035
|
+
return attribute;
|
|
6036
|
+
}
|
|
6037
|
+
/**
|
|
6038
|
+
* Applies a texture transform, if present, to the map definition. Requires
|
|
6039
|
+
* the KHR_texture_transform extension.
|
|
6040
|
+
*
|
|
6041
|
+
* @param {Object} mapDef
|
|
6042
|
+
* @param {THREE.Texture} texture
|
|
6043
|
+
*/
|
|
6044
|
+
applyTextureTransform(mapDef, texture) {
|
|
6045
|
+
let didTransform = false;
|
|
6046
|
+
const transformDef = {};
|
|
6047
|
+
if (texture.offset.x !== 0 || texture.offset.y !== 0) {
|
|
6048
|
+
transformDef.offset = texture.offset.toArray();
|
|
6049
|
+
didTransform = true;
|
|
6050
|
+
}
|
|
6051
|
+
if (texture.rotation !== 0) {
|
|
6052
|
+
transformDef.rotation = texture.rotation;
|
|
6053
|
+
didTransform = true;
|
|
6054
|
+
}
|
|
6055
|
+
if (texture.repeat.x !== 1 || texture.repeat.y !== 1) {
|
|
6056
|
+
transformDef.scale = texture.repeat.toArray();
|
|
6057
|
+
didTransform = true;
|
|
6058
|
+
}
|
|
6059
|
+
if (didTransform) {
|
|
6060
|
+
mapDef.extensions = mapDef.extensions || {};
|
|
6061
|
+
mapDef.extensions["KHR_texture_transform"] = transformDef;
|
|
6062
|
+
this.extensionsUsed["KHR_texture_transform"] = true;
|
|
6063
|
+
}
|
|
6064
|
+
}
|
|
6065
|
+
buildMetalRoughTexture(metalnessMap, roughnessMap) {
|
|
6066
|
+
if (metalnessMap === roughnessMap) return metalnessMap;
|
|
6067
|
+
function getEncodingConversion(map) {
|
|
6068
|
+
if (map.colorSpace === import_three17.SRGBColorSpace) {
|
|
6069
|
+
return function SRGBToLinear(c) {
|
|
6070
|
+
return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
|
|
6071
|
+
};
|
|
6072
|
+
}
|
|
6073
|
+
return function LinearToLinear(c) {
|
|
6074
|
+
return c;
|
|
6075
|
+
};
|
|
6076
|
+
}
|
|
6077
|
+
console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
|
|
6078
|
+
if (metalnessMap instanceof import_three17.CompressedTexture) {
|
|
6079
|
+
metalnessMap = decompress(metalnessMap);
|
|
6080
|
+
}
|
|
6081
|
+
if (roughnessMap instanceof import_three17.CompressedTexture) {
|
|
6082
|
+
roughnessMap = decompress(roughnessMap);
|
|
6083
|
+
}
|
|
6084
|
+
const metalness = metalnessMap ? metalnessMap.image : null;
|
|
6085
|
+
const roughness = roughnessMap ? roughnessMap.image : null;
|
|
6086
|
+
const width = Math.max(metalness ? metalness.width : 0, roughness ? roughness.width : 0);
|
|
6087
|
+
const height = Math.max(metalness ? metalness.height : 0, roughness ? roughness.height : 0);
|
|
6088
|
+
const canvas = getCanvas();
|
|
6089
|
+
canvas.width = width;
|
|
6090
|
+
canvas.height = height;
|
|
6091
|
+
const context = canvas.getContext("2d");
|
|
6092
|
+
context.fillStyle = "#00ffff";
|
|
6093
|
+
context.fillRect(0, 0, width, height);
|
|
6094
|
+
const composite = context.getImageData(0, 0, width, height);
|
|
6095
|
+
if (metalness) {
|
|
6096
|
+
context.drawImage(metalness, 0, 0, width, height);
|
|
6097
|
+
const convert = getEncodingConversion(metalnessMap);
|
|
6098
|
+
const data = context.getImageData(0, 0, width, height).data;
|
|
6099
|
+
for (let i = 2; i < data.length; i += 4) {
|
|
6100
|
+
composite.data[i] = convert(data[i] / 256) * 256;
|
|
6101
|
+
}
|
|
6102
|
+
}
|
|
6103
|
+
if (roughness) {
|
|
6104
|
+
context.drawImage(roughness, 0, 0, width, height);
|
|
6105
|
+
const convert = getEncodingConversion(roughnessMap);
|
|
6106
|
+
const data = context.getImageData(0, 0, width, height).data;
|
|
6107
|
+
for (let i = 1; i < data.length; i += 4) {
|
|
6108
|
+
composite.data[i] = convert(data[i] / 256) * 256;
|
|
6109
|
+
}
|
|
6110
|
+
}
|
|
6111
|
+
context.putImageData(composite, 0, 0);
|
|
6112
|
+
const reference = metalnessMap || roughnessMap;
|
|
6113
|
+
const texture = reference.clone();
|
|
6114
|
+
texture.source = new import_three17.Source(canvas);
|
|
6115
|
+
texture.colorSpace = import_three17.NoColorSpace;
|
|
6116
|
+
texture.channel = (metalnessMap || roughnessMap).channel;
|
|
6117
|
+
if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
|
|
6118
|
+
console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
|
|
6119
|
+
}
|
|
6120
|
+
return texture;
|
|
6121
|
+
}
|
|
6122
|
+
/**
|
|
6123
|
+
* Process a buffer to append to the default one.
|
|
6124
|
+
* @param {ArrayBuffer} buffer
|
|
6125
|
+
* @return {Integer}
|
|
6126
|
+
*/
|
|
6127
|
+
processBuffer(buffer) {
|
|
6128
|
+
const json = this.json;
|
|
6129
|
+
const buffers = this.buffers;
|
|
6130
|
+
if (!json.buffers) json.buffers = [{ byteLength: 0 }];
|
|
6131
|
+
buffers.push(buffer);
|
|
6132
|
+
return 0;
|
|
6133
|
+
}
|
|
6134
|
+
/**
|
|
6135
|
+
* Process and generate a BufferView
|
|
6136
|
+
* @param {BufferAttribute} attribute
|
|
6137
|
+
* @param {number} componentType
|
|
6138
|
+
* @param {number} start
|
|
6139
|
+
* @param {number} count
|
|
6140
|
+
* @param {number} target (Optional) Target usage of the BufferView
|
|
6141
|
+
* @return {Object}
|
|
6142
|
+
*/
|
|
6143
|
+
processBufferView(attribute, componentType, start, count, target) {
|
|
6144
|
+
const json = this.json;
|
|
6145
|
+
if (!json.bufferViews) json.bufferViews = [];
|
|
6146
|
+
let componentSize;
|
|
6147
|
+
switch (componentType) {
|
|
6148
|
+
case WEBGL_CONSTANTS.BYTE:
|
|
6149
|
+
case WEBGL_CONSTANTS.UNSIGNED_BYTE:
|
|
6150
|
+
componentSize = 1;
|
|
6151
|
+
break;
|
|
6152
|
+
case WEBGL_CONSTANTS.SHORT:
|
|
6153
|
+
case WEBGL_CONSTANTS.UNSIGNED_SHORT:
|
|
6154
|
+
componentSize = 2;
|
|
6155
|
+
break;
|
|
6156
|
+
default:
|
|
6157
|
+
componentSize = 4;
|
|
6158
|
+
}
|
|
6159
|
+
const byteLength = getPaddedBufferSize(count * attribute.itemSize * componentSize);
|
|
6160
|
+
const dataView = new DataView(new ArrayBuffer(byteLength));
|
|
6161
|
+
let offset = 0;
|
|
6162
|
+
for (let i = start; i < start + count; i++) {
|
|
6163
|
+
for (let a = 0; a < attribute.itemSize; a++) {
|
|
6164
|
+
let value;
|
|
6165
|
+
if (attribute.itemSize > 4) {
|
|
6166
|
+
value = attribute.array[i * attribute.itemSize + a];
|
|
6167
|
+
} else {
|
|
6168
|
+
if (a === 0) value = attribute.getX(i);
|
|
6169
|
+
else if (a === 1) value = attribute.getY(i);
|
|
6170
|
+
else if (a === 2) value = attribute.getZ(i);
|
|
6171
|
+
else if (a === 3) value = attribute.getW(i);
|
|
6172
|
+
if (attribute.normalized === true) {
|
|
6173
|
+
value = import_three17.MathUtils.normalize(value, attribute.array);
|
|
6174
|
+
}
|
|
6175
|
+
}
|
|
6176
|
+
if (componentType === WEBGL_CONSTANTS.FLOAT) {
|
|
6177
|
+
dataView.setFloat32(offset, value, true);
|
|
6178
|
+
} else if (componentType === WEBGL_CONSTANTS.INT) {
|
|
6179
|
+
dataView.setInt32(offset, value, true);
|
|
6180
|
+
} else if (componentType === WEBGL_CONSTANTS.UNSIGNED_INT) {
|
|
6181
|
+
dataView.setUint32(offset, value, true);
|
|
6182
|
+
} else if (componentType === WEBGL_CONSTANTS.SHORT) {
|
|
6183
|
+
dataView.setInt16(offset, value, true);
|
|
6184
|
+
} else if (componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT) {
|
|
6185
|
+
dataView.setUint16(offset, value, true);
|
|
6186
|
+
} else if (componentType === WEBGL_CONSTANTS.BYTE) {
|
|
6187
|
+
dataView.setInt8(offset, value);
|
|
6188
|
+
} else if (componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE) {
|
|
6189
|
+
dataView.setUint8(offset, value);
|
|
6190
|
+
}
|
|
6191
|
+
offset += componentSize;
|
|
6192
|
+
}
|
|
6193
|
+
}
|
|
6194
|
+
const bufferViewDef = {
|
|
6195
|
+
buffer: this.processBuffer(dataView.buffer),
|
|
6196
|
+
byteOffset: this.byteOffset,
|
|
6197
|
+
byteLength
|
|
6198
|
+
};
|
|
6199
|
+
if (target !== void 0) bufferViewDef.target = target;
|
|
6200
|
+
if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
|
|
6201
|
+
bufferViewDef.byteStride = attribute.itemSize * componentSize;
|
|
6202
|
+
}
|
|
6203
|
+
this.byteOffset += byteLength;
|
|
6204
|
+
json.bufferViews.push(bufferViewDef);
|
|
6205
|
+
const output = {
|
|
6206
|
+
id: json.bufferViews.length - 1,
|
|
6207
|
+
byteLength: 0
|
|
6208
|
+
};
|
|
6209
|
+
return output;
|
|
6210
|
+
}
|
|
6211
|
+
/**
|
|
6212
|
+
* Process and generate a BufferView from an image Blob.
|
|
6213
|
+
* @param {Blob} blob
|
|
6214
|
+
* @return {Promise<Integer>}
|
|
6215
|
+
*/
|
|
6216
|
+
processBufferViewImage(blob) {
|
|
6217
|
+
const writer = this;
|
|
6218
|
+
const json = writer.json;
|
|
6219
|
+
if (!json.bufferViews) json.bufferViews = [];
|
|
6220
|
+
return new Promise(function(resolve) {
|
|
6221
|
+
const reader = new FileReader();
|
|
6222
|
+
reader.readAsArrayBuffer(blob);
|
|
6223
|
+
reader.onloadend = function() {
|
|
6224
|
+
const buffer = getPaddedArrayBuffer(reader.result);
|
|
6225
|
+
const bufferViewDef = {
|
|
6226
|
+
buffer: writer.processBuffer(buffer),
|
|
6227
|
+
byteOffset: writer.byteOffset,
|
|
6228
|
+
byteLength: buffer.byteLength
|
|
6229
|
+
};
|
|
6230
|
+
writer.byteOffset += buffer.byteLength;
|
|
6231
|
+
resolve(json.bufferViews.push(bufferViewDef) - 1);
|
|
6232
|
+
};
|
|
6233
|
+
});
|
|
6234
|
+
}
|
|
6235
|
+
/**
|
|
6236
|
+
* Process attribute to generate an accessor
|
|
6237
|
+
* @param {BufferAttribute} attribute Attribute to process
|
|
6238
|
+
* @param {THREE.BufferGeometry} geometry (Optional) Geometry used for truncated draw range
|
|
6239
|
+
* @param {Integer} start (Optional)
|
|
6240
|
+
* @param {Integer} count (Optional)
|
|
6241
|
+
* @return {Integer|null} Index of the processed accessor on the "accessors" array
|
|
6242
|
+
*/
|
|
6243
|
+
processAccessor(attribute, geometry, start, count) {
|
|
6244
|
+
const json = this.json;
|
|
6245
|
+
const types = {
|
|
6246
|
+
1: "SCALAR",
|
|
6247
|
+
2: "VEC2",
|
|
6248
|
+
3: "VEC3",
|
|
6249
|
+
4: "VEC4",
|
|
6250
|
+
9: "MAT3",
|
|
6251
|
+
16: "MAT4"
|
|
6252
|
+
};
|
|
6253
|
+
let componentType;
|
|
6254
|
+
if (attribute.array.constructor === Float32Array) {
|
|
6255
|
+
componentType = WEBGL_CONSTANTS.FLOAT;
|
|
6256
|
+
} else if (attribute.array.constructor === Int32Array) {
|
|
6257
|
+
componentType = WEBGL_CONSTANTS.INT;
|
|
6258
|
+
} else if (attribute.array.constructor === Uint32Array) {
|
|
6259
|
+
componentType = WEBGL_CONSTANTS.UNSIGNED_INT;
|
|
6260
|
+
} else if (attribute.array.constructor === Int16Array) {
|
|
6261
|
+
componentType = WEBGL_CONSTANTS.SHORT;
|
|
6262
|
+
} else if (attribute.array.constructor === Uint16Array) {
|
|
6263
|
+
componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT;
|
|
6264
|
+
} else if (attribute.array.constructor === Int8Array) {
|
|
6265
|
+
componentType = WEBGL_CONSTANTS.BYTE;
|
|
6266
|
+
} else if (attribute.array.constructor === Uint8Array) {
|
|
6267
|
+
componentType = WEBGL_CONSTANTS.UNSIGNED_BYTE;
|
|
6268
|
+
} else {
|
|
6269
|
+
throw new Error("THREE.GLTFExporter: Unsupported bufferAttribute component type: " + attribute.array.constructor.name);
|
|
6270
|
+
}
|
|
6271
|
+
if (start === void 0) start = 0;
|
|
6272
|
+
if (count === void 0 || count === Infinity) count = attribute.count;
|
|
6273
|
+
if (count === 0) return null;
|
|
6274
|
+
const minMax = getMinMax(attribute, start, count);
|
|
6275
|
+
let bufferViewTarget;
|
|
6276
|
+
if (geometry !== void 0) {
|
|
6277
|
+
bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
|
|
6278
|
+
}
|
|
6279
|
+
const bufferView = this.processBufferView(attribute, componentType, start, count, bufferViewTarget);
|
|
6280
|
+
const accessorDef = {
|
|
6281
|
+
bufferView: bufferView.id,
|
|
6282
|
+
byteOffset: bufferView.byteOffset,
|
|
6283
|
+
componentType,
|
|
6284
|
+
count,
|
|
6285
|
+
max: minMax.max,
|
|
6286
|
+
min: minMax.min,
|
|
6287
|
+
type: types[attribute.itemSize]
|
|
6288
|
+
};
|
|
6289
|
+
if (attribute.normalized === true) accessorDef.normalized = true;
|
|
6290
|
+
if (!json.accessors) json.accessors = [];
|
|
6291
|
+
return json.accessors.push(accessorDef) - 1;
|
|
6292
|
+
}
|
|
6293
|
+
/**
|
|
6294
|
+
* Process image
|
|
6295
|
+
* @param {Image} image to process
|
|
6296
|
+
* @param {Integer} format of the image (RGBAFormat)
|
|
6297
|
+
* @param {Boolean} flipY before writing out the image
|
|
6298
|
+
* @param {String} mimeType export format
|
|
6299
|
+
* @return {Integer} Index of the processed texture in the "images" array
|
|
6300
|
+
*/
|
|
6301
|
+
processImage(image, format, flipY, mimeType = "image/png") {
|
|
6302
|
+
if (image !== null) {
|
|
6303
|
+
const writer = this;
|
|
6304
|
+
const cache = writer.cache;
|
|
6305
|
+
const json = writer.json;
|
|
6306
|
+
const options = writer.options;
|
|
6307
|
+
const pending = writer.pending;
|
|
6308
|
+
if (!cache.images.has(image)) cache.images.set(image, {});
|
|
6309
|
+
const cachedImages = cache.images.get(image);
|
|
6310
|
+
const key = mimeType + ":flipY/" + flipY.toString();
|
|
6311
|
+
if (cachedImages[key] !== void 0) return cachedImages[key];
|
|
6312
|
+
if (!json.images) json.images = [];
|
|
6313
|
+
const imageDef = { mimeType };
|
|
6314
|
+
const canvas = getCanvas();
|
|
6315
|
+
canvas.width = Math.min(image.width, options.maxTextureSize);
|
|
6316
|
+
canvas.height = Math.min(image.height, options.maxTextureSize);
|
|
6317
|
+
const ctx = canvas.getContext("2d");
|
|
6318
|
+
if (flipY === true) {
|
|
6319
|
+
ctx.translate(0, canvas.height);
|
|
6320
|
+
ctx.scale(1, -1);
|
|
6321
|
+
}
|
|
6322
|
+
if (image.data !== void 0) {
|
|
6323
|
+
if (format !== import_three17.RGBAFormat) {
|
|
6324
|
+
console.error("GLTFExporter: Only RGBAFormat is supported.", format);
|
|
6325
|
+
}
|
|
6326
|
+
if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
|
|
6327
|
+
console.warn("GLTFExporter: Image size is bigger than maxTextureSize", image);
|
|
6328
|
+
}
|
|
6329
|
+
const data = new Uint8ClampedArray(image.height * image.width * 4);
|
|
6330
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
6331
|
+
data[i + 0] = image.data[i + 0];
|
|
6332
|
+
data[i + 1] = image.data[i + 1];
|
|
6333
|
+
data[i + 2] = image.data[i + 2];
|
|
6334
|
+
data[i + 3] = image.data[i + 3];
|
|
6335
|
+
}
|
|
6336
|
+
ctx.putImageData(new ImageData(data, image.width, image.height), 0, 0);
|
|
6337
|
+
} else {
|
|
6338
|
+
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
6339
|
+
}
|
|
6340
|
+
if (options.binary === true) {
|
|
6341
|
+
pending.push(
|
|
6342
|
+
getToBlobPromise(canvas, mimeType).then((blob) => writer.processBufferViewImage(blob)).then((bufferViewIndex) => {
|
|
6343
|
+
imageDef.bufferView = bufferViewIndex;
|
|
6344
|
+
})
|
|
6345
|
+
);
|
|
6346
|
+
} else {
|
|
6347
|
+
if (canvas.toDataURL !== void 0) {
|
|
6348
|
+
imageDef.uri = canvas.toDataURL(mimeType);
|
|
6349
|
+
} else {
|
|
6350
|
+
pending.push(
|
|
6351
|
+
getToBlobPromise(canvas, mimeType).then((blob) => new FileReader().readAsDataURL(blob)).then((dataURL) => {
|
|
6352
|
+
imageDef.uri = dataURL;
|
|
6353
|
+
})
|
|
6354
|
+
);
|
|
6355
|
+
}
|
|
6356
|
+
}
|
|
6357
|
+
const index = json.images.push(imageDef) - 1;
|
|
6358
|
+
cachedImages[key] = index;
|
|
6359
|
+
return index;
|
|
6360
|
+
} else {
|
|
6361
|
+
throw new Error("THREE.GLTFExporter: No valid image data found. Unable to process texture.");
|
|
6362
|
+
}
|
|
6363
|
+
}
|
|
6364
|
+
/**
|
|
6365
|
+
* Process sampler
|
|
6366
|
+
* @param {Texture} map Texture to process
|
|
6367
|
+
* @return {Integer} Index of the processed texture in the "samplers" array
|
|
6368
|
+
*/
|
|
6369
|
+
processSampler(map) {
|
|
6370
|
+
const json = this.json;
|
|
6371
|
+
if (!json.samplers) json.samplers = [];
|
|
6372
|
+
const samplerDef = {
|
|
6373
|
+
magFilter: THREE_TO_WEBGL[map.magFilter],
|
|
6374
|
+
minFilter: THREE_TO_WEBGL[map.minFilter],
|
|
6375
|
+
wrapS: THREE_TO_WEBGL[map.wrapS],
|
|
6376
|
+
wrapT: THREE_TO_WEBGL[map.wrapT]
|
|
6377
|
+
};
|
|
6378
|
+
return json.samplers.push(samplerDef) - 1;
|
|
6379
|
+
}
|
|
6380
|
+
/**
|
|
6381
|
+
* Process texture
|
|
6382
|
+
* @param {Texture} map Map to process
|
|
6383
|
+
* @return {Integer} Index of the processed texture in the "textures" array
|
|
6384
|
+
*/
|
|
6385
|
+
processTexture(map) {
|
|
6386
|
+
const writer = this;
|
|
6387
|
+
const options = writer.options;
|
|
6388
|
+
const cache = this.cache;
|
|
6389
|
+
const json = this.json;
|
|
6390
|
+
if (cache.textures.has(map)) return cache.textures.get(map);
|
|
6391
|
+
if (!json.textures) json.textures = [];
|
|
6392
|
+
if (map instanceof import_three17.CompressedTexture) {
|
|
6393
|
+
map = decompress(map, options.maxTextureSize);
|
|
6394
|
+
}
|
|
6395
|
+
let mimeType = map.userData.mimeType;
|
|
6396
|
+
if (mimeType === "image/webp") mimeType = "image/png";
|
|
6397
|
+
const textureDef = {
|
|
6398
|
+
sampler: this.processSampler(map),
|
|
6399
|
+
source: this.processImage(map.image, map.format, map.flipY, mimeType)
|
|
6400
|
+
};
|
|
6401
|
+
if (map.name) textureDef.name = map.name;
|
|
6402
|
+
this._invokeAll(function(ext) {
|
|
6403
|
+
ext.writeTexture && ext.writeTexture(map, textureDef);
|
|
6404
|
+
});
|
|
6405
|
+
const index = json.textures.push(textureDef) - 1;
|
|
6406
|
+
cache.textures.set(map, index);
|
|
6407
|
+
return index;
|
|
6408
|
+
}
|
|
6409
|
+
/**
|
|
6410
|
+
* Process material
|
|
6411
|
+
* @param {THREE.Material} material Material to process
|
|
6412
|
+
* @return {Integer|null} Index of the processed material in the "materials" array
|
|
6413
|
+
*/
|
|
6414
|
+
processMaterial(material) {
|
|
6415
|
+
const cache = this.cache;
|
|
6416
|
+
const json = this.json;
|
|
6417
|
+
if (cache.materials.has(material)) return cache.materials.get(material);
|
|
6418
|
+
if (material.isShaderMaterial) {
|
|
6419
|
+
console.warn("GLTFExporter: THREE.ShaderMaterial not supported.");
|
|
6420
|
+
return null;
|
|
6421
|
+
}
|
|
6422
|
+
if (!json.materials) json.materials = [];
|
|
6423
|
+
const materialDef = { pbrMetallicRoughness: {} };
|
|
6424
|
+
if (material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true) {
|
|
6425
|
+
console.warn("GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.");
|
|
6426
|
+
}
|
|
6427
|
+
const color = material.color.toArray().concat([material.opacity]);
|
|
6428
|
+
if (!equalArray(color, [1, 1, 1, 1])) {
|
|
6429
|
+
materialDef.pbrMetallicRoughness.baseColorFactor = color;
|
|
6430
|
+
}
|
|
6431
|
+
if (material.isMeshStandardMaterial) {
|
|
6432
|
+
materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
|
|
6433
|
+
materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
|
|
6434
|
+
} else {
|
|
6435
|
+
materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
|
|
6436
|
+
materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
|
|
6437
|
+
}
|
|
6438
|
+
if (material.metalnessMap || material.roughnessMap) {
|
|
6439
|
+
const metalRoughTexture = this.buildMetalRoughTexture(material.metalnessMap, material.roughnessMap);
|
|
6440
|
+
const metalRoughMapDef = {
|
|
6441
|
+
index: this.processTexture(metalRoughTexture),
|
|
6442
|
+
channel: metalRoughTexture.channel
|
|
6443
|
+
};
|
|
6444
|
+
this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
|
|
6445
|
+
materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
|
|
6446
|
+
}
|
|
6447
|
+
if (material.map) {
|
|
6448
|
+
const baseColorMapDef = {
|
|
6449
|
+
index: this.processTexture(material.map),
|
|
6450
|
+
texCoord: material.map.channel
|
|
6451
|
+
};
|
|
6452
|
+
this.applyTextureTransform(baseColorMapDef, material.map);
|
|
6453
|
+
materialDef.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
|
|
6454
|
+
}
|
|
6455
|
+
if (material.emissive) {
|
|
6456
|
+
const emissive = material.emissive;
|
|
6457
|
+
const maxEmissiveComponent = Math.max(emissive.r, emissive.g, emissive.b);
|
|
6458
|
+
if (maxEmissiveComponent > 0) {
|
|
6459
|
+
materialDef.emissiveFactor = material.emissive.toArray();
|
|
6460
|
+
}
|
|
6461
|
+
if (material.emissiveMap) {
|
|
6462
|
+
const emissiveMapDef = {
|
|
6463
|
+
index: this.processTexture(material.emissiveMap),
|
|
6464
|
+
texCoord: material.emissiveMap.channel
|
|
6465
|
+
};
|
|
6466
|
+
this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
|
|
6467
|
+
materialDef.emissiveTexture = emissiveMapDef;
|
|
6468
|
+
}
|
|
6469
|
+
}
|
|
6470
|
+
if (material.normalMap) {
|
|
6471
|
+
const normalMapDef = {
|
|
6472
|
+
index: this.processTexture(material.normalMap),
|
|
6473
|
+
texCoord: material.normalMap.channel
|
|
6474
|
+
};
|
|
6475
|
+
if (material.normalScale && material.normalScale.x !== 1) {
|
|
6476
|
+
normalMapDef.scale = material.normalScale.x;
|
|
6477
|
+
}
|
|
6478
|
+
this.applyTextureTransform(normalMapDef, material.normalMap);
|
|
6479
|
+
materialDef.normalTexture = normalMapDef;
|
|
6480
|
+
}
|
|
6481
|
+
if (material.aoMap) {
|
|
6482
|
+
const occlusionMapDef = {
|
|
6483
|
+
index: this.processTexture(material.aoMap),
|
|
6484
|
+
texCoord: material.aoMap.channel
|
|
6485
|
+
};
|
|
6486
|
+
if (material.aoMapIntensity !== 1) {
|
|
6487
|
+
occlusionMapDef.strength = material.aoMapIntensity;
|
|
6488
|
+
}
|
|
6489
|
+
this.applyTextureTransform(occlusionMapDef, material.aoMap);
|
|
6490
|
+
materialDef.occlusionTexture = occlusionMapDef;
|
|
6491
|
+
}
|
|
6492
|
+
if (material.transparent) {
|
|
6493
|
+
materialDef.alphaMode = "BLEND";
|
|
6494
|
+
} else {
|
|
6495
|
+
if (material.alphaTest > 0) {
|
|
6496
|
+
materialDef.alphaMode = "MASK";
|
|
6497
|
+
materialDef.alphaCutoff = material.alphaTest;
|
|
6498
|
+
}
|
|
6499
|
+
}
|
|
6500
|
+
if (material.side === import_three17.DoubleSide) materialDef.doubleSided = true;
|
|
6501
|
+
if (material.name !== "") materialDef.name = material.name;
|
|
6502
|
+
this.serializeUserData(material, materialDef);
|
|
6503
|
+
this._invokeAll(function(ext) {
|
|
6504
|
+
ext.writeMaterial && ext.writeMaterial(material, materialDef);
|
|
6505
|
+
});
|
|
6506
|
+
const index = json.materials.push(materialDef) - 1;
|
|
6507
|
+
cache.materials.set(material, index);
|
|
6508
|
+
return index;
|
|
6509
|
+
}
|
|
6510
|
+
/**
|
|
6511
|
+
* Process mesh
|
|
6512
|
+
* @param {THREE.Mesh} mesh Mesh to process
|
|
6513
|
+
* @return {Integer|null} Index of the processed mesh in the "meshes" array
|
|
6514
|
+
*/
|
|
6515
|
+
processMesh(mesh) {
|
|
6516
|
+
const cache = this.cache;
|
|
6517
|
+
const json = this.json;
|
|
6518
|
+
const meshCacheKeyParts = [mesh.geometry.uuid];
|
|
6519
|
+
if (Array.isArray(mesh.material)) {
|
|
6520
|
+
for (let i = 0, l = mesh.material.length; i < l; i++) {
|
|
6521
|
+
meshCacheKeyParts.push(mesh.material[i].uuid);
|
|
6522
|
+
}
|
|
6523
|
+
} else {
|
|
6524
|
+
meshCacheKeyParts.push(mesh.material.uuid);
|
|
6525
|
+
}
|
|
6526
|
+
const meshCacheKey = meshCacheKeyParts.join(":");
|
|
6527
|
+
if (cache.meshes.has(meshCacheKey)) return cache.meshes.get(meshCacheKey);
|
|
6528
|
+
const geometry = mesh.geometry;
|
|
6529
|
+
let mode;
|
|
6530
|
+
if (mesh.isLineSegments) {
|
|
6531
|
+
mode = WEBGL_CONSTANTS.LINES;
|
|
6532
|
+
} else if (mesh.isLineLoop) {
|
|
6533
|
+
mode = WEBGL_CONSTANTS.LINE_LOOP;
|
|
6534
|
+
} else if (mesh.isLine) {
|
|
6535
|
+
mode = WEBGL_CONSTANTS.LINE_STRIP;
|
|
6536
|
+
} else if (mesh.isPoints) {
|
|
6537
|
+
mode = WEBGL_CONSTANTS.POINTS;
|
|
6538
|
+
} else {
|
|
6539
|
+
mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES;
|
|
6540
|
+
}
|
|
6541
|
+
const meshDef = {};
|
|
6542
|
+
const attributes = {};
|
|
6543
|
+
const primitives = [];
|
|
6544
|
+
const targets = [];
|
|
6545
|
+
const nameConversion = {
|
|
6546
|
+
uv: "TEXCOORD_0",
|
|
6547
|
+
uv1: "TEXCOORD_1",
|
|
6548
|
+
uv2: "TEXCOORD_2",
|
|
6549
|
+
uv3: "TEXCOORD_3",
|
|
6550
|
+
color: "COLOR_0",
|
|
6551
|
+
skinWeight: "WEIGHTS_0",
|
|
6552
|
+
skinIndex: "JOINTS_0"
|
|
6553
|
+
};
|
|
6554
|
+
const originalNormal = geometry.getAttribute("normal");
|
|
6555
|
+
if (originalNormal !== void 0 && !this.isNormalizedNormalAttribute(originalNormal)) {
|
|
6556
|
+
console.warn("THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.");
|
|
6557
|
+
geometry.setAttribute("normal", this.createNormalizedNormalAttribute(originalNormal));
|
|
6558
|
+
}
|
|
6559
|
+
let modifiedAttribute = null;
|
|
6560
|
+
for (let attributeName in geometry.attributes) {
|
|
6561
|
+
if (attributeName.slice(0, 5) === "morph") continue;
|
|
6562
|
+
const attribute = geometry.attributes[attributeName];
|
|
6563
|
+
attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
|
|
6564
|
+
const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
|
|
6565
|
+
if (!validVertexAttributes.test(attributeName)) attributeName = "_" + attributeName;
|
|
6566
|
+
if (cache.attributes.has(this.getUID(attribute))) {
|
|
6567
|
+
attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
|
|
6568
|
+
continue;
|
|
6569
|
+
}
|
|
6570
|
+
modifiedAttribute = null;
|
|
6571
|
+
const array = attribute.array;
|
|
6572
|
+
if (attributeName === "JOINTS_0" && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
|
|
6573
|
+
console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
|
|
6574
|
+
modifiedAttribute = new import_three17.BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
|
|
6575
|
+
}
|
|
6576
|
+
const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
|
|
6577
|
+
if (accessor !== null) {
|
|
6578
|
+
if (!attributeName.startsWith("_")) {
|
|
6579
|
+
this.detectMeshQuantization(attributeName, attribute);
|
|
6580
|
+
}
|
|
6581
|
+
attributes[attributeName] = accessor;
|
|
6582
|
+
cache.attributes.set(this.getUID(attribute), accessor);
|
|
6583
|
+
}
|
|
6584
|
+
}
|
|
6585
|
+
if (originalNormal !== void 0) geometry.setAttribute("normal", originalNormal);
|
|
6586
|
+
if (Object.keys(attributes).length === 0) return null;
|
|
6587
|
+
if (mesh.morphTargetInfluences !== void 0 && mesh.morphTargetInfluences.length > 0) {
|
|
6588
|
+
const weights = [];
|
|
6589
|
+
const targetNames = [];
|
|
6590
|
+
const reverseDictionary = {};
|
|
6591
|
+
if (mesh.morphTargetDictionary !== void 0) {
|
|
6592
|
+
for (const key in mesh.morphTargetDictionary) {
|
|
6593
|
+
reverseDictionary[mesh.morphTargetDictionary[key]] = key;
|
|
6594
|
+
}
|
|
6595
|
+
}
|
|
6596
|
+
for (let i = 0; i < mesh.morphTargetInfluences.length; ++i) {
|
|
6597
|
+
const target = {};
|
|
6598
|
+
let warned = false;
|
|
6599
|
+
for (const attributeName in geometry.morphAttributes) {
|
|
6600
|
+
if (attributeName !== "position" && attributeName !== "normal") {
|
|
6601
|
+
if (!warned) {
|
|
6602
|
+
console.warn("GLTFExporter: Only POSITION and NORMAL morph are supported.");
|
|
6603
|
+
warned = true;
|
|
6604
|
+
}
|
|
6605
|
+
continue;
|
|
6606
|
+
}
|
|
6607
|
+
const attribute = geometry.morphAttributes[attributeName][i];
|
|
6608
|
+
const gltfAttributeName = attributeName.toUpperCase();
|
|
6609
|
+
const baseAttribute = geometry.attributes[attributeName];
|
|
6610
|
+
if (cache.attributes.has(this.getUID(attribute, true))) {
|
|
6611
|
+
target[gltfAttributeName] = cache.attributes.get(this.getUID(attribute, true));
|
|
6612
|
+
continue;
|
|
6613
|
+
}
|
|
6614
|
+
const relativeAttribute = attribute.clone();
|
|
6615
|
+
if (!geometry.morphTargetsRelative) {
|
|
6616
|
+
for (let j = 0, jl = attribute.count; j < jl; j++) {
|
|
6617
|
+
for (let a = 0; a < attribute.itemSize; a++) {
|
|
6618
|
+
if (a === 0) relativeAttribute.setX(j, attribute.getX(j) - baseAttribute.getX(j));
|
|
6619
|
+
if (a === 1) relativeAttribute.setY(j, attribute.getY(j) - baseAttribute.getY(j));
|
|
6620
|
+
if (a === 2) relativeAttribute.setZ(j, attribute.getZ(j) - baseAttribute.getZ(j));
|
|
6621
|
+
if (a === 3) relativeAttribute.setW(j, attribute.getW(j) - baseAttribute.getW(j));
|
|
6622
|
+
}
|
|
6623
|
+
}
|
|
6624
|
+
}
|
|
6625
|
+
target[gltfAttributeName] = this.processAccessor(relativeAttribute, geometry);
|
|
6626
|
+
cache.attributes.set(this.getUID(baseAttribute, true), target[gltfAttributeName]);
|
|
6627
|
+
}
|
|
6628
|
+
targets.push(target);
|
|
6629
|
+
weights.push(mesh.morphTargetInfluences[i]);
|
|
6630
|
+
if (mesh.morphTargetDictionary !== void 0) targetNames.push(reverseDictionary[i]);
|
|
6631
|
+
}
|
|
6632
|
+
meshDef.weights = weights;
|
|
6633
|
+
if (targetNames.length > 0) {
|
|
6634
|
+
meshDef.extras = {};
|
|
6635
|
+
meshDef.extras.targetNames = targetNames;
|
|
6636
|
+
}
|
|
6637
|
+
}
|
|
6638
|
+
const isMultiMaterial = Array.isArray(mesh.material);
|
|
6639
|
+
if (isMultiMaterial && geometry.groups.length === 0) return null;
|
|
6640
|
+
const materials = isMultiMaterial ? mesh.material : [mesh.material];
|
|
6641
|
+
const groups = isMultiMaterial ? geometry.groups : [{ materialIndex: 0, start: void 0, count: void 0 }];
|
|
6642
|
+
for (let i = 0, il = groups.length; i < il; i++) {
|
|
6643
|
+
const primitive = {
|
|
6644
|
+
mode,
|
|
6645
|
+
attributes
|
|
6646
|
+
};
|
|
6647
|
+
this.serializeUserData(geometry, primitive);
|
|
6648
|
+
if (targets.length > 0) primitive.targets = targets;
|
|
6649
|
+
if (geometry.index !== null) {
|
|
6650
|
+
let cacheKey = this.getUID(geometry.index);
|
|
6651
|
+
if (groups[i].start !== void 0 || groups[i].count !== void 0) {
|
|
6652
|
+
cacheKey += ":" + groups[i].start + ":" + groups[i].count;
|
|
6653
|
+
}
|
|
6654
|
+
if (cache.attributes.has(cacheKey)) {
|
|
6655
|
+
primitive.indices = cache.attributes.get(cacheKey);
|
|
6656
|
+
} else {
|
|
6657
|
+
primitive.indices = this.processAccessor(geometry.index, geometry, groups[i].start, groups[i].count);
|
|
6658
|
+
cache.attributes.set(cacheKey, primitive.indices);
|
|
6659
|
+
}
|
|
6660
|
+
if (primitive.indices === null) delete primitive.indices;
|
|
6661
|
+
}
|
|
6662
|
+
const material = this.processMaterial(materials[groups[i].materialIndex]);
|
|
6663
|
+
if (material !== null) primitive.material = material;
|
|
6664
|
+
primitives.push(primitive);
|
|
6665
|
+
}
|
|
6666
|
+
meshDef.primitives = primitives;
|
|
6667
|
+
if (!json.meshes) json.meshes = [];
|
|
6668
|
+
this._invokeAll(function(ext) {
|
|
6669
|
+
ext.writeMesh && ext.writeMesh(mesh, meshDef);
|
|
6670
|
+
});
|
|
6671
|
+
const index = json.meshes.push(meshDef) - 1;
|
|
6672
|
+
cache.meshes.set(meshCacheKey, index);
|
|
6673
|
+
return index;
|
|
6674
|
+
}
|
|
6675
|
+
/**
|
|
6676
|
+
* If a vertex attribute with a
|
|
6677
|
+
* [non-standard data type](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview)
|
|
6678
|
+
* is used, it is checked whether it is a valid data type according to the
|
|
6679
|
+
* [KHR_mesh_quantization](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md)
|
|
6680
|
+
* extension.
|
|
6681
|
+
* In this case the extension is automatically added to the list of used extensions.
|
|
6682
|
+
*
|
|
6683
|
+
* @param {string} attributeName
|
|
6684
|
+
* @param {THREE.BufferAttribute} attribute
|
|
6685
|
+
*/
|
|
6686
|
+
detectMeshQuantization(attributeName, attribute) {
|
|
6687
|
+
if (this.extensionsUsed[KHR_MESH_QUANTIZATION]) return;
|
|
6688
|
+
let attrType = void 0;
|
|
6689
|
+
switch (attribute.array.constructor) {
|
|
6690
|
+
case Int8Array:
|
|
6691
|
+
attrType = "byte";
|
|
6692
|
+
break;
|
|
6693
|
+
case Uint8Array:
|
|
6694
|
+
attrType = "unsigned byte";
|
|
6695
|
+
break;
|
|
6696
|
+
case Int16Array:
|
|
6697
|
+
attrType = "short";
|
|
6698
|
+
break;
|
|
6699
|
+
case Uint16Array:
|
|
6700
|
+
attrType = "unsigned short";
|
|
6701
|
+
break;
|
|
6702
|
+
default:
|
|
6703
|
+
return;
|
|
6704
|
+
}
|
|
6705
|
+
if (attribute.normalized) attrType += " normalized";
|
|
6706
|
+
const attrNamePrefix = attributeName.split("_", 1)[0];
|
|
6707
|
+
if (KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix] && KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix].includes(attrType)) {
|
|
6708
|
+
this.extensionsUsed[KHR_MESH_QUANTIZATION] = true;
|
|
6709
|
+
this.extensionsRequired[KHR_MESH_QUANTIZATION] = true;
|
|
6710
|
+
}
|
|
6711
|
+
}
|
|
6712
|
+
/**
|
|
6713
|
+
* Process camera
|
|
6714
|
+
* @param {THREE.Camera} camera Camera to process
|
|
6715
|
+
* @return {Integer} Index of the processed mesh in the "camera" array
|
|
6716
|
+
*/
|
|
6717
|
+
processCamera(camera) {
|
|
6718
|
+
const json = this.json;
|
|
6719
|
+
if (!json.cameras) json.cameras = [];
|
|
6720
|
+
const isOrtho = camera.isOrthographicCamera;
|
|
6721
|
+
const cameraDef = {
|
|
6722
|
+
type: isOrtho ? "orthographic" : "perspective"
|
|
6723
|
+
};
|
|
6724
|
+
if (isOrtho) {
|
|
6725
|
+
cameraDef.orthographic = {
|
|
6726
|
+
xmag: camera.right * 2,
|
|
6727
|
+
ymag: camera.top * 2,
|
|
6728
|
+
zfar: camera.far <= 0 ? 1e-3 : camera.far,
|
|
6729
|
+
znear: camera.near < 0 ? 0 : camera.near
|
|
6730
|
+
};
|
|
6731
|
+
} else {
|
|
6732
|
+
cameraDef.perspective = {
|
|
6733
|
+
aspectRatio: camera.aspect,
|
|
6734
|
+
yfov: import_three17.MathUtils.degToRad(camera.fov),
|
|
6735
|
+
zfar: camera.far <= 0 ? 1e-3 : camera.far,
|
|
6736
|
+
znear: camera.near < 0 ? 0 : camera.near
|
|
6737
|
+
};
|
|
6738
|
+
}
|
|
6739
|
+
if (camera.name !== "") cameraDef.name = camera.type;
|
|
6740
|
+
return json.cameras.push(cameraDef) - 1;
|
|
6741
|
+
}
|
|
6742
|
+
/**
|
|
6743
|
+
* Creates glTF animation entry from AnimationClip object.
|
|
6744
|
+
*
|
|
6745
|
+
* Status:
|
|
6746
|
+
* - Only properties listed in PATH_PROPERTIES may be animated.
|
|
6747
|
+
*
|
|
6748
|
+
* @param {THREE.AnimationClip} clip
|
|
6749
|
+
* @param {THREE.Object3D} root
|
|
6750
|
+
* @return {number|null}
|
|
6751
|
+
*/
|
|
6752
|
+
processAnimation(clip, root) {
|
|
6753
|
+
const json = this.json;
|
|
6754
|
+
const nodeMap = this.nodeMap;
|
|
6755
|
+
if (!json.animations) json.animations = [];
|
|
6756
|
+
clip = GLTFExporter.Utils.mergeMorphTargetTracks(clip.clone(), root);
|
|
6757
|
+
const tracks = clip.tracks;
|
|
6758
|
+
const channels = [];
|
|
6759
|
+
const samplers = [];
|
|
6760
|
+
for (let i = 0; i < tracks.length; ++i) {
|
|
6761
|
+
const track = tracks[i];
|
|
6762
|
+
const trackBinding = import_three17.PropertyBinding.parseTrackName(track.name);
|
|
6763
|
+
let trackNode = import_three17.PropertyBinding.findNode(root, trackBinding.nodeName);
|
|
6764
|
+
const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
|
|
6765
|
+
if (trackBinding.objectName === "bones") {
|
|
6766
|
+
if (trackNode.isSkinnedMesh === true) {
|
|
6767
|
+
trackNode = trackNode.skeleton.getBoneByName(trackBinding.objectIndex);
|
|
6768
|
+
} else {
|
|
6769
|
+
trackNode = void 0;
|
|
6770
|
+
}
|
|
6771
|
+
}
|
|
6772
|
+
if (!trackNode || !trackProperty) {
|
|
6773
|
+
console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
|
|
6774
|
+
return null;
|
|
6775
|
+
}
|
|
6776
|
+
const inputItemSize = 1;
|
|
6777
|
+
let outputItemSize = track.values.length / track.times.length;
|
|
6778
|
+
if (trackProperty === PATH_PROPERTIES.morphTargetInfluences) {
|
|
6779
|
+
outputItemSize /= trackNode.morphTargetInfluences.length;
|
|
6780
|
+
}
|
|
6781
|
+
let interpolation;
|
|
6782
|
+
if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
|
|
6783
|
+
interpolation = "CUBICSPLINE";
|
|
6784
|
+
outputItemSize /= 3;
|
|
6785
|
+
} else if (track.getInterpolation() === import_three17.InterpolateDiscrete) {
|
|
6786
|
+
interpolation = "STEP";
|
|
6787
|
+
} else {
|
|
6788
|
+
interpolation = "LINEAR";
|
|
6789
|
+
}
|
|
6790
|
+
samplers.push({
|
|
6791
|
+
input: this.processAccessor(new import_three17.BufferAttribute(track.times, inputItemSize)),
|
|
6792
|
+
output: this.processAccessor(new import_three17.BufferAttribute(track.values, outputItemSize)),
|
|
6793
|
+
interpolation
|
|
6794
|
+
});
|
|
6795
|
+
channels.push({
|
|
6796
|
+
sampler: samplers.length - 1,
|
|
6797
|
+
target: {
|
|
6798
|
+
node: nodeMap.get(trackNode),
|
|
6799
|
+
path: trackProperty
|
|
6800
|
+
}
|
|
6801
|
+
});
|
|
6802
|
+
}
|
|
6803
|
+
json.animations.push({
|
|
6804
|
+
name: clip.name || "clip_" + json.animations.length,
|
|
6805
|
+
samplers,
|
|
6806
|
+
channels
|
|
6807
|
+
});
|
|
6808
|
+
return json.animations.length - 1;
|
|
6809
|
+
}
|
|
6810
|
+
/**
|
|
6811
|
+
* @param {THREE.Object3D} object
|
|
6812
|
+
* @return {number|null}
|
|
6813
|
+
*/
|
|
6814
|
+
processSkin(object) {
|
|
6815
|
+
const json = this.json;
|
|
6816
|
+
const nodeMap = this.nodeMap;
|
|
6817
|
+
const node = json.nodes[nodeMap.get(object)];
|
|
6818
|
+
const skeleton = object.skeleton;
|
|
6819
|
+
if (skeleton === void 0) return null;
|
|
6820
|
+
const rootJoint = object.skeleton.bones[0];
|
|
6821
|
+
if (rootJoint === void 0) return null;
|
|
6822
|
+
const joints = [];
|
|
6823
|
+
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
6824
|
+
const temporaryBoneInverse = new import_three17.Matrix4();
|
|
6825
|
+
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
6826
|
+
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
6827
|
+
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
6828
|
+
temporaryBoneInverse.multiply(object.bindMatrix).toArray(inverseBindMatrices, i * 16);
|
|
6829
|
+
}
|
|
6830
|
+
if (json.skins === void 0) json.skins = [];
|
|
6831
|
+
json.skins.push({
|
|
6832
|
+
inverseBindMatrices: this.processAccessor(new import_three17.BufferAttribute(inverseBindMatrices, 16)),
|
|
6833
|
+
joints,
|
|
6834
|
+
skeleton: nodeMap.get(rootJoint)
|
|
6835
|
+
});
|
|
6836
|
+
const skinIndex = node.skin = json.skins.length - 1;
|
|
6837
|
+
return skinIndex;
|
|
6838
|
+
}
|
|
6839
|
+
/**
|
|
6840
|
+
* Process Object3D node
|
|
6841
|
+
* @param {THREE.Object3D} node Object3D to processNode
|
|
6842
|
+
* @return {Integer} Index of the node in the nodes list
|
|
6843
|
+
*/
|
|
6844
|
+
processNode(object) {
|
|
6845
|
+
const json = this.json;
|
|
6846
|
+
const options = this.options;
|
|
6847
|
+
const nodeMap = this.nodeMap;
|
|
6848
|
+
if (!json.nodes) json.nodes = [];
|
|
6849
|
+
const nodeDef = {};
|
|
6850
|
+
if (options.trs) {
|
|
6851
|
+
const rotation = object.quaternion.toArray();
|
|
6852
|
+
const position = object.position.toArray();
|
|
6853
|
+
const scale = object.scale.toArray();
|
|
6854
|
+
if (!equalArray(rotation, [0, 0, 0, 1])) {
|
|
6855
|
+
nodeDef.rotation = rotation;
|
|
6856
|
+
}
|
|
6857
|
+
if (!equalArray(position, [0, 0, 0])) {
|
|
6858
|
+
nodeDef.translation = position;
|
|
6859
|
+
}
|
|
6860
|
+
if (!equalArray(scale, [1, 1, 1])) {
|
|
6861
|
+
nodeDef.scale = scale;
|
|
6862
|
+
}
|
|
6863
|
+
} else {
|
|
6864
|
+
if (object.matrixAutoUpdate) {
|
|
6865
|
+
object.updateMatrix();
|
|
6866
|
+
}
|
|
6867
|
+
if (isIdentityMatrix(object.matrix) === false) {
|
|
6868
|
+
nodeDef.matrix = object.matrix.elements;
|
|
6869
|
+
}
|
|
6870
|
+
}
|
|
6871
|
+
if (object.name !== "") nodeDef.name = String(object.name);
|
|
6872
|
+
this.serializeUserData(object, nodeDef);
|
|
6873
|
+
if (object.isMesh || object.isLine || object.isPoints) {
|
|
6874
|
+
const meshIndex = this.processMesh(object);
|
|
6875
|
+
if (meshIndex !== null) nodeDef.mesh = meshIndex;
|
|
6876
|
+
} else if (object.isCamera) {
|
|
6877
|
+
nodeDef.camera = this.processCamera(object);
|
|
6878
|
+
}
|
|
6879
|
+
if (object.isSkinnedMesh) this.skins.push(object);
|
|
6880
|
+
if (object.children.length > 0) {
|
|
6881
|
+
const children = [];
|
|
6882
|
+
for (let i = 0, l = object.children.length; i < l; i++) {
|
|
6883
|
+
const child = object.children[i];
|
|
6884
|
+
if (child.visible || options.onlyVisible === false) {
|
|
6885
|
+
const nodeIndex2 = this.processNode(child);
|
|
6886
|
+
if (nodeIndex2 !== null) children.push(nodeIndex2);
|
|
6887
|
+
}
|
|
6888
|
+
}
|
|
6889
|
+
if (children.length > 0) nodeDef.children = children;
|
|
6890
|
+
}
|
|
6891
|
+
this._invokeAll(function(ext) {
|
|
6892
|
+
ext.writeNode && ext.writeNode(object, nodeDef);
|
|
6893
|
+
});
|
|
6894
|
+
const nodeIndex = json.nodes.push(nodeDef) - 1;
|
|
6895
|
+
nodeMap.set(object, nodeIndex);
|
|
6896
|
+
return nodeIndex;
|
|
6897
|
+
}
|
|
6898
|
+
/**
|
|
6899
|
+
* Process Scene
|
|
6900
|
+
* @param {Scene} node Scene to process
|
|
6901
|
+
*/
|
|
6902
|
+
processScene(scene) {
|
|
6903
|
+
const json = this.json;
|
|
6904
|
+
const options = this.options;
|
|
6905
|
+
if (!json.scenes) {
|
|
6906
|
+
json.scenes = [];
|
|
6907
|
+
json.scene = 0;
|
|
6908
|
+
}
|
|
6909
|
+
const sceneDef = {};
|
|
6910
|
+
if (scene.name !== "") sceneDef.name = scene.name;
|
|
6911
|
+
json.scenes.push(sceneDef);
|
|
6912
|
+
const nodes = [];
|
|
6913
|
+
for (let i = 0, l = scene.children.length; i < l; i++) {
|
|
6914
|
+
const child = scene.children[i];
|
|
6915
|
+
if (child.visible || options.onlyVisible === false) {
|
|
6916
|
+
const nodeIndex = this.processNode(child);
|
|
6917
|
+
if (nodeIndex !== null) nodes.push(nodeIndex);
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
if (nodes.length > 0) sceneDef.nodes = nodes;
|
|
6921
|
+
this.serializeUserData(scene, sceneDef);
|
|
6922
|
+
}
|
|
6923
|
+
/**
|
|
6924
|
+
* Creates a Scene to hold a list of objects and parse it
|
|
6925
|
+
* @param {Array} objects List of objects to process
|
|
6926
|
+
*/
|
|
6927
|
+
processObjects(objects) {
|
|
6928
|
+
const scene = new import_three17.Scene();
|
|
6929
|
+
scene.name = "AuxScene";
|
|
6930
|
+
for (let i = 0; i < objects.length; i++) {
|
|
6931
|
+
scene.children.push(objects[i]);
|
|
6932
|
+
}
|
|
6933
|
+
this.processScene(scene);
|
|
6934
|
+
}
|
|
6935
|
+
/**
|
|
6936
|
+
* @param {THREE.Object3D|Array<THREE.Object3D>} input
|
|
6937
|
+
*/
|
|
6938
|
+
processInput(input) {
|
|
6939
|
+
const options = this.options;
|
|
6940
|
+
input = input instanceof Array ? input : [input];
|
|
6941
|
+
this._invokeAll(function(ext) {
|
|
6942
|
+
ext.beforeParse && ext.beforeParse(input);
|
|
6943
|
+
});
|
|
6944
|
+
const objectsWithoutScene = [];
|
|
6945
|
+
for (let i = 0; i < input.length; i++) {
|
|
6946
|
+
if (input[i] instanceof import_three17.Scene) {
|
|
6947
|
+
this.processScene(input[i]);
|
|
6948
|
+
} else {
|
|
6949
|
+
objectsWithoutScene.push(input[i]);
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
if (objectsWithoutScene.length > 0) this.processObjects(objectsWithoutScene);
|
|
6953
|
+
for (let i = 0; i < this.skins.length; ++i) {
|
|
6954
|
+
this.processSkin(this.skins[i]);
|
|
6955
|
+
}
|
|
6956
|
+
for (let i = 0; i < options.animations.length; ++i) {
|
|
6957
|
+
this.processAnimation(options.animations[i], input[0]);
|
|
6958
|
+
}
|
|
6959
|
+
this._invokeAll(function(ext) {
|
|
6960
|
+
ext.afterParse && ext.afterParse(input);
|
|
6961
|
+
});
|
|
6962
|
+
}
|
|
6963
|
+
_invokeAll(func) {
|
|
6964
|
+
for (let i = 0, il = this.plugins.length; i < il; i++) {
|
|
6965
|
+
func(this.plugins[i]);
|
|
6966
|
+
}
|
|
6967
|
+
}
|
|
6968
|
+
};
|
|
6969
|
+
var GLTFLightExtension = class {
|
|
6970
|
+
constructor(writer) {
|
|
6971
|
+
this.writer = writer;
|
|
6972
|
+
this.name = "KHR_lights_punctual";
|
|
6973
|
+
}
|
|
6974
|
+
writeNode(light, nodeDef) {
|
|
6975
|
+
if (!light.isLight) return;
|
|
6976
|
+
if (!light.isDirectionalLight && !light.isPointLight && !light.isSpotLight) {
|
|
6977
|
+
console.warn("THREE.GLTFExporter: Only directional, point, and spot lights are supported.", light);
|
|
6978
|
+
return;
|
|
6979
|
+
}
|
|
6980
|
+
const writer = this.writer;
|
|
6981
|
+
const json = writer.json;
|
|
6982
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
6983
|
+
const lightDef = {};
|
|
6984
|
+
if (light.name) lightDef.name = light.name;
|
|
6985
|
+
lightDef.color = light.color.toArray();
|
|
6986
|
+
lightDef.intensity = light.intensity;
|
|
6987
|
+
if (light.isDirectionalLight) {
|
|
6988
|
+
lightDef.type = "directional";
|
|
6989
|
+
} else if (light.isPointLight) {
|
|
6990
|
+
lightDef.type = "point";
|
|
6991
|
+
if (light.distance > 0) lightDef.range = light.distance;
|
|
6992
|
+
} else if (light.isSpotLight) {
|
|
6993
|
+
lightDef.type = "spot";
|
|
6994
|
+
if (light.distance > 0) lightDef.range = light.distance;
|
|
6995
|
+
lightDef.spot = {};
|
|
6996
|
+
lightDef.spot.innerConeAngle = (1 - light.penumbra) * light.angle;
|
|
6997
|
+
lightDef.spot.outerConeAngle = light.angle;
|
|
6998
|
+
}
|
|
6999
|
+
if (light.decay !== void 0 && light.decay !== 2) {
|
|
7000
|
+
console.warn("THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, and expects light.decay=2.");
|
|
7001
|
+
}
|
|
7002
|
+
if (light.target && (light.target.parent !== light || light.target.position.x !== 0 || light.target.position.y !== 0 || light.target.position.z !== -1)) {
|
|
7003
|
+
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.");
|
|
7004
|
+
}
|
|
7005
|
+
if (!extensionsUsed[this.name]) {
|
|
7006
|
+
json.extensions = json.extensions || {};
|
|
7007
|
+
json.extensions[this.name] = { lights: [] };
|
|
7008
|
+
extensionsUsed[this.name] = true;
|
|
7009
|
+
}
|
|
7010
|
+
const lights = json.extensions[this.name].lights;
|
|
7011
|
+
lights.push(lightDef);
|
|
7012
|
+
nodeDef.extensions = nodeDef.extensions || {};
|
|
7013
|
+
nodeDef.extensions[this.name] = { light: lights.length - 1 };
|
|
7014
|
+
}
|
|
7015
|
+
};
|
|
7016
|
+
var GLTFMaterialsUnlitExtension = class {
|
|
7017
|
+
constructor(writer) {
|
|
7018
|
+
this.writer = writer;
|
|
7019
|
+
this.name = "KHR_materials_unlit";
|
|
7020
|
+
}
|
|
7021
|
+
writeMaterial(material, materialDef) {
|
|
7022
|
+
if (!material.isMeshBasicMaterial) return;
|
|
7023
|
+
const writer = this.writer;
|
|
7024
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7025
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7026
|
+
materialDef.extensions[this.name] = {};
|
|
7027
|
+
extensionsUsed[this.name] = true;
|
|
7028
|
+
materialDef.pbrMetallicRoughness.metallicFactor = 0;
|
|
7029
|
+
materialDef.pbrMetallicRoughness.roughnessFactor = 0.9;
|
|
7030
|
+
}
|
|
7031
|
+
};
|
|
7032
|
+
var GLTFMaterialsClearcoatExtension = class {
|
|
7033
|
+
constructor(writer) {
|
|
7034
|
+
this.writer = writer;
|
|
7035
|
+
this.name = "KHR_materials_clearcoat";
|
|
7036
|
+
}
|
|
7037
|
+
writeMaterial(material, materialDef) {
|
|
7038
|
+
if (!material.isMeshPhysicalMaterial || material.clearcoat === 0) return;
|
|
7039
|
+
const writer = this.writer;
|
|
7040
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7041
|
+
const extensionDef = {};
|
|
7042
|
+
extensionDef.clearcoatFactor = material.clearcoat;
|
|
7043
|
+
if (material.clearcoatMap) {
|
|
7044
|
+
const clearcoatMapDef = {
|
|
7045
|
+
index: writer.processTexture(material.clearcoatMap),
|
|
7046
|
+
texCoord: material.clearcoatMap.channel
|
|
7047
|
+
};
|
|
7048
|
+
writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
|
|
7049
|
+
extensionDef.clearcoatTexture = clearcoatMapDef;
|
|
7050
|
+
}
|
|
7051
|
+
extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
|
|
7052
|
+
if (material.clearcoatRoughnessMap) {
|
|
7053
|
+
const clearcoatRoughnessMapDef = {
|
|
7054
|
+
index: writer.processTexture(material.clearcoatRoughnessMap),
|
|
7055
|
+
texCoord: material.clearcoatRoughnessMap.channel
|
|
7056
|
+
};
|
|
7057
|
+
writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
|
|
7058
|
+
extensionDef.clearcoatRoughnessTexture = clearcoatRoughnessMapDef;
|
|
7059
|
+
}
|
|
7060
|
+
if (material.clearcoatNormalMap) {
|
|
7061
|
+
const clearcoatNormalMapDef = {
|
|
7062
|
+
index: writer.processTexture(material.clearcoatNormalMap),
|
|
7063
|
+
texCoord: material.clearcoatNormalMap.channel
|
|
7064
|
+
};
|
|
7065
|
+
writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
|
|
7066
|
+
extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
|
|
7067
|
+
}
|
|
7068
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7069
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7070
|
+
extensionsUsed[this.name] = true;
|
|
7071
|
+
}
|
|
7072
|
+
};
|
|
7073
|
+
var GLTFMaterialsIridescenceExtension = class {
|
|
7074
|
+
constructor(writer) {
|
|
7075
|
+
this.writer = writer;
|
|
7076
|
+
this.name = "KHR_materials_iridescence";
|
|
7077
|
+
}
|
|
7078
|
+
writeMaterial(material, materialDef) {
|
|
7079
|
+
if (!material.isMeshPhysicalMaterial || material.iridescence === 0) return;
|
|
7080
|
+
const writer = this.writer;
|
|
7081
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7082
|
+
const extensionDef = {};
|
|
7083
|
+
extensionDef.iridescenceFactor = material.iridescence;
|
|
7084
|
+
if (material.iridescenceMap) {
|
|
7085
|
+
const iridescenceMapDef = {
|
|
7086
|
+
index: writer.processTexture(material.iridescenceMap),
|
|
7087
|
+
texCoord: material.iridescenceMap.channel
|
|
7088
|
+
};
|
|
7089
|
+
writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
|
|
7090
|
+
extensionDef.iridescenceTexture = iridescenceMapDef;
|
|
7091
|
+
}
|
|
7092
|
+
extensionDef.iridescenceIor = material.iridescenceIOR;
|
|
7093
|
+
extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[0];
|
|
7094
|
+
extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
|
|
7095
|
+
if (material.iridescenceThicknessMap) {
|
|
7096
|
+
const iridescenceThicknessMapDef = {
|
|
7097
|
+
index: writer.processTexture(material.iridescenceThicknessMap),
|
|
7098
|
+
texCoord: material.iridescenceThicknessMap.channel
|
|
7099
|
+
};
|
|
7100
|
+
writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
|
|
7101
|
+
extensionDef.iridescenceThicknessTexture = iridescenceThicknessMapDef;
|
|
7102
|
+
}
|
|
7103
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7104
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7105
|
+
extensionsUsed[this.name] = true;
|
|
7106
|
+
}
|
|
7107
|
+
};
|
|
7108
|
+
var GLTFMaterialsTransmissionExtension = class {
|
|
7109
|
+
constructor(writer) {
|
|
7110
|
+
this.writer = writer;
|
|
7111
|
+
this.name = "KHR_materials_transmission";
|
|
7112
|
+
}
|
|
7113
|
+
writeMaterial(material, materialDef) {
|
|
7114
|
+
if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
|
|
7115
|
+
const writer = this.writer;
|
|
7116
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7117
|
+
const extensionDef = {};
|
|
7118
|
+
extensionDef.transmissionFactor = material.transmission;
|
|
7119
|
+
if (material.transmissionMap) {
|
|
7120
|
+
const transmissionMapDef = {
|
|
7121
|
+
index: writer.processTexture(material.transmissionMap),
|
|
7122
|
+
texCoord: material.transmissionMap.channel
|
|
7123
|
+
};
|
|
7124
|
+
writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
|
|
7125
|
+
extensionDef.transmissionTexture = transmissionMapDef;
|
|
7126
|
+
}
|
|
7127
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7128
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7129
|
+
extensionsUsed[this.name] = true;
|
|
7130
|
+
}
|
|
7131
|
+
};
|
|
7132
|
+
var GLTFMaterialsVolumeExtension = class {
|
|
7133
|
+
constructor(writer) {
|
|
7134
|
+
this.writer = writer;
|
|
7135
|
+
this.name = "KHR_materials_volume";
|
|
7136
|
+
}
|
|
7137
|
+
writeMaterial(material, materialDef) {
|
|
7138
|
+
if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
|
|
7139
|
+
const writer = this.writer;
|
|
7140
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7141
|
+
const extensionDef = {};
|
|
7142
|
+
extensionDef.thicknessFactor = material.thickness;
|
|
7143
|
+
if (material.thicknessMap) {
|
|
7144
|
+
const thicknessMapDef = {
|
|
7145
|
+
index: writer.processTexture(material.thicknessMap),
|
|
7146
|
+
texCoord: material.thicknessMap.channel
|
|
7147
|
+
};
|
|
7148
|
+
writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
|
|
7149
|
+
extensionDef.thicknessTexture = thicknessMapDef;
|
|
7150
|
+
}
|
|
7151
|
+
extensionDef.attenuationDistance = material.attenuationDistance;
|
|
7152
|
+
extensionDef.attenuationColor = material.attenuationColor.toArray();
|
|
7153
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7154
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7155
|
+
extensionsUsed[this.name] = true;
|
|
7156
|
+
}
|
|
7157
|
+
};
|
|
7158
|
+
var GLTFMaterialsIorExtension = class {
|
|
7159
|
+
constructor(writer) {
|
|
7160
|
+
this.writer = writer;
|
|
7161
|
+
this.name = "KHR_materials_ior";
|
|
7162
|
+
}
|
|
7163
|
+
writeMaterial(material, materialDef) {
|
|
7164
|
+
if (!material.isMeshPhysicalMaterial || material.ior === 1.5) return;
|
|
7165
|
+
const writer = this.writer;
|
|
7166
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7167
|
+
const extensionDef = {};
|
|
7168
|
+
extensionDef.ior = material.ior;
|
|
7169
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7170
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7171
|
+
extensionsUsed[this.name] = true;
|
|
7172
|
+
}
|
|
7173
|
+
};
|
|
7174
|
+
var GLTFMaterialsSpecularExtension = class {
|
|
7175
|
+
constructor(writer) {
|
|
7176
|
+
this.writer = writer;
|
|
7177
|
+
this.name = "KHR_materials_specular";
|
|
7178
|
+
}
|
|
7179
|
+
writeMaterial(material, materialDef) {
|
|
7180
|
+
if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorTexture) return;
|
|
7181
|
+
const writer = this.writer;
|
|
7182
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7183
|
+
const extensionDef = {};
|
|
7184
|
+
if (material.specularIntensityMap) {
|
|
7185
|
+
const specularIntensityMapDef = {
|
|
7186
|
+
index: writer.processTexture(material.specularIntensityMap),
|
|
7187
|
+
texCoord: material.specularIntensityMap.channel
|
|
7188
|
+
};
|
|
7189
|
+
writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
|
|
7190
|
+
extensionDef.specularTexture = specularIntensityMapDef;
|
|
7191
|
+
}
|
|
7192
|
+
if (material.specularColorMap) {
|
|
7193
|
+
const specularColorMapDef = {
|
|
7194
|
+
index: writer.processTexture(material.specularColorMap),
|
|
7195
|
+
texCoord: material.specularColorMap.channel
|
|
7196
|
+
};
|
|
7197
|
+
writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
|
|
7198
|
+
extensionDef.specularColorTexture = specularColorMapDef;
|
|
7199
|
+
}
|
|
7200
|
+
extensionDef.specularFactor = material.specularIntensity;
|
|
7201
|
+
extensionDef.specularColorFactor = material.specularColor.toArray();
|
|
7202
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7203
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7204
|
+
extensionsUsed[this.name] = true;
|
|
7205
|
+
}
|
|
7206
|
+
};
|
|
7207
|
+
var GLTFMaterialsSheenExtension = class {
|
|
7208
|
+
constructor(writer) {
|
|
7209
|
+
this.writer = writer;
|
|
7210
|
+
this.name = "KHR_materials_sheen";
|
|
7211
|
+
}
|
|
7212
|
+
writeMaterial(material, materialDef) {
|
|
7213
|
+
if (!material.isMeshPhysicalMaterial || material.sheen == 0) return;
|
|
7214
|
+
const writer = this.writer;
|
|
7215
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7216
|
+
const extensionDef = {};
|
|
7217
|
+
if (material.sheenRoughnessMap) {
|
|
7218
|
+
const sheenRoughnessMapDef = {
|
|
7219
|
+
index: writer.processTexture(material.sheenRoughnessMap),
|
|
7220
|
+
texCoord: material.sheenRoughnessMap.channel
|
|
7221
|
+
};
|
|
7222
|
+
writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
|
|
7223
|
+
extensionDef.sheenRoughnessTexture = sheenRoughnessMapDef;
|
|
7224
|
+
}
|
|
7225
|
+
if (material.sheenColorMap) {
|
|
7226
|
+
const sheenColorMapDef = {
|
|
7227
|
+
index: writer.processTexture(material.sheenColorMap),
|
|
7228
|
+
texCoord: material.sheenColorMap.channel
|
|
7229
|
+
};
|
|
7230
|
+
writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
|
|
7231
|
+
extensionDef.sheenColorTexture = sheenColorMapDef;
|
|
7232
|
+
}
|
|
7233
|
+
extensionDef.sheenRoughnessFactor = material.sheenRoughness;
|
|
7234
|
+
extensionDef.sheenColorFactor = material.sheenColor.toArray();
|
|
7235
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7236
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7237
|
+
extensionsUsed[this.name] = true;
|
|
7238
|
+
}
|
|
7239
|
+
};
|
|
7240
|
+
var GLTFMaterialsAnisotropyExtension = class {
|
|
7241
|
+
constructor(writer) {
|
|
7242
|
+
this.writer = writer;
|
|
7243
|
+
this.name = "KHR_materials_anisotropy";
|
|
7244
|
+
}
|
|
7245
|
+
writeMaterial(material, materialDef) {
|
|
7246
|
+
if (!material.isMeshPhysicalMaterial || material.anisotropy == 0) return;
|
|
7247
|
+
const writer = this.writer;
|
|
7248
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7249
|
+
const extensionDef = {};
|
|
7250
|
+
if (material.anisotropyMap) {
|
|
7251
|
+
const anisotropyMapDef = { index: writer.processTexture(material.anisotropyMap) };
|
|
7252
|
+
writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
|
|
7253
|
+
extensionDef.anisotropyTexture = anisotropyMapDef;
|
|
7254
|
+
}
|
|
7255
|
+
extensionDef.anisotropyStrength = material.anisotropy;
|
|
7256
|
+
extensionDef.anisotropyRotation = material.anisotropyRotation;
|
|
7257
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7258
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7259
|
+
extensionsUsed[this.name] = true;
|
|
7260
|
+
}
|
|
7261
|
+
};
|
|
7262
|
+
var GLTFMaterialsEmissiveStrengthExtension = class {
|
|
7263
|
+
constructor(writer) {
|
|
7264
|
+
this.writer = writer;
|
|
7265
|
+
this.name = "KHR_materials_emissive_strength";
|
|
7266
|
+
}
|
|
7267
|
+
writeMaterial(material, materialDef) {
|
|
7268
|
+
if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1) return;
|
|
7269
|
+
const writer = this.writer;
|
|
7270
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
7271
|
+
const extensionDef = {};
|
|
7272
|
+
extensionDef.emissiveStrength = material.emissiveIntensity;
|
|
7273
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
7274
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
7275
|
+
extensionsUsed[this.name] = true;
|
|
7276
|
+
}
|
|
7277
|
+
};
|
|
7278
|
+
var GLTFMeshGpuInstancing = class {
|
|
7279
|
+
constructor(writer) {
|
|
7280
|
+
this.writer = writer;
|
|
7281
|
+
this.name = "EXT_mesh_gpu_instancing";
|
|
7282
|
+
}
|
|
7283
|
+
writeNode(object, nodeDef) {
|
|
7284
|
+
if (!object.isInstancedMesh) return;
|
|
7285
|
+
const writer = this.writer;
|
|
7286
|
+
const mesh = object;
|
|
7287
|
+
const translationAttr = new Float32Array(mesh.count * 3);
|
|
7288
|
+
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
7289
|
+
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
7290
|
+
const matrix = new import_three17.Matrix4();
|
|
7291
|
+
const position = new import_three17.Vector3();
|
|
7292
|
+
const quaternion = new import_three17.Quaternion();
|
|
7293
|
+
const scale = new import_three17.Vector3();
|
|
7294
|
+
for (let i = 0; i < mesh.count; i++) {
|
|
7295
|
+
mesh.getMatrixAt(i, matrix);
|
|
7296
|
+
matrix.decompose(position, quaternion, scale);
|
|
7297
|
+
position.toArray(translationAttr, i * 3);
|
|
7298
|
+
quaternion.toArray(rotationAttr, i * 4);
|
|
7299
|
+
scale.toArray(scaleAttr, i * 3);
|
|
7300
|
+
}
|
|
7301
|
+
const attributes = {
|
|
7302
|
+
TRANSLATION: writer.processAccessor(new import_three17.BufferAttribute(translationAttr, 3)),
|
|
7303
|
+
ROTATION: writer.processAccessor(new import_three17.BufferAttribute(rotationAttr, 4)),
|
|
7304
|
+
SCALE: writer.processAccessor(new import_three17.BufferAttribute(scaleAttr, 3))
|
|
7305
|
+
};
|
|
7306
|
+
if (mesh.instanceColor)
|
|
7307
|
+
attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
|
|
7308
|
+
nodeDef.extensions = nodeDef.extensions || {};
|
|
7309
|
+
nodeDef.extensions[this.name] = { attributes };
|
|
7310
|
+
writer.extensionsUsed[this.name] = true;
|
|
7311
|
+
writer.extensionsRequired[this.name] = true;
|
|
7312
|
+
}
|
|
7313
|
+
};
|
|
7314
|
+
GLTFExporter.Utils = {
|
|
7315
|
+
insertKeyframe: function(track, time) {
|
|
7316
|
+
const tolerance = 1e-3;
|
|
7317
|
+
const valueSize = track.getValueSize();
|
|
7318
|
+
const times = new track.TimeBufferType(track.times.length + 1);
|
|
7319
|
+
const values = new track.ValueBufferType(track.values.length + valueSize);
|
|
7320
|
+
const interpolant = track.createInterpolant(new track.ValueBufferType(valueSize));
|
|
7321
|
+
let index;
|
|
7322
|
+
if (track.times.length === 0) {
|
|
7323
|
+
times[0] = time;
|
|
7324
|
+
for (let i = 0; i < valueSize; i++) {
|
|
7325
|
+
values[i] = 0;
|
|
7326
|
+
}
|
|
7327
|
+
index = 0;
|
|
7328
|
+
} else if (time < track.times[0]) {
|
|
7329
|
+
if (Math.abs(track.times[0] - time) < tolerance) return 0;
|
|
7330
|
+
times[0] = time;
|
|
7331
|
+
times.set(track.times, 1);
|
|
7332
|
+
values.set(interpolant.evaluate(time), 0);
|
|
7333
|
+
values.set(track.values, valueSize);
|
|
7334
|
+
index = 0;
|
|
7335
|
+
} else if (time > track.times[track.times.length - 1]) {
|
|
7336
|
+
if (Math.abs(track.times[track.times.length - 1] - time) < tolerance) {
|
|
7337
|
+
return track.times.length - 1;
|
|
7338
|
+
}
|
|
7339
|
+
times[times.length - 1] = time;
|
|
7340
|
+
times.set(track.times, 0);
|
|
7341
|
+
values.set(track.values, 0);
|
|
7342
|
+
values.set(interpolant.evaluate(time), track.values.length);
|
|
7343
|
+
index = times.length - 1;
|
|
7344
|
+
} else {
|
|
7345
|
+
for (let i = 0; i < track.times.length; i++) {
|
|
7346
|
+
if (Math.abs(track.times[i] - time) < tolerance) return i;
|
|
7347
|
+
if (track.times[i] < time && track.times[i + 1] > time) {
|
|
7348
|
+
times.set(track.times.slice(0, i + 1), 0);
|
|
7349
|
+
times[i + 1] = time;
|
|
7350
|
+
times.set(track.times.slice(i + 1), i + 2);
|
|
7351
|
+
values.set(track.values.slice(0, (i + 1) * valueSize), 0);
|
|
7352
|
+
values.set(interpolant.evaluate(time), (i + 1) * valueSize);
|
|
7353
|
+
values.set(track.values.slice((i + 1) * valueSize), (i + 2) * valueSize);
|
|
7354
|
+
index = i + 1;
|
|
7355
|
+
break;
|
|
7356
|
+
}
|
|
7357
|
+
}
|
|
7358
|
+
}
|
|
7359
|
+
track.times = times;
|
|
7360
|
+
track.values = values;
|
|
7361
|
+
return index;
|
|
7362
|
+
},
|
|
7363
|
+
mergeMorphTargetTracks: function(clip, root) {
|
|
7364
|
+
const tracks = [];
|
|
7365
|
+
const mergedTracks = {};
|
|
7366
|
+
const sourceTracks = clip.tracks;
|
|
7367
|
+
for (let i = 0; i < sourceTracks.length; ++i) {
|
|
7368
|
+
let sourceTrack = sourceTracks[i];
|
|
7369
|
+
const sourceTrackBinding = import_three17.PropertyBinding.parseTrackName(sourceTrack.name);
|
|
7370
|
+
const sourceTrackNode = import_three17.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
|
|
7371
|
+
if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
|
|
7372
|
+
tracks.push(sourceTrack);
|
|
7373
|
+
continue;
|
|
7374
|
+
}
|
|
7375
|
+
if (sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete && sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear) {
|
|
7376
|
+
if (sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
|
|
7377
|
+
throw new Error("THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.");
|
|
7378
|
+
}
|
|
7379
|
+
console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
|
|
7380
|
+
sourceTrack = sourceTrack.clone();
|
|
7381
|
+
sourceTrack.setInterpolation(import_three17.InterpolateLinear);
|
|
7382
|
+
}
|
|
7383
|
+
const targetCount = sourceTrackNode.morphTargetInfluences.length;
|
|
7384
|
+
const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
|
|
7385
|
+
if (targetIndex === void 0) {
|
|
7386
|
+
throw new Error("THREE.GLTFExporter: Morph target name not found: " + sourceTrackBinding.propertyIndex);
|
|
7387
|
+
}
|
|
7388
|
+
let mergedTrack;
|
|
7389
|
+
if (mergedTracks[sourceTrackNode.uuid] === void 0) {
|
|
7390
|
+
mergedTrack = sourceTrack.clone();
|
|
7391
|
+
const values = new mergedTrack.ValueBufferType(targetCount * mergedTrack.times.length);
|
|
7392
|
+
for (let j = 0; j < mergedTrack.times.length; j++) {
|
|
7393
|
+
values[j * targetCount + targetIndex] = mergedTrack.values[j];
|
|
7394
|
+
}
|
|
7395
|
+
mergedTrack.name = (sourceTrackBinding.nodeName || "") + ".morphTargetInfluences";
|
|
7396
|
+
mergedTrack.values = values;
|
|
7397
|
+
mergedTracks[sourceTrackNode.uuid] = mergedTrack;
|
|
7398
|
+
tracks.push(mergedTrack);
|
|
7399
|
+
continue;
|
|
7400
|
+
}
|
|
7401
|
+
const sourceInterpolant = sourceTrack.createInterpolant(new sourceTrack.ValueBufferType(1));
|
|
7402
|
+
mergedTrack = mergedTracks[sourceTrackNode.uuid];
|
|
7403
|
+
for (let j = 0; j < mergedTrack.times.length; j++) {
|
|
7404
|
+
mergedTrack.values[j * targetCount + targetIndex] = sourceInterpolant.evaluate(mergedTrack.times[j]);
|
|
7405
|
+
}
|
|
7406
|
+
for (let j = 0; j < sourceTrack.times.length; j++) {
|
|
7407
|
+
const keyframeIndex = this.insertKeyframe(mergedTrack, sourceTrack.times[j]);
|
|
7408
|
+
mergedTrack.values[keyframeIndex * targetCount + targetIndex] = sourceTrack.values[j];
|
|
7409
|
+
}
|
|
7410
|
+
}
|
|
7411
|
+
clip.tracks = tracks;
|
|
7412
|
+
return clip;
|
|
7413
|
+
}
|
|
7414
|
+
};
|
|
7415
|
+
|
|
7416
|
+
// src/export/SceneExporter.ts
|
|
7417
|
+
init_MineRenderError();
|
|
7418
|
+
init_DisplayTransforms();
|
|
7419
|
+
init_CanvasCompat();
|
|
7420
|
+
var SceneExporter = class {
|
|
7421
|
+
/** Returns OBJ geometry with normals and UVs; material files and textures are not included. */
|
|
7422
|
+
static toObj(root) {
|
|
7423
|
+
const snapshot = createSnapshot(root, false);
|
|
7424
|
+
try {
|
|
7425
|
+
return new OBJExporter().parse(snapshot.scene);
|
|
7426
|
+
} finally {
|
|
7427
|
+
snapshot.dispose();
|
|
7428
|
+
}
|
|
7429
|
+
}
|
|
7430
|
+
/** Returns PLY geometry with vertex colors and UVs; texture images are not included. */
|
|
7431
|
+
static toPLY(root, options) {
|
|
7432
|
+
const snapshot = createSnapshot(root, false, true);
|
|
7433
|
+
try {
|
|
7434
|
+
const result = new PLYExporter().parse(snapshot.scene, void 0, options);
|
|
7435
|
+
if (result === null) throw new MineRenderError("The scene could not be exported as PLY");
|
|
7436
|
+
return result;
|
|
7437
|
+
} finally {
|
|
7438
|
+
snapshot.dispose();
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7441
|
+
/**
|
|
7442
|
+
* Exports a static glTF/GLB snapshot in a browser. Atlas textures and vertex tints are retained;
|
|
7443
|
+
* MineRender's custom directional lighting is not baked into the exported materials.
|
|
7444
|
+
*/
|
|
7445
|
+
static async toGLTF(root, options = {}) {
|
|
7446
|
+
if (typeof document === "undefined" || typeof FileReader === "undefined") {
|
|
7447
|
+
throw new MineRenderError("glTF export requires a browser with canvas and FileReader support");
|
|
7448
|
+
}
|
|
7449
|
+
if (options.maxTextureSize !== void 0 && !(options.maxTextureSize >= 1)) {
|
|
7450
|
+
throw new MineRenderError("maxTextureSize must be at least 1 pixel");
|
|
7451
|
+
}
|
|
7452
|
+
const snapshot = createSnapshot(root, true);
|
|
7453
|
+
try {
|
|
7454
|
+
return await new GLTFExporter().parseAsync(snapshot.scene, {
|
|
7455
|
+
binary: options.binary ?? false,
|
|
7456
|
+
maxTextureSize: options.maxTextureSize ?? Infinity
|
|
7457
|
+
});
|
|
7458
|
+
} finally {
|
|
7459
|
+
snapshot.dispose();
|
|
7460
|
+
}
|
|
7461
|
+
}
|
|
7462
|
+
};
|
|
7463
|
+
function localMatrix(object) {
|
|
7464
|
+
return object.matrixAutoUpdate ? new import_three18.Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
|
|
7465
|
+
}
|
|
7466
|
+
function createSnapshot(root, gltf, bakeColors = false) {
|
|
7467
|
+
const scene = new import_three18.Scene();
|
|
7468
|
+
const geometries = [];
|
|
7469
|
+
const materials = [];
|
|
7470
|
+
const textures = [];
|
|
7471
|
+
const textureCopies = /* @__PURE__ */ new Map();
|
|
7472
|
+
const dispose = () => {
|
|
7473
|
+
for (const geometry of geometries) geometry.dispose();
|
|
7474
|
+
for (const material of materials) material.dispose();
|
|
7475
|
+
for (const texture of textures) texture.dispose();
|
|
7476
|
+
};
|
|
7477
|
+
const copyMaterial = (source, geometry) => {
|
|
7478
|
+
let material;
|
|
7479
|
+
const shader = source;
|
|
7480
|
+
if (shader.isShaderMaterial && gltf) {
|
|
7481
|
+
const uniforms = shader.uniforms;
|
|
7482
|
+
if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
|
|
7483
|
+
throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
|
|
7484
|
+
}
|
|
7485
|
+
material = new import_three18.MeshBasicMaterial({
|
|
7486
|
+
map: uniforms.map.value,
|
|
7487
|
+
vertexColors: source.vertexColors,
|
|
7488
|
+
transparent: source.transparent,
|
|
7489
|
+
side: source.side,
|
|
7490
|
+
alphaTest: 0.01,
|
|
7491
|
+
depthWrite: source.depthWrite
|
|
7492
|
+
});
|
|
7493
|
+
material.name = source.name;
|
|
7494
|
+
} else if (shader.isShaderMaterial) {
|
|
7495
|
+
material = new import_three18.MeshBasicMaterial({ vertexColors: source.vertexColors });
|
|
7496
|
+
material.name = source.name;
|
|
7497
|
+
} else {
|
|
7498
|
+
const copySource = Object.create(source);
|
|
7499
|
+
copySource.userData = {};
|
|
7500
|
+
material = source.clone.call(copySource);
|
|
7501
|
+
}
|
|
7502
|
+
materials.push(material);
|
|
7503
|
+
if (gltf) {
|
|
7504
|
+
selectAlphaMode(material, geometry);
|
|
7505
|
+
for (const [key, value] of Object.entries(material)) {
|
|
7506
|
+
if (value?.isDataTexture) {
|
|
7507
|
+
let texture = textureCopies.get(value);
|
|
7508
|
+
if (!texture) {
|
|
7509
|
+
texture = copyDataTexture(value);
|
|
7510
|
+
textureCopies.set(value, texture);
|
|
7511
|
+
textures.push(texture);
|
|
7512
|
+
}
|
|
7513
|
+
material[key] = texture;
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
}
|
|
7517
|
+
return material;
|
|
7518
|
+
};
|
|
7519
|
+
const addMesh = (mesh, world, instanceColor) => {
|
|
7520
|
+
if (world.determinant() === 0 || !mesh.geometry.getAttribute("position")) return;
|
|
7521
|
+
const source = mesh.geometry;
|
|
7522
|
+
const count = source.index?.count ?? source.getAttribute("position").count;
|
|
7523
|
+
const groups = Array.isArray(mesh.material) ? source.groups : [{ start: 0, count, materialIndex: 0 }];
|
|
7524
|
+
for (const group of groups) {
|
|
7525
|
+
const sourceMaterial = Array.isArray(mesh.material) ? mesh.material[group.materialIndex ?? 0] : mesh.material;
|
|
7526
|
+
if (!sourceMaterial?.visible) continue;
|
|
7527
|
+
const start = Math.max(group.start, source.drawRange.start);
|
|
7528
|
+
const end = Math.min(count, group.start + group.count, source.drawRange.start + source.drawRange.count);
|
|
7529
|
+
const indices = [];
|
|
7530
|
+
for (let i = start; i + 2 < end; i += 3) {
|
|
7531
|
+
for (let corner = 0; corner < 3; corner++) indices.push(source.index?.getX(i + corner) ?? i + corner);
|
|
7532
|
+
}
|
|
7533
|
+
if (!indices.length) continue;
|
|
7534
|
+
let geometry = source.clone();
|
|
7535
|
+
geometry.setIndex(indices);
|
|
7536
|
+
if (new Set(indices).size < geometry.getAttribute("position").count) {
|
|
7537
|
+
const compact = geometry.toNonIndexed();
|
|
7538
|
+
geometry.dispose();
|
|
7539
|
+
geometry = compact;
|
|
7540
|
+
}
|
|
7541
|
+
geometries.push(geometry);
|
|
7542
|
+
geometry.userData = {};
|
|
7543
|
+
geometry.clearGroups();
|
|
7544
|
+
geometry.setDrawRange(0, Infinity);
|
|
7545
|
+
DisplayTransforms.apply(geometry, world);
|
|
7546
|
+
const material = copyMaterial(sourceMaterial, geometry);
|
|
7547
|
+
if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
|
|
7548
|
+
if (bakeColors || instanceColor) {
|
|
7549
|
+
const tint = (material.color ?? new import_three18.Color()).clone();
|
|
7550
|
+
if (instanceColor) tint.multiply(instanceColor);
|
|
7551
|
+
if (bakeColors) {
|
|
7552
|
+
const original = geometry.getAttribute("color");
|
|
7553
|
+
const colors = new import_three18.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
|
|
7554
|
+
for (let i = 0; i < colors.count; i++) {
|
|
7555
|
+
colors.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
|
|
7556
|
+
}
|
|
7557
|
+
geometry.setAttribute("color", colors);
|
|
7558
|
+
} else if (material.color) {
|
|
7559
|
+
material.color.copy(tint);
|
|
7560
|
+
}
|
|
7561
|
+
}
|
|
7562
|
+
const copy = new import_three18.Mesh(geometry, material);
|
|
7563
|
+
copy.name = mesh.name;
|
|
7564
|
+
copy.renderOrder = mesh.renderOrder;
|
|
7565
|
+
scene.add(copy);
|
|
7566
|
+
}
|
|
7567
|
+
};
|
|
7568
|
+
const visit = (object, parentWorld) => {
|
|
7569
|
+
if (!object.visible) return;
|
|
7570
|
+
const world = parentWorld.clone().multiply(localMatrix(object));
|
|
7571
|
+
const mesh = object;
|
|
7572
|
+
if (mesh.isMesh) {
|
|
7573
|
+
const instanced = mesh;
|
|
7574
|
+
if (instanced.isInstancedMesh) {
|
|
7575
|
+
for (let i = 0; i < instanced.count; i++) {
|
|
7576
|
+
const matrix = new import_three18.Matrix4();
|
|
7577
|
+
instanced.getMatrixAt(i, matrix);
|
|
7578
|
+
const color = instanced.instanceColor ? new import_three18.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
7579
|
+
addMesh(mesh, world.clone().multiply(matrix), color);
|
|
7580
|
+
}
|
|
7581
|
+
} else {
|
|
7582
|
+
addMesh(mesh, world);
|
|
7583
|
+
}
|
|
7584
|
+
}
|
|
7585
|
+
for (const child of object.children) visit(child, world);
|
|
7586
|
+
};
|
|
7587
|
+
try {
|
|
7588
|
+
const ancestors = [];
|
|
7589
|
+
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
7590
|
+
const world = new import_three18.Matrix4();
|
|
7591
|
+
for (const ancestor of ancestors) {
|
|
7592
|
+
if (!ancestor.visible) return { scene, dispose };
|
|
7593
|
+
world.multiply(localMatrix(ancestor));
|
|
7594
|
+
}
|
|
7595
|
+
visit(root, world);
|
|
7596
|
+
return { scene, dispose };
|
|
7597
|
+
} catch (error) {
|
|
7598
|
+
dispose();
|
|
7599
|
+
throw error;
|
|
7600
|
+
}
|
|
7601
|
+
}
|
|
7602
|
+
function selectAlphaMode(material, geometry) {
|
|
7603
|
+
const texture = material.map;
|
|
7604
|
+
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;
|
|
7605
|
+
const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
|
|
7606
|
+
const colors = geometry.getAttribute("color");
|
|
7607
|
+
if (!uv || material.vertexColors && colors?.itemSize === 4) return;
|
|
7608
|
+
const { data, width, height } = texture.image;
|
|
7609
|
+
if (!data || width < 1 || height < 1 || data.length < width * height * 4) return;
|
|
7610
|
+
const count = geometry.index?.count ?? uv.count;
|
|
7611
|
+
let holes = false;
|
|
7612
|
+
for (let i = 0; i + 2 < count; i += 3) {
|
|
7613
|
+
let minU = Infinity, maxU = -Infinity, minV = Infinity, maxV = -Infinity;
|
|
7614
|
+
for (let corner = 0; corner < 3; corner++) {
|
|
7615
|
+
const index = geometry.index?.getX(i + corner) ?? i + corner;
|
|
7616
|
+
const u = uv.getX(index), v = texture.flipY ? 1 - uv.getY(index) : uv.getY(index);
|
|
7617
|
+
if (!Number.isFinite(u) || !Number.isFinite(v)) return;
|
|
7618
|
+
minU = Math.min(minU, u);
|
|
7619
|
+
maxU = Math.max(maxU, u);
|
|
7620
|
+
minV = Math.min(minV, v);
|
|
7621
|
+
maxV = Math.max(maxV, v);
|
|
7622
|
+
}
|
|
7623
|
+
const minX = Math.max(0, Math.min(width - 1, Math.floor(minU * width)));
|
|
7624
|
+
const maxX = Math.max(minX, Math.min(width - 1, Math.ceil(maxU * width) - 1));
|
|
7625
|
+
const minY = Math.max(0, Math.min(height - 1, Math.floor(minV * height)));
|
|
7626
|
+
const maxY = Math.max(minY, Math.min(height - 1, Math.ceil(maxV * height) - 1));
|
|
7627
|
+
for (let y = minY; y <= maxY; y++) {
|
|
7628
|
+
for (let x = minX; x <= maxX; x++) {
|
|
7629
|
+
const alpha = data[(y * width + x) * 4 + 3];
|
|
7630
|
+
if (alpha === 255) continue;
|
|
7631
|
+
if (alpha !== 0 && alpha / 255 >= material.alphaTest) return;
|
|
7632
|
+
holes = true;
|
|
7633
|
+
}
|
|
7634
|
+
}
|
|
7635
|
+
}
|
|
7636
|
+
material.transparent = false;
|
|
7637
|
+
if (holes && material.alphaTest === 0) material.alphaTest = 1 / 255;
|
|
7638
|
+
}
|
|
7639
|
+
function copyDataTexture(source) {
|
|
7640
|
+
const image = source.image;
|
|
7641
|
+
if (source.format !== import_three18.RGBAFormat || source.type !== import_three18.UnsignedByteType) {
|
|
7642
|
+
throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
|
|
7643
|
+
}
|
|
7644
|
+
const canvas = createCanvas2(image.width, image.height);
|
|
7645
|
+
const context = canvas.getContext("2d");
|
|
7646
|
+
if (!context) throw new MineRenderError("glTF export could not create a 2D canvas context");
|
|
7647
|
+
const pixels = context.createImageData(image.width, image.height);
|
|
7648
|
+
pixels.data.set(image.data);
|
|
7649
|
+
context.putImageData(pixels, 0, 0);
|
|
7650
|
+
const copySource = Object.create(source);
|
|
7651
|
+
copySource.userData = {};
|
|
7652
|
+
copySource.source = new import_three18.Source(canvas);
|
|
7653
|
+
return new import_three18.Texture().copy(copySource);
|
|
7654
|
+
}
|
|
7655
|
+
|
|
5119
7656
|
// src/gui/GuiHelper.ts
|
|
5120
7657
|
var GuiHelper = class {
|
|
5121
7658
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
@@ -5125,7 +7662,7 @@ var GuiHelper = class {
|
|
|
5125
7662
|
};
|
|
5126
7663
|
|
|
5127
7664
|
// src/gui/scene/GuiObject.ts
|
|
5128
|
-
var
|
|
7665
|
+
var import_three19 = require("three");
|
|
5129
7666
|
init_AssetKey();
|
|
5130
7667
|
init_ModelTextures();
|
|
5131
7668
|
init_Caching();
|
|
@@ -5137,7 +7674,7 @@ var GuiObject = class extends SceneObject {
|
|
|
5137
7674
|
this.textureLayers = textureLayers;
|
|
5138
7675
|
this.isGuiObject = true;
|
|
5139
7676
|
/** Local bounds in GUI pixels, with y growing down from the origin. */
|
|
5140
|
-
this.bounds = new
|
|
7677
|
+
this.bounds = new import_three19.Box2();
|
|
5141
7678
|
this.geometries = /* @__PURE__ */ new Set();
|
|
5142
7679
|
this.ownedMaterials = /* @__PURE__ */ new Set();
|
|
5143
7680
|
this.initialized = false;
|
|
@@ -5152,7 +7689,7 @@ var GuiObject = class extends SceneObject {
|
|
|
5152
7689
|
const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
|
|
5153
7690
|
const [width, height] = layer.size ?? [cropWidth, cropHeight];
|
|
5154
7691
|
const [x, y] = layer.position ?? [0, 0];
|
|
5155
|
-
const geometry = new
|
|
7692
|
+
const geometry = new import_three19.PlaneGeometry(width, height);
|
|
5156
7693
|
this.geometries.add(geometry);
|
|
5157
7694
|
const uv = geometry.getAttribute("uv");
|
|
5158
7695
|
for (let i = 0; i < uv.count; i++) {
|
|
@@ -5162,13 +7699,13 @@ var GuiObject = class extends SceneObject {
|
|
|
5162
7699
|
1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
|
|
5163
7700
|
);
|
|
5164
7701
|
}
|
|
5165
|
-
const mesh = new
|
|
7702
|
+
const mesh = new import_three19.Mesh(geometry, material);
|
|
5166
7703
|
mesh.name = `mesh:${layer.name ?? index}`;
|
|
5167
7704
|
mesh.position.set(x + width / 2, -y - height / 2, 0);
|
|
5168
7705
|
mesh.renderOrder = index;
|
|
5169
7706
|
this.add(mesh);
|
|
5170
|
-
this.bounds.expandByPoint(new
|
|
5171
|
-
this.bounds.expandByPoint(new
|
|
7707
|
+
this.bounds.expandByPoint(new import_three19.Vector2(x, y));
|
|
7708
|
+
this.bounds.expandByPoint(new import_three19.Vector2(x + width, y + height));
|
|
5172
7709
|
}
|
|
5173
7710
|
this.initialized = true;
|
|
5174
7711
|
this.notifyDirty();
|
|
@@ -5215,7 +7752,7 @@ function isGuiObject(obj) {
|
|
|
5215
7752
|
init_image();
|
|
5216
7753
|
|
|
5217
7754
|
// src/inspector/SceneInspector.ts
|
|
5218
|
-
var
|
|
7755
|
+
var import_three20 = require("three");
|
|
5219
7756
|
init_SceneObject();
|
|
5220
7757
|
init_util();
|
|
5221
7758
|
init_log();
|
|
@@ -5225,11 +7762,11 @@ var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
|
|
|
5225
7762
|
var SceneInspector = class {
|
|
5226
7763
|
constructor(renderer) {
|
|
5227
7764
|
this.renderer = renderer;
|
|
5228
|
-
this.mouse = new
|
|
7765
|
+
this.mouse = new import_three20.Vector2();
|
|
5229
7766
|
this.listeners = new AbortController();
|
|
5230
7767
|
this.objectInfoContainer = document.createElement("div");
|
|
5231
7768
|
this.objectControlsContainer = document.createElement("div");
|
|
5232
|
-
this.raycaster = new
|
|
7769
|
+
this.raycaster = new import_three20.Raycaster();
|
|
5233
7770
|
this.init();
|
|
5234
7771
|
}
|
|
5235
7772
|
init() {
|
|
@@ -5645,7 +8182,7 @@ init_ModelGenerator();
|
|
|
5645
8182
|
init_ModelMerger();
|
|
5646
8183
|
|
|
5647
8184
|
// src/model/block/BlockStateResolver.ts
|
|
5648
|
-
var
|
|
8185
|
+
var import_three23 = require("three");
|
|
5649
8186
|
init_BlockStates();
|
|
5650
8187
|
init_MineRenderError();
|
|
5651
8188
|
init_util();
|
|
@@ -5723,7 +8260,7 @@ var BlockStateResolver = class {
|
|
|
5723
8260
|
return variants[variants.length - 1];
|
|
5724
8261
|
}
|
|
5725
8262
|
static rotation(variant) {
|
|
5726
|
-
const rotation = new
|
|
8263
|
+
const rotation = new import_three23.Euler();
|
|
5727
8264
|
if (typeof variant.x !== "undefined") {
|
|
5728
8265
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
5729
8266
|
}
|
|
@@ -5830,7 +8367,7 @@ init_SceneObject();
|
|
|
5830
8367
|
init_ModelObject();
|
|
5831
8368
|
init_Models();
|
|
5832
8369
|
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
5833
|
-
var
|
|
8370
|
+
var import_three28 = require("three");
|
|
5834
8371
|
init_MineRenderError();
|
|
5835
8372
|
init_InstanceReference();
|
|
5836
8373
|
init_AssetKey();
|
|
@@ -5899,12 +8436,12 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
5899
8436
|
getModelCullMask(model, worldMask) {
|
|
5900
8437
|
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
5901
8438
|
if (object.options.displayPosition) return 0;
|
|
5902
|
-
const position = new
|
|
5903
|
-
const rotation = new
|
|
5904
|
-
const scale = new
|
|
8439
|
+
const position = new import_three28.Vector3();
|
|
8440
|
+
const rotation = new import_three28.Quaternion();
|
|
8441
|
+
const scale = new import_three28.Vector3();
|
|
5905
8442
|
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
5906
|
-
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new
|
|
5907
|
-
return ModelCulling.toLocalMask(worldMask, new
|
|
8443
|
+
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three28.Vector3(1, 1, 1)) > 1e-10) return 0;
|
|
8444
|
+
return ModelCulling.toLocalMask(worldMask, new import_three28.Euler().setFromQuaternion(rotation));
|
|
5908
8445
|
}
|
|
5909
8446
|
async setCullMask(worldMask) {
|
|
5910
8447
|
worldMask &= 63;
|
|
@@ -5966,7 +8503,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
5966
8503
|
() => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
|
|
5967
8504
|
);
|
|
5968
8505
|
const previous = this._fluidModel;
|
|
5969
|
-
const matrix = previous ? this.getModelMatrix(previous) : new
|
|
8506
|
+
const matrix = previous ? this.getModelMatrix(previous) : new import_three28.Matrix4().makeTranslation(...this.position.toArray());
|
|
5970
8507
|
if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
|
|
5971
8508
|
else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
5972
8509
|
this._models = this._models.filter((model) => model !== previous);
|
|
@@ -6097,7 +8634,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
6097
8634
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
6098
8635
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
6099
8636
|
}
|
|
6100
|
-
getMatrixAt(index, matrix = new
|
|
8637
|
+
getMatrixAt(index, matrix = new import_three28.Matrix4()) {
|
|
6101
8638
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
6102
8639
|
const child = this._models[0];
|
|
6103
8640
|
if (child && isModelObject(child)) {
|
|
@@ -7963,7 +10500,7 @@ init_ModelObject();
|
|
|
7963
10500
|
init_nbt();
|
|
7964
10501
|
|
|
7965
10502
|
// src/renderer/MineRenderScene.ts
|
|
7966
|
-
var
|
|
10503
|
+
var import_three30 = require("three");
|
|
7967
10504
|
init_SceneObject();
|
|
7968
10505
|
var import_ts_deepmerge8 = __toESM(require_dist());
|
|
7969
10506
|
init_ModelObject();
|
|
@@ -8696,7 +11233,7 @@ var import_ts_deepmerge7 = __toESM(require_dist());
|
|
|
8696
11233
|
init_util();
|
|
8697
11234
|
|
|
8698
11235
|
// src/skin/SkinTextures.ts
|
|
8699
|
-
var
|
|
11236
|
+
var import_three29 = require("three");
|
|
8700
11237
|
init_Caching();
|
|
8701
11238
|
init_CacheKey();
|
|
8702
11239
|
init_MineRenderError();
|
|
@@ -8780,11 +11317,11 @@ var SkinTextures = class {
|
|
|
8780
11317
|
});
|
|
8781
11318
|
}
|
|
8782
11319
|
static createMaterial(pixels, width, height, transparent = true) {
|
|
8783
|
-
const texture = Textures.initTextureProps(new
|
|
8784
|
-
texture.colorSpace =
|
|
11320
|
+
const texture = Textures.initTextureProps(new import_three29.DataTexture(pixels, width, height));
|
|
11321
|
+
texture.colorSpace = import_three29.SRGBColorSpace;
|
|
8785
11322
|
texture.flipY = true;
|
|
8786
11323
|
texture.needsUpdate = true;
|
|
8787
|
-
return new
|
|
11324
|
+
return new import_three29.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three29.DoubleSide : import_three29.FrontSide, alphaTest: transparent ? 0.1 : 0 });
|
|
8788
11325
|
}
|
|
8789
11326
|
static isSlim(image, scale) {
|
|
8790
11327
|
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
@@ -9011,7 +11548,7 @@ var SkinObject = class extends SceneObject {
|
|
|
9011
11548
|
};
|
|
9012
11549
|
|
|
9013
11550
|
// src/renderer/MineRenderScene.ts
|
|
9014
|
-
var MineRenderScene = class _MineRenderScene extends
|
|
11551
|
+
var MineRenderScene = class _MineRenderScene extends import_three30.Scene {
|
|
9015
11552
|
constructor(options) {
|
|
9016
11553
|
super();
|
|
9017
11554
|
this.isMineRenderScene = true;
|
|
@@ -9144,7 +11681,7 @@ function isMineRenderScene(obj) {
|
|
|
9144
11681
|
}
|
|
9145
11682
|
|
|
9146
11683
|
// src/renderer/Renderer.ts
|
|
9147
|
-
var
|
|
11684
|
+
var import_three32 = require("three");
|
|
9148
11685
|
var import_ts_deepmerge9 = __toESM(require_dist());
|
|
9149
11686
|
var import_stats = __toESM(require("stats.js"));
|
|
9150
11687
|
var import_postprocessing = require("postprocessing");
|
|
@@ -9152,11 +11689,11 @@ init_util();
|
|
|
9152
11689
|
init_three();
|
|
9153
11690
|
|
|
9154
11691
|
// src/three/OrbitControls.js
|
|
9155
|
-
var
|
|
11692
|
+
var import_three31 = require("three");
|
|
9156
11693
|
var _changeEvent = { type: "change" };
|
|
9157
11694
|
var _startEvent = { type: "start" };
|
|
9158
11695
|
var _endEvent = { type: "end" };
|
|
9159
|
-
var OrbitControls = class extends
|
|
11696
|
+
var OrbitControls = class extends import_three31.EventDispatcher {
|
|
9160
11697
|
constructor(object, domElement) {
|
|
9161
11698
|
super();
|
|
9162
11699
|
if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
|
|
@@ -9165,7 +11702,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9165
11702
|
this.domElement = domElement;
|
|
9166
11703
|
this.domElement.style.touchAction = "none";
|
|
9167
11704
|
this.enabled = true;
|
|
9168
|
-
this.target = new
|
|
11705
|
+
this.target = new import_three31.Vector3();
|
|
9169
11706
|
this.minDistance = 0;
|
|
9170
11707
|
this.maxDistance = Infinity;
|
|
9171
11708
|
this.minZoom = 0;
|
|
@@ -9187,8 +11724,8 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9187
11724
|
this.autoRotate = false;
|
|
9188
11725
|
this.autoRotateSpeed = 2;
|
|
9189
11726
|
this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
|
|
9190
|
-
this.mouseButtons = { LEFT:
|
|
9191
|
-
this.touches = { ONE:
|
|
11727
|
+
this.mouseButtons = { LEFT: import_three31.MOUSE.ROTATE, MIDDLE: import_three31.MOUSE.DOLLY, RIGHT: import_three31.MOUSE.PAN };
|
|
11728
|
+
this.touches = { ONE: import_three31.TOUCH.ROTATE, TWO: import_three31.TOUCH.DOLLY_PAN };
|
|
9192
11729
|
this.target0 = this.target.clone();
|
|
9193
11730
|
this.position0 = this.object.position.clone();
|
|
9194
11731
|
this.zoom0 = this.object.zoom;
|
|
@@ -9217,11 +11754,11 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9217
11754
|
state = STATE.NONE;
|
|
9218
11755
|
};
|
|
9219
11756
|
this.update = function() {
|
|
9220
|
-
const offset = new
|
|
9221
|
-
const quat = new
|
|
11757
|
+
const offset = new import_three31.Vector3();
|
|
11758
|
+
const quat = new import_three31.Quaternion().setFromUnitVectors(object.up, new import_three31.Vector3(0, 1, 0));
|
|
9222
11759
|
const quatInverse = quat.clone().invert();
|
|
9223
|
-
const lastPosition = new
|
|
9224
|
-
const lastQuaternion = new
|
|
11760
|
+
const lastPosition = new import_three31.Vector3();
|
|
11761
|
+
const lastQuaternion = new import_three31.Quaternion();
|
|
9225
11762
|
const twoPI = 2 * Math.PI;
|
|
9226
11763
|
return function update() {
|
|
9227
11764
|
const position = scope.object.position;
|
|
@@ -9307,20 +11844,20 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9307
11844
|
};
|
|
9308
11845
|
let state = STATE.NONE;
|
|
9309
11846
|
const EPS = 1e-6;
|
|
9310
|
-
const spherical = new
|
|
9311
|
-
const sphericalDelta = new
|
|
11847
|
+
const spherical = new import_three31.Spherical();
|
|
11848
|
+
const sphericalDelta = new import_three31.Spherical();
|
|
9312
11849
|
let scale = 1;
|
|
9313
|
-
const panOffset = new
|
|
11850
|
+
const panOffset = new import_three31.Vector3();
|
|
9314
11851
|
let zoomChanged = false;
|
|
9315
|
-
const rotateStart = new
|
|
9316
|
-
const rotateEnd = new
|
|
9317
|
-
const rotateDelta = new
|
|
9318
|
-
const panStart = new
|
|
9319
|
-
const panEnd = new
|
|
9320
|
-
const panDelta = new
|
|
9321
|
-
const dollyStart = new
|
|
9322
|
-
const dollyEnd = new
|
|
9323
|
-
const dollyDelta = new
|
|
11852
|
+
const rotateStart = new import_three31.Vector2();
|
|
11853
|
+
const rotateEnd = new import_three31.Vector2();
|
|
11854
|
+
const rotateDelta = new import_three31.Vector2();
|
|
11855
|
+
const panStart = new import_three31.Vector2();
|
|
11856
|
+
const panEnd = new import_three31.Vector2();
|
|
11857
|
+
const panDelta = new import_three31.Vector2();
|
|
11858
|
+
const dollyStart = new import_three31.Vector2();
|
|
11859
|
+
const dollyEnd = new import_three31.Vector2();
|
|
11860
|
+
const dollyDelta = new import_three31.Vector2();
|
|
9324
11861
|
const pointers = [];
|
|
9325
11862
|
const pointerPositions = {};
|
|
9326
11863
|
function getAutoRotationAngle() {
|
|
@@ -9336,7 +11873,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9336
11873
|
sphericalDelta.phi -= angle;
|
|
9337
11874
|
}
|
|
9338
11875
|
const panLeft = function() {
|
|
9339
|
-
const v = new
|
|
11876
|
+
const v = new import_three31.Vector3();
|
|
9340
11877
|
return function panLeft2(distance, objectMatrix) {
|
|
9341
11878
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
9342
11879
|
v.multiplyScalar(-distance);
|
|
@@ -9344,7 +11881,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9344
11881
|
};
|
|
9345
11882
|
}();
|
|
9346
11883
|
const panUp = function() {
|
|
9347
|
-
const v = new
|
|
11884
|
+
const v = new import_three31.Vector3();
|
|
9348
11885
|
return function panUp2(distance, objectMatrix) {
|
|
9349
11886
|
if (scope.screenSpacePanning === true) {
|
|
9350
11887
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -9357,7 +11894,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9357
11894
|
};
|
|
9358
11895
|
}();
|
|
9359
11896
|
const pan = function() {
|
|
9360
|
-
const offset = new
|
|
11897
|
+
const offset = new import_three31.Vector3();
|
|
9361
11898
|
return function pan2(deltaX, deltaY) {
|
|
9362
11899
|
const element = scope.domElement;
|
|
9363
11900
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -9606,12 +12143,12 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9606
12143
|
mouseAction = -1;
|
|
9607
12144
|
}
|
|
9608
12145
|
switch (mouseAction) {
|
|
9609
|
-
case
|
|
12146
|
+
case import_three31.MOUSE.DOLLY:
|
|
9610
12147
|
if (scope.enableZoom === false) return;
|
|
9611
12148
|
handleMouseDownDolly(event);
|
|
9612
12149
|
state = STATE.DOLLY;
|
|
9613
12150
|
break;
|
|
9614
|
-
case
|
|
12151
|
+
case import_three31.MOUSE.ROTATE:
|
|
9615
12152
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
9616
12153
|
if (scope.enablePan === false) return;
|
|
9617
12154
|
handleMouseDownPan(event);
|
|
@@ -9622,7 +12159,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9622
12159
|
state = STATE.ROTATE;
|
|
9623
12160
|
}
|
|
9624
12161
|
break;
|
|
9625
|
-
case
|
|
12162
|
+
case import_three31.MOUSE.PAN:
|
|
9626
12163
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
9627
12164
|
if (scope.enableRotate === false) return;
|
|
9628
12165
|
handleMouseDownRotate(event);
|
|
@@ -9678,12 +12215,12 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9678
12215
|
switch (pointers.length) {
|
|
9679
12216
|
case 1:
|
|
9680
12217
|
switch (scope.touches.ONE) {
|
|
9681
|
-
case
|
|
12218
|
+
case import_three31.TOUCH.ROTATE:
|
|
9682
12219
|
if (scope.enableRotate === false) return;
|
|
9683
12220
|
handleTouchStartRotate();
|
|
9684
12221
|
state = STATE.TOUCH_ROTATE;
|
|
9685
12222
|
break;
|
|
9686
|
-
case
|
|
12223
|
+
case import_three31.TOUCH.PAN:
|
|
9687
12224
|
if (scope.enablePan === false) return;
|
|
9688
12225
|
handleTouchStartPan();
|
|
9689
12226
|
state = STATE.TOUCH_PAN;
|
|
@@ -9694,12 +12231,12 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9694
12231
|
break;
|
|
9695
12232
|
case 2:
|
|
9696
12233
|
switch (scope.touches.TWO) {
|
|
9697
|
-
case
|
|
12234
|
+
case import_three31.TOUCH.DOLLY_PAN:
|
|
9698
12235
|
if (scope.enableZoom === false && scope.enablePan === false) return;
|
|
9699
12236
|
handleTouchStartDollyPan();
|
|
9700
12237
|
state = STATE.TOUCH_DOLLY_PAN;
|
|
9701
12238
|
break;
|
|
9702
|
-
case
|
|
12239
|
+
case import_three31.TOUCH.DOLLY_ROTATE:
|
|
9703
12240
|
if (scope.enableZoom === false && scope.enableRotate === false) return;
|
|
9704
12241
|
handleTouchStartDollyRotate();
|
|
9705
12242
|
state = STATE.TOUCH_DOLLY_ROTATE;
|
|
@@ -9766,7 +12303,7 @@ var OrbitControls = class extends import_three26.EventDispatcher {
|
|
|
9766
12303
|
function trackPointer(event) {
|
|
9767
12304
|
let position = pointerPositions[event.pointerId];
|
|
9768
12305
|
if (position === void 0) {
|
|
9769
|
-
position = new
|
|
12306
|
+
position = new import_three31.Vector2();
|
|
9770
12307
|
pointerPositions[event.pointerId] = position;
|
|
9771
12308
|
}
|
|
9772
12309
|
position.set(event.pageX, event.pageY);
|
|
@@ -9786,10 +12323,10 @@ var MapControls = class extends OrbitControls {
|
|
|
9786
12323
|
constructor(object, domElement) {
|
|
9787
12324
|
super(object, domElement);
|
|
9788
12325
|
this.screenSpacePanning = false;
|
|
9789
|
-
this.mouseButtons.LEFT =
|
|
9790
|
-
this.mouseButtons.RIGHT =
|
|
9791
|
-
this.touches.ONE =
|
|
9792
|
-
this.touches.TWO =
|
|
12326
|
+
this.mouseButtons.LEFT = import_three31.MOUSE.PAN;
|
|
12327
|
+
this.mouseButtons.RIGHT = import_three31.MOUSE.ROTATE;
|
|
12328
|
+
this.touches.ONE = import_three31.TOUCH.PAN;
|
|
12329
|
+
this.touches.TWO = import_three31.TOUCH.DOLLY_ROTATE;
|
|
9793
12330
|
}
|
|
9794
12331
|
};
|
|
9795
12332
|
|
|
@@ -9838,8 +12375,8 @@ var Renderer = class _Renderer {
|
|
|
9838
12375
|
top: void 0,
|
|
9839
12376
|
bottom: void 0
|
|
9840
12377
|
},
|
|
9841
|
-
position: new
|
|
9842
|
-
lookingAt: new
|
|
12378
|
+
position: new import_three32.Vector3(50, 50, 50),
|
|
12379
|
+
lookingAt: new import_three32.Vector3(0, 0, 0)
|
|
9843
12380
|
},
|
|
9844
12381
|
render: {
|
|
9845
12382
|
fpsLimit: 60,
|
|
@@ -9870,14 +12407,14 @@ var Renderer = class _Renderer {
|
|
|
9870
12407
|
switch (this.options.camera.type) {
|
|
9871
12408
|
case "perspective":
|
|
9872
12409
|
default:
|
|
9873
|
-
return new
|
|
12410
|
+
return new import_three32.PerspectiveCamera(
|
|
9874
12411
|
this.options.camera.perspective.fov,
|
|
9875
12412
|
this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
|
|
9876
12413
|
this.options.camera.near,
|
|
9877
12414
|
this.options.camera.far
|
|
9878
12415
|
);
|
|
9879
12416
|
case "orthographic":
|
|
9880
|
-
return new
|
|
12417
|
+
return new import_three32.OrthographicCamera(
|
|
9881
12418
|
this.options.camera.orthographic.left ?? this.viewWidth / -2,
|
|
9882
12419
|
this.options.camera.orthographic.right ?? this.viewWidth / 2,
|
|
9883
12420
|
this.options.camera.orthographic.top ?? this.viewHeight / 2,
|
|
@@ -9888,7 +12425,7 @@ var Renderer = class _Renderer {
|
|
|
9888
12425
|
}
|
|
9889
12426
|
}
|
|
9890
12427
|
createRenderer() {
|
|
9891
|
-
const renderer = new
|
|
12428
|
+
const renderer = new import_three32.WebGLRenderer({
|
|
9892
12429
|
antialias: this.options.render.antialias,
|
|
9893
12430
|
alpha: true,
|
|
9894
12431
|
powerPreference: "high-performance",
|
|
@@ -9896,8 +12433,8 @@ var Renderer = class _Renderer {
|
|
|
9896
12433
|
});
|
|
9897
12434
|
renderer.setClearColor(0, 0);
|
|
9898
12435
|
renderer.shadowMap.enabled = true;
|
|
9899
|
-
renderer.shadowMap.type =
|
|
9900
|
-
renderer.outputColorSpace =
|
|
12436
|
+
renderer.shadowMap.type = import_three32.PCFSoftShadowMap;
|
|
12437
|
+
renderer.outputColorSpace = import_three32.SRGBColorSpace;
|
|
9901
12438
|
renderer.setPixelRatio(this.options.render.pixelRatio ?? 1);
|
|
9902
12439
|
renderer.setSize(this.viewWidth, this.viewHeight);
|
|
9903
12440
|
return renderer;
|
|
@@ -9932,20 +12469,20 @@ var Renderer = class _Renderer {
|
|
|
9932
12469
|
window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
|
|
9933
12470
|
}
|
|
9934
12471
|
if (this.options.debug.grid) {
|
|
9935
|
-
const gridHelper = new
|
|
12472
|
+
const gridHelper = new import_three32.GridHelper(128, 16);
|
|
9936
12473
|
this._debugHelpers.push(gridHelper);
|
|
9937
12474
|
this.scene.add(gridHelper);
|
|
9938
|
-
const gridHelper2 = new
|
|
12475
|
+
const gridHelper2 = new import_three32.GridHelper(128, 16);
|
|
9939
12476
|
this._debugHelpers.push(gridHelper2);
|
|
9940
12477
|
gridHelper2.rotation.x = 90 * (Math.PI / 180);
|
|
9941
12478
|
this.scene.add(gridHelper2);
|
|
9942
|
-
const gridHelper3 = new
|
|
12479
|
+
const gridHelper3 = new import_three32.GridHelper(128, 16);
|
|
9943
12480
|
this._debugHelpers.push(gridHelper3);
|
|
9944
12481
|
gridHelper3.rotation.z = 90 * (Math.PI / 180);
|
|
9945
12482
|
this.scene.add(gridHelper3);
|
|
9946
12483
|
}
|
|
9947
12484
|
if (this.options.debug.axes) {
|
|
9948
|
-
const axesHelper = new
|
|
12485
|
+
const axesHelper = new import_three32.AxesHelper(64);
|
|
9949
12486
|
this._debugHelpers.push(axesHelper);
|
|
9950
12487
|
this.scene.add(axesHelper);
|
|
9951
12488
|
}
|
|
@@ -10089,6 +12626,9 @@ var Renderer = class _Renderer {
|
|
|
10089
12626
|
if (next !== void 0 && t + 0.1 < next) return;
|
|
10090
12627
|
this._nextFrameTime = next !== void 0 && t - next < interval ? next + interval : t + interval;
|
|
10091
12628
|
}
|
|
12629
|
+
this.drawFrame();
|
|
12630
|
+
}
|
|
12631
|
+
drawFrame() {
|
|
10092
12632
|
if (this._stats) {
|
|
10093
12633
|
this._stats.begin();
|
|
10094
12634
|
}
|
|
@@ -10103,8 +12643,28 @@ var Renderer = class _Renderer {
|
|
|
10103
12643
|
}
|
|
10104
12644
|
}
|
|
10105
12645
|
//</editor-fold>
|
|
10106
|
-
|
|
10107
|
-
|
|
12646
|
+
/**
|
|
12647
|
+
* Renders a fresh frame and returns an image data URL, including while the animation loop is stopped.
|
|
12648
|
+
* Trimming removes transparent borders; an empty image becomes one transparent pixel.
|
|
12649
|
+
* MIME type support and lossy quality (0–1) follow the canvas encoder.
|
|
12650
|
+
*/
|
|
12651
|
+
toImage(trim = false, mime = "image/png", quality) {
|
|
12652
|
+
if (this._disposed) throw new Error("Cannot export an image from a disposed renderer");
|
|
12653
|
+
if (this._controls?.enabled) {
|
|
12654
|
+
this._controls.update();
|
|
12655
|
+
}
|
|
12656
|
+
this.drawFrame();
|
|
12657
|
+
const canvas = trim ? trimCanvas(this.renderer.domElement) : this.renderer.domElement;
|
|
12658
|
+
return canvas.toDataURL(mime, quality);
|
|
12659
|
+
}
|
|
12660
|
+
toObj() {
|
|
12661
|
+
return SceneExporter.toObj(this.scene);
|
|
12662
|
+
}
|
|
12663
|
+
toPLY(options) {
|
|
12664
|
+
return SceneExporter.toPLY(this.scene, options);
|
|
12665
|
+
}
|
|
12666
|
+
toGLTF(options) {
|
|
12667
|
+
return SceneExporter.toGLTF(this.scene, options);
|
|
10108
12668
|
}
|
|
10109
12669
|
///
|
|
10110
12670
|
get attachedToBody() {
|
|
@@ -10575,19 +13135,19 @@ var AnvilParser = class {
|
|
|
10575
13135
|
};
|
|
10576
13136
|
|
|
10577
13137
|
// src/world/Chunk.ts
|
|
10578
|
-
var
|
|
13138
|
+
var import_three37 = require("three");
|
|
10579
13139
|
init_BlockStates();
|
|
10580
13140
|
init_AssetKey();
|
|
10581
13141
|
|
|
10582
13142
|
// src/world/MineRenderWorld.ts
|
|
10583
|
-
var
|
|
13143
|
+
var import_three35 = require("three");
|
|
10584
13144
|
init_BatchedExecutor();
|
|
10585
13145
|
init_AssetKey();
|
|
10586
13146
|
init_BlockStates();
|
|
10587
13147
|
init_CubeFace();
|
|
10588
13148
|
|
|
10589
13149
|
// src/world/SectionModels.ts
|
|
10590
|
-
var
|
|
13150
|
+
var import_three34 = require("three");
|
|
10591
13151
|
init_AssetKey();
|
|
10592
13152
|
init_Models();
|
|
10593
13153
|
init_CubeFace();
|
|
@@ -10653,12 +13213,12 @@ var SectionModels = class {
|
|
|
10653
13213
|
});
|
|
10654
13214
|
await object.init();
|
|
10655
13215
|
const geometry = object.children[0].geometry;
|
|
10656
|
-
geometry.applyMatrix4(new
|
|
13216
|
+
geometry.applyMatrix4(new import_three34.Matrix4().makeRotationFromEuler(rotation));
|
|
10657
13217
|
object.clear();
|
|
10658
13218
|
const cullFaces = CUBE_FACES.map((face) => {
|
|
10659
13219
|
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
10660
13220
|
if (local < 0) return 0;
|
|
10661
|
-
const normal = new
|
|
13221
|
+
const normal = new import_three34.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
|
|
10662
13222
|
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);
|
|
10663
13223
|
return 1 << world;
|
|
10664
13224
|
});
|
|
@@ -10688,20 +13248,20 @@ var MineRenderWorld = class {
|
|
|
10688
13248
|
}
|
|
10689
13249
|
getBlockAt(posOrX, y, z) {
|
|
10690
13250
|
if (typeof posOrX == "number") {
|
|
10691
|
-
return this.getBlockAt(new
|
|
13251
|
+
return this.getBlockAt(new import_three35.Vector3(posOrX, y, z));
|
|
10692
13252
|
}
|
|
10693
13253
|
if (isTripleArray(posOrX)) {
|
|
10694
|
-
return this.getBlockAt(new
|
|
13254
|
+
return this.getBlockAt(new import_three35.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
10695
13255
|
}
|
|
10696
13256
|
this.validatePosBounds(posOrX);
|
|
10697
13257
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
10698
13258
|
}
|
|
10699
13259
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
10700
13260
|
if (typeof posOrX == "number") {
|
|
10701
|
-
return this.setBlockAt(new
|
|
13261
|
+
return this.setBlockAt(new import_three35.Vector3(posOrX, yOrBlock, z), block);
|
|
10702
13262
|
}
|
|
10703
13263
|
if (isTripleArray(posOrX)) {
|
|
10704
|
-
return this.setBlockAt(new
|
|
13264
|
+
return this.setBlockAt(new import_three35.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
10705
13265
|
}
|
|
10706
13266
|
return this.placeBlock(posOrX, yOrBlock);
|
|
10707
13267
|
}
|
|
@@ -10722,7 +13282,7 @@ var MineRenderWorld = class {
|
|
|
10722
13282
|
const collect = async (positions2) => {
|
|
10723
13283
|
for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
|
|
10724
13284
|
};
|
|
10725
|
-
const place = (block) => this.placeBlock(new
|
|
13285
|
+
const place = (block) => this.placeBlock(new import_three35.Vector3(...block.position), block, collect);
|
|
10726
13286
|
const keys = /* @__PURE__ */ new Map();
|
|
10727
13287
|
for (const block of multiblock.blocks) {
|
|
10728
13288
|
if (Chunk.isAir(block)) continue;
|
|
@@ -10800,13 +13360,13 @@ var MineRenderWorld = class {
|
|
|
10800
13360
|
for (const pos of positions) {
|
|
10801
13361
|
this.pendingCulling.set(pos.toArray().join(","), pos.clone());
|
|
10802
13362
|
for (const offset of CUBE_FACE_OFFSETS) {
|
|
10803
|
-
const neighbor = pos.clone().add(new
|
|
13363
|
+
const neighbor = pos.clone().add(new import_three35.Vector3(...offset));
|
|
10804
13364
|
this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
|
|
10805
13365
|
}
|
|
10806
13366
|
for (let y = -1; y <= 1; y++) {
|
|
10807
13367
|
for (let z = -1; z <= 1; z++) {
|
|
10808
13368
|
for (let x = -1; x <= 1; x++) {
|
|
10809
|
-
const neighbor = pos.clone().add(new
|
|
13369
|
+
const neighbor = pos.clone().add(new import_three35.Vector3(x, y, z));
|
|
10810
13370
|
if (this.getBlockAt(neighbor)?.object?.fluidKind) {
|
|
10811
13371
|
this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
|
|
10812
13372
|
}
|
|
@@ -10828,7 +13388,7 @@ var MineRenderWorld = class {
|
|
|
10828
13388
|
if (!block) continue;
|
|
10829
13389
|
if (block.object?.fluidKind) {
|
|
10830
13390
|
await block.object.updateFluid((x, y, z) => {
|
|
10831
|
-
const neighbor = pos.clone().add(new
|
|
13391
|
+
const neighbor = pos.clone().add(new import_three35.Vector3(x, y, z));
|
|
10832
13392
|
const section = this.getChunkAt(neighbor);
|
|
10833
13393
|
const object = section?.getBlockAt(neighbor)?.object;
|
|
10834
13394
|
return {
|
|
@@ -10840,7 +13400,7 @@ var MineRenderWorld = class {
|
|
|
10840
13400
|
}
|
|
10841
13401
|
let mask = 0;
|
|
10842
13402
|
for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
10843
|
-
const neighbor = pos.clone().add(new
|
|
13403
|
+
const neighbor = pos.clone().add(new import_three35.Vector3(...offset));
|
|
10844
13404
|
if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
|
|
10845
13405
|
mask |= 1 << face;
|
|
10846
13406
|
}
|
|
@@ -10874,14 +13434,14 @@ var MineRenderWorld = class {
|
|
|
10874
13434
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
10875
13435
|
}
|
|
10876
13436
|
static worldToScenePosition(pos) {
|
|
10877
|
-
return new
|
|
13437
|
+
return new import_three35.Vector3(
|
|
10878
13438
|
pos.x * 16,
|
|
10879
13439
|
pos.y * 16,
|
|
10880
13440
|
pos.z * 16
|
|
10881
13441
|
);
|
|
10882
13442
|
}
|
|
10883
13443
|
static sceneToWorldPosition(pos) {
|
|
10884
|
-
return new
|
|
13444
|
+
return new import_three35.Vector3(
|
|
10885
13445
|
pos.x / 16,
|
|
10886
13446
|
pos.y / 16,
|
|
10887
13447
|
pos.z / 16
|
|
@@ -10901,10 +13461,10 @@ var MineRenderWorld = class {
|
|
|
10901
13461
|
};
|
|
10902
13462
|
|
|
10903
13463
|
// src/world/SectionMesh.ts
|
|
10904
|
-
var
|
|
13464
|
+
var import_three36 = require("three");
|
|
10905
13465
|
init_CanvasCompat();
|
|
10906
13466
|
init_Materials();
|
|
10907
|
-
var SectionMesh = class _SectionMesh extends
|
|
13467
|
+
var SectionMesh = class _SectionMesh extends import_three36.Group {
|
|
10908
13468
|
constructor() {
|
|
10909
13469
|
super(...arguments);
|
|
10910
13470
|
this.ownedMeshes = [];
|
|
@@ -10977,18 +13537,18 @@ var SectionMesh = class _SectionMesh extends import_three31.Group {
|
|
|
10977
13537
|
for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
|
|
10978
13538
|
}
|
|
10979
13539
|
}
|
|
10980
|
-
const geometry = new
|
|
10981
|
-
geometry.setAttribute("position", new
|
|
10982
|
-
geometry.setAttribute("normal", new
|
|
10983
|
-
geometry.setAttribute("uv", new
|
|
10984
|
-
geometry.setAttribute("color", new
|
|
13540
|
+
const geometry = new import_three36.BufferGeometry();
|
|
13541
|
+
geometry.setAttribute("position", new import_three36.Float32BufferAttribute(positions, 3));
|
|
13542
|
+
geometry.setAttribute("normal", new import_three36.Float32BufferAttribute(normals, 3));
|
|
13543
|
+
geometry.setAttribute("uv", new import_three36.Float32BufferAttribute(uvs, 2));
|
|
13544
|
+
geometry.setAttribute("color", new import_three36.Float32BufferAttribute(colors, 3));
|
|
10985
13545
|
geometry.setIndex(indices);
|
|
10986
13546
|
geometry.computeBoundingBox();
|
|
10987
13547
|
geometry.computeBoundingSphere();
|
|
10988
13548
|
const material = Materials.createShadedCanvasMaterial(canvas, false);
|
|
10989
13549
|
material.vertexColors = true;
|
|
10990
13550
|
const texture = material.uniforms?.map?.value ?? material.map;
|
|
10991
|
-
const mesh = new
|
|
13551
|
+
const mesh = new import_three36.Mesh(geometry, material);
|
|
10992
13552
|
section.add(mesh);
|
|
10993
13553
|
section.ownedMeshes.push({ mesh, texture });
|
|
10994
13554
|
}
|
|
@@ -11022,10 +13582,10 @@ var Chunk = class _Chunk {
|
|
|
11022
13582
|
}
|
|
11023
13583
|
getBlockAt(posOrX, y, z) {
|
|
11024
13584
|
if (typeof posOrX == "number") {
|
|
11025
|
-
return this.getBlockAt(new
|
|
13585
|
+
return this.getBlockAt(new import_three37.Vector3(posOrX, y, z));
|
|
11026
13586
|
}
|
|
11027
13587
|
if (isTripleArray(posOrX)) {
|
|
11028
|
-
return this.getBlockAt(new
|
|
13588
|
+
return this.getBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
11029
13589
|
}
|
|
11030
13590
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
11031
13591
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -11033,10 +13593,10 @@ var Chunk = class _Chunk {
|
|
|
11033
13593
|
}
|
|
11034
13594
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
11035
13595
|
if (typeof posOrX == "number") {
|
|
11036
|
-
return this.setBlockAt(new
|
|
13596
|
+
return this.setBlockAt(new import_three37.Vector3(posOrX, yOrBlock, z), block);
|
|
11037
13597
|
}
|
|
11038
13598
|
if (isTripleArray(posOrX)) {
|
|
11039
|
-
return this.setBlockAt(new
|
|
13599
|
+
return this.setBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
11040
13600
|
}
|
|
11041
13601
|
const worldPos = posOrX;
|
|
11042
13602
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -11121,7 +13681,7 @@ var Chunk = class _Chunk {
|
|
|
11121
13681
|
}
|
|
11122
13682
|
async clear(onBlocksChanged = this.onBlocksChanged) {
|
|
11123
13683
|
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
11124
|
-
new
|
|
13684
|
+
new import_three37.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
11125
13685
|
));
|
|
11126
13686
|
for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
|
|
11127
13687
|
this.sectionBlocks.clear();
|
|
@@ -11145,14 +13705,14 @@ var Chunk = class _Chunk {
|
|
|
11145
13705
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
11146
13706
|
}
|
|
11147
13707
|
worldPosToChunkPos(pos) {
|
|
11148
|
-
return new
|
|
13708
|
+
return new import_three37.Vector3(
|
|
11149
13709
|
pos.x - this.x * 16,
|
|
11150
13710
|
pos.y - this.y * 16,
|
|
11151
13711
|
pos.z - this.z * 16
|
|
11152
13712
|
);
|
|
11153
13713
|
}
|
|
11154
13714
|
chunkPosToWorldPos(pos) {
|
|
11155
|
-
return new
|
|
13715
|
+
return new import_three37.Vector3(
|
|
11156
13716
|
this.x * 16 + pos.x,
|
|
11157
13717
|
this.y * 16 + pos.y,
|
|
11158
13718
|
this.z * 16 + pos.z
|
|
@@ -11232,6 +13792,7 @@ var Chunk = class _Chunk {
|
|
|
11232
13792
|
RequestError,
|
|
11233
13793
|
Requests,
|
|
11234
13794
|
SKIN_PARTS,
|
|
13795
|
+
SceneExporter,
|
|
11235
13796
|
SceneInspector,
|
|
11236
13797
|
SceneObject,
|
|
11237
13798
|
SceneStats,
|
|
@@ -11320,6 +13881,7 @@ var Chunk = class _Chunk {
|
|
|
11320
13881
|
timingStart,
|
|
11321
13882
|
toDegrees,
|
|
11322
13883
|
toRadians,
|
|
11323
|
-
toTrianglesDrawMode
|
|
13884
|
+
toTrianglesDrawMode,
|
|
13885
|
+
trimCanvas
|
|
11324
13886
|
});
|
|
11325
13887
|
//# sourceMappingURL=index.js.map
|