simvx.core.animation.skeletal

Skeletal animation: bone tracks and skeletal clips.

Module Contents

Classes

BoneTrack

Animation track for a single bone: position, rotation, scale keyframes.

SkeletalAnimationClip

Animation clip with bone tracks for skeletal animation.

Functions

compose_trs

Compose translation, rotation (quat xyzw) and scale into a 4x4 matrix.

blend_trs

Blend two TRS poses by factor t in [0, 1] -> composed 4x4 matrix.

API

class simvx.core.animation.skeletal.BoneTrack(bone_index: int)[source]

Animation track for a single bone: position, rotation, scale keyframes.

Rotation keyframes use quaternions [x, y, z, w] for spherical interpolation.

Initialization

add_position_key(time: float, position: numpy.ndarray) None[source]

Insert a position (vec3) keyframe, keeping the list time-sorted.

add_rotation_key(time: float, rotation: numpy.ndarray) None[source]

Insert a rotation (quaternion xyzw) keyframe, keeping the list time-sorted.

add_scale_key(time: float, scale: numpy.ndarray) None[source]

Insert a scale (vec3) keyframe, keeping the list time-sorted.

sample_trs(time: float) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray][source]

Interpolate keyframes at time -> (translation, rotation_xyzw, scale).

Components are returned in TRS space (not composed into a matrix) so callers can blend two poses correctly: SLERP rotation, LERP position and scale. :meth:sample builds the matrix from these.

sample(time: float) numpy.ndarray[source]

Interpolate keyframes at given time -> 4x4 local transform matrix.

to_dict() dict[source]

Serialize the bone track. Arrays are stored as plain lists.

classmethod from_dict(data: dict) simvx.core.animation.skeletal.BoneTrack[source]

Deserialize a bone track, restoring keys as float32 arrays.

class simvx.core.animation.skeletal.SkeletalAnimationClip(name: str, duration: float)[source]

Animation clip with bone tracks for skeletal animation.

Initialization

add_bone_track(track: simvx.core.animation.skeletal.BoneTrack) None[source]
evaluate(time: float) dict[int, numpy.ndarray][source]

Evaluate all bone tracks at given time.

Returns dict mapping bone_index -> 4x4 local transform.

evaluate_trs(time: float) dict[int, tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]][source]

Evaluate all bone tracks at time as TRS components per bone.

Returns dict mapping bone_index -> (translation, rotation_xyzw, scale). Used by crossfade blending, which must operate in TRS space.

to_dict() dict[source]

Serialize the skeletal clip. kind tags it for polymorphic loading.

classmethod from_dict(data: dict) simvx.core.animation.skeletal.SkeletalAnimationClip[source]

Deserialize a skeletal clip.

simvx.core.animation.skeletal.compose_trs(translation: numpy.ndarray, rotation_xyzw: numpy.ndarray, scale: numpy.ndarray) numpy.ndarray[source]

Compose translation, rotation (quat xyzw) and scale into a 4x4 matrix.

simvx.core.animation.skeletal.blend_trs(a: tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray], b: tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray], t: float) numpy.ndarray[source]

Blend two TRS poses by factor t in [0, 1] -> composed 4x4 matrix.

Position and scale are linearly interpolated; rotation uses SLERP. Blending happens in TRS space (never by lerping matrices) so the result stays a valid rigid-plus-scale transform.