mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-02-17 16:20:13 +08:00
Fix #1534 Flip Animation is missing starting keyframe
Improve smooth keyframe validation, closes #1542
This commit is contained in:
parent
1024a4b008
commit
9f1061f305
@ -1012,17 +1012,34 @@ BARS.defineActions(function() {
|
||||
opposite_animator = Animation.selected.getBoneAnimator(opposite_bone);
|
||||
}
|
||||
|
||||
let center_keyframe;
|
||||
if (formResult.offset && !kfs.find(kf => Math.epsilon(kf.time, Timeline.snapTime(Animation.selected.length/2), 0.004))) {
|
||||
center_keyframe = animator.createKeyframe(null, Timeline.snapTime(Animation.selected.length/2), channel, false, false);
|
||||
kfs.push(center_keyframe);
|
||||
}
|
||||
kfs.sort((a, b) => a.time - b.time);
|
||||
let occupied_times = [];
|
||||
kfs.forEach(old_kf => {
|
||||
let time = old_kf.time;
|
||||
if (formResult.offset) {
|
||||
time = (time + Animation.selected.length/2) % (Animation.selected.length + 0.001);
|
||||
}
|
||||
let new_kf = opposite_animator.createKeyframe(old_kf, Timeline.snapTime(time), channel, false, false)
|
||||
time = Timeline.snapTime(time);
|
||||
if (occupied_times.includes(time)) return;
|
||||
occupied_times.push(time);
|
||||
let new_kf = opposite_animator.createKeyframe(old_kf, time, channel, false, false)
|
||||
if (new_kf) {
|
||||
new_kf.flip(0);
|
||||
new_keyframes.push(new_kf);
|
||||
}
|
||||
})
|
||||
if (formResult.offset && !occupied_times.includes(0)) {
|
||||
let new_kf = opposite_animator.createKeyframe(new_keyframes.last(), 0, channel, false, false)
|
||||
if (new_kf) {
|
||||
new_keyframes.push(new_kf);
|
||||
}
|
||||
}
|
||||
if (center_keyframe) center_keyframe.remove();
|
||||
})
|
||||
if (formResult.show_in_timeline && opposite_animator) {
|
||||
opposite_animator.addToTimeline();
|
||||
|
@ -189,6 +189,16 @@ new ValidatorCheck('catmullrom_keyframes', {
|
||||
condition: {features: ['animation_files']},
|
||||
update_triggers: ['update_keyframe_selection'],
|
||||
run() {
|
||||
function getButtons(kf) {
|
||||
return [{
|
||||
name: 'Reveal Keyframe',
|
||||
icon: 'icon-keyframe',
|
||||
click() {
|
||||
Dialog.open.close();
|
||||
kf.showInTimeline();
|
||||
}
|
||||
}]
|
||||
}
|
||||
Animation.all.forEach(animation => {
|
||||
for (let key in animation.animators) {
|
||||
let animator = animation.animators[key];
|
||||
@ -201,30 +211,42 @@ new ValidatorCheck('catmullrom_keyframes', {
|
||||
if (kf.interpolation == 'catmullrom') {
|
||||
if (kf.data_points.find(dp => isNaN(dp.x) || isNaN(dp.y) || isNaN(dp.z))) {
|
||||
this.fail({
|
||||
message: `${animator.channels[channel].name} keyframe at ${kf.time.toFixed(2)} on "${animator.name}" in "${animation.name}" contains non-numeric value. Smooth keyframes cannot contain math expressions.`,
|
||||
buttons: [{
|
||||
name: 'Reveal Keyframe',
|
||||
icon: 'icon-keyframe',
|
||||
click() {
|
||||
Dialog.open.close();
|
||||
kf.showInTimeline();
|
||||
}
|
||||
}]
|
||||
message: `${animator.channels[channel].name} keyframe at ${kf.time.toFixed(2)} on "${animator.name}" in "${animation.name}" contains non-numeric values. Smooth keyframes cannot contain math expressions.`,
|
||||
buttons: getButtons(kf)
|
||||
})
|
||||
|
||||
}
|
||||
if ((!keyframes[i-1] || keyframes[i-1].interpolation != 'catmullrom') && (!keyframes[i+1] || keyframes[i+1].interpolation != 'catmullrom')) {
|
||||
this.warn({
|
||||
message: `${animator.channels[channel].name} keyframe at ${kf.time.toFixed(2)} on "${animator.name}" in "${animation.name}" is not surrounded by smooth keyframes. Multiple smooth keyframes are required to create a smooth spline.`,
|
||||
buttons: [{
|
||||
name: 'Reveal Keyframe',
|
||||
icon: 'icon-keyframe',
|
||||
click() {
|
||||
Dialog.open.close();
|
||||
kf.showInTimeline();
|
||||
}
|
||||
}]
|
||||
buttons: getButtons(kf)
|
||||
})
|
||||
|
||||
} else if (!keyframes[i+1] && animation.length && (kf.time+0.01) < animation.length && kf.data_points.find(dp => parseFloat(dp.x) || parseFloat(dp.y) || parseFloat(dp.z))) {
|
||||
this.warn({
|
||||
message: `${animator.channels[channel].name} keyframe at ${kf.time.toFixed(2)} on "${animator.name}" in "${animation.name}" is the last smooth keyframe, but does not line up with the end of the animation. The last keyframe should either be linear, or line up with the animation end.`,
|
||||
buttons: getButtons(kf)
|
||||
})
|
||||
|
||||
}
|
||||
} else if (keyframes[i+1] && keyframes[i+1].interpolation == 'catmullrom' && kf.data_points.find(dp => isNaN(dp.x) || isNaN(dp.y) || isNaN(dp.z))) {
|
||||
this.fail({
|
||||
message: `${animator.channels[channel].name} keyframe at ${kf.time.toFixed(2)} on "${animator.name}" in "${animation.name}" contains non-numeric values. Keyframes that are adjacent to smooth keyframes cannot contain math expressions.`,
|
||||
buttons: getButtons(kf)
|
||||
})
|
||||
|
||||
} else if (keyframes[i-1] && keyframes[i-1].interpolation == 'catmullrom' && kf.data_points.find(dp => isNaN(dp.x) || isNaN(dp.y) || isNaN(dp.z))) {
|
||||
this.fail({
|
||||
message: `${animator.channels[channel].name} keyframe at ${kf.time.toFixed(2)} on "${animator.name}" in "${animation.name}" contains non-numeric values. Keyframes that are adjacent to smooth keyframes cannot contain math expressions.`,
|
||||
buttons: getButtons(kf)
|
||||
})
|
||||
|
||||
} else if (keyframes[i-2] && keyframes[i-2].interpolation == 'catmullrom' && kf.data_points.find(dp => isNaN(dp.x) || isNaN(dp.y) || isNaN(dp.z))) {
|
||||
this.warn({
|
||||
message: `${animator.channels[channel].name} keyframe at ${kf.time.toFixed(2)} on "${animator.name}" in "${animation.name}" contains non-numeric values. Keyframes that are adjacent to smooth keyframes cannot contain math expressions.`,
|
||||
buttons: getButtons(kf)
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1603,7 +1603,7 @@
|
||||
"menu.animation.properties": "Properties...",
|
||||
"menu.animation.file": "File",
|
||||
"menu.animation.snapping": "Snapping",
|
||||
"menu.animation.open_location": "Open File Location",
|
||||
"menu.animation.open_location": "Show in File Explorer",
|
||||
"menu.animation.unload": "Unload",
|
||||
"menu.animation.flip_keyframes": "Flip Keyframes",
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user