class MAGES::MeshDeformations::AutoUV

Overview

Procedural per-wedge UV atlas generator for triangular meshes whose triangles are topologically separate — every triangle owns its own three vertices and no vertex index is shared between triangles (the “fully split” render meshes produced by DynamicSoftbodyActor / simulation meshes). More…

class AutoUV
{
public:
    // classes

    class PeelLayer;
    class TriangleGrid;

    // fields

    static const float DefaultPadding = 0.001f;
    static const float DefaultChartAngleDegrees = 45f;

    // methods

    static float2[] Generate(float3[] vertices, int[] indices);
    static float2[] Generate(float3[] vertices, int[] indices, float padding);

    static float2[] Generate(
        float3[] vertices,
        int[] indices,
        float padding,
        bool assumeHull
    );

    static float2[] Generate(
        float3[] vertices,
        int[] indices,
        float padding,
        bool assumeHull,
        float chartAngleDegrees
    );
};

Detailed Documentation

Procedural per-wedge UV atlas generator for triangular meshes whose triangles are topologically separate — every triangle owns its own three vertices and no vertex index is shared between triangles (the “fully split” render meshes produced by DynamicSoftbodyActor / simulation meshes).

Because vertices are unique per triangle, topology-based unwrappers only produce disconnected triangles. Instead AutoUV grows orientation-coherent charts : face adjacency (which the fully split index buffer does not carry) is recovered by welding coincident corner positions, then a flood-fill collects each connected run of hull faces whose normals stay within the chart cone half-angle (DefaultChartAngleDegrees unless overridden) of the chart’s running average normal. Each chart is projected orthographically onto the plane perpendicular to its own area-weighted average normal — so a surface patch that is contiguous in 3D stays in one island even where it crosses the 45° boundary between two cardinal directions, instead of shattering across up to six axis islands. Because a concave patch can still stack (fold) along its projection axis, each chart is depth-peeled into layers whose projected triangles do not overlap; every layer becomes an island. A convex / non-self-overlapping chart yields exactly one layer (a flat cube still produces the classic 6-island box layout). The islands are bin-packed into the [0,1] square at a single uniform texel density.

Precondition: the input must be fully split — indices.Length is a multiple of 3 and every group of three indices addresses three vertices used by no other triangle. The class does not defend against shared/reused indices (an editor-only assert warns when it detects reuse); results for non-split input are undefined.

Fields

static const float DefaultPadding = 0.001f

Default inter-island gutter used by the 2-argument Generate(float3[], int[]) entry point, expressed in UV units. Roughly two texels at a 1024² atlas (2 / 1024 ≈ 0.002).

static const float DefaultChartAngleDegrees = 45f

Default chart cone half-angle, in degrees, used by the entry points that do not take an explicit angle. A face normal may deviate up to this much from its chart’s running average normal and still join the chart. Larger grows bigger charts (fewer seams) but at more projection stretch; 60° keeps the worst-case stretch near 2x while still rejecting the 90° neighbours of a cube, so a flat cube reproduces the classic six-island box layout.

Methods

static float2[] Generate(float3[] vertices, int[] indices)

Generate a seamed, non-overlapping UV atlas for a fully split triangular mesh using the DefaultPadding inter-island gutter.

Parameters:

vertices

Vertex positions. One UV is produced per entry.

indices

Triangle indices (length a multiple of 3), fully split.

Returns:

One UV per input vertex; result.Length == vertices.Length.

static float2[] Generate(float3[] vertices, int[] indices, float padding)

Generate a seamed, non-overlapping UV atlas for a fully split triangular mesh.

Parameters:

vertices

Vertex positions. One UV is produced per entry.

indices

Triangle indices (length a multiple of 3), fully split.

padding

Inter-island gutter, in UV units (also used as the outer border).

Returns:

One UV per input vertex; result.Length == vertices.Length.

static float2[] Generate(
    float3[] vertices,
    int[] indices,
    float padding,
    bool assumeHull
)

Generate a seamed, non-overlapping UV atlas for a fully split triangular mesh, optionally trusting the caller’s topology instead of ray-casting to classify hull vs. interior faces. Uses the DefaultChartAngleDegrees chart cone half-angle.

Parameters:

vertices

Vertex positions. One UV is produced per entry.

indices

Triangle indices (length a multiple of 3), fully split.

padding

Inter-island gutter, in UV units (also used as the outer border).

assumeHull

When true, every non-degenerate face is treated as a hull face — the spatial grid and the outward hemisphere ray test are skipped entirely. Use this when the input is already known to be a topological boundary surface (e.g. SimulationMeshSurface.BuildBoundarySurface(SimulationMesh)), where the ray-cast hull test is redundant and can only lose real faces buried in concave pockets. When false the classic ray-cast classification runs (default; behavior unchanged).

Returns:

One UV per input vertex; result.Length == vertices.Length.

static float2[] Generate(
    float3[] vertices,
    int[] indices,
    float padding,
    bool assumeHull,
    float chartAngleDegrees
)

Generate a seamed, non-overlapping UV atlas for a fully split triangular mesh with an explicit chart cone half-angle.

Parameters:

vertices

Vertex positions. One UV is produced per entry.

indices

Triangle indices (length a multiple of 3), fully split.

padding

Inter-island gutter, in UV units (also used as the outer border).

assumeHull

See Generate(float3[], int[], float, bool).

chartAngleDegrees

The chart cone half-angle in degrees: a face joins a chart only while its normal stays within this angle of the chart’s running average normal. Larger grows bigger charts (fewer seams) at more projection stretch; smaller fragments into more, flatter charts. Clamped to [5°, 89°]. See DefaultChartAngleDegrees.

Returns:

One UV per input vertex; result.Length == vertices.Length.