Actor SOG / SPZ / PLY: загрузка одиночных файлов 3DGS
Три Actor — ASogActor, ASpzActor и APlyActor — соответствуют форматам .sog, .spz и .ply и служат для загрузки одиночного файла 3DGS без структуры каталогов LCC. Все они наследуют ALCCActorBase.
| Модуль | LCC4UnrealRuntime |
| Заголовочные файлы | SogActor.h, SpzActor.h, PlyActor.h |
| Родительский класс | ALCCActorBase |
| Внутренний Component | ULCC2Component |
#include "SogActor.h"
#include "SpzActor.h"
#include "PlyActor.h"
Все три внутри повторно используют полный конвейер рендеринга LCC2, конструируя виртуальную FLCC2MetaInfo. То есть возможности LCC2 так же доступны для этих трёх форматов, включая управление полосами сферических гармоник, режимы нормалей для освещения, обрезку и секущие плоскости, коррекцию цвета. По той же причине наследуются и ограничения конвейера LCC2, например неработающие интерфейсы для нескольких вьюпортов.
Поддерживаемые форматы
| Actor | Расширение | Область применения |
|---|---|---|
ASogActor | .sog | Сжатый формат, малый объём, быстрая загрузка |
ASpzActor | .spz | Сжатый формат |
APlyActor | .ply | Универсальный формат обмена облаками точек и 3DGS, штатный вывод большинства инструментов обучения |
Объём поддержки каждого формата см. в Введении — поддерживаемые форматы.
Сравнение с форматами каталогов LCC
.sog / .spz / .ply | Каталог LCC / LCC2 | |
|---|---|---|
| Организация файлов | Один файл | Файл метаинформации + несколько блоков данных |
| Уровни LOD | Нет | Есть, потоковая загрузка по расстоянию |
| Подходящий масштаб | Небольшие и средние сцены | Большие сцены |
| Данные коллизий | Нет | Могут быть |
| Удобство распространения | Высокое, один файл | Требуется сохранять целостность каталога |
Основание для выбора: эти три формата подходят, когда объём данных невелик, нужно быстро проверить результат или требуется распространение одним файлом. Для больших сцен, где производительность держится на LOD, обязательны форматы каталогов LCC / LCC2.
Методы
Все публичные интерфейсы этих трёх Actor унаследованы от ALCCActorBase; переопределены только перечисленные ниже методы.
SelectFile
// ASogActor
virtual void SelectFile() override; // the dialog lists only .sog
// ASpzActor
virtual void SelectFile() override; // the dialog lists only .spz
// APlyActor
virtual void SelectFile() override; // the dialog lists only .ply
Открывает диалог выбора файла, каждый со своим фильтром расширения. В панели Details отображается как кнопка Load.
Доступно только в редакторе; в упакованной сборке используй Load.
Load (переопределён только в APlyActor)
// APlyActor
virtual void Load(const FString& String) const override;
Загружает файл .ply. Путь с расширением, отличным от .ply, отклоняется сразу, попытка разбора не выполняется.
ASogActor и ASpzActor не переопределяют Load и используют реализацию базового класса.
Примеры
Загрузка одиночного файла .sog
#include "SogActor.h"
#include "LCC2Component.h"
void AMyLoader::LoadSogFile()
{
ASogActor* SogActor = GetWorld()->SpawnActor<ASogActor>(
ASogActor::StaticClass(), FVector::ZeroVector, FRotator::ZeroRotator);
if (!SogActor)
{
return;
}
SogActor->Load(TEXT("D:/Data/scene.sog"));
// Internally it is a ULCC2Component, so all LCC2 capabilities are available
ULCC2Component* Comp = Cast<ULCC2Component>(SogActor->GetLCCComponent());
if (Comp)
{
Comp->SetSHBands(2);
Comp->SetSplatScale(0.9f);
}
}
Автоматический выбор Actor по расширению
У каждого формата свой Actor, поэтому в реальных проектах обычно требуется распределение по расширению.
Не полагайся для этого на DetermineFileFormat: эта функция распознаёт только .lcc, .splats, .las и .ply, а для .lcc2, .sog и .spz неизменно возвращает None. Прямая проверка расширения надёжнее:
#include "Tools/LCCUtilLibrary.h"
#include "LCCActor.h"
#include "LCC2Actor.h"
#include "SogActor.h"
#include "SpzActor.h"
#include "PlyActor.h"
ALCCActorBase* AMyLoader::LoadAnyFormat(const FString& Path)
{
if (!ULCCUtilLibrary::CheckPathValid(Path))
{
UE_LOG(LogTemp, Error, TEXT("Path does not exist: %s"), *Path);
return nullptr;
}
const FString Ext = FPaths::GetExtension(Path).ToLower();
UClass* ActorClass = nullptr;
if (Ext == TEXT("lcc")) ActorClass = ALCCActor::StaticClass();
else if (Ext == TEXT("lcc2")) ActorClass = ALCC2Actor::StaticClass();
else if (Ext == TEXT("sog")) ActorClass = ASogActor::StaticClass();
else if (Ext == TEXT("spz")) ActorClass = ASpzActor::StaticClass();
else if (Ext == TEXT("ply")) ActorClass = APlyActor::StaticClass();
if (!ActorClass)
{
UE_LOG(LogTemp, Error, TEXT("Unsupported format: %s"), *Path);
return nullptr;
}
ALCCActorBase* Actor = GetWorld()->SpawnActor<ALCCActorBase>(
ActorClass, FVector::ZeroVector, FRotator::ZeroRotator);
if (Actor)
{
Actor->Load(Path);
}
return Actor;
}
В Blueprint нет узла, напрямую получающего расширение, поэтому можно использовать проверку строки:
[Custom Event: LoadAnyFormat]
Path (String)
│
▼
[Check Path Valid]
Path = Path
│ Return Value ──┐
▼ │
[Branch] ◀───────────────┘
│ True
▼
[Ends With]
Source String = Path
In Suffix = ".sog"
Search Case = Ignore Case
│ Return Value ──┐
▼ │
[Branch] ◀───────────────┘
│ True
▼
[Spawn Actor from Class]
Class = SogActor
│ Return Value ──┐
▼ │
[Load] ◀─────────────────┘
Target = (Return Value)
String = Path
(the False branch keeps checking ".spz", ".ply", ".lcc2", ".lcc" with Ends With)
Замечания
- У этих трёх форматов нет уровней LOD. При загрузке строится дерево из одного уровня с одним узлом (общее число уровней 1, у корневого узла нет дочерних), поэтому параметры LOD
StartLevel,EndLevelиLevelFactorхотя и читаются, но выбирать уровни не из чего, и фактически они не действуют. Производительностью управляют главным образом черезMaxSplatNumиSplatScale. - Эти три формата не содержат данных коллизий, альтернативы см. в Коллизиях — альтернативы для одиночных форматов.
- Файлы большого объёма загружаются целиком за один раз, расход видеопамяти постоянен и не меняется вместе с ракурсом. Предел загрузки и способ его расчёта см. в Рендеринге — ограничения загрузки одиночных форматов.
- В панели Details всех трёх отображается
bSyncLoadAtRuntime(по умолчанию включено), которое определяет, выполняется ли в упакованной сборке синхронная загрузка на этапе BeginPlay, см. ULCC2Component. - Используется конвейер рендеринга LCC2, поэтому интерфейсы для нескольких вьюпортов из базового класса не применимы.
- Все три при конструировании задают компоненту
bUseMipFilterзначениеfalse(в базовом классе по умолчаниюtrue) и устанавливают поворот Actor в(0, 0, 90). - У
.plyесть несколько подформатов; плагин поддерживает вариант с атрибутами 3DGS. Загрузка обычного геометрического меша.plyзавершится ошибкой.
Смотрите также
- ALCCActorBase: все унаследованные интерфейсы
- ULCC2Component: компонент, который используют эти три Actor внутри
- ULCCUtilLibrary: определение формата и проверка пути