minerender 2.1.0-alpha.37 → 2.1.0-alpha.38
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 +21 -2
- package/dist/browser/index.d.ts +21 -2
- package/dist/browser/index.js +275 -111
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +217 -53
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +177 -11
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +21 -2
- package/dist/node/index.d.ts +21 -2
- package/dist/node/index.js +277 -111
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +217 -53
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -48096,6 +48096,7 @@ return ${compiler2.callType("value", tagType)}
|
|
|
48096
48096
|
BrowserCache: () => BrowserCache,
|
|
48097
48097
|
BrowserEnv: () => BrowserEnv,
|
|
48098
48098
|
CUBE_FACES: () => CUBE_FACES,
|
|
48099
|
+
CUBE_FACE_OFFSETS: () => CUBE_FACE_OFFSETS,
|
|
48099
48100
|
Caching: () => Caching,
|
|
48100
48101
|
CanvasImage: () => CanvasImage,
|
|
48101
48102
|
Chunk: () => Chunk,
|
|
@@ -48129,6 +48130,7 @@ return ${compiler2.callType("value", tagType)}
|
|
|
48129
48130
|
MineRenderWorld: () => MineRenderWorld,
|
|
48130
48131
|
MinecraftCubeTexture: () => MinecraftCubeTexture,
|
|
48131
48132
|
MinecraftFaceUV: () => MinecraftFaceUV,
|
|
48133
|
+
ModelCulling: () => ModelCulling,
|
|
48132
48134
|
ModelGenerator: () => ModelGenerator,
|
|
48133
48135
|
ModelMerger: () => ModelMerger,
|
|
48134
48136
|
ModelObject: () => ModelObject,
|
|
@@ -68052,6 +68054,14 @@ return ${compiler2.callType("value", tagType)}
|
|
|
68052
68054
|
return CubeFaceIndex2;
|
|
68053
68055
|
})(CubeFaceIndex || {});
|
|
68054
68056
|
var CUBE_FACES = Object.values(CubeFace);
|
|
68057
|
+
var CUBE_FACE_OFFSETS = [
|
|
68058
|
+
[1, 0, 0],
|
|
68059
|
+
[-1, 0, 0],
|
|
68060
|
+
[0, 1, 0],
|
|
68061
|
+
[0, -1, 0],
|
|
68062
|
+
[0, 0, 1],
|
|
68063
|
+
[0, 0, -1]
|
|
68064
|
+
];
|
|
68055
68065
|
|
|
68056
68066
|
// src/Disposable.ts
|
|
68057
68067
|
init_dirname();
|
|
@@ -82275,6 +82285,44 @@ ${key}` : key;
|
|
|
82275
82285
|
return Array.isArray(obj) && obj.length === 4;
|
|
82276
82286
|
}
|
|
82277
82287
|
|
|
82288
|
+
// src/model/ModelCulling.ts
|
|
82289
|
+
init_dirname();
|
|
82290
|
+
init_buffer2();
|
|
82291
|
+
init_process2();
|
|
82292
|
+
var ModelCulling = class {
|
|
82293
|
+
static toLocalMask(worldMask, rotation) {
|
|
82294
|
+
let localMask = 0;
|
|
82295
|
+
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
82296
|
+
const normal = new Vector3(...offset).applyEuler(rotation);
|
|
82297
|
+
const worldFace = CUBE_FACE_OFFSETS.findIndex(([x4, y5, z4]) => Math.abs(normal.x - x4) < 1e-6 && Math.abs(normal.y - y5) < 1e-6 && Math.abs(normal.z - z4) < 1e-6);
|
|
82298
|
+
if (worldFace < 0) return 0;
|
|
82299
|
+
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
82300
|
+
}
|
|
82301
|
+
return localMask;
|
|
82302
|
+
}
|
|
82303
|
+
static isOpaqueFullCube(atlas) {
|
|
82304
|
+
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
82305
|
+
const element = atlas.model.elements[0];
|
|
82306
|
+
if (element.from.length !== 3 || !element.from.every((value) => value === 0) || element.to.length !== 3 || !element.to.every((value) => value === 16) || element.rotation && element.rotation.angle !== 0 || element.mappedUv?.length !== 48 || !element.mappedUv.every(Number.isFinite)) return false;
|
|
82307
|
+
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
82308
|
+
return CUBE_FACES.every((face, faceIndex) => {
|
|
82309
|
+
const texture = element.faces[face]?.texture;
|
|
82310
|
+
if (!texture?.startsWith("#")) return false;
|
|
82311
|
+
const key = texture.slice(1);
|
|
82312
|
+
const position = atlas.positions[key];
|
|
82313
|
+
const size = atlas.sizes[key];
|
|
82314
|
+
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
82315
|
+
for (let vertex2 = 0; vertex2 < 4; vertex2++) {
|
|
82316
|
+
const uvIndex = (faceIndex * 4 + vertex2) * 2;
|
|
82317
|
+
const x4 = element.mappedUv[uvIndex] * atlas.image.width;
|
|
82318
|
+
const y5 = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
82319
|
+
if (x4 < position[0] - 1e-6 || x4 > position[0] + size[0] + 1e-6 || y5 < position[1] - 1e-6 || y5 > position[1] + size[1] + 1e-6) return false;
|
|
82320
|
+
}
|
|
82321
|
+
return true;
|
|
82322
|
+
});
|
|
82323
|
+
}
|
|
82324
|
+
};
|
|
82325
|
+
|
|
82278
82326
|
// src/model/ModelElement.ts
|
|
82279
82327
|
init_dirname();
|
|
82280
82328
|
init_buffer2();
|
|
@@ -82960,6 +83008,9 @@ ${key}` : key;
|
|
|
82960
83008
|
get textureAtlas() {
|
|
82961
83009
|
return this.atlas;
|
|
82962
83010
|
}
|
|
83011
|
+
get isOpaqueFullCube() {
|
|
83012
|
+
return !this.options.displayPosition && ModelCulling.isOpaqueFullCube(this.atlas);
|
|
83013
|
+
}
|
|
82963
83014
|
//TODO: support for replacing textures
|
|
82964
83015
|
async loadTextures() {
|
|
82965
83016
|
this.atlas = await UVMapper.getAtlas(this.originalModel);
|
|
@@ -82973,6 +83024,15 @@ ${key}` : key;
|
|
|
82973
83024
|
if (this.atlas.model.elements) {
|
|
82974
83025
|
this.atlas.model.elements?.forEach((el) => {
|
|
82975
83026
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
83027
|
+
if (this.options.cullMask) {
|
|
83028
|
+
const indices = Array.from(elGeo.getIndex().array);
|
|
83029
|
+
elGeo.setIndex(indices.filter((_4, index) => {
|
|
83030
|
+
const face = CUBE_FACES[Math.floor(index / 6)];
|
|
83031
|
+
const direction = CUBE_FACES.findIndex((name2) => name2 === el.faces[face]?.cullface);
|
|
83032
|
+
return direction < 0 || !(this.options.cullMask & 1 << direction);
|
|
83033
|
+
}));
|
|
83034
|
+
elGeo.clearGroups();
|
|
83035
|
+
}
|
|
82976
83036
|
if (this.options.uvLockRotation) {
|
|
82977
83037
|
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler(...this.options.uvLockRotation));
|
|
82978
83038
|
}
|
|
@@ -83096,6 +83156,7 @@ ${key}` : key;
|
|
|
83096
83156
|
this._instanceModel = [];
|
|
83097
83157
|
this._variants = [];
|
|
83098
83158
|
this._models = [];
|
|
83159
|
+
this._cullMask = 0;
|
|
83099
83160
|
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
83100
83161
|
}
|
|
83101
83162
|
async init() {
|
|
@@ -83129,12 +83190,69 @@ ${key}` : key;
|
|
|
83129
83190
|
super.removeFromScene();
|
|
83130
83191
|
}
|
|
83131
83192
|
clearModels() {
|
|
83132
|
-
|
|
83193
|
+
this.removeModels(this._models.splice(0));
|
|
83194
|
+
this._isInstanced = false;
|
|
83195
|
+
this._instanceCounter = 0;
|
|
83196
|
+
}
|
|
83197
|
+
removeModels(models) {
|
|
83198
|
+
for (const model of models) {
|
|
83133
83199
|
model.removeFromScene();
|
|
83134
83200
|
if (!isInstanceReference(model)) model.dispose();
|
|
83135
83201
|
}
|
|
83136
|
-
|
|
83137
|
-
|
|
83202
|
+
}
|
|
83203
|
+
get isOccluding() {
|
|
83204
|
+
return this._models.some((model) => {
|
|
83205
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
83206
|
+
return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
|
|
83207
|
+
});
|
|
83208
|
+
}
|
|
83209
|
+
getModelMatrix(model) {
|
|
83210
|
+
if (isInstanceReference(model)) return model.getMatrix();
|
|
83211
|
+
if (model.matrixAutoUpdate) model.updateMatrix();
|
|
83212
|
+
return model.matrix.clone();
|
|
83213
|
+
}
|
|
83214
|
+
getModelCullMask(model, worldMask) {
|
|
83215
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
83216
|
+
if (object.options.displayPosition) return 0;
|
|
83217
|
+
const position = new Vector3();
|
|
83218
|
+
const rotation = new Quaternion();
|
|
83219
|
+
const scale = new Vector3();
|
|
83220
|
+
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
83221
|
+
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector3(1, 1, 1)) > 1e-10) return 0;
|
|
83222
|
+
return ModelCulling.toLocalMask(worldMask, new Euler().setFromQuaternion(rotation));
|
|
83223
|
+
}
|
|
83224
|
+
async setCullMask(worldMask) {
|
|
83225
|
+
worldMask &= 63;
|
|
83226
|
+
const replacements = [];
|
|
83227
|
+
try {
|
|
83228
|
+
for (const model of this._models) {
|
|
83229
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
83230
|
+
const cullMask = this.getModelCullMask(model, worldMask);
|
|
83231
|
+
if (cullMask === (object.options.cullMask ?? 0)) {
|
|
83232
|
+
replacements.push(model);
|
|
83233
|
+
continue;
|
|
83234
|
+
}
|
|
83235
|
+
const matrix = this.getModelMatrix(model);
|
|
83236
|
+
const replacement = await this.scene.addModel(object.originalModel, { ...object.options, cullMask });
|
|
83237
|
+
replacements.push(replacement);
|
|
83238
|
+
if (isInstanceReference(replacement)) {
|
|
83239
|
+
replacement.setMatrix(matrix);
|
|
83240
|
+
} else {
|
|
83241
|
+
replacement.matrix.copy(matrix);
|
|
83242
|
+
matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
83243
|
+
replacement.matrixAutoUpdate = object.matrixAutoUpdate;
|
|
83244
|
+
replacement.visible = object.visible;
|
|
83245
|
+
}
|
|
83246
|
+
}
|
|
83247
|
+
} catch (error) {
|
|
83248
|
+
this.removeModels(replacements.filter((model) => !this._models.includes(model)));
|
|
83249
|
+
throw error;
|
|
83250
|
+
}
|
|
83251
|
+
const previous = this._models;
|
|
83252
|
+
this._models = replacements;
|
|
83253
|
+
this._cullMask = worldMask;
|
|
83254
|
+
this.removeModels(previous.filter((model) => !replacements.includes(model)));
|
|
83255
|
+
this.notifyDirty();
|
|
83138
83256
|
}
|
|
83139
83257
|
get state() {
|
|
83140
83258
|
return this._state;
|
|
@@ -83227,7 +83345,8 @@ ${key}` : key;
|
|
|
83227
83345
|
const options = {
|
|
83228
83346
|
...this.options,
|
|
83229
83347
|
tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
|
|
83230
|
-
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
|
|
83348
|
+
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0,
|
|
83349
|
+
cullMask: this.options.displayPosition ? 0 : ModelCulling.toLocalMask(this._cullMask, rotation)
|
|
83231
83350
|
};
|
|
83232
83351
|
const obj = await this.scene.addModel(model, options);
|
|
83233
83352
|
if (isInstanceReference(obj) || obj.isInstanced) {
|
|
@@ -84539,11 +84658,12 @@ ${key}` : key;
|
|
|
84539
84658
|
console.log("instanceMeshes + key");
|
|
84540
84659
|
let key = asset.key.serialize();
|
|
84541
84660
|
if (isModelObject(obj)) {
|
|
84542
|
-
const { displayPosition, uvLockRotation, tints } = obj.options;
|
|
84661
|
+
const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
|
|
84543
84662
|
if (displayPosition) key += `|display:${displayPosition}`;
|
|
84544
84663
|
if (uvLockRotation) key += `|uvlock:${uvLockRotation.join(",")}`;
|
|
84545
84664
|
const palette = Object.entries(tints ?? {}).sort(([a4], [b4]) => Number(a4) - Number(b4));
|
|
84546
84665
|
if (palette.length) key += `|tints:${JSON.stringify(palette)}`;
|
|
84666
|
+
if (cullMask) key += `|cull:${cullMask}`;
|
|
84547
84667
|
}
|
|
84548
84668
|
return this.instanceManager.getOrCreate(key, async () => {
|
|
84549
84669
|
obj.scene = this;
|
|
@@ -87635,6 +87755,7 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
87635
87755
|
var MineRenderWorld = class {
|
|
87636
87756
|
constructor(scene) {
|
|
87637
87757
|
this._chunks = /* @__PURE__ */ new Map();
|
|
87758
|
+
this.pendingCulling = /* @__PURE__ */ new Map();
|
|
87638
87759
|
this.scene = scene;
|
|
87639
87760
|
}
|
|
87640
87761
|
getBlockAt(posOrX, y5, z4) {
|
|
@@ -87695,16 +87816,54 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
87695
87816
|
}
|
|
87696
87817
|
}
|
|
87697
87818
|
async clear() {
|
|
87698
|
-
|
|
87819
|
+
await this.culling;
|
|
87820
|
+
const chunks = [...this._chunks.values()];
|
|
87821
|
+
this._chunks.clear();
|
|
87822
|
+
for (const chunk of chunks) {
|
|
87699
87823
|
await chunk.dispose();
|
|
87700
87824
|
}
|
|
87701
|
-
|
|
87825
|
+
}
|
|
87826
|
+
updateCulling(positions) {
|
|
87827
|
+
for (const pos of positions) {
|
|
87828
|
+
this.pendingCulling.set(pos.toArray().join(","), pos.clone());
|
|
87829
|
+
for (const offset of CUBE_FACE_OFFSETS) {
|
|
87830
|
+
const neighbor = pos.clone().add(new Vector3(...offset));
|
|
87831
|
+
this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
|
|
87832
|
+
}
|
|
87833
|
+
}
|
|
87834
|
+
return this.culling ?? (this.culling = Promise.resolve().then(async () => {
|
|
87835
|
+
try {
|
|
87836
|
+
while (this.pendingCulling.size) {
|
|
87837
|
+
const batch = [...this.pendingCulling.values()];
|
|
87838
|
+
this.pendingCulling.clear();
|
|
87839
|
+
for (const pos of batch) {
|
|
87840
|
+
const block = this.getBlockAt(pos)?.object;
|
|
87841
|
+
if (!block) continue;
|
|
87842
|
+
let mask = 0;
|
|
87843
|
+
for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
87844
|
+
if (this.getBlockAt(pos.clone().add(new Vector3(...offset)))?.object.isOccluding) {
|
|
87845
|
+
mask |= 1 << face;
|
|
87846
|
+
}
|
|
87847
|
+
}
|
|
87848
|
+
await block.setCullMask(mask);
|
|
87849
|
+
}
|
|
87850
|
+
}
|
|
87851
|
+
} finally {
|
|
87852
|
+
this.culling = void 0;
|
|
87853
|
+
}
|
|
87854
|
+
}));
|
|
87702
87855
|
}
|
|
87703
87856
|
getOrCreateChunkAt(pos) {
|
|
87704
87857
|
const key = this.worldPosToChunkKey(pos);
|
|
87705
87858
|
let chunk = this._chunks.get(key);
|
|
87706
87859
|
if (typeof chunk === "undefined") {
|
|
87707
|
-
chunk = new Chunk(
|
|
87860
|
+
chunk = new Chunk(
|
|
87861
|
+
this.scene,
|
|
87862
|
+
Math.floor(pos.x / 16),
|
|
87863
|
+
Math.floor(pos.y / 16),
|
|
87864
|
+
Math.floor(pos.z / 16),
|
|
87865
|
+
(positions) => this.updateCulling(positions)
|
|
87866
|
+
);
|
|
87708
87867
|
this._chunks.set(key, chunk);
|
|
87709
87868
|
}
|
|
87710
87869
|
return chunk;
|
|
@@ -87741,7 +87900,8 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
87741
87900
|
|
|
87742
87901
|
// src/world/Chunk.ts
|
|
87743
87902
|
var Chunk = class _Chunk {
|
|
87744
|
-
constructor(scene, x4, y5, z4) {
|
|
87903
|
+
constructor(scene, x4, y5, z4, onBlocksChanged) {
|
|
87904
|
+
this.onBlocksChanged = onBlocksChanged;
|
|
87745
87905
|
this.data = new ChunkData();
|
|
87746
87906
|
this.renderedBlocks = /* @__PURE__ */ new Map();
|
|
87747
87907
|
this.scene = scene;
|
|
@@ -87784,10 +87944,10 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
87784
87944
|
const readBlock = this.data.snapshot(index);
|
|
87785
87945
|
this.renderedBlocks.get(index)?.object.removeFromScene();
|
|
87786
87946
|
this.renderedBlocks.delete(index);
|
|
87787
|
-
if (!readBlock) return void 0;
|
|
87788
|
-
const stored = readBlock();
|
|
87789
87947
|
let object;
|
|
87790
87948
|
try {
|
|
87949
|
+
if (!readBlock) return void 0;
|
|
87950
|
+
const stored = readBlock();
|
|
87791
87951
|
const blockState = await BlockStates.get(AssetKey.parse("blockstates", stored.type));
|
|
87792
87952
|
if (!blockState) {
|
|
87793
87953
|
this.data.set(index, void 0);
|
|
@@ -87809,12 +87969,18 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
87809
87969
|
this.data.set(index, void 0);
|
|
87810
87970
|
object?.removeFromScene();
|
|
87811
87971
|
throw error;
|
|
87972
|
+
} finally {
|
|
87973
|
+
await this.onBlocksChanged?.([worldPos]);
|
|
87812
87974
|
}
|
|
87813
87975
|
}
|
|
87814
87976
|
async clear() {
|
|
87977
|
+
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
87978
|
+
new Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
87979
|
+
));
|
|
87815
87980
|
for (const info of this.renderedBlocks.values()) info.object.removeFromScene();
|
|
87816
87981
|
this.renderedBlocks.clear();
|
|
87817
87982
|
this.data.clear();
|
|
87983
|
+
await this.onBlocksChanged?.(positions);
|
|
87818
87984
|
}
|
|
87819
87985
|
async dispose() {
|
|
87820
87986
|
await this.clear();
|