Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Isaac sim IsaacGymEnvs Skeleton3D

From Leeroopedia
Knowledge Sources
Domains Character_Animation, Skeleton_Representation
Last Updated 2026-02-15 11:00 GMT

Overview

The skeleton3d module provides three core classes -- SkeletonTree, SkeletonState, and SkeletonMotion -- that form a complete hierarchical skeleton representation system for loading, manipulating, and retargeting 3D character poses and motion sequences.

Description

The module at isaacgymenvs/tasks/amp/poselib/poselib/skeleton/skeleton3d.py implements a layered skeleton abstraction. SkeletonTree represents the static joint hierarchy as a tree of named nodes with parent indices and local translation offsets. It can be constructed from MJCF files (from_mjcf()), dictionaries (from_dict()), or FBX files, and serialized back via to_dict(). The tree defines the topology (which joints are connected) and the rest-pose bone lengths.

SkeletonState represents a single pose of the skeleton. It combines a SkeletonTree with per-joint rotations and a root translation. The class provides both local and global coordinate frame accessors: local_rotation/global_rotation and local_translation/global_translation, automatically performing forward kinematics to convert between frames. The factory method from_rotation_and_root_translation() constructs a state from local joint rotations and a root position, while zero_pose() creates a rest pose.

SkeletonMotion extends SkeletonState to represent a temporal sequence of poses with an associated framerate. It provides velocity, angular_velocity, global_root_velocity, and global_root_angular_velocity properties computed via finite differences. The from_file() factory loads motion from NPZ/FBX files, and retarget_to() performs motion retargeting between different skeleton topologies. All three classes inherit from Serializable, enabling consistent serialization and deserialization.

Usage

Use these classes throughout the AMP pipeline to load motion capture data, compute reference states for the discriminator, perform motion retargeting between different character morphologies, and represent skeleton poses during simulation. They are the primary data structures for the poselib motion processing library.

Code Reference

Source Location

Signature

class SkeletonTree(Serializable):
    """Joint hierarchy with node names, parent indices, and local translations."""

    @staticmethod
    def from_dict(dict_repr, *args, **kwargs) -> "SkeletonTree":
        """Construct from dictionary representation."""

    @staticmethod
    def from_mjcf(path: str) -> "SkeletonTree":
        """Parse MJCF XML file to build skeleton tree."""

    def to_dict(self) -> OrderedDict:
        """Serialize to dictionary."""

    @property
    def node_names(self) -> List[str]: ...
    @property
    def parent_indices(self) -> Tensor: ...
    @property
    def local_translation(self) -> Tensor: ...
    @property
    def num_joints(self) -> int: ...


class SkeletonState(Serializable):
    """Single skeleton pose: rotations + root translation on a SkeletonTree."""

    @staticmethod
    def from_rotation_and_root_translation(skeleton_tree, rotation, root_translation, is_local=True):
        """Construct state from per-joint rotations and root position."""

    @staticmethod
    def zero_pose(skeleton_tree) -> "SkeletonState":
        """Create identity/rest pose."""

    @property
    def global_rotation(self) -> Tensor: ...
    @property
    def local_rotation(self) -> Tensor: ...
    @property
    def global_translation(self) -> Tensor: ...
    @property
    def local_translation(self) -> Tensor: ...
    @property
    def root_translation(self) -> Tensor: ...


class SkeletonMotion(SkeletonState):
    """Temporal sequence of skeleton poses with framerate."""

    @staticmethod
    def from_file(path: str) -> "SkeletonMotion":
        """Load motion from NPZ or FBX file."""

    def retarget_to(self, target_skeleton_tree, joint_mapping, ...) -> "SkeletonMotion":
        """Retarget motion to a different skeleton topology."""

    @property
    def fps(self) -> float: ...
    @property
    def velocity(self) -> Tensor: ...
    @property
    def angular_velocity(self) -> Tensor: ...
    @property
    def global_root_velocity(self) -> Tensor: ...
    @property
    def global_root_angular_velocity(self) -> Tensor: ...

Import

from isaacgymenvs.tasks.amp.poselib.poselib.skeleton.skeleton3d import SkeletonTree, SkeletonState, SkeletonMotion

I/O Contract

Inputs

Name Type Required Description
path str Yes File path for loading: MJCF XML for SkeletonTree, NPZ/FBX for SkeletonMotion
skeleton_tree SkeletonTree Yes Joint hierarchy definition required by SkeletonState and SkeletonMotion
rotation Tensor(..., num_joints, 4) Yes Per-joint quaternion rotations in (x, y, z, w) format
root_translation Tensor(..., 3) Yes Root joint world-space position
is_local bool No Whether rotations are in local (True) or global (False) frame; defaults to True
joint_mapping dict No Mapping from source to target joint names for retargeting

Outputs

Name Type Description
SkeletonTree SkeletonTree Parsed joint hierarchy with node_names, parent_indices, local_translation
SkeletonState SkeletonState Single pose with global/local rotation and translation accessors
SkeletonMotion SkeletonMotion Temporal pose sequence with velocity properties and fps
global_translation Tensor(..., num_joints, 3) World-space positions of all joints via forward kinematics
velocity Tensor(..., num_joints, 3) Per-joint linear velocities computed via finite differences

Usage Examples

from isaacgymenvs.tasks.amp.poselib.poselib.skeleton.skeleton3d import (
    SkeletonTree, SkeletonState, SkeletonMotion
)

# Load skeleton from MJCF
skeleton_tree = SkeletonTree.from_mjcf("assets/mjcf/amp_humanoid.xml")
print(f"Joints: {skeleton_tree.num_joints}")
print(f"Names: {skeleton_tree.node_names}")

# Create a zero (rest) pose
rest_pose = SkeletonState.zero_pose(skeleton_tree)
print(f"Root position: {rest_pose.root_translation}")

# Load a motion capture clip
motion = SkeletonMotion.from_file("assets/amp/motions/walk.npz")
print(f"Duration: {motion.tensor.shape[0] / motion.fps:.2f}s")
print(f"Global root velocity shape: {motion.global_root_velocity.shape}")

# Access per-frame data
frame_0_global_pos = motion.global_translation[0]  # (num_joints, 3)
frame_0_global_rot = motion.global_rotation[0]      # (num_joints, 4)

# Retarget motion to a different skeleton
target_tree = SkeletonTree.from_mjcf("assets/mjcf/target_humanoid.xml")
retargeted = motion.retarget_to(
    target_skeleton_tree=target_tree,
    joint_mapping={"source_hip": "target_hip", "source_knee": "target_knee"}
)

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment