Skip to content
PRODUCT GITHUB  ↗

Converting Dynamic & Procedural Meshes

URealtimeMeshDynamicMeshConverter (in the RealtimeMeshExt module — see the section overview for the Build.cs dependency) copies geometry between GeometryScript’s UDynamicMesh (UE::Geometry::FDynamicMesh3) and RMC. This is a one-shot conversion: it snapshots the geometry once. If you instead want a RealtimeMesh that continuously mirrors a UDynamicMesh as you edit it, use RealtimeMeshDynamic — that’s a different tool for a different job.

This page also covers ProceduralMeshComponent at the bottom.


At the stream-set level, CopyStreamSetFromDynamicMesh reads a FDynamicMesh3 into a stream set:

#include "RealtimeMeshDynamicMeshConverter.h"
#include "RealtimeMeshSimple.h"
using namespace RealtimeMesh;
FRealtimeMeshStreamSet StreamSet;
FStreamSetDynamicMeshConversionOptions Options;
Options.bWantNormals = true;
Options.bWantTangents = true;
Options.bWantUVs = true;
Options.bWantVertexColors = true;
Options.bWantMaterialIDs = true; // dynamic-mesh material IDs become poly groups
URealtimeMeshDynamicMeshConverter::CopyStreamSetFromDynamicMesh(SourceDynamicMesh3, StreamSet, Options);
URealtimeMeshSimple* Mesh = GetRealtimeMeshComponent()->InitializeRealtimeMesh<URealtimeMeshSimple>();
const FRealtimeMeshBufferSetKey GroupKey = FRealtimeMeshBufferSetKey::Create(0, FName("FromDynamicMesh"));
Mesh->CreateBufferSet(GroupKey, MoveTemp(StreamSet));

The Blueprint node Copy Realtime Mesh From Dynamic Mesh does the whole thing in one call — it takes a UDynamicMesh, a target URealtimeMeshSimple, and a FRealtimeMeshDynamicMeshConversionOptions (which additionally carries the target SectionGroup key), returning the mesh with a Success/Failure pin.

FStreamSetDynamicMeshConversionOptions exposes two TFunction hooks that let you transform the mesh as it’s read. These are C++-only (not UPROPERTY), so they’re available on the stream-set overloads but not from Blueprint:

FStreamSetDynamicMeshConversionOptions Options;
// Drop triangles you don't want in the output.
Options.TriangleFilterFunction =
[](const UE::Geometry::FDynamicMesh3& Mesh, int32 TriangleID)
{
return ShouldKeep(Mesh, TriangleID); // return false to skip this triangle
};
// Remap each triangle's poly-group value (e.g. collapse many groups into a few sections).
Options.PolyGroupRemapFunction =
[](const UE::Geometry::FDynamicMesh3& Mesh, int32 TriangleID)
{
return RemapGroup(Mesh, TriangleID); // returns the poly group to emit
};

There’s also bAutoSortPolyGroupsIfNecessary (on by default), which reorders triangles so each poly group is contiguous — required for the group to split cleanly into sections.


CopyStreamSetToDynamicMesh writes a stream set into a FDynamicMesh3:

UE::Geometry::FDynamicMesh3 OutMesh;
FStreamSetDynamicMeshConversionOptions Options;
const bool bAppend = false; // true appends to OutMesh instead of replacing it
URealtimeMeshDynamicMeshConverter::CopyStreamSetToDynamicMesh(StreamSet, OutMesh, Options, bAppend);

The Blueprint node Copy Realtime Mesh To Dynamic Mesh takes a URealtimeMeshSimple and a target UDynamicMesh. The final bShouldAppendToExisting parameter (on the C++ stream-set overloads) lets you accumulate several conversions into one dynamic mesh. CopyStreamSetFromDynamicMesh can also report where each poly group landed via its optional OutGroupRanges map (TMap<int32, FRealtimeMeshStreamRange>).


NodeDirection
Copy Stream Set From Dynamic MeshDynamicMesh → stream set
Copy Stream Set To Dynamic Meshstream set → DynamicMesh
Copy Realtime Mesh From Dynamic MeshDynamicMesh → RealtimeMesh
Copy Realtime Mesh To Dynamic MeshRealtimeMesh → DynamicMesh

All four expose a Success/Failure execution pin.


RMC does not provide a data converter that reads an existing UProceduralMeshComponent’s sections into a stream set (the way the static-mesh and dynamic-mesh converters do). The URealtimeMeshProceduralMeshLibrary helpers exist for API parity with UKismetProceduralMeshLibrary, but they deliberately do not mirror PMC’s static-mesh conversion helpers.

Instead, RMC’s PMC story is a drop-in replacement component. URealtimeMeshProcedural (in the core RealtimeMeshComponent module, not RealtimeMeshExt) mirrors UProceduralMeshComponent’s Blueprint surface — CreateMeshSection, CreateMeshSection_LinearColor, UpdateMeshSection, GetMeshSection, ClearMeshSection, ClearAllMeshSections, SetMeshSectionVisible, GetNumSections, AddCollisionConvexMesh, and so on — so PMC content can migrate largely by find-and-replace rather than by converting mesh data at runtime.

URealtimeMeshProceduralMeshLibrary complements it with the familiar geometry helpers (GenerateBoxMesh, CalculateTangentsForMesh, ConvertQuadToTriangles, CreateGridMeshTriangles, CreateGridMeshWelded, CreateGridMeshSplit, GetSectionFromProceduralMesh) that mirror UKismetProceduralMeshLibrary, all producing the plain CPU arrays URealtimeMeshProcedural expects.

For the full API and migration guidance, see RealtimeMeshProcedural.

If you specifically need the geometry out of a PMC as a stream set, read its section arrays with PMC’s own API (or GetSectionFromProceduralMesh for a URealtimeMeshProcedural) and feed those arrays into a TRealtimeMeshBuilderLocal — the general fill-a-stream-set pattern.