commonMain.ru.casperix.spine.renderer.SpineController.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spine-jvm Show documentation
Show all versions of spine-jvm Show documentation
Signals for all occasions
package ru.casperix.spine.renderer
import ru.casperix.math.quad_matrix.float32.Matrix3f
import ru.casperix.misc.toFloat
import ru.casperix.renderer.Renderer2D
import ru.casperix.spine.AnimationMode
import ru.casperix.spine.AnimationState
import ru.casperix.spine.Skeleton
import ru.casperix.spine.SkeletonData
import ru.casperix.spine.animation.Animation
import ru.casperix.spine.json.SpineData
import ru.casperix.spine.renderer.SkeletonRenderer.drawSkeleton
import ru.casperix.spine.renderer.SkeletonRenderer.drawSkeletonDebug
import kotlin.time.Duration
import kotlin.time.DurationUnit
class SpineController(val skeleton: Skeleton) {
constructor(spineData: SpineData) : this(spineData.skeletonData)
constructor(skeletonData: SkeletonData) : this(Skeleton(skeletonData))
val animationList = mutableListOf()
var worldMatrix = Matrix3f.IDENTITY
var speed = 1f
init {
val skin = skeleton.data.defaultSkin ?: skeleton.data.skins.firstOrNull()
skeleton.skins = setOfNotNull(skin)
skeleton.setToSetupPose()
skeleton.setTime(0f)
}
fun nextFrame(tick: Duration) {
val tickInSec = tick.toFloat(DurationUnit.SECONDS) * speed
skeleton.setTime(skeleton.time + tickInSec)
animationList.removeAll {
it.nextFrame(skeleton, tickInSec)
}
}
fun render(renderer: Renderer2D, debug: Boolean = false) {
renderer.drawSkeleton(skeleton, worldMatrix)
if (debug) {
renderer.drawSkeletonDebug(skeleton, worldMatrix)
}
}
fun addAnimationIfExist(animationName: String, mode: AnimationMode = AnimationMode.PLAY_LOOP, dropAfterStop:Boolean = false): AnimationState? {
val animation = skeleton.data.animations.firstOrNull { it.name == animationName }
?: return null
return addAnimation(animation, mode, dropAfterStop)
}
fun addAnimationIfExist(animation: Animation?, mode: AnimationMode = AnimationMode.PLAY_LOOP, dropAfterStop:Boolean = false): AnimationState? {
if (animation == null) return null
return addAnimation(animation, mode, dropAfterStop)
}
fun addAnimation(animation: Animation, mode: AnimationMode = AnimationMode.PLAY_LOOP, dropAfterStop:Boolean = false): AnimationState {
val last = animationList.firstOrNull { it.animation == animation }
if (last != null) {
return last
}
val animationState = AnimationState(animation, mode, dropAfterStop)
animationList += animationState
animationState.applyAnimation(skeleton, animation, 0f)
return animationState
}
fun removeAnimation(animationName: String) {
animationList.removeAll { it.animation?.name == animationName }
}
fun removeAnimationIfExist(animation: Animation?) {
if (animation == null) return
removeAnimation(animation)
}
fun removeAnimation(animation: Animation) {
animationList.removeAll { it.animation == animation }
}
}