ImporterMesh
Промежуточные CPU-данные поверхностей импорта с построением ArrayMesh.
ImporterMesh — RefCounted с данными подготовки, не Mesh для прямого отображения и не Entity. Добавьте поверхности через AddSurface, задайте режим blend shapes, hint lightmap и LOD, затем вызовите GetMesh. Полученный ArrayMesh можно назначить MeshInstance3D или сохранить как ресурс.
using var staged = new ImporterMesh();
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(1, 1, 0), new(0, 1, 0)
};
arrays[(int)Mesh.ArrayType.Index] = new int[] { 0, 1, 2, 0, 2, 3 };
staged.AddSurface(Mesh.PrimitiveType.Triangles, arrays, name: "part");
using var mesh = staged.GetMesh();
int vertexCount = mesh.SurfaceGetArrayLen(0); // 4Пример создаёт геометрию без видимого экземпляра и материала. Для показа назначьте mesh потребителю и сохраняйте его живым на время использования; using в примере заканчивает срок жизни после проверки данных. Сначала полностью подготовьте staging-данные, затем стройте результат. По умолчанию blend mode здесь Normalized, а у нового ArrayMesh — Relative.
AddSurface принимает ровно Mesh.ArrayType.Max слотов с непустыми Vector3-позициями. Для используемых каналов подготовьте согласованные длины и допустимые индексы. Метод проверяет не всю геометрию, которую позднее упаковывает ArrayMesh. GetSurfaceFormat возвращает переданные flags, а не вычисленную маску каналов: 0 не означает отсутствие вершин. Основной flags — ulong; uint-перегрузка только передаёт значение в неё.
Важное отличие от ArrayMesh: AddSurface сохраняет общий Array-контейнер, GetSurfaceArrays и GetSurfaceBlendShapeArrays возвращают его alias. Замена слота влияет на staging-данные и исходный контейнер. Но AsVector3Array даёт managed-копию: после правки её нужно явно присвоить слоту. Для независимой подготовки копируйте контейнеры заранее; ресурсы Material всё равно могут оставаться общими. Изменение общего массива не сбрасывает кэш результата и не отправляет Changed.
GetMesh кэширует результат и повторно возвращает ту же ссылку. AddSurface, SetSurfaceName и SetSurfaceMaterial сбрасывают кэш, но ранее выданный ArrayMesh остаётся отдельным прежним результатом. SetBlendShapeMode и SetLightmapSizeHint кэш не сбрасывают. Устанавливайте их до первого GetMesh; последующее чтение не обновит старый ресурс. baseMesh используется только при первом построении и не очищается: поверхности дописываются. Передавайте пустой отдельный ArrayMesh, если нужен контролируемый результат; не используйте ресурс, который нельзя менять.
Имена форм задавайте до поверхностей. Двоеточие заменяется на подчёркивание, уникальность не обеспечивается. Для каждой объявленной формы нужен Max-слотовый массив с тем же числом вершин. Дубли имён могут стать другими именами после преобразования в ArrayMesh — используйте уникальные имена сами. LOD staging хранит числовой порог и индексный список; конечный renderer требует положительный порог и список короче базового. Генерацию LOD выполняйте до первого GetMesh и отдельно проверяйте её качество.
FromMesh копирует поверхности, blend-данные, LOD, имя и metadata; Material остаётся общим. Имя поверхности берётся из ArrayMesh, а при пустом имени — из Material.ResourceName. Это не полный перенос настроек: lightmap hint и shadow mesh таким вызовом не переносятся. Clear удаляет поверхности/имена форм/кэш, но сохраняет режим blend shapes и lightmap hint; автоматического Changed нет.
MergeImporterMeshes применяет относительный Transform3D к статической геометрии. При deduplicateSurfaces = true поверхности с одинаковым именем, primitive и flags могут объединиться даже при разных материалах: остаётся первый материал. Для разных материалов отключайте объединение. Это конкатенация вершин и смещение индексов, не welding. Blend shapes и LOD отбрасываются с предупреждением. Скелеты и bind poses не переназначаются; nonuniform scale не обрабатывает normals через inverse-transpose, tangent handedness при отражении сохраняется. Не используйте операцию как универсальное объединение анимированных моделей.
Скрытое _Data предназначено для сериализации, не безопасного редактирования. В текущем коде getter пишет blend_shapes, setter читает b_shapes; режим и lightmap hint в словарь не входят. Не рассчитывайте на полный roundtrip через _Data.
26 Windows headless-проверок подтвердили staging, aliases, кэш, простой blend/LOD пакет и объединение статических поверхностей. Видимый рендер, новая генерация LOD, reflected/nonuniform/skinned merge и сериализация с blend shapes в этом проходе не проверялись. Ранее проверенные LOD-описания сохранены со своим отдельным отчётом.
Объявления сверены с C# SDK 1.0.0. Раскройте имя, чтобы увидеть сигнатуры и описание.
Конструкторы1
ImporterMeshКонструктор
public ImporterMesh();Создаёт пустой собственный staging RefCounted: нет поверхностей/форм, режим Normalized, lightmap hint (0,0). Не является отображаемым Mesh.
Свойства1
_DataСвойство
public Reckfell.Collections.Dictionary _Data { get; set; }Скрытый Dictionary сериализации со staging-массивами и общими ссылками. Не независимая копия всего ресурса. Getter пишет blend_shapes, setter читает b_shapes; mode/hint отсутствуют. Не используйте как гарантированный lossless roundtrip.
Методы26
AddBlendShapevoid
public void AddBlendShape(string name);Добавляет имя до поверхностей. Заменяет : на _, но не делает имя уникальным. Заранее исключайте дубли, чтобы GetMesh не переименовал формы иначе.
| Имя | Тип | По умолчанию |
|---|---|---|
name | string | — |
nameИмя формы до sanitization : → _; уникальность обеспечьте сами.
AddSurface2 перегрузки
public void AddSurface(Mesh.PrimitiveType primitive, Reckfell.Collections.Array arrays, Reckfell.Collections.Array<Reckfell.Collections.Array> blendShapes, Reckfell.Collections.Dictionary lods, Material material, string name, uint flags);Добавляет staging-поверхность и сбрасывает кэш GetMesh. Сохраняет общий arrays и blend-контейнеры, material/name/flags; не отправляет Changed. Проверка входа частичная: подготовьте допустимые каналы и индексы до построения ArrayMesh. ulong — основной вариант, uint — forwarding overload.
| Имя | Тип | По умолчанию |
|---|---|---|
primitive | Mesh.PrimitiveType | — |
arrays | Reckfell.Collections.Array | — |
blendShapes | Reckfell.Collections.Array<Reckfell.Collections.Array> | — |
lods | Reckfell.Collections.Dictionary | — |
material | Material | — |
name | string | — |
flags | uint | — |
primitiveСпособ сборки. Для Triangles подготовьте число углов/индексов, кратное трём.
arraysРовно Mesh.ArrayType.Max слотов с непустым Vector3[] Vertex и согласованными каналами. Контейнер сохраняется общим.
blendShapesОдин Max-слотовый Array на объявленную форму в том же порядке, с тем же числом вершин. null только без форм.
lodsНеобязательный Dictionary порог → int[] индексов. Для итогового ArrayMesh нужны положительные пороги и более короткие допустимые списки; staging проверяет это не полностью.
materialОбщая ссылка Material либо null; не клонируется.
nameИмя staging-поверхности; пустое/повторяющееся допустимо.
flagsulong flags упаковки/custom-форматов, по умолчанию 0. uint-перегрузка передаёт значение в ulong без получения маски из массивов.
public void AddSurface(Mesh.PrimitiveType primitive, Reckfell.Collections.Array arrays, Reckfell.Collections.Array<Reckfell.Collections.Array> blendShapes = null, Reckfell.Collections.Dictionary lods = null, Material material = null, string name = "", ulong flags = 0);Добавляет staging-поверхность и сбрасывает кэш GetMesh. Сохраняет общий arrays и blend-контейнеры, material/name/flags; не отправляет Changed. Проверка входа частичная: подготовьте допустимые каналы и индексы до построения ArrayMesh. ulong — основной вариант, uint — forwarding overload.
| Имя | Тип | По умолчанию |
|---|---|---|
primitive | Mesh.PrimitiveType | — |
arrays | Reckfell.Collections.Array | — |
blendShapes | Reckfell.Collections.Array<Reckfell.Collections.Array> | null |
lods | Reckfell.Collections.Dictionary | null |
material | Material | null |
name | string | "" |
flags | ulong | 0 |
primitiveСпособ сборки. Для Triangles подготовьте число углов/индексов, кратное трём.
arraysРовно Mesh.ArrayType.Max слотов с непустым Vector3[] Vertex и согласованными каналами. Контейнер сохраняется общим.
blendShapesОдин Max-слотовый Array на объявленную форму в том же порядке, с тем же числом вершин. null только без форм.
lodsНеобязательный Dictionary порог → int[] индексов. Для итогового ArrayMesh нужны положительные пороги и более короткие допустимые списки; staging проверяет это не полностью.
materialОбщая ссылка Material либо null; не клонируется.
nameИмя staging-поверхности; пустое/повторяющееся допустимо.
flagsulong flags упаковки/custom-форматов, по умолчанию 0. uint-перегрузка передаёт значение в ulong без получения маски из массивов.
Clearvoid
public void Clear();Удаляет поверхности, имена blend shapes и кэш результата. Сохраняет blend mode и lightmap size hint; не является полным reset всех настроек и не отправляет Changed.
FromMeshImporterMesh
public static ImporterMesh FromMesh(Mesh mesh);Создаёт ImporterMesh из Mesh: поверхности, формы/LOD, общие Material, имя и metadata. При пустом имени поверхности использует имя Material. Не копирует lightmap hint, shadow mesh и все остальные настройки ресурса. null даёт пустой ImporterMesh.
| Имя | Тип | По умолчанию |
|---|---|---|
mesh | Mesh | — |
meshИсходный Mesh с читаемыми поверхностями либо null для пустого результата; не полный снимок всех настроек.
ImporterMeshНовый собственный ImporterMesh, пустой при null. Material и некоторые данные могут оставаться общими.
GenerateLodsvoid
public void GenerateLods(float normalMergeAngle, float normalSplitAngle, Reckfell.Collections.Array boneTransformArray);Готовит дополнительные индексные уровни детализации треугольных поверхностей. Вызывайте после AddSurface и до первого GetMesh. По исходникам поверхности без индексов пропускаются; наличие вызова само по себе не гарантирует LOD. Проверяйте GetSurfaceLodCount и качество результата.
| Имя | Тип | По умолчанию |
|---|---|---|
normalMergeAngle | float | — |
normalSplitAngle | float | — |
boneTransformArray | Reckfell.Collections.Array | — |
normalMergeAngleУгол объединения нормалей в градусах; в примере 60. Влияет на подготовку упрощения, не является дистанцией переключения LOD.
normalSplitAngleПараметр текущей сигнатуры, который реализация не использует. Пример передаёт 0; изменение этого числа не подтверждает изменение результата.
boneTransformArrayМассив Transform3D для костей при соответствующей геометрии. Для несмещённой статической сферы передаётся пустой Array. Skinned/blend-shape сценарии этим примером не проверены.
GetBlendShapeCountint
public int GetBlendShapeCount();Возвращает число объявленных форм staging-данных; после Clear равно 0.
intНеотрицательное число объявленных форм.
GetBlendShapeModeMesh.BlendShapeMode
public Mesh.BlendShapeMode GetBlendShapeMode();Возвращает staging-режим, по умолчанию Normalized. Он может отличаться от уже кэшированного GetMesh.
Mesh.BlendShapeModeStaging Mesh.BlendShapeMode, первоначально Normalized.
GetBlendShapeNamestring
public string GetBlendShapeName(int blendShapeIdx);Читает имя после замены : на _. Дубликаты возможны; это не гарантированно уникальный идентификатор.
| Имя | Тип | По умолчанию |
|---|---|---|
blendShapeIdx | int | — |
blendShapeIdxИндекс объявленной формы от 0 до GetBlendShapeCount()-1. Для getter массива форма должна присутствовать в выбранной поверхности.
stringСохранённая строка или пустой fallback при неверном индексе.
GetLightmapSizeHintVector2I
public Vector2I GetLightmapSizeHint();Читает сохранённую подсказку размера lightmap. Не измеряет готовую текстуру/UV2 и может отличаться от кэшированного ArrayMesh.
Vector2IVector2I подсказки; (0,0) у нового объекта.
GetMeshArrayMesh
public ArrayMesh GetMesh(ArrayMesh baseMesh = null);Получает ArrayMesh подготовленных поверхностей и LOD. Результат кэшируется: создавайте LOD до первого GetMesh, не рассчитывайте, что повторное чтение автоматически пересоберёт ранее полученный ресурс.
| Имя | Тип | По умолчанию |
|---|---|---|
baseMesh | ArrayMesh | null |
baseMeshНеобязательный ArrayMesh для первичного построения результата. По исходникам используется при отсутствии кэшированного mesh. Не передавайте ресурс, который нельзя изменять.
ArrayMeshArrayMesh с подготовленными LOD либо null при невозможности получить результат. Пример сохраняет его в .rdata, загружает без кэша и повторно подтверждает дальний LOD по отрисованным примитивам.
GetSurfaceArraysReckfell.Collections.Array
public Reckfell.Collections.Array GetSurfaceArrays(int surfaceIdx);Возвращает alias общего Array поверхности. Замена слота меняет staging, но не сбрасывает GetMesh-кэш. Packed-массив, полученный через AsVector3Array и подобные методы, является managed-копией. Освободите свой wrapper после использования.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
Reckfell.Collections.ArrayСобственный wrapper общего Array, не независимый snapshot. При неверном индексе пустой контейнер.
GetSurfaceBlendShapeArraysReckfell.Collections.Array
public Reckfell.Collections.Array GetSurfaceBlendShapeArrays(int surfaceIdx, int blendShapeIdx);Возвращает alias общего Array одной формы поверхности. Правки слотов видны staging-данным и исходному контейнеру, но не обновляют построенный ArrayMesh.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
blendShapeIdx | int | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
blendShapeIdxИндекс объявленной формы от 0 до GetBlendShapeCount()-1. Для getter массива форма должна присутствовать в выбранной поверхности.
Reckfell.Collections.ArrayСобственный wrapper общего Array формы; пустой контейнер при диагностике неверных индексов.
GetSurfaceCountint
public int GetSurfaceCount();Число staging-поверхностей, не число поверхностей произвольного переданного baseMesh.
intЧисло staging-поверхностей; 0 у нового/очищенного объекта.
GetSurfaceFormatulong
public ulong GetSurfaceFormat(int surfaceIdx);Возвращает flags, переданные в AddSurface. Не вычисляет каналы из массивов, поэтому значение 0 допустимо при наличии вершин/индексов. Реальный packed layout читайте у построенного ArrayMesh.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
ulongПереданные flags типа ulong; 0 также используется при неверном surface index.
GetSurfaceLodCountint
public int GetSurfaceLodCount(int surfaceIdx);Читает число дополнительных LOD указанной поверхности. Это число уровней данных ресурса, не количество видимых объектов и не текущий выбранный renderer уровень.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
surfaceIdxИндекс существующей поверхности, начиная с 0.
intКоличество дополнительных уровней; 0 означает отсутствие таких уровней. Базовая полная геометрия в это число не входит.
GetSurfaceLodIndicesint[]
public int[] GetSurfaceLodIndices(int surfaceIdx, int lodIdx);Получает треугольный индексный массив одного подготовленного LOD. Меньше индексов уменьшает передаваемые примитивы, но не означает выгрузку исходного меша или создание отдельной Entity.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
lodIdx | int | — |
surfaceIdxИндекс поверхности.
lodIdxИндекс дополнительного LOD от 0 до GetSurfaceLodCount(surfaceIdx)-1.
int[]Массив int-индексов. Для корректной треугольной поверхности длина кратна 3; в проверке каждый дополнительный уровень короче базового массива.
GetSurfaceLodSizefloat
public float GetSurfaceLodSize(int surfaceIdx, int lodIdx);Читает метрику уровня, используемую при выборе LOD. По исходникам это ошибка упрощения, умноженная на масштаб геометрии, а не готовая мировая дистанция до камеры.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
lodIdx | int | — |
surfaceIdxИндекс поверхности.
lodIdxИндекс дополнительного LOD.
floatМетрика error/scale уровня. Фактический выбор зависит также от проекции, дистанции, масштаба объекта, LodBias и порога viewport.
GetSurfaceMaterialMaterial
public Material GetSurfaceMaterial(int surfaceIdx);Возвращает общую ссылку Material либо null. Это не копия; не освобождайте alias раньше владельца.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
MaterialОбщий Material либо null; диагностический null также возможен при неверном индексе.
GetSurfaceNamestring
public string GetSurfaceName(int surfaceIdx);Возвращает staging-имя, возможно пустое/повторяющееся. Не уникальный постоянный ID.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
stringИмя или пустая строка; пустота не доказывает валидность индекса.
GetSurfacePrimitiveTypeMesh.PrimitiveType
public Mesh.PrimitiveType GetSurfacePrimitiveType(int surfaceIdx);Читает primitive staging-поверхности. Диагностический Max при неверном индексе не описывает допустимую геометрию.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
Mesh.PrimitiveTypeСохранённый primitive либо Max при неверном индексе.
MergeImporterMeshesImporterMesh
public static ImporterMesh MergeImporterMeshes(Reckfell.Collections.Array<ImporterMesh> importerMeshes, Reckfell.Collections.Array<Transform3D> relativeTransforms, bool deduplicateSurfaces = true);Объединяет статические данные с относительными Transform3D. По умолчанию одинаковые name/primitive/flags объединяются без сравнения Material — остаётся первый. Это не welding. Blend shapes/LOD отбрасываются с предупреждением; скелеты не переназначаются. Для разных материалов передавайте false; nonuniform/reflected normals/tangents требуют отдельной проверки.
| Имя | Тип | По умолчанию |
|---|---|---|
importerMeshes | Reckfell.Collections.Array<ImporterMesh> | — |
relativeTransforms | Reckfell.Collections.Array<Transform3D> | — |
deduplicateSurfaces | bool | true |
importerMeshesНепустой typed-массив ненулевых ImporterMesh. Для безопасного общего случая используйте согласованные статические 3D-поверхности.
relativeTransformsПо одному Transform3D на входной mesh, в том же порядке, из его локального пространства в пространство результата.
deduplicateSurfacestrue объединяет совпавшие name/primitive/flags без проверки материалов. false сохраняет отдельные поверхности и различает совпавшие имена суффиксами.
ImporterMeshНовый собственный ImporterMesh либо null при отклонённом входе. Непустой результат не гарантирует сохранение материалов, анимации или качества освещения.
SetBlendShapeModevoid
public void SetBlendShapeMode(Mesh.BlendShapeMode mode);Меняет staging-режим без конвертации массивов, сброса GetMesh-кэша или Changed. Устанавливайте до первого построения.
| Имя | Тип | По умолчанию |
|---|---|---|
mode | Mesh.BlendShapeMode | — |
modeNormalized или Relative согласно подготовленным данным; не меняет кэшированный результат автоматически.
SetLightmapSizeHintvoid
public void SetLightmapSizeHint(Vector2I size);Сохраняет подсказку для следующего построения ArrayMesh. Не создаёт UV2/текстуру и не сбрасывает уже созданный кэш.
| Имя | Тип | По умолчанию |
|---|---|---|
size | Vector2I | — |
sizeНеотрицательные размеры подсказки в texels; (0,0) означает отсутствие заданной подсказки. Это не команда генерации.
SetSurfaceMaterialvoid
public void SetSurfaceMaterial(int surfaceIdx, Material material);Меняет общую ссылку материала staging-поверхности и сбрасывает кэш GetMesh. Уже выданные ArrayMesh не изменяются; Changed не отправляется.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
material | Material | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
materialОбщая ссылка Material либо null; не клонируется.
SetSurfaceNamevoid
public void SetSurfaceName(int surfaceIdx, string name);Меняет staging-имя и сбрасывает GetMesh-кэш. Уникальность не проверяется, старый результат не редактируется, Changed не отправляется.
| Имя | Тип | По умолчанию |
|---|---|---|
surfaceIdx | int | — |
name | string | — |
surfaceIdxТекущий индекс staging-поверхности от 0 до GetSurfaceCount()-1.
nameИмя staging-поверхности; пустое/повторяющееся допустимо.