Mesh
Base geometry resource: surfaces, materials and CPU-derived data.
Mesh is a base resource rather than an Entity or physics body. For ordinary construction use ArrayMesh, ImmediateMesh or a concrete PrimitiveMesh such as BoxMesh. MeshInstance3D places the resource in the world; multiple instances can share one Mesh. Surface Material belongs to the shared resource, while per-instance settings belong to the consumer. Native Mesh is registered as a virtual class: a C# constructor does not make new Mesh() usable geometry.
using var mesh = new ArrayMesh();
using var arrays = new Reckfell.Collections.Array();
arrays.Resize((int)Mesh.ArrayType.Max);
arrays[(int)Mesh.ArrayType.Vertex] = new Vector3[] {
Vector3.Zero, new(1, 0, 0), new(0, 1, 0)
};
mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
Vector3[] faces = mesh.GetFaces(); // 3 corners
using var shape = mesh.CreateTrimeshShape();The example creates a triangle and shape resource, not a visible object or world collision. Assign shape to CollisionShape3D under an appropriate CollisionObject3D for physics; display requires MeshInstance3D using mesh. Keep resources alive while used; the using scopes here bound a data check.
SurfaceGetArrays returns Mesh.ArrayType slots rather than a flat corner list. On indexed surfaces Vertex stores unique records and Index determines corner order. GetFaces expands eligible Triangles and TriangleStrip surfaces into Vector3 triples, skipping Points/Lines. These are local-space data without instance Transform3D, GPU shader deformation, current skeleton pose or renderer-selected LOD.
GetFaces uses GenerateTriangleMesh: its CPU BVH is cached and coordinates snap to a 0.0001 grid. GetFaces returns a managed copy, while GenerateTriangleMesh can repeatedly return the same wrapper: do not release a repeated alias ahead of its owner. This is not exact readback of source Vertex floats. Validate input indices yourself; the utility is not a validator for arbitrary malformed geometry.
Known 1.0.0 defect: ArrayMesh.ClearSurfaces does not invalidate this cache. After an earlier GetFaces/GenerateTriangleMesh call, removed triangles can remain in later GetFaces or a generated trimesh shape. Use a new ArrayMesh for full geometry replacement and regenerate dependent shapes; zero surfaces does not guarantee an empty cache. Ordinary ArrayMesh surface append/removal invalidates the main triangle cache, but an already-returned TriangleMesh remains the old snapshot.
CreateTrimeshShape copies triangles into ConcavePolygonShape3D, returning null if none exist. It represents a surface rather than an automatically filled volume or ready Entity. Use a suitable convex primitive/shape for a moving convex object; constructing shape data here does not establish scene physics stability. CreateConvexShape gathers positions from every surface, including unused indexed vertices and non-Triangles. clean builds a cleaned hull; simplify attempts one hull using an available decomposer, with diagnostic fallback on failure. Convex shapes do not preserve cavities/openings.
CreateOutline returns a separate Mesh with vertices displaced along geometric normals and reversed winding. It neither enables a post-effect nor sets pixel width or draws automatically. Assign material separately. Use consistent Triangles surfaces starting at the first surface; a non-Triangles first surface is not a reliable path. The method combines surfaces without preserving separate materials/blend shapes/LODs and is not a universal lossless editor.
LightmapSizeHint stores a size hint; its setter does not generate UV2, bake lighting or emit Changed. CreatePlaceholder builds PlaceholderMesh with only the current Aabb; it does not transfer textures/materials/triangles or collision.
Underscore methods (_GetSurfaceCount, _SurfaceGetArrays and others) are callbacks for a custom Mesh implementation. Override a consistent set; directly calling a generated base method returns default rather than invoking a concrete ArrayMesh native getter. _SurfaceGetFormat is uint, whereas ArrayMesh.SurfaceGetFormat returns 64-bit Mesh.ArrayFormat: do not arbitrarily pass high bits into that callback. A complete custom implementation and visible rendering are outside this example.
19 Windows headless checks covered CPU triples/strips, snapping, cache, a simple outline, placeholder and shape data. Actual physics-world collisions, clean/simplify, deformation, custom Mesh rendering and performance remain unestablished. The cache defect was reproduced without patching the engine.
Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.
Constructors1
MeshConstructor
public Mesh();Base virtual native resource type. Use concrete ArrayMesh/ImmediateMesh/BoxMesh for ordinary geometry; the C# constructor does not supply surfaces or required callback implementations.
Properties1
LightmapSizeHintProperty
public Vector2I LightmapSizeHint { get; set; }Lightmap-size hint in texels. Default (0,0); setting does not bake lighting/UV2 or emit Changed.
Methods28
CreateConvexShapeConvexPolygonShape3D
public ConvexPolygonShape3D CreateConvexShape(bool clean = true, bool simplify = false);Creates a convex shape from positions of every surface, not only used triangle corners. clean builds a hull; simplify attempts one-hull decomposition with possible fallback. Does not preserve concavity or create a physics body.
| Name | Type | Default |
|---|---|---|
clean | bool | true |
simplify | bool | false |
cleantrue attempts a hull removing internal/redundant points, with possible fallback. Not a mesh watertightness check.
simplifytrue attempts available convex decomposition with one hull; more expensive and can fall back. Not exercised in this pass.
ConvexPolygonShape3DNew owned ConvexPolygonShape3D; inspect data/diagnostics. A shape does not establish physics stability or concave-object fidelity.
CreateOutlineMesh
public Mesh CreateOutline(float margin);Creates a new single-surface Mesh with geometric-normal offset and reversed winding. Requires consistent Triangles starting at the first surface. Not a material/post-effect/pixel outline; separate surface materials and LODs are not preserved.
| Name | Type | Default |
|---|---|---|
margin | float | — |
marginFinite local displacement along accumulated geometric normals. Not pixels or guaranteed uniform screen thickness.
MeshNew Mesh, normally ArrayMesh, or null on rejected data. Material is not assigned automatically.
CreatePlaceholderResource
public Resource CreatePlaceholder();Creates PlaceholderMesh with current GetAabb. Does not copy geometry, materials, textures or collision; later source-bound changes do not update it automatically.
ResourceNew owned PlaceholderMesh Resource retaining bounds.
CreateTrimeshShapeConcavePolygonShape3D
public ConcavePolygonShape3D CreateTrimeshShape();Creates ConcavePolygonShape3D from GetFaces, including TriangleMesh snapping/cache behavior. null without triangles. Does not add CollisionShape3D to the world; regenerate dependent shapes after mesh changes.
ConcavePolygonShape3DNew owned ConcavePolygonShape3D, or null without triangles.
GenerateTriangleMeshTriangleMesh
public TriangleMesh GenerateTriangleMesh();Returns a cached CPU TriangleMesh from Triangles/TriangleStrip, skipping other primitives. Positions snap to 0.0001 and visible deformation is not included. Known issue: ArrayMesh.ClearSurfaces does not invalidate the old cache.
TriangleMeshShared cached TriangleMesh reference, or null without eligible triangles. Repeated results can be the same wrapper.
GetAabbAabb
public Aabb GetAabb();Queries the Mesh resource local bounds. Concrete native types provide their own implementation; ArrayMesh, for example, returns stored geometry bounds. Base Mesh delegates the request to _GetAabb. This excludes instance transforms, CustomAabb, ExtraCullMargin and GPU-shader displacement.
AabbThe resource local Aabb supplied by the Mesh implementation. Apply an instance transform separately for a world-space estimate; that still does not query final renderer bounds.
GetFacesVector3[]
public Vector3[] GetFaces();Returns a managed copy of local corner triples from GenerateTriangleMesh. Snapped/cached CPU data rather than exact source Vertex floats or final GPU pose.
Vector3[]New Vector3[] of corner triples, empty without triangles; coordinates are already BVH-snapped.
GetLightmapSizeHintVector2I
public Vector2I GetLightmapSizeHint();Reads the stored lightmap-size hint rather than a baked texture size or UV-unwrap result.
Vector2IStored Vector2I, default (0,0).
GetSurfaceCountint
public int GetSurfaceCount();Returns the concrete implementation surface count rather than instance-material or triangle count.
intImplementation surface count.
SetLightmapSizeHintvoid
public void SetLightmapSizeHint(Vector2I size);Stores the hint also exposed by LightmapSizeHint. Does not modify geometry or start baking; does not emit Changed.
| Name | Type | Default |
|---|---|---|
size | Vector2I | — |
sizeNonnegative hint dimensions in texels; (0,0) for no specified hint.
SurfaceGetArraysReckfell.Collections.Array
public Reckfell.Collections.Array SurfaceGetArrays(int surfIdx);Reads surface Mesh.ArrayType slots through the concrete implementation. ArrayMesh/ImmediateMesh return snapshots, while custom Mesh semantics depend on its callback. Not a universal deep-copy guarantee.
| Name | Type | Default |
|---|---|---|
surfIdx | int | — |
surfIdxConcrete Mesh surface index from 0 to GetSurfaceCount()-1.
Reckfell.Collections.ArrayChannel-slot Array; dispose its wrapper after reading. Copy semantics depend on implementation.
SurfaceGetBlendShapeArraysReckfell.Collections.Array<Reckfell.Collections.Array>
public Reckfell.Collections.Array<Reckfell.Collections.Array> SurfaceGetBlendShapeArrays(int surfIdx);Reads the typed array of surface blend-shape channel arrays. Order follows the implementation shape definitions; empty without shapes. Each shape is an Array of slots rather than just Vector3[].
| Name | Type | Default |
|---|---|---|
surfIdx | int | — |
surfIdxConcrete Mesh surface index from 0 to GetSurfaceCount()-1.
Reckfell.Collections.Array<Reckfell.Collections.Array>Typed array of shape Arrays; dispose individual untyped Array wrappers after reading, while typed Array itself is not IDisposable.
SurfaceGetMaterialMaterial
public Material SurfaceGetMaterial(int surfIdx);Returns the shared surface Material or null. Resource material rather than an individual MeshInstance3D MaterialOverride/overlay.
| Name | Type | Default |
|---|---|---|
surfIdx | int | — |
surfIdxConcrete Mesh surface index from 0 to GetSurfaceCount()-1.
MaterialShared Material reference or null rather than a separate copy to Dispose early.
SurfaceSetMaterialvoid
public void SurfaceSetMaterial(int surfIdx, Material material);Changes the shared surface Material through the concrete implementation. Instances using the resource can observe it unless overriding material. Changed notification depends on implementation.
| Name | Type | Default |
|---|---|---|
surfIdx | int | — |
material | Material | — |
surfIdxConcrete Mesh surface index from 0 to GetSurfaceCount()-1.
materialShared Material or null; passing does not clone the resource.
_GetAabbAabb
public virtual Aabb _GetAabb();Virtual callback supplying local bounds for a custom resource based on Mesh. Called by the base Mesh.GetAabb implementation. Native derived types may override GetAabb directly, so this callback is not a universal way to replace bounds on every built-in Mesh.
AabbThe custom Mesh local geometry bounds. Do not include an individual MeshInstance3D transform.
_GetBlendShapeCountint
public virtual int _GetBlendShapeCount();Return the shape count in a custom Mesh implementation. A callback rather than a native GetBlendShapeCount query on an arbitrary ArrayMesh.
intShape count; generated base returns 0.
_GetBlendShapeNameStringName
public virtual StringName _GetBlendShapeName(int index);Return the shape name for index in a custom implementation. Keep it consistent with shape count and blend-array order.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexShape index in your data from 0 to declared shape count minus 1.
StringNameShape StringName; generated base returns default.
_GetSurfaceCountint
public virtual int _GetSurfaceCount();Return the custom Mesh surface count; every surface callback must handle matching indices.
intSurface count; generated base returns 0.
_SetBlendShapeNamevoid
public virtual void _SetBlendShapeName(int index, StringName name);Implement shape renaming in your own data. The generated base method does nothing and does not forward to native ArrayMesh.
| Name | Type | Default |
|---|---|---|
index | int | — |
name | StringName | — |
indexShape index in your data from 0 to declared shape count minus 1.
nameNew shape name consistent with your implementation and serialization.
_SurfaceGetArrayIndexLenint
public virtual int _SurfaceGetArrayIndexLen(int index);Return the surface index-array length, 0 without indices. Element count rather than bytes/triangles.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexSurface index in your data from 0 to declared surface count minus 1.
intIndex count, 0 for a nonindexed surface.
_SurfaceGetArrayLenint
public virtual int _SurfaceGetArrayLen(int index);Return surface Vertex record count, consistent with attribute arrays and indices.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexSurface index in your data from 0 to declared surface count minus 1.
intSelected surface Vertex record count.
_SurfaceGetArraysReckfell.Collections.Array
public virtual Reckfell.Collections.Array _SurfaceGetArrays(int index);Return a consistent Array of exactly Mesh.ArrayType.Max slots with required packed types. CPU callback data rather than automatic GPU mesh creation.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexSurface index in your data from 0 to declared surface count minus 1.
Reckfell.Collections.ArrayChannel Array consistent with format/lengths; generated base returns null.
_SurfaceGetBlendShapeArraysReckfell.Collections.Array<Reckfell.Collections.Array>
public virtual Reckfell.Collections.Array<Reckfell.Collections.Array> _SurfaceGetBlendShapeArrays(int index);Return one Max-slot Array per surface shape in declared shape order; empty without shapes.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexShape index in your data from 0 to declared shape count minus 1.
Reckfell.Collections.Array<Reckfell.Collections.Array>Typed array of shape Arrays; generated base returns null.
_SurfaceGetFormatuint
public virtual uint _SurfaceGetFormat(int index);Return consistent channel/format bits. This callback is uint rather than ulong; it cannot guarantee transfer of high ArrayMesh 64-bit flags.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexSurface index in your data from 0 to declared surface count minus 1.
uint32-bit uint mask; generated base returns 0 rather than full ulong ArrayMesh format.
_SurfaceGetLodsReckfell.Collections.Dictionary
public virtual Reckfell.Collections.Dictionary _SurfaceGetLods(int index);Return a metric → int[] Dictionary of surface LOD indices. Level data rather than camera switching or automatic simplification.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexSurface index in your data from 0 to declared surface count minus 1.
Reckfell.Collections.DictionaryLevel Dictionary; generated base returns null.
_SurfaceGetMaterialMaterial
public virtual Material _SurfaceGetMaterial(int index);Return a shared Material reference or null from your implementation; keep it alive while needed by the mesh.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexSurface index in your data from 0 to declared surface count minus 1.
MaterialShared Material or null; generated base returns null.
_SurfaceGetPrimitiveTypeuint
public virtual uint _SurfaceGetPrimitiveType(int index);Return the surface Mesh.PrimitiveType uint value consistent with arrays. Do not substitute an arbitrary flags enum.
| Name | Type | Default |
|---|---|---|
index | int | — |
indexSurface index in your data from 0 to declared surface count minus 1.
uintPrimitive uint value. Generated base 0 corresponds to Points and does not establish a valid implementation.
_SurfaceSetMaterialvoid
public virtual void _SurfaceSetMaterial(int index, Material material);Implement the material-reference change in your custom Mesh. The generated base method neither changes native material nor emits Changed.
| Name | Type | Default |
|---|---|---|
index | int | — |
material | Material | — |
indexSurface index in your data from 0 to declared surface count minus 1.
materialShared Material or null; passing does not clone the resource.
Mesh.ArrayCustomFormat
| Value | Description |
|---|---|
Max = 8 | Represents the size of the |
RFloat = 4 | Indicates this custom channel contains full float colors, in a |
RgFloat = 5 | Indicates this custom channel contains full float colors, in a |
RgHalf = 2 | Indicates this custom channel contains half precision float colors, encoded as |
RgbFloat = 6 | Indicates this custom channel contains full float colors, in a |
Rgba8Snorm = 1 | Indicates this custom channel contains signed normalized byte colors from -1 to 1, encoded as |
Rgba8Unorm = 0 | Indicates this custom channel contains unsigned normalized byte colors from 0 to 1, encoded as |
RgbaFloat = 7 | Indicates this custom channel contains full float colors, in a |
RgbaHalf = 3 | Indicates this custom channel contains half precision float colors, encoded as |
Mesh.ArrayFormat
| Value | Description |
|---|---|
CompressFlagsBase = 25 | Shift of first compress flag. Compress flags should be passed to |
FlagCompressAttributes = 536870912 | Flag used to mark that a mesh is using compressed attributes (vertices, normals, tangents, UVs). When this form of compression is enabled, vertex positions will be packed into an RGBA16UNORM attribute and scaled in the vertex shader. The normal and tangent will be packed into an RG16UNORM representing an axis, and a 16-bit float stored in the A-channel of the vertex. UVs will use 16-bit normalized floats instead of full 32-bit signed floats. When using this compression mode you must use either vertices, normals, and tangents or only vertices. You cannot use normals without tangents. Importers will automatically enable this compression if they can. |
FlagUse2DVertices = 33554432 | Flag used to mark that the array contains 2D vertices. |
FlagUse8BoneWeights = 134217728 | Flag used to mark that the mesh contains up to 8 bone influences per vertex. This flag indicates that |
FlagUseDynamicUpdate = 67108864 | Flag used to mark that the mesh data will use |
FlagUseStorageBuffer = 1073741824 | Flag used to mark that the surface's vertex, attribute, skin, and index buffers must be created with the storage-buffer usage bit so they can be bound as storage buffers in compute shaders. This is required to write into them from a compute pipeline through the |
FlagUsesEmptyVertexArray = 268435456 | Flag used to mark that the mesh intentionally contains no vertex array. |
FormatBlendShapeMask = 7 | Mask of mesh channels permitted in blend shapes. |
FormatBones = 1024 | Mesh array contains bones. |
FormatColor = 8 | Mesh array contains colors. |
FormatCustom0 = 64 | Mesh array contains custom channel index 0. |
FormatCustom0Shift = 13 | Amount to shift |
FormatCustom1 = 128 | Mesh array contains custom channel index 1. |
FormatCustom1Shift = 16 | Amount to shift |
FormatCustom2 = 256 | Mesh array contains custom channel index 2. |
FormatCustom2Shift = 19 | Amount to shift |
FormatCustom3 = 512 | Mesh array contains custom channel index 3. |
FormatCustom3Shift = 22 | Amount to shift |
FormatCustomBase = 13 | Shift of first custom channel. |
FormatCustomBits = 3 | Number of format bits per custom channel. See |
FormatCustomMask = 7 | Mask of custom format bits per custom channel. Must be shifted by one of the SHIFT constants. See |
FormatIndex = 4096 | Mesh array uses indices. |
FormatNormal = 2 | Mesh array contains normals. |
FormatTangent = 4 | Mesh array contains tangents. |
FormatTexUV = 16 | Mesh array contains UVs. |
FormatTexUV2 = 32 | Mesh array contains second UV. |
FormatVertex = 1 | Mesh array contains vertices. All meshes require a vertex array so this should always be present. |
FormatWeights = 2048 | Mesh array contains bone weights. |
Mesh.ArrayType
| Value | Description |
|---|---|
Bones = 10 |
|
Color = 3 |
|
Custom0 = 6 | Contains custom color channel 0. |
Custom1 = 7 | Contains custom color channel 1. |
Custom2 = 8 | Contains custom color channel 2. |
Custom3 = 9 | Contains custom color channel 3. |
Index = 12 |
|
Max = 13 | Represents the size of the |
Normal = 1 |
|
Tangent = 2 |
|
TexUV = 4 |
|
TexUV2 = 5 |
|
Vertex = 0 |
|
Weights = 11 |
|
Mesh.BlendShapeMode
| Value | Description |
|---|---|
Normalized = 0 | Blend shapes are normalized. |
Relative = 1 | Blend shapes are relative to base weight. |
Mesh.PrimitiveType
| Value | Description |
|---|---|
LineStrip = 2 | Render array as line strip. |
Lines = 1 | Render array as lines (every two vertices a line is created). |
Points = 0 | Render array as points (one vertex equals one point). |
TriangleStrip = 4 | Render array as triangle strips. |
Triangles = 3 | Render array as triangles (every three vertices a triangle is created). |