# `Cauldron3D.Skeleton`
[🔗](https://github.com/jaman/cauldron/blob/v0.2.2/cauldron_3d/lib/cauldron_3d/skeleton.ex#L1)

Bones posed into place: each bone's own position and rotation relative to its parent,
turned into a transform from the bone's space to the model's.

A transform is three rows `{{r00, r01, r02, tx}, {r10, r11, r12, ty}, {r20, r21, r22,
tz}}`: a point `p` goes to `{row0 · p + tx, row1 · p + ty, row2 · p + tz}`.

    parents = {-1, 0, 1}
    locals = [{{0.0, 0.0, 0.0}, q0}, {{0.0, 0.0, 10.0}, q1}, {{0.0, 0.0, 10.0}, q2}]
    transforms = Cauldron3D.Skeleton.pose(parents, locals)
    Cauldron3D.Skeleton.apply(elem(transforms, 2), {0.0, 0.0, 0.0})

A bone's parent comes before it; `-1` marks a bone with none.

# `transform`

```elixir
@type transform() :: {tuple(), tuple(), tuple()}
```

# `apply`

```elixir
@spec apply(transform(), Cauldron3D.Vec.t()) :: Cauldron3D.Vec.t()
```

Point `point` moved by `transform`.

# `concat`

```elixir
@spec concat(transform(), transform()) :: transform()
```

The transform doing `inner` and then `outer`.

# `identity`

```elixir
@spec identity() :: transform()
```

The transform that changes nothing.

# `origin`

```elixir
@spec origin(transform()) :: Cauldron3D.Vec.t()
```

Where `transform` puts the origin.

# `pose`

```elixir
@spec pose(tuple(), [{Cauldron3D.Vec.t(), Cauldron3D.Quat.t()}], transform()) ::
  tuple()
```

Each bone's transform into the model's space, `root` applied to the bones without a parent.

# `rotate`

```elixir
@spec rotate(transform(), Cauldron3D.Vec.t()) :: Cauldron3D.Vec.t()
```

Direction `vector` turned by `transform`, its move left out.

# `transform`

```elixir
@spec transform(Cauldron3D.Vec.t(), Cauldron3D.Quat.t()) :: transform()
```

The transform of a rotation `q` followed by a move to `position`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
