Nodes/Pixar's OpenUSD/Create USD Quaternion
ComfyUI Node

Create USD Quaternion

Rotations as (w,x,y,z), not Euler angles

By cjhosken·Created 3 months ago·Updated 2 months ago· 9
Create USD Quaternion
  • rotation
  • quat
quat_precisionquatf
normalizetrue

Quaternions are the "actually correct" way to store a rotation, and USD stores them natively. Create USD Quaternion takes a (w, x, y, z) - the four floats that make up a quaternion - and wraps them in a proper USD Quatf/Quatd value for the pack's attribute and scripting nodes. If you're setting a rotation attribute on a prim directly (rather than going through a transform node), this is the correctly-typed value to hand over.

Do you need quaternions for the stuff most people do with this pack? Probably not - for casual scene building you'd reach for Create USD Matrix, which builds transforms from friendlier translation/rotation/scale inputs. Quaternions earn their keep when you're doing real math: interpolating between rotations, avoiding gimbal lock, or interoperating with an engine or DCC that stores rotations as quats. This node is for that tier of work.

The inputs

  • rotation - a VEC4 socket carrying (w, x, y, z), which is the quaternion's real part first, then the imaginary vector. Wire it from a Create USD Vec4 node. Note the ordering: it's w-first, not x-first - a classic source of silent wrongness.
  • quat_precision - quatf (float, default), quatd (double), or quath (half - with the pack's usual caveat that half is stored as float in the Python layer; there's no true half quaternion in USD).
  • normalize - boolean, on by default. Normalizing makes the quaternion unit-length, which is what rotation math assumes. Leave it on; an unnormalized quaternion is a unit quaternion with a bug in it.

Output is a single USD_VALUE socket with the typed quaternion.

How it works

The node constructs the USD quaternion (Gf.Quatf(real, imaginary_vec)), normalizes it if asked, and emits the {"data": ..., "type": ...} dict the pack's attribute machinery consumes. Nothing surprising - the work is all in getting the component order and the normalization right, which it does for you.

Install & caveats

Pack install: ComfyUI Manager → search "ComfyUI-OpenUSD", or

cd ComfyUI/custom_nodes
git clone https://github.com/cjhosken/ComfyUI-OpenUSD

then restart. Deps: usd-core==26.5, numpy==2.5.0, trimesh.

Caveats: the USD_VALUE socket is pack-private, and the w-first ordering is the thing most likely to trip you up - double-check that the VEC4 feeding it has real first. If a rotation "looks scrambled," it's almost always an ordering or normalization issue, both of which this node exists to prevent.

Category3d/usd/type

Inputs (3)

NameTypeDefaultDescription
rotationVEC4
quat_precisionCOMBOquatf3 options: quatf, quatd, quath
normalizeBOOLEANtrue

Outputs (1)

NameTypeDescription
quatUSD_VALUE