minerender 2.1.0-alpha.54 → 2.1.0-alpha.59
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 +163 -2
- package/dist/browser/index.d.ts +163 -2
- package/dist/browser/index.js +574 -266
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +338 -30
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +324 -7
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +163 -2
- package/dist/node/index.d.ts +163 -2
- package/dist/node/index.js +584 -266
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +342 -30
- 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() {
|
|
@@ -1770,6 +1778,11 @@ function addWireframeToMesh(geo, mesh, color = 16777215, w = 2) {
|
|
|
1770
1778
|
mesh.add(wireframe);
|
|
1771
1779
|
let axes = new AxesHelper(1);
|
|
1772
1780
|
mesh.add(axes);
|
|
1781
|
+
return () => {
|
|
1782
|
+
wireGeo.dispose();
|
|
1783
|
+
wireMat.dispose();
|
|
1784
|
+
axes.dispose();
|
|
1785
|
+
};
|
|
1773
1786
|
}
|
|
1774
1787
|
var init_model = __esm({
|
|
1775
1788
|
"src/util/model.ts"() {
|
|
@@ -3161,7 +3174,7 @@ var init_InstanceReference = __esm({
|
|
|
3161
3174
|
});
|
|
3162
3175
|
|
|
3163
3176
|
// src/renderer/SceneObject.ts
|
|
3164
|
-
import { Color as Color2, Euler as Euler3, InstancedBufferAttribute, InstancedMesh, MathUtils, Matrix4 as
|
|
3177
|
+
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
3178
|
function isSceneObject(obj) {
|
|
3166
3179
|
return obj.isSceneObject;
|
|
3167
3180
|
}
|
|
@@ -3377,7 +3390,7 @@ var init_SceneObject = __esm({
|
|
|
3377
3390
|
mesh.instanceColor.needsUpdate = true;
|
|
3378
3391
|
}
|
|
3379
3392
|
if (this._scene) this._scene.stats.instanceCount++;
|
|
3380
|
-
this.setMatrixAt(index, new
|
|
3393
|
+
this.setMatrixAt(index, new Matrix44());
|
|
3381
3394
|
return reference;
|
|
3382
3395
|
}
|
|
3383
3396
|
/** Returns the live reference for a raycast hit on this object's instance mesh. */
|
|
@@ -3390,7 +3403,7 @@ var init_SceneObject = __esm({
|
|
|
3390
3403
|
removeInstanceAt(index) {
|
|
3391
3404
|
if (!this.instanceReferences.has(index)) return;
|
|
3392
3405
|
const mesh = this.instanceMesh;
|
|
3393
|
-
this.setMatrixAt(index, new
|
|
3406
|
+
this.setMatrixAt(index, new Matrix44().makeScale(0, 0, 0));
|
|
3394
3407
|
this.instanceReferences.delete(index);
|
|
3395
3408
|
this.freeInstanceIndices.push(index);
|
|
3396
3409
|
this._instanceCounter = this.instanceReferences.size;
|
|
@@ -3420,7 +3433,7 @@ var init_SceneObject = __esm({
|
|
|
3420
3433
|
}
|
|
3421
3434
|
//</editor-fold>
|
|
3422
3435
|
//<editor-fold desc="TRANSFORMATION">
|
|
3423
|
-
getMatrixAt(index, matrix = new
|
|
3436
|
+
getMatrixAt(index, matrix = new Matrix44()) {
|
|
3424
3437
|
if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
|
|
3425
3438
|
this.instanceMesh.getMatrixAt(index, matrix);
|
|
3426
3439
|
return matrix;
|
|
@@ -3439,7 +3452,7 @@ var init_SceneObject = __esm({
|
|
|
3439
3452
|
const oldPosition = new Vector35();
|
|
3440
3453
|
const oldRotation = new Quaternion3();
|
|
3441
3454
|
const oldScale = new Vector35();
|
|
3442
|
-
const matrix = new
|
|
3455
|
+
const matrix = new Matrix44();
|
|
3443
3456
|
if (!scale || !rotation || !position) {
|
|
3444
3457
|
this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
|
|
3445
3458
|
}
|
|
@@ -4187,7 +4200,7 @@ var init_ModelCulling = __esm({
|
|
|
4187
4200
|
});
|
|
4188
4201
|
|
|
4189
4202
|
// src/model/scene/ModelObject.ts
|
|
4190
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as
|
|
4203
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as Matrix48 } from "three";
|
|
4191
4204
|
function isModelObject(obj) {
|
|
4192
4205
|
return obj.isModelObject;
|
|
4193
4206
|
}
|
|
@@ -4269,12 +4282,12 @@ var init_ModelObject = __esm({
|
|
|
4269
4282
|
}
|
|
4270
4283
|
elGeo.setAttribute("color", new BufferAttribute5(colors, 3));
|
|
4271
4284
|
}
|
|
4272
|
-
elGeo.applyMatrix4(new
|
|
4273
|
-
elGeo.applyMatrix4(new
|
|
4285
|
+
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));
|
|
4286
|
+
elGeo.applyMatrix4(new Matrix48().makeTranslation(el.from[0], el.from[1], el.from[2]));
|
|
4274
4287
|
if (el.rotation) {
|
|
4275
4288
|
applyElementRotation(el.rotation, elGeo);
|
|
4276
4289
|
}
|
|
4277
|
-
elGeo.applyMatrix4(new
|
|
4290
|
+
elGeo.applyMatrix4(new Matrix48().makeTranslation(-8, -8, -8));
|
|
4278
4291
|
if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
|
|
4279
4292
|
if (this.options.mergeMeshes) {
|
|
4280
4293
|
allGeos.push(elGeo);
|
|
@@ -4843,6 +4856,59 @@ function shutdown() {
|
|
|
4843
4856
|
init_AssetKey();
|
|
4844
4857
|
init_AssetLoader();
|
|
4845
4858
|
init_Assets();
|
|
4859
|
+
|
|
4860
|
+
// src/assets/BlockEntities.ts
|
|
4861
|
+
init_AssetKey();
|
|
4862
|
+
init_AssetLoader();
|
|
4863
|
+
init_source();
|
|
4864
|
+
init_Caching();
|
|
4865
|
+
import { Matrix4 as Matrix43 } from "three";
|
|
4866
|
+
var BlockEntities = class {
|
|
4867
|
+
/**
|
|
4868
|
+
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
4869
|
+
* a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty
|
|
4870
|
+
* result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.
|
|
4871
|
+
*/
|
|
4872
|
+
static async getIndex(root) {
|
|
4873
|
+
const key = new AssetKey("entity-models", "blocks", void 0, void 0, void 0, ".json", root);
|
|
4874
|
+
key.rootType = void 0;
|
|
4875
|
+
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
4876
|
+
try {
|
|
4877
|
+
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
4878
|
+
} catch (error) {
|
|
4879
|
+
console.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
4880
|
+
return {};
|
|
4881
|
+
}
|
|
4882
|
+
});
|
|
4883
|
+
return index ?? {};
|
|
4884
|
+
}
|
|
4885
|
+
/** The index entry of a block ID such as `minecraft:chest`. */
|
|
4886
|
+
static entry(index, block) {
|
|
4887
|
+
const entry = Object.prototype.hasOwnProperty.call(index, block) ? index[block] : void 0;
|
|
4888
|
+
return Array.isArray(entry?.parts) ? entry : void 0;
|
|
4889
|
+
}
|
|
4890
|
+
/** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */
|
|
4891
|
+
static resolve(index, block, state = {}) {
|
|
4892
|
+
const entry = this.entry(index, block);
|
|
4893
|
+
if (!entry) return void 0;
|
|
4894
|
+
const value = (property) => String(state[property]).toLowerCase();
|
|
4895
|
+
const parts = entry.parts.filter((part) => Object.entries(part.when ?? {}).every(([property, values]) => String(values).split("|").includes(value(property))));
|
|
4896
|
+
if (!parts.length) return void 0;
|
|
4897
|
+
let rotation = 0;
|
|
4898
|
+
if (entry.rotation) {
|
|
4899
|
+
const selected = value(entry.rotation.property);
|
|
4900
|
+
rotation = "degrees" in entry.rotation ? entry.rotation.degrees[selected] : Number(selected) * entry.rotation.step;
|
|
4901
|
+
if (!Number.isFinite(rotation)) rotation = 0;
|
|
4902
|
+
}
|
|
4903
|
+
return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };
|
|
4904
|
+
}
|
|
4905
|
+
/** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
|
|
4906
|
+
static matrix(resolved, matrix = new Matrix43()) {
|
|
4907
|
+
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));
|
|
4908
|
+
}
|
|
4909
|
+
};
|
|
4910
|
+
|
|
4911
|
+
// src/assets/index.ts
|
|
4846
4912
|
init_BlockStates();
|
|
4847
4913
|
|
|
4848
4914
|
// src/assets/Entities.ts
|
|
@@ -4913,6 +4979,15 @@ var Entities = class {
|
|
|
4913
4979
|
})));
|
|
4914
4980
|
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
4915
4981
|
}
|
|
4982
|
+
/**
|
|
4983
|
+
* Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
|
|
4984
|
+
*/
|
|
4985
|
+
static async getAnimations(modelKey) {
|
|
4986
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4987
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
|
|
4988
|
+
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4989
|
+
return file?.animations;
|
|
4990
|
+
}
|
|
4916
4991
|
static async resolveTexture(modelKey) {
|
|
4917
4992
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4918
4993
|
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
|
|
@@ -4989,6 +5064,119 @@ function trimCanvas(source) {
|
|
|
4989
5064
|
return canvas;
|
|
4990
5065
|
}
|
|
4991
5066
|
|
|
5067
|
+
// src/entity/EntityAnimation.ts
|
|
5068
|
+
var ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
|
|
5069
|
+
function catmullRom(delta, p0, p1, p22, p32) {
|
|
5070
|
+
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);
|
|
5071
|
+
}
|
|
5072
|
+
function sampleEntityKeyframes(keyframes, time) {
|
|
5073
|
+
if (keyframes.length === 0) return [0, 0, 0];
|
|
5074
|
+
let low = 0, high = keyframes.length;
|
|
5075
|
+
while (low < high) {
|
|
5076
|
+
const middle = low + high >>> 1;
|
|
5077
|
+
if (time <= keyframes[middle].time) high = middle;
|
|
5078
|
+
else low = middle + 1;
|
|
5079
|
+
}
|
|
5080
|
+
const a = Math.max(0, low - 1);
|
|
5081
|
+
const b = Math.min(keyframes.length - 1, a + 1);
|
|
5082
|
+
const from = keyframes[a];
|
|
5083
|
+
const to = keyframes[b];
|
|
5084
|
+
const delta = a === b ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
|
|
5085
|
+
if (to.interpolation === "catmullrom") {
|
|
5086
|
+
const before = keyframes[Math.max(0, a - 1)].value;
|
|
5087
|
+
const after = keyframes[Math.min(keyframes.length - 1, b + 1)].value;
|
|
5088
|
+
return [0, 1, 2].map((i) => catmullRom(delta, before[i], from.value[i], to.value[i], after[i]));
|
|
5089
|
+
}
|
|
5090
|
+
const target = to.pre ?? to.value;
|
|
5091
|
+
return [0, 1, 2].map((i) => from.value[i] + (target[i] - from.value[i]) * delta);
|
|
5092
|
+
}
|
|
5093
|
+
function entityAnimationTime(animation, time, loop = animation.loop) {
|
|
5094
|
+
return loop && animation.length > 0 ? time % animation.length : time;
|
|
5095
|
+
}
|
|
5096
|
+
function sampleEntityAnimation(animation, time, loop = animation.loop) {
|
|
5097
|
+
const elapsed = entityAnimationTime(animation, time, loop);
|
|
5098
|
+
const pose = {};
|
|
5099
|
+
for (const [name, bone] of Object.entries(animation.bones)) {
|
|
5100
|
+
const sampled = pose[name] = {};
|
|
5101
|
+
for (const channel of ENTITY_ANIMATION_CHANNELS) {
|
|
5102
|
+
const keyframes = bone[channel];
|
|
5103
|
+
if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
|
|
5104
|
+
}
|
|
5105
|
+
}
|
|
5106
|
+
return pose;
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5109
|
+
// src/entity/scene/EntityAnimationPlayer.ts
|
|
5110
|
+
var ZERO = [0, 0, 0];
|
|
5111
|
+
var EntityAnimationPlayer = class {
|
|
5112
|
+
constructor() {
|
|
5113
|
+
this.parts = [];
|
|
5114
|
+
this._time = 0;
|
|
5115
|
+
this.loop = false;
|
|
5116
|
+
this.speed = 1;
|
|
5117
|
+
}
|
|
5118
|
+
get animation() {
|
|
5119
|
+
return this._animation;
|
|
5120
|
+
}
|
|
5121
|
+
get time() {
|
|
5122
|
+
return this._time;
|
|
5123
|
+
}
|
|
5124
|
+
/**
|
|
5125
|
+
* Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
|
|
5126
|
+
* bones without a matching part are skipped.
|
|
5127
|
+
*/
|
|
5128
|
+
play(layers, animation, options = {}) {
|
|
5129
|
+
this.stop();
|
|
5130
|
+
this._animation = animation;
|
|
5131
|
+
this._time = options.time ?? 0;
|
|
5132
|
+
this.loop = options.loop ?? animation.loop;
|
|
5133
|
+
this.speed = options.speed ?? 1;
|
|
5134
|
+
for (const layer of layers) {
|
|
5135
|
+
for (const bone of Object.keys(animation.bones)) {
|
|
5136
|
+
const object = layer.getObjectByName(`group:${bone}`);
|
|
5137
|
+
if (!object) continue;
|
|
5138
|
+
this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
this.apply();
|
|
5142
|
+
}
|
|
5143
|
+
/** Restores the default poses. Returns whether an animation was active. */
|
|
5144
|
+
stop() {
|
|
5145
|
+
if (!this._animation) return false;
|
|
5146
|
+
for (const part of this.parts) {
|
|
5147
|
+
part.object.position.copy(part.position);
|
|
5148
|
+
part.object.rotation.copy(part.rotation);
|
|
5149
|
+
part.object.scale.copy(part.scale);
|
|
5150
|
+
}
|
|
5151
|
+
this.clear();
|
|
5152
|
+
return true;
|
|
5153
|
+
}
|
|
5154
|
+
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
5155
|
+
clear() {
|
|
5156
|
+
this.parts = [];
|
|
5157
|
+
this._animation = void 0;
|
|
5158
|
+
this._time = 0;
|
|
5159
|
+
}
|
|
5160
|
+
setTime(seconds) {
|
|
5161
|
+
if (!this._animation) return false;
|
|
5162
|
+
this._time = seconds;
|
|
5163
|
+
this.apply();
|
|
5164
|
+
return true;
|
|
5165
|
+
}
|
|
5166
|
+
advance(deltaSeconds) {
|
|
5167
|
+
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
5168
|
+
}
|
|
5169
|
+
apply() {
|
|
5170
|
+
const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
|
|
5171
|
+
for (const part of this.parts) {
|
|
5172
|
+
const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
|
|
5173
|
+
part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
|
|
5174
|
+
part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
|
|
5175
|
+
part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
|
|
5176
|
+
}
|
|
5177
|
+
}
|
|
5178
|
+
};
|
|
5179
|
+
|
|
4992
5180
|
// src/entity/scene/EntityObject.ts
|
|
4993
5181
|
init_SceneObject();
|
|
4994
5182
|
init_Caching();
|
|
@@ -4998,7 +5186,7 @@ init_model();
|
|
|
4998
5186
|
init_ModelTextures();
|
|
4999
5187
|
init_AssetKey();
|
|
5000
5188
|
init_Materials();
|
|
5001
|
-
import { Color as Color3, Euler as Euler4, Matrix4 as
|
|
5189
|
+
import { Color as Color3, Euler as Euler4, Matrix4 as Matrix45, Object3D as Object3D3 } from "three";
|
|
5002
5190
|
init_three();
|
|
5003
5191
|
var EntityObject = class _EntityObject extends SceneObject {
|
|
5004
5192
|
constructor(entity, options) {
|
|
@@ -5006,11 +5194,16 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5006
5194
|
this.entity = entity;
|
|
5007
5195
|
this.isEntityObject = true;
|
|
5008
5196
|
this.meshesCreated = false;
|
|
5197
|
+
this.geometries = /* @__PURE__ */ new Set();
|
|
5198
|
+
this.disposeWireframes = [];
|
|
5009
5199
|
/** Scrolling materials are owned: their texture offset follows this entity's age. */
|
|
5010
5200
|
this.scrollMaterials = [];
|
|
5011
5201
|
/** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
|
|
5012
5202
|
this.age = 0;
|
|
5203
|
+
this.animationPlayer = new EntityAnimationPlayer();
|
|
5013
5204
|
this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
5205
|
+
this.addEventListener("added", () => this.updateScrollSubscription());
|
|
5206
|
+
this.addEventListener("removed", () => this.updateScrollSubscription());
|
|
5014
5207
|
}
|
|
5015
5208
|
static {
|
|
5016
5209
|
this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
|
|
@@ -5024,6 +5217,10 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5024
5217
|
}
|
|
5025
5218
|
disposeAndRemoveAllChildren() {
|
|
5026
5219
|
this.clearScrollMaterials();
|
|
5220
|
+
for (const geometry of this.geometries) geometry.dispose();
|
|
5221
|
+
this.geometries.clear();
|
|
5222
|
+
for (const dispose of this.disposeWireframes.splice(0)) dispose();
|
|
5223
|
+
this.animationPlayer.clear();
|
|
5027
5224
|
super.disposeAndRemoveAllChildren();
|
|
5028
5225
|
}
|
|
5029
5226
|
clearScrollMaterials() {
|
|
@@ -5034,6 +5231,19 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5034
5231
|
material.dispose();
|
|
5035
5232
|
}
|
|
5036
5233
|
}
|
|
5234
|
+
updateScrollSubscription() {
|
|
5235
|
+
if (this.parent && this.scrollMaterials.length) {
|
|
5236
|
+
if (this.scrollTicker === void 0) {
|
|
5237
|
+
this.scrollTicker = Ticker.add(() => {
|
|
5238
|
+
this.age++;
|
|
5239
|
+
this.updateScroll();
|
|
5240
|
+
});
|
|
5241
|
+
}
|
|
5242
|
+
} else {
|
|
5243
|
+
Ticker.remove(this.scrollTicker);
|
|
5244
|
+
this.scrollTicker = void 0;
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5037
5247
|
/** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
|
|
5038
5248
|
updateScroll() {
|
|
5039
5249
|
for (const { offset, speed } of this.scrollMaterials) {
|
|
@@ -5041,6 +5251,39 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5041
5251
|
}
|
|
5042
5252
|
this.notifyDirty();
|
|
5043
5253
|
}
|
|
5254
|
+
//<editor-fold desc="ANIMATION">
|
|
5255
|
+
/** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
|
|
5256
|
+
get animation() {
|
|
5257
|
+
return this.animationPlayer.animation;
|
|
5258
|
+
}
|
|
5259
|
+
/** Seconds since the animation started, before looping. */
|
|
5260
|
+
get animationTime() {
|
|
5261
|
+
return this.animationPlayer.time;
|
|
5262
|
+
}
|
|
5263
|
+
/**
|
|
5264
|
+
* Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
|
|
5265
|
+
* Parts of every layer are matched by name and their current pose is the default the offsets add to.
|
|
5266
|
+
* The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
|
|
5267
|
+
*/
|
|
5268
|
+
playAnimation(animation, options) {
|
|
5269
|
+
this.createMeshes();
|
|
5270
|
+
const layers = Object.keys(this.entityLayers).map((name) => this.getLayerGroup(name)).filter((layer) => !!layer);
|
|
5271
|
+
this.animationPlayer.play(layers, animation, options);
|
|
5272
|
+
this.notifyDirty();
|
|
5273
|
+
}
|
|
5274
|
+
/** Stops the animation and restores the default pose. */
|
|
5275
|
+
stopAnimation() {
|
|
5276
|
+
if (this.animationPlayer.stop()) this.notifyDirty();
|
|
5277
|
+
}
|
|
5278
|
+
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
5279
|
+
setAnimationTime(seconds) {
|
|
5280
|
+
if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
|
|
5281
|
+
}
|
|
5282
|
+
/** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
|
|
5283
|
+
advanceAnimation(deltaSeconds) {
|
|
5284
|
+
if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
|
|
5285
|
+
}
|
|
5286
|
+
//</editor-fold>
|
|
5044
5287
|
getLayerGroup(name) {
|
|
5045
5288
|
return super.getGroupByName(`layer:${name}`);
|
|
5046
5289
|
}
|
|
@@ -5074,7 +5317,7 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5074
5317
|
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
5075
5318
|
if (transform) {
|
|
5076
5319
|
for (const op of transform) {
|
|
5077
|
-
const matrix = new
|
|
5320
|
+
const matrix = new Matrix45();
|
|
5078
5321
|
if ("scale" in op) matrix.makeScale(...op.scale);
|
|
5079
5322
|
else if ("translate" in op) matrix.makeTranslation(...op.translate);
|
|
5080
5323
|
else matrix.makeRotationFromEuler(new Euler4(...op.rotate, "ZYX"));
|
|
@@ -5111,6 +5354,7 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5111
5354
|
depth + growZ * 2,
|
|
5112
5355
|
uv
|
|
5113
5356
|
).clone();
|
|
5357
|
+
this.geometries.add(geometry);
|
|
5114
5358
|
geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
|
|
5115
5359
|
if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
|
|
5116
5360
|
const index = Array.from(geometry.getIndex().array);
|
|
@@ -5119,7 +5363,7 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5119
5363
|
const mesh = this.createMesh(name, geometry, material);
|
|
5120
5364
|
mesh.renderOrder = renderOrder;
|
|
5121
5365
|
anchor.add(mesh);
|
|
5122
|
-
if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
|
|
5366
|
+
if (this.options.wireframe) this.disposeWireframes.push(addWireframeToMesh(geometry, mesh));
|
|
5123
5367
|
}
|
|
5124
5368
|
for (const [childName, child] of Object.entries(part.children)) {
|
|
5125
5369
|
this.createPart(childName, child, anchor, size, material, renderOrder, inward);
|
|
@@ -5153,11 +5397,8 @@ var EntityObject = class _EntityObject extends SceneObject {
|
|
|
5153
5397
|
this.clearScrollMaterials();
|
|
5154
5398
|
} else if (this.scrollMaterials.length) {
|
|
5155
5399
|
this.updateScroll();
|
|
5156
|
-
this.scrollTicker = Ticker.add(() => {
|
|
5157
|
-
this.age++;
|
|
5158
|
-
this.updateScroll();
|
|
5159
|
-
});
|
|
5160
5400
|
}
|
|
5401
|
+
this.updateScrollSubscription();
|
|
5161
5402
|
this.notifyDirty();
|
|
5162
5403
|
}
|
|
5163
5404
|
};
|
|
@@ -5169,7 +5410,7 @@ function isEntityObject(obj) {
|
|
|
5169
5410
|
init_MineRenderError();
|
|
5170
5411
|
|
|
5171
5412
|
// src/export/SceneExporter.ts
|
|
5172
|
-
import { ClampToEdgeWrapping as ClampToEdgeWrapping2, Color as Color7, Float32BufferAttribute as Float32BufferAttribute3, Matrix4 as
|
|
5413
|
+
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
5414
|
|
|
5174
5415
|
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
5175
5416
|
import {
|
|
@@ -5595,7 +5836,7 @@ import {
|
|
|
5595
5836
|
LinearMipmapLinearFilter,
|
|
5596
5837
|
LinearMipmapNearestFilter,
|
|
5597
5838
|
MathUtils as MathUtils2,
|
|
5598
|
-
Matrix4 as
|
|
5839
|
+
Matrix4 as Matrix46,
|
|
5599
5840
|
MirroredRepeatWrapping,
|
|
5600
5841
|
NearestFilter as NearestFilter2,
|
|
5601
5842
|
NearestMipmapLinearFilter,
|
|
@@ -6885,7 +7126,7 @@ var GLTFWriter = class {
|
|
|
6885
7126
|
if (rootJoint === void 0) return null;
|
|
6886
7127
|
const joints = [];
|
|
6887
7128
|
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
6888
|
-
const temporaryBoneInverse = new
|
|
7129
|
+
const temporaryBoneInverse = new Matrix46();
|
|
6889
7130
|
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
6890
7131
|
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
6891
7132
|
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
@@ -7351,7 +7592,7 @@ var GLTFMeshGpuInstancing = class {
|
|
|
7351
7592
|
const translationAttr = new Float32Array(mesh.count * 3);
|
|
7352
7593
|
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
7353
7594
|
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
7354
|
-
const matrix = new
|
|
7595
|
+
const matrix = new Matrix46();
|
|
7355
7596
|
const position = new Vector38();
|
|
7356
7597
|
const quaternion = new Quaternion4();
|
|
7357
7598
|
const scale = new Vector38();
|
|
@@ -7525,7 +7766,7 @@ var SceneExporter = class {
|
|
|
7525
7766
|
}
|
|
7526
7767
|
};
|
|
7527
7768
|
function localMatrix(object) {
|
|
7528
|
-
return object.matrixAutoUpdate ? new
|
|
7769
|
+
return object.matrixAutoUpdate ? new Matrix47().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
|
|
7529
7770
|
}
|
|
7530
7771
|
function createSnapshot(root, gltf, bakeColors = false) {
|
|
7531
7772
|
const scene = new Scene4();
|
|
@@ -7637,7 +7878,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7637
7878
|
const instanced = mesh;
|
|
7638
7879
|
if (instanced.isInstancedMesh) {
|
|
7639
7880
|
for (let i = 0; i < instanced.count; i++) {
|
|
7640
|
-
const matrix = new
|
|
7881
|
+
const matrix = new Matrix47();
|
|
7641
7882
|
instanced.getMatrixAt(i, matrix);
|
|
7642
7883
|
const color = instanced.instanceColor ? new Color7().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
7643
7884
|
addMesh(mesh, world.clone().multiply(matrix), color);
|
|
@@ -7651,7 +7892,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
7651
7892
|
try {
|
|
7652
7893
|
const ancestors = [];
|
|
7653
7894
|
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
7654
|
-
const world = new
|
|
7895
|
+
const world = new Matrix47();
|
|
7655
7896
|
for (const ancestor of ancestors) {
|
|
7656
7897
|
if (!ancestor.visible) return { scene, dispose };
|
|
7657
7898
|
world.multiply(localMatrix(ancestor));
|
|
@@ -8553,7 +8794,7 @@ var import_ts_deepmerge6 = __toESM(require_dist());
|
|
|
8553
8794
|
init_MineRenderError();
|
|
8554
8795
|
init_InstanceReference();
|
|
8555
8796
|
init_AssetKey();
|
|
8556
|
-
import { Euler as Euler8, Matrix4 as
|
|
8797
|
+
import { Euler as Euler8, Matrix4 as Matrix49, Quaternion as Quaternion5, Vector3 as Vector311 } from "three";
|
|
8557
8798
|
init_ModelCulling();
|
|
8558
8799
|
init_FluidGeometry();
|
|
8559
8800
|
var BlockObject = class _BlockObject extends SceneObject {
|
|
@@ -8570,6 +8811,9 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8570
8811
|
this._variants = [];
|
|
8571
8812
|
this._models = [];
|
|
8572
8813
|
this._cullMask = 0;
|
|
8814
|
+
this._entities = [];
|
|
8815
|
+
this._entityPlacement = new Matrix49();
|
|
8816
|
+
this._entityGeneration = 0;
|
|
8573
8817
|
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
8574
8818
|
}
|
|
8575
8819
|
static {
|
|
@@ -8594,6 +8838,8 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8594
8838
|
}
|
|
8595
8839
|
clearModels() {
|
|
8596
8840
|
this.removeModels(this._models.splice(0));
|
|
8841
|
+
this._entityGeneration++;
|
|
8842
|
+
this.removeEntities(this._entities.splice(0));
|
|
8597
8843
|
this._fluidKey = void 0;
|
|
8598
8844
|
this._fluidModel = void 0;
|
|
8599
8845
|
this._isInstanced = false;
|
|
@@ -8605,6 +8851,57 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8605
8851
|
if (!isInstanceReference(model)) model.dispose();
|
|
8606
8852
|
}
|
|
8607
8853
|
}
|
|
8854
|
+
removeEntities(entities) {
|
|
8855
|
+
for (const entity of entities) {
|
|
8856
|
+
entity.removeFromScene();
|
|
8857
|
+
entity.dispose();
|
|
8858
|
+
}
|
|
8859
|
+
}
|
|
8860
|
+
/** Entity models drawn for this block instead of its block model; they are scene children, unlike the block. */
|
|
8861
|
+
get blockEntities() {
|
|
8862
|
+
return this._entities;
|
|
8863
|
+
}
|
|
8864
|
+
/**
|
|
8865
|
+
* Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
|
|
8866
|
+
* when the block is not listed or one of its models cannot be loaded.
|
|
8867
|
+
*/
|
|
8868
|
+
async createBlockEntities() {
|
|
8869
|
+
const key = this.blockState.key;
|
|
8870
|
+
if (!key || this.options.displayPosition) return false;
|
|
8871
|
+
const generation = this._entityGeneration;
|
|
8872
|
+
const created = [];
|
|
8873
|
+
let resolved;
|
|
8874
|
+
try {
|
|
8875
|
+
resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);
|
|
8876
|
+
if (!resolved) return false;
|
|
8877
|
+
for (const part of resolved.parts) {
|
|
8878
|
+
const [namespace, path] = part.model.includes(":") ? part.model.split(":") : [key.namespace, part.model];
|
|
8879
|
+
const texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
8880
|
+
if (texture) texture.root = key.root;
|
|
8881
|
+
const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });
|
|
8882
|
+
if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);
|
|
8883
|
+
created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }));
|
|
8884
|
+
}
|
|
8885
|
+
} catch (error) {
|
|
8886
|
+
console.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
|
|
8887
|
+
this.removeEntities(created);
|
|
8888
|
+
return false;
|
|
8889
|
+
}
|
|
8890
|
+
if (generation !== this._entityGeneration) {
|
|
8891
|
+
this.removeEntities(created);
|
|
8892
|
+
return true;
|
|
8893
|
+
}
|
|
8894
|
+
BlockEntities.matrix(resolved, this._entityPlacement);
|
|
8895
|
+
this._entities = created;
|
|
8896
|
+
this.placeEntities();
|
|
8897
|
+
return true;
|
|
8898
|
+
}
|
|
8899
|
+
placeEntities() {
|
|
8900
|
+
const matrix = new Matrix49().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
|
|
8901
|
+
for (const entity of this._entities) {
|
|
8902
|
+
matrix.decompose(entity.position, entity.quaternion, entity.scale);
|
|
8903
|
+
}
|
|
8904
|
+
}
|
|
8608
8905
|
get isOccluding() {
|
|
8609
8906
|
return this._models.some((model) => {
|
|
8610
8907
|
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
@@ -8686,7 +8983,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8686
8983
|
() => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
|
|
8687
8984
|
);
|
|
8688
8985
|
const previous = this._fluidModel;
|
|
8689
|
-
const matrix = previous ? this.getModelMatrix(previous) : new
|
|
8986
|
+
const matrix = previous ? this.getModelMatrix(previous) : new Matrix49().makeTranslation(...this.position.toArray());
|
|
8690
8987
|
if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
|
|
8691
8988
|
else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
8692
8989
|
this._models = this._models.filter((model) => model !== previous);
|
|
@@ -8716,13 +9013,20 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8716
9013
|
await this.updateFluid(this._fluidSampler);
|
|
8717
9014
|
return;
|
|
8718
9015
|
}
|
|
9016
|
+
const hasEntities = await this.createBlockEntities();
|
|
8719
9017
|
const variantsToCreate = await this.mapStateToVariant(this.state);
|
|
8720
9018
|
this._variants = variantsToCreate;
|
|
8721
9019
|
for (let blockStateVariant of variantsToCreate) {
|
|
9020
|
+
if (hasEntities && !await this.hasGeometry(blockStateVariant)) continue;
|
|
8722
9021
|
this._models.push(await this.createVariant(blockStateVariant));
|
|
8723
9022
|
}
|
|
8724
9023
|
await this.updateFluid(this._fluidSampler);
|
|
8725
9024
|
}
|
|
9025
|
+
async hasGeometry(variant) {
|
|
9026
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
9027
|
+
modelKey.root = this.blockState.key?.root;
|
|
9028
|
+
return !!(await Models.getMerged(modelKey))?.elements?.length;
|
|
9029
|
+
}
|
|
8726
9030
|
getSingleVariant(variants) {
|
|
8727
9031
|
return BlockStateResolver.choose(variants);
|
|
8728
9032
|
}
|
|
@@ -8817,7 +9121,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8817
9121
|
setPositionRotationScaleAt(index, position, rotation, scale) {
|
|
8818
9122
|
super.setPositionRotationScaleAt(index, position, rotation, scale);
|
|
8819
9123
|
}
|
|
8820
|
-
getMatrixAt(index, matrix = new
|
|
9124
|
+
getMatrixAt(index, matrix = new Matrix49()) {
|
|
8821
9125
|
if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
|
|
8822
9126
|
const child = this._models[0];
|
|
8823
9127
|
if (child && isModelObject(child)) {
|
|
@@ -8842,6 +9146,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
8842
9146
|
for (let model of this._models) {
|
|
8843
9147
|
model.setPosition(position);
|
|
8844
9148
|
}
|
|
9149
|
+
this.placeEntities();
|
|
8845
9150
|
this.notifyDirty();
|
|
8846
9151
|
}
|
|
8847
9152
|
//TODO: should override rotation + scale methods
|
|
@@ -13379,7 +13684,7 @@ init_CubeFace();
|
|
|
13379
13684
|
init_AssetKey();
|
|
13380
13685
|
init_Models();
|
|
13381
13686
|
init_CubeFace();
|
|
13382
|
-
import { Matrix4 as
|
|
13687
|
+
import { Matrix4 as Matrix410, Vector3 as Vector314 } from "three";
|
|
13383
13688
|
init_ModelCulling();
|
|
13384
13689
|
init_ModelObject();
|
|
13385
13690
|
init_UVMapper();
|
|
@@ -13442,7 +13747,7 @@ var SectionModels = class {
|
|
|
13442
13747
|
});
|
|
13443
13748
|
await object.init();
|
|
13444
13749
|
const geometry = object.children[0].geometry;
|
|
13445
|
-
geometry.applyMatrix4(new
|
|
13750
|
+
geometry.applyMatrix4(new Matrix410().makeRotationFromEuler(rotation));
|
|
13446
13751
|
object.clear();
|
|
13447
13752
|
const cullFaces = CUBE_FACES.map((face) => {
|
|
13448
13753
|
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
@@ -13854,7 +14159,8 @@ var Chunk = class _Chunk {
|
|
|
13854
14159
|
this.data.set(index, void 0);
|
|
13855
14160
|
return void 0;
|
|
13856
14161
|
}
|
|
13857
|
-
const
|
|
14162
|
+
const perBlock = !this.sectionModels || getFluidKind(blockState.key, stored.properties) || blockState.key && BlockEntities.entry(await BlockEntities.getIndex(blockState.key.root), blockState.key.toNamespacedString());
|
|
14163
|
+
const template = perBlock ? void 0 : await this.sectionModels.get(blockState, stored.properties);
|
|
13858
14164
|
if (template) {
|
|
13859
14165
|
this.sectionBlocks.set(index, { index, template, cullMask: 0 });
|
|
13860
14166
|
this.meshDirty = true;
|
|
@@ -13963,6 +14269,7 @@ export {
|
|
|
13963
14269
|
BUILTIN_GENERATED,
|
|
13964
14270
|
BasicAssetKey,
|
|
13965
14271
|
BatchedExecutor,
|
|
14272
|
+
BlockEntities,
|
|
13966
14273
|
BlockObject,
|
|
13967
14274
|
BlockStateResolver,
|
|
13968
14275
|
BlockStates,
|
|
@@ -13984,7 +14291,9 @@ export {
|
|
|
13984
14291
|
DefaultBlockStates,
|
|
13985
14292
|
DisplayPosition,
|
|
13986
14293
|
DisplayTransforms,
|
|
14294
|
+
ENTITY_ANIMATION_CHANNELS,
|
|
13987
14295
|
Entities,
|
|
14296
|
+
EntityAnimationPlayer,
|
|
13988
14297
|
EntityObject,
|
|
13989
14298
|
Env,
|
|
13990
14299
|
FluidModelObject,
|
|
@@ -14060,6 +14369,7 @@ export {
|
|
|
14060
14369
|
createCanvas2 as createCanvas,
|
|
14061
14370
|
createFluidGeometry,
|
|
14062
14371
|
createImage,
|
|
14372
|
+
entityAnimationTime,
|
|
14063
14373
|
estimateBytesUsed,
|
|
14064
14374
|
getBlockFluidState,
|
|
14065
14375
|
getFluidKind,
|
|
@@ -14092,6 +14402,8 @@ export {
|
|
|
14092
14402
|
mergeVertices,
|
|
14093
14403
|
prefix,
|
|
14094
14404
|
registerNodeEnv,
|
|
14405
|
+
sampleEntityAnimation,
|
|
14406
|
+
sampleEntityKeyframes,
|
|
14095
14407
|
sampleFluid,
|
|
14096
14408
|
serializeBoxGeometryKey,
|
|
14097
14409
|
serializeImageKey,
|