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/node/index.mjs
CHANGED
|
@@ -290,6 +290,12 @@ var init_Caching = __esm({
|
|
|
290
290
|
static {
|
|
291
291
|
this.entityTextureCache = _Caching.createAssetCache();
|
|
292
292
|
}
|
|
293
|
+
static {
|
|
294
|
+
this.entityAnimationCache = _Caching.createAssetCache();
|
|
295
|
+
}
|
|
296
|
+
static {
|
|
297
|
+
this.blockEntityIndexCache = _Caching.createAssetCache();
|
|
298
|
+
}
|
|
293
299
|
static createAssetCache() {
|
|
294
300
|
return Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
295
301
|
}
|
|
@@ -314,7 +320,9 @@ var init_Caching = __esm({
|
|
|
314
320
|
this.defaultBlockStatesCache,
|
|
315
321
|
this.blockTintCache,
|
|
316
322
|
this.entityModelCache,
|
|
317
|
-
this.entityTextureCache
|
|
323
|
+
this.entityTextureCache,
|
|
324
|
+
this.entityAnimationCache,
|
|
325
|
+
this.blockEntityIndexCache
|
|
318
326
|
];
|
|
319
327
|
}
|
|
320
328
|
static clear() {
|
|
@@ -3161,7 +3169,7 @@ var init_InstanceReference = __esm({
|
|
|
3161
3169
|
});
|
|
3162
3170
|
|
|
3163
3171
|
// src/renderer/SceneObject.ts
|
|
3164
|
-
import { Color as Color2, Euler as Euler3, InstancedBufferAttribute, InstancedMesh, MathUtils, Matrix4 as
|
|
3172
|
+
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";
|
|
3165
3173
|
function isSceneObject(obj) {
|
|
3166
3174
|
return obj.isSceneObject;
|
|
3167
3175
|
}
|
|
@@ -3377,7 +3385,7 @@ var init_SceneObject = __esm({
|
|
|
3377
3385
|
mesh.instanceColor.needsUpdate = true;
|
|
3378
3386
|
}
|
|
3379
3387
|
if (this._scene) this._scene.stats.instanceCount++;
|
|
3380
|
-
this.setMatrixAt(index, new
|
|
3388
|
+
this.setMatrixAt(index, new Matrix44());
|
|
3381
3389
|
return reference;
|
|
3382
3390
|
}
|
|
3383
3391
|
/** Returns the live reference for a raycast hit on this object's instance mesh. */
|
|
@@ -3390,7 +3398,7 @@ var init_SceneObject = __esm({
|
|
|
3390
3398
|
removeInstanceAt(index) {
|
|
3391
3399
|
if (!this.instanceReferences.has(index)) return;
|
|
3392
3400
|
const mesh = this.instanceMesh;
|
|
3393
|
-
this.setMatrixAt(index, new
|
|
3401
|
+
this.setMatrixAt(index, new Matrix44().makeScale(0, 0, 0));
|
|
3394
3402
|
this.instanceReferences.delete(index);
|
|
3395
3403
|
this.freeInstanceIndices.push(index);
|
|
3396
3404
|
this._instanceCounter = this.instanceReferences.size;
|
|
@@ -3420,7 +3428,7 @@ var init_SceneObject = __esm({
|
|
|
3420
3428
|
}
|
|
3421
3429
|
//</editor-fold>
|
|
3422
3430
|
//<editor-fold desc="TRANSFORMATION">
|
|
3423
|
-
getMatrixAt(index, matrix = new
|
|
3431
|
+
getMatrixAt(index, matrix = new Matrix44()) {
|
|
3424
3432
|
if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
|
|
3425
3433
|
this.instanceMesh.getMatrixAt(index, matrix);
|
|
3426
3434
|
return matrix;
|
|
@@ -3439,7 +3447,7 @@ var init_SceneObject = __esm({
|
|
|
3439
3447
|
const oldPosition = new Vector35();
|
|
3440
3448
|
const oldRotation = new Quaternion3();
|
|
3441
3449
|
const oldScale = new Vector35();
|
|
3442
|
-
const matrix = new
|
|
3450
|
+
const matrix = new Matrix44();
|
|
3443
3451
|
if (!scale || !rotation || !position) {
|
|
3444
3452
|
this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
|
|
3445
3453
|
}
|
|
@@ -4187,7 +4195,7 @@ var init_ModelCulling = __esm({
|
|
|
4187
4195
|
});
|
|
4188
4196
|
|
|
4189
4197
|
// src/model/scene/ModelObject.ts
|
|
4190
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as
|
|
4198
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as Matrix48 } from "three";
|
|
4191
4199
|
function isModelObject(obj) {
|
|
4192
4200
|
return obj.isModelObject;
|
|
4193
4201
|
}
|
|
@@ -4269,12 +4277,12 @@ var init_ModelObject = __esm({
|
|
|
4269
4277
|
}
|
|
4270
4278
|
elGeo.setAttribute("color", new BufferAttribute5(colors, 3));
|
|
4271
4279
|
}
|
|
4272
|
-
elGeo.applyMatrix4(new
|
|
4273
|
-
elGeo.applyMatrix4(new
|
|
4280
|
+
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));
|
|
4281
|
+
elGeo.applyMatrix4(new Matrix48().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4274
4282
|
if (el.rotation) {
|
|
4275
4283
|
applyElementRotation(el.rotation, elGeo);
|
|
4276
4284
|
}
|
|
4277
|
-
elGeo.applyMatrix4(new
|
|
4285
|
+
elGeo.applyMatrix4(new Matrix48().makeTranslation(-8, -8, -8));
|
|
4278
4286
|
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4279
4287
|
if (this.options.mergeMeshes) {
|
|
4280
4288
|
allGeos.push(elGeo);
|
|
@@ -4843,6 +4851,59 @@ function shutdown() {
|
|
|
4843
4851
|
init_AssetKey();
|
|
4844
4852
|
init_AssetLoader();
|
|
4845
4853
|
init_Assets();
|
|
4854
|
+
|
|
4855
|
+
// src/assets/BlockEntities.ts
|
|
4856
|
+
init_AssetKey();
|
|
4857
|
+
init_AssetLoader();
|
|
4858
|
+
init_source();
|
|
4859
|
+
init_Caching();
|
|
4860
|
+
import { Matrix4 as Matrix43 } from "three";
|
|
4861
|
+
var BlockEntities = class {
|
|
4862
|
+
/**
|
|
4863
|
+
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
4864
|
+
* a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty
|
|
4865
|
+
* result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.
|
|
4866
|
+
*/
|
|
4867
|
+
static async getIndex(root) {
|
|
4868
|
+
const key = new AssetKey("entity-models", "blocks", void 0, void 0, void 0, ".json", root);
|
|
4869
|
+
key.rootType = void 0;
|
|
4870
|
+
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
4871
|
+
try {
|
|
4872
|
+
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
4873
|
+
} catch (error) {
|
|
4874
|
+
console.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
4875
|
+
return {};
|
|
4876
|
+
}
|
|
4877
|
+
});
|
|
4878
|
+
return index ?? {};
|
|
4879
|
+
}
|
|
4880
|
+
/** The index entry of a block ID such as `minecraft:chest`. */
|
|
4881
|
+
static entry(index, block) {
|
|
4882
|
+
const entry = Object.prototype.hasOwnProperty.call(index, block) ? index[block] : void 0;
|
|
4883
|
+
return Array.isArray(entry?.parts) ? entry : void 0;
|
|
4884
|
+
}
|
|
4885
|
+
/** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */
|
|
4886
|
+
static resolve(index, block, state = {}) {
|
|
4887
|
+
const entry = this.entry(index, block);
|
|
4888
|
+
if (!entry) return void 0;
|
|
4889
|
+
const value = (property) => String(state[property]).toLowerCase();
|
|
4890
|
+
const parts = entry.parts.filter((part) => Object.entries(part.when ?? {}).every(([property, values]) => String(values).split("|").includes(value(property))));
|
|
4891
|
+
if (!parts.length) return void 0;
|
|
4892
|
+
let rotation = 0;
|
|
4893
|
+
if (entry.rotation) {
|
|
4894
|
+
const selected = value(entry.rotation.property);
|
|
4895
|
+
rotation = "degrees" in entry.rotation ? entry.rotation.degrees[selected] : Number(selected) * entry.rotation.step;
|
|
4896
|
+
if (!Number.isFinite(rotation)) rotation = 0;
|
|
4897
|
+
}
|
|
4898
|
+
return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };
|
|
4899
|
+
}
|
|
4900
|
+
/** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
|
|
4901
|
+
static matrix(resolved, matrix = new Matrix43()) {
|
|
4902
|
+
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));
|
|
4903
|
+
}
|
|
4904
|
+
};
|
|
4905
|
+
|
|
4906
|
+
// src/assets/index.ts
|
|
4846
4907
|
init_BlockStates();
|
|
4847
4908
|
|
|
4848
4909
|
// src/assets/Entities.ts
|
|
@@ -4913,6 +4974,15 @@ var Entities = class {
|
|
|
4913
4974
|
})));
|
|
4914
4975
|
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
4915
4976
|
}
|
|
4977
|
+
/**
|
|
4978
|
+
* Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
|
|
4979
|
+
*/
|
|
4980
|
+
static async getAnimations(modelKey) {
|
|
4981
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4982
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
|
|
4983
|
+
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4984
|
+
return file?.animations;
|
|
4985
|
+
}
|
|
4916
4986
|
static async resolveTexture(modelKey) {
|
|
4917
4987
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4918
4988
|
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
@@ -4989,6 +5059,119 @@ function trimCanvas(source) {
|
|
|
4989
5059
|
return canvas;
|
|
4990
5060
|
}
|
|
4991
5061
|
|
|
5062
|
+
// src/entity/EntityAnimation.ts
|
|
5063
|
+
var ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
|
|
5064
|
+
function catmullRom(delta, p0, p1, p22, p32) {
|
|
5065
|
+
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);
|
|
5066
|
+
}
|
|
5067
|
+
function sampleEntityKeyframes(keyframes, time) {
|
|
5068
|
+
if (keyframes.length === 0) return [0, 0, 0];
|
|
5069
|
+
let low = 0, high = keyframes.length;
|
|
5070
|
+
while (low < high) {
|
|
5071
|
+
const middle = low + high >>> 1;
|
|
5072
|
+
if (time <= keyframes[middle].time) high = middle;
|
|
5073
|
+
else low = middle + 1;
|
|
5074
|
+
}
|
|
5075
|
+
const a = Math.max(0, low - 1);
|
|
5076
|
+
const b = Math.min(keyframes.length - 1, a + 1);
|
|
5077
|
+
const from = keyframes[a];
|
|
5078
|
+
const to = keyframes[b];
|
|
5079
|
+
const delta = a === b ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
|
|
5080
|
+
if (to.interpolation === "catmullrom") {
|
|
5081
|
+
const before = keyframes[Math.max(0, a - 1)].value;
|
|
5082
|
+
const after = keyframes[Math.min(keyframes.length - 1, b + 1)].value;
|
|
5083
|
+
return [0, 1, 2].map((i) => catmullRom(delta, before[i], from.value[i], to.value[i], after[i]));
|
|
5084
|
+
}
|
|
5085
|
+
const target = to.pre ?? to.value;
|
|
5086
|
+
return [0, 1, 2].map((i) => from.value[i] + (target[i] - from.value[i]) * delta);
|
|
5087
|
+
}
|
|
5088
|
+
function entityAnimationTime(animation, time, loop = animation.loop) {
|
|
5089
|
+
return loop && animation.length > 0 ? time % animation.length : time;
|
|
5090
|
+
}
|
|
5091
|
+
function sampleEntityAnimation(animation, time, loop = animation.loop) {
|
|
5092
|
+
const elapsed = entityAnimationTime(animation, time, loop);
|
|
5093
|
+
const pose = {};
|
|
5094
|
+
for (const [name, bone] of Object.entries(animation.bones)) {
|
|
5095
|
+
const sampled = pose[name] = {};
|
|
5096
|
+
for (const channel of ENTITY_ANIMATION_CHANNELS) {
|
|
5097
|
+
const keyframes = bone[channel];
|
|
5098
|
+
if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
return pose;
|
|
5102
|
+
}
|
|
5103
|
+
|
|
5104
|
+
// src/entity/scene/EntityAnimationPlayer.ts
|
|
5105
|
+
var ZERO = [0, 0, 0];
|
|
5106
|
+
var EntityAnimationPlayer = class {
|
|
5107
|
+
constructor() {
|
|
5108
|
+
this.parts = [];
|
|
5109
|
+
this._time = 0;
|
|
5110
|
+
this.loop = false;
|
|
5111
|
+
this.speed = 1;
|
|
5112
|
+
}
|
|
5113
|
+
get animation() {
|
|
5114
|
+
return this._animation;
|
|
5115
|
+
}
|
|
5116
|
+
get time() {
|
|
5117
|
+
return this._time;
|
|
5118
|
+
}
|
|
5119
|
+
/**
|
|
5120
|
+
* Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
|
|
5121
|
+
* bones without a matching part are skipped.
|
|
5122
|
+
*/
|
|
5123
|
+
play(layers, animation, options = {}) {
|
|
5124
|
+
this.stop();
|
|
5125
|
+
this._animation = animation;
|
|
5126
|
+
this._time = options.time ?? 0;
|
|
5127
|
+
this.loop = options.loop ?? animation.loop;
|
|
5128
|
+
this.speed = options.speed ?? 1;
|
|
5129
|
+
for (const layer of layers) {
|
|
5130
|
+
for (const bone of Object.keys(animation.bones)) {
|
|
5131
|
+
const object = layer.getObjectByName(`group:${bone}`);
|
|
5132
|
+
if (!object) continue;
|
|
5133
|
+
this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5136
|
+
this.apply();
|
|
5137
|
+
}
|
|
5138
|
+
/** Restores the default poses. Returns whether an animation was active. */
|
|
5139
|
+
stop() {
|
|
5140
|
+
if (!this._animation) return false;
|
|
5141
|
+
for (const part of this.parts) {
|
|
5142
|
+
part.object.position.copy(part.position);
|
|
5143
|
+
part.object.rotation.copy(part.rotation);
|
|
5144
|
+
part.object.scale.copy(part.scale);
|
|
5145
|
+
}
|
|
5146
|
+
this.clear();
|
|
5147
|
+
return true;
|
|
5148
|
+
}
|
|
5149
|
+
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
5150
|
+
clear() {
|
|
5151
|
+
this.parts = [];
|
|
5152
|
+
this._animation = void 0;
|
|
5153
|
+
this._time = 0;
|
|
5154
|
+
}
|
|
5155
|
+
setTime(seconds) {
|
|
5156
|
+
if (!this._animation) return false;
|
|
5157
|
+
this._time = seconds;
|
|
5158
|
+
this.apply();
|
|
5159
|
+
return true;
|
|
5160
|
+
}
|
|
5161
|
+
advance(deltaSeconds) {
|
|
5162
|
+
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
5163
|
+
}
|
|
5164
|
+
apply() {
|
|
5165
|
+
const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
|
|
5166
|
+
for (const part of this.parts) {
|
|
5167
|
+
const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
|
|
5168
|
+
part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
|
|
5169
|
+
part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
|
|
5170
|
+
part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
|
|
5171
|
+
}
|
|
5172
|
+
}
|
|
5173
|
+
};
|
|
5174
|
+
|
|
4992
5175
|
// src/entity/scene/EntityObject.ts
|
|
4993
5176
|
init_SceneObject();
|
|
4994
5177
|
init_Caching();
|
|
@@ -4998,7 +5181,7 @@ init_model();
|
|
|
4998
5181
|
init_ModelTextures();
|
|
4999
5182
|
init_AssetKey();
|
|
5000
5183
|
init_Materials();
|
|
5001
|
-
import { Color as Color3, Euler as Euler4, Matrix4 as
|
|
5184
|
+
import { Color as Color3, Euler as Euler4, Matrix4 as Matrix45, Object3D as Object3D3 } from "three";
|
|
5002
5185
|
init_three();
|
|
5003
5186
|
var EntityObject = class _EntityObject extends SceneObject {
|
|
5004
5187
|
constructor(entity, options) {
|
|
@@ -5010,6 +5193,7 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5010
5193
|
this.scrollMaterials = [];
|
|
5011
5194
|
/** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
|
|
5012
5195
|
this.age = 0;
|
|
5196
|
+
this.animationPlayer = new EntityAnimationPlayer();
|
|
5013
5197
|
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
5014
5198
|
}
|
|
5015
5199
|
static {
|
|
@@ -5024,6 +5208,7 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5024
5208
|
}
|
|
5025
5209
|
disposeAndRemoveAllChildren() {
|
|
5026
5210
|
this.clearScrollMaterials();
|
|
5211
|
+
this.animationPlayer.clear();
|
|
5027
5212
|
super.disposeAndRemoveAllChildren();
|
|
5028
5213
|
}
|
|
5029
5214
|
clearScrollMaterials() {
|
|
@@ -5041,6 +5226,39 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5041
5226
|
}
|
|
5042
5227
|
this.notifyDirty();
|
|
5043
5228
|
}
|
|
5229
|
+
//<editor-fold desc="ANIMATION">
|
|
5230
|
+
/** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
|
|
5231
|
+
get animation() {
|
|
5232
|
+
return this.animationPlayer.animation;
|
|
5233
|
+
}
|
|
5234
|
+
/** Seconds since the animation started, before looping. */
|
|
5235
|
+
get animationTime() {
|
|
5236
|
+
return this.animationPlayer.time;
|
|
5237
|
+
}
|
|
5238
|
+
/**
|
|
5239
|
+
* Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
|
|
5240
|
+
* Parts of every layer are matched by name and their current pose is the default the offsets add to.
|
|
5241
|
+
* The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
|
|
5242
|
+
*/
|
|
5243
|
+
playAnimation(animation, options) {
|
|
5244
|
+
this.createMeshes();
|
|
5245
|
+
const layers = Object.keys(this.entityLayers).map((name) => this.getLayerGroup(name)).filter((layer) => !!layer);
|
|
5246
|
+
this.animationPlayer.play(layers, animation, options);
|
|
5247
|
+
this.notifyDirty();
|
|
5248
|
+
}
|
|
5249
|
+
/** Stops the animation and restores the default pose. */
|
|
5250
|
+
stopAnimation() {
|
|
5251
|
+
if (this.animationPlayer.stop()) this.notifyDirty();
|
|
5252
|
+
}
|
|
5253
|
+
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
5254
|
+
setAnimationTime(seconds) {
|
|
5255
|
+
if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
|
|
5256
|
+
}
|
|
5257
|
+
/** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
|
|
5258
|
+
advanceAnimation(deltaSeconds) {
|
|
5259
|
+
if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
|
|
5260
|
+
}
|
|
5261
|
+
//</editor-fold>
|
|
5044
5262
|
getLayerGroup(name) {
|
|
5045
5263
|
return super.getGroupByName(`layer:${name}`);
|
|
5046
5264
|
}
|
|
@@ -5074,7 +5292,7 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5074
5292
|
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
5075
5293
|
if (transform) {
|
|
5076
5294
|
for (const op of transform) {
|
|
5077
|
-
const matrix = new
|
|
5295
|
+
const matrix = new Matrix45();
|
|
5078
5296
|
if ("scale" in op) matrix.makeScale(...op.scale);
|
|
5079
5297
|
else if ("translate" in op) matrix.makeTranslation(...op.translate);
|
|
5080
5298
|
else matrix.makeRotationFromEuler(new Euler4(...op.rotate, "ZYX"));
|
|
@@ -5169,7 +5387,7 @@ function isEntityObject(obj) {
|
|
|
5169
5387
|
init_MineRenderError();
|
|
5170
5388
|
|
|
5171
5389
|
// src/export/SceneExporter.ts
|
|
5172
|
-
import { ClampToEdgeWrapping as ClampToEdgeWrapping2, Color as Color7, Float32BufferAttribute as Float32BufferAttribute3, Matrix4 as
|
|
5390
|
+
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";
|
|
5173
5391
|
|
|
5174
5392
|
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
5175
5393
|
import {
|
|
@@ -5595,7 +5813,7 @@ import {
|
|
|
5595
5813
|
LinearMipmapLinearFilter,
|
|
5596
5814
|
LinearMipmapNearestFilter,
|
|
5597
5815
|
MathUtils as MathUtils2,
|
|
5598
|
-
Matrix4 as
|
|
5816
|
+
Matrix4 as Matrix46,
|
|
5599
5817
|
MirroredRepeatWrapping,
|
|
5600
5818
|
NearestFilter as NearestFilter2,
|
|
5601
5819
|
NearestMipmapLinearFilter,
|
|
@@ -6885,7 +7103,7 @@ var GLTFWriter = class {
|
|
|
6885
7103
|
if (rootJoint === void 0) return null;
|
|
6886
7104
|
const joints = [];
|
|
6887
7105
|
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
6888
|
-
const temporaryBoneInverse = new
|
|
7106
|
+
const temporaryBoneInverse = new Matrix46();
|
|
6889
7107
|
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
6890
7108
|
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
6891
7109
|
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
@@ -7351,7 +7569,7 @@ var GLTFMeshGpuInstancing = class {
|
|
|
7351
7569
|
const translationAttr = new Float32Array(mesh.count * 3);
|
|
7352
7570
|
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
7353
7571
|
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
7354
|
-
const matrix = new
|
|
7572
|
+
const matrix = new Matrix46();
|
|
7355
7573
|
const position = new Vector38();
|
|
7356
7574
|
const quaternion = new Quaternion4();
|
|
7357
7575
|
const scale = new Vector38();
|
|
@@ -7525,7 +7743,7 @@ var SceneExporter = class {
|
|
|
7525
7743
|
}
|
|
7526
7744
|
};
|
|
7527
7745
|
function localMatrix(object) {
|
|
7528
|
-
return object.matrixAutoUpdate ? new
|
|
7746
|
+
return object.matrixAutoUpdate ? new Matrix47().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
|
|
7529
7747
|
}
|
|
7530
7748
|
function createSnapshot(root, gltf, bakeColors = false) {
|
|
7531
7749
|
const scene = new Scene4();
|
|
@@ -7637,7 +7855,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7637
7855
|
const instanced = mesh;
|
|
7638
7856
|
if (instanced.isInstancedMesh) {
|
|
7639
7857
|
for (let i = 0; i < instanced.count; i++) {
|
|
7640
|
-
const matrix = new
|
|
7858
|
+
const matrix = new Matrix47();
|
|
7641
7859
|
instanced.getMatrixAt(i, matrix);
|
|
7642
7860
|
const color = instanced.instanceColor ? new Color7().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
7643
7861
|
addMesh(mesh, world.clone().multiply(matrix), color);
|
|
@@ -7651,7 +7869,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7651
7869
|
try {
|
|
7652
7870
|
const ancestors = [];
|
|
7653
7871
|
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
7654
|
-
const world = new
|
|
7872
|
+
const world = new Matrix47();
|
|
7655
7873
|
for (const ancestor of ancestors) {
|
|
7656
7874
|
if (!ancestor.visible) return { scene, dispose };
|
|
7657
7875
|
world.multiply(localMatrix(ancestor));
|
|
@@ -8553,7 +8771,7 @@ var import_ts_deepmerge6 = __toESM(require_dist());
|
|
|
8553
8771
|
init_MineRenderError();
|
|
8554
8772
|
init_InstanceReference();
|
|
8555
8773
|
init_AssetKey();
|
|
8556
|
-
import { Euler as Euler8, Matrix4 as
|
|
8774
|
+
import { Euler as Euler8, Matrix4 as Matrix49, Quaternion as Quaternion5, Vector3 as Vector311 } from "three";
|
|
8557
8775
|
init_ModelCulling();
|
|
8558
8776
|
init_FluidGeometry();
|
|
8559
8777
|
var BlockObject = class _BlockObject extends SceneObject {
|
|
@@ -8570,6 +8788,9 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8570
8788
|
this._variants = [];
|
|
8571
8789
|
this._models = [];
|
|
8572
8790
|
this._cullMask = 0;
|
|
8791
|
+
this._entities = [];
|
|
8792
|
+
this._entityPlacement = new Matrix49();
|
|
8793
|
+
this._entityGeneration = 0;
|
|
8573
8794
|
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
8574
8795
|
}
|
|
8575
8796
|
static {
|
|
@@ -8594,6 +8815,8 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8594
8815
|
}
|
|
8595
8816
|
clearModels() {
|
|
8596
8817
|
this.removeModels(this._models.splice(0));
|
|
8818
|
+
this._entityGeneration++;
|
|
8819
|
+
this.removeEntities(this._entities.splice(0));
|
|
8597
8820
|
this._fluidKey = void 0;
|
|
8598
8821
|
this._fluidModel = void 0;
|
|
8599
8822
|
this._isInstanced = false;
|
|
@@ -8605,6 +8828,57 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8605
8828
|
if (!isInstanceReference(model)) model.dispose();
|
|
8606
8829
|
}
|
|
8607
8830
|
}
|
|
8831
|
+
removeEntities(entities) {
|
|
8832
|
+
for (const entity of entities) {
|
|
8833
|
+
entity.removeFromScene();
|
|
8834
|
+
entity.dispose();
|
|
8835
|
+
}
|
|
8836
|
+
}
|
|
8837
|
+
/** Entity models drawn for this block instead of its block model; they are scene children, unlike the block. */
|
|
8838
|
+
get blockEntities() {
|
|
8839
|
+
return this._entities;
|
|
8840
|
+
}
|
|
8841
|
+
/**
|
|
8842
|
+
* Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
|
|
8843
|
+
* when the block is not listed or one of its models cannot be loaded.
|
|
8844
|
+
*/
|
|
8845
|
+
async createBlockEntities() {
|
|
8846
|
+
const key = this.blockState.key;
|
|
8847
|
+
if (!key || this.options.displayPosition) return false;
|
|
8848
|
+
const generation = this._entityGeneration;
|
|
8849
|
+
const created = [];
|
|
8850
|
+
let resolved;
|
|
8851
|
+
try {
|
|
8852
|
+
resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);
|
|
8853
|
+
if (!resolved) return false;
|
|
8854
|
+
for (const part of resolved.parts) {
|
|
8855
|
+
const [namespace, path] = part.model.includes(":") ? part.model.split(":") : [key.namespace, part.model];
|
|
8856
|
+
const texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
8857
|
+
if (texture) texture.root = key.root;
|
|
8858
|
+
const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });
|
|
8859
|
+
if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);
|
|
8860
|
+
created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }));
|
|
8861
|
+
}
|
|
8862
|
+
} catch (error) {
|
|
8863
|
+
console.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
|
|
8864
|
+
this.removeEntities(created);
|
|
8865
|
+
return false;
|
|
8866
|
+
}
|
|
8867
|
+
if (generation !== this._entityGeneration) {
|
|
8868
|
+
this.removeEntities(created);
|
|
8869
|
+
return true;
|
|
8870
|
+
}
|
|
8871
|
+
BlockEntities.matrix(resolved, this._entityPlacement);
|
|
8872
|
+
this._entities = created;
|
|
8873
|
+
this.placeEntities();
|
|
8874
|
+
return true;
|
|
8875
|
+
}
|
|
8876
|
+
placeEntities() {
|
|
8877
|
+
const matrix = new Matrix49().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
|
|
8878
|
+
for (const entity of this._entities) {
|
|
8879
|
+
matrix.decompose(entity.position, entity.quaternion, entity.scale);
|
|
8880
|
+
}
|
|
8881
|
+
}
|
|
8608
8882
|
get isOccluding() {
|
|
8609
8883
|
return this._models.some((model) => {
|
|
8610
8884
|
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
@@ -8686,7 +8960,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8686
8960
|
() => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
|
|
8687
8961
|
);
|
|
8688
8962
|
const previous = this._fluidModel;
|
|
8689
|
-
const matrix = previous ? this.getModelMatrix(previous) : new
|
|
8963
|
+
const matrix = previous ? this.getModelMatrix(previous) : new Matrix49().makeTranslation(...this.position.toArray());
|
|
8690
8964
|
if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
|
|
8691
8965
|
else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
8692
8966
|
this._models = this._models.filter((model) => model !== previous);
|
|
@@ -8716,13 +8990,20 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8716
8990
|
await this.updateFluid(this._fluidSampler);
|
|
8717
8991
|
return;
|
|
8718
8992
|
}
|
|
8993
|
+
const hasEntities = await this.createBlockEntities();
|
|
8719
8994
|
const variantsToCreate = await this.mapStateToVariant(this.state);
|
|
8720
8995
|
this._variants = variantsToCreate;
|
|
8721
8996
|
for (let blockStateVariant of variantsToCreate) {
|
|
8997
|
+
if (hasEntities && !await this.hasGeometry(blockStateVariant)) continue;
|
|
8722
8998
|
this._models.push(await this.createVariant(blockStateVariant));
|
|
8723
8999
|
}
|
|
8724
9000
|
await this.updateFluid(this._fluidSampler);
|
|
8725
9001
|
}
|
|
9002
|
+
async hasGeometry(variant) {
|
|
9003
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
9004
|
+
modelKey.root = this.blockState.key?.root;
|
|
9005
|
+
return !!(await Models.getMerged(modelKey))?.elements?.length;
|
|
9006
|
+
}
|
|
8726
9007
|
getSingleVariant(variants) {
|
|
8727
9008
|
return BlockStateResolver.choose(variants);
|
|
8728
9009
|
}
|
|
@@ -8817,7 +9098,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8817
9098
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
8818
9099
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
8819
9100
|
}
|
|
8820
|
-
getMatrixAt(index, matrix = new
|
|
9101
|
+
getMatrixAt(index, matrix = new Matrix49()) {
|
|
8821
9102
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
8822
9103
|
const child = this._models[0];
|
|
8823
9104
|
if (child && isModelObject(child)) {
|
|
@@ -8842,6 +9123,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8842
9123
|
for (let model of this._models) {
|
|
8843
9124
|
model.setPosition(position);
|
|
8844
9125
|
}
|
|
9126
|
+
this.placeEntities();
|
|
8845
9127
|
this.notifyDirty();
|
|
8846
9128
|
}
|
|
8847
9129
|
//TODO: should override rotation + scale methods
|
|
@@ -13379,7 +13661,7 @@ init_CubeFace();
|
|
|
13379
13661
|
init_AssetKey();
|
|
13380
13662
|
init_Models();
|
|
13381
13663
|
init_CubeFace();
|
|
13382
|
-
import { Matrix4 as
|
|
13664
|
+
import { Matrix4 as Matrix410, Vector3 as Vector314 } from "three";
|
|
13383
13665
|
init_ModelCulling();
|
|
13384
13666
|
init_ModelObject();
|
|
13385
13667
|
init_UVMapper();
|
|
@@ -13442,7 +13724,7 @@ var SectionModels = class {
|
|
|
13442
13724
|
});
|
|
13443
13725
|
await object.init();
|
|
13444
13726
|
const geometry = object.children[0].geometry;
|
|
13445
|
-
geometry.applyMatrix4(new
|
|
13727
|
+
geometry.applyMatrix4(new Matrix410().makeRotationFromEuler(rotation));
|
|
13446
13728
|
object.clear();
|
|
13447
13729
|
const cullFaces = CUBE_FACES.map((face) => {
|
|
13448
13730
|
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
@@ -13854,7 +14136,8 @@ var Chunk = class _Chunk {
|
|
|
13854
14136
|
this.data.set(index, void 0);
|
|
13855
14137
|
return void 0;
|
|
13856
14138
|
}
|
|
13857
|
-
const
|
|
14139
|
+
const perBlock = !this.sectionModels || getFluidKind(blockState.key, stored.properties) || blockState.key && BlockEntities.entry(await BlockEntities.getIndex(blockState.key.root), blockState.key.toNamespacedString());
|
|
14140
|
+
const template = perBlock ? void 0 : await this.sectionModels.get(blockState, stored.properties);
|
|
13858
14141
|
if (template) {
|
|
13859
14142
|
this.sectionBlocks.set(index, { index, template, cullMask: 0 });
|
|
13860
14143
|
this.meshDirty = true;
|
|
@@ -13963,6 +14246,7 @@ export {
|
|
|
13963
14246
|
BUILTIN_GENERATED,
|
|
13964
14247
|
BasicAssetKey,
|
|
13965
14248
|
BatchedExecutor,
|
|
14249
|
+
BlockEntities,
|
|
13966
14250
|
BlockObject,
|
|
13967
14251
|
BlockStateResolver,
|
|
13968
14252
|
BlockStates,
|
|
@@ -13984,7 +14268,9 @@ export {
|
|
|
13984
14268
|
DefaultBlockStates,
|
|
13985
14269
|
DisplayPosition,
|
|
13986
14270
|
DisplayTransforms,
|
|
14271
|
+
ENTITY_ANIMATION_CHANNELS,
|
|
13987
14272
|
Entities,
|
|
14273
|
+
EntityAnimationPlayer,
|
|
13988
14274
|
EntityObject,
|
|
13989
14275
|
Env,
|
|
13990
14276
|
FluidModelObject,
|
|
@@ -14060,6 +14346,7 @@ export {
|
|
|
14060
14346
|
createCanvas2 as createCanvas,
|
|
14061
14347
|
createFluidGeometry,
|
|
14062
14348
|
createImage,
|
|
14349
|
+
entityAnimationTime,
|
|
14063
14350
|
estimateBytesUsed,
|
|
14064
14351
|
getBlockFluidState,
|
|
14065
14352
|
getFluidKind,
|
|
@@ -14092,6 +14379,8 @@ export {
|
|
|
14092
14379
|
mergeVertices,
|
|
14093
14380
|
prefix,
|
|
14094
14381
|
registerNodeEnv,
|
|
14382
|
+
sampleEntityAnimation,
|
|
14383
|
+
sampleEntityKeyframes,
|
|
14095
14384
|
sampleFluid,
|
|
14096
14385
|
serializeBoxGeometryKey,
|
|
14097
14386
|
serializeImageKey,
|