### StatusProvider::set usage example Source: https://epicgames.github.io/OpenRigLogic/api/status/Provider Shows how to create a StatusProvider and call the static set method with a status code and an interpolated argument. The example also demonstrates checking the result with isOk(). Note that formatted messages are truncated to 512 bytes and the format string must match the arguments. ```cpp sc::StatusProvider provider{StatusCode{1, "Failed to open file: %s"}}; sc::StatusProvider::set(StatusCode{1, "Failed to open file: %s"}, "rig.dna"); if (!sc::StatusProvider::isOk()) { // handle the formatted status message } ``` -------------------------------- ### translate function example Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Transforms Shows how to build a homogeneous translation matrix from a position vector and how to compose a translation onto an existing transform using the m-taking overload. ```cpp mat4 t = translate(vec3{1.0f, 2.0f, 3.0f}); // Compose onto an existing transform mat4 base = mat4::identity(); mat4 combined = translate(base, vec3{0.0f, 0.0f, 5.0f}); ``` -------------------------------- ### convert_scale usage example with sign_policy::preserve Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Transforms Example showing how to call convert_scale with coordinate systems and a scale delta, using sign_policy::preserve to keep the sign for signed scale deltas. ```cpp coord_sys maya_up{/* ... */}; coord_sys unreal_up{/* ... */}; vec3 scale_delta{0.1f, -0.2f, 0.0f}; vec3 converted = convert_scale(scale_delta, maya_up, unreal_up, sign_policy::preserve); ``` -------------------------------- ### Make Source: https://epicgames.github.io/OpenRigLogic/api/status A compile-time recursive template that builds an ISeq of a given size, starting at a given offset. ```APIDOC ## Make ### Description A compile-time recursive template that builds an ISeq of a given size, starting at a given offset. ### Module Provider ### Summary A compile-time recursive template that builds an ISeq of a given size, starting at a given offset. ``` -------------------------------- ### Construct ivec3 with initializer list Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Types Shows how to create a 3-component integer vector using brace initialization. The example initializes a variable named voxel_coord with values 1, 2, and 3. ```cpp ivec3 voxel_coord{ 1, 2, 3 }; ``` -------------------------------- ### Using pma::New to create an object Source: https://epicgames.github.io/OpenRigLogic/api/pma/ScopedPtr Shows how to use pma::New as a creator policy. The example creates a creator object and invokes it to allocate a dna::VersionInfo instance, equivalent to new dna::VersionInfo{}. ```cpp pma::New creator; auto* obj = creator(); // equivalent to new dna::VersionInfo{} ``` -------------------------------- ### Construct ivec2 with initializer list Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Types Shows how to create a 2-component integer vector using brace initialization. The example initializes a variable named pixel_coord with values 12 and 34. ```cpp ivec2 pixel_coord{ 12, 34 }; ``` -------------------------------- ### convert_rotation example Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Transforms Shows how to convert Euler angles from one coordinate system and rotation convention to another using the overload that takes source and destination coordinate systems. The change-of-basis matrix is computed internally. ```cpp coord_sys maya_up{/* ... */}; coord_sys unreal_up{/* ... */}; rad3 maya_rotation{rad{0.1f}, rad{0.2f}, rad{0.3f}}; rad3 unreal_rotation = convert_rotation(maya_rotation, maya_up, rot_seq::xyz, rot_sign{1,1,1}, unreal_up, rot_seq::zyx, rot_sign{1,1,1}); ``` -------------------------------- ### convert_position example Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Transforms Shows how to convert a position vector from one coordinate system to another using the overload that takes source and destination coordinate systems. The change-of-basis matrix is computed internally. ```cpp coord_sys maya_up{/* ... */}; coord_sys unreal_up{/* ... */}; vec3 maya_pos{10.0f, 20.0f, 30.0f}; vec3 unreal_pos = convert_position(maya_pos, maya_up, unreal_up); ``` -------------------------------- ### change_of_basis example Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Transforms Builds a change-of-basis matrix between two coordinate systems. The matrix can be reused across multiple convert_position/convert_direction calls. Both coordinate systems must have orthonormal bases. ```cpp coord_sys maya_up{/* ... */}; coord_sys unreal_up{/* ... */}; mat3 c = change_of_basis(maya_up, unreal_up); // c can now be reused across many convert_position/convert_direction calls ``` -------------------------------- ### Get and set stream position with tell and seek Source: https://epicgames.github.io/OpenRigLogic/api/trio/Concepts Uses stream->tell() to get the current position and stream->seek(0u) to move the cursor to the start. The position parameter is an offset relative to the start (0 = start). ```cpp std::uint64_t pos = stream->tell(); stream->seek(0u); // stream cursor is now at the start ``` -------------------------------- ### Create Writer and Reader, copy all or geometry layers Source: https://epicgames.github.io/OpenRigLogic/api/dna/Writer Shows how to obtain Writer and Reader instances from BinaryStream factories, then copy all layers with Preserve policy and only geometry with Discard policy. Demonstrates the two DataLayer and UnknownLayerPolicy combinations. ```cpp // Obtain a Writer instance (e.g., from BinaryStreamWriter factory) dna::Writer* writer = dna::BinaryStreamWriter::create(stream, memRes); const dna::Reader* reader = dna::BinaryStreamReader::create(inputStream, memRes); // Copy all layers, preserving any unknown data writer->setFrom(reader, dna::DataLayer::All, dna::UnknownLayerPolicy::Preserve); // Copy only geometry, discarding unrecognized layers writer->setFrom(reader, dna::DataLayer::Geometry, dna::UnknownLayerPolicy::Discard); ``` -------------------------------- ### axis_vector example: convert axis_dir to vec3 Source: https://epicgames.github.io/OpenRigLogic/api/tdm/CoordSys Shows how to use tdm::impl::axis_vector to get the unit vector for a named axis direction. The example uses tdm::axis_dir::up and expects the result {0.0f, 1.0f, 0.0f}. ```cpp tdm::vec3 upVec = tdm::impl::axis_vector(tdm::axis_dir::up); // upVec is {0.0f, 1.0f, 0.0f} ``` -------------------------------- ### tdm::length vector example Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Computations Shows how to compute the magnitude of a vector using tdm::length. The result is the Euclidean length; for this example, dist is 5.0. ```cpp tdm::vec3 displacement{3.0f, 4.0f, 0.0f}; float dist = tdm::length(displacement); // dist is 5.0 ``` -------------------------------- ### Creating and using a StreamReader with BinaryStreamReader Source: https://epicgames.github.io/OpenRigLogic/api/dna/StreamReader Shows how to create a StreamReader from a stream using BinaryStreamReader::create, call read() to load data, and then use the reader. The reader cannot be instantiated directly; use a concrete subclass. ```cpp StreamReader* reader = BinaryStreamReader::create(&stream); reader->read(); // reader now has data loaded into internal structures ``` -------------------------------- ### Create and destroy a RigLogic instance Source: https://epicgames.github.io/OpenRigLogic/api/riglogic/riglogic/RigLogic Shows the typical lifecycle of a RigLogic instance: create a configuration, create the RigLogic from a DNA reader, create a RigInstance, evaluate it, and destroy the RigLogic. The destructor is protected, so instances must be released via RigLogic::destroy, not delete. ```cpp rl4::Configuration config; rl4::RigLogic* rigLogic = rl4::RigLogic::create(dnaReader, config); rl4::RigInstance* instance = rl4::RigInstance::create(rigLogic); // ... evaluate instance ... rl4::RigLogic::destroy(rigLogic); ``` -------------------------------- ### BinaryStreamReader::create() Before Migration Source: https://epicgames.github.io/OpenRigLogic/release_notes Old signature with positional parameters for DataLayer, UnknownLayerPolicy, maxLOD, and MemoryResource. Replace with the new Configuration struct. ```cpp static BinaryStreamReader* create(BoundedIOStream* stream, DataLayer layer = DataLayer::All, UnknownLayerPolicy policy = UnknownLayerPolicy::Preserve, std::uint16_t maxLOD = 0u, MemoryResource* memRes = nullptr); ``` -------------------------------- ### Assert twist axis remapping after Maya-to-UE conversion Source: https://epicgames.github.io/OpenRigLogic/release_notes Verifies that after a Maya-to-UE coordinate system conversion, twist and swing setup twist axes are remapped to the dominant destination axis. The expected values are Z, X, Y for both twist and swing setups. ```cpp ASSERT_EQ(reader->getTwistSetupTwistAxis(0), TwistAxis::Z); ASSERT_EQ(reader->getTwistSetupTwistAxis(1), TwistAxis::X); ASSERT_EQ(reader->getTwistSetupTwistAxis(2), TwistAxis::Y); ASSERT_EQ(reader->getSwingSetupTwistAxis(0), TwistAxis::Z); ASSERT_EQ(reader->getSwingSetupTwistAxis(1), TwistAxis::X); ASSERT_EQ(reader->getSwingSetupTwistAxis(2), TwistAxis::Y); ``` -------------------------------- ### Status::getHook Source: https://epicgames.github.io/OpenRigLogic/api/status/Status Retrieves the currently installed hook function, if any. ```APIDOC ## Status::getHook ### Description Returns the currently installed hook function, if any. ### Method getHook ### Returns `HookFunction` — the currently installed hook, if any. ``` -------------------------------- ### Construct and configure a Configuration object Source: https://epicgames.github.io/OpenRigLogic/api/dna/Configuration Set layer, LOD range, and coordinate system transform policy on a Configuration instance. Use this to customize how a DNA file is loaded. ```cpp Configuration config; config.layer = DataLayer::Geometry; config.maxLOD = 0; config.minLOD = 3; config.coordinateSystemTransformPolicy = CoordinateSystemTransformPolicy::Transform; ``` -------------------------------- ### Status::setHook Source: https://epicgames.github.io/OpenRigLogic/api/status/Status Installs a hook function to intercept status messages and arguments. ```APIDOC ## Status::setHook ### Description Installs a hook function to intercept status messages and arguments. Replaces any previously registered hook silently. ### Method setHook ### Parameters - **hook** (`HookFunction`) - Required - The function to invoke for each status message and interpolation argument. ### Returns None ### Watch out for - `Status` holds global (static) state. In multi-threaded code, concurrent calls to `setHook()` and `isOk()` / `get()` are not guarded by the visible interface — establish external synchronization if the hook may be changed after initialization. - `setHook()` replaces any previously registered hook silently. If multiple subsystems need hook behavior, compose them manually before registering. ``` -------------------------------- ### Seekable::seek Source: https://epicgames.github.io/OpenRigLogic/api/trio/Concepts Moves the stream cursor to a specified offset relative to the start of the stream. ```APIDOC ## Seekable::seek ### Description Moves the stream cursor to a specified offset relative to the start of the stream. ### Method seek ### Parameters - **position** (`std::uint64_t`) - Required - Offset relative to the start of the stream (0 = start). ### Example ```cpp stream->seek(0u); // stream cursor is now at the start ``` ``` -------------------------------- ### ArrayView::begin() Source: https://epicgames.github.io/OpenRigLogic/api/arrayview/ArrayView Returns an iterator to the first element of the view. ```APIDOC ## begin() ### Description Returns an iterator to the first element of the view. ### Returns - **iterator** - Iterator to the first element. ``` -------------------------------- ### Seekable::tell Source: https://epicgames.github.io/OpenRigLogic/api/trio/Concepts Returns the current position of the stream cursor relative to the start of the stream. ```APIDOC ## Seekable::tell ### Description Returns the current position of the stream cursor relative to the start of the stream. ### Method tell ### Returns - `std::uint64_t` - The current position relative to the stream's start. ### Example ```cpp std::uint64_t pos = stream->tell(); ``` ``` -------------------------------- ### Basic BoundedIOStream usage: open, size, close Source: https://epicgames.github.io/OpenRigLogic/api/trio/Stream Shows how to obtain a BoundedIOStream pointer from a concrete implementation, open it, retrieve its size, and close it. Note that the stream pointer is obtained from a concrete implementation, and the example does not include error handling. ```cpp trio::BoundedIOStream* stream = /* obtained from a concrete implementation */; stream->open(); std::uint64_t total = stream->size(); stream->close(); ``` -------------------------------- ### Populate GUI-to-raw mapping and PSD expressions Source: https://epicgames.github.io/OpenRigLogic/api/dna/layers/BehaviorWriter Shows how to use BehaviorWriter setters to populate GUI-to-raw mapping and PSD expressions. The example assumes writer is a BehaviorWriter pointer and that the data arrays (guiInputIdx, rawOutputIdx, fromVals, slopes, cuts, psdRows, psdCols, psdWeights) and psdCount are already defined. Setters copy from the source address, so the caller retains ownership of the buffers. ```cpp // Populate GUI-to-raw mapping writer->setGUIToRawInputIndices(guiInputIdx.data(), static_cast(guiInputIdx.size())); writer->setGUIToRawOutputIndices(rawOutputIdx.data(), static_cast(rawOutputIdx.size())); writer->setGUIToRawFromValues(fromVals.data(), static_cast(fromVals.size())); writer->setGUIToRawSlopeValues(slopes.data(), static_cast(slopes.size())); writer->setGUIToRawCutValues(cuts.data(), static_cast(cuts.size())); // Populate PSD expressions writer->setPSDCount(static_cast(psdCount)); writer->setPSDRowIndices(psdRows.data(), static_cast(psdRows.size())); writer->setPSDColumnIndices(psdCols.data(), static_cast(psdCols.size())); writer->setPSDValues(psdWeights.data(), static_cast(psdWeights.size())); ``` -------------------------------- ### pi Source: https://epicgames.github.io/OpenRigLogic/api/tdm Get the value of π as a compile-time constant for use in angle conversions and trigonometric calculations. ```APIDOC ## pi ### Description Get the value of π as a compile-time constant for use in angle conversions and trigonometric calculations. ### Module Ang ### Summary Get the value of π as a compile-time constant for use in angle conversions and trigonometric calculations. ``` -------------------------------- ### RigInstance RBF Controls Source: https://epicgames.github.io/OpenRigLogic/api/riglogic/riglogic/RigInstance Methods to get RBF (radial basis function) control values on a RigInstance. ```APIDOC ## RigInstance RBF Controls ### Description Methods to get RBF (radial basis function) control values on a RigInstance. ### Methods - `getRBFControlCount()` - Returns the number of RBF controls. - `getRBFControl(index)` - Returns the value of the RBF control at the given index. - `getRBFControlValues()` - Returns an array of all RBF control values. ### Parameters - **index** (unsigned int) - Required - The zero-based index of the control. ### Returns - `getRBFControlCount` - unsigned int - The number of RBF controls. - `getRBFControl` - float - The value of the control. - `getRBFControlValues` - float* - Pointer to the array of control values. ``` -------------------------------- ### BinaryStreamReader::create() After Migration Source: https://epicgames.github.io/OpenRigLogic/release_notes New signature using a single dna::Configuration struct as the second argument. Set cfg.layer, cfg.unknownLayerPolicy, cfg.maxLOD, and cfg.minLOD before passing. ```cpp static BinaryStreamReader* create(BoundedIOStream* stream, const Configuration& config = {}, MemoryResource* memRes = nullptr); ``` -------------------------------- ### DescriptorWriter usage example Source: https://epicgames.github.io/OpenRigLogic/api/dna/layers/DescriptorWriter Shows how to set character metadata, coordinate conventions, LOD levels, and database info using a DescriptorWriter obtained from a Writer subclass. Note that strings are copied, and passing nullptr to setMetaData deletes the key. ```cpp // Obtain a writer from BinaryStreamWriter or equivalent Writer subclass. // DescriptorWriter* dw = writer->getDescriptorWriter(); dw->setName("Ada"); dw->setArchetype(Archetype::other); dw->setGender(Gender::female); dw->setAge(30); // Coordinate frame: Y-up, centimetre, XYZ rotation order. dw->setTranslationUnit(TranslationUnit::cm); dw->setCoordinateSystem(CoordinateSystem::RightHand_YUp); dw->setRotationUnit(RotationUnit::degrees); dw->setRotationSequence(RotationSequence::XYZ); // Six LOD levels: 0 (highest detail) ... 5 (lowest). dw->setLODCount(6); dw->setDBMaxLOD(5); // Optional key-value metadata; overwrite or delete by key. dw->setMetaData("rig_version", "2.4.1"); dw->setMetaData("obsolete_key", nullptr); // deletes the entry dw->setDBComplexity("Face"); dw->setDBName("MetaHumans"); ``` -------------------------------- ### RigInstance PSD Controls Source: https://epicgames.github.io/OpenRigLogic/api/riglogic/riglogic/RigInstance Methods to get PSD (pose space deformation) control values on a RigInstance. ```APIDOC ## RigInstance PSD Controls ### Description Methods to get PSD (pose space deformation) control values on a RigInstance. ### Methods - `getPSDControlCount()` - Returns the number of PSD controls. - `getPSDControl(index)` - Returns the value of the PSD control at the given index. - `getPSDControlValues()` - Returns an array of all PSD control values. ### Parameters - **index** (unsigned int) - Required - The zero-based index of the control. ### Returns - `getPSDControlCount` - unsigned int - The number of PSD controls. - `getPSDControl` - float - The value of the control. - `getPSDControlValues` - float* - Pointer to the array of control values. ``` -------------------------------- ### MakeISeq Source: https://epicgames.github.io/OpenRigLogic/api/status A convenience alias for Make::Type, producing an ISeq of Size indices starting at Offset. ```APIDOC ## MakeISeq ### Description A convenience alias for Make::Type, producing an ISeq of Size indices starting at Offset. ### Module Provider ### Summary A convenience alias for Make::Type, producing an ISeq of Size indices starting at Offset. ``` -------------------------------- ### Create, use, and destroy a RigInstance Source: https://epicgames.github.io/OpenRigLogic/api/riglogic/riglogic/RigInstance Shows the full lifecycle of a RigInstance: create it from a RigLogic instance, set a GUI control value, read the joint outputs, and destroy it. The destructor is protected, so instances must be released through RigInstance::destroy, not delete; skipping destroy leaks memory. A RigInstance created from one RigLogic instance cannot be evaluated by a different RigLogic instance. ```cpp rl4::RigInstance* instance = rl4::RigInstance::create(rigLogic); instance->setGUIControl(0, 0.75f); auto joints = instance->getJointOutputs(); rl4::RigInstance::destroy(instance); ``` -------------------------------- ### Construct ivec4 with initializer list Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Types Shows how to construct a 4-component integer vector using an initializer list with values 0, 0, 128, 128. ```cpp ivec4 rect{ 0, 0, 128, 128 }; ``` -------------------------------- ### Normal Source: https://epicgames.github.io/OpenRigLogic/api/dna/layers/Geometry Type alias for Vector3 representing a vertex normal. Construction example shows how to create a Normal value. ```APIDOC ## Normal ### Description Type alias for `Vector3` that represents a vertex normal. Surface normals must be interpreted as unit-length direction vectors; normalizing them incorrectly or treating them as positional data produces rendering artifacts. ### Type Alias `Normal` is an alias for `Vector3`. ### Construction ```cpp dna::Normal n = dna::Vector3{0.0f, 0.0f, 1.0f}; ``` ### Relationships - `Position` — sibling alias of Vector3 - `Delta` — sibling alias of Vector3; used for blend-shape displacements - `VertexLayout` — holds an index into the normal array ``` -------------------------------- ### DescriptorWriter Class Reference Source: https://epicgames.github.io/OpenRigLogic/api/dna/layers/DescriptorWriter Documentation for the DescriptorWriter class, including its purpose, method groups, parameters, and usage example. ```APIDOC ## DescriptorWriter ### Description Write metadata about the character and the rig: name, archetype, gender, age, key-value metadata, coordinate conventions, LOD count and database info. ### When to use this Use it when you author a DNA and need to set its descriptor. Implementors should inherit from `Writer` itself, not from this class. ### Method Groups | Group | Methods | |---|---| | Character | setName, setArchetype, setGender, setAge | | MetaData | clearMetaData, setMetaData | | Conventions | setTranslationUnit, setRotationUnit, setCoordinateSystem, setRotationSequence, setRotationSign, setFaceWindingOrder | | LOD | setLODCount, setDBMaxLOD | | DB | setDBComplexity, setDBName | ### Example ```cpp // Obtain a writer from BinaryStreamWriter or equivalent Writer subclass. // DescriptorWriter* dw = writer->getDescriptorWriter(); dw->setName("Ada"); dw->setArchetype(Archetype::other); dw->setGender(Gender::female); dw->setAge(30); // Coordinate frame: Y-up, centimetre, XYZ rotation order. dw->setTranslationUnit(TranslationUnit::cm); dw->setCoordinateSystem(CoordinateSystem::RightHand_YUp); dw->setRotationUnit(RotationUnit::degrees); dw->setRotationSequence(RotationSequence::XYZ); // Six LOD levels: 0 (highest detail) ... 5 (lowest). dw->setLODCount(6); dw->setDBMaxLOD(5); // Optional key-value metadata; overwrite or delete by key. dw->setMetaData("rig_version", "2.4.1"); dw->setMetaData("obsolete_key", nullptr); // deletes the entry dw->setDBComplexity("Face"); dw->setDBName("MetaHumans"); ``` ### Parameters | Name | Type | Description | |---|---|---| | `name` _(setName)_ | `const char*` | required — null-terminated character name; the string is copied (allocation occurs). | | `archetype` | `Archetype` | required — enum value describing the character archetype. | | `gender` | `Gender` | required — enum value describing the character gender. | | `age` | `std::uint16_t` | required — character age in years. | | `key` _(setMetaData)_ | `const char*` | required — unique null-terminated key; duplicate calls overwrite the previous value. | | `value` _(setMetaData)_ | `const char*` | required — null-terminated metadata value; pass `nullptr` to delete the key. | | `unit` _(setTranslationUnit)_ | `TranslationUnit` | required — spatial unit for translation values (e.g., centimetres, metres). | | `unit` _(setRotationUnit)_ | `RotationUnit` | required — angular unit for rotation values (e.g., degrees, radians). | | `system` | `CoordinateSystem` | required — handedness and up-axis convention for the rig. | | `rotationSequence` | `RotationSequence` | required — Euler rotation application order (e.g., XYZ). | | `rotationSign` | `const RotationSign&` | required — sign convention for rotation axes. | | `faceWindingOrder` | `FaceWindingOrder` | required — vertex winding order for face geometry. | | `lodCount` _(setLODCount)_ | `std::uint16_t` | required — total number of LOD levels; level 0 is highest detail. | | `lod` _(setDBMaxLOD)_ | `std::uint16_t` | required — maximum LOD index stored in the DNA data for this character. | | `name` _(setDBComplexity)_ | `const char*` | required — null-terminated name of the input control interface; string is copied. | | `name` _(setDBName)_ | `const char*` | required — null-terminated name of the originating database; string is copied. | ### Watch out for - Consecutive `setMetaData` calls with the same key overwrite existing data. - Passing nullptr as the value removes the key. - Strings are copied, which costs an additional allocation. - Do not subclass `DescriptorWriter` directly — the class docstring states that implementors must inherit from `Writer` itself. Subclassing `DescriptorWriter` bypasses the full writer contract. - Passing `nullptr` as the `value` argument to `setMetaData` deletes the associated key rather than storing a null value. This is a deletion shortcut, not a no-op. - Every `const char*` name or value is copied internally, so the caller's buffer may be freed after the call — but each copy involves an allocation; avoid calling string setters in tight per-frame loops. ``` -------------------------------- ### Create and destroy a MemoryMappedFileStream Source: https://epicgames.github.io/OpenRigLogic/api/trio/streams/MemoryMappedFileStream Shows how to create a memory-mapped file stream with create() and release it with destroy(). The user must call destroy() explicitly; the pointer is not RAII-managed. Copy operations are deleted, and after a move the source instance is invalid. ```cpp trio::MemoryMappedFileStream* stream = trio::MemoryMappedFileStream::create("character.dna", trio::AccessMode::Read); // ... use stream via BoundedIOStream / Buffered / Resizable interfaces ... trio::MemoryMappedFileStream::destroy(stream); ``` -------------------------------- ### RigInstance ML Controls Source: https://epicgames.github.io/OpenRigLogic/api/riglogic/riglogic/RigInstance Methods to get ML (machine learning) control values and related metadata on a RigInstance. ```APIDOC ## RigInstance ML Controls ### Description Methods to get ML (machine learning) control values and related metadata on a RigInstance. ### Methods - `getMLControlCount()` - Returns the number of ML controls. - `getMLControl(index)` - Returns the value of the ML control at the given index. - `getMLControlValues()` - Returns an array of all ML control values. - `getMLTypeCount()` - Returns the number of ML types. - `getMLOperationSetCount()` - Returns the number of ML operation sets. - `getMLOperationCount()` - Returns the number of ML operations. - `getMLMaskValues()` - Returns an array of ML mask values. ### Parameters - **index** (unsigned int) - Required - The zero-based index of the control. ### Returns - `getMLControlCount` - unsigned int - The number of ML controls. - `getMLControl` - float - The value of the control. - `getMLControlValues` - float* - Pointer to the array of control values. - `getMLTypeCount` - unsigned int - The number of ML types. - `getMLOperationSetCount` - unsigned int - The number of ML operation sets. - `getMLOperationCount` - unsigned int - The number of ML operations. - `getMLMaskValues` - float* - Pointer to the array of mask values. ``` -------------------------------- ### Create JSONStreamWriter, set from binary reader, write, and destroy Source: https://epicgames.github.io/OpenRigLogic/api/dna/JSONStreamWriter Use this example to export binary DNA to JSON. It creates a JSONStreamWriter with an indent width of 4, copies data from a binaryReader using DataLayer::All and UnknownLayerPolicy::Preserve, writes the output, and destroys the writer. You own the returned pointer; forgetting to call destroy leaks memory. ```cpp FileStream stream("rig.json", FileStream::AccessMode::Write, FileStream::OpenMode::Text); JSONStreamWriter* writer = JSONStreamWriter::create(&stream, 4u); writer->setFrom(binaryReader, DataLayer::All, UnknownLayerPolicy::Preserve); writer->write(); JSONStreamWriter::destroy(writer); ``` -------------------------------- ### ScopedPtr Construction with Default and Custom Destroyers Source: https://epicgames.github.io/OpenRigLogic/api/pma/ScopedPtr Shows two construction patterns: using the default delete destroyer with direct initialization, and using makeScoped with custom FactoryCreate/FactoryDestroy policies for an ArenaMemoryResource. ```cpp // Default destroyer (delete) pma::ScopedPtr owned{new Impl{}}; // Custom destroyer via makeScoped auto arena = pma::makeScoped, FactoryDestroy>(regionSize, growthFactor, upstream); ``` -------------------------------- ### RigInstance GUI Controls Source: https://epicgames.github.io/OpenRigLogic/api/riglogic/riglogic/RigInstance Methods to get and set GUI control values on a RigInstance. These are the high-level controls that drive the rig. ```APIDOC ## RigInstance GUI Controls ### Description Methods to get and set GUI control values on a RigInstance. These are the high-level controls that drive the rig. ### Methods - `getGUIControlCount()` - Returns the number of GUI controls. - `getGUIControl(index)` - Returns the value of the GUI control at the given index. - `setGUIControl(index, value)` - Sets the value of the GUI control at the given index. - `getGUIControlValues()` - Returns an array of all GUI control values. ### Parameters - **index** (unsigned int) - Required - The zero-based index of the control. - **value** (float) - Required - The value to set for the control. ### Returns - `getGUIControlCount` - unsigned int - The number of GUI controls. - `getGUIControl` - float - The value of the control. - `getGUIControlValues` - float* - Pointer to the array of control values. ### Example ```cpp instance->setGUIControl(0, 0.75f); ``` ``` -------------------------------- ### Status Source: https://epicgames.github.io/OpenRigLogic/api/status Provides read access to the current status and lets callers install a hook to intercept status messages and arguments. ```APIDOC ## Status ### Description Provides read access to the current status and lets callers install a hook to intercept status messages and arguments. ### Module Status ### Summary Provides read access to the current status and lets callers install a hook to intercept status messages and arguments. ``` -------------------------------- ### BinaryStreamWriter usage example Source: https://epicgames.github.io/OpenRigLogic/api/dna/BinaryStreamWriter Creates a BinaryStreamWriter, copies data from a BinaryStreamReader, writes to a file stream, and destroys the writer. Requires a BinaryStreamReader instance and a writable binary stream. The writer must be destroyed with destroy(), not delete. ```cpp FileStream stream("output.dna", FileStream::AccessMode::Write, FileStream::OpenMode::Binary); BinaryStreamWriter* writer = BinaryStreamWriter::create(&stream); writer->setFrom(binaryReader, DataLayer::All, UnknownLayerPolicy::Preserve); writer->write(); BinaryStreamWriter::destroy(writer); ``` -------------------------------- ### Reading DNA format generation and version with HeaderReader Source: https://epicgames.github.io/OpenRigLogic/api/dna/layers/HeaderReader Use this snippet to query the DNA file format generation and version from a concrete Reader instance. The example assumes a reader variable of type BinaryStreamReader or similar. The getFileFormatGeneration() method distinguishes major revisions, while getFileFormatVersion() distinguishes minor revisions within a generation. The comment shows an example output where gen == 3 and ver == 0. ```cpp // reader is a concrete Reader instance (e.g. BinaryStreamReader) HeaderReader* hdr = reader; std::uint16_t gen = hdr->getFileFormatGeneration(); std::uint16_t ver = hdr->getFileFormatVersion(); // e.g. gen == 3, ver == 0 identifies a specific DNA format revision ``` -------------------------------- ### Construct frad with radians Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Types Creates a float-precision radian angle value using the `frad` alias. The example initializes it with 1.5708 radians. ```cpp frad rotation{ 1.5708f }; ``` -------------------------------- ### convert_direction example Source: https://epicgames.github.io/OpenRigLogic/api/tdm/Transforms Converts a direction vector (e.g., normal) between coordinate systems. Renormalization is enabled by default to ensure unit length. ```cpp coord_sys maya_up{/* ... */}; coord_sys unreal_up{/* ... */}; vec3 normal{0.0f, 1.0f, 0.0f}; vec3 converted = convert_direction(normal, maya_up, unreal_up); // converted is re-normalized by default ``` -------------------------------- ### C++ example: Writing DNA definition with DefinitionWriter Source: https://epicgames.github.io/OpenRigLogic/api/dna/layers/DefinitionWriter Shows how to use a concrete Writer instance to set GUI/raw control names, joint names and hierarchy, neutral-pose translations, LOD joint mappings, blend shape channel names, and mesh blend shape channel mappings. The writer is obtained from a factory and inherits DefinitionWriter. Note that storage is resized implicitly based on the index passed in, and for joint indices the index refers to a row in a 2D matrix. ```cpp // writer is a concrete Writer* obtained from a factory (inherits DefinitionWriter) // --- GUI / Raw controls --- writer->clearGUIControlNames(); writer->setGUIControlName(0, "CTRL_L_eye_blink"); writer->setGUIControlName(1, "CTRL_R_eye_blink"); writer->clearRawControlNames(); writer->setRawControlName(0, "raw_L_eye_blink"); // --- Joints --- writer->clearJointNames(); writer->setJointName(0, "spine_01"); writer->setJointName(1, "neck_01"); writer->setJointName(2, "head"); // Joint hierarchy: spine_01 is root (index 0); neck_01 and head are children of spine_01 const std::uint16_t hierarchy[] = {0, 0, 1}; writer->setJointHierarchy(hierarchy, 3); // Neutral-pose translations const Vector3 translations[] = {{0.0f, 0.0f, 0.0f}, {0.0f, 10.0f, 0.0f}, {0.0f, 5.0f, 0.0f}}; writer->setNeutralJointTranslations(translations, 3); // Assign joints to LOD 0 via an index list const std::uint16_t lod0Joints[] = {0, 1, 2}; writer->clearJointIndices(); writer->setJointIndices(0, lod0Joints, 3); writer->clearLODJointMappings(); writer->setLODJointMapping(/*lod=*/0, /*index=*/0); // --- Blend shape channels --- writer->clearBlendShapeChannelNames(); writer->setBlendShapeChannelName(0, "browInnerUp_L"); // Associate blend shape channel 0 with mesh 0 writer->clearMeshBlendShapeChannelMappings(); writer->setMeshBlendShapeChannelMapping(/*mappingIndex=*/0, /*meshIndex=*/0, /*bsChannelIndex=*/0); ``` -------------------------------- ### RigInstance constructor Source: https://epicgames.github.io/OpenRigLogic/api/riglogic Holds the instance-specific input and output buffers for evaluating one instance of a rig, including level-of-detail and control values. ```APIDOC ## RigInstance constructor ### Description Holds the instance-specific input and output buffers for evaluating one instance of a rig, including level-of-detail and control values. ### Method constructor ### Parameters - **rigLogic** (RigLogic) - Required - The RigLogic instance that creates and evaluates this RigInstance. ### Returns A RigInstance object. ``` -------------------------------- ### PolyAllocator Class Source: https://epicgames.github.io/OpenRigLogic/api/pma/PolyAllocator Template class definition and usage example for PolyAllocator, including constructor, allocation methods, and STL allocator interface. ```APIDOC ## PolyAllocator Class ### Description A standard-library-compatible allocator that forwards allocation and construction to a runtime-supplied MemoryResource, letting containers use arbitrary memory strategies without being templated on the allocator's concrete type. ### Template Parameters - **T** (type) - The type of objects to allocate. - **Alignment** (std::size_t) - The alignment requirement for allocations. - **TDefaultMemoryResource** (class) - The default memory resource type used when no resource is supplied. ### When to use this Use this to plug a custom MemoryResource (arena, pool, tracking allocator) into std::vector, std::map, or any other allocator-aware standard container. Construct it with a MemoryResource*; passing nullptr falls back to a default (TDefaultMemoryResource) static instance. ### Method Groups | Group | Methods | | --- | --- | | Construction | PolyAllocator() (default and from MemoryResource* / nullptr / rebind-compatible allocator) | | Raw allocation | allocateBytes, deallocateBytes | | Object allocation | allocateObject, deallocateObject, newObject, deleteObject | | STL allocator interface | allocate (and the deallocate/rebind machinery inherited from scoped_allocator_adaptor) | ### Example ```cpp pma::MemoryResource* memRes = getArenaMemoryResource(); pma::PolyAllocator alloc{memRes}; std::vector> joints{alloc}; joints.push_back({1.0f, 0.0f, 0.0f}); ``` ### Parameters | Name | Type | Description | | --- | --- | --- | | memRes | MemoryResource* | optional — the backing memory resource; if nullptr, falls back to a static TDefaultMemoryResource instance. | | count | std::size_t | required (for allocateObject/deallocateObject) — number of objects to allocate/deallocate. | | alignment | std::size_t | optional — defaults to the allocator's Alignment template parameter. | ### Watch out for - Two PolyAllocator instances compare equal only if both Alignment matches and their underlying MemoryResource pointers match — allocators from different memory resources are never interchangeable. - The default-constructed default memory resource is a function-local static, guarded against clang's exit-time-destructor warning — its lifetime spans the whole program. - The default MemoryResource is a static local inside the default constructor, created once per instantiation. Its destructor runs at program exit. Clang's -Wexit-time-destructors warning is explicitly suppressed here; be aware of destruction ordering if your program relies on destructor sequencing. - Passing nullptr explicitly is equivalent to the default constructor — it does not disable allocation; it selects the static default resource. - The outer pma::PolyAllocator inherits from std::scoped_allocator_adaptor, meaning nested containers (e.g., std::vector) automatically propagate the same resource to their inner allocators. If you want independent resources per nesting level, do not use the scoped adaptor directly. ### Constraints - Thread safety of allocations depends entirely on the supplied MemoryResource. The allocator wrapper itself performs no synchronization. ``` -------------------------------- ### RigInstance Raw Controls Source: https://epicgames.github.io/OpenRigLogic/api/riglogic/riglogic/RigInstance Methods to get and set raw control values on a RigInstance. Raw controls are the low-level inputs before any processing. ```APIDOC ## RigInstance Raw Controls ### Description Methods to get and set raw control values on a RigInstance. Raw controls are the low-level inputs before any processing. ### Methods - `getRawControlCount()` - Returns the number of raw controls. - `getRawControl(index)` - Returns the value of the raw control at the given index. - `setRawControl(index, value)` - Sets the value of the raw control at the given index. - `getRawControlValues()` - Returns an array of all raw control values. ### Parameters - **index** (unsigned int) - Required - The zero-based index of the control. - **value** (float) - Required - The value to set for the control. ### Returns - `getRawControlCount` - unsigned int - The number of raw controls. - `getRawControl` - float - The value of the control. - `getRawControlValues` - float* - Pointer to the array of control values. ``` -------------------------------- ### Iterate over twist setups using TwistSwingBehaviorReader Source: https://epicgames.github.io/OpenRigLogic/api/dna/layers/TwistSwingBehaviorReader Shows how to loop through twist parameter groups, retrieving the twist axis, output joint indices, and blend weights. The reader implements Reader, which composes TwistSwingBehaviorReader. Note that the control indices are always 4 values (quaternion x, y, z, w) and blend weights are parallel to output joints. ```cpp // reader implements Reader, which composes TwistSwingBehaviorReader for (std::uint16_t twistIdx = 0u; twistIdx < reader->getTwistCount(); ++twistIdx) { auto axis = reader->getTwistSetupTwistAxis(twistIdx); auto drivenJoints = reader->getTwistOutputJointIndices(twistIdx); auto weights = reader->getTwistBlendWeights(twistIdx); } ```