XGRIDSDocs
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • Lixel PortalCam-serie

    • PortalCam P1

      • Productoverzicht
      • Basisbediening
      • De LCC Scan App gebruiken
      • Onderhoud en verzorging
      • Veelgestelde vragen
  • Lixel K-serie

    • Lixel K1

      • Productoverzicht
      • Basisbediening
      • Apparaat activeren en verbinden
      • Scanworkflow
      • Puntenwolkgegevens met absolute coördinaten verkrijgen
      • Kaartfusie
      • Suggesties voor routeplanning bij typische scènes
      • Voorzorgsmaatregelen
      • FAQ
    • Lixel K2

      • Productoverzicht
      • Basisbediening
      • Apparaat activeren en verbinden
      • Scanworkflow
      • Puntenwolkgegevens met absolute coördinaten verkrijgen
      • Kaartfusie
      • Suggesties voor routeplanning bij typische scènes
      • Voorzorgsmaatregelen
      • FAQ
  • Lixel L-serie

    • Lixel L2 Pro

      • Productoverzicht
      • Basisbediening
      • Apparaatactivering en -verbinding
      • Scanworkflow
      • Puntenwolkgegevens met absolute coördinaten opnemen
      • Meetpunt
      • Appendix
      • FAQ
    • Lixel L3

      • Productoverzicht
      • Basisfuncties van het apparaat
      • Apparaatactivering en -verbinding
      • Gegevensopname
      • Absolute coördinaten opnemen
      • Appendix
  • Accessoires

    • Stick Light

      • Installatiegids
      • Basisbediening
      • FAQ
  • Lixel Studio

    • Versie en copyright
    • Installatie en activering
    • Software-interface
    • Bestandsbewerkingen
    • Projectverwerking
    • Gereedschappen
    • 2D-tekenen
    • Toepassingen
    • Instellingen
    • Apparaatverbinding
  • 07-plugin-sdk

    • Unity

      • LCC Unity SDK Introductie
      • Technische functies
      • Vereisten voor de ontwikkelomgeving
      • Snelstartgids voor pc
      • Optimalisatiegids voor projectinstellingen
      • Ontwikkelgids voor Pico 4 Ultra
      • Pc-streaminggids voor Pico 4 Ultra
      • Ontwikkelgids voor Quest 3
      • Pc-streaminggids voor Quest 3
      • Ontwikkelgids voor OpenXR
      • Business Streaming-gids voor Pico 4 Ultra
      • Woordenlijst
      • Veelgestelde vragen
      • Contact opnemen
      • Ontwikkelingshandleiding voor functies

        • Ontwikkelgids voor gemengde rendering van meerdere scènes
        • Ontwikkelgids voor het ontvangen van schaduwen
        • Ontwikkelgids voor realtime belichting
        • Ontwikkelgids voor multi-camera rendering
        • Ontwikkelgids voor het renderen van afbeeldingen met hoge resolutie
        • Ontwikkelgids voor compatibiliteit van de gegevensformaten LCC en LCC2
        • Ontwikkelgids voor laadeffecten
        • Ontwikkelgids voor het schakelen tussen Mip-renderingmodi
        • Ontwikkelgids voor rand- en hoeksnapping
        • Ontwikkelgids voor geprojecteerde decal
        • Ontwikkelgids voor video-geprojecteerde decal
        • Ontwikkelgids voor markeren
        • Ontwikkelgids voor realtime knippen
        • Ontwikkelgids voor kleuraanpassing
        • Ontwikkelgids voor het ophalen van scène-Meshgegevens
        • Ontwikkelgids voor de Editor-modus
        • Configuratiegids voor renderprestatieparameters
        • Ontwikkelgids voor het samen verpakken van de applicatie en de gegevens
        • Ontwikkelgids voor het botsingssysteem
        • Gids voor macOS-ontwikkelingsmachtigingsproblemen
        • Ontwikkelgids voor compilatie en verpakking voor iOS-apparaten
      • API-referentie

        • LCCManager
        • Renderer
        • Gegevenstypen
      • Wijzigingslogboek

        • v2.3.0
        • v2.2.10
        • v2.2.0
        • v2.1.19
        • v2.0.14

Ontwikkelgids voor het ophalen van scène-Meshgegevens

Bij het reconstrueren van LCC-gegevens genereert de LCC Unity SDK ook Meshgegevens die voor botsingen worden gebruikt. Naast botsingsdetectie biedt de SDK de mogelijkheid om deze Meshgegevens te extraheren, om te zetten naar Unity Mesh-objecten en te visualiseren, wat handig is voor scenario's zoals exporteren en het bakken van NavMesh.

Hieronder wordt aan de hand van een volledig voorbeeld beschreven hoe je alle Meshgegevens synchroon ophaalt en hoe je Meshgegevens van een opgegeven bereik op aanvraag ophaalt.

Omgevingsopzet

Maak een gloednieuwe scène aan in Unity. Unity maakt standaard Main Camera en Directional Light aan.

Main Camera instellen

Selecteer Main Camera in het Hiërarchie-venster en stel de eigenschappen in het Inspector-venster in zoals hieronder wordt weergegeven.

Stel de eigenschappen van Main Camera in

Stel de eigenschappen van Main Camera in

LCCManager aanmaken

Klik met de rechtermuisknop op een leeg gebied in het Hiërarchie-venster, selecteer Create Empty in het pop-upmenu om een leeg GameObject aan te maken, geef het de naam LCCManager, normaliseer de Transform en voeg het LCCManager-script eraan toe via Component toevoegen.

Maak het LCCManager-GameObject aan en voeg het LCCManager-script toe

Maak het LCCManager-GameObject aan en voeg het LCCManager-script toe

LCCRenderer aanmaken

Klik met de rechtermuisknop op een leeg gebied in het Hiërarchie-venster, selecteer Create Empty om een leeg GameObject aan te maken, geef het de naam LCCRenderer en stel de Transform in op Rotation.x = -90 en Scale.x = -1.

Maak LCCRenderer aan en stel de Transform in

Maak LCCRenderer aan en stel de Transform in (Rotation.x = -90, Scale.x = -1)

Opmerking:

De Transform-instellingen van het LCCRenderer-GameObject (Rotation.x = -90, Scale.x = -1) lijnen het uit met het coördinatensysteem van de LCC-gegevens. Zie "Coördinatensysteem van LCC-gegevens" in LCC Unity SDK Introductie voor meer informatie over de uitlijning van het coördinatensysteem.

Gegevensvereisten

De vereiste voor het van kracht worden van het ophalen van Meshgegevens is dat de scène de bijbehorende botsings-Meshgegevens meedraagt (gegenereerd wanneer LCC Studio deze reconstrueert). Bovendien heeft deze mogelijkheid de volgende beperkingen:

  • Alleen pc / Mac en alleen lokale gegevensbronnen worden ondersteund (HTTP-gegevensbronnen worden niet ondersteund).
  • Kan alleen op de hoofdthread worden aangeroepen.
  • Gegevens in native formaat (PLY / SOG / SPZ / splat / ksplat) dragen geen botsings-Meshgegevens mee; het aanroepen van de gerelateerde methoden retourneert null.

Gegevens die in eerdere versies zijn gereconstrueerd, bevatten mogelijk geen botsingsgegevens; in dat geval retourneert GetMeshes() null.

Alle Meshgegevens synchroon ophalen

Alle Meshgegevens synchroon ophalen betekent dat de geometriegegevens van alle botsings-Mesh-blokken in de scène in één keer worden gelezen, geïmplementeerd via de methode Renderer.GetMeshes().

Maak een nieuw C#-script aan met de naam Meshes.cs met de volgende code:

using System.Collections.Generic;
using LCCCore;
using UnityEngine;
using UnityEngine.Rendering;

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

    private const string kContainerName = "LCCVisualizedMeshes";

    void Start()
    {
        m_camera = Camera.main;
        m_isLoaded = false;
        m_manager.SetPlatformType(PlatformType.PC);

        m_renderer = m_manager.GetRender(this.transform);
        m_renderer.Load(m_FilePath,
            p => Debug.Log($"[Meshes] laadvoortgang: {p:P1}"),
            () =>
            {
                Debug.Log($"[Meshes] bestand geladen: {m_FilePath}");
                m_isLoaded = true;
                m_manager.SetAutoFov(false);
            },
            e => Debug.LogError($"[Meshes] laadfout van het bestand: {e}")
        );
    }

    public void onGetAllMeshes()
    {
        if (!m_isLoaded || m_renderer == null)
        {
            Debug.LogWarning("[Meshes] Gegevens zijn nog niet geladen; kan Meshes niet ophalen.");
            return;
        }

        var meshes = m_renderer.GetMeshes();
        if (meshes == null || meshes.Count == 0)
        {
            Debug.LogWarning("[Meshes] Geen Meshes verkregen (de gegevens bevatten mogelijk geen colliders).");
            return;
        }

        VisualizeMeshes(meshes);
    }

    private void VisualizeMeshes(List<LCCMeshBlock> meshes)
    {
        // Ruim het vorige visualisatieresultaat op om ophoping te voorkomen
        Transform root = m_renderer.Transform;
        Transform old = root.Find(kContainerName);
        if (old != null) Destroy(old.gameObject);

        var container = new GameObject(kContainerName).transform;
        container.SetParent(root, false);

        Material material = CreateVisualMaterial();

        for (int i = 0; i < meshes.Count; i++)
        {
            LCCMeshBlock block = meshes[i];
            if (block.vertices == null || block.vertices.Length == 0) continue;
            if (block.triangles == null || block.triangles.Length < 3) continue;

            var go = new GameObject(string.IsNullOrEmpty(block.id) ? $"MeshBlock_{i}" : block.id);
            go.transform.SetParent(container, false);

            var mesh = new Mesh { name = go.name };
            // Het aantal hoekpunten van één blok kan 65535 overschrijden, dus er moeten 32-bits indices worden gebruikt, anders wordt de geometrie beschadigd
            mesh.indexFormat = IndexFormat.UInt32;
            mesh.vertices = block.vertices;
            mesh.triangles = block.triangles;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            var mf = go.AddComponent<MeshFilter>();
            mf.sharedMesh = mesh;

            var mr = go.AddComponent<MeshRenderer>();
            mr.sharedMaterial = material;
        }

        Debug.Log($"[Meshes] GameObjects aangemaakt en {meshes.Count} Mesh-blokken gevisualiseerd.");
    }

    private Material CreateVisualMaterial()
    {
        Shader shader = Shader.Find("Universal Render Pipeline/Lit")
            ?? Shader.Find("Standard")
            ?? Shader.Find("Diffuse");
        if (shader == null) return null;

        var mat = new Material(shader) { color = new Color(0.7f, 0.7f, 0.7f, 1f) };
        // De winding-volgorde van botsingsmesh-driehoeken is niet gegarandeerd consistent; schakel back-face culling uit voor volledige weergave
        mat.SetFloat("_Cull", (float)CullMode.Off);
        return mat;
    }
}

Opmerking:

  • GetMeshes() is een synchrone zware bewerking: het leest synchroon van schijf, parseert en wijst geheugen toe. In grote scènes, bijvoorbeeld een dataset van 262 blokken, kan het een grote hoeveelheid schijfgegevens moeten lezen en enkele GB tot tientallen GB aan beheerd geheugen toewijzen. Roep het één keer aan en cache het resultaat zelf; roep het nooit elke frame aan.
  • vertices / boundsLocal bevinden zich in het object-lokale coördinatensysteem, dus door het visualisatie-GameObject onder Renderer.Transform te plaatsen, wordt het automatisch uitgelijnd.
  • Het aantal hoekpunten van één blok kan 65535 overschrijden (gemeten maximum 390.656); voordat je je eigen Mesh opbouwt, moet je mesh.indexFormat = IndexFormat.UInt32 instellen, anders wordt de geometrie beschadigd.
  • De winding-volgorde van botsingsmesh-driehoeken is niet gegarandeerd consistent; het voorbeeld schakelt back-face culling (_Cull = Off) uit voor volledige weergave.

Voeg het script toe aan het LCCRenderer-GameObject en sleep in de Inspector het LCCManager-GameObject naar de eigenschap Manager en vul het File Path in.

Maak vervolgens een Button en koppel de methode onGetAllMeshes() aan de gebeurtenis onClick ervan.

Klik na het uitvoeren op de Button om alle botsings-Meshes in de scène te zien.

Alle Meshgegevens synchroon ophalen en visualiseren

Visualiseer alle botsings-Meshgegevens nadat je op de knop hebt geklikt

Meshgegevens op aanvraag ophalen

Ophalen op aanvraag betekent dat alleen het opgegeven deel van de Meshgegevens wordt gelezen in plaats van alle Meshgegevens in één keer, om grote I/O- en geheugenoverhead te vermijden. Hieronder wordt het lezen van de Mesh-blokken binnen een bepaald bereik rond de camera als voorbeeld gebruikt.

Gebruik eerst GetMeshBlockInfos() om de metadata van alle blokken op te halen (inclusief begrenzingskaders in wereldruimte), bereken de afstand van het centrum van de rendercamera tot het BBOX-oppervlak van het blok in wereldcoördinaten, filter de blok-ids met een afstand kleiner dan 100 m eruit en gebruik vervolgens de geparameteriseerde GetMeshes(ids) om alleen die blokken te lezen.

Voeg de volgende methoden toe aan Meshes.cs:

public void onRequireMeshes()
{
    if (!m_isLoaded || m_renderer == null)
    {
        Debug.LogWarning("[Meshes] Gegevens zijn nog niet geladen; kan Meshes niet ophalen.");
        return;
    }

    // 1. Zero-I/O-lezing van alle blokmetadata, blokken binnen 100 m filteren op basis van de afstand van camera tot BBOX-oppervlak
    var infos = m_renderer.GetMeshBlockInfos();
    if (infos == null || infos.Count == 0)
    {
        Debug.LogWarning("[Meshes] Geen Mesh-info verkregen (de gegevens bevatten mogelijk geen colliders).");
        return;
    }

    Vector3 camPos = m_camera.transform.position;
    var ids = new List<string>();
    foreach (var info in infos)
    {
        // Wanneer de camera zich binnen de BBOX bevindt, retourneert ClosestPoint de camera zelf en is de afstand 0, dus wordt deze ook geselecteerd
        if (calculateMinDistanceToAABB(info.boundsWorld, camPos) < 100f)
            ids.Add(info.id);
    }

    if (ids.Count == 0)
    {
        Debug.LogWarning("[Meshes] Geen Mesh-blokken binnen 100 m van de camera.");
        return;
    }

    // 2. Lees alleen de gefilterde blokken op id en visualiseer ze
    var meshes = m_renderer.GetMeshes(ids);
    if (meshes == null || meshes.Count == 0)
    {
        Debug.LogWarning("[Meshes] Ophalen van Meshes op id mislukt.");
        return;
    }

    VisualizeMeshes(meshes);
    Debug.Log($"[Meshes] {ids.Count} blokken binnen 100 m van de camera geselecteerd, {meshes.Count} gevisualiseerd.");
}

// Bereken de kortste afstand van een punt tot het AABB-oppervlak (retourneert 0 wanneer het punt zich binnen de AABB bevindt)
private static float calculateMinDistanceToAABB(Bounds _aabb, Vector3 _point)
{
    Vector3 p = _aabb.ClosestPoint(_point);
    return Vector3.Distance(p, _point);
}

Opmerking:

  • GetMeshBlockInfos() is een zero-I/O-, zero-parsingbewerking die alleen de metadata leest die al in het geheugen staat; je kunt het vrij aanroepen.
  • Het afstandsfilter gebruikt boundsWorld (begrenzingskader in wereldruimte) en het cameracentrum neemt Camera.transform.position.
  • Gebruik Bounds.ClosestPoint om de kortste afstand van een punt tot het AABB-oppervlak te berekenen: wanneer de camera zich binnen de BBOX bevindt, retourneert ClosestPoint de camera zelf en is de afstand 0, zodat dat blok ook wordt geselecteerd.
  • De filterstraal 100f (eenheid: meter) in het voorbeeld kan naar behoefte worden aangepast.

Maak een Button en koppel onRequireMeshes() aan de gebeurtenis onClick ervan.

Klik na het uitvoeren op de knop om de Mesh-blokken binnen 100 m van de camera te zien.

Meshgegevens binnen 100 m van de camera op aanvraag ophalen en visualiseren

Meshgegevens binnen 100 m van de camera op aanvraag ophalen

Belangrijkste stappen

De belangrijkste stappen voor het ophalen en visualiseren van scène-Meshgegevens:

  1. Voltooi de pre-configuratie zoals SetPlatformType en laad de LCC-scène via GetRender + Load.
  2. Controleer of de gegevens botsings-Meshgegevens meedragen (native formaten of in eerdere versies gereconstrueerde gegevens mogelijk niet).
  3. Volledige ophaling: roep GetMeshes() aan om alle blokken in één keer te lezen en cache het resultaat zelf om herhaalde aanroepen te voorkomen.
  4. Ophaling op aanvraag: gebruik eerst GetMeshBlockInfos() om de wereldbegrenzingskaders van blokken op te halen, filter ids op camera-afstand en gebruik vervolgens GetMeshes(ids) om alleen de doelblokken te lezen.
  5. Plaats bij het visualiseren het GameObject onder Renderer.Transform om het uit te lijnen met lokale coördinaten en bouw de Mesh met IndexFormat.UInt32.

Mesh-ophaal-API's

De volgende methoden bevinden zich allemaal op Renderer; ze moeten worden aangeroepen nadat de scène is geladen en de gegevens moeten botsings-Meshgegevens meedragen.

GetMeshBlockInfos

// Retourwaarde: List<LCCMeshBlockInfo> → metadata van botsings-Mesh-blokken; null wanneer er geen Mesh is of niet beschikbaar
public List<LCCMeshBlockInfo> GetMeshBlockInfos()

Retourneert de metadata van alle botsings-Mesh-blokken (id, begrenzingskader in wereld/lokaal, aantal hoekpunten, aantal vlakken). Zero-I/O en zero-parsing; leest alleen de metadata die al in het geheugen staat.

Gebruiksvoorbeeld:

var infos = renderer.GetMeshBlockInfos();
foreach (var info in infos)
{
    Debug.Log($"{info.id}: verts={info.vertexCount}, faces={info.faceCount}, bbox={info.boundsWorld.size}");
}

Opmerkingen:

  • Alleen pc / Mac + lokale gegevensbron; alleen hoofdthread.
  • Typisch gebruik: gebruik het eerst om de wereld-BBox van elk blok op te halen, kies de benodigde ids en roep vervolgens GetMeshes(ids) aan om alleen die blokken te lezen.
  • Native formaten (PLY / SOG / SPZ / splat / ksplat) hebben geen Mesh en retourneren null (wat normaal is en niet wordt gelogd).

GetMeshes

// Retourwaarde: List<LCCMeshBlock> → alle geometriegegevens van botsings-Meshes; null wanneer niet beschikbaar
public List<LCCMeshBlock> GetMeshes()

Retourneert synchroon de geometriegegevens van alle botsings-Mesh-blokken (hoekpunten + driehoeksindices, in het lokale coördinatensysteem). Dit is een zware bewerking (synchrone schijflezing + parsen + allocatie); roep het één keer aan en cache het zelf, nooit elke frame.

Gebruiksvoorbeeld:

var meshes = renderer.GetMeshes();
foreach (var block in meshes)
{
    // block.vertices / block.triangles bevinden zich in het object-lokale coördinatensysteem
}

Opmerkingen:

  • Alleen pc / Mac + lokale gegevensbron; alleen hoofdthread.
  • Gebruik voor grote scènes GetMeshBlockInfos() om ids te kiezen + GetMeshes(ids) in plaats daarvan, om te voorkomen dat er in één keer een enorme hoeveelheid beheerd geheugen wordt toegewezen.
  • Het aantal hoekpunten van één blok kan 65535 overschrijden; voordat je je eigen Mesh opbouwt, moet je mesh.indexFormat = IndexFormat.UInt32 instellen.

GetMeshes (op id)

// Retourwaarde: List<LCCMeshBlock> → geometriegegevens van botsings-Meshes voor de opgegeven ids; null wanneer geen treffers
public List<LCCMeshBlock> GetMeshes(IEnumerable<string> _ids)

Retourneert synchroon de geometriegegevens van de botsings-Mesh-blokken met de opgegeven ids (lokaal coördinatensysteem). De ids worden geleverd door GetMeshBlockInfos().

ParameterTypeBeschrijving
_idsIEnumerable<string>De verzameling doelblok-ids (geleverd door GetMeshBlockInfos())

Gebruiksvoorbeeld:

var ids = new List<string> { "block-0", "block-3" };
var meshes = renderer.GetMeshes(ids);

Opmerkingen:

  • Onbekende ids worden overgeslagen met een waarschuwing; dubbele ids worden gededupliceerd (niet herhaaldelijk van schijf gelezen); de retourvolgorde is de doorloopvolgorde van de ids (na deduplicatie).
  • Het doorgeven van null, lege invoer of geen treffers retourneert null met een waarschuwing.
  • Andere beperkingen zijn hetzelfde als bij GetMeshes().

Gegevensstructuur LCCMeshBlockInfo

public struct LCCMeshBlockInfo {
    public string id;           // knoop-id, overeenkomend met LCCMeshBlock.id
    public Bounds boundsWorld;  // wereldruimte-AABB, gebruikt om ids te selecteren
    public Bounds boundsLocal;  // lokale-ruimte-AABB
    public int vertexCount;     // aantal hoekpunten
    public int faceCount;       // aantal vlakken
}
VeldTypeBeschrijving
idstringKnoop-id, overeenkomend met LCCMeshBlock.id
boundsWorldBoundsWereldruimte-AABB, gebruikt om ids te selecteren
boundsLocalBoundsLokale-ruimte-AABB
vertexCountintAantal hoekpunten
faceCountintAantal vlakken

Gegevensstructuur LCCMeshBlock

public struct LCCMeshBlock {
    public string id;           // knoop-id
    public Vector3[] vertices;  // hoekpunten, lokaal coördinatensysteem
    public int[] triangles;     // driehoeksindices, 3 per driehoek
    public Bounds boundsLocal;  // begrenzingen in dezelfde ruimte als de hoekpunten
}
VeldTypeBeschrijving
idstringKnoop-id
verticesVector3[]Hoekpuntarray, object-lokaal coördinatensysteem
trianglesint[]Driehoeksindices, 3 per driehoek
boundsLocalBoundsBegrenzingen in dezelfde ruimte als de hoekpunten

Opmerking:

vertices / boundsLocal bevinden zich beide in het object-lokale coördinatensysteem. Om ze in Unity te visualiseren, plaats je het GameObject dat de Mesh bevat onder Renderer.Transform om automatisch uit te lijnen. Het aantal hoekpunten van één blok kan 65535 overschrijden; voordat je je eigen Mesh opbouwt, moet je mesh.indexFormat = IndexFormat.UInt32 instellen.