glTF models support storing animation data about transforms in interpolatable keyframes.
Sourcing animations
You can obtain animations from various sources. This section includes some of the more popular tools and services for getting or creating animations.
Sketchfab
Sketchfab and other 3D asset websites will often have animations. On Sketchfab, you can filter by Animated to find these models specifically. You can switch between animations at the bottom of the Sketchfab viewer. The names of the animations should correspond with the animationNameToTrack property mentioned below.
Mixamo
Mixamo is an excellent place to rig and animate your characters, or browse through shared animations uploaded by others. As mentioned on the glTF page, Mixamo doesn’t support glTF models yet. You must convert the .fbx files to the glTF format. You can use Blender or other software to do this conversion.
Blender
Besides re-exporting from Mixamo, you can create animations yourself using Blender. The Blender manual has more information on animation. When exporting to glTF format, use the settings mentioned in the Blender documentation to ensure your exported files are correct.
Loading animations
Before adding your animations in Spatial SDK, check them using a reference glTF viewer to ensure they are correct. You can use Khronos’ glTF sample viewer and go to the Animation tab on the right-hand side to check that all your animations are there and play correctly.
Controlling animations in a Meta Spatial app
After confirming that your animation data is in your glTF file and working correctly, you can import the animation into your scene using the Animated component and a mesh component:
For simple use cases, you can play an infinitely looping animation.
// assuming you already have a Mesh component on myEntity
myEntity.setComponent(Animated(System.currentTimeMillis()))
Here is a breakdown of the arguments:
startTime: This is the Unix timestamp (milliseconds) of when you want your animation to start. The code example above sets the current system time so that the animation will start immediately.
pausedTime: This is a floating point time in seconds representing the moment to display in the animation when you pause it.
playbackState: Corresponds to the PlaybackState enum. Either PLAYING (default) or PAUSED.
playbackType: Corresponds to the PlaybackType enum.
LOOP (default): Restarts the animation when it passes the end of the animation.
CLAMP: Freezes the model in the final pose of the animation at the end.
track: The index of the animation track you want to play (the default is 0, which is the first track). You can utilize SceneMesh.animationNameToTrack to get a track ID using the track’s name.
System animations
You can write a system to control the animations of meshes.
Here is an example of AnimationSystem:
class AnimationSystem() : SystemBase() {
var previousTime: Long = 0L
override fun execute() {
if (previousTime == 0L) {
previousTime = System.currentTimeMillis()
}
val currentTime = System.currentTimeMillis()
val timeDeltaInSeconds = (currentTime - previousTime) / 1000.0f
previousTime = currentTime
val q = Query.where { has(AComponent.id) }
for (entity in q.eval()) {
val tf = entity.tryGetComponent<Transform>() ?: continue
tf.transform.t.y = tf.transform.t.y + 0.01f * timeDeltaInSeconds
entity.setComponent(tf)
}
}
}
To use AnimationSystem, register it in your application:
class TestActivity : AppSystemActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
systemManager.registerSystem(AnimationSystem())
}
}
After running the app, scene objects that have an AComponent will move up 1 cm every second.
Android animations
Android provides a number of tools to support animations in Android applications. For example, you can use ValueAnimator to animate meshes.
Here is an example that demonstrates how to animate the scaling of an object from zero to its full size using ValueAnimator:
ValueAnimator.ofFloat(0f, 1f)
.apply {
duration = 1000
interpolator = OvershootInterpolator(1f)
addUpdateListener { animation ->
val v = animation.animatedValue as Float
entity.setComponent(Scale(scale.scale.multiply(v)))
}
}
.start()
This code snippet starts an animation that scales a scene object from zero to its original size over a period of one second.
For more information on how to make Android animations, see the official Android Introduction to animations page.