60 lines
1.6 KiB
Kotlin
60 lines
1.6 KiB
Kotlin
package org.openrndr.extra.keyframer
|
|
|
|
import org.openrndr.extra.easing.Easing
|
|
import org.openrndr.extra.easing.EasingFunction
|
|
import org.openrndr.math.Quaternion
|
|
import org.openrndr.math.slerp
|
|
|
|
class KeyQuaternion(val time: Double, val value: Quaternion, val easing: EasingFunction)
|
|
|
|
class KeyframerChannelQuaternion {
|
|
val keys = mutableListOf<KeyQuaternion>()
|
|
|
|
operator fun invoke() : Double {
|
|
return 0.0
|
|
}
|
|
|
|
fun add(time: Double, value: Quaternion?, easing: EasingFunction = Easing.Linear.function) {
|
|
|
|
value?.let {
|
|
keys.add(KeyQuaternion(time, it, easing))
|
|
}
|
|
}
|
|
|
|
fun lastValue(): Quaternion? {
|
|
return keys.lastOrNull()?.value
|
|
}
|
|
|
|
fun duration(): Double {
|
|
return keys.last().time
|
|
}
|
|
|
|
fun value(time: Double): Quaternion? {
|
|
if (keys.size == 0) {
|
|
return null
|
|
}
|
|
if (keys.size == 1) {
|
|
return if (time < keys.first().time) {
|
|
keys[0].value.normalized
|
|
} else {
|
|
keys[0].value.normalized
|
|
}
|
|
}
|
|
|
|
if (time < keys.first().time) {
|
|
return null
|
|
}
|
|
|
|
val rightIndex = keys.indexOfFirst { it.time > time }
|
|
return if (rightIndex == -1) {
|
|
keys.last().value.normalized
|
|
} else {
|
|
val leftIndex = (rightIndex - 1).coerceAtLeast(0)
|
|
val rightKey = keys[rightIndex]
|
|
val leftKey = keys[leftIndex]
|
|
val t0 = (time - leftKey.time) / (rightKey.time - leftKey.time)
|
|
val e0 = rightKey.easing(t0, 0.0, 1.0, 1.0)
|
|
slerp(leftKey.value, rightKey.value, e0).normalized
|
|
}
|
|
}
|
|
} |