Animation rows can target behavior variables and shader parameters (#104)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b278605c53
commit
beeea355d9
9 files changed
+273
-77
No files matched your search
@@ -1,12 +1,12 @@
|
||||
import { newId } from '../ids';
|
||||
import {
|
||||
ANIMATION_ROOT_TYPES,
|
||||
animatableDefs,
|
||||
animatedKind,
|
||||
blends,
|
||||
isKeyInterpolation,
|
||||
normalizeKeys,
|
||||
targetAssetOf,
|
||||
targetDefs,
|
||||
trackDef,
|
||||
trackValueAt,
|
||||
} from '../model/animation';
|
||||
import type { AnimationAsset, AnimationKey, AnimationTrack, KeyInterpolation } from '../model/Asset';
|
||||
@@ -42,10 +42,13 @@ function requireAnimatable(
|
||||
property: string,
|
||||
): string {
|
||||
if (!findAsset(project, asset.root)) throw new CommandError(`${asset.name} has nothing to animate yet`);
|
||||
const aimed = targetAssetOf(project, asset, target);
|
||||
if (!aimed) throw new CommandError('That object is not part of the animated asset');
|
||||
const kind = animatedKind(aimed.type, property);
|
||||
if (!kind) throw new CommandError(`${aimed.name} has no property ${property} to animate`);
|
||||
const defs = targetDefs(project, asset, target);
|
||||
if (!defs) throw new CommandError('That object is not part of the animated asset');
|
||||
const kind = defs.find((d) => d.key === property)?.kind;
|
||||
if (!kind)
|
||||
throw new CommandError(
|
||||
`${targetAssetOf(project, asset, target)?.name} has no property ${property} to animate`,
|
||||
);
|
||||
return kind;
|
||||
}
|
||||
|
||||
@@ -163,8 +166,7 @@ export class RetargetAnimationTrackCommand extends TimelineCommand {
|
||||
protected apply(project: Project, asset: AnimationAsset): void {
|
||||
const track = requireTrack(asset, this.trackId);
|
||||
const kind = requireAnimatable(project, asset, this.target, this.property);
|
||||
const aimed = targetAssetOf(project, asset, track.target);
|
||||
const was = aimed ? animatedKind(aimed.type, track.property) : undefined;
|
||||
const was = trackDef(project, asset, track)?.kind;
|
||||
if (was !== undefined && was !== kind) throw new CommandError(`A ${was} row cannot become a ${kind} row`);
|
||||
requireUnique(asset, this.target, this.property, track.id);
|
||||
track.target = this.target;
|
||||
@@ -217,8 +219,7 @@ export class SetAnimationKeyCommand extends TimelineCommand {
|
||||
const track = requireTrack(asset, this.trackId);
|
||||
if (!Number.isInteger(this.frame) || this.frame < 0)
|
||||
throw new CommandError('A key sits on a whole frame from 0');
|
||||
const aimed = targetAssetOf(project, asset, track.target);
|
||||
const def = aimed && animatableDefs(aimed.type).find((d) => d.key === track.property);
|
||||
const def = trackDef(project, asset, track);
|
||||
if (!def) throw new CommandError('The row aims at something that is gone');
|
||||
const current = trackValueAt(track.keys, def.kind, this.frame);
|
||||
const raw = this.value ?? current ?? (track.relative ? 0 : def.default);
|
||||
@@ -252,8 +253,7 @@ export class SetKeyInterpolationCommand extends TimelineCommand {
|
||||
const track = requireTrack(asset, ref.trackId);
|
||||
const key = track.keys.find((k) => k.frame === ref.frame);
|
||||
if (!key) throw new CommandError(`No key on frame ${ref.frame}`);
|
||||
const aimed = targetAssetOf(project, asset, track.target);
|
||||
const kind = aimed ? animatedKind(aimed.type, track.property) : undefined;
|
||||
const kind = trackDef(project, asset, track)?.kind;
|
||||
if (kind !== undefined && !blends(kind)) continue;
|
||||
if (this.interpolation === 'linear') delete key.interpolation;
|
||||
else key.interpolation = this.interpolation;
|
||||
|
||||
Reference in new issue
Block a user