PhysicsSphericalJoint#
Ball joint: three rotational degrees of freedom about a common point, optionally bounded by an elliptical cone given as two half-angles in degrees. Inherits every PhysicsJoint column and adds the cone axis and the two cone half-angles. Standalone it is a PxD6Joint with the three linear axes locked and the swing axes limited by a PxJointLimitCone; inside an articulation it is an eSPHERICAL joint with eTWIST free and symmetric eSWING1/eSWING2 limits.
Type chain:
Imageable,Typed,PhysicsJointExtends:
PhysicsJoint; its columns, derived values, interactions and findings are inherited and listed here.Applicable APIs:
PhysicsArticulationRootAPI,PhysicsDriveAPI,PhysicsJointStateAPI,PhysicsLimitAPI,PhysicsMaterialAPI,PhysxArticulationAPI,PhysxDrivePerformanceEnvelopeAPI,PhysxJointAPI,PhysxJointAxisAPI,PhysxLimitAPI,PhysxMaterialAPI,PhysxPhysicsDistanceJointAPI,PhysxSceneAPIDiscovery: by prim_type, probe
physics:localPos0Transform columns: none, not
XformableUses blocks:
prim
What USD population writes#
As PhysicsJoint; additionally publishes physics:axis, physics:coneAngle0Limit and physics:coneAngle1Limit at their resolved values (X, -1, -1 when unauthored).
Columns#
Raw fallback is the USD schema value. Producer writes is what ovstage population puts in the column for a USD stage. Parser default applies on the consumer when the column is absent, in stage units. diverges means writing the raw fallback literally parses differently from omitting the column (the parser default): USD population may well publish that very value for an unauthored attribute, so the marker is about the column being present, not about its value.
Column |
Type |
Units |
Raw fallback |
Producer writes |
Parser default |
If absent |
|---|---|---|---|---|---|---|
|
uint64 array, RELATIONSHIP_PATH_ID |
not written |
Side 0 anchors to the world. The consumer keeps localPos0/localRot0 verbatim as a world-space frame (only the quaternion is normalised, no body scale is baked) and, for articulations, treats the joint as a fixed-base anchor candidate. Only the first target is read; it is resolved to the nearest enclosing enabled rigid body, which may differ from the target itself. |
|||
|
uint64 array, RELATIONSHIP_PATH_ID |
not written |
Side 1 anchors to the world; see physics:body0. A joint with both relationships absent is still enumerated and parsed but no PhysX joint is created (no actor on either side). |
|||
|
float32[3], POINT |
length |
(0, 0, 0) |
resolved USD value (authored, else raw fallback) |
(0, 0, 0) |
Frame origin at the body-0 origin. Stored in stage length units; there is no metersPerUnit scaling, but the resolved body’s world scale is multiplied component-wise into the authored value because PhysX actors carry no scale (localPos0 (1,1,1) under scale (2,3,4) reaches PhysX as (2,3,4)). When the relationship target is not the resolved body the frame is lifted to world through the target and pulled back into the body frame with scale and shear removed. |
|
float32[4], QUATERNION |
none |
(0, 0, 0, 1) |
resolved USD value (authored, else raw fallback) |
(0, 0, 0, 1) |
Identity rotation. The consumer normalises the quaternion unconditionally, even when the body relationship is absent. |
|
float32[3], POINT |
length |
(0, 0, 0) |
resolved USD value (authored, else raw fallback) |
(0, 0, 0) |
Frame origin at the body-1 origin. Same scale and re-anchoring rules as physics:localPos0. |
|
float32[4], QUATERNION |
none |
(0, 0, 0, 1) |
resolved USD value (authored, else raw fallback) |
(0, 0, 0, 1) |
Identity rotation; see physics:localRot0. |
|
bool8 |
none |
true |
resolved USD value (authored, else raw fallback) |
true |
Joint is created and simulated. false creates no PhysX joint and removes the joint from the articulation graph entirely. |
|
bool8 |
none |
false |
resolved USD value (authored, else raw fallback) |
false |
Collision between the two jointed bodies is disabled. |
|
float32 |
mass*length/s^2 |
|
resolved USD value (authored, else raw fallback) |
|
Unbreakable. The consumer seeds FLT_MAX before reading; the USD schema fallback is inf. Either value reaches PhysX as FLT_MAX because the runtime maps every non-finite break force to FLT_MAX. |
|
float32 |
mass*length^2/s^2 |
|
resolved USD value (authored, else raw fallback) |
|
Unbreakable; see physics:breakForce. |
|
bool8 |
none |
false |
resolved USD value (authored, else raw fallback) |
false |
The joint is a candidate articulation joint: inside an articulation subtree it becomes a PxArticulationJointReducedCoordinate and its body-to-world side (if any) elects a fixed base. true keeps it a standalone PxJoint (graph weight +1000 instead of +100000/+100, no recursion through it). |
|
uint64, TOKEN_ID |
none |
X |
resolved USD value (authored, else raw fallback) |
X |
Cone axis is local X. Only Y and Z are matched; any other token falls back to X. For Y or Z the runtime post-multiplies the axis fixup plus an extra 90 degree twist so the cone half-angles keep their meaning. |
|
float32 |
deg (deg_to_rad) |
-1.0 |
resolved USD value (authored, else raw fallback) |
0.0 |
CAUTION: an absent column leaves the half-angle at 0 and the AND-form enable rule (both bounds finite and non-negative) activates a zero-width cone, locking both swing axes. USD population publishes the resolved -1, which disables the cone; -1 is safe to write literally. |
|
float32 |
deg (deg_to_rad) |
-1.0 |
resolved USD value (authored, else raw fallback) |
0.0 |
Same trap as physics:coneAngle0Limit. -1 is safe to write literally. |
Interactions#
prim: When a body relationship is absent (or its target resolves to no enabled dynamic body) that side of the joint is anchored to the world: the authored local frame is used verbatim in world space and no body scale is baked into it. When a body resolves, its world scale, decomposed from the composed transform, is multiplied component-wise into localPos on that side.PhysicsRigidBodyAPI: body0/body1 are resolved to the nearest enclosing prim with an enabling rigid body. Without an actor on at least one side no PhysX joint is created.PhysicsArticulationRootAPI: A joint with one side anchored to the world (absent relationship, or a static, disabled or kinematic body) and excludeFromArticulation false becomes the fixed-base anchor of an articulation that contains its other body; the joint prim itself is elected root and fixBase is set.PhysxJointAPI: The producer creates physxJoint:maxJointVelocity = FLT_MAX on every joint-typed prim when unauthored, even without PhysxJointAPI in usd-schemas; the consumer ignores it unless the API is listed.PhysicsLimitAPI: Only a prim typed exactly PhysicsJoint (the D6) reads PhysicsLimitAPI:; typed joints read their own limit columns. PhysicsDriveAPI: The D6 reads PhysicsDriveAPI:transX..rotZ and :distance; revolute reads :angular, prismatic reads :linear; the other subtypes read no drive.PhysxLimitAPI: Reads PhysxLimitAPI:cone (not rotX/rotY) for the cone’s restitution, bounceThreshold, stiffness and damping.PhysxJointAxisAPI: Reads all three of PhysxJointAxisAPI:rotX, :rotY, :rotZ with rotational conversions, mapped to eTWIST, eSWING1, eSWING2 on articulation joints; ignored with a warning on standalone joints.PhysicsDriveAPI: No drive is read for a spherical joint, and no performance envelope.PhysicsJointStateAPI: Never read for a spherical joint: SphericalPhysxJointDesc::state exists but is never populated.
Known divergences#
note (consumer)
physics:breakForce: The ovstage walker seeds breakForce/breakTorque with FLT_MAX while the USD walker leaves the schema fallback inf, so the descriptor differs bit-for-bit between backends when the columns are unauthored. No simulation difference: the runtime maps any non-finite value to FLT_MAX before calling PxJoint::setBreakForce.fragile (consumer)
physics:localRot0: The PhysxJointDesc constructor default for localPose0Orientation/localPose1Orientation is {1, 0, 0, 0} in the (x, y, z, w) layout, a 180 degree rotation about X rather than identity. Masked today because copyBaseFields always overwrites it from JointInfo, whose default {0, 0, 0, 1} is identity. Any future path that builds a joint descriptor without copyBaseFields inherits a flipped frame.note (producer)
physics:localRot0: Quaternion lanes are published (x, y, z, w) although USD authors (w, x, y, z); the consumer reads the lanes verbatim. A hand populator that copies the USD tuple order produces a wrong frame with no diagnostic. Also applies to physics:localRot1.defect (consumer)
physics:coneAngle0Limit: Absent coneAngle0Limit/coneAngle1Limit columns leave both half-angles at 0, which satisfies the non-negative AND rule and activates a zero cone. PhysX rejects it: PxJointLimitCone::isValid requires 0 < angle < pi, so PxD6Joint::setSwingLimit reports ‘limit invalid’ through the error callback and the swing limit is not applied (the contract test bootstrap treats the error as fatal, which is why spherical_joint_pair authors both angles in every variant). Masked on producer-populated stages, which publish -1 and leave the swing axes free with the PhysX default cone (bounceThreshold 0.5).
Notes#
Instance matrix for this type: PhysxLimitAPI:cone; PhysxJointAxisAPI:rotX, :rotY, :rotZ; no PhysicsDriveAPI, no PhysxDrivePerformanceEnvelopeAPI, no PhysicsJointStateAPI. PhysicsLimitAPI is not read.
The cone enable rule is AND with non-negativity, unlike the OR rule of revolute/prismatic/D6, and is identical on both backends.