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

    • 灵视 P1

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

    • 灵光 K1

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

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

    • 灵光 L2 Pro

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

      • 产品概述
      • 设备基本功能
      • 设备激活与连接
      • 设备采集
      • 获取绝对坐标点云数据操作流程
      • 附录
  • 配件

    • 补光灯

      • 安装指导
      • 基本操作
      • 常见问题
  • Lixel Studio

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

    • LCC Studio

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

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

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

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

      • 产品概要说明
      • 基本架构说明书
      • 安装部署说明书
      • 容器启动参数说明书
      • CodeMeter离线授权部署说明书
      • API指令集说明书
      • 附录-开发者数据说明书
      • 附录-错误码列表
      • 单机多卡集群部署QuickStart
    • 使用技巧

      • 多个大型 3DGS 模型融合工作流
    • 历史版本
  • Plugin & SDK

    • Unreal

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

        • 用 LixelStudio 网格为 3DGS 重打光
      • API 参考

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

        • v3.4.0
        • 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
    • Unity

      • Unity SDK 简介
      • 技术特性
      • 开发环境要求
      • PC 快速开发入门指南
      • 工程设置优化指南
      • Pico 4 Ultra 开发指南
      • Pico 4 Ultra PC 串流指南
      • Quest 3 开发指南
      • Quest 3 PC 串流指南
      • OpenXR 开发指南
      • Pico 4 Ultra 企业串流指南
      • 术语表
      • 常见问题
      • 联系我们
      • 功能开发指南

        • 多场景混合渲染开发指南
        • 阴影接收开发指南
        • 实时光照开发指南
        • 多相机渲染开发指南
        • 高清图像渲染开发指南
        • LCC 与 LCC2 数据格式兼容开发指南
        • 加载特效开发指南
        • Mip 渲染模式切换开发指南
        • 边角点吸附开发指南
        • 投影贴花开发指南
        • 视频流投影开发指南
        • 高亮显示开发指南
        • 实时裁剪开发指南
        • 调色开发指南
        • 获取场景 Mesh 数据开发指南
        • 编辑器模式开发指南
        • 渲染性能参数设置指南
        • 应用与数据协同打包开发指南
        • 碰撞系统开发指南
        • macOS 开发权限问题操作指南
        • iOS 设备编译打包开发指南
      • API 参考

        • LCCManager
        • Renderer
        • 数据类型
      • 更新日志

        • v2.3.0
        • v2.2.10
        • v2.2.0
        • v2.1.19
        • v2.0.14
    • X-Brain

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

      • 介绍
      • 渲染性能优化指南
      • 显卡配置
      • 常见开发问题
      • API参考

        • LCCRender::clearIndexDB
        • LCCRender::dispose
        • LCCRender::load
        • LCCRender::setCamera
        • LCCRender::unload
        • LCCRender::update
        • LCCObject::checkRenderNextFrame
        • LCCObject::clearRenderNextFrame
        • LCCObject::ecef2Prj
        • LCCObject::getBounds
        • LCCObject::getEnvInstancedMesh
        • LCCObject::getInstancedMesh
        • LCCObject::getLodInfos
        • LCCObject::getOriginPosition
        • LCCObject::getProjectionCoordinateSystemInfos
        • LCCObject::hasCollision
        • LCCObject::hasEnvironment
        • LCCObject::hasShcoef
        • LCCObject::intersectsCapsule
        • LCCObject::intersectsRayExt
        • LCCObject::intersectsRayFromOriginExt
        • LCCObject::intersectsSphere
        • LCCObject::lowerToBottom
        • LCCObject::prj2Ecef
        • LCCObject::raiseToTop
        • LCCObject::raycast
        • LCCObject::raycastFromOrigin
        • LCCObject::setAlpha
        • LCCObject::setClipBox
        • LCCObject::setClipPlane
        • LCCObject::setEndLod
        • LCCObject::setLodAutoLevelUp
        • LCCObject::setMaxDistance
        • LCCObject::setMaxNodeSplats
        • LCCObject::setMaxSplats
        • LCCObject::setOriginPosition
        • LCCObject::setPointsColor
        • LCCObject::setRenderState
        • LCCObject::setRotation
        • LCCObject::setScale
        • LCCObject::setSemantic
        • LCCObject::setSemanticColor
        • LCCObject::setSmooth
        • LCCObject::setStartLod
        • LCCObject::setTranslation
        • LCCObject::setVisible
        • LCCObject::togglePointsDisplayMode
        • LCCObject::useEnvironment
        • LCCObject::useShcoef
      • 更新日志

        • v0.6.3
        • v0.6.2
        • v0.6.1
        • v0.6.0
        • v0.5.5
        • v0.5.4
        • v0.5.3
        • v0.5.2
        • v0.5.1
        • v0.5.0
        • v0.4.1
        • v0.4.0
        • v0.3.1
        • v0.3.0
        • v0.2.0
    • Lixel OpenAPI

      • 概述
      • 连接与鉴权
      • 消息模型与编解码
      • 接口清单
      • 实时数据
      • 项目文件访问
      • 错误码
      • Python

        • 快速开始
        • 客户端封装与工具
        • 常见问题
      • C++

        • 快速开始
        • 客户端与示例
        • 常见问题

边角点吸附开发指南

LCC Unity SDK 支持对 3DGS 表面进行边缘、角点检测和吸附预览,可用于测量、标注、放置等需要精确定位的交互场景。下面介绍实现边缘/角点检测及吸附的完整步骤。

说明:

吸附功能(边缘/角点检测、吸附预览、带吸附的射线检测)仅在 PC / Mac 平台支持,移动端 / VR 平台调用相关 API 无效并会输出警告。

步骤 1:创建场景与游戏对象

在 Unity 中创建一个全新的场景,Unity 默认会创建 Main Camera 和 Directional Light。

设置 Main Camera

在 Hierarchy 窗口中选择 Main Camera,在 Inspector 窗口中按下图设置其属性。

设置 Main Camera 的属性

设置 Main Camera 的属性

创建 LCCManager

在 Hierarchy 窗口空白处单击鼠标右键,在弹出的菜单中选择 Create Empty,创建一个空游戏对象,命名为 LCCManager,将其 Transform 归一,并通过 Add Component 为其添加 LCCManager 脚本。

创建 LCCManager 游戏对象并添加 LCCManager 脚本

创建 LCCManager 游戏对象并添加 LCCManager 脚本

创建 LCCRenderer

在 Hierarchy 窗口空白处单击鼠标右键,选择 Create Empty,创建一个空游戏对象,命名为 LCCRenderer,将其 Transform 设置为 Rotation.x = -90、Scale.x = -1。

创建 LCCRenderer 并设置 Transform

创建 LCCRenderer 并设置 Transform(Rotation.x = -90、Scale.x = -1)

注意:

LCCRenderer 游戏对象的 Transform 设置(Rotation.x = -90、Scale.x = -1)是与 LCC 数据坐标系的对齐。关于坐标系对齐的详细说明,参见 Unity SDK 简介 中的「LCC 数据坐标系」。

步骤 2:添加 Render Feature

  1. 在 Unity 菜单栏中选择 File → Project Settings,在左侧选择 Graphics,确认当前使用的 Default Render Pipeline Asset。本示例为 URP(Universal Render Pipeline Asset)。
在 Graphics 设置中确认 Default Render Pipeline Asset

在 Graphics 设置中确认 Default Render Pipeline Asset

  1. 点击该 Asset,在 Project 窗口中定位到对应的资源文件,找到与之关联的 Renderer(本示例为 URP_Renderer.asset)。

  2. 选中该 Renderer 资源文件,在 Inspector 窗口中点击 Add Renderer Feature,添加 Snap Frame Capture Feature。

在 URP Renderer 中添加 Snap Frame Capture Feature

在 URP Renderer 中添加 Snap Frame Capture Feature

步骤 3:编写脚本开启吸附功能

新建一个 C# 脚本,命名为 Snap.cs,代码如下:

using LCCCore;
using UnityEngine;

public class Snap : MonoBehaviour
{
    public LCCManager m_manager;
    public string m_FilePath;
    private LCCCore.Renderer m_renderer;
    private bool m_loaded = false;
    private Camera m_camera;

    void Start()
    {
        m_camera = Camera.main;
        m_manager.SetPlatformType(PlatformType.PC);
        Debug.Log("Started ");
        m_renderer = m_manager.GetRender(this.transform);
        m_renderer.Load(m_FilePath, onProgress, onComplete);
    }

    private void onProgress(float _progress)
    {
        Debug.Log($"[LCCRenderer] file load progress: {_progress:P1}");
    }

    private void onComplete()
    {
        Debug.Log($"[LCCRenderer] file loaded");
        m_loaded = true;
        // 开启边缘/角点检测与吸附预览
        m_manager.SetSnapEnabled(true);
        m_manager.SetSnapPreviewEnabled(true);
    }

    private void Update()
    {
        if (!m_loaded) return;
        // 根据当前鼠标位置实时更新吸附预览
        m_manager.UpdateSnapPreview(Input.mousePosition, m_camera);
        if (Input.GetMouseButtonDown(1))
        {
            m_manager.RaycastWithSnap(Input.mousePosition, m_camera, out HitResult result);
            if (result.isHit)
            {
                GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                sphere.transform.position = result.hitPos;
                sphere.GetComponent<UnityEngine.Renderer>().material.color = Color.red;
                sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
            }
        }
    }
}

注意:

边缘/角点检测(SetSnapEnabled)与吸附预览(SetSnapPreviewEnabled)需要在 LCC 场景加载完成后开启,因此二者都在 onComplete 回调中调用。吸附预览还需要在 Update 中通过 UpdateSnapPreview 持续更新。

上述示例演示了以下要点:

  • 开启边缘、角点检测:m_manager.SetSnapEnabled(true)
  • 开启吸附预览:m_manager.SetSnapPreviewEnabled(true)
  • 实时更新吸附预览:m_manager.UpdateSnapPreview(Input.mousePosition, m_camera)
  • 在吸附点进行射线检测并创建碰撞点小球:m_manager.RaycastWithSnap(...),命中后在 result.hitPos 处创建红色小球

步骤 4:挂载脚本并设置数据路径

  1. 将 Snap.cs 脚本挂载到 Hierarchy 窗口中的 LCCRenderer 游戏对象上。
  2. 在 Inspector 窗口中,将 LCCManager 游戏对象拖动到脚本的 Manager 属性上。
  3. 在脚本的 File Path 属性中填写 LCC 文件的路径地址。

步骤 5:运行

在 Game 窗口中点击 Play 按钮,即可看到实时检测到的边缘、角点以及吸附目标的预览图标。移动鼠标时预览图标会实时跟随最近的吸附目标;单击鼠标右键会在吸附点处进行射线检测并创建一个红色小球。

运行后实时检测到的边缘、角点及吸附预览图标

运行后实时检测到的边缘、角点及吸附预览图标

常见问题:关闭兼容模式

如果 Unity Console 窗口报错且没有出现吸附预览图标,请关闭兼容模式:通过 Edit → Project Settings → Graphics 打开设置面板,选择 URP 选项卡,不要勾选 Render Graph → Compatibility Mode (Render Graph Disabled) 后的多选框。

不要勾选 Render Graph 兼容模式

不要勾选 Render Graph 兼容模式(Render Graph Disabled)

关键步骤

实现边缘/角点检测及吸附的关键步骤:

  1. 确保在 URP Renderer 中添加了 Snap Frame Capture Feature 渲染特性。
  2. 确保在 LCC 场景加载完成后通过代码开启了边缘/角点检测功能(SetSnapEnabled(true))和吸附预览功能(SetSnapPreviewEnabled(true))。
  3. 确保在 Update 中实时调用 UpdateSnapPreview 更新预览图标。

吸附相关 API

LCC Unity SDK 通过 LCCManager 提供了以下吸附相关 API。它们仅在 PC / Mac 平台支持,移动端 / VR 平台调用无效并输出警告;且都需要在 LCC 场景加载完成后调用。

SetSnapEnabled

// 返回值:void
public void SetSnapEnabled(bool enable)

开关吸附功能。启用后 RaycastWithSnap 会自动搜索附近的边缘/角点进行吸附。

参数类型说明
enablebool是否启用吸附

调用示例:

m_manager.SetSnapEnabled(true);

说明:

  • 默认关闭。
  • 仅 PC / Mac 平台支持,移动端 / VR 调用无效并输出警告。
  • 启用后会分配 GPU 资源(EdgeDetect / CornerDetect / SnapSearch )。

SetSnapRadius

// 返回值:void
public void SetSnapRadius(float pixels)

设置吸附搜索半径。在此像素范围内搜索最近的边缘/角点。

参数类型说明
pixelsfloat吸附搜索半径(像素)

调用示例:

m_manager.SetSnapRadius(30f);

说明:

  • 默认 20 像素。
  • 值越大搜索范围越广,但可能吸附到非预期目标。
  • 仅 PC / Mac 平台支持。

SetEdgeThreshold

// 返回值:void
public void SetEdgeThreshold(float threshold)

设置 Sobel 边缘检测的阈值。值越小检测到的边缘越多。

参数类型说明
thresholdfloat边缘检测阈值

调用示例:

m_manager.SetEdgeThreshold(0.2f);

说明:

  • 默认 0.3。
  • 建议取值范围 [0.1, 0.8]。
  • 值过小会产生大量噪声边缘。
  • 仅 PC / Mac 平台支持。

SetSnapPreviewEnabled

// 返回值:void
public void SetSnapPreviewEnabled(bool enable)

开关吸附预览功能。启用后鼠标移动时实时显示最近的吸附目标指示器。

参数类型说明
enablebool是否启用吸附预览

调用示例:

m_manager.SetSnapPreviewEnabled(true);

说明:

  • 需先调用 SetSnapEnabled(true)。
  • 预览会持续消耗 GPU 资源(每帧检测)。
  • 仅 PC / Mac 平台支持。

UpdateSnapPreview

// 返回值:void
public void UpdateSnapPreview(Vector2 mousePos, Camera cam)

更新吸附预览状态。在鼠标移动时调用,更新预览指示器位置。

参数类型说明
mousePosVector2当前鼠标屏幕坐标
camCamera相机

调用示例:

void Update()
{
    m_manager.UpdateSnapPreview(Input.mousePosition, Camera.main);
}

说明:

  • 需先调用 SetSnapPreviewEnabled(true)。
  • 建议在 Update 中持续调用。
  • 仅 PC / Mac 平台支持。

GetSnapPreviewState

// 返回值:SnapPreviewState(screenPos 为屏幕坐标)
public SnapPreviewState GetSnapPreviewState()

获取当前吸附预览状态,包括是否有吸附目标、目标类型、目标屏幕位置和到鼠标的像素距离。

调用示例:

var state = m_manager.GetSnapPreviewState();
if (state.hasTarget)
{
    // state.snapType: Corner / Edge
    // state.screenPos: 吸附目标屏幕坐标
    // state.distanceToMouse: 像素距离
}

说明:

  • 需先调用 SetSnapPreviewEnabled(true) 和 UpdateSnapPreview。
  • 无目标时返回 default(SnapPreviewState)。
  • screenPos 是屏幕坐标,不是世界坐标;需要世界坐标时请用 RaycastWithSnap 取 HitResult.hitPos。
  • 仅 PC / Mac 平台支持。

RaycastWithSnap

// 返回值:bool(true = 命中)
public bool RaycastWithSnap(Vector2 screenPos, Camera cam, out HitResult result)

带吸附功能的射线检测。先进行普通 Raycast,再在命中点附近搜索边缘/角点进行吸附。

参数类型说明
screenPosVector2屏幕坐标
camCamera相机
resultout HitResult命中结果(含吸附信息)

调用示例:

if (m_manager.RaycastWithSnap(Input.mousePosition, m_camera, out HitResult hit))
{
    // hit.snapType: Corner / Edge / None
    // hit.hitPos: 吸附后的世界坐标
    // hit.originalHitPos: 吸附前的原始命中点
}

说明:

  • 需先调用 SetSnapEnabled(true)。
  • 吸附优先级:Corner > Edge > None。
  • 本入口同步阻塞主线程(等待 GPU 回读结果),建议仅在交互事件(如点击)时调用,不要每帧调用。
  • 预览模式(SetSnapPreviewEnabled(true))下若已有吸附目标,则直接复用预览缓存,不再重新计算;否则走正常吸附流程。
  • 仅 PC / Mac 平台支持。

相关数据结构

SnapType

public enum SnapType { None, Edge, Corner }

吸附目标类型:无 / 边缘 / 角点。

SnapPreviewState

public struct SnapPreviewState {
    public bool hasTarget;          // 是否有吸附目标
    public SnapType snapType;       // None / Edge / Corner
    public Vector2 screenPos;       // 吸附目标屏幕坐标(非世界坐标)
    public float distanceToMouse;   // 到鼠标位置的像素距离
}

⚠️ screenPos 是屏幕像素坐标,不是世界坐标。需要世界坐标时请用 RaycastWithSnap 取 HitResult.hitPos。

HitResult

public struct HitResult {
    public bool isHit;             // 是否命中
    public float distance;         // 距离
    public Vector3 hitPos;         // 命中点世界坐标(字段名为 hitPos,非 position)
    public Vector3 normal;         // 命中法线
    public float hitAlpha;         // 被击中椭球的 Alpha
    public float dist2Origin;      // 到射线源的距离
    public float scale;            // 椭球 scale
    public SnapType snapType;      // 吸附类型(None / Edge / Corner)
    public Vector3 originalHitPos; // 吸附前原始命中点
}

⚠️ 字段命名差异:命中点世界坐标的字段是 hitPos(而非 position),调用方代码请按实际字段名访问。