added way of replacing actor models

This commit is contained in:
2026-09-28 18:40:30 +02:00
parent a5e72e1d74
commit f1f597dcca
2 changed files with 224 additions and 5 deletions
+59
View File
@@ -0,0 +1,59 @@
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const vm = require('node:vm');
test('retains all stage tracks when group removal deletes their animation bindings', () => {
const source = fs.readFileSync(path.join(__dirname, '..', 'AnimationDirector.js'), 'utf8').replace(
' Plugin.register(PLUGIN_ID, {',
' globalThis.replacementTest = { captureActorAnimationBindings, removeActorGeometry, rebindActorAnimations };\n Plugin.register(PLUGIN_ID, {'
);
const animations = [];
class Group {
static all = [];
constructor(name, uuid, parent = 'root') {
Object.assign(this, { name, uuid, parent });
Group.all.push(this);
}
remove() {
for (const child of Group.all.filter((group) => group.parent === this)) child.remove();
for (const animation of animations) animation.removeAnimator(this.uuid);
Group.all = Group.all.filter((group) => group !== this);
}
}
const root = new Group('actor1_body', 'old-body');
new Group('actor1_head', 'old-head', root);
new Group('actor1_removed', 'old-removed', root);
new Group('actor2_body', 'other-body');
for (let stage = 1; stage <= 2; stage++) {
const animators = {};
for (const group of Group.all) {
const track = { uuid: group.uuid, _name: group.name, keyframes: [{ time: stage, rotation: [1, 2, 3] }] };
Object.defineProperty(track, 'name', { get() { return this._name; } });
animators[group.uuid] = track;
}
animations.push({ animators, saved: true, removeAnimator(uuid) { delete this.animators[uuid]; } });
}
const originalTracks = animations.map((animation) => ({ ...animation.animators }));
const context = { Group, Animation: { all: animations }, Plugin: { register() {} }, console };
vm.runInNewContext(source, context);
const snapshot = context.replacementTest.captureActorAnimationBindings(1);
context.replacementTest.removeActorGeometry(1);
assert.equal(animations[0].animators['old-body'], undefined);
new Group('actor1_body', 'new-body');
new Group('actor1_head', 'new-head');
const result = context.replacementTest.rebindActorAnimations(1, snapshot);
assert.equal(result.rebound, 4);
assert.equal(result.missing, 2);
animations.forEach((animation, index) => {
assert.equal(animation.animators['new-body'], originalTracks[index]['old-body']);
assert.equal(animation.animators['new-head'], originalTracks[index]['old-head']);
assert.equal(animation.animators['other-body'], originalTracks[index]['other-body']);
assert.equal(animation.animators['old-removed'], originalTracks[index]['old-removed']);
assert.equal(animation.animators['new-body'].uuid, 'new-body');
assert.equal(animation.animators['old-body'], undefined);
assert.equal(animation.saved, false);
assert.deepEqual(animation.animators['new-body'].keyframes, [{ time: index + 1, rotation: [1, 2, 3] }]);
});
});