minerender 2.1.0-alpha.27 → 2.1.0-alpha.28
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 +26 -8
- package/dist/browser/index.d.ts +26 -8
- package/dist/browser/index.js +185 -90
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +120 -25
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +130 -23
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +26 -8
- package/dist/node/index.d.ts +26 -8
- package/dist/node/index.js +186 -90
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +120 -25
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -45411,6 +45411,7 @@ return ${compiler2.callType("value", tagType)}
|
|
|
45411
45411
|
SchematicParser: () => SchematicParser,
|
|
45412
45412
|
SkinObject: () => SkinObject,
|
|
45413
45413
|
SkinPart: () => SkinPart,
|
|
45414
|
+
SkinTextures: () => SkinTextures,
|
|
45414
45415
|
Skins: () => Skins,
|
|
45415
45416
|
StructureParser: () => StructureParser,
|
|
45416
45417
|
TextureAtlas: () => TextureAtlas,
|
|
@@ -63612,6 +63613,16 @@ return ${compiler2.callType("value", tagType)}
|
|
|
63612
63613
|
}
|
|
63613
63614
|
}
|
|
63614
63615
|
};
|
|
63616
|
+
var DataTexture = class extends Texture {
|
|
63617
|
+
constructor(data = null, width = 1, height = 1, format2, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, colorSpace) {
|
|
63618
|
+
super(null, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy, colorSpace);
|
|
63619
|
+
this.isDataTexture = true;
|
|
63620
|
+
this.image = { data, width, height };
|
|
63621
|
+
this.generateMipmaps = false;
|
|
63622
|
+
this.flipY = false;
|
|
63623
|
+
this.unpackAlignment = 1;
|
|
63624
|
+
}
|
|
63625
|
+
};
|
|
63615
63626
|
var InstancedBufferAttribute = class extends BufferAttribute {
|
|
63616
63627
|
constructor(array, itemSize, normalized, meshPerAttribute = 1) {
|
|
63617
63628
|
super(array, itemSize, normalized);
|
|
@@ -81332,14 +81343,98 @@ return ${compiler2.callType("value", tagType)}
|
|
|
81332
81343
|
|
|
81333
81344
|
// src/skin/scene/SkinObject.ts
|
|
81334
81345
|
var import_ts_deepmerge7 = __toESM(require_dist());
|
|
81346
|
+
|
|
81347
|
+
// src/skin/SkinTextures.ts
|
|
81348
|
+
init_dirname();
|
|
81349
|
+
init_buffer2();
|
|
81350
|
+
init_process2();
|
|
81351
|
+
var SkinTextures = class {
|
|
81352
|
+
static async get(src, legacy) {
|
|
81353
|
+
const image = await ImageLoader.getData(src);
|
|
81354
|
+
const scale = image.width / 64;
|
|
81355
|
+
if (!Number.isInteger(scale) || scale < 1 || image.height !== image.width && image.height !== image.width / 2) {
|
|
81356
|
+
throw new MineRenderError(`Invalid skin dimensions ${image.width}x${image.height}; expected 64x64 or 64x32, or an integer-scaled equivalent`);
|
|
81357
|
+
}
|
|
81358
|
+
const isLegacy = legacy ?? image.height === image.width / 2;
|
|
81359
|
+
if (!isLegacy && image.height !== image.width) {
|
|
81360
|
+
throw new MineRenderError(`Invalid skin dimensions ${image.width}x${image.height}; non-legacy skins must be square`);
|
|
81361
|
+
}
|
|
81362
|
+
const slim = !isLegacy && this.isSlim(image, scale);
|
|
81363
|
+
const key = `skin:${serializeImageKey({ src })}:${isLegacy}`;
|
|
81364
|
+
const material = Caching.materialCache.get(key, () => {
|
|
81365
|
+
const pixels = isLegacy ? this.normalizeLegacy(image, scale) : new Uint8Array(image.data);
|
|
81366
|
+
const texture = Textures.initTextureProps(new DataTexture(pixels, image.width, image.width));
|
|
81367
|
+
texture.colorSpace = SRGBColorSpace;
|
|
81368
|
+
texture.flipY = true;
|
|
81369
|
+
texture.needsUpdate = true;
|
|
81370
|
+
return new MeshBasicMaterial({ map: texture, transparent: true, side: DoubleSide, alphaTest: 0.5 });
|
|
81371
|
+
});
|
|
81372
|
+
return { material, slim, legacy: isLegacy };
|
|
81373
|
+
}
|
|
81374
|
+
static isSlim(image, scale) {
|
|
81375
|
+
for (const [x4, y5] of [[46, 52], [54, 20]]) {
|
|
81376
|
+
for (let row = y5 * scale; row < (y5 + 12) * scale; row++) {
|
|
81377
|
+
for (let column = x4 * scale; column < (x4 + 1) * scale; column++) {
|
|
81378
|
+
if (image.data[(row * image.width + column) * 4 + 3] !== 0) return false;
|
|
81379
|
+
}
|
|
81380
|
+
}
|
|
81381
|
+
}
|
|
81382
|
+
return true;
|
|
81383
|
+
}
|
|
81384
|
+
static normalizeLegacy(image, scale) {
|
|
81385
|
+
const pixels = new Uint8Array(image.width * image.width * 4);
|
|
81386
|
+
pixels.set(image.data.subarray(0, image.width * image.width / 2 * 4));
|
|
81387
|
+
for (const [sx, sy, dx, dy, width, height] of [
|
|
81388
|
+
[4, 16, 20, 48, 4, 4],
|
|
81389
|
+
[8, 16, 24, 48, 4, 4],
|
|
81390
|
+
[0, 20, 24, 52, 4, 12],
|
|
81391
|
+
[4, 20, 20, 52, 4, 12],
|
|
81392
|
+
[8, 20, 16, 52, 4, 12],
|
|
81393
|
+
[12, 20, 28, 52, 4, 12],
|
|
81394
|
+
[44, 16, 36, 48, 4, 4],
|
|
81395
|
+
[48, 16, 40, 48, 4, 4],
|
|
81396
|
+
[40, 20, 40, 52, 4, 12],
|
|
81397
|
+
[44, 20, 36, 52, 4, 12],
|
|
81398
|
+
[48, 20, 32, 52, 4, 12],
|
|
81399
|
+
[52, 20, 44, 52, 4, 12]
|
|
81400
|
+
]) {
|
|
81401
|
+
for (let y5 = 0; y5 < height * scale; y5++) {
|
|
81402
|
+
for (let x4 = 0; x4 < width * scale; x4++) {
|
|
81403
|
+
const source = ((sy * scale + y5) * image.width + sx * scale + x4) * 4;
|
|
81404
|
+
const target = ((dy * scale + y5) * image.width + (dx + width) * scale - 1 - x4) * 4;
|
|
81405
|
+
pixels.set(image.data.subarray(source, source + 4), target);
|
|
81406
|
+
}
|
|
81407
|
+
}
|
|
81408
|
+
}
|
|
81409
|
+
let clearHat = true;
|
|
81410
|
+
for (let y5 = 0; y5 < 32 * scale; y5++) {
|
|
81411
|
+
for (let x4 = 32 * scale; x4 < image.width; x4++) {
|
|
81412
|
+
if (pixels[(y5 * image.width + x4) * 4 + 3] < 128) clearHat = false;
|
|
81413
|
+
}
|
|
81414
|
+
}
|
|
81415
|
+
for (let y5 = 0; y5 < image.width; y5++) {
|
|
81416
|
+
for (let x4 = 0; x4 < image.width; x4++) {
|
|
81417
|
+
const alpha = (y5 * image.width + x4) * 4 + 3;
|
|
81418
|
+
if (x4 < 32 * scale && y5 < 16 * scale || y5 >= 16 * scale && y5 < 32 * scale || x4 >= 16 * scale && x4 < 48 * scale && y5 >= 48 * scale) {
|
|
81419
|
+
pixels[alpha] = 255;
|
|
81420
|
+
} else if (clearHat && x4 >= 32 * scale && y5 < 32 * scale) {
|
|
81421
|
+
pixels[alpha] = 0;
|
|
81422
|
+
}
|
|
81423
|
+
}
|
|
81424
|
+
}
|
|
81425
|
+
return pixels;
|
|
81426
|
+
}
|
|
81427
|
+
};
|
|
81428
|
+
|
|
81429
|
+
// src/skin/scene/SkinObject.ts
|
|
81335
81430
|
var SkinObject = class extends SceneObject {
|
|
81336
81431
|
constructor(options) {
|
|
81337
81432
|
super();
|
|
81338
81433
|
this.slim = false;
|
|
81339
|
-
this.
|
|
81340
|
-
this.
|
|
81341
|
-
this.skinTextureHeight = 64;
|
|
81434
|
+
this.detectedSlim = false;
|
|
81435
|
+
this.skinLoad = 0;
|
|
81342
81436
|
this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
81437
|
+
this.slim = this.options.slim ?? false;
|
|
81343
81438
|
}
|
|
81344
81439
|
async init() {
|
|
81345
81440
|
this.createMeshes();
|
|
@@ -81348,15 +81443,13 @@ return ${compiler2.callType("value", tagType)}
|
|
|
81348
81443
|
}
|
|
81349
81444
|
createMeshes() {
|
|
81350
81445
|
console.log("#createMeshes");
|
|
81351
|
-
const mat = Materials.MISSING_TEXTURE;
|
|
81446
|
+
const mat = this.skinMaterial ?? Materials.MISSING_TEXTURE;
|
|
81352
81447
|
{
|
|
81353
81448
|
const headGroup = this.createAndAddGroup("head", 0, 28, 0, "y" /* Y */, -4);
|
|
81354
81449
|
const headGeo = this.getBoxGeometry("head" /* HEAD */);
|
|
81355
81450
|
const head = this.createAndAddMesh("head", headGroup, headGeo, mat, "y" /* Y */, 4);
|
|
81356
|
-
|
|
81357
|
-
|
|
81358
|
-
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
81359
|
-
}
|
|
81451
|
+
const hatGeo = this.getBoxGeometry("hat" /* HAT */);
|
|
81452
|
+
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
81360
81453
|
}
|
|
81361
81454
|
{
|
|
81362
81455
|
const bodyGroup = this.createAndAddGroup("body", 0, 18, 0);
|
|
@@ -81399,21 +81492,30 @@ return ${compiler2.callType("value", tagType)}
|
|
|
81399
81492
|
}
|
|
81400
81493
|
console.log("#createMeshes done");
|
|
81401
81494
|
}
|
|
81402
|
-
setSkinTexture(src) {
|
|
81495
|
+
async setSkinTexture(src) {
|
|
81403
81496
|
if (typeof src === "undefined") return;
|
|
81404
|
-
|
|
81405
|
-
|
|
81406
|
-
|
|
81407
|
-
|
|
81408
|
-
|
|
81409
|
-
|
|
81497
|
+
this.skinTextureSrc = src;
|
|
81498
|
+
const load = ++this.skinLoad;
|
|
81499
|
+
const texture = await SkinTextures.get(src, this.options.legacy);
|
|
81500
|
+
if (load !== this.skinLoad) return;
|
|
81501
|
+
this.skinMaterial = texture.material;
|
|
81502
|
+
this.detectedSlim = texture.slim;
|
|
81503
|
+
this.updateSlim(this.options.slim ?? this.detectedSlim);
|
|
81504
|
+
for (const part of SKIN_PARTS) {
|
|
81505
|
+
const mesh = this.getMeshByName(part);
|
|
81410
81506
|
if (mesh) {
|
|
81411
|
-
mesh.material =
|
|
81507
|
+
mesh.material = texture.material;
|
|
81412
81508
|
}
|
|
81413
81509
|
}
|
|
81510
|
+
this.notifyDirty();
|
|
81414
81511
|
}
|
|
81415
81512
|
//TODO: cape
|
|
81513
|
+
/** Select the arm model, or pass undefined to use texture detection. */
|
|
81416
81514
|
setSlim(slim) {
|
|
81515
|
+
this.options.slim = slim;
|
|
81516
|
+
this.updateSlim(slim ?? this.detectedSlim);
|
|
81517
|
+
}
|
|
81518
|
+
updateSlim(slim) {
|
|
81417
81519
|
if (slim === this.slim) return;
|
|
81418
81520
|
this.slim = slim;
|
|
81419
81521
|
for (const part of ["leftArm" /* LEFT_ARM */, "leftSleeve" /* LEFT_SLEEVE */, "rightArm" /* RIGHT_ARM */, "rightSleeve" /* RIGHT_SLEEVE */]) {
|
|
@@ -81427,17 +81529,22 @@ return ${compiler2.callType("value", tagType)}
|
|
|
81427
81529
|
if (rightArm) rightArm.position.x -= offset;
|
|
81428
81530
|
this.notifyDirty();
|
|
81429
81531
|
}
|
|
81430
|
-
|
|
81431
|
-
|
|
81432
|
-
|
|
81433
|
-
this.legacy = legacy;
|
|
81532
|
+
/** Select the texture layout, or pass undefined to detect it from image dimensions. */
|
|
81533
|
+
async setLegacy(legacy) {
|
|
81534
|
+
if (legacy === this.options.legacy) return;
|
|
81535
|
+
this.options.legacy = legacy;
|
|
81536
|
+
if (this.skinTextureSrc) await this.setSkinTexture(this.skinTextureSrc);
|
|
81537
|
+
}
|
|
81538
|
+
dispose() {
|
|
81539
|
+
this.skinLoad++;
|
|
81540
|
+
super.dispose();
|
|
81434
81541
|
}
|
|
81435
81542
|
//TODO: layer toggles
|
|
81436
81543
|
getBoxGeometry(part) {
|
|
81437
81544
|
console.log("slim", this.slim);
|
|
81438
81545
|
const coordinates = this.slim ? slimSkinTextureCoordinates : classicSkinTextureCoordinates;
|
|
81439
81546
|
const geometries = this.slim ? slimSkinGeometries : classicSkinGeometries;
|
|
81440
|
-
return this._getBoxGeometryFromDimensions(geometries[part], coordinates[part], [64, 64], [
|
|
81547
|
+
return this._getBoxGeometryFromDimensions(geometries[part], coordinates[part], [64, 64], [64, 64]);
|
|
81441
81548
|
}
|
|
81442
81549
|
};
|
|
81443
81550
|
|
|
@@ -81547,10 +81654,10 @@ return ${compiler2.callType("value", tagType)}
|
|
|
81547
81654
|
this.dirty = true;
|
|
81548
81655
|
const obj = new SkinObject(options);
|
|
81549
81656
|
obj.scene = this;
|
|
81550
|
-
await obj.init();
|
|
81551
81657
|
if (skin) {
|
|
81552
|
-
obj.setSkinTexture(skin);
|
|
81658
|
+
await obj.setSkinTexture(skin);
|
|
81553
81659
|
}
|
|
81660
|
+
await obj.init();
|
|
81554
81661
|
parent.add(obj);
|
|
81555
81662
|
return obj;
|
|
81556
81663
|
}
|