BVHFiles.BVHGraphType
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_positionFunction
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.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.loadMethod
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.saveMethod
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_errorsMethod
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_errorsMethod
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.