reckfellENGINE

ArrayMesh: создать поверхность из массивов

Полный квадрат с нормалями, UV и индексами; форматы массивов, порядок граней и сохранение ресурса.

На этой странице

Запустить квадрат

Добавьте GeometryStage3D.cs и ArrayQuadLab3D.cs в C#-проект 1.0.0. Прикрепите ArrayQuadLab3D к корню Entity3D отдельного уровня, задайте viewport 640×420, соберите и нажмите F6. Над серым полом появится синяя квадратная поверхность. У неё одна поверхность, четыре вершины и шесть индексов.

Квадрат ArrayMesh из четырёх вершин и двух треугольников

GeometryStage3D.cs
C#
using Reckfell;

public static class GeometryStage3D
{
    public static StandardMaterial3D Material(bool vertexColors = false, bool unshaded = false)
    {
        return new StandardMaterial3D
        {
            AlbedoColor = vertexColors ? Colors.White : new Color(0.24f, 0.44f, 1),
            VertexColorUseAsAlbedo = vertexColors,
            ShadingMode = unshaded ? BaseMaterial3D.ShadingModeEnum.Unshaded : BaseMaterial3D.ShadingModeEnum.PerPixel,
            Roughness = 0.8f
        };
    }

    public static void Setup(Entity3D root, string ru, string en)
    {
        root.AddChild(new WorldEnvironment { Environment = new Reckfell.Environment
        {
            BackgroundMode = Reckfell.Environment.BGMode.Color,
            BackgroundColor = new Color(0.035f, 0.04f, 0.05f),
            AmbientLightSource = Reckfell.Environment.AmbientSource.Color,
            AmbientLightColor = Colors.White, AmbientLightEnergy = 0.5f
        }});
        root.AddChild(new DirectionalLight3D { RotationDegrees = new Vector3(-55, -25, 0), LightEnergy = 1.2f });
        root.AddChild(new MeshInstance3D
        {
            Mesh = new BoxMesh { Size = new Vector3(8, 0.05f, 6) }, Position = new Vector3(0, -0.12f, 0),
            MaterialOverride = new StandardMaterial3D { AlbedoColor = new Color(0.10f, 0.11f, 0.13f), Roughness = 1 }
        });
        var camera = new Camera3D { Position = new Vector3(4, 4.8f, 6), Current = true, Fov = 45 };
        root.AddChild(camera); camera.LookAt(new Vector3(0, 0.35f, 0), Vector3.Up);
        var canvas = new CanvasLayer(); root.AddChild(canvas);
        var label = new Label { Position = new Vector2(24, 20), Text = TranslationServer.GetLocale().StartsWith("ru") ? ru : en };
        label.AddThemeFontSizeOverride("font_size", 22); canvas.AddChild(label);
    }
}
ArrayQuadLab3D.cs
C#
using Reckfell;

public partial class ArrayQuadLab3D : Entity3D
{
    public ArrayMesh Generated { get; private set; } = null!;

    public static ArrayMesh CreateQuad()
    {
        Vector3[] vertices = [new(-1, 0, -1), new(1, 0, -1), new(1, 0, 1), new(-1, 0, 1)];
        Vector3[] normals = [Vector3.Up, Vector3.Up, Vector3.Up, Vector3.Up];
        Vector2[] uv = [new(0, 0), new(1, 0), new(1, 1), new(0, 1)];
        int[] indices = [0, 1, 2, 0, 2, 3];
        using var arrays = new Reckfell.Collections.Array();
        arrays.Resize((int)Mesh.ArrayType.Max);
        arrays[(int)Mesh.ArrayType.Vertex] = vertices;
        arrays[(int)Mesh.ArrayType.Normal] = normals;
        arrays[(int)Mesh.ArrayType.TexUV] = uv;
        arrays[(int)Mesh.ArrayType.Index] = indices;
        var mesh = new ArrayMesh();
        mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
        return mesh;
    }

    public override void _Ready()
    {
        GeometryStage3D.Setup(this, "ArrayMesh: 4 вершины, 2 треугольника", "ArrayMesh: 4 vertices, 2 triangles");
        Generated = CreateQuad();
        AddChild(new MeshInstance3D { Mesh = Generated, MaterialOverride = GeometryStage3D.Material() });
    }
}

Собрать согласованный набор

Внешний Reckfell.Collections.Array имеет размер Mesh.ArrayType.Max. Его индексы — слоты атрибутов, а не номера вершин. Незаполненные слоты остаются Nil. Код передаёт типизированные Vector3[], Vector2[] и int[]; не заменяйте их массивом случайных Variant.

СлотДанные примера
Vertex4 позиции Vector3
Normal4 нормали Vector3, здесь Up
TexUV4 координаты Vector2
Index6 индексов int: 0, 1, 2, 0, 2, 3

Все включённые повершинные атрибуты должны соответствовать числу вершин. Каждый индекс должен быть в диапазоне 0..vertexCount−1. Для Triangles число индексов кратно 3. Нормали нужны корректной длины и направления; наличие UV само по себе не назначает текстуру.

Порядок примера задаёт лицевую сторону сверху: при расчёте нормали для этих трёх вершин (C−A).Cross(B−A) даёт Up. Геометрический обход, освещение и сторона нормали должны быть согласованы. Для normal map дополнительно нужны корректные tangents; их построение показано в SurfaceTool.

Добавление не равно замене

AddSurfaceFromArrays добавляет новую поверхность. Второй вызов не перезаписывает первую. Для полного обновления собственного ресурса сначала подготовьте и проверьте новые данные, затем создайте новый ArrayMesh либо очистите старые поверхности. Не очищайте общий ресурс, если другие объекты должны сохранить прежнюю геометрию.

Материал можно назначить поверхности либо через MaterialOverride показывающей MeshInstance3D. Несколько поверхностей или дополнительных проходов материала могут означать дополнительные отрисовки; один Mesh не обещает единственный draw call.

Сохранить результат

ResourceSaver.Save сохраняет готовый ArrayMesh как ресурс, например user://quad.rdata; проверяйте Error. В стенде выполнены сохранение и повторная загрузка с CacheMode.Ignore, после которой сохранились поверхность и четыре вершины. Для игрового проекта отдельно решите, генерировать меш при запуске или включить сохранённый ресурс в экспорт. Сохранение меша не сохраняет автоматически текущий уровень, камеру и C#-код.

Проверены массивы, лицевая сторона, AABB, добавление/очистка поверхностей, сохранение/загрузка и реальное отображение. Это геометрия без физического коллайдера; skin, blend shapes и произвольные повреждённые входные данные этим квадратом не проверены.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.