-
Notifications
You must be signed in to change notification settings - Fork 7
Heck Animation Baking
- You should read Transform Utilities to understand how
rm.Transformstructures work.
The baking system is used to generate a new animation from an old one by sampling it at small intervals.
The reason this could be useful is that you get to define what happens at every moment, when usually you're relying on the game to interpolate the animation.
- Note: It is unlikely you will be using the baking system directly, as it's usually used internally for much easier and user friendly solutions like
rm.emulateParent(see Transform-Utilities). But it's still important to understand what is happening when I say an animation is "baked"!
Let's look at an example.
We want to rotate a wall around it's center. The issue is that the wall's anchor point is somewhere on the edge of it, not in the center.
If we just try a start and end point, it'll end up like this:

Instead, we need to include more points in our animation to describe our path more accurately.

The more points, the more accurate the animation.
The rm.bakeAnimation function will take in an animated Transform, and return a new one which has been generated by sampling the first one at small intervals.
Code Example
const animation: rm.AnimatedTransform = {
position: [[0, 0, 0, 0], [0, 10, 0, 1, 'easeInOutExpo']],
}
rm.bakeAnimation(animation)
/*
{
position: [
[ 0, 0, 0, 0 ],
[ 0, 0.007636299408441899, 0, 0.03225806451612903 ],
...
],
rotation: [
[ 0, 0, 0, 0 ],
[ 0, 0, 0, 0.03225806451612903 ],
...
],
scale: [
[ 1, 1, 1, 0 ],
[ 1, 1, 1, 0.03225806451612903 ],
...
]
}
*/For every new frame that gets baked, you can optionally provide a callback to edit the frame. You'll be passed the following structure:
{
position: rm.Vec3
rotation: rm.Vec3
scale: rm.Vec3
time: number
}You can edit it however you want and that's how it will end up in the final animation.
Code Example
const animation: rm.AnimatedTransform = {
position: [[0, 0, 0, 0], [0, 10, 0, 1, 'easeInOutExpo']],
}
rm.bakeAnimation(animation, transform => {
transform.position[1] += 10
})
/*
{
position: [
[ 0, 10, 0, 0 ],
[ 0, 10.007636299408441899, 0, 0.03225806451612903 ],
...
],
rotation: [
[ 0, 0, 0, 0 ],
[ 0, 0, 0, 0.03225806451612903 ],
...
],
scale: [
[ 1, 1, 1, 0 ],
[ 1, 1, 1, 0.03225806451612903 ],
...
]
}
*/You can also pass in animation settings as the third parameter to change how the animation is generated.
Code Example
const animationSettings = new rm.AnimationSettings()
animationSettings.bakeSampleFrequency = 5
animationSettings.optimizeSettings.disabled = true
const animation: rm.AnimatedTransform = {
position: [[0, 0, 0, 0], [0, 10, 0, 1, 'easeInOutExpo']],
}
rm.bakeAnimation(animation, undefined, animationSettings)
/*
{
position: [
[ 0, 0, 0, 0 ],
[ 0, 0.15625, 0, 0.25 ],
[ 0, 5, 0, 0.5 ],
[ 0, 9.84375, 0, 0.75 ],
[ 0, 10, 0, 1 ]
],
rotation: [
[ 0, 0, 0, 0 ],
[ 0, 0, 0, 0.25 ],
[ 0, 0, 0, 0.5 ],
[ 0, 0, 0, 0.75 ],
[ 0, 0, 0, 1 ]
],
scale: [
[ 1, 1, 1, 0 ],
[ 1, 1, 1, 0.25 ],
[ 1, 1, 1, 0.5 ],
[ 1, 1, 1, 0.75 ],
[ 1, 1, 1, 1 ]
]
}
*/The fourth parameter defines the "domain" of the animation. This describes the minimum and maximum time the animation should take place.
Code Example
const animation: rm.AnimatedTransform = {
position: [[0, 0, 0, 0], [0, 10, 0, 1, 'easeInOutExpo']],
}
rm.bakeAnimation(animation, undefined, undefined, { min: 0.5, max: 1 })
/*
{
position: [
[ 0, 3.998191155582921, 0, 0.4838709677419355 ],
[ 0, 9.331637688393082, 0, 0.6451612903225805 ],
...
],
rotation: [
[ 0, 0, 0, 0.4838709677419355 ],
[ 0, 0, 0, 0.5161290322580645 ],
...
],
scale: [
[ 1, 1, 1, 0.4838709677419355 ],
[ 1, 1, 1, 0.5161290322580645 ],
...
]
}
*/By default, this is just the minimum and maximum time of all the points combined.
- Info
- Difficulty
- Beatmap Objects
- Gameplay Objects
- Walls
- Basic Notemods
- Note Iterators
- Basic Events
- V3 Events
- Custom Events
- Heck Tracks and Animation
- Easings
- Point Types
- Point Utilities
- Heck Animation Baking
- Heck Animation Settings
Non-Vivify Models
Vivify