Source code for isaaclab.sim.spawners.materials.physics_materials
# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
from __future__ import annotations
import dataclasses
from typing import TYPE_CHECKING
from pxr import Usd, UsdPhysics, UsdShade
from isaaclab.sim.schemas.schemas import _apply_namespaced_schemas
from isaaclab.sim.utils import clone
from isaaclab.sim.utils.stage import get_current_stage
if TYPE_CHECKING:
from . import physics_materials_cfg
[docs]
@clone
def spawn_rigid_body_material(prim_path: str, cfg: physics_materials_cfg.RigidBodyMaterialBaseCfg) -> Usd.Prim:
"""Create material with rigid-body physics properties.
Rigid body materials are used to define the physical properties to meshes of a rigid body. These
include the friction, restitution, and (PhysX-only) compliant-contact spring and combine-mode
tokens. For more information on rigid body material, please refer to the `documentation on
PxMaterial <https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/_api_build/classPxBaseMaterial.html>`_.
The writer is metadata-driven: it always applies the standard ``UsdPhysics.MaterialAPI`` and
writes the friction/restitution fields, then reads ``_usd_applied_schema``, ``_usd_namespace``,
and ``_usd_attr_name_map`` from the cfg to author solver-specific attributes. The applied
schema (e.g. ``PhysxMaterialAPI``) is added only when at least one solver-specific field has a
non-``None`` value at the instance level.
.. note::
This function is decorated with :func:`clone` that resolves prim path into list of paths
if the input prim path is a regex pattern. This is done to support spawning multiple assets
from a single and cloning the USD prim at the given path expression.
Args:
prim_path: The prim path or pattern to spawn the asset at. If the prim path is a regex pattern,
then the asset is spawned at all the matching prim paths.
cfg: The configuration for the physics material.
Returns:
The spawned rigid body material prim.
Raises:
ValueError: When a prim already exists at the specified prim path and is not a material.
ValueError: When the cfg defines solver-specific fields but does not define ``_usd_namespace``.
"""
# get stage handle
stage = get_current_stage()
# create material prim if no prim exists
if not stage.GetPrimAtPath(prim_path).IsValid():
_ = UsdShade.Material.Define(stage, prim_path)
# obtain prim
prim = stage.GetPrimAtPath(prim_path)
# check if prim is a material
if not prim.IsA(UsdShade.Material):
raise ValueError(f"A prim already exists at path: '{prim_path}' but is not a material.")
# apply the standard UsdPhysics MaterialAPI (always)
if not UsdPhysics.MaterialAPI(prim):
UsdPhysics.MaterialAPI.Apply(prim)
# build cfg dict, dropping underscore-prefixed metadata keys and the spawner ``func`` field
cfg_dict = {f.name: getattr(cfg, f.name) for f in dataclasses.fields(cfg) if f.name != "func"}
# All fields routed by the helper: base friction/restitution under ``physics:*``,
# PhysX-subclass fields (compliant-contact, combine modes) under ``physxMaterial:*``.
_apply_namespaced_schemas(prim, cfg, cfg_dict)
# return the prim
return prim