minerender 2.1.0-alpha.131 → 2.1.0-alpha.132
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/esm/entity/scene/EntityAnimationPlayer.mjs +62 -11
- package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityObject.mjs +53 -20
- package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +28 -7
- package/dist/browser/index.d.ts +28 -7
- package/dist/browser/index.js +112 -28
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +112 -28
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +28 -7
- package/dist/node/index.d.ts +28 -7
- package/dist/node/index.js +113 -28
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +112 -28
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -84835,6 +84835,13 @@ ${key}` : key;
|
|
|
84835
84835
|
});
|
|
84836
84836
|
|
|
84837
84837
|
// src/entity/scene/EntityAnimationPlayer.ts
|
|
84838
|
+
function validateAnimationWeights(weights, count) {
|
|
84839
|
+
const values = Array.from(weights);
|
|
84840
|
+
if (values.length !== count || values.some((weight) => !Number.isFinite(weight) || weight < 0)) {
|
|
84841
|
+
throw new Error("Animation weights must match the clip count and contain only finite nonnegative numbers");
|
|
84842
|
+
}
|
|
84843
|
+
return values;
|
|
84844
|
+
}
|
|
84838
84845
|
var ZERO, EntityAnimationPlayer;
|
|
84839
84846
|
var init_EntityAnimationPlayer = __esm({
|
|
84840
84847
|
"src/entity/scene/EntityAnimationPlayer.ts"() {
|
|
@@ -84847,12 +84854,20 @@ ${key}` : key;
|
|
|
84847
84854
|
EntityAnimationPlayer = class {
|
|
84848
84855
|
constructor() {
|
|
84849
84856
|
this.parts = [];
|
|
84857
|
+
this._animations = [];
|
|
84858
|
+
this._weights = [];
|
|
84859
|
+
this.loops = [];
|
|
84850
84860
|
this._time = 0;
|
|
84851
|
-
this.loop = false;
|
|
84852
84861
|
this.speed = 1;
|
|
84853
84862
|
}
|
|
84854
84863
|
get animation() {
|
|
84855
|
-
return this.
|
|
84864
|
+
return this._animations[0];
|
|
84865
|
+
}
|
|
84866
|
+
get animations() {
|
|
84867
|
+
return this._animations.slice();
|
|
84868
|
+
}
|
|
84869
|
+
get weights() {
|
|
84870
|
+
return this._weights.slice();
|
|
84856
84871
|
}
|
|
84857
84872
|
get time() {
|
|
84858
84873
|
return this._time;
|
|
@@ -84862,10 +84877,20 @@ ${key}` : key;
|
|
|
84862
84877
|
* without them, the current pose is used. Stopping restores the pose from before playback.
|
|
84863
84878
|
*/
|
|
84864
84879
|
play(layers, animation, options = {}, poses) {
|
|
84880
|
+
this.playAnimations(layers, [animation], options, poses);
|
|
84881
|
+
}
|
|
84882
|
+
/**
|
|
84883
|
+
* Starts clips on matching parts with a shared clock. Weighted offsets add to the supplied baked poses
|
|
84884
|
+
* or, without poses, to each animated part's pose when playback starts.
|
|
84885
|
+
*/
|
|
84886
|
+
playAnimations(layers, animations, options = {}, poses) {
|
|
84887
|
+
const weights = validateAnimationWeights(options.weights ?? animations.map(() => 1), animations.length);
|
|
84865
84888
|
this.stop();
|
|
84866
|
-
this.
|
|
84889
|
+
this._animations = animations.slice();
|
|
84890
|
+
this._weights = weights;
|
|
84891
|
+
if (!animations.length) return;
|
|
84867
84892
|
this._time = options.time ?? 0;
|
|
84868
|
-
this.
|
|
84893
|
+
this.loops = animations.map((animation) => options.loop ?? animation.loop);
|
|
84869
84894
|
this.speed = options.speed ?? 1;
|
|
84870
84895
|
for (const layer of layers) {
|
|
84871
84896
|
const objects = [];
|
|
@@ -84874,7 +84899,8 @@ ${key}` : key;
|
|
|
84874
84899
|
if (poses.has(object4)) objects.push(object4);
|
|
84875
84900
|
});
|
|
84876
84901
|
} else {
|
|
84877
|
-
|
|
84902
|
+
const bones = new Set(animations.flatMap((animation) => Object.keys(animation.bones)));
|
|
84903
|
+
for (const bone of bones) {
|
|
84878
84904
|
const object4 = layer.getObjectByName(`group:${bone}`);
|
|
84879
84905
|
if (object4) objects.push(object4);
|
|
84880
84906
|
}
|
|
@@ -84898,7 +84924,7 @@ ${key}` : key;
|
|
|
84898
84924
|
}
|
|
84899
84925
|
/** Restores the poses from before playback. Returns whether an animation was active. */
|
|
84900
84926
|
stop() {
|
|
84901
|
-
if (!this.
|
|
84927
|
+
if (!this._animations.length) return false;
|
|
84902
84928
|
for (const part of this.parts) {
|
|
84903
84929
|
part.object.position.copy(part.position);
|
|
84904
84930
|
part.object.rotation.copy(part.rotation);
|
|
@@ -84910,12 +84936,14 @@ ${key}` : key;
|
|
|
84910
84936
|
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
84911
84937
|
clear() {
|
|
84912
84938
|
this.parts = [];
|
|
84913
|
-
this.
|
|
84939
|
+
this._animations = [];
|
|
84940
|
+
this._weights = [];
|
|
84941
|
+
this.loops = [];
|
|
84914
84942
|
this._time = 0;
|
|
84915
84943
|
}
|
|
84916
84944
|
/** Applies the pose at an absolute playback time. Returns `false` when no clip is active. */
|
|
84917
84945
|
setTime(seconds) {
|
|
84918
|
-
if (!this.
|
|
84946
|
+
if (!this._animations.length) return false;
|
|
84919
84947
|
this._time = seconds;
|
|
84920
84948
|
this.apply();
|
|
84921
84949
|
return true;
|
|
@@ -84924,8 +84952,30 @@ ${key}` : key;
|
|
|
84924
84952
|
advance(deltaSeconds) {
|
|
84925
84953
|
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
84926
84954
|
}
|
|
84955
|
+
/** Changes weights in clip order and reapplies the current time without restarting playback. */
|
|
84956
|
+
setWeights(weights) {
|
|
84957
|
+
if (!this._animations.length) return false;
|
|
84958
|
+
const validated = validateAnimationWeights(weights, this._animations.length);
|
|
84959
|
+
this._weights = validated;
|
|
84960
|
+
this.apply();
|
|
84961
|
+
return true;
|
|
84962
|
+
}
|
|
84927
84963
|
apply() {
|
|
84928
|
-
const pose =
|
|
84964
|
+
const pose = /* @__PURE__ */ Object.create(null);
|
|
84965
|
+
for (let i4 = 0; i4 < this._animations.length; i4++) {
|
|
84966
|
+
const weight = this._weights[i4];
|
|
84967
|
+
if (weight === 0) continue;
|
|
84968
|
+
const sampled = sampleEntityAnimation(this._animations[i4], this._time, this.loops[i4]);
|
|
84969
|
+
for (const [bone, channels] of Object.entries(sampled)) {
|
|
84970
|
+
const blended = pose[bone] ?? (pose[bone] = {});
|
|
84971
|
+
for (const channel of ENTITY_ANIMATION_CHANNELS) {
|
|
84972
|
+
const value = channels[channel];
|
|
84973
|
+
if (!value) continue;
|
|
84974
|
+
const target = blended[channel] ?? (blended[channel] = [0, 0, 0]);
|
|
84975
|
+
for (let axis = 0; axis < 3; axis++) target[axis] += value[axis] * weight;
|
|
84976
|
+
}
|
|
84977
|
+
}
|
|
84978
|
+
}
|
|
84929
84979
|
for (const part of this.parts) {
|
|
84930
84980
|
const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone] ?? {};
|
|
84931
84981
|
part.object.position.set(part.basePosition.x + position[0], part.basePosition.y + position[1], part.basePosition.z + position[2]);
|
|
@@ -85554,7 +85604,7 @@ ${key}` : key;
|
|
|
85554
85604
|
for (const geometry of this.geometries) geometry.dispose();
|
|
85555
85605
|
this.geometries.clear();
|
|
85556
85606
|
for (const dispose of this.disposeWireframes.splice(0)) dispose();
|
|
85557
|
-
for (const player of this.animationPlayers.splice(0)) player.clear();
|
|
85607
|
+
for (const { player } of this.animationPlayers.splice(0)) player.clear();
|
|
85558
85608
|
this.partPoses.clear();
|
|
85559
85609
|
super.disposeAndRemoveAllChildren();
|
|
85560
85610
|
}
|
|
@@ -85589,15 +85639,31 @@ ${key}` : key;
|
|
|
85589
85639
|
//<editor-fold desc="ANIMATION">
|
|
85590
85640
|
/** The first active clip, until playback is stopped or the object is disposed. */
|
|
85591
85641
|
get animation() {
|
|
85592
|
-
return this.animationPlayers[0]?.animation;
|
|
85642
|
+
return this.animationPlayers[0]?.player.animation;
|
|
85593
85643
|
}
|
|
85594
|
-
/** Clips playing together,
|
|
85644
|
+
/** Clips playing together, in the order passed to {@link playAnimations}. */
|
|
85595
85645
|
get activeAnimations() {
|
|
85596
|
-
|
|
85646
|
+
const animations = [];
|
|
85647
|
+
for (const { player, indices } of this.animationPlayers) {
|
|
85648
|
+
player.animations.forEach((animation, i4) => {
|
|
85649
|
+
animations[indices[i4]] = animation;
|
|
85650
|
+
});
|
|
85651
|
+
}
|
|
85652
|
+
return animations;
|
|
85653
|
+
}
|
|
85654
|
+
/** Weights of the active clips, in the same order as {@link activeAnimations}. */
|
|
85655
|
+
get animationWeights() {
|
|
85656
|
+
const weights = [];
|
|
85657
|
+
for (const { player, indices } of this.animationPlayers) {
|
|
85658
|
+
player.weights.forEach((weight, i4) => {
|
|
85659
|
+
weights[indices[i4]] = weight;
|
|
85660
|
+
});
|
|
85661
|
+
}
|
|
85662
|
+
return weights;
|
|
85597
85663
|
}
|
|
85598
85664
|
/** Seconds since the animation started, before looping. */
|
|
85599
85665
|
get animationTime() {
|
|
85600
|
-
return this.animationPlayers[0]?.time ?? 0;
|
|
85666
|
+
return this.animationPlayers[0]?.player.time ?? 0;
|
|
85601
85667
|
}
|
|
85602
85668
|
/**
|
|
85603
85669
|
* Plays a clip from {@link Entities.getAnimations}, replacing all active clips.
|
|
@@ -85608,42 +85674,59 @@ ${key}` : key;
|
|
|
85608
85674
|
playAnimation(animation, options) {
|
|
85609
85675
|
this.playAnimations([animation], options);
|
|
85610
85676
|
}
|
|
85611
|
-
/**
|
|
85677
|
+
/**
|
|
85678
|
+
* Plays clips with a shared clock, adding their weighted offsets within each geometry layer.
|
|
85679
|
+
* Weights default to 1 and are not normalized. Selected layers without their own clip follow `main`.
|
|
85680
|
+
*/
|
|
85612
85681
|
playAnimations(animations, options) {
|
|
85613
|
-
const
|
|
85614
|
-
const selections =
|
|
85682
|
+
const weights = validateAnimationWeights(options?.weights ?? animations.map(() => 1), animations.length);
|
|
85683
|
+
const selections = /* @__PURE__ */ new Map();
|
|
85684
|
+
animations.forEach((animation, index) => {
|
|
85615
85685
|
const layer = animation.layer ?? "main";
|
|
85616
|
-
if (targets.has(layer)) throw new Error(`Multiple animations target layer "${layer}"`);
|
|
85617
|
-
targets.add(layer);
|
|
85618
85686
|
const names = Object.keys(this.entityLayers).filter((name2) => name2.split("#")[0] === layer);
|
|
85619
85687
|
if (!names.length) throw new Error(`Entity ${this.entity.id} has no selected animation layer "${layer}"`);
|
|
85620
|
-
|
|
85688
|
+
let selection = selections.get(layer);
|
|
85689
|
+
if (!selection) selections.set(layer, selection = { animations: [], names, indices: [] });
|
|
85690
|
+
selection.animations.push(animation);
|
|
85691
|
+
selection.indices.push(index);
|
|
85621
85692
|
});
|
|
85622
|
-
const main = selections.
|
|
85623
|
-
if (main) main.names.push(...Object.keys(this.entityLayers).filter((name2) => !
|
|
85693
|
+
const main = selections.get("main");
|
|
85694
|
+
if (main) main.names.push(...Object.keys(this.entityLayers).filter((name2) => !selections.has(name2.split("#")[0])));
|
|
85624
85695
|
this.createMeshes();
|
|
85625
85696
|
this.stopAnimation();
|
|
85626
|
-
for (const {
|
|
85697
|
+
for (const { animations: clips, names, indices } of selections.values()) {
|
|
85627
85698
|
const player = new EntityAnimationPlayer();
|
|
85628
|
-
player.
|
|
85629
|
-
|
|
85699
|
+
player.playAnimations(
|
|
85700
|
+
names.map((name2) => this.getLayerGroup(name2)),
|
|
85701
|
+
clips,
|
|
85702
|
+
{ ...options, weights: indices.map((index) => weights[index]) },
|
|
85703
|
+
this.partPoses
|
|
85704
|
+
);
|
|
85705
|
+
this.animationPlayers.push({ player, indices });
|
|
85630
85706
|
}
|
|
85631
85707
|
this.notifyDirty();
|
|
85632
85708
|
}
|
|
85709
|
+
/** Changes weights in active clip order, notifying the scene without restarting the shared clock. Has no effect without an animation. */
|
|
85710
|
+
setAnimationWeights(weights) {
|
|
85711
|
+
if (!this.animationPlayers.length) return;
|
|
85712
|
+
const values = validateAnimationWeights(weights, this.activeAnimations.length);
|
|
85713
|
+
for (const { player, indices } of this.animationPlayers) player.setWeights(indices.map((index) => values[index]));
|
|
85714
|
+
this.notifyDirty();
|
|
85715
|
+
}
|
|
85633
85716
|
/** Stops all clips and restores the poses from before playback. */
|
|
85634
85717
|
stopAnimation() {
|
|
85635
85718
|
const players = this.animationPlayers.splice(0);
|
|
85636
|
-
for (const player of players) player.stop();
|
|
85719
|
+
for (const { player } of players) player.stop();
|
|
85637
85720
|
if (players.length) this.notifyDirty();
|
|
85638
85721
|
}
|
|
85639
85722
|
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
85640
85723
|
setAnimationTime(seconds) {
|
|
85641
|
-
for (const player of this.animationPlayers) player.setTime(seconds);
|
|
85724
|
+
for (const { player } of this.animationPlayers) player.setTime(seconds);
|
|
85642
85725
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
85643
85726
|
}
|
|
85644
85727
|
/** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
|
|
85645
85728
|
advanceAnimation(deltaSeconds) {
|
|
85646
|
-
for (const player of this.animationPlayers) player.advance(deltaSeconds);
|
|
85729
|
+
for (const { player } of this.animationPlayers) player.advance(deltaSeconds);
|
|
85647
85730
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
85648
85731
|
}
|
|
85649
85732
|
//</editor-fold>
|
|
@@ -94105,6 +94188,7 @@ ${shader.fragmentShader}`.replace(
|
|
|
94105
94188
|
toRadians: () => toRadians,
|
|
94106
94189
|
toTrianglesDrawMode: () => toTrianglesDrawMode,
|
|
94107
94190
|
trimCanvas: () => trimCanvas,
|
|
94191
|
+
validateAnimationWeights: () => validateAnimationWeights,
|
|
94108
94192
|
yieldToEventLoop: () => yieldToEventLoop
|
|
94109
94193
|
});
|
|
94110
94194
|
init_dirname();
|