diff --git a/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/Model.kt b/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/Model.kt index 9b997a25d..c4e2b8aa8 100644 --- a/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/Model.kt +++ b/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/Model.kt @@ -30,7 +30,9 @@ class Model(name: String? = null) : Node(name) { } fun applyAnimation(deltaT: Float) { - animations.forEach(Animation::reset) + for (i in animations.indices) { + animations[i].reset() + } var firstActive = true for (i in animations.indices) { diff --git a/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/Animation.kt b/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/Animation.kt index 6966a6d17..ec7c3065c 100644 --- a/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/Animation.kt +++ b/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/Animation.kt @@ -1,7 +1,6 @@ package de.fabmax.kool.scene.animation import de.fabmax.kool.math.* -import de.fabmax.kool.scene.MatrixTransformF import de.fabmax.kool.scene.Mesh import de.fabmax.kool.scene.Node import de.fabmax.kool.scene.TrsTransformF @@ -22,7 +21,7 @@ class Animation(val name: String?) { private val animationNodes = mutableListOf() fun prepareAnimation() { - duration = channels.map { it.lastKeyTime }.maxOrNull() ?: 0f + duration = channels.maxOfOrNull { it.lastKeyTime } ?: 0f channels.forEach { it.duration = duration } animationNodes += channels.map { it.animationNode }.distinct() } @@ -117,8 +116,9 @@ class AnimatedTransformGroup(val target: Node) : AnimationNode { private val animRotation = MutableQuatF() private val animScale = MutableVec3f(1f, 1f, 1f) - private val baseRotation = MutableQuatF() - private val baseScale = MutableVec3f(Vec3f.ONES) + private val blendTranslation = MutableVec3f() + private val blendRotation = MutableQuatF() + private val blendScale = MutableVec3f() init { val vec4 = MutableVec4f() @@ -151,11 +151,9 @@ class AnimatedTransformGroup(val target: Node) : AnimationNode { target.transform = t } - t.translate(animTranslation.mul(weight)) - t.rotate(baseRotation.mix(animRotation, weight)) - t.scale(baseScale.mix(animScale, weight)) - - t.markDirty() + t.translate(animTranslation.mul(weight, blendTranslation)) + t.rotate(QuatF.IDENTITY.mix(animRotation, weight, blendRotation)) + t.scale(Vec3f.ONES.mix(animScale, weight, blendScale)) } override fun setTranslation(translation: Vec3f) { diff --git a/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/AnimationController.kt b/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/AnimationController.kt index 1479d16b1..9c393b4ef 100644 --- a/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/AnimationController.kt +++ b/kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/animation/AnimationController.kt @@ -9,9 +9,10 @@ class AnimationController(val model: Model) { private var currentState = initialState fun update(deltaTime: Float) { - states.forEach { state -> + for (i in states.indices) { + val state = states[i] val newState = state.update(deltaTime, state.name == currentState) - if(newState != currentState) { + if (newState != currentState) { currentState = newState state.onExit() states.find { it.name == newState }?.onEnter?.invoke() @@ -20,16 +21,17 @@ class AnimationController(val model: Model) { model.applyAnimation(deltaTime) } - fun state(stateName: String, body: AnimationState.() -> Unit) = AnimationState(model) - .apply(body).apply { name = stateName; states.add(this) } + fun state(stateName: String, body: AnimationState.() -> Unit) = AnimationState(model, stateName).apply { + body() + states.add(this) + } } -class AnimationState(val model: Model) { +class AnimationState(val model: Model, var name: String) { private val animations = mutableListOf() private val transitions = mutableListOf() private var weight = 0f - var name = "" var blendTransition = 0.2f var onEnter: () -> Unit = {} var onExit: () -> Unit = {} @@ -38,7 +40,9 @@ class AnimationState(val model: Model) { fun update(deltaTime: Float, isActiveState: Boolean): String { updateWeight(deltaTime, isActiveState) onUpdate(deltaTime) - animations.forEach { it.update(deltaTime, weight) } + for (i in animations.indices) { + animations[i].update(deltaTime, weight) + } return transitions.firstOrNull { it.predicate() }?.nextState ?: name }