BVHFiles.BVHGraph
— Typestruct BVHGraph{T <: Integer} <: AbstractGraph{T}
Used to store motion capture data. Usually constructed by using load
on a BVH file.
BVHFiles.add_frames!
— Functionadd_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!
— Functionadd_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!
— Methodadd_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!
— Methodchange_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!
— Methodchange_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
— Functionglobal_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!
— Methodglobal_positions!(g::BVHGraph)
Calculate the global positions for every vertex and frame in g
and store them.
See also: global_position
BVHFiles.interpolate!
— Functioninterpolate!(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
— Methodload(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!
— Methodoptimize_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!
— Functionoptimize_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!
— Functionproject!(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!
— Functionremove_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!
— Functionremove_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!
— Methodremove_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!
— Methodrename!(g::BVHGraph, dict::Dict{String,String})
Change the names of all vertices in keys to their values.
BVHFiles.replace_offset!
— Functionreplace_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!
— Functionreplace_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
— Methodsave(g::BVHGraph, filename::AbstractString)
Save a BVHGraph g
to filename
as a BVH file.
BVHFiles.scale!
— Methodscale!(g::BVHGraph, scale::Float64)
Multiply all offsets as well as the positions of ROOT by scale
.
BVHFiles.squared_errors
— Methodsquared_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
— Methodtotal_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!
— Methodzero!(g::BVHGraph)
Change all rotations as well as the positions of ROOT to zero.