## Configuring the build

Configuring the build to enable animation in your app involves modifying the
`build.gradle` file and importing animations into your project.

1. Update your **app's** `build.gradle` to support an imported animation
   model renderable, by adding the Sceneform animation dependency:

        dependencies {
            ...
            // Support for animated model renderables.
            implementation "com.google.ar.sceneform:animation:1.15.0"
            }

2. [Import and preview your `*.fbx` animation files](https://developers.google.com/sceneform/develop/import-assets)
   to obtain an `*.sfb` file containing the imported model.

## Using animations at runtime

Use runtime operations to:

- [Create an animated renderable](https://developers.google.com/sceneform/develop/animation/enable-animations#renderable)

- [Get access to animation data](https://developers.google.com/sceneform/develop/animation/enable-animations#get-access)

- [Control playback](https://developers.google.com/sceneform/develop/animation/enable-animations#control-playback)

- (Optional) [Add additional property animations](https://developers.google.com/sceneform/develop/animation/enable-animations#property-animation)

### Creating an animation renderable

At runtime, use [`ModelRenderable.Builder`](https://developers.google.com/sceneform/reference/com/google/ar/sceneform/rendering/ModelRenderable.Builder)
to load the `*.sfb` and attach it to a node in the scene, as you would do
with any `ModelRenderable`:

      // Create the ModelRenderable.
      ModelRenderable.builder()
          .setSource(this, R.raw.andy)
          .build()
          .thenAccept(renderable -> andyRenderable = renderable)
          .exceptionally(
              throwable -> {
              Log.e(TAG, "Unable to load Renderable.", throwable);
              return null;
          });

      // Attach the ModelRenderable to the node in the scene.
      Node andyNode = new Node();
      andyNode.setParent(arFragment.getArSceneView().getScene());
      andyNode.setRenderable(andyRenderable);

### Get access to the animation data

    // Get the animation data called "andy_dance" from the `andyRenderable`.
    AnimationData danceData = andyRenderable.getAnimationData("andy_dance");

#### Accessing animations based on different metadata

         // Get the animation name.
         danceData.getName();

To retrieve an instance of animation data, use the `ModelRenderable.getAnimationData()`
methods:

         // Access animations by index.
         numAnimations = andyRenderable.getAnimationDataCount();
         danceData = andyRenderable.getAnimationData(0);

### Control playback

Create a [`ModelAnimator`](https://developers.google.com/sceneform/reference/com/google/ar/sceneform/animation/ModelAnimator)
to control playback.

    ModelAnimator andyAnimator = new ModelAnimator(danceData, andyRenderable);

Use `start()` to play back the animation. It will stop automatically at the end.

    andyAnimator.start();

To loop the animation, use `setRepeatCount()`

    andyAnimator.setRepeatCount(<number of repeats>)

### (Optional) Add property animation operations

The `ModelAnimator` extends the Android `Animator` class, which allows more rich
interactions such as [looping](https://developer.android.com/guide/topics/graphics/prop-animation),
responding to events, and [non-linear interpolators](https://developer.android.com/reference/android/graphics/Interpolator).

## Using `SkeletonNode` to identify and attach models to bones

When you're working with a renderable containing *bones* , use the
`SkeletonNode` class to get access to individual bones in the skeleton by
attaching nodes to the bones. This lets you "attach" objects to bones or control
their position.

While the animation is playing, The position, scale, and orientation of the
attached node is updated by the `SkeletonNode` each frame. Setting the position,
scale, or rotation of the attached node will override the bone until the next
time the bone is updated by the animation.

In the [**Animation**](https://github.com/google-ar/sceneform-android-sdk/tree/v1.15.0/samples/animation) sample, this is done
by attaching a `Node` containing a model of a hat to the bone for Andy's "head."
When Andy is animated, the hat stays on his head.

### Accessing information about bones

To access information about bones in a [`ModelRenderable`](https://developers.google.com/sceneform/reference/com/google/ar/sceneform/rendering/ModelRenderable),
use the `getBoneCount()`, `getBoneName()`, or `getBoneParent()` methods:

    // Get the number of bones in the model's skeleton.
    andyRenderable.getBoneCount();

    // Get the names of the bones in the model's skeleton.
    andyRenderable.getBoneName();

    // Get the hierarchy of the bones in the model's skeleton.
    andyRenderable.getBoneParent();

### Working with `SkeletonNode`s

The [`SkeletonNode`](https://developers.google.com/sceneform/reference/com/google/ar/sceneform/SkeletonNode)
class exposes the skeleton of a model in order to attach nodes to
specific bones.

To use `SkeletonNode`, create a new instantiation of it and set the renderable
to the renderable that contains a model with a skeleton.

     andyWithSkeleton = new SkeletonNode();
     andyWithSkeleton.setRenderable(andyRenderable);
     andyWithSkeleton.setParent(scene);

To attach a renderable to a specific bone, first create a new node and attach it
to the bone. Add the node containing the renderable as a child of the first
node. To ensure that the scale and rotation of the bone isn't used to set the
relative transform of the nodes, make sure to reset the scale and position of
the second node.

     hatNode = new Node();
     Node boneNode = new Node();
     boneNode.setParent(andy);
     andy.setBoneAttachment(HAT_BONE_NAME, boneNode);
     hatNode.setRenderable(hatRenderable);
     hatNode.setParent(boneNode);
     hatNode.setWorldScale(Vector3.one());
     hatNode.setWorldRotation(Quaternion.identity());
     Vector3 pos = hatNode.getWorldPosition();