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