Nodes/comfyui_cv/CV 3D Object Transform
ComfyUI Node

CV 3D Object Transform

Places a 3D model, from ONE set of numbers, in BOTH lanes that can carry a placement: the 'object_transform' string 'CV Preview 3D (Calibrated Camera)' renders with, and the 4x4 'CV Transform Points 3D' applies to the mesh 'CV Mesh From 3D Model' pulled out of the same file. Those two live in DIFFERENT coordinate systems - the viewer is Three.js (Y up), OpenCV is Y down - so driving them from two hand-typed values is how a render and a tracker end up disagreeing about where the object is. Set 'space' to whatever 'CV Mesh From 3D Model'.axis_convention is set to, type the numbers in that space, and the conversion is done for you. 'model_up' then stands the model on the target plane, so the 'rotate_x_deg = -90' the AR workflows type by hand is a dropdown. 'CV Parse Object Transform' is the return leg, for a placement dragged out with the viewer's gizmo.

By bmad4ever·Created 3 months ago·Updated 2 days ago· 0
CV 3D Object Transform
    • object_transform
    • matrix
    spaceOpenCV (Y down, Z into the scene)
    model_upleave as the file has it
    position_x0.00
    position_y0.00
    position_z0.00
    rotate_x_deg0
    rotate_y_deg0
    rotate_z_deg0
    scale1.00
    Categoryimage/CV/low-level

    Inputs (9)

    NameTypeDefaultDescription
    spaceCOMBOOpenCV (Y down, Z into the scene)Which convention the numbers below are written in, and the space 'matrix' comes back in - match it to 'CV Mesh From 3D Model'.axis_convention. The two are the same scene under a 180 degree roll about X (both right-handed), so this says how to READ the numbers below rather than what to do to the model: type y/z (and y/z rotations) with the opposite sign in the other space and the result is identical. Flipping this ALONE therefore does move the model - it is not a free switch, it is a promise about what your numbers mean. To turn the model on purpose, use 'model_up' and rotate_*. The 'object_transform' string is always Three.js whatever this says, because that is what the viewer reads.
    model_upCOMBOleave as the file has itWhich axis points UP inside the model FILE - a one-off turn that stands it on the calibration target, applied before your rotate_* values so those stay a free nudge on top. Note that UP here is the target's own normal (OpenCV +Z, since the markers lie in its XY plane), NOT +/-Y: a stock +Y-up GLB arrives lying flat across the board. Most GLB is +Y up (the manual equivalent is rotate_x_deg = -90); Blender/CAD/OBJ geometry is usually +Z up. Leave it alone for a model already authored to stand. Not the same job as 'space': that only renames a placement, this moves the model.
    position_xFLOAT0.00-1000000–1000000Translation along X, in the SAME units as the mesh and the camera pose (metres, if the calibration is). Applied last, after the rotation.
    position_yFLOAT0.00-1000000–1000000Translation along Y. This axis flips with 'space' - +Y is UP in Three.js, DOWN in OpenCV - so the same number moves the model opposite ways.
    position_zFLOAT0.00-1000000–1000000Translation along Z: OFF the target plane, since the board normal is the up direction here. +Z runs into the scene in OpenCV, toward the viewer in Three.js.
    rotate_x_degFLOAT0-360–360Rotation about X, in degrees, about the mesh ORIGIN (use 'CV Mesh From 3D Model'.recenter to spin about the object's own centre). Applied FIRST of the three, and after 'model_up' - tilt, once the model already stands.
    rotate_y_degFLOAT0-360–360Rotation about Y, in degrees. Applied second - the full order is Rz . Ry . Rx, matching the 'CV Transform Points (Scale, Rotate, Translate)' blueprint.
    rotate_z_degFLOAT0-360–360Rotation about Z, in degrees. Applied LAST of the three - with 'model_up' set, this is the one that aims the standing model (its yaw about the board normal).
    scaleFLOAT1.000.000001–1000000Uniform scale, applied before rotation and translation. Reconciles authoring units with the calibration (centimetres against a pose in metres needs 0.01) - a scale error reads as an object at the right bearing and the wrong depth.

    Outputs (2)

    NameTypeDescription
    object_transformSTRINGJSON for the 'object_transform' input of 'CV Preview 3D (Calibrated Camera)': position, quaternion [x, y, z, w] and scale in Three.js world space. Convert that widget to an input and wire this into it; the viewer's gizmo then only previews, because this value wins on the next run.
    matrixNPARRAYThe same placement as a 4x4 float64 model matrix, in the selected 'space'. Feed it to 'CV Transform Points 3D' to move the mesh (or annotation anchors, or a point cloud) exactly the way the render moved the model.