CustomMesh.BuilderFromMeshData


public final class CustomMesh.BuilderFromMeshData


Builder for CustomMesh providing raw data directly.

This builder implicitly creates an underlying MeshBuffer for you. It supports creating either a static (immutable) mesh or a dynamic mesh with fixed GPU capacities that can be updated at runtime.

Static Mesh

To create an immutable mesh, provide the Session and VertexLayout, along with required initial vertex and index data:


val builder = CustomMesh.BuilderFromMeshData(session, myLayout)
     .addVertexData(myVertexData)
     .setIndexData(myIndexData)

Dynamic Mesh

To create a dynamic mesh supporting runtime updates, specify the maximum vertex and index capacities:


val builder = CustomMesh.BuilderFromMeshData(
     session,
     myLayout,
     maxVertices = 100,
     maxIndices = 300,
)

For dynamic meshes, initial vertex and index data are optional. Passing null or omitting initial data allocates zero-initialized GPU buffers up to the specified capacities. Vertex and index data can later be updated at runtime using MeshBuffer.updateVertexData and MeshBuffer.updateIndexData accessed via CustomMesh.meshBuffer.

Topology and Subsets

From here, you have two options for defining the mesh topology:

  • You can explicitly add one or more subsets:


builder.addSubset(MeshSubset(MeshSubsetTopology.TRIANGLES, 0, subset1Count))
builder.addSubset(MeshSubset(MeshSubsetTopology.TRIANGLES, subset1Count, subset2Count))
  • Or, if the entire mesh uses the same topology, you can define a single subset that spans all the provided index data (or maximum capacity for dynamic meshes):


builder.setTopology(MeshSubsetTopology.TRIANGLES)

Bounds and Building

For dynamic meshes, it is strongly recommended to set an explicit bounding box using setBounds that encompasses all possible deformed positions across the mesh's lifetime, as automatic bounds computation only considers initial vertex data.

Finally, build the mesh:


val mesh = builder.build()

Summary

Public constructors

BuilderFromMeshData(
    @NonNull Session session,
    @NonNull VertexLayout vertexLayout
)

Creates a builder for an immutable, static CustomMesh.

@RequiresSpatialApi(value = 4)
BuilderFromMeshData(
    @NonNull Session session,
    @NonNull VertexLayout vertexLayout,
    @IntRange(from = 1) int maxVertices,
    @IntRange(from = 1) int maxIndices
)

Creates a builder for a dynamic CustomMesh with fixed GPU buffer capacities.

Public methods

final @NonNull CustomMesh.BuilderFromMeshData

Adds a MeshSubset defining a part of the mesh.

final @NonNull CustomMesh.BuilderFromMeshData
addSubset(
    @NonNull MeshSubsetTopology topology,
    @IntRange(from = 0) int indexOffset,
    @IntRange(from = 0) int indexCount
)

Adds a MeshSubset defining a part of the mesh using the specified topology, index offset, and index count.

final @NonNull CustomMesh.BuilderFromMeshData

Adds vertex data for a single buffer.

final @NonNull CustomMesh.BuilderFromMeshData
addVertexData(
    @NonNull ByteBuffer buffer,
    @IntRange(from = 0) int offset,
    @IntRange(from = 1) int size
)

Adds vertex data for a single buffer using the provided ByteBuffer, offset, and size.

final @NonNull CustomMesh

Builds a new CustomMesh.

final @NonNull CustomMesh.BuilderFromMeshData

Sets an optional user-supplied bounding box for culling.

final @NonNull CustomMesh.BuilderFromMeshData

Sets the index data.

final @NonNull CustomMesh.BuilderFromMeshData
setIndexData(
    @NonNull ByteBuffer buffer,
    @IntRange(from = 0) int offset,
    @IntRange(from = 1) int size
)

Sets the index data using the provided ByteBuffer, offset, and size.

final @NonNull CustomMesh.BuilderFromMeshData

Sets the MeshSubsetTopology to use for the entire mesh, defining a single subset that spans all provided index data.

Public constructors

BuilderFromMeshData

Added in 1.0.0
public BuilderFromMeshData(
    @NonNull Session session,
    @NonNull VertexLayout vertexLayout
)

Creates a builder for an immutable, static CustomMesh.

Parameters
@NonNull Session session

the Session

@NonNull VertexLayout vertexLayout

vertex layout describing the format of vertex attributes

BuilderFromMeshData

Added in 1.1.0-alpha01
@RequiresSpatialApi(value = 4)
public BuilderFromMeshData(
    @NonNull Session session,
    @NonNull VertexLayout vertexLayout,
    @IntRange(from = 1) int maxVertices,
    @IntRange(from = 1) int maxIndices
)

Creates a builder for a dynamic CustomMesh with fixed GPU buffer capacities.

The maxVertices and maxIndices parameters define the fixed maximum capacity of the underlying GPU buffers. The allocated buffer cannot be resized after creation. Any runtime updates via MeshBuffer.updateVertexData or MeshBuffer.updateIndexData that exceed these capacities will throw an IllegalArgumentException.

Parameters
@NonNull Session session

the Session

@NonNull VertexLayout vertexLayout

vertex layout describing the format of vertex attributes

@IntRange(from = 1) int maxVertices

fixed maximum number of vertices this mesh buffer can hold

@IntRange(from = 1) int maxIndices

fixed maximum number of indices this mesh buffer can hold

Throws
IllegalArgumentException

if maxVertices or maxIndices is not positive

Public methods

addSubset

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData addSubset(@NonNull MeshSubset subset)

Adds a MeshSubset defining a part of the mesh.

This cannot be used in combination with setTopology.

Throws
IllegalStateException

if a topology has already been set

addSubset

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData addSubset(
    @NonNull MeshSubsetTopology topology,
    @IntRange(from = 0) int indexOffset,
    @IntRange(from = 0) int indexCount
)

Adds a MeshSubset defining a part of the mesh using the specified topology, index offset, and index count.

This cannot be used in combination with setTopology.

Throws
IllegalStateException

if a topology has already been set

IllegalArgumentException

if indexOffset or indexCount is negative

addVertexData

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData addVertexData(ByteBufferRegion vertexData)

Adds vertex data for a single buffer.

The order in which this method is called determines the buffer index. The first call provides data for buffer index 0, the second for buffer index 1, etc. The data is copied during build, so the original ByteBuffer can be modified or released after build without affecting the underlying MeshBuffer.

When creating a dynamic mesh, initial vertex data is optional. Passing null allows skipping initial data for a specific buffer index in a multi-buffer layout while leaving that buffer zero-initialized. When creating a static mesh, passing null will throw an IllegalArgumentException.

Parameters
ByteBufferRegion vertexData

initial vertex data for this buffer, or null if this buffer is dynamic and should be allocated without initial data

Returns
@NonNull CustomMesh.BuilderFromMeshData

this builder instance

Throws
IllegalArgumentException

if vertexData is null when creating a static mesh

addVertexData

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData addVertexData(
    @NonNull ByteBuffer buffer,
    @IntRange(from = 0) int offset,
    @IntRange(from = 1) int size
)

Adds vertex data for a single buffer using the provided ByteBuffer, offset, and size.

The order in which this method is called determines the buffer index. The first call provides data for buffer index 0, the second for buffer index 1, etc. The data is copied during build, so the original ByteBuffer can be modified or released after build without affecting the underlying MeshBuffer.

Parameters
@NonNull ByteBuffer buffer

containing the data

@IntRange(from = 0) int offset

absolute starting position within the buffer (ignoring its current position) in bytes (defaults to 0)

@IntRange(from = 1) int size

number of bytes in the region (defaults to the remaining capacity of the buffer after the given offset)

Throws
IllegalArgumentException

if offset is negative, if size is zero or negative, if offset exceeds buffer.capacity(), or if offset + size exceeds buffer.capacity().

build

Added in 1.0.0
@MainThread
public final @NonNull CustomMesh build()

Builds a new CustomMesh.

Returns
@NonNull CustomMesh

a new CustomMesh

Throws
IllegalStateException

if index data or vertex data are missing when constructing a static mesh, or if initial dynamic data exceeds allocated capacities

setBounds

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData setBounds(@NonNull BoundingBox bounds)

Sets an optional user-supplied bounding box for culling.

The bounding box does not need to be perfectly tight, but tighter bounds will result in more efficient culling. It is an axis-aligned bounding box in the mesh's local coordinate space.

If not provided, an auto-computed bounding box for the supplied vertex and index data will be used.

setIndexData

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData setIndexData(ByteBufferRegion indexData)

Sets the index data.

The data is copied during build, so the original ByteBuffer can be modified or released after build without affecting the underlying MeshBuffer.

When creating a dynamic mesh, initial index data is optional. Passing null (or omitting this call entirely) allocates the index buffer with zero-initialized content. When creating a static mesh, passing null will throw an IllegalArgumentException.

Parameters
ByteBufferRegion indexData

initial 32-bit index data, or null if the index buffer is dynamic and should be allocated without initial data

Returns
@NonNull CustomMesh.BuilderFromMeshData

this builder instance

Throws
IllegalArgumentException

if indexData is null when creating a static mesh

setIndexData

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData setIndexData(
    @NonNull ByteBuffer buffer,
    @IntRange(from = 0) int offset,
    @IntRange(from = 1) int size
)

Sets the index data using the provided ByteBuffer, offset, and size.

The data is copied during build, so the original ByteBuffer can be modified or released after build without affecting the underlying MeshBuffer.

Parameters
@NonNull ByteBuffer buffer

containing the data

@IntRange(from = 0) int offset

absolute starting position within the buffer (ignoring its current position) in bytes (defaults to 0)

@IntRange(from = 1) int size

number of bytes in the region (defaults to the remaining capacity of the buffer after the given offset)

Throws
IllegalArgumentException

if offset is negative, if size is zero or negative, if offset exceeds buffer.capacity(), or if offset + size exceeds buffer.capacity().

setTopology

Added in 1.0.0
public final @NonNull CustomMesh.BuilderFromMeshData setTopology(@NonNull MeshSubsetTopology topology)

Sets the MeshSubsetTopology to use for the entire mesh, defining a single subset that spans all provided index data.

This cannot be used in combination with addSubset.

Throws
IllegalStateException

if subsets have already been added