MeshBuffer

A triangle mesh kept in buffers, the same on the Lune and native runtimes, read from and saved to obj, glb, gltf, fbx.

What it is

A MeshBuffer holds a mesh's positions, normals, UVs, colours and triangles in buffers, with optional named groups (each object of a loaded file is a group). It works the same on the Lune runtime and the native one, where an EditableMesh exists only natively. A UV's V counts down from the top, like an image's rows. Only the file members end in Async; the rest never yield.

Making one

new(positions, triangles, options)from a list of Vector3 and a flat list of 1-based vertex numbers, three a triangle; options may give Normals, UVs, Colors, Alphas and Groups, and what is left out is worked out (normals) or zero (UVs) or white (colours)
FromTriangles(corners)from a corner buffer, 36 bytes a corner (Unions has the layout); equal corners become one vertex
FromBuffer(bytes, format)from the bytes of a GLB, glTF, FBX, OBJ or Roblox .mesh file; the format ("glb", "gltf", "fbx", "obj" or "mesh") is told by content when left out
LoadAsync(path)from such a file, the format from its ending
FromPlace(root, options)from the plain Parts under an instance of a PlaceFile (Block, Wedge, CornerWedge, Cylinder and Ball, a Seat and a SpawnLocation counting as Parts too), in world space or relative to options.Origin; options may give Segments and Transparent. Gives the mesh and a table with Parts (how many were built) and Skipped (a count for each class left out: MeshParts, Unions, SpecialMeshes and the rest); stops the run when there is nothing to build

Loading stops the run with the reason when the file cannot be read.

Reading

VertexCount, TriangleCounthow many vertices and triangles
GetInfo()the counts of vertices, triangles and groups, and Min, Max, Size and Center
GetVertices()a copy of every vertex: Position, Normal, UV, Color and Alpha
GetGroups()the groups in triangle order, each Name, FirstTriangle (from 1) and Triangles; {} when there are none
ToTriangles()the triangles as a corner buffer, 36 bytes a corner, as EditableMesh's ReadTriangles gives them (Unions has the layout)

Changing

Normalize, Transform and SetColor give a new mesh and leave the first one as it was.

Normalize(size)scaled evenly to fit the box (a number is a cube, a Vector3 the box) and centred on the origin
Transform(cframe, scale)scaled (a number or per axis; negative mirrors), then moved by the CFrame; normals are rotated too
SetColor(color, alpha)every vertex this colour (alpha 1 unless given)
MeshBuffer.Merge(items)one mesh from several, each moved first by its Transform and Scale; an item is a MeshBuffer or a table with Mesh, Transform, Scale and Name
MeshBuffer.EasyColorMerge(items)Merge for meshes of one colour each (an item may give Color): gives the mesh, with white colours and UVs into the atlas, and the atlas, a PixelImage with a 4 x 4 texel block a colour

Saving

Encode(format, atlas)the file's bytes: "glb" (the default; an atlas PixelImage is embedded), "gltf" (text), "fbx" or "obj"
SaveMeshWithAtlasAsync(path, atlas)writes a .glb, .gltf, .fbx or .obj file and the atlas as a PNG beside it named <name>.png

Native runtime only

MeshBuffer.FromEditableMesh(mesh)a copy of an EditableMesh's triangles
mesh:ToEditableMesh()a new EditableMesh with this mesh, which the caller owns

Both refuse on the Lune runtime, which has no EditableMesh.

See also

Editables (EditableMesh and its triangles), PixelImage (the atlas), Unions (the corner buffer's layout), FileService (paths).