SceneView / sceneview-android

SceneView is a 3D and AR Android Composable and View with Google Filament and ARCore. This is a Sceneform replacement in Kotlin
Apache License 2.0
756 stars 151 forks source link

Stop the animation at last frame of animation playback #465

Closed ahegd-dlb closed 1 month ago

ahegd-dlb commented 2 months ago

I am trying to load a .glb file using Sceneview and play the animations present in it. Currently, I see that there's only a simple play/stop functionality seen in the ModelNode class which allows to play a particular animation by referring to the index/name as follows:

val modelFile = "models/test_model.glb"
val modelInstance = sceneView.modelLoader.createModelInstance(modelFile)
val modelNode = ModelNode(
    modelInstance = modelInstance,
    scaleToUnits = 2.0f,
).apply {
    transform(
        position = Position(x = -0.030f, y = -0.20f, z = 0.0f),
        rotation = Rotation(y = 20.0f)
    )
    playAnimation(1, false)
}

I would like to control the animation playback to start/stop at a specific frame. With the current setup, I see that the animation does not stop at the last frame and is reset at the end of playback. Could you please advise on how to achieve this?

Dreiko commented 1 month ago

as a fast solution in my case did the following workaround

internal class AModelNode(
  modelInstance: ModelInstance,
  autoAnimate: Boolean = true,
  scaleToUnits: Float? = null,
  centerOrigin: Position? = null
) : ModelNode(modelInstance, autoAnimate, scaleToUnits, centerOrigin) {

  override fun onFrame(frameTimeNanos: Long) {
    val isPlayingAnimations = playingAnimations.isNotEmpty()

    super.onFrame(frameTimeNanos)

    if (isPlayingAnimations && playingAnimations.isEmpty()) {
      val animationIndex = 0 // the only animation in my case
      val animator = animator
      val duration = animator.getAnimationDuration(animationIndex)
      val preFinalAnimationTime = duration - 0.01f // or whatever is better for your animation
      animator.applyAnimation(animationIndex, preFinalAnimationTime)
      animator.updateBoneMatrices()
    }
  }
}