MeshGeometry.fromArrays constructor
- required Float32List positions,
- Float32List? normals,
- Float32List? texCoords,
- Float32List? colors,
- List<
int> ? indices, - PrimitiveType primitiveType = gpu.PrimitiveType.triangle,
- GeometryStorage storage = GeometryStorage.fixed,
Builds a mesh from structure-of-arrays vertex attributes.
positions is required and holds three floats per vertex. The
optional attributes hold, per vertex, three floats for normals,
two for texCoords, and four for colors; each must match the
vertex count implied by positions when supplied. Absent
attributes fall back to defaults: texture coordinate (0, 0) and
color opaque white.
When normals is omitted and primitiveType is a triangle list,
area-weighted vertex normals are generated from the faces; for line
and point primitives, absent normals keep their default. indices,
when supplied, is an index list; when omitted a triangle mesh must
have a vertex count that is a multiple of three.
primitiveType selects how the vertex/index data is assembled into
primitives when drawn, and defaults to a triangle list.
storage selects whether the mesh can later be updated in place.
An updatable mesh fixes its indexed-or-not state at construction:
supplying indices makes rebuild require indices thereafter, and
omitting them makes it reject them. To start empty, pass a
zero-length positions array with GeometryStorage.updatable.
Implementation
MeshGeometry.fromArrays({
required Float32List positions,
Float32List? normals,
Float32List? texCoords,
Float32List? colors,
List<int>? indices,
gpu.PrimitiveType primitiveType = gpu.PrimitiveType.triangle,
this.storage = GeometryStorage.fixed,
}) {
if (positions.length % 3 != 0) {
throw ArgumentError(
'positions has ${positions.length} floats; expected a multiple of '
'three (one vec3 per vertex)',
);
}
final vertexCount = positions.length ~/ 3;
this.primitiveType = primitiveType;
// Normals are generated from triangle faces; line and point
// geometry has none, so absent normals are left at their default.
final resolvedNormals =
normals ??
(vertexCount > 0 && primitiveType == gpu.PrimitiveType.triangle
? InterleavedLayoutAdapter.generateNormals(
positions: positions,
vertexCount: vertexCount,
indices: indices,
)
: null);
if (storage == GeometryStorage.fixed) {
_uploadFixed(
positions,
vertexCount,
resolvedNormals,
texCoords,
colors,
indices,
);
} else {
_indexed = indices != null;
_setCpuStreams(
positions,
vertexCount,
resolvedNormals,
texCoords,
colors,
);
_vertexCapacity = nextBufferCapacity(vertexCount);
_vertexBuffer = gpu.gpuContext.createDeviceBuffer(
gpu.StorageMode.hostVisible,
_vertexCapacity * kInterleavedVertexBytes,
);
_liveVertexCount = vertexCount;
_uploadVertexBytes();
if (_indexed) _uploadIndices(indices!);
_recomputeBounds();
}
}