* Normalizes the frame number to a value between 0 and 1 based on the input range. * @param frame - The current frame number. * @returns The normalized value.
(frame: number)
| 61 | * @returns The normalized value. |
| 62 | */ |
| 63 | private normalize(frame: number): { t: number, segment: number } { |
| 64 | const { input: inputRange } = this; |
| 65 | |
| 66 | if (frame < inputRange[0]) { |
| 67 | if (this.options.extrapolate === "clamp") { |
| 68 | return { t: 0, segment: 0 }; |
| 69 | } else { |
| 70 | return { t: (frame - inputRange[0]) / (inputRange[1] - inputRange[0]), segment: 0 }; |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | if (frame > inputRange[inputRange.length - 1]) { |
| 75 | if (this.options.extrapolate === "clamp") { |
| 76 | return { t: 1, segment: inputRange.length - 2 }; |
| 77 | } else { |
| 78 | return { t: (frame - inputRange[inputRange.length - 2]) / (inputRange[inputRange.length - 1] - inputRange[inputRange.length - 2]), segment: inputRange.length - 2 }; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | for (let i = 0; i < inputRange.length - 1; i++) { |
| 83 | const inputStart = inputRange[i]; |
| 84 | const inputEnd = inputRange[i + 1]; |
| 85 | if (frame >= inputStart && frame <= inputEnd) { |
| 86 | const t = (frame - inputStart) / (inputEnd - inputStart); |
| 87 | return { t, segment: i }; |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | // If not clamped and frame is outside the input range |
| 92 | return { t: 0, segment: 0 }; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Interpolates the output value based on the normalized frame value. |