Skip to content

Point Types

Swifter edited this page Nov 5, 2024 · 4 revisions

Prerequisites

What are points?

"Points" refer to a collection of data describing how values change over time on an object. For example, all properties inside of the animation property on an individual path animation are a collection of points.

Point Forms

Points have 2 forms: "Simple" and "Complex".

"Simple" is just a static value:

animation: {
   position: [x, y, z]
}

"Complex" is a collection of values with corresponding times and interpolations:

animation: {
   position: [
      [x, y, z, t, ...optional easings/splines/flags],
      ...
   ]
}

In order to easily switch between them, rm.complexifyPoints and rm.simplifyPoints exist.

complexifyPoints will take simple points and return a homogeneous complex array by adding a t value of 0. If the points are already complex, the original array is returned.

rm.complexifyPoints([0,0,0]) // [[0,0,0,0]]
rm.complexifyPoints([[0,0,0,1]]) // [[0,0,0,1]]

simplifyPoints will take complex points and attempt to simplify them. If they can't be simplified, the original array is returned.

rm.simplifyPoints([0,0,0]) // [0,0,0]
rm.simplifyPoints([[0,0,0,0]]) // [0,0,0]
rm.simplifyPoints([[0,0,0,1]]) // [[0,0,0,1]]

You can check if points are simple or complex with rm.arePointsSimple

rm.arePointsSimple([0,0,0]) // true
rm.arePointsSimple([[0,0,0,0]]) // false

Point Form Groups

Point form groups describe what forms of points are allowed. There are 4 main groups of point forms: "Complex", "Inner", "Raw", and "Difficulty".

"Complex" points allow complex points as described above.

const p1: rm.ComplexPointsVec3 = [[0,0,0,0,'easeOutExpo']]

"Inner" points allow a single inner point from complex points.

const p1: rm.InnerPointVec3 = [0,0,0,0,'easeOutExpo']

"Raw" points allow complex points and simple points.

const p1: rm.RawPointsVec3 = [[0,0,0,0,'easeOutExpo']]
const p2: rm.RawPointsVec3 = [0,0,0]

"Difficulty" points allow complex points, simple points, or a string to reference a point definition on the difficulty.

const p1: rm.DifficultyPointsVec3 = [[0,0,0,0,'easeOutExpo']]
const p2: rm.DifficultyPointsVec3 = [0,0,0]
const p3: rm.DifficultyPointsVec3 = 'definition'
  • Note: There is no "simple" type group because that ends up just being the tuple itself. E.g. SimplePointsVec3 would end up just being Vec3.

Point Tuples

A point "tuple" describes how many values are being animated. There are 5 types of point tuples: "Linear", "Vec3", "Vec4", "Any", and "Boundless".

"Linear" points animate only one value. (e.g. dissolve)

const p1: rm.RawPointsLinear = [[0, 0, 'easeOutExpo']]
const p2: rm.RawPointsLinear = [0]

"Vec3" points animate three values. (e.g. position)

const p1: rm.RawPointsVec3 = [[0, 0, 0, 0, 'easeOutExpo']]
const p2: rm.RawPointsVec3 = [0, 0, 0]

"Vec4" points animate four values. (e.g. color)

const p1: rm.RawPointsVec4 = [[0, 0, 0, 0, 0, 'easeOutExpo']]
const p2: rm.RawPointsVec4 = [0, 0, 0, 0]

"Any" points allow all of these, but not anything that isn't Linear, Vec3, or Vec4.

const p1: rm.RawPointsAny = [0]
const p2: rm.RawPointsAny = [0, 0] // error
const p3: rm.RawPointsAny = [0, 0, 0]
const p4: rm.RawPointsAny = [0, 0, 0, 0]

"Boundless" points allow any size of points, and does not enforce consistent sizes between points. It handles runtime points by allowing any possible properties.

const p: rm.RuntimeRawPointsBoundless = [
    ['baseLeftHandLocalPosition', ['baseEnvironmentColor0Boost', 'opMul'], 0], // vec3 and vec4
    [0, 0], // linear
    [0, 0, 0, 'easeInBack'], // vec2, which doesn't exist
]

Runtime Points

Because of the modifier system, points can reference values that won't be evaluated until runtime. This makes it impossible to perform certain operations on them such as getting values at a given time.

In order to distinguish these types of points, "Runtime" can be appended to any of the point types:

const p: rm.RuntimeRawPointsVec3 = [
    ['baseHeadLocalPosition', [0, 0, 100, 'opMul'], 0],
    ['baseHeadLocalPosition', 1],
]

If you have points that are typed as runtime but you want to perform logic on them as if they were non-runtime, you can use rm.arePointsRuntime to check and then downcast.

const p: rm.RuntimeRawPointsVec3 = [0, 0, 0]

if (rm.arePointsRuntime(p)) {
    const absoluteP = p as rm.RawPointsVec3
    const values = rm.getPointValuesAtTime('position', absoluteP, 0)
    console.log(values)
}

Clone this wiki locally