minerender 2.1.0-alpha.54 → 2.1.0-alpha.55
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 +159 -1
- package/dist/browser/index.d.ts +159 -1
- package/dist/browser/index.js +546 -261
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +310 -25
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +296 -2
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +159 -1
- package/dist/node/index.d.ts +159 -1
- package/dist/node/index.js +556 -261
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +314 -25
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -32176,7 +32176,9 @@ var MineRender = (() => {
|
|
|
32176
32176
|
this.defaultBlockStatesCache,
|
|
32177
32177
|
this.blockTintCache,
|
|
32178
32178
|
this.entityModelCache,
|
|
32179
|
-
this.entityTextureCache
|
|
32179
|
+
this.entityTextureCache,
|
|
32180
|
+
this.entityAnimationCache,
|
|
32181
|
+
this.blockEntityIndexCache
|
|
32180
32182
|
];
|
|
32181
32183
|
}
|
|
32182
32184
|
static clear() {
|
|
@@ -32221,6 +32223,8 @@ var MineRender = (() => {
|
|
|
32221
32223
|
_Caching.blockTintCache = _Caching.createAssetCache();
|
|
32222
32224
|
_Caching.entityModelCache = _Caching.createAssetCache();
|
|
32223
32225
|
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
32226
|
+
_Caching.entityAnimationCache = _Caching.createAssetCache();
|
|
32227
|
+
_Caching.blockEntityIndexCache = _Caching.createAssetCache();
|
|
32224
32228
|
Caching = _Caching;
|
|
32225
32229
|
}
|
|
32226
32230
|
});
|
|
@@ -83042,6 +83046,7 @@ ${key}` : key;
|
|
|
83042
83046
|
BUILTIN_GENERATED: () => BUILTIN_GENERATED,
|
|
83043
83047
|
BasicAssetKey: () => BasicAssetKey,
|
|
83044
83048
|
BatchedExecutor: () => BatchedExecutor,
|
|
83049
|
+
BlockEntities: () => BlockEntities,
|
|
83045
83050
|
BlockObject: () => BlockObject,
|
|
83046
83051
|
BlockStateResolver: () => BlockStateResolver,
|
|
83047
83052
|
BlockStates: () => BlockStates,
|
|
@@ -83065,7 +83070,9 @@ ${key}` : key;
|
|
|
83065
83070
|
DefaultBlockStates: () => DefaultBlockStates,
|
|
83066
83071
|
DisplayPosition: () => DisplayPosition,
|
|
83067
83072
|
DisplayTransforms: () => DisplayTransforms,
|
|
83073
|
+
ENTITY_ANIMATION_CHANNELS: () => ENTITY_ANIMATION_CHANNELS,
|
|
83068
83074
|
Entities: () => Entities,
|
|
83075
|
+
EntityAnimationPlayer: () => EntityAnimationPlayer,
|
|
83069
83076
|
EntityObject: () => EntityObject,
|
|
83070
83077
|
Env: () => Env,
|
|
83071
83078
|
FluidModelObject: () => FluidModelObject,
|
|
@@ -83139,6 +83146,7 @@ ${key}` : key;
|
|
|
83139
83146
|
createCanvas: () => createCanvas,
|
|
83140
83147
|
createFluidGeometry: () => createFluidGeometry,
|
|
83141
83148
|
createImage: () => createImage,
|
|
83149
|
+
entityAnimationTime: () => entityAnimationTime,
|
|
83142
83150
|
estimateBytesUsed: () => estimateBytesUsed,
|
|
83143
83151
|
getBlockFluidState: () => getBlockFluidState,
|
|
83144
83152
|
getFluidKind: () => getFluidKind,
|
|
@@ -83172,6 +83180,8 @@ ${key}` : key;
|
|
|
83172
83180
|
prefix: () => prefix,
|
|
83173
83181
|
probeImageSize: () => probeImageSize,
|
|
83174
83182
|
registerBrowserEnv: () => registerBrowserEnv,
|
|
83183
|
+
sampleEntityAnimation: () => sampleEntityAnimation,
|
|
83184
|
+
sampleEntityKeyframes: () => sampleEntityKeyframes,
|
|
83175
83185
|
sampleFluid: () => sampleFluid,
|
|
83176
83186
|
serializeBoxGeometryKey: () => serializeBoxGeometryKey,
|
|
83177
83187
|
serializeImageKey: () => serializeImageKey,
|
|
@@ -83543,6 +83553,62 @@ ${key}` : key;
|
|
|
83543
83553
|
init_AssetKey();
|
|
83544
83554
|
init_AssetLoader();
|
|
83545
83555
|
init_Assets();
|
|
83556
|
+
|
|
83557
|
+
// src/assets/BlockEntities.ts
|
|
83558
|
+
init_dirname();
|
|
83559
|
+
init_buffer2();
|
|
83560
|
+
init_process2();
|
|
83561
|
+
init_three_module();
|
|
83562
|
+
init_AssetKey();
|
|
83563
|
+
init_AssetLoader();
|
|
83564
|
+
init_source();
|
|
83565
|
+
init_Caching();
|
|
83566
|
+
var BlockEntities = class {
|
|
83567
|
+
/**
|
|
83568
|
+
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
83569
|
+
* a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty
|
|
83570
|
+
* result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.
|
|
83571
|
+
*/
|
|
83572
|
+
static async getIndex(root) {
|
|
83573
|
+
const key = new AssetKey("entity-models", "blocks", void 0, void 0, void 0, ".json", root);
|
|
83574
|
+
key.rootType = void 0;
|
|
83575
|
+
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
83576
|
+
try {
|
|
83577
|
+
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
83578
|
+
} catch (error) {
|
|
83579
|
+
console.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
83580
|
+
return {};
|
|
83581
|
+
}
|
|
83582
|
+
});
|
|
83583
|
+
return index ?? {};
|
|
83584
|
+
}
|
|
83585
|
+
/** The index entry of a block ID such as `minecraft:chest`. */
|
|
83586
|
+
static entry(index, block) {
|
|
83587
|
+
const entry = Object.prototype.hasOwnProperty.call(index, block) ? index[block] : void 0;
|
|
83588
|
+
return Array.isArray(entry?.parts) ? entry : void 0;
|
|
83589
|
+
}
|
|
83590
|
+
/** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */
|
|
83591
|
+
static resolve(index, block, state = {}) {
|
|
83592
|
+
const entry = this.entry(index, block);
|
|
83593
|
+
if (!entry) return void 0;
|
|
83594
|
+
const value = (property) => String(state[property]).toLowerCase();
|
|
83595
|
+
const parts = entry.parts.filter((part) => Object.entries(part.when ?? {}).every(([property, values]) => String(values).split("|").includes(value(property))));
|
|
83596
|
+
if (!parts.length) return void 0;
|
|
83597
|
+
let rotation = 0;
|
|
83598
|
+
if (entry.rotation) {
|
|
83599
|
+
const selected = value(entry.rotation.property);
|
|
83600
|
+
rotation = "degrees" in entry.rotation ? entry.rotation.degrees[selected] : Number(selected) * entry.rotation.step;
|
|
83601
|
+
if (!Number.isFinite(rotation)) rotation = 0;
|
|
83602
|
+
}
|
|
83603
|
+
return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };
|
|
83604
|
+
}
|
|
83605
|
+
/** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
|
|
83606
|
+
static matrix(resolved, matrix = new Matrix4()) {
|
|
83607
|
+
return matrix.makeTranslation(8, 0, 8).multiply(new Matrix4().makeRotationY(resolved.rotation * Math.PI / 180)).multiply(new Matrix4().makeTranslation(resolved.translation[0] - 8, resolved.translation[1], resolved.translation[2] - 8));
|
|
83608
|
+
}
|
|
83609
|
+
};
|
|
83610
|
+
|
|
83611
|
+
// src/assets/index.ts
|
|
83546
83612
|
init_BlockStates();
|
|
83547
83613
|
|
|
83548
83614
|
// src/assets/Entities.ts
|
|
@@ -83616,6 +83682,15 @@ ${key}` : key;
|
|
|
83616
83682
|
})));
|
|
83617
83683
|
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
83618
83684
|
}
|
|
83685
|
+
/**
|
|
83686
|
+
* Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
|
|
83687
|
+
*/
|
|
83688
|
+
static async getAnimations(modelKey) {
|
|
83689
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
83690
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
|
|
83691
|
+
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
83692
|
+
return file?.animations;
|
|
83693
|
+
}
|
|
83619
83694
|
static async resolveTexture(modelKey) {
|
|
83620
83695
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
83621
83696
|
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
@@ -83731,6 +83806,51 @@ ${key}` : key;
|
|
|
83731
83806
|
init_buffer2();
|
|
83732
83807
|
init_process2();
|
|
83733
83808
|
|
|
83809
|
+
// src/entity/EntityAnimation.ts
|
|
83810
|
+
init_dirname();
|
|
83811
|
+
init_buffer2();
|
|
83812
|
+
init_process2();
|
|
83813
|
+
var ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
|
|
83814
|
+
function catmullRom(delta, p0, p1, p22, p32) {
|
|
83815
|
+
return 0.5 * (2 * p1 + (p22 - p0) * delta + (2 * p0 - 5 * p1 + 4 * p22 - p32) * delta * delta + (3 * p1 - p0 - 3 * p22 + p32) * delta * delta * delta);
|
|
83816
|
+
}
|
|
83817
|
+
function sampleEntityKeyframes(keyframes, time) {
|
|
83818
|
+
if (keyframes.length === 0) return [0, 0, 0];
|
|
83819
|
+
let low = 0, high = keyframes.length;
|
|
83820
|
+
while (low < high) {
|
|
83821
|
+
const middle = low + high >>> 1;
|
|
83822
|
+
if (time <= keyframes[middle].time) high = middle;
|
|
83823
|
+
else low = middle + 1;
|
|
83824
|
+
}
|
|
83825
|
+
const a4 = Math.max(0, low - 1);
|
|
83826
|
+
const b4 = Math.min(keyframes.length - 1, a4 + 1);
|
|
83827
|
+
const from = keyframes[a4];
|
|
83828
|
+
const to = keyframes[b4];
|
|
83829
|
+
const delta = a4 === b4 ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
|
|
83830
|
+
if (to.interpolation === "catmullrom") {
|
|
83831
|
+
const before = keyframes[Math.max(0, a4 - 1)].value;
|
|
83832
|
+
const after = keyframes[Math.min(keyframes.length - 1, b4 + 1)].value;
|
|
83833
|
+
return [0, 1, 2].map((i4) => catmullRom(delta, before[i4], from.value[i4], to.value[i4], after[i4]));
|
|
83834
|
+
}
|
|
83835
|
+
const target = to.pre ?? to.value;
|
|
83836
|
+
return [0, 1, 2].map((i4) => from.value[i4] + (target[i4] - from.value[i4]) * delta);
|
|
83837
|
+
}
|
|
83838
|
+
function entityAnimationTime(animation, time, loop = animation.loop) {
|
|
83839
|
+
return loop && animation.length > 0 ? time % animation.length : time;
|
|
83840
|
+
}
|
|
83841
|
+
function sampleEntityAnimation(animation, time, loop = animation.loop) {
|
|
83842
|
+
const elapsed = entityAnimationTime(animation, time, loop);
|
|
83843
|
+
const pose = {};
|
|
83844
|
+
for (const [name2, bone] of Object.entries(animation.bones)) {
|
|
83845
|
+
const sampled = pose[name2] = {};
|
|
83846
|
+
for (const channel of ENTITY_ANIMATION_CHANNELS) {
|
|
83847
|
+
const keyframes = bone[channel];
|
|
83848
|
+
if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
|
|
83849
|
+
}
|
|
83850
|
+
}
|
|
83851
|
+
return pose;
|
|
83852
|
+
}
|
|
83853
|
+
|
|
83734
83854
|
// src/entity/EntityModel.ts
|
|
83735
83855
|
init_dirname();
|
|
83736
83856
|
init_buffer2();
|
|
@@ -83741,6 +83861,80 @@ ${key}` : key;
|
|
|
83741
83861
|
init_buffer2();
|
|
83742
83862
|
init_process2();
|
|
83743
83863
|
|
|
83864
|
+
// src/entity/scene/EntityAnimationPlayer.ts
|
|
83865
|
+
init_dirname();
|
|
83866
|
+
init_buffer2();
|
|
83867
|
+
init_process2();
|
|
83868
|
+
var ZERO = [0, 0, 0];
|
|
83869
|
+
var EntityAnimationPlayer = class {
|
|
83870
|
+
constructor() {
|
|
83871
|
+
this.parts = [];
|
|
83872
|
+
this._time = 0;
|
|
83873
|
+
this.loop = false;
|
|
83874
|
+
this.speed = 1;
|
|
83875
|
+
}
|
|
83876
|
+
get animation() {
|
|
83877
|
+
return this._animation;
|
|
83878
|
+
}
|
|
83879
|
+
get time() {
|
|
83880
|
+
return this._time;
|
|
83881
|
+
}
|
|
83882
|
+
/**
|
|
83883
|
+
* Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
|
|
83884
|
+
* bones without a matching part are skipped.
|
|
83885
|
+
*/
|
|
83886
|
+
play(layers, animation, options = {}) {
|
|
83887
|
+
this.stop();
|
|
83888
|
+
this._animation = animation;
|
|
83889
|
+
this._time = options.time ?? 0;
|
|
83890
|
+
this.loop = options.loop ?? animation.loop;
|
|
83891
|
+
this.speed = options.speed ?? 1;
|
|
83892
|
+
for (const layer of layers) {
|
|
83893
|
+
for (const bone of Object.keys(animation.bones)) {
|
|
83894
|
+
const object = layer.getObjectByName(`group:${bone}`);
|
|
83895
|
+
if (!object) continue;
|
|
83896
|
+
this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
|
|
83897
|
+
}
|
|
83898
|
+
}
|
|
83899
|
+
this.apply();
|
|
83900
|
+
}
|
|
83901
|
+
/** Restores the default poses. Returns whether an animation was active. */
|
|
83902
|
+
stop() {
|
|
83903
|
+
if (!this._animation) return false;
|
|
83904
|
+
for (const part of this.parts) {
|
|
83905
|
+
part.object.position.copy(part.position);
|
|
83906
|
+
part.object.rotation.copy(part.rotation);
|
|
83907
|
+
part.object.scale.copy(part.scale);
|
|
83908
|
+
}
|
|
83909
|
+
this.clear();
|
|
83910
|
+
return true;
|
|
83911
|
+
}
|
|
83912
|
+
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
83913
|
+
clear() {
|
|
83914
|
+
this.parts = [];
|
|
83915
|
+
this._animation = void 0;
|
|
83916
|
+
this._time = 0;
|
|
83917
|
+
}
|
|
83918
|
+
setTime(seconds) {
|
|
83919
|
+
if (!this._animation) return false;
|
|
83920
|
+
this._time = seconds;
|
|
83921
|
+
this.apply();
|
|
83922
|
+
return true;
|
|
83923
|
+
}
|
|
83924
|
+
advance(deltaSeconds) {
|
|
83925
|
+
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
83926
|
+
}
|
|
83927
|
+
apply() {
|
|
83928
|
+
const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
|
|
83929
|
+
for (const part of this.parts) {
|
|
83930
|
+
const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
|
|
83931
|
+
part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
|
|
83932
|
+
part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
|
|
83933
|
+
part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
|
|
83934
|
+
}
|
|
83935
|
+
}
|
|
83936
|
+
};
|
|
83937
|
+
|
|
83744
83938
|
// src/entity/scene/EntityObject.ts
|
|
83745
83939
|
init_dirname();
|
|
83746
83940
|
init_buffer2();
|
|
@@ -83765,6 +83959,7 @@ ${key}` : key;
|
|
|
83765
83959
|
this.scrollMaterials = [];
|
|
83766
83960
|
/** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
|
|
83767
83961
|
this.age = 0;
|
|
83962
|
+
this.animationPlayer = new EntityAnimationPlayer();
|
|
83768
83963
|
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
83769
83964
|
}
|
|
83770
83965
|
async init() {
|
|
@@ -83776,6 +83971,7 @@ ${key}` : key;
|
|
|
83776
83971
|
}
|
|
83777
83972
|
disposeAndRemoveAllChildren() {
|
|
83778
83973
|
this.clearScrollMaterials();
|
|
83974
|
+
this.animationPlayer.clear();
|
|
83779
83975
|
super.disposeAndRemoveAllChildren();
|
|
83780
83976
|
}
|
|
83781
83977
|
clearScrollMaterials() {
|
|
@@ -83793,6 +83989,39 @@ ${key}` : key;
|
|
|
83793
83989
|
}
|
|
83794
83990
|
this.notifyDirty();
|
|
83795
83991
|
}
|
|
83992
|
+
//<editor-fold desc="ANIMATION">
|
|
83993
|
+
/** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
|
|
83994
|
+
get animation() {
|
|
83995
|
+
return this.animationPlayer.animation;
|
|
83996
|
+
}
|
|
83997
|
+
/** Seconds since the animation started, before looping. */
|
|
83998
|
+
get animationTime() {
|
|
83999
|
+
return this.animationPlayer.time;
|
|
84000
|
+
}
|
|
84001
|
+
/**
|
|
84002
|
+
* Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
|
|
84003
|
+
* Parts of every layer are matched by name and their current pose is the default the offsets add to.
|
|
84004
|
+
* The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
|
|
84005
|
+
*/
|
|
84006
|
+
playAnimation(animation, options) {
|
|
84007
|
+
this.createMeshes();
|
|
84008
|
+
const layers = Object.keys(this.entityLayers).map((name2) => this.getLayerGroup(name2)).filter((layer) => !!layer);
|
|
84009
|
+
this.animationPlayer.play(layers, animation, options);
|
|
84010
|
+
this.notifyDirty();
|
|
84011
|
+
}
|
|
84012
|
+
/** Stops the animation and restores the default pose. */
|
|
84013
|
+
stopAnimation() {
|
|
84014
|
+
if (this.animationPlayer.stop()) this.notifyDirty();
|
|
84015
|
+
}
|
|
84016
|
+
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
84017
|
+
setAnimationTime(seconds) {
|
|
84018
|
+
if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
|
|
84019
|
+
}
|
|
84020
|
+
/** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
|
|
84021
|
+
advanceAnimation(deltaSeconds) {
|
|
84022
|
+
if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
|
|
84023
|
+
}
|
|
84024
|
+
//</editor-fold>
|
|
83796
84025
|
getLayerGroup(name2) {
|
|
83797
84026
|
return super.getGroupByName(`layer:${name2}`);
|
|
83798
84027
|
}
|
|
@@ -87400,6 +87629,9 @@ property list uchar int vertex_index
|
|
|
87400
87629
|
this._variants = [];
|
|
87401
87630
|
this._models = [];
|
|
87402
87631
|
this._cullMask = 0;
|
|
87632
|
+
this._entities = [];
|
|
87633
|
+
this._entityPlacement = new Matrix4();
|
|
87634
|
+
this._entityGeneration = 0;
|
|
87403
87635
|
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
87404
87636
|
}
|
|
87405
87637
|
async init() {
|
|
@@ -87419,6 +87651,8 @@ property list uchar int vertex_index
|
|
|
87419
87651
|
}
|
|
87420
87652
|
clearModels() {
|
|
87421
87653
|
this.removeModels(this._models.splice(0));
|
|
87654
|
+
this._entityGeneration++;
|
|
87655
|
+
this.removeEntities(this._entities.splice(0));
|
|
87422
87656
|
this._fluidKey = void 0;
|
|
87423
87657
|
this._fluidModel = void 0;
|
|
87424
87658
|
this._isInstanced = false;
|
|
@@ -87430,6 +87664,57 @@ property list uchar int vertex_index
|
|
|
87430
87664
|
if (!isInstanceReference(model)) model.dispose();
|
|
87431
87665
|
}
|
|
87432
87666
|
}
|
|
87667
|
+
removeEntities(entities) {
|
|
87668
|
+
for (const entity of entities) {
|
|
87669
|
+
entity.removeFromScene();
|
|
87670
|
+
entity.dispose();
|
|
87671
|
+
}
|
|
87672
|
+
}
|
|
87673
|
+
/** Entity models drawn for this block instead of its block model; they are scene children, unlike the block. */
|
|
87674
|
+
get blockEntities() {
|
|
87675
|
+
return this._entities;
|
|
87676
|
+
}
|
|
87677
|
+
/**
|
|
87678
|
+
* Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
|
|
87679
|
+
* when the block is not listed or one of its models cannot be loaded.
|
|
87680
|
+
*/
|
|
87681
|
+
async createBlockEntities() {
|
|
87682
|
+
const key = this.blockState.key;
|
|
87683
|
+
if (!key || this.options.displayPosition) return false;
|
|
87684
|
+
const generation = this._entityGeneration;
|
|
87685
|
+
const created = [];
|
|
87686
|
+
let resolved;
|
|
87687
|
+
try {
|
|
87688
|
+
resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);
|
|
87689
|
+
if (!resolved) return false;
|
|
87690
|
+
for (const part of resolved.parts) {
|
|
87691
|
+
const [namespace, path] = part.model.includes(":") ? part.model.split(":") : [key.namespace, part.model];
|
|
87692
|
+
const texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
87693
|
+
if (texture) texture.root = key.root;
|
|
87694
|
+
const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });
|
|
87695
|
+
if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);
|
|
87696
|
+
created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }));
|
|
87697
|
+
}
|
|
87698
|
+
} catch (error) {
|
|
87699
|
+
console.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
|
|
87700
|
+
this.removeEntities(created);
|
|
87701
|
+
return false;
|
|
87702
|
+
}
|
|
87703
|
+
if (generation !== this._entityGeneration) {
|
|
87704
|
+
this.removeEntities(created);
|
|
87705
|
+
return true;
|
|
87706
|
+
}
|
|
87707
|
+
BlockEntities.matrix(resolved, this._entityPlacement);
|
|
87708
|
+
this._entities = created;
|
|
87709
|
+
this.placeEntities();
|
|
87710
|
+
return true;
|
|
87711
|
+
}
|
|
87712
|
+
placeEntities() {
|
|
87713
|
+
const matrix = new Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
|
|
87714
|
+
for (const entity of this._entities) {
|
|
87715
|
+
matrix.decompose(entity.position, entity.quaternion, entity.scale);
|
|
87716
|
+
}
|
|
87717
|
+
}
|
|
87433
87718
|
get isOccluding() {
|
|
87434
87719
|
return this._models.some((model) => {
|
|
87435
87720
|
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
@@ -87541,13 +87826,20 @@ property list uchar int vertex_index
|
|
|
87541
87826
|
await this.updateFluid(this._fluidSampler);
|
|
87542
87827
|
return;
|
|
87543
87828
|
}
|
|
87829
|
+
const hasEntities = await this.createBlockEntities();
|
|
87544
87830
|
const variantsToCreate = await this.mapStateToVariant(this.state);
|
|
87545
87831
|
this._variants = variantsToCreate;
|
|
87546
87832
|
for (let blockStateVariant of variantsToCreate) {
|
|
87833
|
+
if (hasEntities && !await this.hasGeometry(blockStateVariant)) continue;
|
|
87547
87834
|
this._models.push(await this.createVariant(blockStateVariant));
|
|
87548
87835
|
}
|
|
87549
87836
|
await this.updateFluid(this._fluidSampler);
|
|
87550
87837
|
}
|
|
87838
|
+
async hasGeometry(variant) {
|
|
87839
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
87840
|
+
modelKey.root = this.blockState.key?.root;
|
|
87841
|
+
return !!(await Models.getMerged(modelKey))?.elements?.length;
|
|
87842
|
+
}
|
|
87551
87843
|
getSingleVariant(variants) {
|
|
87552
87844
|
return BlockStateResolver.choose(variants);
|
|
87553
87845
|
}
|
|
@@ -87667,6 +87959,7 @@ property list uchar int vertex_index
|
|
|
87667
87959
|
for (let model of this._models) {
|
|
87668
87960
|
model.setPosition(position);
|
|
87669
87961
|
}
|
|
87962
|
+
this.placeEntities();
|
|
87670
87963
|
this.notifyDirty();
|
|
87671
87964
|
}
|
|
87672
87965
|
//TODO: should override rotation + scale methods
|
|
@@ -94553,7 +94846,8 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
94553
94846
|
this.data.set(index, void 0);
|
|
94554
94847
|
return void 0;
|
|
94555
94848
|
}
|
|
94556
|
-
const
|
|
94849
|
+
const perBlock = !this.sectionModels || getFluidKind(blockState.key, stored.properties) || blockState.key && BlockEntities.entry(await BlockEntities.getIndex(blockState.key.root), blockState.key.toNamespacedString());
|
|
94850
|
+
const template = perBlock ? void 0 : await this.sectionModels.get(blockState, stored.properties);
|
|
94557
94851
|
if (template) {
|
|
94558
94852
|
this.sectionBlocks.set(index, { index, template, cullMask: 0 });
|
|
94559
94853
|
this.meshDirty = true;
|