`BVHFiles.BVHGraph`

— Type`struct BVHGraph{T <: Integer} <: AbstractGraph{T}`

Used to store motion capture data. Usually constructed by using `load`

on a BVH file.

`BVHFiles.add_frames!`

— Function`add_frames!(g::BVHGraph, frames::Integer)`

Extend the animation by a number of `frames`

.

The positions and rotations for the additional frames are set to zero.

`BVHFiles.add_joint!`

— Function`add_joint!(g::BVHGraph, v₋₁::Integer, name::AbstractString, off::Vector{Float64}, nb::Vector = outneighbors(g, v₋₁))`

Add a vertex named `name`

with offset `off`

as an outneighbor to `v₋₁`

. The outneighbors of `v₋₁`

that should be attached as outneighbors to the new vertex can be specified.

"JOINT" is automatically added in front of `name`

. `v₋₁`

can also be identified by its name.

`BVHFiles.add_joint!`

— Method`add_joint!(g::BVHGraph, v₋₁::Integer, v₊₁::Integer, name::AbstractString; fraction::Float64 = 0.5)`

Add a vertex on the straight line between `v₋₁`

and `v₊₁`

named `name`

. `fraction`

refers to the fraction of the old offset that will be assigned to the new vertex.

"JOINT" is automatically added in front of `name`

. `v₋₁`

and `v₊₁`

can also be identified by their name.

`BVHFiles.change_sequence!`

— Method`change_sequence!(g::BVHGraph, v::Integer, sym::Symbol)`

Change the rotation order of vertex `v`

to `sym`

. The euler angles are adjusted accordingly.

Valid Symbols are `:XYZ`

, `:XYX`

, `:XZX`

, `:XZY`

, `:YXZ`

, `:YZX`

, `:YXY`

, `:YZY`

, `:ZXY`

, `:ZYX`

, `:ZXZ`

, `:ZYZ`

.

See also: `change_sequences!`

`BVHFiles.change_sequences!`

— Method`change_sequences!(g::BVHGraph, sym::Symbol)`

Change the rotation order of all vertices to `sym`

. The euler angles are adjusted accordingly.

Valid Symbols are `:XYZ`

, `:XYX`

, `:XZX`

, `:XZY`

, `:YXZ`

, `:YZX`

, `:YXY`

, `:YZY`

, `:ZXY`

, `:ZYX`

, `:ZXZ`

, `:ZYZ`

.

See also: `change_sequence!`

`BVHFiles.global_position`

— Function`global_position(g::BVHGraph, v::Integer, f::Integer, N::Matrix{Float64} = Matrix(1.0I, 4, 4))`

Return the global position of vertex `v`

for frame `f`

.

This function does not store the result in `g`

. `N`

should not be changed.

See also: `global_positions!`

`BVHFiles.global_positions!`

— Method`global_positions!(g::BVHGraph)`

Calculate the global positions for every vertex and frame in `g`

and store them.

See also: `global_position`

`BVHFiles.interpolate!`

— Function`interpolate!(g::BVHGraph, h::Integer = 1)`

Add a number of `h`

frames between each pair of consecutive frames by interpolating between them using LERP.

`BVHFiles.load`

— Method`load(filename::AbstractString)`

Read a BVH file with name `filename`

and return a `BVHGraph`

.

**Examples**

```
julia> g = load("Test.bvh")
BVHGraph
Name: Test.bvh
[...]
```

`BVHFiles.optimize_offsets!`

— Method`optimize_offsets!(g::BVHGraph)`

For each edge calculate the average norm of the global positions between its source and destination, then adjust the offset vector accordingly.

After removing vertices this function can reduce the deviations of the vertices from their original global positions since the new offsets are usually biased.

**Examples**

```
julia> g = load("Example.bvh") |>
global_positions! |>
remove_joint!(7) |>
remove_joint!(13) |>
remove_joints!("J_L_Bale", "J_R_Bale", "J_L4", "J_L3", "J_L1", "J_T12", "J_T10", "J_T9", "J_T8", "J_T6", "J_T5", "J_T4", "J_T3", "J_T2") |>
optimize_offsets!
BVHGraph
Name: Example.bvh
[...]
```

See also: `optimize_rotations!`

, `total_squared_errors`

`BVHFiles.optimize_rotations!`

— Function`optimize_rotations!(g::BVHGraph, optimizer, η::Number, iterations::Integer, exclude::Vector{<:Integer} = Integer[])`

Optimize the rotations of each vertex that has got outneighbors and is not in `exclude`

using a gradient descent algorithm.

`optimizer`

should implement the Flux interface for optimizers. `η`

is the learning rate and the number of repetitions for each frame is determined by `iterations`

. Vertices can be excluded from the algorithm by putting them in `exclude`

. This can be useful if parts of the graph (for example the legs) have not been changed and therefore don't need optimization.

**Examples**

```
julia> g = load("Example.bvh") |>
global_positions! |>
remove_joint!(7) |>
remove_joint!(13) |>
remove_joints!("J_L_Bale", "J_R_Bale", "J_L4", "J_L3", "J_L1", "J_T12", "J_T10", "J_T9", "J_T8", "J_T6", "J_T5", "J_T4", "J_T3", "J_T2") |>
optimize_offsets! |>
optimize_rotations!(ADAM, 0.005, 10, [1, 2, 3, 4, 6, 8, 9, 10, 12, 14])
BVHGraph
Name: Example.bvh
[...]
```

See also: `optimize_offsets!`

, `total_squared_errors`

`BVHFiles.project!`

— Function`project!(g::BVHGraph, h::BVHGraph, T::Matrix = Matrix(1.0I, 3, 3))`

Transfer the rotations of each vertex in `h`

to the corresponding vertex in `g`

. The corresponding vertices must have the same names. `T`

is a rotation matrix that should be provided if the global orientations of `g`

and `h`

differ.

See also: `replace_offset!`

, `replace_offsets!`

`BVHFiles.remove_frames!`

— Function`remove_frames!(g::BVHGraph, frames::Integer, from_end::Bool = true)`

Shorten the animation by a number of `frames`

.

By default the frames are removed from the end.

`BVHFiles.remove_joint!`

— Function`remove_joint!(g::BVHGraph, v::Integer, v₊₁::Integer = outneighbors(g, v) != [] ? outneighbors(g, v)[1] : 0)`

Remove a vertex `v`

and adjust the offsets and rotations of the surrounding vertices in such a way that deviations from their original positions are minimized.

In the case that `v`

possesses multiple outneighbors, a neighbor `v₊₁`

can be specified that will be prioritized when adjusting rotations. `v`

and `v₊₁`

can also be identified by their name.

See also: `remove_joints!`

, `optimize_offsets!`

`BVHFiles.remove_joints!`

— Method`remove_joints!(g::BVHGraph, names::AbstractString...)`

Remove every vertex in `names`

and adjust the offsets and rotations of the surrounding vertices in such a way that deviations from their original positions are minimized.

See also: `remove_joint!`

, `optimize_offsets!`

`BVHFiles.rename!`

— Method`rename!(g::BVHGraph, dict::Dict{String,String})`

Change the names of all vertices in keys to their values.

`BVHFiles.replace_offset!`

— Function`replace_offset!(g::BVHGraph, h::BVHGraph, gv₊₁::Integer, T::Matrix{Float64} = Matrix(1.0I, 3, 3); change_rotation::Bool = true)`

Replace the offset of a vertex `gv₊₁`

in `g`

with the offset of the corresponding vertex in `h`

. The corresponding vertex and its inneighbor must have the same names as those in `g`

. The rotations of the surrounding vertices are adjusted. `T`

is a rotation matrix that should be provided if the global orientations of `g`

and `h`

differ.

See also: `replace_offsets!`

, `project!`

`BVHFiles.replace_offsets!`

— Function`replace_offsets!(g::BVHGraph, h::BVHGraph, exclude::Vector, T::Matrix{Float64} = Matrix(1.0I, 3, 3))`

Replace the offsets of all vertices in `g`

, except those in `exclude`

, with the offsets of their corresponding vertices in `h`

. The corresponding vertex and its inneighbor must have the same names as those in `g`

. The rotations of the surrounding vertices are adjusted. `T`

is a rotation matrix that should be provided if the global orientations of `g`

and `h`

differ.

See also: `replace_offset!`

, `project!`

`BVHFiles.save`

— Method`save(g::BVHGraph, filename::AbstractString)`

Save a BVHGraph `g`

to `filename`

as a BVH file.

`BVHFiles.scale!`

— Method`scale!(g::BVHGraph, scale::Float64)`

Multiply all offsets as well as the positions of ROOT by `scale`

.

`BVHFiles.squared_errors`

— Method`squared_errors(g::BVHGraph, f::Integer)`

Calculate the sum of the squared differences between the current and stored positions of the vertices for a given frame `f`

.

Only those vertices are taken into account that have got positions for every frame.

See also: `total_squared_errors`

`BVHFiles.total_squared_errors`

— Method`total_squared_errors(g::BVHGraph)`

Calculate the sum of the squared differences between the current and stored positions of the vertices for all frames.

Only those vertices are taken into account that have got positions for every frame.

See also: `squared_errors`

`BVHFiles.zero!`

— Method`zero!(g::BVHGraph)`

Change all rotations as well as the positions of ROOT to zero.