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/browser/index.mjs
CHANGED
|
@@ -256,7 +256,9 @@ var init_Caching = __esm({
|
|
|
256
256
|
this.defaultBlockStatesCache,
|
|
257
257
|
this.blockTintCache,
|
|
258
258
|
this.entityModelCache,
|
|
259
|
-
this.entityTextureCache
|
|
259
|
+
this.entityTextureCache,
|
|
260
|
+
this.entityAnimationCache,
|
|
261
|
+
this.blockEntityIndexCache
|
|
260
262
|
];
|
|
261
263
|
}
|
|
262
264
|
static clear() {
|
|
@@ -301,6 +303,8 @@ var init_Caching = __esm({
|
|
|
301
303
|
_Caching.blockTintCache = _Caching.createAssetCache();
|
|
302
304
|
_Caching.entityModelCache = _Caching.createAssetCache();
|
|
303
305
|
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
306
|
+
_Caching.entityAnimationCache = _Caching.createAssetCache();
|
|
307
|
+
_Caching.blockEntityIndexCache = _Caching.createAssetCache();
|
|
304
308
|
Caching = _Caching;
|
|
305
309
|
}
|
|
306
310
|
});
|
|
@@ -3079,7 +3083,7 @@ var init_InstanceReference = __esm({
|
|
|
3079
3083
|
});
|
|
3080
3084
|
|
|
3081
3085
|
// src/renderer/SceneObject.ts
|
|
3082
|
-
import { Color as Color2, Euler as Euler3, InstancedBufferAttribute, InstancedMesh, MathUtils, Matrix4 as
|
|
3086
|
+
import { Color as Color2, Euler as Euler3, InstancedBufferAttribute, InstancedMesh, MathUtils, Matrix4 as Matrix44, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion3, Vector3 as Vector35 } from "three";
|
|
3083
3087
|
function isSceneObject(obj) {
|
|
3084
3088
|
return obj.isSceneObject;
|
|
3085
3089
|
}
|
|
@@ -3287,7 +3291,7 @@ var init_SceneObject = __esm({
|
|
|
3287
3291
|
mesh.instanceColor.needsUpdate = true;
|
|
3288
3292
|
}
|
|
3289
3293
|
if (this._scene) this._scene.stats.instanceCount++;
|
|
3290
|
-
this.setMatrixAt(index, new
|
|
3294
|
+
this.setMatrixAt(index, new Matrix44());
|
|
3291
3295
|
return reference;
|
|
3292
3296
|
}
|
|
3293
3297
|
/** Returns the live reference for a raycast hit on this object's instance mesh. */
|
|
@@ -3300,7 +3304,7 @@ var init_SceneObject = __esm({
|
|
|
3300
3304
|
removeInstanceAt(index) {
|
|
3301
3305
|
if (!this.instanceReferences.has(index)) return;
|
|
3302
3306
|
const mesh = this.instanceMesh;
|
|
3303
|
-
this.setMatrixAt(index, new
|
|
3307
|
+
this.setMatrixAt(index, new Matrix44().makeScale(0, 0, 0));
|
|
3304
3308
|
this.instanceReferences.delete(index);
|
|
3305
3309
|
this.freeInstanceIndices.push(index);
|
|
3306
3310
|
this._instanceCounter = this.instanceReferences.size;
|
|
@@ -3330,7 +3334,7 @@ var init_SceneObject = __esm({
|
|
|
3330
3334
|
}
|
|
3331
3335
|
//</editor-fold>
|
|
3332
3336
|
//<editor-fold desc="TRANSFORMATION">
|
|
3333
|
-
getMatrixAt(index, matrix = new
|
|
3337
|
+
getMatrixAt(index, matrix = new Matrix44()) {
|
|
3334
3338
|
if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
|
|
3335
3339
|
this.instanceMesh.getMatrixAt(index, matrix);
|
|
3336
3340
|
return matrix;
|
|
@@ -3349,7 +3353,7 @@ var init_SceneObject = __esm({
|
|
|
3349
3353
|
const oldPosition = new Vector35();
|
|
3350
3354
|
const oldRotation = new Quaternion3();
|
|
3351
3355
|
const oldScale = new Vector35();
|
|
3352
|
-
const matrix = new
|
|
3356
|
+
const matrix = new Matrix44();
|
|
3353
3357
|
if (!scale || !rotation || !position) {
|
|
3354
3358
|
this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
|
|
3355
3359
|
}
|
|
@@ -4104,7 +4108,7 @@ var init_ModelCulling = __esm({
|
|
|
4104
4108
|
});
|
|
4105
4109
|
|
|
4106
4110
|
// src/model/scene/ModelObject.ts
|
|
4107
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as
|
|
4111
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as Matrix48 } from "three";
|
|
4108
4112
|
function isModelObject(obj) {
|
|
4109
4113
|
return obj.isModelObject;
|
|
4110
4114
|
}
|
|
@@ -4183,12 +4187,12 @@ var init_ModelObject = __esm({
|
|
|
4183
4187
|
}
|
|
4184
4188
|
elGeo.setAttribute("color", new BufferAttribute5(colors, 3));
|
|
4185
4189
|
}
|
|
4186
|
-
elGeo.applyMatrix4(new
|
|
4187
|
-
elGeo.applyMatrix4(new
|
|
4190
|
+
elGeo.applyMatrix4(new Matrix48().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
|
|
4191
|
+
elGeo.applyMatrix4(new Matrix48().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4188
4192
|
if (el.rotation) {
|
|
4189
4193
|
applyElementRotation(el.rotation, elGeo);
|
|
4190
4194
|
}
|
|
4191
|
-
elGeo.applyMatrix4(new
|
|
4195
|
+
elGeo.applyMatrix4(new Matrix48().makeTranslation(-8, -8, -8));
|
|
4192
4196
|
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4193
4197
|
if (this.options.mergeMeshes) {
|
|
4194
4198
|
allGeos.push(elGeo);
|
|
@@ -4797,6 +4801,59 @@ function shutdown() {
|
|
|
4797
4801
|
init_AssetKey();
|
|
4798
4802
|
init_AssetLoader();
|
|
4799
4803
|
init_Assets();
|
|
4804
|
+
|
|
4805
|
+
// src/assets/BlockEntities.ts
|
|
4806
|
+
init_AssetKey();
|
|
4807
|
+
init_AssetLoader();
|
|
4808
|
+
init_source();
|
|
4809
|
+
init_Caching();
|
|
4810
|
+
import { Matrix4 as Matrix43 } from "three";
|
|
4811
|
+
var BlockEntities = class {
|
|
4812
|
+
/**
|
|
4813
|
+
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
4814
|
+
* a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty
|
|
4815
|
+
* result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.
|
|
4816
|
+
*/
|
|
4817
|
+
static async getIndex(root) {
|
|
4818
|
+
const key = new AssetKey("entity-models", "blocks", void 0, void 0, void 0, ".json", root);
|
|
4819
|
+
key.rootType = void 0;
|
|
4820
|
+
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
4821
|
+
try {
|
|
4822
|
+
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
4823
|
+
} catch (error) {
|
|
4824
|
+
console.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
4825
|
+
return {};
|
|
4826
|
+
}
|
|
4827
|
+
});
|
|
4828
|
+
return index ?? {};
|
|
4829
|
+
}
|
|
4830
|
+
/** The index entry of a block ID such as `minecraft:chest`. */
|
|
4831
|
+
static entry(index, block) {
|
|
4832
|
+
const entry = Object.prototype.hasOwnProperty.call(index, block) ? index[block] : void 0;
|
|
4833
|
+
return Array.isArray(entry?.parts) ? entry : void 0;
|
|
4834
|
+
}
|
|
4835
|
+
/** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */
|
|
4836
|
+
static resolve(index, block, state = {}) {
|
|
4837
|
+
const entry = this.entry(index, block);
|
|
4838
|
+
if (!entry) return void 0;
|
|
4839
|
+
const value = (property) => String(state[property]).toLowerCase();
|
|
4840
|
+
const parts = entry.parts.filter((part) => Object.entries(part.when ?? {}).every(([property, values]) => String(values).split("|").includes(value(property))));
|
|
4841
|
+
if (!parts.length) return void 0;
|
|
4842
|
+
let rotation = 0;
|
|
4843
|
+
if (entry.rotation) {
|
|
4844
|
+
const selected = value(entry.rotation.property);
|
|
4845
|
+
rotation = "degrees" in entry.rotation ? entry.rotation.degrees[selected] : Number(selected) * entry.rotation.step;
|
|
4846
|
+
if (!Number.isFinite(rotation)) rotation = 0;
|
|
4847
|
+
}
|
|
4848
|
+
return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };
|
|
4849
|
+
}
|
|
4850
|
+
/** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
|
|
4851
|
+
static matrix(resolved, matrix = new Matrix43()) {
|
|
4852
|
+
return matrix.makeTranslation(8, 0, 8).multiply(new Matrix43().makeRotationY(resolved.rotation * Math.PI / 180)).multiply(new Matrix43().makeTranslation(resolved.translation[0] - 8, resolved.translation[1], resolved.translation[2] - 8));
|
|
4853
|
+
}
|
|
4854
|
+
};
|
|
4855
|
+
|
|
4856
|
+
// src/assets/index.ts
|
|
4800
4857
|
init_BlockStates();
|
|
4801
4858
|
|
|
4802
4859
|
// src/assets/Entities.ts
|
|
@@ -4867,6 +4924,15 @@ var Entities = class {
|
|
|
4867
4924
|
})));
|
|
4868
4925
|
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
4869
4926
|
}
|
|
4927
|
+
/**
|
|
4928
|
+
* Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
|
|
4929
|
+
*/
|
|
4930
|
+
static async getAnimations(modelKey) {
|
|
4931
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4932
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
|
|
4933
|
+
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4934
|
+
return file?.animations;
|
|
4935
|
+
}
|
|
4870
4936
|
static async resolveTexture(modelKey) {
|
|
4871
4937
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4872
4938
|
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
@@ -4943,6 +5009,119 @@ function trimCanvas(source) {
|
|
|
4943
5009
|
return canvas;
|
|
4944
5010
|
}
|
|
4945
5011
|
|
|
5012
|
+
// src/entity/EntityAnimation.ts
|
|
5013
|
+
var ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
|
|
5014
|
+
function catmullRom(delta, p0, p1, p22, p32) {
|
|
5015
|
+
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);
|
|
5016
|
+
}
|
|
5017
|
+
function sampleEntityKeyframes(keyframes, time) {
|
|
5018
|
+
if (keyframes.length === 0) return [0, 0, 0];
|
|
5019
|
+
let low = 0, high = keyframes.length;
|
|
5020
|
+
while (low < high) {
|
|
5021
|
+
const middle = low + high >>> 1;
|
|
5022
|
+
if (time <= keyframes[middle].time) high = middle;
|
|
5023
|
+
else low = middle + 1;
|
|
5024
|
+
}
|
|
5025
|
+
const a = Math.max(0, low - 1);
|
|
5026
|
+
const b = Math.min(keyframes.length - 1, a + 1);
|
|
5027
|
+
const from = keyframes[a];
|
|
5028
|
+
const to = keyframes[b];
|
|
5029
|
+
const delta = a === b ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
|
|
5030
|
+
if (to.interpolation === "catmullrom") {
|
|
5031
|
+
const before = keyframes[Math.max(0, a - 1)].value;
|
|
5032
|
+
const after = keyframes[Math.min(keyframes.length - 1, b + 1)].value;
|
|
5033
|
+
return [0, 1, 2].map((i) => catmullRom(delta, before[i], from.value[i], to.value[i], after[i]));
|
|
5034
|
+
}
|
|
5035
|
+
const target = to.pre ?? to.value;
|
|
5036
|
+
return [0, 1, 2].map((i) => from.value[i] + (target[i] - from.value[i]) * delta);
|
|
5037
|
+
}
|
|
5038
|
+
function entityAnimationTime(animation, time, loop = animation.loop) {
|
|
5039
|
+
return loop && animation.length > 0 ? time % animation.length : time;
|
|
5040
|
+
}
|
|
5041
|
+
function sampleEntityAnimation(animation, time, loop = animation.loop) {
|
|
5042
|
+
const elapsed = entityAnimationTime(animation, time, loop);
|
|
5043
|
+
const pose = {};
|
|
5044
|
+
for (const [name, bone] of Object.entries(animation.bones)) {
|
|
5045
|
+
const sampled = pose[name] = {};
|
|
5046
|
+
for (const channel of ENTITY_ANIMATION_CHANNELS) {
|
|
5047
|
+
const keyframes = bone[channel];
|
|
5048
|
+
if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
|
|
5049
|
+
}
|
|
5050
|
+
}
|
|
5051
|
+
return pose;
|
|
5052
|
+
}
|
|
5053
|
+
|
|
5054
|
+
// src/entity/scene/EntityAnimationPlayer.ts
|
|
5055
|
+
var ZERO = [0, 0, 0];
|
|
5056
|
+
var EntityAnimationPlayer = class {
|
|
5057
|
+
constructor() {
|
|
5058
|
+
this.parts = [];
|
|
5059
|
+
this._time = 0;
|
|
5060
|
+
this.loop = false;
|
|
5061
|
+
this.speed = 1;
|
|
5062
|
+
}
|
|
5063
|
+
get animation() {
|
|
5064
|
+
return this._animation;
|
|
5065
|
+
}
|
|
5066
|
+
get time() {
|
|
5067
|
+
return this._time;
|
|
5068
|
+
}
|
|
5069
|
+
/**
|
|
5070
|
+
* Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
|
|
5071
|
+
* bones without a matching part are skipped.
|
|
5072
|
+
*/
|
|
5073
|
+
play(layers, animation, options = {}) {
|
|
5074
|
+
this.stop();
|
|
5075
|
+
this._animation = animation;
|
|
5076
|
+
this._time = options.time ?? 0;
|
|
5077
|
+
this.loop = options.loop ?? animation.loop;
|
|
5078
|
+
this.speed = options.speed ?? 1;
|
|
5079
|
+
for (const layer of layers) {
|
|
5080
|
+
for (const bone of Object.keys(animation.bones)) {
|
|
5081
|
+
const object = layer.getObjectByName(`group:${bone}`);
|
|
5082
|
+
if (!object) continue;
|
|
5083
|
+
this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
|
|
5084
|
+
}
|
|
5085
|
+
}
|
|
5086
|
+
this.apply();
|
|
5087
|
+
}
|
|
5088
|
+
/** Restores the default poses. Returns whether an animation was active. */
|
|
5089
|
+
stop() {
|
|
5090
|
+
if (!this._animation) return false;
|
|
5091
|
+
for (const part of this.parts) {
|
|
5092
|
+
part.object.position.copy(part.position);
|
|
5093
|
+
part.object.rotation.copy(part.rotation);
|
|
5094
|
+
part.object.scale.copy(part.scale);
|
|
5095
|
+
}
|
|
5096
|
+
this.clear();
|
|
5097
|
+
return true;
|
|
5098
|
+
}
|
|
5099
|
+
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
5100
|
+
clear() {
|
|
5101
|
+
this.parts = [];
|
|
5102
|
+
this._animation = void 0;
|
|
5103
|
+
this._time = 0;
|
|
5104
|
+
}
|
|
5105
|
+
setTime(seconds) {
|
|
5106
|
+
if (!this._animation) return false;
|
|
5107
|
+
this._time = seconds;
|
|
5108
|
+
this.apply();
|
|
5109
|
+
return true;
|
|
5110
|
+
}
|
|
5111
|
+
advance(deltaSeconds) {
|
|
5112
|
+
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
5113
|
+
}
|
|
5114
|
+
apply() {
|
|
5115
|
+
const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
|
|
5116
|
+
for (const part of this.parts) {
|
|
5117
|
+
const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
|
|
5118
|
+
part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
|
|
5119
|
+
part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
|
|
5120
|
+
part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
|
|
5121
|
+
}
|
|
5122
|
+
}
|
|
5123
|
+
};
|
|
5124
|
+
|
|
4946
5125
|
// src/entity/scene/EntityObject.ts
|
|
4947
5126
|
init_SceneObject();
|
|
4948
5127
|
init_Caching();
|
|
@@ -4952,7 +5131,7 @@ init_model();
|
|
|
4952
5131
|
init_ModelTextures();
|
|
4953
5132
|
init_AssetKey();
|
|
4954
5133
|
init_Materials();
|
|
4955
|
-
import { Color as Color3, Euler as Euler4, Matrix4 as
|
|
5134
|
+
import { Color as Color3, Euler as Euler4, Matrix4 as Matrix45, Object3D as Object3D3 } from "three";
|
|
4956
5135
|
init_three();
|
|
4957
5136
|
var _EntityObject = class _EntityObject extends SceneObject {
|
|
4958
5137
|
constructor(entity, options) {
|
|
@@ -4964,6 +5143,7 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4964
5143
|
this.scrollMaterials = [];
|
|
4965
5144
|
/** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
|
|
4966
5145
|
this.age = 0;
|
|
5146
|
+
this.animationPlayer = new EntityAnimationPlayer();
|
|
4967
5147
|
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
4968
5148
|
}
|
|
4969
5149
|
async init() {
|
|
@@ -4975,6 +5155,7 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4975
5155
|
}
|
|
4976
5156
|
disposeAndRemoveAllChildren() {
|
|
4977
5157
|
this.clearScrollMaterials();
|
|
5158
|
+
this.animationPlayer.clear();
|
|
4978
5159
|
super.disposeAndRemoveAllChildren();
|
|
4979
5160
|
}
|
|
4980
5161
|
clearScrollMaterials() {
|
|
@@ -4992,6 +5173,39 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
4992
5173
|
}
|
|
4993
5174
|
this.notifyDirty();
|
|
4994
5175
|
}
|
|
5176
|
+
//<editor-fold desc="ANIMATION">
|
|
5177
|
+
/** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
|
|
5178
|
+
get animation() {
|
|
5179
|
+
return this.animationPlayer.animation;
|
|
5180
|
+
}
|
|
5181
|
+
/** Seconds since the animation started, before looping. */
|
|
5182
|
+
get animationTime() {
|
|
5183
|
+
return this.animationPlayer.time;
|
|
5184
|
+
}
|
|
5185
|
+
/**
|
|
5186
|
+
* Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
|
|
5187
|
+
* Parts of every layer are matched by name and their current pose is the default the offsets add to.
|
|
5188
|
+
* The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
|
|
5189
|
+
*/
|
|
5190
|
+
playAnimation(animation, options) {
|
|
5191
|
+
this.createMeshes();
|
|
5192
|
+
const layers = Object.keys(this.entityLayers).map((name) => this.getLayerGroup(name)).filter((layer) => !!layer);
|
|
5193
|
+
this.animationPlayer.play(layers, animation, options);
|
|
5194
|
+
this.notifyDirty();
|
|
5195
|
+
}
|
|
5196
|
+
/** Stops the animation and restores the default pose. */
|
|
5197
|
+
stopAnimation() {
|
|
5198
|
+
if (this.animationPlayer.stop()) this.notifyDirty();
|
|
5199
|
+
}
|
|
5200
|
+
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
5201
|
+
setAnimationTime(seconds) {
|
|
5202
|
+
if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
|
|
5203
|
+
}
|
|
5204
|
+
/** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
|
|
5205
|
+
advanceAnimation(deltaSeconds) {
|
|
5206
|
+
if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
|
|
5207
|
+
}
|
|
5208
|
+
//</editor-fold>
|
|
4995
5209
|
getLayerGroup(name) {
|
|
4996
5210
|
return super.getGroupByName(`layer:${name}`);
|
|
4997
5211
|
}
|
|
@@ -5025,7 +5239,7 @@ var _EntityObject = class _EntityObject extends SceneObject {
|
|
|
5025
5239
|
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
5026
5240
|
if (transform) {
|
|
5027
5241
|
for (const op of transform) {
|
|
5028
|
-
const matrix = new
|
|
5242
|
+
const matrix = new Matrix45();
|
|
5029
5243
|
if ("scale" in op) matrix.makeScale(...op.scale);
|
|
5030
5244
|
else if ("translate" in op) matrix.makeTranslation(...op.translate);
|
|
5031
5245
|
else matrix.makeRotationFromEuler(new Euler4(...op.rotate, "ZYX"));
|
|
@@ -5122,7 +5336,7 @@ function isEntityObject(obj) {
|
|
|
5122
5336
|
init_MineRenderError();
|
|
5123
5337
|
|
|
5124
5338
|
// src/export/SceneExporter.ts
|
|
5125
|
-
import { ClampToEdgeWrapping as ClampToEdgeWrapping2, Color as Color7, Float32BufferAttribute as Float32BufferAttribute3, Matrix4 as
|
|
5339
|
+
import { ClampToEdgeWrapping as ClampToEdgeWrapping2, Color as Color7, Float32BufferAttribute as Float32BufferAttribute3, Matrix4 as Matrix47, Mesh as Mesh5, MeshBasicMaterial as MeshBasicMaterial2, NearestFilter as NearestFilter3, RGBAFormat as RGBAFormat3, Scene as Scene4, Source as Source2, Texture as Texture4, UnsignedByteType } from "three";
|
|
5126
5340
|
|
|
5127
5341
|
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
5128
5342
|
import {
|
|
@@ -5548,7 +5762,7 @@ import {
|
|
|
5548
5762
|
LinearMipmapLinearFilter,
|
|
5549
5763
|
LinearMipmapNearestFilter,
|
|
5550
5764
|
MathUtils as MathUtils2,
|
|
5551
|
-
Matrix4 as
|
|
5765
|
+
Matrix4 as Matrix46,
|
|
5552
5766
|
MirroredRepeatWrapping,
|
|
5553
5767
|
NearestFilter as NearestFilter2,
|
|
5554
5768
|
NearestMipmapLinearFilter,
|
|
@@ -6838,7 +7052,7 @@ var GLTFWriter = class {
|
|
|
6838
7052
|
if (rootJoint === void 0) return null;
|
|
6839
7053
|
const joints = [];
|
|
6840
7054
|
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
6841
|
-
const temporaryBoneInverse = new
|
|
7055
|
+
const temporaryBoneInverse = new Matrix46();
|
|
6842
7056
|
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
6843
7057
|
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
6844
7058
|
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
@@ -7304,7 +7518,7 @@ var GLTFMeshGpuInstancing = class {
|
|
|
7304
7518
|
const translationAttr = new Float32Array(mesh.count * 3);
|
|
7305
7519
|
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
7306
7520
|
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
7307
|
-
const matrix = new
|
|
7521
|
+
const matrix = new Matrix46();
|
|
7308
7522
|
const position = new Vector38();
|
|
7309
7523
|
const quaternion = new Quaternion4();
|
|
7310
7524
|
const scale = new Vector38();
|
|
@@ -7478,7 +7692,7 @@ var SceneExporter = class {
|
|
|
7478
7692
|
}
|
|
7479
7693
|
};
|
|
7480
7694
|
function localMatrix(object) {
|
|
7481
|
-
return object.matrixAutoUpdate ? new
|
|
7695
|
+
return object.matrixAutoUpdate ? new Matrix47().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
|
|
7482
7696
|
}
|
|
7483
7697
|
function createSnapshot(root, gltf, bakeColors = false) {
|
|
7484
7698
|
const scene = new Scene4();
|
|
@@ -7590,7 +7804,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7590
7804
|
const instanced = mesh;
|
|
7591
7805
|
if (instanced.isInstancedMesh) {
|
|
7592
7806
|
for (let i = 0; i < instanced.count; i++) {
|
|
7593
|
-
const matrix = new
|
|
7807
|
+
const matrix = new Matrix47();
|
|
7594
7808
|
instanced.getMatrixAt(i, matrix);
|
|
7595
7809
|
const color = instanced.instanceColor ? new Color7().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
7596
7810
|
addMesh(mesh, world.clone().multiply(matrix), color);
|
|
@@ -7604,7 +7818,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7604
7818
|
try {
|
|
7605
7819
|
const ancestors = [];
|
|
7606
7820
|
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
7607
|
-
const world = new
|
|
7821
|
+
const world = new Matrix47();
|
|
7608
7822
|
for (const ancestor of ancestors) {
|
|
7609
7823
|
if (!ancestor.visible) return { scene, dispose };
|
|
7610
7824
|
world.multiply(localMatrix(ancestor));
|
|
@@ -8506,7 +8720,7 @@ var import_ts_deepmerge6 = __toESM(require_dist());
|
|
|
8506
8720
|
init_MineRenderError();
|
|
8507
8721
|
init_InstanceReference();
|
|
8508
8722
|
init_AssetKey();
|
|
8509
|
-
import { Euler as Euler8, Matrix4 as
|
|
8723
|
+
import { Euler as Euler8, Matrix4 as Matrix49, Quaternion as Quaternion5, Vector3 as Vector311 } from "three";
|
|
8510
8724
|
init_ModelCulling();
|
|
8511
8725
|
init_FluidGeometry();
|
|
8512
8726
|
var _BlockObject = class _BlockObject extends SceneObject {
|
|
@@ -8523,6 +8737,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8523
8737
|
this._variants = [];
|
|
8524
8738
|
this._models = [];
|
|
8525
8739
|
this._cullMask = 0;
|
|
8740
|
+
this._entities = [];
|
|
8741
|
+
this._entityPlacement = new Matrix49();
|
|
8742
|
+
this._entityGeneration = 0;
|
|
8526
8743
|
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
8527
8744
|
}
|
|
8528
8745
|
async init() {
|
|
@@ -8542,6 +8759,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8542
8759
|
}
|
|
8543
8760
|
clearModels() {
|
|
8544
8761
|
this.removeModels(this._models.splice(0));
|
|
8762
|
+
this._entityGeneration++;
|
|
8763
|
+
this.removeEntities(this._entities.splice(0));
|
|
8545
8764
|
this._fluidKey = void 0;
|
|
8546
8765
|
this._fluidModel = void 0;
|
|
8547
8766
|
this._isInstanced = false;
|
|
@@ -8553,6 +8772,57 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8553
8772
|
if (!isInstanceReference(model)) model.dispose();
|
|
8554
8773
|
}
|
|
8555
8774
|
}
|
|
8775
|
+
removeEntities(entities) {
|
|
8776
|
+
for (const entity of entities) {
|
|
8777
|
+
entity.removeFromScene();
|
|
8778
|
+
entity.dispose();
|
|
8779
|
+
}
|
|
8780
|
+
}
|
|
8781
|
+
/** Entity models drawn for this block instead of its block model; they are scene children, unlike the block. */
|
|
8782
|
+
get blockEntities() {
|
|
8783
|
+
return this._entities;
|
|
8784
|
+
}
|
|
8785
|
+
/**
|
|
8786
|
+
* Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
|
|
8787
|
+
* when the block is not listed or one of its models cannot be loaded.
|
|
8788
|
+
*/
|
|
8789
|
+
async createBlockEntities() {
|
|
8790
|
+
const key = this.blockState.key;
|
|
8791
|
+
if (!key || this.options.displayPosition) return false;
|
|
8792
|
+
const generation = this._entityGeneration;
|
|
8793
|
+
const created = [];
|
|
8794
|
+
let resolved;
|
|
8795
|
+
try {
|
|
8796
|
+
resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);
|
|
8797
|
+
if (!resolved) return false;
|
|
8798
|
+
for (const part of resolved.parts) {
|
|
8799
|
+
const [namespace, path] = part.model.includes(":") ? part.model.split(":") : [key.namespace, part.model];
|
|
8800
|
+
const texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
8801
|
+
if (texture) texture.root = key.root;
|
|
8802
|
+
const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });
|
|
8803
|
+
if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);
|
|
8804
|
+
created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }));
|
|
8805
|
+
}
|
|
8806
|
+
} catch (error) {
|
|
8807
|
+
console.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
|
|
8808
|
+
this.removeEntities(created);
|
|
8809
|
+
return false;
|
|
8810
|
+
}
|
|
8811
|
+
if (generation !== this._entityGeneration) {
|
|
8812
|
+
this.removeEntities(created);
|
|
8813
|
+
return true;
|
|
8814
|
+
}
|
|
8815
|
+
BlockEntities.matrix(resolved, this._entityPlacement);
|
|
8816
|
+
this._entities = created;
|
|
8817
|
+
this.placeEntities();
|
|
8818
|
+
return true;
|
|
8819
|
+
}
|
|
8820
|
+
placeEntities() {
|
|
8821
|
+
const matrix = new Matrix49().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
|
|
8822
|
+
for (const entity of this._entities) {
|
|
8823
|
+
matrix.decompose(entity.position, entity.quaternion, entity.scale);
|
|
8824
|
+
}
|
|
8825
|
+
}
|
|
8556
8826
|
get isOccluding() {
|
|
8557
8827
|
return this._models.some((model) => {
|
|
8558
8828
|
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
@@ -8634,7 +8904,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8634
8904
|
() => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
|
|
8635
8905
|
);
|
|
8636
8906
|
const previous = this._fluidModel;
|
|
8637
|
-
const matrix = previous ? this.getModelMatrix(previous) : new
|
|
8907
|
+
const matrix = previous ? this.getModelMatrix(previous) : new Matrix49().makeTranslation(...this.position.toArray());
|
|
8638
8908
|
if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
|
|
8639
8909
|
else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
8640
8910
|
this._models = this._models.filter((model) => model !== previous);
|
|
@@ -8664,13 +8934,20 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8664
8934
|
await this.updateFluid(this._fluidSampler);
|
|
8665
8935
|
return;
|
|
8666
8936
|
}
|
|
8937
|
+
const hasEntities = await this.createBlockEntities();
|
|
8667
8938
|
const variantsToCreate = await this.mapStateToVariant(this.state);
|
|
8668
8939
|
this._variants = variantsToCreate;
|
|
8669
8940
|
for (let blockStateVariant of variantsToCreate) {
|
|
8941
|
+
if (hasEntities && !await this.hasGeometry(blockStateVariant)) continue;
|
|
8670
8942
|
this._models.push(await this.createVariant(blockStateVariant));
|
|
8671
8943
|
}
|
|
8672
8944
|
await this.updateFluid(this._fluidSampler);
|
|
8673
8945
|
}
|
|
8946
|
+
async hasGeometry(variant) {
|
|
8947
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
8948
|
+
modelKey.root = this.blockState.key?.root;
|
|
8949
|
+
return !!(await Models.getMerged(modelKey))?.elements?.length;
|
|
8950
|
+
}
|
|
8674
8951
|
getSingleVariant(variants) {
|
|
8675
8952
|
return BlockStateResolver.choose(variants);
|
|
8676
8953
|
}
|
|
@@ -8765,7 +9042,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8765
9042
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
8766
9043
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
8767
9044
|
}
|
|
8768
|
-
getMatrixAt(index, matrix = new
|
|
9045
|
+
getMatrixAt(index, matrix = new Matrix49()) {
|
|
8769
9046
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
8770
9047
|
const child = this._models[0];
|
|
8771
9048
|
if (child && isModelObject(child)) {
|
|
@@ -8790,6 +9067,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
8790
9067
|
for (let model of this._models) {
|
|
8791
9068
|
model.setPosition(position);
|
|
8792
9069
|
}
|
|
9070
|
+
this.placeEntities();
|
|
8793
9071
|
this.notifyDirty();
|
|
8794
9072
|
}
|
|
8795
9073
|
//TODO: should override rotation + scale methods
|
|
@@ -13329,7 +13607,7 @@ init_CubeFace();
|
|
|
13329
13607
|
init_AssetKey();
|
|
13330
13608
|
init_Models();
|
|
13331
13609
|
init_CubeFace();
|
|
13332
|
-
import { Matrix4 as
|
|
13610
|
+
import { Matrix4 as Matrix410, Vector3 as Vector314 } from "three";
|
|
13333
13611
|
init_ModelCulling();
|
|
13334
13612
|
init_ModelObject();
|
|
13335
13613
|
init_UVMapper();
|
|
@@ -13392,7 +13670,7 @@ var SectionModels = class {
|
|
|
13392
13670
|
});
|
|
13393
13671
|
await object.init();
|
|
13394
13672
|
const geometry = object.children[0].geometry;
|
|
13395
|
-
geometry.applyMatrix4(new
|
|
13673
|
+
geometry.applyMatrix4(new Matrix410().makeRotationFromEuler(rotation));
|
|
13396
13674
|
object.clear();
|
|
13397
13675
|
const cullFaces = CUBE_FACES.map((face) => {
|
|
13398
13676
|
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
@@ -13804,7 +14082,8 @@ var Chunk = class _Chunk {
|
|
|
13804
14082
|
this.data.set(index, void 0);
|
|
13805
14083
|
return void 0;
|
|
13806
14084
|
}
|
|
13807
|
-
const
|
|
14085
|
+
const perBlock = !this.sectionModels || getFluidKind(blockState.key, stored.properties) || blockState.key && BlockEntities.entry(await BlockEntities.getIndex(blockState.key.root), blockState.key.toNamespacedString());
|
|
14086
|
+
const template = perBlock ? void 0 : await this.sectionModels.get(blockState, stored.properties);
|
|
13808
14087
|
if (template) {
|
|
13809
14088
|
this.sectionBlocks.set(index, { index, template, cullMask: 0 });
|
|
13810
14089
|
this.meshDirty = true;
|
|
@@ -13913,6 +14192,7 @@ export {
|
|
|
13913
14192
|
BUILTIN_GENERATED,
|
|
13914
14193
|
BasicAssetKey,
|
|
13915
14194
|
BatchedExecutor,
|
|
14195
|
+
BlockEntities,
|
|
13916
14196
|
BlockObject,
|
|
13917
14197
|
BlockStateResolver,
|
|
13918
14198
|
BlockStates,
|
|
@@ -13936,7 +14216,9 @@ export {
|
|
|
13936
14216
|
DefaultBlockStates,
|
|
13937
14217
|
DisplayPosition,
|
|
13938
14218
|
DisplayTransforms,
|
|
14219
|
+
ENTITY_ANIMATION_CHANNELS,
|
|
13939
14220
|
Entities,
|
|
14221
|
+
EntityAnimationPlayer,
|
|
13940
14222
|
EntityObject,
|
|
13941
14223
|
Env,
|
|
13942
14224
|
FluidModelObject,
|
|
@@ -14010,6 +14292,7 @@ export {
|
|
|
14010
14292
|
createCanvas,
|
|
14011
14293
|
createFluidGeometry,
|
|
14012
14294
|
createImage,
|
|
14295
|
+
entityAnimationTime,
|
|
14013
14296
|
estimateBytesUsed,
|
|
14014
14297
|
getBlockFluidState,
|
|
14015
14298
|
getFluidKind,
|
|
@@ -14043,6 +14326,8 @@ export {
|
|
|
14043
14326
|
prefix,
|
|
14044
14327
|
probeImageSize,
|
|
14045
14328
|
registerBrowserEnv,
|
|
14329
|
+
sampleEntityAnimation,
|
|
14330
|
+
sampleEntityKeyframes,
|
|
14046
14331
|
sampleFluid,
|
|
14047
14332
|
serializeBoxGeometryKey,
|
|
14048
14333
|
serializeImageKey,
|