XGRIDS文档
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • 灵视 P1

    • 产品概述
    • 设备基本操作
    • 使用 LCC Scan App
    • 维护及保养
    • 常见问题
  • 灵光 K 系列

    • 灵光 K1

      • 产品概述
      • 设备基本操作
      • 设备激活与连接
      • 设备采集
      • 获取绝对坐标点云数据
      • 地图融合
      • 典型场景路线规划建议
      • 注意事项
      • 常见问题
    • 灵光 K2

      • 产品概述
      • 设备基本操作
      • 设备激活与连接
      • 设备采集
      • 获取绝对坐标点云数据
      • 地图融合
      • 典型场景路线规划建议
      • 注意事项
      • 常见问题
  • 灵光 L 系列

    • 灵光 L2 Pro

      • 产品概述
      • 设备基本操作
      • 设备激活与连接
      • 设备采集
      • 获取绝对坐标点云数据
      • 实时测量功能
      • 附录
      • 常见问题
  • Lixel Studio

    • 版权
    • 安装与激活
    • 界面说明
    • 文件
    • 工程处理
    • 工具
    • 平面绘制
    • 行业应用
    • 设置
    • 设备感知
  • Lixel CyberColor

    • LCC Studio

      • 入门
      • 版本与更新
      • 下载与安装
      • 界面概览与导航
      • 重建前工作
      • 模型重建
      • 单模型重建
      • 地图融合
      • 空地融合
      • 航拍重建
      • 我的模型
      • 其他功能
      • 设置与账号
      • 转换工具
      • 视频重建
      • 常见问题 / FAQ
    • LCC Scene Editor

      • 版本与更新
      • 账号与登录
      • 产品概览与主页
      • 编辑器界面介绍
      • 三种场景漫游快捷操作
      • 文件
      • 设置
      • 编辑操作
      • 窗口
      • 视图工具栏
      • 资产与属性
      • 左侧工具栏
      • 视点
      • 跳转点
      • 天空盒
      • 标注
      • 测量
      • 场景漫游
      • 场景报告
      • 智能户型图(3D Layout)
      • 小地图
      • 预览模式(Viewer)
      • 帮助
      • 常见问题 / FAQ
      • 出生点
    • LCC Model Editor

      • 版本与更新
      • 新手指引
      • 概览与界面
      • 文件操作
      • 选择器
      • 编辑操作
      • 测量
      • 调色
      • 资产管理
      • 设置与帮助
      • 常见问题 / FAQ
    • 采集指南

      • 概述
      • 采集设备总览
      • 通用采集原则
      • 室内场景采集
      • 室外场景采集
      • 大场景采集(地图融合)
      • 空地融合采集
      • 物体采集
      • 人物采集
      • 视频重建采集
      • 高清补拍
      • 控制点(灵视 P1)
      • 常见问题与排查
    • 历史版本
  • Plugin & SDK

    • Unreal

      • 介绍
      • 快速入门 - Windows
      • 快速入门 - Linux
      • 快速入门 - Quest3
      • 版本与授权
      • 渲染
      • 画面调节
      • 法线与光照
      • 场景编辑
      • 性能参数说明
      • 性能优化指南
      • 第三方与引擎插件集成
      • 代理网格
      • 加载动画
      • 碰撞
      • 寻路系统支持
      • 单层水支持
      • 本地化
      • 常见问题
      • 故障排查
      • 日志与诊断
      • 联系我们
      • API 参考

        • ALCCActorBase
        • ULCCComponentBase
        • ULCCComponent
        • ULCC2Component
        • SOG / SPZ / PLY Actors
        • ALCC2ProxyMesh
        • ALCCClippingVolume
        • ALCCSectionPlane
        • ULCCUtilLibrary
        • Enums
        • Structs
      • 更新日志

        • v3.3.1
        • v3.0.0
        • v2.2.1
        • v1.0.0
        • v0.9.0
        • v0.8.0
        • v0.7.1
        • v0.6.1
        • v0.5.2
        • v0.4.1
        • v0.4.0
        • v0.3.0
        • v0.0.5
        • v0.0.4
        • v0.0.3
        • v0.0.2
        • v0.0.1
    • X-Brain 系列

      • 产品概述
      • 快速开始
      • 核心概念
      • 集成指南
      • API 参考
      • 数据类型
      • ROS2 桥接
      • 示例程序
      • 部署与网络
      • 排障与 FAQ
      • 版本与发布

ALCCActorBase:3DGS Actor 基类

所有 LCC Actor 的基类,负责把 3DGS 数据放进关卡。ALCCActor、ALCC2Actor、ASogActor、ASpzActor、APlyActor 都继承自它。

模块LCC4UnrealRuntime
头文件LCCActorBase.h
父类AActor
蓝图可继承(BlueprintType)
#include "LCCActorBase.h"

Actor 本身不做渲染,它持有一个 ULCCComponentBase 并把加载类操作转发过去。渲染参数、颜色、性能、碰撞全部在 Component 上,通过 GetLCCComponent 获取。

缩放限制:LCC 系列 Actor 只支持等比缩放。 不要使用带负值的缩放(如 (-1, 1, 1))或各轴不等的缩放(如 (2, 1, 3)),否则会出现渲染异常,画面上通常表现为一道线。

Properties

属性类型访问说明
DefaultSceneRootULCCFocusRootComponent*只读不可见的根组件。存在的唯一目的是给编辑器视口一个固定的小包围盒,按 F 聚焦时不会因为场景巨大而失效。
LCCComponentULCCComponentBase*只读真正干活的组件。子类构造时决定它的具体类型。

两个属性都是 VisibleAnywhere + BlueprintReadOnly,不能在细节面板或蓝图里替换,只能读。

Methods

Load

UFUNCTION(BlueprintCallable, Category = "XGrids")
virtual void Load(const FString& String) const;

按路径加载 3DGS 数据。这是运行时加载场景的主入口。

参数:

参数类型说明
Stringconst FString&数据文件路径。支持绝对路径(D:/Data/Tower/Tower.lcc)和相对路径。相对路径以工程 Content 目录为基准,例如 Tower/Tower.lcc 指向 Content/Tower/Tower.lcc。

不同子类接受的路径形态不同:

Actor传入什么
ALCCActorLCC1 的 .lcc 文件路径。文件名不固定,同目录必须有 data.bin 与 index.bin
ALCC2ActorLCC2 的 .lcc2 文件路径。文件名不固定
ASogActor.sog 文件路径
ASpzActor.spz 文件路径
APlyActor.ply 文件路径,扩展名不是 .ply 会被直接拒绝

注:.lcc 与 .lcc2 的文件名由数据生产端决定,不要假设它一定叫 meta.lcc。判断格式请看扩展名,或用 ULCCUtilLibrary::DetermineFileFormat。

用法要点:

  • 方法是 const,因为状态变更发生在 LCCComponent 内部,不修改 Actor 自身。
  • 加载是异步的。调用返回时数据还没就绪,当前版本需要用 GetLCCComponent()->CheckIfLoaded() 轮询。后续版本会提供加载完成回调,届时不必再轮询。
  • CheckIfLoaded() 返回 true 只代表元信息与索引已建立、可以安全读参数配参数,Splat 数据仍在按视角流式加载,画面会继续补齐。
  • 想在关卡里预设路径而不写代码,直接在细节面板设 Component 的 DefaultLoadPath,运行时会自动加载。
  • 传入空路径等价于卸载当前数据。
  • 传入的路径与当前已加载的路径相同时,调用会直接返回,不会重新加载。
  • 路径可疑时先用 ULCCUtilLibrary::CheckLCCValid 校验,避免加载失败只在日志里报错。

C++ 示例:

#include "LCCActor.h"
#include "LCCComponentBase.h"

void AMyGameMode::SpawnLCCScene()
{
    // 生成 Actor
    ALCCActor* LCCActor = GetWorld()->SpawnActor<ALCCActor>(
        ALCCActor::StaticClass(),
        FVector::ZeroVector,
        FRotator::ZeroRotator);

    if (!LCCActor)
    {
        return;
    }

    // 绝对路径加载
    LCCActor->Load(TEXT("D:/Data/Tower/Tower.lcc"));

    // 或相对 Content 目录加载
    // LCCActor->Load(TEXT("Tower/Tower.lcc"));
}

等待加载完成后再操作。当前版本没有回调,只能轮询:

void AMyActor::LoadAndConfigure()
{
    LCCActor->Load(TEXT("D:/Data/Tower/Tower.lcc"));

    // 每 0.2 秒检查一次是否就绪
    GetWorld()->GetTimerManager().SetTimer(
        LoadCheckTimer, this, &AMyActor::OnCheckLoaded, 0.2f, true);
}

void AMyActor::OnCheckLoaded()
{
    ULCCComponentBase* Component = LCCActor->GetLCCComponent();
    if (!Component || !Component->CheckIfLoaded())
    {
        return;
    }

    GetWorld()->GetTimerManager().ClearTimer(LoadCheckTimer);

    // 元信息已就绪,可以安全配参数(Splat 数据仍在流式加载)
    Component->SetRenderMode(ERenderMode::Splatting);
    UE_LOG(LogTemp, Log, TEXT("Total splats: %d"), Component->GetSplatNumber());
}

文本蓝图:

[Event BeginPlay]
        │
        ▼
[Spawn Actor from Class]
        Class = LCCActor
        Spawn Transform = (默认)
        │ Return Value ──┐
        ▼                │
[Load] ◀────────────────┘
        Target = (上一步的 Return Value)
        String = "D:/Data/Tower/Tower.lcc"

UnLoad

UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
    meta = (DisplayName = "UnLoad", DisplayPriority = 2))
virtual void UnLoad();

卸载当前数据并释放资源,包括 GPU 缓冲、节点缓存和碰撞体。

用法要点:

  • 带 CallInEditor,细节面板 Actions 分类下有一个 UnLoad 按钮,编辑器里可直接点。
  • 卸载后 Actor 还在关卡里,只是不再渲染任何内容。再调 Load 可以加载别的数据。
  • 切换大场景时先 UnLoad 再 Load,避免两份数据同时占用显存。
  • 不需要手动在 EndPlay 里调用,Component 销毁时会自行清理。

C++ 示例,切换场景:

void AMyManager::SwitchScene(const FString& NewPath)
{
    // 先释放旧数据,防止显存峰值叠加
    LCCActor->UnLoad();
    LCCActor->Load(NewPath);
}

Refresh

UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
    meta = (DisplayPriority = 3))
virtual void Refresh();

重新加载当前数据。内部实现是先 UnLoad() 再 Load(),所以开销与一次完整重新加载相当,不是轻量操作。

之所以能重新加载「当前」数据,是因为加载成功时会把路径同步写入 DefaultLoadPath,Refresh 取的就是这个值。

用法要点:

  • 磁盘上的数据文件被替换后,用它重新读盘。
  • 想让渲染结果重新计算一遍,不要用它。改属性走 Setter 会自动触发更新;确实需要推一帧的话用 Component 的 ForceUpdate(),那个才是轻量的。
  • 重新加载后需要重新等待就绪,之前对 Component 设置的运行时参数需要视情况重设。
  • 编辑器细节面板 Actions 分类下有对应按钮。

GetLCCComponent

UFUNCTION(BlueprintCallable, Category = "XGrids")
ULCCComponentBase* GetLCCComponent() const;

返回 Actor 内部的 Component 指针。这是访问全部渲染能力的入口。

返回值:ULCCComponentBase*。正常情况下非空,Actor 构造时就已创建。

用法要点:

  • 需要子类专属能力时向下转型。ALCCActor 拿到的是 ULCCComponent,ALCC2Actor 与三种单文件 Actor 拿到的是 ULCC2Component。
  • 转型一律用 Cast<>,不要用 C 风格强转。类型不匹配时 Cast 返回 nullptr,方便早退。

C++ 示例,改基类通用参数:

ULCCComponentBase* Component = LCCActor->GetLCCComponent();
if (Component)
{
    Component->SetSplatScale(0.8f);
    Component->SetGlobalAlpha(1.0f);
}

向下转型访问 LCC2 专属参数:

#include "LCC2Component.h"

ULCC2Component* LCC2Comp = Cast<ULCC2Component>(LCC2Actor->GetLCCComponent());
if (LCC2Comp)
{
    LCC2Comp->SetSHBands(2);
    LCC2Comp->NormalMode = ELCC2NormalGenerationMode::Hemispherical;
}

文本蓝图,蓝图里转型用 Cast To 节点:

[Get LCC Component]
        Target = LCCActor
        │ Return Value ──┐
        ▼                │
[Cast To LCC2Component] ◀┘
        Object = (上一步的 Return Value)
        │ Cast Succeeded
        ▼
[Set SH Bands]
        Target = (Cast 输出的 As LCC2 Component)
        In SH Bands = 2

SelectFile

UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
    meta = (DisplayName = "Load", DisplayPriority = 1))
virtual void SelectFile();

弹出系统文件选择对话框,选中后立即加载。

用法要点:

  • 细节面板上显示为 Load 按钮,是编辑器里加载数据最常用的入口。
  • 各子类重写了它,用于过滤对应扩展名:ASogActor 只列 .sog,ASpzActor 只列 .spz,APlyActor 只列 .ply。
  • 依赖编辑器的对话框能力,打包后的运行时不要用它,运行时请用 Load。

DebugNodeBound

UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
    meta = (DisplayName = "Debug Node Bound", DisplayPriority = 4))
void DebugNodeBound();

开关八叉树节点边界的可视化,用线框盒画出当前加载的节点。

盒体颜色对应节点 Level:红、橙、黄、绿、蓝、紫依次递进,红色是最低 Level(细节最高),白色是最高 Level(细节最低)。

用法要点:

  • 排查 LOD 问题时用。看到远处还在渲染红色盒子,说明 LevelFactor 偏小或 StartLevel 设得太低,性能被浪费了。
  • 反过来,近处全是高 Level 的冷色盒子,说明细节被压得过狠,画面会发糊。
  • 再调用一次关闭,是开关式的。
  • 只在编辑器与开发构建下有效。

Stats

UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
    meta = (DisplayPriority = 5))
void Stats();

开关渲染统计面板,等价于控制台执行 stat XGrids。

面板给出当前渲染的 Splat 数量、加载中的节点数、各阶段耗时。调性能参数时对着它看效果,比凭感觉调靠谱。

ShowCollision

UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
    meta = (DisplayName = "Show Collision", DisplayPriority = 6))
void ShowCollision();

开关碰撞线框可视化,等价于控制台执行 r.xgrids.DrawCollision。

用法要点:

  • 前提是数据本身带碰撞,且 Component 的 bEnableCollision 已打开,否则什么都不会显示。
  • 角色穿模、射线打不中的时候先开这个,确认碰撞体到底有没有加载出来。
  • 碰撞是按距离流式加载的,远处没有线框属于正常表现,受 Performance.CollisionLoadMaxDistance 控制。

ShowFPS

UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
    meta = (DisplayName = "Show FPS", DisplayPriority = 7))
void ShowFPS();

开关帧率显示,等价于控制台执行 stat fps。配合 Stats 一起用,一边看帧率一边看 Splat 数量。

Complete Example

运行时加载一个 LCC 场景,就绪后配置渲染参数:

// MyLCCLoader.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyLCCLoader.generated.h"

UCLASS()
class AMyLCCLoader : public AActor
{
    GENERATED_BODY()

public:
    /** 要加载的数据路径,绝对路径或相对 Content 目录 */
    UPROPERTY(EditAnywhere, Category = "MyLCC")
    FString ScenePath = TEXT("Tower/Tower.lcc");

protected:
    virtual void BeginPlay() override;

private:
    void OnLoadCheck();

    UPROPERTY()
    TObjectPtr<class ALCCActor> LCCActor;

    FTimerHandle LoadCheckTimer;
};
// MyLCCLoader.cpp
#include "MyLCCLoader.h"
#include "LCCActor.h"
#include "LCCComponentBase.h"

void AMyLCCLoader::BeginPlay()
{
    Super::BeginPlay();

    LCCActor = GetWorld()->SpawnActor<ALCCActor>(
        ALCCActor::StaticClass(), GetActorTransform());
    if (!LCCActor)
    {
        return;
    }

    LCCActor->Load(ScenePath);

    GetWorld()->GetTimerManager().SetTimer(
        LoadCheckTimer, this, &AMyLCCLoader::OnLoadCheck, 0.2f, true);
}

void AMyLCCLoader::OnLoadCheck()
{
    ULCCComponentBase* Component = LCCActor ? LCCActor->GetLCCComponent() : nullptr;
    if (!Component || !Component->CheckIfLoaded())
    {
        return;
    }

    GetWorld()->GetTimerManager().ClearTimer(LoadCheckTimer);

    // 元信息已就绪,按需要配置
    Component->SetRenderMode(ERenderMode::Splatting);
    Component->SetSplatScale(0.9f);
    Component->SetMaxDistance(200);        // 最远渲染 200 米
    Component->SetMaxSplatNum(1500);       // 每帧最多 1500 万个 Splat
    Component->SetLCCCollisionEnable(true);

    UE_LOG(LogTemp, Log, TEXT("LCC ready, splat number: %d"),
        Component->GetSplatNumber());
}

See Also

  • ULCCComponentBase:渲染与性能参数都在这里
  • SOG / SPZ / PLY Actors:三种单文件格式的专用 Actor
  • ULCCUtilLibrary:加载前的路径与格式校验
下一页
ULCCComponentBase