Skip to content

Point Utilities

Swifter edited this page Jan 27, 2025 · 2 revisions

Prerequisites

  • You should learn about point types before continuing.

Utilities

Get/Set Values

Get/Set the values ([...] in [..., t]) of an inner point.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.getPointValues(p) // [1, 2, 3]

rm.setPointValues(p, [0, 0, 0])
// p = [0, 0, 0, 0, 'easeInExpo']

Get Values At Time

You can use rm.getPointValuesAtTime to get the values of points at a given time in the animation. The property being animated must be provided as it's important to the context of how the point should be interpolated.

const p: rm.RawPointsVec3 = [
    [0, 300, 0, 0],
    [0, 0, 0, 1],
]

const values = rm.getPointValuesAtTime('position', p, 0.5) // [0, 150, 0]

Notice how using rotation instead causes a spherical interpolation between -180 and 180.

const p: rm.RawPointsVec3 = [
    [0, 300, 0, 0], // interpreted as the coterminal angle -60
    [0, 0, 0, 1],
]

const values = rm.getPointValuesAtTime('rotation', p, 0.5) // [0, -30, 0]

Get/Set Point Time

Get/Set the time (t in [..., t]) of an inner point.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.getPointTime(p) // 0

rm.setPointTime(p, 0.5)
// p = [1, 2, 3, 0.5, 'easeInExpo']

You can also get the index of the time.

const p1: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.getPointTimeIndex(p1) // 3

const p2: rm.InnerPointLinear = [1, 0, 'easeInExpo']
rm.getPointTimeIndex(p2) // 1

Get/Set Point Flags

Get/Set the easing of a point.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.getPointEasing(p) // 'easeInExpo'

rm.setPointEasing(p, undefined)
// p = [1, 2, 3, 0]

rm.setPointEasing(p, 'easeInBounce')
// p = [1, 2, 3, 0, 'easeInBounce']

This example works verbatim for rm.getPointSpline. It works similarly for rm.setPointHSVLerp and rm.getPointHSVLerp, but it uses a boolean value since it's either there or it's not.


Get/Set a flag on a point. This can be easings, splines, HSVlerp, or anything else that ends up being a thing.

rm.setPointFlag lets you either add a flag or replace an old one with a new one if possible. If the old parameter isn't defined, it will just ensure a flag exists.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.setPointFlag(p, 'lerpHSV')
// p = [1, 2, 3, 0, 'easeInExpo', 'lerpHSV']

rm.setPointFlag(p, 'lerpHSV')
// p = [1, 2, 3, 0, 'easeInExpo', 'lerpHSV'] same thing

If you define old, it will replace a previous flag that contains old in the string.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.setPointFlag(p, 'lerpHSV', 'ease') // 'easeInExpo' contains 'ease', so it will replace.
// p = [1, 2, 3, 0, 'lerpHSV']

If you define exact, it will determine if old (or value if it's defined) is used to exactly match a flag it can replace.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.setPointFlag(p, 'lerpHSV', 'ease', true) // 'ease' won't match 'easeInExpo' exactly, so it won't replace.
// p = [1, 2, 3, 0, 'easeInExpo', 'lerpHSV']

If you set value to undefined, it will try to remove the flag it finds instead. value can only be undefined if old is provided so it knows what to replace.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'lerpHSV', 'easeInExpo']
rm.setPointFlag(p, undefined) // error
rm.setPointFlag(p, undefined, 'lerpHSV', true) // exactly match 'lerpHSV'
// p = [1, 2, 3, 0, 'easeInExpo']

You can also use rm.getPointFlagIndex to get the index of a flag if it exists. It will return -1 if it does not.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.getPointFlagIndex(p, 'lerpHSV') // -1
rm.getPointFlagIndex(p, 'easeInExpo') // 4

exact (true by default) will determine whether flag should be matched exactly.

const p: rm.InnerPointVec3 = [1, 2, 3, 0, 'easeInExpo']
rm.getPointFlagIndex(p, 'ease', true) // -1
rm.getPointFlagIndex(p, 'ease', false) // 4

Iterate Points

rm.iteratePoints will let you manipulate individual elements of each point without worrying about if they're simple or complex.

const p1: rm.RawPointsVec3 = [1, 2, 3]
rm.iteratePoints(p1, (x) => {
    x[1] = 4
})
// p1 = [1, 4, 3]

const p2: rm.RawPointsVec3 = [[1, 2, 3, 0], [0, 0, 0, 1]]
rm.iteratePoints(p2, (x) => {
    x[1] = 4
})
// p2 = [[1, 4, 3, 0], [0, 4, 0, 1]]

It also passes an index parameter into the callback for the position of the current point in the root array. Simple points always return 0 for this.

const p: rm.RawPointsVec3 = [[1, 2, 3, 0], [0, 0, 0, 1]]
rm.iteratePoints(p, (x, i) => {
    console.log(i) // 0, then 1
})

Clone this wiki locally