mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-11-21 01:13:37 +08:00
Merge branch 'root-ik' of https://github.com/TheDrawingCoder-Gamer/blockbench into TheDrawingCoder-Gamer-root-ik
This commit is contained in:
commit
417fc2a5cb
@ -547,14 +547,24 @@ class NullObjectAnimator extends BoneAnimator {
|
||||
let bone_references = [];
|
||||
let current = target.parent;
|
||||
|
||||
let source;
|
||||
if (null_object.ik_source) {
|
||||
source = [...Group.all].find(node => node.uuid == null_object.ik_source);
|
||||
} else {
|
||||
source = null_object.parent;
|
||||
}
|
||||
if (!source) return;
|
||||
if (!target.isChildOf(source)) return;
|
||||
let target_original_quaternion = null_object.lock_ik_target_rotation &&
|
||||
target instanceof Group &&
|
||||
target.mesh.getWorldQuaternion(new THREE.Quaternion());
|
||||
|
||||
while (current !== null_object.parent) {
|
||||
while (current !== source) {
|
||||
bones.push(current);
|
||||
current = current.parent;
|
||||
}
|
||||
if (null_object.ik_source)
|
||||
bones.push(source);
|
||||
if (!bones.length) return;
|
||||
bones.reverse();
|
||||
|
||||
@ -791,4 +801,4 @@ class EffectAnimator extends GeneralAnimator {
|
||||
particle: {name: tl('timeline.particle'), mutable: true, max_data_points: 1000},
|
||||
sound: {name: tl('timeline.sound'), mutable: true, max_data_points: 1000},
|
||||
timeline: {name: tl('timeline.timeline'), mutable: true, max_data_points: 1},
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ class NullObject extends OutlinerElement {
|
||||
NullObject.prototype.needsUniqueName = true;
|
||||
NullObject.prototype.menu = new Menu([
|
||||
'set_ik_target',
|
||||
'set_ik_source',
|
||||
{
|
||||
id: 'lock_ik_target_rotation',
|
||||
name: 'menu.null_object.lock_ik_target_rotation',
|
||||
@ -138,6 +139,7 @@ class NullObject extends OutlinerElement {
|
||||
new Property(NullObject, 'string', 'name', {default: 'null_object'})
|
||||
new Property(NullObject, 'vector', 'position')
|
||||
new Property(NullObject, 'string', 'ik_target', {condition: () => Format.animation_mode});
|
||||
new Property(NullObject, 'string', 'ik_source', {condition: () => Format.animation_mode});
|
||||
new Property(NullObject, 'boolean', 'lock_ik_target_rotation')
|
||||
new Property(NullObject, 'boolean', 'visibility', {default: true});
|
||||
new Property(NullObject, 'boolean', 'locked');
|
||||
@ -257,4 +259,45 @@ BARS.defineActions(function() {
|
||||
new Menu('set_ik_target', this.children(this), {searchable: true}).show(event.target, this);
|
||||
}
|
||||
})
|
||||
|
||||
new Action('set_ik_source', {
|
||||
icon: 'fa-link',
|
||||
category: 'edit',
|
||||
condition() {
|
||||
let action = BarItems.set_ik_source;
|
||||
return NullObject.selected.length && action.children(action).length
|
||||
},
|
||||
searchable: true,
|
||||
children() {
|
||||
let nodes = [];
|
||||
iterate(Outliner.root)
|
||||
|
||||
function iterate(arr) {
|
||||
arr.forEach(node => {
|
||||
if (node instanceof Group) {
|
||||
nodes.push(node);
|
||||
iterate(node.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
return nodes.map(node => {
|
||||
return {
|
||||
name: node.name + (node.uuid == NullObject.selected[0].ik_source ? ' (✔)' : ''),
|
||||
icon: node instanceof Locator ? 'fa-anchor' : 'folder',
|
||||
color: markerColors[node.color % markerColors.length] && markerColors[node.color % markerColors.length].standard,
|
||||
click() {
|
||||
Undo.initEdit({elements: NullObject.selected});
|
||||
NullObject.selected.forEach(null_object => {
|
||||
null_object.ik_source = node.uuid;
|
||||
})
|
||||
Undo.finishEdit('Set IK source');
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
click(event) {
|
||||
new Menu('set_ik_source', this.children(this), {searchable: true}).show(event.target, this);
|
||||
}
|
||||
|
||||
})
|
||||
})
|
||||
|
File diff suppressed because one or more lines are too long
@ -1620,6 +1620,8 @@
|
||||
"action.timeline_focus.hide_empty": "Hide empty channels",
|
||||
"action.set_ik_target": "Set IK Target",
|
||||
"action.set_ik_target.desc": "Select the target bone that should be moved by this null object via Inverse Kinematics",
|
||||
"action.set_ik_source": "Set IK Root",
|
||||
"action.set_ik_source.desc": "Select the root bone of the chain that should be moved by this null object via Inverse Kinematics",
|
||||
"action.lock_motion_trail": "Lock Motion Trail",
|
||||
"action.lock_motion_trail.desc": "Lock the motion trail to the currently selected group",
|
||||
"action.looped_animation_playback": "Looped Playback",
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user