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

    • PortalCam P1

      • Panoramica del prodotto
      • Operazioni di base
      • Uso della LCC Scan App
      • Manutenzione e cura
      • FAQ
  • Serie Lixel K

    • Lixel K1

      • Panoramica del prodotto
      • Operazioni di base
      • Attivazione e connessione del dispositivo
      • Flusso di scansione
      • Ottenere una nuvola di punti con coordinate assolute
      • Fusione delle mappe
      • Consigli di pianificazione dei percorsi per scene tipiche
      • Precauzioni
      • FAQ
    • Lixel K2

      • Panoramica del prodotto
      • Operazioni di base
      • Attivazione e connessione
      • Flusso di scansione
      • Acquisire una nuvola di punti con coordinate assolute
      • Fusione mappe
      • Consigli di pianificazione dei percorsi per scene tipiche
      • Precauzioni
      • FAQ
  • Serie Lixel L

    • Lixel L2 Pro

      • Panoramica del prodotto
      • Operazioni di base
      • Attivazione e connessione del dispositivo
      • Flusso di scansione
      • Ottenere una nuvola di punti con coordinate assolute
      • Punto di misura
      • Appendice
      • FAQ
    • Lixel L3

      • Panoramica del prodotto
      • Operazioni di base
      • Attivazione e connessione del dispositivo
      • Acquisizione dei dati
      • Acquisizione di coordinate assolute
      • Appendice
  • Accessori

    • Stick Light

      • Guida all'installazione
      • Operazioni di base
      • Domande frequenti
  • Lixel Studio

    • Versione e copyright
    • Installazione e attivazione
    • Interfaccia del software
    • Operazioni sui file
    • Elaborazione del progetto
    • Strumenti
    • Disegno 2D
    • Applicazioni di settore
    • Impostazioni
    • Connessione del dispositivo
    • Domande Frequenti
  • Lixel CyberColor

    • LCC Studio

      • Introduzione
      • Versione e aggiornamenti
      • Download e installazione
      • Panoramica dell'interfaccia e navigazione
      • Operazioni preliminari alla ricostruzione
      • Prima della ricostruzione
      • Ricostruzione del modello
      • Ricostruzione modello singolo
      • Fusione delle mappe
      • Fusione aria-terra
      • Ricostruzione aerea
      • I miei modelli
      • Altre funzioni
      • Impostazioni e account
      • Convertitore
      • Ricostruzione video
      • Domande Frequenti / FAQ
    • LCC Scene Editor

      • Versione e aggiornamenti
      • Account e accesso
      • Panoramica del prodotto e home page
      • Interfaccia dell'editor
      • Modalità di navigazione
      • File
      • Impostazioni
      • Modifica
      • Finestra
      • Barra degli strumenti globale
      • Asset e proprietà
      • Barra degli strumenti sinistra
      • Punti di vista
      • Portale
      • Skybox
      • Annotazioni
      • Misurazione
      • Flythrough
      • Rapporto scena
      • 3D Layout
      • Mini-mappa
      • Modalità Anteprima (Viewer)
      • Aiuto
      • Domande frequenti (FAQ)
      • Punto di spawn
    • LCC Model Editor

      • Versione e aggiornamenti
      • Guida utente
      • Panoramica e interfaccia
      • Operazioni sui file
      • Selettori
      • Modifica dei modelli
      • Misurazione
      • Correzione colore
      • Gestione degli asset
      • Impostazioni e Aiuto
      • Domande frequenti
    • Capture Guide

      • Panoramica
      • Panoramica dei dispositivi di acquisizione
      • Principi generali di acquisizione
      • Acquisizione di scene interne
      • Acquisizione di scene esterne
      • Acquisizione su larga scala (map fusion)
      • Acquisizione per aerial-ground map fusion
      • Acquisizione di oggetti
      • Acquisizione di persone
      • Acquisizione per ricostruzione da video
      • HD Enhancement
      • Control points (Lixel P1)
      • FAQ e risoluzione dei problemi
    • Buone Pratiche

      • Unione di più modelli 3DGS di grandi dimensioni
    • Cronologia versioni
  • Plugin e SDK

    • Unreal

      • Introduzione
      • Avvio rapido - Windows
      • Avvio rapido - Linux
      • Avvio rapido - Quest3
      • Edizioni e licenze
      • Rendering
      • Rasterizzazione Tiled (sperimentale)
      • Impostazioni visive
      • Normali e illuminazione
      • Modifica della scena
      • Parametri di prestazione
      • Guida alle prestazioni
      • Integrazione con plugin di terze parti e del motore
      • Proxy Mesh
      • Animazione di caricamento
      • Collisioni
      • Supporto del Navigation System
      • Supporto di Single Layer Water
      • Localizzazione
      • FAQ
      • Risoluzione dei problemi
      • Log e diagnostica
      • Contattaci
      • Buone pratiche

        • Rilluminare il 3DGS con una mesh di LixelStudio
      • Riferimento API

        • ALCCActorBase
        • ULCCComponentBase
        • ULCCComponent
        • ULCC2Component
        • Actor SOG / SPZ / PLY
        • ALCC2ProxyMesh
        • ALCCClippingVolume
        • ALCCSectionPlane
        • ALCCLoadVolume
        • ULCCUtilLibrary
        • Enum
        • Struct
      • Registro delle modifiche

        • 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

      • Introduzione all'Unity SDK
      • Caratteristiche tecniche
      • Requisiti dell'ambiente di sviluppo
      • Guida rapida per PC
      • Guida all'ottimizzazione delle impostazioni di progetto
      • Guida allo sviluppo per Pico 4 Ultra
      • Guida allo streaming PC per Pico 4 Ultra
      • Guida allo sviluppo per Quest 3
      • Guida allo streaming PC per Quest 3
      • Guida allo sviluppo OpenXR
      • Guida allo streaming Business per Pico 4 Ultra
      • Glossario
      • FAQ
      • Contattaci
      • Guida allo sviluppo delle funzionalità

        • Guida allo sviluppo del rendering misto multi-scena
        • Guida allo sviluppo della ricezione delle ombre
        • Guida allo sviluppo dell'illuminazione in tempo reale
        • Guida allo sviluppo del rendering multi-camera
        • Guida allo sviluppo del rendering di immagini ad alta risoluzione
        • Guida allo sviluppo della compatibilità dei formati dati LCC e LCC2
        • Guida allo sviluppo dell'effetto di caricamento
        • Guida allo sviluppo del cambio di modalità di rendering Mip
        • Guida allo sviluppo dello snap a bordi e angoli
        • Guida allo sviluppo della decal proiettata
        • Guida allo sviluppo della decal proiettata video
        • Guida allo sviluppo dell'evidenziazione
        • Guida allo sviluppo del ritaglio in tempo reale
        • Guida allo sviluppo della regolazione del tono
        • Guida allo sviluppo dell'ottenimento dei dati Mesh della scena
        • Guida allo sviluppo della modalità Editor
        • Guida alla configurazione dei parametri di prestazioni di rendering
        • Guida allo sviluppo del co-impacchettamento di applicazione e dati
        • Guida allo sviluppo del sistema di collisione
        • Guida ai problemi di autorizzazione nello sviluppo su macOS
        • Guida allo sviluppo di compilazione e packaging per dispositivi iOS
      • Riferimento API

        • LCCManager
        • Renderer
        • Tipi di dati
      • Registro delle modifiche

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

      • Introduzione
      • Guida all'ottimizzazione delle prestazioni di rendering
      • Configurazione grafica
      • Domande frequenti
      • Riferimento 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
      • Registro delle modifiche

        • 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

Guida allo sviluppo dell'ottenimento dei dati Mesh della scena

Quando ricostruisce i dati LCC, l'LCC Unity SDK genera anche dati Mesh usati per le collisioni. Oltre al rilevamento delle collisioni, l'SDK offre la capacità di estrarre questi dati Mesh, convertirli in oggetti Mesh di Unity e visualizzarli, il che è comodo per scenari come l'esportazione e il baking della NavMesh.

Di seguito viene usato un esempio completo per descrivere i passaggi per ottenere in modo sincrono tutti i dati Mesh e per ottenere su richiesta i dati Mesh di un intervallo specificato.

Configurazione dell'ambiente

Crea una scena completamente nuova in Unity. Unity crea Camera principale e Luce direzionale per impostazione predefinita.

Configura la Camera principale

Seleziona Camera principale nella finestra Gerarchia e imposta le sue proprietà nella finestra Inspector come mostrato di seguito.

Imposta le proprietà della Camera principale

Imposta le proprietà della Camera principale

Crea LCCManager

Fai clic con il pulsante destro su un'area vuota nella finestra Gerarchia, seleziona Crea vuoto dal menu a comparsa per creare un GameObject vuoto, assegna il nome LCCManager, normalizza il suo Transform e aggiungi lo script LCCManager tramite Aggiungi componente.

Crea il GameObject LCCManager e aggiungi lo script LCCManager

Crea il GameObject LCCManager e aggiungi lo script LCCManager

Crea LCCRenderer

Fai clic con il pulsante destro su un'area vuota nella finestra Gerarchia, seleziona Crea vuoto per creare un GameObject vuoto, assegna il nome LCCRenderer e imposta il suo Transform su Rotation.x = -90 e Scale.x = -1.

Crea LCCRenderer e imposta il suo Transform

Crea LCCRenderer e imposta il suo Transform (Rotation.x = -90, Scale.x = -1)

Nota:

Le impostazioni Transform del GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) lo allineano al sistema di coordinate dei dati LCC. Per i dettagli sull'allineamento del sistema di coordinate, vedi "Sistema di coordinate dei dati LCC" in Introduzione all'Unity SDK.

Prerequisiti dei dati

Il prerequisito affinché l'ottenimento dei dati Mesh abbia effetto è che la scena contenga i corrispondenti dati Mesh di collisione (generati quando LCC Studio la ricostruisce). Inoltre, questa capacità ha i seguenti vincoli:

  • Solo PC / Mac, e sono supportate solo le origini dati locali (le origini dati HTTP non sono supportate).
  • Può essere chiamata solo sul thread principale.
  • I dati in formato nativo (PLY / SOG / SPZ / splat / ksplat) non contengono dati Mesh di collisione; la chiamata dei metodi correlati restituisce null.

I dati ricostruiti in versioni precedenti potrebbero non contenere dati di collisione, nel qual caso la chiamata di GetMeshes() restituisce null.

Ottieni in modo sincrono tutti i dati Mesh

Ottenere in modo sincrono tutti i dati Mesh significa leggere i dati geometrici di tutti i blocchi Mesh di collisione nella scena in una volta sola, implementato tramite il metodo Renderer.GetMeshes().

Crea un nuovo script C# denominato Meshes.cs con il seguente codice:

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] avanzamento caricamento: {p:P1}"),
            () =>
            {
                Debug.Log($"[Meshes] file caricato: {m_FilePath}");
                m_isLoaded = true;
                m_manager.SetAutoFov(false);
            },
            e => Debug.LogError($"[Meshes] errore di caricamento del file: {e}")
        );
    }

    public void onGetAllMeshes()
    {
        if (!m_isLoaded || m_renderer == null)
        {
            Debug.LogWarning("[Meshes] I dati non hanno terminato il caricamento; impossibile ottenere i Meshes.");
            return;
        }

        var meshes = m_renderer.GetMeshes();
        if (meshes == null || meshes.Count == 0)
        {
            Debug.LogWarning("[Meshes] Nessun Mesh ottenuto (i dati potrebbero non contenere collider).");
            return;
        }

        VisualizeMeshes(meshes);
    }

    private void VisualizeMeshes(List<LCCMeshBlock> meshes)
    {
        // Pulisci il risultato di visualizzazione precedente per evitare accumuli
        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 };
            // Il numero di vertici di un singolo blocco può superare 65535, quindi devono essere usati indici a 32 bit, altrimenti la geometria verrà corrotta
            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] Creati GameObject e visualizzati {meshes.Count} blocchi Mesh.");
    }

    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) };
        // L'ordine di avvolgimento dei triangoli della mesh di collisione non è garantito coerente; disabilita il back-face culling per una visualizzazione completa
        mat.SetFloat("_Cull", (float)CullMode.Off);
        return mat;
    }
}

Nota:

  • GetMeshes() è un'operazione sincrona pesante: legge in modo sincrono dal disco, analizza e alloca memoria. Nelle scene grandi, ad es. un dataset di 262 blocchi, potrebbe dover leggere una grande quantità di dati dal disco e allocare da diversi GB a decine di GB di memoria gestita. Chiamalo una volta e memorizza tu stesso il risultato in cache; non chiamarlo mai a ogni fotogramma.
  • vertices / boundsLocal sono nel sistema di coordinate locale dell'oggetto, quindi associare il GameObject di visualizzazione sotto Renderer.Transform lo allinea automaticamente.
  • Il numero di vertici di un singolo blocco può superare 65535 (massimo misurato 390.656); prima di costruire il tuo Mesh, devi impostare mesh.indexFormat = IndexFormat.UInt32, altrimenti la geometria verrà corrotta.
  • L'ordine di avvolgimento dei triangoli della mesh di collisione non è garantito coerente; l'esempio disabilita il back-face culling (_Cull = Off) per una visualizzazione completa.

Associa lo script al GameObject LCCRenderer e, nell'Inspector, trascina il GameObject LCCManager sulla proprietà Manager e compila il File Path.

Poi crea un Button e associa il metodo onGetAllMeshes() al suo evento onClick.

Dopo l'esecuzione, fai clic sul Button per vedere tutti i Mesh di collisione nella scena.

Ottieni in modo sincrono tutti i dati Mesh e visualizzali

Visualizza tutti i dati Mesh di collisione dopo aver fatto clic sul pulsante

Ottieni i dati Mesh su richiesta

Il recupero su richiesta significa leggere solo la parte specificata dei dati Mesh invece di leggere tutti i dati Mesh in una volta sola, per evitare un grande overhead di I/O e memoria. Di seguito viene usato come esempio la lettura dei blocchi Mesh entro un certo intervallo attorno alla camera.

Prima usa GetMeshBlockInfos() per ottenere i metadati di tutti i blocchi (inclusi i box di delimitazione in spazio mondo), calcola la distanza dal centro della camera di rendering alla superficie del BBOX del blocco in coordinate mondo, filtra gli id dei blocchi con una distanza inferiore a 100 m, e poi usa il parametrizzato GetMeshes(ids) per leggere solo quei blocchi.

Aggiungi i seguenti metodi a Meshes.cs:

public void onRequireMeshes()
{
    if (!m_isLoaded || m_renderer == null)
    {
        Debug.LogWarning("[Meshes] I dati non hanno terminato il caricamento; impossibile ottenere i Meshes.");
        return;
    }

    // 1. Lettura a zero I/O di tutti i metadati dei blocchi, filtrando i blocchi entro 100 m tramite la distanza camera-superficie BBOX
    var infos = m_renderer.GetMeshBlockInfos();
    if (infos == null || infos.Count == 0)
    {
        Debug.LogWarning("[Meshes] Nessuna informazione Mesh ottenuta (i dati potrebbero non contenere collider).");
        return;
    }

    Vector3 camPos = m_camera.transform.position;
    var ids = new List<string>();
    foreach (var info in infos)
    {
        // Quando la camera è dentro il BBOX, ClosestPoint restituisce la camera stessa e la distanza è 0, quindi viene selezionato anche quel blocco
        if (calculateMinDistanceToAABB(info.boundsWorld, camPos) < 100f)
            ids.Add(info.id);
    }

    if (ids.Count == 0)
    {
        Debug.LogWarning("[Meshes] Nessun blocco Mesh entro 100 m dalla camera.");
        return;
    }

    // 2. Leggi solo i blocchi filtrati per id e visualizzali
    var meshes = m_renderer.GetMeshes(ids);
    if (meshes == null || meshes.Count == 0)
    {
        Debug.LogWarning("[Meshes] Impossibile ottenere i Meshes per id.");
        return;
    }

    VisualizeMeshes(meshes);
    Debug.Log($"[Meshes] Selezionati {ids.Count} blocchi entro 100 m dalla camera, visualizzati {meshes.Count}.");
}

// Calcola la distanza più vicina da un punto alla superficie dell'AABB (restituisce 0 quando il punto è dentro l'AABB)
private static float calculateMinDistanceToAABB(Bounds _aabb, Vector3 _point)
{
    Vector3 p = _aabb.ClosestPoint(_point);
    return Vector3.Distance(p, _point);
}

Nota:

  • GetMeshBlockInfos() è un'operazione a zero I/O, zero parsing che legge solo i metadati già in memoria; puoi chiamarla liberamente.
  • Il filtro della distanza usa boundsWorld (box di delimitazione in spazio mondo), e il centro della camera prende Camera.transform.position.
  • Usa Bounds.ClosestPoint per calcolare la distanza più vicina da un punto alla superficie dell'AABB: quando la camera è dentro il BBOX, ClosestPoint restituisce la camera stessa e la distanza è 0, quindi viene selezionato anche quel blocco.
  • Il raggio di filtro 100f (unità: metri) nell'esempio può essere regolato secondo necessità.

Crea un Button e associa onRequireMeshes() al suo evento onClick.

Dopo l'esecuzione, fai clic sul pulsante per vedere i blocchi Mesh entro 100 m dalla camera.

Ottieni su richiesta i dati Mesh entro 100 m dalla camera e visualizzali

Ottieni su richiesta i dati Mesh entro 100 m dalla camera

Punti chiave

I passaggi chiave per ottenere e visualizzare i dati Mesh della scena:

  1. Completa la preconfigurazione come SetPlatformType e carica la scena LCC tramite GetRender + Load.
  2. Conferma che i dati contengano dati Mesh di collisione (i formati nativi o i dati ricostruiti in versioni precedenti potrebbero non contenerli).
  3. Recupero completo: chiama GetMeshes() per leggere tutti i blocchi in una volta sola e memorizza tu stesso il risultato in cache per evitare chiamate ripetute.
  4. Recupero su richiesta: usa prima GetMeshBlockInfos() per ottenere i box di delimitazione mondo dei blocchi, filtra gli id per distanza dalla camera, poi usa GetMeshes(ids) per leggere solo i blocchi di destinazione.
  5. Durante la visualizzazione, associa il GameObject sotto Renderer.Transform per allinearlo alle coordinate locali e costruisci il Mesh con IndexFormat.UInt32.

API per il recupero dei Mesh

I seguenti metodi sono tutti su Renderer; devono essere chiamati dopo che la scena ha terminato il caricamento, e i dati devono contenere dati Mesh di collisione.

GetMeshBlockInfos

// Valore restituito: List<LCCMeshBlockInfo> → metadati dei blocchi Mesh di collisione; null quando non c'è alcun Mesh o non è disponibile
public List<LCCMeshBlockInfo> GetMeshBlockInfos()

Restituisce i metadati di tutti i blocchi Mesh di collisione (id, box di delimitazione mondo/locale, numero di vertici, numero di facce). Zero-I/O e zero-parsing; legge solo i metadati già in memoria.

Esempio di utilizzo:

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

Note:

  • Solo PC / Mac + origine dati locale; solo thread principale.
  • Uso tipico: usalo prima per ottenere il BBox mondo di ogni blocco, seleziona gli id necessari, poi chiama GetMeshes(ids) per leggere solo quei blocchi.
  • I formati nativi (PLY / SOG / SPZ / splat / ksplat) non hanno Mesh e restituiscono null (il che è normale e non viene registrato).

GetMeshes

// Valore restituito: List<LCCMeshBlock> → tutti i dati geometrici dei Mesh di collisione; null quando non disponibili
public List<LCCMeshBlock> GetMeshes()

Restituisce in modo sincrono i dati geometrici di tutti i blocchi Mesh di collisione (vertici + indici dei triangoli, nel sistema di coordinate locale). È un'operazione pesante (lettura sincrona dal disco + parsing + allocazione); chiamala una volta e memorizza tu stesso il risultato in cache, mai a ogni fotogramma.

Esempio di utilizzo:

var meshes = renderer.GetMeshes();
foreach (var block in meshes)
{
    // block.vertices / block.triangles sono nel sistema di coordinate locale dell'oggetto
}

Note:

  • Solo PC / Mac + origine dati locale; solo thread principale.
  • Per scene grandi, usa invece GetMeshBlockInfos() per selezionare gli id + GetMeshes(ids), per evitare di allocare una grande quantità di memoria gestita in una volta sola.
  • Il numero di vertici di un singolo blocco può superare 65535; prima di costruire il tuo Mesh, devi impostare mesh.indexFormat = IndexFormat.UInt32.

GetMeshes (per id)

// Valore restituito: List<LCCMeshBlock> → dati geometrici dei Mesh di collisione per gli id specificati; null quando non ci sono corrispondenze
public List<LCCMeshBlock> GetMeshes(IEnumerable<string> _ids)

Restituisce in modo sincrono i dati geometrici dei blocchi Mesh di collisione con gli id specificati (sistema di coordinate locale). Gli id sono forniti da GetMeshBlockInfos().

ParametroTipoDescrizione
_idsIEnumerable<string>La raccolta degli id dei blocchi di destinazione (fornita da GetMeshBlockInfos())

Esempio di utilizzo:

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

Note:

  • Gli id sconosciuti vengono saltati con un avviso; gli id duplicati vengono deduplicati (non letti dal disco ripetutamente); l'ordine di restituzione è l'ordine di attraversamento degli id (dopo la deduplicazione).
  • Passando null, un input vuoto o nessuna corrispondenza si restituisce null con un avviso.
  • Gli altri vincoli sono gli stessi di GetMeshes().

Struttura dati LCCMeshBlockInfo

public struct LCCMeshBlockInfo {
    public string id;           // id del nodo, corrispondente a LCCMeshBlock.id
    public Bounds boundsWorld;  // AABB in spazio mondo, usata per selezionare gli id
    public Bounds boundsLocal;  // AABB in spazio locale
    public int vertexCount;     // numero di vertici
    public int faceCount;       // numero di facce
}
CampoTipoDescrizione
idstringId del nodo, corrispondente a LCCMeshBlock.id
boundsWorldBoundsAABB in spazio mondo, usata per selezionare gli id
boundsLocalBoundsAABB in spazio locale
vertexCountintNumero di vertici
faceCountintNumero di facce

Struttura dati LCCMeshBlock

public struct LCCMeshBlock {
    public string id;           // id del nodo
    public Vector3[] vertices;  // vertici, sistema di coordinate locale
    public int[] triangles;     // indici dei triangoli, 3 per triangolo
    public Bounds boundsLocal;  // limiti nello stesso spazio dei vertici
}
CampoTipoDescrizione
idstringId del nodo
verticesVector3[]Array di vertici, sistema di coordinate locale dell'oggetto
trianglesint[]Indici dei triangoli, 3 per triangolo
boundsLocalBoundsLimiti nello stesso spazio dei vertici

Nota:

vertices / boundsLocal sono entrambi nel sistema di coordinate locale dell'oggetto. Per visualizzarli in Unity, associa il GameObject che contiene il Mesh sotto Renderer.Transform per allinearli automaticamente. Il numero di vertici di un singolo blocco può superare 65535; prima di costruire il tuo Mesh, devi impostare mesh.indexFormat = IndexFormat.UInt32.