diff --git a/src/experimental/usd/mjcPhysics/collisionAPI.cpp b/src/experimental/usd/mjcPhysics/collisionAPI.cpp new file mode 100644 index 00000000..ff113849 --- /dev/null +++ b/src/experimental/usd/mjcPhysics/collisionAPI.cpp @@ -0,0 +1,124 @@ +// Copyright 2025 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "./collisionAPI.h" + +#include "pxr/usd/sdf/assetPath.h" +#include "pxr/usd/sdf/types.h" +#include "pxr/usd/usd/schemaRegistry.h" +#include "pxr/usd/usd/typed.h" + +PXR_NAMESPACE_OPEN_SCOPE + +// Register the schema with the TfType system. +TF_REGISTRY_FUNCTION(TfType) { + TfType::Define >(); +} + +/* virtual */ +MjcPhysicsCollisionAPI::~MjcPhysicsCollisionAPI() {} + +/* static */ +MjcPhysicsCollisionAPI MjcPhysicsCollisionAPI::Get(const UsdStagePtr &stage, + const SdfPath &path) { + if (!stage) { + TF_CODING_ERROR("Invalid stage"); + return MjcPhysicsCollisionAPI(); + } + return MjcPhysicsCollisionAPI(stage->GetPrimAtPath(path)); +} + +/* virtual */ +UsdSchemaKind MjcPhysicsCollisionAPI::_GetSchemaKind() const { + return MjcPhysicsCollisionAPI::schemaKind; +} + +/* static */ +bool MjcPhysicsCollisionAPI::CanApply(const UsdPrim &prim, + std::string *whyNot) { + return prim.CanApplyAPI(whyNot); +} + +/* static */ +MjcPhysicsCollisionAPI MjcPhysicsCollisionAPI::Apply(const UsdPrim &prim) { + if (prim.ApplyAPI()) { + return MjcPhysicsCollisionAPI(prim); + } + return MjcPhysicsCollisionAPI(); +} + +/* static */ +const TfType &MjcPhysicsCollisionAPI::_GetStaticTfType() { + static TfType tfType = TfType::Find(); + return tfType; +} + +/* static */ +bool MjcPhysicsCollisionAPI::_IsTypedSchema() { + static bool isTyped = _GetStaticTfType().IsA(); + return isTyped; +} + +/* virtual */ +const TfType &MjcPhysicsCollisionAPI::_GetTfType() const { + return _GetStaticTfType(); +} + +UsdAttribute MjcPhysicsCollisionAPI::GetShellInertiaAttr() const { + return GetPrim().GetAttribute(MjcPhysicsTokens->mjcShellinertia); +} + +UsdAttribute MjcPhysicsCollisionAPI::CreateShellInertiaAttr( + VtValue const &defaultValue, bool writeSparsely) const { + return UsdSchemaBase::_CreateAttr( + MjcPhysicsTokens->mjcShellinertia, SdfValueTypeNames->Bool, + /* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely); +} + +namespace { +static inline TfTokenVector _ConcatenateAttributeNames( + const TfTokenVector &left, const TfTokenVector &right) { + TfTokenVector result; + result.reserve(left.size() + right.size()); + result.insert(result.end(), left.begin(), left.end()); + result.insert(result.end(), right.begin(), right.end()); + return result; +} +} // namespace + +/*static*/ +const TfTokenVector &MjcPhysicsCollisionAPI::GetSchemaAttributeNames( + bool includeInherited) { + static TfTokenVector localNames = { + MjcPhysicsTokens->mjcShellinertia, + }; + static TfTokenVector allNames = _ConcatenateAttributeNames( + UsdAPISchemaBase::GetSchemaAttributeNames(true), localNames); + + if (includeInherited) + return allNames; + else + return localNames; +} + +PXR_NAMESPACE_CLOSE_SCOPE + +// ===================================================================== // +// Feel free to add custom code below this line. It will be preserved by +// the code generator. +// +// Just remember to wrap code in the appropriate delimiters: +// 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'. +// ===================================================================== // +// --(BEGIN CUSTOM CODE)-- diff --git a/src/experimental/usd/mjcPhysics/collisionAPI.h b/src/experimental/usd/mjcPhysics/collisionAPI.h new file mode 100644 index 00000000..e3681526 --- /dev/null +++ b/src/experimental/usd/mjcPhysics/collisionAPI.h @@ -0,0 +1,185 @@ +// Copyright 2025 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MJCPHYSICS_GENERATED_COLLISIONAPI_H +#define MJCPHYSICS_GENERATED_COLLISIONAPI_H + +/// \file mjcPhysics/collisionAPI.h + +#include "./api.h" +#include "./tokens.h" +#include "pxr/base/gf/matrix4d.h" +#include "pxr/base/gf/vec3d.h" +#include "pxr/base/gf/vec3f.h" +#include "pxr/base/tf/token.h" +#include "pxr/base/tf/type.h" +#include "pxr/base/vt/value.h" +#include "pxr/pxr.h" +#include "pxr/usd/usd/apiSchemaBase.h" +#include "pxr/usd/usd/prim.h" +#include "pxr/usd/usd/stage.h" + +PXR_NAMESPACE_OPEN_SCOPE + +class SdfAssetPath; + +// -------------------------------------------------------------------------- // +// COLLISIONAPI // +// -------------------------------------------------------------------------- // + +/// \class MjcPhysicsCollisionAPI +/// +/// API describing a Mujoco collider. +/// +class MjcPhysicsCollisionAPI : public UsdAPISchemaBase { + public: + /// Compile time constant representing what kind of schema this class is. + /// + /// \sa UsdSchemaKind + static const UsdSchemaKind schemaKind = UsdSchemaKind::SingleApplyAPI; + + /// Construct a MjcPhysicsCollisionAPI on UsdPrim \p prim . + /// Equivalent to MjcPhysicsCollisionAPI::Get(prim.GetStage(), prim.GetPath()) + /// for a \em valid \p prim, but will not immediately throw an error for + /// an invalid \p prim + explicit MjcPhysicsCollisionAPI(const UsdPrim &prim = UsdPrim()) + : UsdAPISchemaBase(prim) {} + + /// Construct a MjcPhysicsCollisionAPI on the prim held by \p schemaObj . + /// Should be preferred over MjcPhysicsCollisionAPI(schemaObj.GetPrim()), + /// as it preserves SchemaBase state. + explicit MjcPhysicsCollisionAPI(const UsdSchemaBase &schemaObj) + : UsdAPISchemaBase(schemaObj) {} + + /// Destructor. + MJCPHYSICS_API + virtual ~MjcPhysicsCollisionAPI(); + + /// Return a vector of names of all pre-declared attributes for this schema + /// class and all its ancestor classes. Does not include attributes that + /// may be authored by custom/extended methods of the schemas involved. + MJCPHYSICS_API + static const TfTokenVector &GetSchemaAttributeNames( + bool includeInherited = true); + + /// Return a MjcPhysicsCollisionAPI holding the prim adhering to this + /// schema at \p path on \p stage. If no prim exists at \p path on + /// \p stage, or if the prim at that path does not adhere to this schema, + /// return an invalid schema object. This is shorthand for the following: + /// + /// \code + /// MjcPhysicsCollisionAPI(stage->GetPrimAtPath(path)); + /// \endcode + /// + MJCPHYSICS_API + static MjcPhysicsCollisionAPI Get(const UsdStagePtr &stage, + const SdfPath &path); + + /// Returns true if this single-apply API schema can be applied to + /// the given \p prim. If this schema can not be a applied to the prim, + /// this returns false and, if provided, populates \p whyNot with the + /// reason it can not be applied. + /// + /// Note that if CanApply returns false, that does not necessarily imply + /// that calling Apply will fail. Callers are expected to call CanApply + /// before calling Apply if they want to ensure that it is valid to + /// apply a schema. + /// + /// \sa UsdPrim::GetAppliedSchemas() + /// \sa UsdPrim::HasAPI() + /// \sa UsdPrim::CanApplyAPI() + /// \sa UsdPrim::ApplyAPI() + /// \sa UsdPrim::RemoveAPI() + /// + MJCPHYSICS_API + static bool CanApply(const UsdPrim &prim, std::string *whyNot = nullptr); + + /// Applies this single-apply API schema to the given \p prim. + /// This information is stored by adding "CollisionAPI" to the + /// token-valued, listOp metadata \em apiSchemas on the prim. + /// + /// \return A valid MjcPhysicsCollisionAPI object is returned upon success. + /// An invalid (or empty) MjcPhysicsCollisionAPI object is returned upon + /// failure. See \ref UsdPrim::ApplyAPI() for conditions + /// resulting in failure. + /// + /// \sa UsdPrim::GetAppliedSchemas() + /// \sa UsdPrim::HasAPI() + /// \sa UsdPrim::CanApplyAPI() + /// \sa UsdPrim::ApplyAPI() + /// \sa UsdPrim::RemoveAPI() + /// + MJCPHYSICS_API + static MjcPhysicsCollisionAPI Apply(const UsdPrim &prim); + + protected: + /// Returns the kind of schema this class belongs to. + /// + /// \sa UsdSchemaKind + MJCPHYSICS_API + UsdSchemaKind _GetSchemaKind() const override; + + private: + // needs to invoke _GetStaticTfType. + friend class UsdSchemaRegistry; + MJCPHYSICS_API + static const TfType &_GetStaticTfType(); + + static bool _IsTypedSchema(); + + // override SchemaBase virtuals. + MJCPHYSICS_API + const TfType &_GetTfType() const override; + + public: + // --------------------------------------------------------------------- // + // SHELLINERTIA + // --------------------------------------------------------------------- // + /// Enables handling of the inertia assuming mass is concentrated on the + /// surface. + /// + /// | || + /// | -- | -- | + /// | Declaration | `uniform bool mjc:shellinertia = 0` | + /// | C++ Type | bool | + /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Bool | + /// | \ref SdfVariability "Variability" | SdfVariabilityUniform | + MJCPHYSICS_API + UsdAttribute GetShellInertiaAttr() const; + + /// See GetShellInertiaAttr(), and also + /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create. + /// If specified, author \p defaultValue as the attribute's default, + /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true - + /// the default for \p writeSparsely is \c false. + MJCPHYSICS_API + UsdAttribute CreateShellInertiaAttr(VtValue const &defaultValue = VtValue(), + bool writeSparsely = false) const; + + public: + // ===================================================================== // + // Feel free to add custom code below this line, it will be preserved by + // the code generator. + // + // Just remember to: + // - Close the class declaration with }; + // - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE + // - Close the include guard with #endif + // ===================================================================== // + // --(BEGIN CUSTOM CODE)-- +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif diff --git a/src/experimental/usd/mjcPhysics/generatedSchema.usda b/src/experimental/usd/mjcPhysics/generatedSchema.usda index ee17510b..6b70af62 100644 --- a/src/experimental/usd/mjcPhysics/generatedSchema.usda +++ b/src/experimental/usd/mjcPhysics/generatedSchema.usda @@ -226,3 +226,24 @@ class "SiteAPI" ( { } +class "CollisionAPI" ( + doc = "API describing a Mujoco collider." +) +{ + uniform bool mjc:shellinertia = 0 ( + displayName = "Shell Inertia" + doc = "Enables handling of the inertia assuming mass is concentrated on the surface." + ) +} + +class "MeshCollisionAPI" ( + doc = "API describing a Mujoco collider." +) +{ + uniform token mjc:inertia = "legacy" ( + allowedTokens = ["legacy", "convex", "exact", "shell"] + displayName = "Inertia" + doc = "Controls how a mesh is used when mass and inertia are inferred from geometry." + ) +} + diff --git a/src/experimental/usd/mjcPhysics/meshCollisionAPI.cpp b/src/experimental/usd/mjcPhysics/meshCollisionAPI.cpp new file mode 100644 index 00000000..50c579dd --- /dev/null +++ b/src/experimental/usd/mjcPhysics/meshCollisionAPI.cpp @@ -0,0 +1,126 @@ +// Copyright 2025 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "./meshCollisionAPI.h" + +#include "pxr/usd/sdf/assetPath.h" +#include "pxr/usd/sdf/types.h" +#include "pxr/usd/usd/schemaRegistry.h" +#include "pxr/usd/usd/typed.h" + +PXR_NAMESPACE_OPEN_SCOPE + +// Register the schema with the TfType system. +TF_REGISTRY_FUNCTION(TfType) { + TfType::Define >(); +} + +/* virtual */ +MjcPhysicsMeshCollisionAPI::~MjcPhysicsMeshCollisionAPI() {} + +/* static */ +MjcPhysicsMeshCollisionAPI MjcPhysicsMeshCollisionAPI::Get( + const UsdStagePtr &stage, const SdfPath &path) { + if (!stage) { + TF_CODING_ERROR("Invalid stage"); + return MjcPhysicsMeshCollisionAPI(); + } + return MjcPhysicsMeshCollisionAPI(stage->GetPrimAtPath(path)); +} + +/* virtual */ +UsdSchemaKind MjcPhysicsMeshCollisionAPI::_GetSchemaKind() const { + return MjcPhysicsMeshCollisionAPI::schemaKind; +} + +/* static */ +bool MjcPhysicsMeshCollisionAPI::CanApply(const UsdPrim &prim, + std::string *whyNot) { + return prim.CanApplyAPI(whyNot); +} + +/* static */ +MjcPhysicsMeshCollisionAPI MjcPhysicsMeshCollisionAPI::Apply( + const UsdPrim &prim) { + if (prim.ApplyAPI()) { + return MjcPhysicsMeshCollisionAPI(prim); + } + return MjcPhysicsMeshCollisionAPI(); +} + +/* static */ +const TfType &MjcPhysicsMeshCollisionAPI::_GetStaticTfType() { + static TfType tfType = TfType::Find(); + return tfType; +} + +/* static */ +bool MjcPhysicsMeshCollisionAPI::_IsTypedSchema() { + static bool isTyped = _GetStaticTfType().IsA(); + return isTyped; +} + +/* virtual */ +const TfType &MjcPhysicsMeshCollisionAPI::_GetTfType() const { + return _GetStaticTfType(); +} + +UsdAttribute MjcPhysicsMeshCollisionAPI::GetInertiaAttr() const { + return GetPrim().GetAttribute(MjcPhysicsTokens->mjcInertia); +} + +UsdAttribute MjcPhysicsMeshCollisionAPI::CreateInertiaAttr( + VtValue const &defaultValue, bool writeSparsely) const { + return UsdSchemaBase::_CreateAttr( + MjcPhysicsTokens->mjcInertia, SdfValueTypeNames->Token, + /* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely); +} + +namespace { +static inline TfTokenVector _ConcatenateAttributeNames( + const TfTokenVector &left, const TfTokenVector &right) { + TfTokenVector result; + result.reserve(left.size() + right.size()); + result.insert(result.end(), left.begin(), left.end()); + result.insert(result.end(), right.begin(), right.end()); + return result; +} +} // namespace + +/*static*/ +const TfTokenVector &MjcPhysicsMeshCollisionAPI::GetSchemaAttributeNames( + bool includeInherited) { + static TfTokenVector localNames = { + MjcPhysicsTokens->mjcInertia, + }; + static TfTokenVector allNames = _ConcatenateAttributeNames( + UsdAPISchemaBase::GetSchemaAttributeNames(true), localNames); + + if (includeInherited) + return allNames; + else + return localNames; +} + +PXR_NAMESPACE_CLOSE_SCOPE + +// ===================================================================== // +// Feel free to add custom code below this line. It will be preserved by +// the code generator. +// +// Just remember to wrap code in the appropriate delimiters: +// 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'. +// ===================================================================== // +// --(BEGIN CUSTOM CODE)-- diff --git a/src/experimental/usd/mjcPhysics/meshCollisionAPI.h b/src/experimental/usd/mjcPhysics/meshCollisionAPI.h new file mode 100644 index 00000000..55c8c27e --- /dev/null +++ b/src/experimental/usd/mjcPhysics/meshCollisionAPI.h @@ -0,0 +1,191 @@ +// Copyright 2025 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MJCPHYSICS_GENERATED_MESHCOLLISIONAPI_H +#define MJCPHYSICS_GENERATED_MESHCOLLISIONAPI_H + +/// \file mjcPhysics/meshCollisionAPI.h + +#include "./api.h" +#include "./tokens.h" +#include "pxr/base/gf/matrix4d.h" +#include "pxr/base/gf/vec3d.h" +#include "pxr/base/gf/vec3f.h" +#include "pxr/base/tf/token.h" +#include "pxr/base/tf/type.h" +#include "pxr/base/vt/value.h" +#include "pxr/pxr.h" +#include "pxr/usd/usd/apiSchemaBase.h" +#include "pxr/usd/usd/prim.h" +#include "pxr/usd/usd/stage.h" + +PXR_NAMESPACE_OPEN_SCOPE + +class SdfAssetPath; + +// -------------------------------------------------------------------------- // +// MESHCOLLISIONAPI // +// -------------------------------------------------------------------------- // + +/// \class MjcPhysicsMeshCollisionAPI +/// +/// API describing a Mujoco collider. +/// +/// For any described attribute \em Fallback \em Value or \em Allowed \em Values +/// below that are text/tokens, the actual token is published and defined in +/// \ref MjcPhysicsTokens. So to set an attribute to the value "rightHanded", +/// use MjcPhysicsTokens->rightHanded as the value. +/// +class MjcPhysicsMeshCollisionAPI : public UsdAPISchemaBase { + public: + /// Compile time constant representing what kind of schema this class is. + /// + /// \sa UsdSchemaKind + static const UsdSchemaKind schemaKind = UsdSchemaKind::SingleApplyAPI; + + /// Construct a MjcPhysicsMeshCollisionAPI on UsdPrim \p prim . + /// Equivalent to MjcPhysicsMeshCollisionAPI::Get(prim.GetStage(), + /// prim.GetPath()) for a \em valid \p prim, but will not immediately throw an + /// error for an invalid \p prim + explicit MjcPhysicsMeshCollisionAPI(const UsdPrim &prim = UsdPrim()) + : UsdAPISchemaBase(prim) {} + + /// Construct a MjcPhysicsMeshCollisionAPI on the prim held by \p schemaObj . + /// Should be preferred over MjcPhysicsMeshCollisionAPI(schemaObj.GetPrim()), + /// as it preserves SchemaBase state. + explicit MjcPhysicsMeshCollisionAPI(const UsdSchemaBase &schemaObj) + : UsdAPISchemaBase(schemaObj) {} + + /// Destructor. + MJCPHYSICS_API + virtual ~MjcPhysicsMeshCollisionAPI(); + + /// Return a vector of names of all pre-declared attributes for this schema + /// class and all its ancestor classes. Does not include attributes that + /// may be authored by custom/extended methods of the schemas involved. + MJCPHYSICS_API + static const TfTokenVector &GetSchemaAttributeNames( + bool includeInherited = true); + + /// Return a MjcPhysicsMeshCollisionAPI holding the prim adhering to this + /// schema at \p path on \p stage. If no prim exists at \p path on + /// \p stage, or if the prim at that path does not adhere to this schema, + /// return an invalid schema object. This is shorthand for the following: + /// + /// \code + /// MjcPhysicsMeshCollisionAPI(stage->GetPrimAtPath(path)); + /// \endcode + /// + MJCPHYSICS_API + static MjcPhysicsMeshCollisionAPI Get(const UsdStagePtr &stage, + const SdfPath &path); + + /// Returns true if this single-apply API schema can be applied to + /// the given \p prim. If this schema can not be a applied to the prim, + /// this returns false and, if provided, populates \p whyNot with the + /// reason it can not be applied. + /// + /// Note that if CanApply returns false, that does not necessarily imply + /// that calling Apply will fail. Callers are expected to call CanApply + /// before calling Apply if they want to ensure that it is valid to + /// apply a schema. + /// + /// \sa UsdPrim::GetAppliedSchemas() + /// \sa UsdPrim::HasAPI() + /// \sa UsdPrim::CanApplyAPI() + /// \sa UsdPrim::ApplyAPI() + /// \sa UsdPrim::RemoveAPI() + /// + MJCPHYSICS_API + static bool CanApply(const UsdPrim &prim, std::string *whyNot = nullptr); + + /// Applies this single-apply API schema to the given \p prim. + /// This information is stored by adding "MeshCollisionAPI" to the + /// token-valued, listOp metadata \em apiSchemas on the prim. + /// + /// \return A valid MjcPhysicsMeshCollisionAPI object is returned upon + /// success. An invalid (or empty) MjcPhysicsMeshCollisionAPI object is + /// returned upon failure. See \ref UsdPrim::ApplyAPI() for conditions + /// resulting in failure. + /// + /// \sa UsdPrim::GetAppliedSchemas() + /// \sa UsdPrim::HasAPI() + /// \sa UsdPrim::CanApplyAPI() + /// \sa UsdPrim::ApplyAPI() + /// \sa UsdPrim::RemoveAPI() + /// + MJCPHYSICS_API + static MjcPhysicsMeshCollisionAPI Apply(const UsdPrim &prim); + + protected: + /// Returns the kind of schema this class belongs to. + /// + /// \sa UsdSchemaKind + MJCPHYSICS_API + UsdSchemaKind _GetSchemaKind() const override; + + private: + // needs to invoke _GetStaticTfType. + friend class UsdSchemaRegistry; + MJCPHYSICS_API + static const TfType &_GetStaticTfType(); + + static bool _IsTypedSchema(); + + // override SchemaBase virtuals. + MJCPHYSICS_API + const TfType &_GetTfType() const override; + + public: + // --------------------------------------------------------------------- // + // INERTIA + // --------------------------------------------------------------------- // + /// Controls how a mesh is used when mass and inertia are inferred from + /// geometry. + /// + /// | || + /// | -- | -- | + /// | Declaration | `uniform token mjc:inertia = "legacy"` | + /// | C++ Type | TfToken | + /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Token | + /// | \ref SdfVariability "Variability" | SdfVariabilityUniform | + /// | \ref MjcPhysicsTokens "Allowed Values" | legacy, convex, exact, shell | + MJCPHYSICS_API + UsdAttribute GetInertiaAttr() const; + + /// See GetInertiaAttr(), and also + /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create. + /// If specified, author \p defaultValue as the attribute's default, + /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true - + /// the default for \p writeSparsely is \c false. + MJCPHYSICS_API + UsdAttribute CreateInertiaAttr(VtValue const &defaultValue = VtValue(), + bool writeSparsely = false) const; + + public: + // ===================================================================== // + // Feel free to add custom code below this line, it will be preserved by + // the code generator. + // + // Just remember to: + // - Close the class declaration with }; + // - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE + // - Close the include guard with #endif + // ===================================================================== // + // --(BEGIN CUSTOM CODE)-- +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif diff --git a/src/experimental/usd/mjcPhysics/plugInfo.json b/src/experimental/usd/mjcPhysics/plugInfo.json index 56e11dd5..efc5fe13 100644 --- a/src/experimental/usd/mjcPhysics/plugInfo.json +++ b/src/experimental/usd/mjcPhysics/plugInfo.json @@ -6,6 +6,26 @@ { "Info": { "Types": { + "MjcPhysicsCollisionAPI": { + "alias": { + "UsdSchemaBase": "CollisionAPI" + }, + "autoGenerated": true, + "bases": [ + "UsdAPISchemaBase" + ], + "schemaKind": "singleApplyAPI" + }, + "MjcPhysicsMeshCollisionAPI": { + "alias": { + "UsdSchemaBase": "MeshCollisionAPI" + }, + "autoGenerated": true, + "bases": [ + "UsdAPISchemaBase" + ], + "schemaKind": "singleApplyAPI" + }, "MjcPhysicsSceneAPI": { "alias": { "UsdSchemaBase": "SceneAPI" diff --git a/src/experimental/usd/mjcPhysics/schema.usda b/src/experimental/usd/mjcPhysics/schema.usda index 322a90a4..7996e5b5 100644 --- a/src/experimental/usd/mjcPhysics/schema.usda +++ b/src/experimental/usd/mjcPhysics/schema.usda @@ -515,3 +515,36 @@ class "SiteAPI" ) {} +class "CollisionAPI" +( + doc = """API describing a Mujoco collider.""" + + inherits = +) +{ + uniform bool mjc:shellinertia = False ( + customData = { + string apiName = "ShellInertia" + } + displayName = "Shell Inertia" + doc = """Enables handling of the inertia assuming mass is concentrated on the surface.""" + ) +} + +class "MeshCollisionAPI" +( + doc = """API describing a Mujoco collider.""" + + inherits = +) +{ + uniform token mjc:inertia = "legacy" ( + allowedTokens = ["legacy", "convex", "exact", "shell"] + customData = { + string apiName = "Inertia" + } + displayName = "Inertia" + doc = """Controls how a mesh is used when mass and inertia are inferred from geometry.""" + ) +} + diff --git a/src/experimental/usd/mjcPhysics/tokens.cpp b/src/experimental/usd/mjcPhysics/tokens.cpp index 2cc35a98..fc442b3f 100644 --- a/src/experimental/usd/mjcPhysics/tokens.cpp +++ b/src/experimental/usd/mjcPhysics/tokens.cpp @@ -19,11 +19,14 @@ PXR_NAMESPACE_OPEN_SCOPE MjcPhysicsTokensType::MjcPhysicsTokensType() : auto_("auto", TfToken::Immortal), cg("cg", TfToken::Immortal), + convex("convex", TfToken::Immortal), dense("dense", TfToken::Immortal), elliptic("elliptic", TfToken::Immortal), euler("euler", TfToken::Immortal), + exact("exact", TfToken::Immortal), implicit("implicit", TfToken::Immortal), implicitfast("implicitfast", TfToken::Immortal), + legacy("legacy", TfToken::Immortal), mjcFlagActuation("mjc:flag:actuation", TfToken::Immortal), mjcFlagAutoreset("mjc:flag:autoreset", TfToken::Immortal), mjcFlagClampctrl("mjc:flag:clampctrl", TfToken::Immortal), @@ -47,6 +50,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType() mjcFlagRefsafe("mjc:flag:refsafe", TfToken::Immortal), mjcFlagSensor("mjc:flag:sensor", TfToken::Immortal), mjcFlagWarmstart("mjc:flag:warmstart", TfToken::Immortal), + mjcInertia("mjc:inertia", TfToken::Immortal), mjcOptionActuatorgroupdisable("mjc:option:actuatorgroupdisable", TfToken::Immortal), mjcOptionApirate("mjc:option:apirate", TfToken::Immortal), @@ -76,20 +80,27 @@ MjcPhysicsTokensType::MjcPhysicsTokensType() mjcOptionTolerance("mjc:option:tolerance", TfToken::Immortal), mjcOptionViscosity("mjc:option:viscosity", TfToken::Immortal), mjcOptionWind("mjc:option:wind", TfToken::Immortal), + mjcShellinertia("mjc:shellinertia", TfToken::Immortal), newton("newton", TfToken::Immortal), pgs("pgs", TfToken::Immortal), pyramidal("pyramidal", TfToken::Immortal), rk4("rk4", TfToken::Immortal), + shell("shell", TfToken::Immortal), sparse("sparse", TfToken::Immortal), + CollisionAPI("CollisionAPI", TfToken::Immortal), + MeshCollisionAPI("MeshCollisionAPI", TfToken::Immortal), SceneAPI("SceneAPI", TfToken::Immortal), SiteAPI("SiteAPI", TfToken::Immortal), allTokens({auto_, cg, + convex, dense, elliptic, euler, + exact, implicit, implicitfast, + legacy, mjcFlagActuation, mjcFlagAutoreset, mjcFlagClampctrl, @@ -113,6 +124,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType() mjcFlagRefsafe, mjcFlagSensor, mjcFlagWarmstart, + mjcInertia, mjcOptionActuatorgroupdisable, mjcOptionApirate, mjcOptionCcd_iterations, @@ -139,11 +151,15 @@ MjcPhysicsTokensType::MjcPhysicsTokensType() mjcOptionTolerance, mjcOptionViscosity, mjcOptionWind, + mjcShellinertia, newton, pgs, pyramidal, rk4, + shell, sparse, + CollisionAPI, + MeshCollisionAPI, SceneAPI, SiteAPI}) {} diff --git a/src/experimental/usd/mjcPhysics/tokens.h b/src/experimental/usd/mjcPhysics/tokens.h index 7bdf56f2..1624ce6a 100644 --- a/src/experimental/usd/mjcPhysics/tokens.h +++ b/src/experimental/usd/mjcPhysics/tokens.h @@ -63,6 +63,10 @@ struct MjcPhysicsTokensType { /// Possible value for MjcPhysicsSceneAPI::GetSolverAttr(), This token /// represents the CG constraint solver algorithm. const TfToken cg; + /// \brief "convex" + /// + /// Possible value for MjcPhysicsMeshCollisionAPI::GetInertiaAttr() + const TfToken convex; /// \brief "dense" /// /// Possible value for MjcPhysicsSceneAPI::GetJacobianAttr(), This token @@ -78,6 +82,10 @@ struct MjcPhysicsTokensType { /// Fallback value for MjcPhysicsSceneAPI::GetIntegratorAttr(), This token /// represents the Euler numerical integrator. const TfToken euler; + /// \brief "exact" + /// + /// Possible value for MjcPhysicsMeshCollisionAPI::GetInertiaAttr() + const TfToken exact; /// \brief "implicit" /// /// Possible value for MjcPhysicsSceneAPI::GetIntegratorAttr(), This token @@ -88,6 +96,10 @@ struct MjcPhysicsTokensType { /// Possible value for MjcPhysicsSceneAPI::GetIntegratorAttr(), This token /// represents the implicitfast numerical integrator. const TfToken implicitfast; + /// \brief "legacy" + /// + /// Fallback value for MjcPhysicsMeshCollisionAPI::GetInertiaAttr() + const TfToken legacy; /// \brief "mjc:flag:actuation" /// /// MjcPhysicsSceneAPI @@ -180,6 +192,10 @@ struct MjcPhysicsTokensType { /// /// MjcPhysicsSceneAPI const TfToken mjcFlagWarmstart; + /// \brief "mjc:inertia" + /// + /// MjcPhysicsMeshCollisionAPI + const TfToken mjcInertia; /// \brief "mjc:option:actuatorgroupdisable" /// /// MjcPhysicsSceneAPI @@ -284,6 +300,10 @@ struct MjcPhysicsTokensType { /// /// MjcPhysicsSceneAPI const TfToken mjcOptionWind; + /// \brief "mjc:shellinertia" + /// + /// MjcPhysicsCollisionAPI + const TfToken mjcShellinertia; /// \brief "newton" /// /// Fallback value for MjcPhysicsSceneAPI::GetSolverAttr(), This token @@ -304,11 +324,23 @@ struct MjcPhysicsTokensType { /// Possible value for MjcPhysicsSceneAPI::GetIntegratorAttr(), This token /// represents the RK4 numerical integrator. const TfToken rk4; + /// \brief "shell" + /// + /// Possible value for MjcPhysicsMeshCollisionAPI::GetInertiaAttr() + const TfToken shell; /// \brief "sparse" /// /// Possible value for MjcPhysicsSceneAPI::GetJacobianAttr(), This token /// represents the sparse constraint Jacobian and matrices computed from it. const TfToken sparse; + /// \brief "CollisionAPI" + /// + /// Schema identifer and family for MjcPhysicsCollisionAPI + const TfToken CollisionAPI; + /// \brief "MeshCollisionAPI" + /// + /// Schema identifer and family for MjcPhysicsMeshCollisionAPI + const TfToken MeshCollisionAPI; /// \brief "SceneAPI" /// /// Schema identifer and family for MjcPhysicsSceneAPI