forked from JannisX11/blockbench-plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathposekey.js
More file actions
103 lines (83 loc) · 3.94 KB
/
posekey.js
File metadata and controls
103 lines (83 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
(function() {
let action_posekey;
function getAllDescendants(groups) {
let all_groups = [];
function recurse(arr) {
arr.forEach(item => {
if (item.type === 'group') {
if (!all_groups.includes(item)) all_groups.push(item);
if (item.children && item.children.length > 0) recurse(item.children);
}
});
}
recurse(groups);
return all_groups;
}
BBPlugin.register('posekey', {
title: 'PoseKey',
author: 'FroXaL',
icon: 'key',
description: 'Adds a single keyframe (position, rotation, scale) at the current timeline position for all selected groups and their descendants. Useful for quickly setting key poses without affecting other keyframes.',
version: '3.0.0',
variant: 'both',
onload() {
action_posekey = new Action('pose_key_action_id', {
name: 'PoseKey',
description: 'Unique P+R+S keyframe at cursor',
icon: 'key',
category: 'animation',
condition: () => Animator.open,
click: function() {
let anim = Animator.animation;
if (!anim && Animation.selected) anim = Animation.selected;
if (!anim) {
Blockbench.showQuickMessage("⚠️ No active animation!");
return;
}
let selection_base = [];
if (Group.selected.length > 0) selection_base.push(...Group.selected);
if (Cube.selected.length > 0) {
Cube.selected.forEach(cube => {
if (cube.parent && cube.parent.type === 'group') {
if (!selection_base.includes(cube.parent)) selection_base.push(cube.parent);
}
});
}
if (selection_base.length === 0) {
Blockbench.showQuickMessage("⚠️ Select an object!");
return;
}
let final_targets = getAllDescendants(selection_base);
Undo.initEdit({animations: [anim]});
let currentTime = Timeline.time;
final_targets.forEach(group => {
let uuid = group.uuid;
let bone_animator = anim.animators[uuid];
if (!bone_animator) {
bone_animator = new GeneralAnimator(uuid, anim);
bone_animator.init();
anim.animators[uuid] = bone_animator;
}
['position', 'rotation', 'scale'].forEach(channel => {
let channel_array = bone_animator[channel];
let was_empty = channel_array.length === 0;
bone_animator.getOrMakeKeyframe(channel, currentTime);
if (was_empty && currentTime > 0 && channel_array.length > 1) {
let key_at_zero = channel_array.find(k => k.time === 0);
if (key_at_zero) {
key_at_zero.remove();
}
}
});
});
Undo.finishEdit('PoseKey', {animations: [anim]});
if (Animator.open) Animator.preview();
Blockbench.showQuickMessage(`🔑 Unique keyframe set on ${final_targets.length} groups!`);
}
});
},
onunload() {
if (action_posekey) action_posekey.delete();
}
});
})();