Guida allo sviluppo del ritaglio in tempo reale
L'LCC Unity SDK supporta operazioni di modifica come l'evidenziazione e il ritaglio sulle scene 3DGS. Questa guida illustra le operazioni di ritaglio in tempo reale: selezionare un'area tramite texture proiettate 2D, geometria 3D o un mix di entrambe, ritagliando l'area selezionata fuori dalla scena, supportando la selezione normale e l'inversione della selezione.
Nota:
L'attuale funzionalità di ritaglio è solo un effetto di visualizzazione in fase di esecuzione; non modifica in alcun modo il file dati originale e non supporta il salvataggio o l'esportazione del risultato della modifica. Se devi regolare il colore, ritagliare e salvare i dati, usa lo strumento software XGRIDS LCC Editor.
Se non vuoi modificare i dati, puoi anche registrare le operazioni e riprodurle dopo che i dati avranno terminato il caricamento la volta successiva.
Prerequisiti
Il ritaglio di una scena tramite l'SDK richiede le seguenti condizioni:
- Entra nello stato di modifica prima di caricare i dati. L'SDK è nello stato di navigazione (View) per impostazione predefinita, che offre le migliori prestazioni ed è consigliato per la navigazione normale. Per eseguire operazioni di modifica come il ritaglio, passa allo stato di modifica tramite
SetEditorMode(true)prima di chiamareLoad. Questo metodo ha effetto solo se chiamato prima del caricamento di tutti i dati. - Esegui l'operazione di ritaglio dopo che i dati hanno terminato il caricamento. L'interfaccia di ritaglio deve essere chiamata dopo che i dati della scena sono stati completamente caricati.
Passaggio 1: configura la scena
Prepara i GameObject necessari per il ritaglio nella scena come mostrato di seguito.

Struttura della gerarchia della scena per l'esempio di ritaglio
- Camera principale: la camera della scena; il ritaglio 2D usa le sue matrici di vista e proiezione.
- LCCManager: un GameObject vuoto con un Transform normalizzato, con lo script
LCCManageraggiunto. - LCCRenderer: un GameObject vuoto con Transform impostato su Rotation.x = -90, Scale.x = -1 (allineato al sistema di coordinate dei dati LCC), usato per associare lo script
Clipscritto in seguito. - Geometria di selezione 3D: oggetti ausiliari per il ritaglio 3D. L'esempio prepara 3 Cubi (
Box1,Box2,Box3) e 1 Sfera (Clipsphere); spostando e ridimensionando questi oggetti si controllano la posizione e la dimensione della selezione di ritaglio.
Nota:
Per le impostazioni relative alla camera di rendering e ai GameObject LCCManager e LCCRenderer, consulta le sezioni pertinenti della Guida rapida per PC e della Guida all'ottimizzazione delle impostazioni di progetto.

Geometria di selezione usata per il ritaglio 3D (Box1 / Box2 / Box3 / Clipsphere)
Passaggio 2: comprendi le strutture dati
Il ritaglio coinvolge tre metodi operativi — 2D, 3D e misto 2D/3D. Gli enum e le struct usati sono i seguenti.
public enum SelectMode { normal, invert, clip } // selezione normale, inversione, ritaglio in tempo reale
public enum OperationMode { normal, erase } // selezione normale, cancellazione della selezione
public enum ShapeType { box, sphere } // selezione Box 3D, selezione Sfera 3D
public enum EditType { Edit2D, Edit3D } // modifica 2D, modifica 3D
// Selezione tramite texture 2D
public struct Data2D
{
public Texture2D texture; // texture maschera 2D
public Matrix4x4 mv; // matrice di vista della camera
public Matrix4x4 mvp; // matrice di vista-proiezione della camera
public SelectMode mode; // modalità di selezione
}
// Selezione tramite geometria 3D
public struct Data3D
{
public ShapeType type; // tipo di geometria (box / sphere)
public Matrix4x4 invMat; // matrice world-to-local (inversa) della geometria
public OperationMode operation; // tipo di operazione (unione normale / differenza di cancellazione)
public SelectMode mode; // modalità di selezione
}
// Selezione mista 2D / 3D
public struct DataMix
{
public EditType editType; // tipo di modifica (obbligatorio; determina se vengono usati i campi 2D o 3D)
public Texture2D texture; // texture maschera 2D (usata da Edit2D)
public Matrix4x4 mv; // matrice di vista della camera (usata da Edit2D)
public Matrix4x4 mvp; // matrice di vista-proiezione della camera (usata da Edit2D)
public ShapeType type; // tipo di geometria (usato da Edit3D)
public Matrix4x4 invMat; // matrice inversa della geometria (usata da Edit3D)
public OperationMode operation; // tipo di operazione (usato da Edit3D)
public SelectMode mode; // modalità di selezione (obbligatorio)
}
Ci sono tre punti da notare sull'elenco di selezione:
- L'elenco è ordinato. Sia in 2D che in 3D, le voci dell'elenco hanno effetto in ordine; assicurati che l'ordine di aggiunta corrisponda alle tue aspettative.
- L'inversione è un comando operativo e non deve essere associata a dati di selezione specifici. Aggiungi semplicemente una voce con
mode = SelectMode.invertper invertire l'area attualmente selezionata. - Il numero massimo di voci in un singolo elenco è 255. Superarlo restituisce un codice di errore.
Passaggio 3: comprendi le API di ritaglio
Tutte le interfacce relative al ritaglio sono fornite da LCCManager, inclusi tre overload di SetClip e un metodo di uscita.
SetClip (ritaglio tramite texture 2D)
// Valore restituito: int
// 0: operazione riuscita
// 1: l'elenco è null o ha 0 elementi
// 2: gli elementi dell'elenco superano il massimo di 255
public int SetClip(List<Data2D> _2Ds)
Ritaglia la scena usando una texture maschera proiettata 2D; l'area contrassegnata viene ritagliata fuori dalla scena.
SetClip (ritaglio tramite geometria 3D)
// Valore restituito: int
// 0: operazione riuscita
// 1: l'elenco è null o ha 0 elementi
// 2: gli elementi dell'elenco superano il massimo di 255
// 3: il numero di box della geometria di selezione è 0
public int SetClip(List<Data3D> _3Ds)
Definisce l'area di ritaglio usando la geometria 3D (cuboide, cubo, sfera), supportando combinazioni di unione e differenza. È richiesta almeno una geometria con operation == OperationMode.normal.
SetClip (ritaglio in modalità mista)
// Valore restituito: int
// 0: operazione riuscita
// 1: l'elenco è null o ha 0 elementi
// 2: gli elementi dell'elenco superano il massimo di 255
public int SetClip(List<DataMix> _Mix)
Definisce l'area di ritaglio usando texture 2D e geometria 3D contemporaneamente; ogni voce determina se viene elaborata come 2D o 3D tramite editType.
QuitClipMode
// Valore restituito: void
public void QuitClipMode()
Esce dalla modalità di ritaglio e ripristina la visualizzazione completa della scena.
Suggerimento:
I tre overload di
SetClipsi escludono a vicenda. Quando cambi metodo di ritaglio o cancelli il ritaglio corrente, chiama primaQuitClipMode()e poi imposta il nuovo ritaglio.
Passaggio 4: specifica della texture maschera 2D
Il ritaglio 2D descrive la selezione tramite una texture maschera, supportando vari metodi di selezione come quadrilateri, triangoli, pennelli e lazo — basta contrassegnare i pixel corrispondenti nella texture con il valore di ritaglio. Quando usi operazioni 2D, la camera dovrebbe essere bloccata e la texture contrassegnata da un punto di vista fisso. La texture e i valori dei pixel hanno le seguenti convenzioni:
- La texture è fissa a 1024 × 1024,
R8canale singolo, senza Mipmap, filtro punto (FilterMode.Point) e campionamento bloccato (TextureWrapMode.Clamp). - Convenzioni dei valori dei pixel:
| Valore pixel | Significato |
|---|---|
128 | Predefinito (mantieni) |
240 | Selezionato |
180 | Deseleziona (cancella l'area già selezionata) |
0 | Ritaglio |
In uno scenario di ritaglio, di solito vengono usati solo i due valori 128 (mantieni predefinito) e 0 (ritaglio).
Passaggio 5: scrivi lo script
Crea un nuovo script C# denominato Clip.cs. Completa prima lo scheletro di base: in Start, entra nello stato di modifica e carica i dati; dopo il completamento del caricamento, imposta il flag di caricamento per i successivi metodi di ritaglio da verificare.
using LCCCore;
using System.Collections.Generic;
using UnityEngine;
public class Clip : MonoBehaviour
{
public LCCManager m_manager;
public string m_FilePath;
public GameObject m_Box1;
public GameObject m_Box2;
public GameObject m_Box3;
public GameObject m_Clipsphere;
private LCCCore.Renderer m_renderer;
private Camera m_camera;
private bool m_isLoaded = false;
void Start()
{
m_camera = Camera.main;
m_manager.SetPlatformType(PlatformType.PC);
// Entra in modalità di modifica; deve essere chiamato prima di Load
m_manager.SetEditorMode(true);
m_renderer = m_manager.GetRender(this.transform);
if (m_renderer == null)
Debug.LogError("GetRender non riuscito, verifica che il manager sia impostato correttamente e che il percorso del file sia valido.");
m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
}
private void onLoadProgress(float value)
{
Debug.Log($"avanzamento caricamento: {value}");
}
private void onLoadCallback()
{
Debug.Log("dati caricati !!!");
m_isLoaded = true;
// Disabilita il rendering dell'ambiente (nuvola di punti di campo lontano a bassa precisione) per osservare meglio il risultato del ritaglio
m_renderer.SetEnvironment(false);
}
// metodi di ritaglio 2D / 3D / misto di seguito
}
Nota:
SetEditorMode(true)deve essere chiamato prima diLoadper avere effetto; eSetClipdeve essere chiamato dopo che i dati hanno terminato il caricamento (dopo che il callbackonLoadCallbackviene attivato).SetEnvironment(false)disabilita la nuvola di punti dell'ambiente di campo lontano per rendere più chiaro il risultato del ritaglio; decidi se chiamarlo secondo necessità.
Passaggio 6: associa lo script e imposta le proprietà
- Associa lo script
Clip.csal GameObject LCCRenderer. - Nella finestra Inspector, trascina il GameObject LCCManager sulla proprietà Manager dello script.
- Inserisci il percorso del file LCC nella proprietà File Path.
- Trascina
Box1,Box2,Box3eClipspheredella scena rispettivamente sulle proprietà corrispondenti dello script.

Imposta le proprietà dello script Clip nell'Inspector
Passaggio 7: esempi di operazioni di ritaglio
Aggiungi i metodi seguenti alla classe Clip e chiama il metodo corrispondente dopo l'esecuzione e dopo che i dati hanno terminato il caricamento.
Ritaglio tramite texture 2D
Costruisci due texture maschera R8, contrassegna i pixel da ritagliare come 0 e il resto dell'area da mantenere come 128, poi costruisci Data2D con le matrici della camera e aggiungile all'elenco.
public void on2DClip()
{
// La dimensione della texture è fissa a 1024*1024; mantieni le altre proprietà uguali all'esempio
Texture2D _texture = new Texture2D(1024, 1024, TextureFormat.R8, false);
_texture.filterMode = FilterMode.Point;
_texture.wrapMode = TextureWrapMode.Clamp;
int _count = 1024 * 1024;
int _half = _count / 2;
byte[] _values = new byte[_count];
for (int i = 0; i < _count; i++)
{
if (i < _half)
_values[i] = 0; // 0 significa ritaglio, 128 significa predefinito, 240 significa selezionato
else
_values[i] = 128;
}
_texture.SetPixelData(_values, 0);
Texture2D _texture2 = new Texture2D(1024, 1024, TextureFormat.R8, false);
_texture2.filterMode = FilterMode.Point;
_texture2.wrapMode = TextureWrapMode.Clamp;
byte[] _values2 = new byte[_count];
for (int i = 0; i < _count; i++)
{
if (i > _count * 0.75 && i < _count * 0.9)
_values2[i] = 0;
else
_values2[i] = 128;
}
_texture2.SetPixelData(_values2, 0);
List<Data2D> _2Ds = new List<Data2D>();
Data2D _2d01 = new Data2D();
_2d01.mv = m_camera.worldToCameraMatrix;
_2d01.texture = _texture;
_2d01.mode = SelectMode.normal;
_2d01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_2Ds.Add(_2d01);
Data2D _2d02 = new Data2D();
_2d02.mv = m_camera.worldToCameraMatrix;
_2d02.texture = _texture2;
_2d02.mode = SelectMode.normal;
_2d02.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_2Ds.Add(_2d02);
m_manager.SetClip(_2Ds);
}
Spiegazione del codice: vengono costruite due texture maschera. La prima maschera ritaglia la metà inferiore dello schermo (l'origine dello schermo è l'angolo inferiore sinistro) e la seconda maschera ritaglia la regione da 0.75 a 0.9 della metà superiore dello schermo. L'effetto dell'esempio è il seguente.
Nell'uso reale, puoi usare vari strumenti di selezione come rettangoli, triangoli, pennelli e lazo per selezionare le posizioni corrispondenti sulla maschera.

Effetto del ritaglio tramite texture 2D
Ritaglio tramite geometria 3D
Usa la worldToLocalMatrix della geometria come matrice inversa della selezione, combina unione (normal) e differenza (erase) tramite operation e implementa l'inversione della selezione tramite una voce con mode = SelectMode.invert.
public void on3DClip()
{
List<Data3D> _3Ds = new List<Data3D>();
var _mat1 = m_Box1.transform.worldToLocalMatrix;
var _mat2 = m_Box2.transform.worldToLocalMatrix;
var _mat3 = m_Box3.transform.worldToLocalMatrix;
var _mat4 = m_Clipsphere.transform.worldToLocalMatrix;
// Selezione Box
Data3D _3d01 = new Data3D();
_3d01.type = ShapeType.box;
_3d01.operation = OperationMode.normal;
_3d01.mode = SelectMode.normal;
_3d01.invMat = _mat1;
_3Ds.Add(_3d01);
Data3D _3d02 = new Data3D();
_3d02.type = ShapeType.box;
_3d02.operation = OperationMode.normal;
_3d02.mode = SelectMode.normal;
_3d02.invMat = _mat2;
_3Ds.Add(_3d02);
// Selezione Sfera
Data3D _3d04 = new Data3D();
_3d04.type = ShapeType.sphere;
_3d04.operation = OperationMode.normal;
_3d04.mode = SelectMode.normal;
_3d04.invMat = _mat4;
_3Ds.Add(_3d04);
// Cancella Box/Sfera (differenza)
Data3D _3d03 = new Data3D();
_3d03.type = ShapeType.box;
_3d03.operation = OperationMode.erase;
_3d03.mode = SelectMode.normal;
_3d03.invMat = _mat3;
_3Ds.Add(_3d03);
// Inversione
//Data3D _3d05 = new Data3D();
//_3d05.mode = SelectMode.invert;
//_3Ds.Add(_3d05);
m_manager.SetClip(_3Ds);
}
Spiegazione del codice: vengono usate 4 geometrie, dove Box1, Box2 e Sfera sono selezioni normali, e Box3 è una selezione di cancellazione, ovvero cancella l'area selezionata in precedenza. Con il codice relativo all'inversione commentato, l'effetto dell'esempio è il seguente:

Effetto del ritaglio tramite geometria 3D
Decommenta il codice di inversione affinché l'inversione abbia effetto; l'effetto dell'esempio è il seguente. L'inversione capovolge l'area selezionata in precedenza; è un comando e non deve essere associata a dati operativi.
In particolare, nota che l'elenco è ordinato; diversi passaggi operativi producono effetti finali diversi.

Effetto del ritaglio con geometria 3D + inversione
Ritaglio in modalità mista
Mescola voci di texture 2D e geometria 3D nello stesso elenco; ogni voce specifica il proprio metodo di elaborazione tramite editType.
public void onMixClip()
{
// --- Preparazione della selezione 2D ---
// La dimensione della texture è fissa a 1024*1024; mantieni le altre proprietà uguali all'esempio
Texture2D _texture = new Texture2D(1024, 1024, TextureFormat.R8, false);
_texture.filterMode = FilterMode.Point;
_texture.wrapMode = TextureWrapMode.Clamp;
int _count = 1024 * 1024;
int _half = _count / 2;
byte[] _values = new byte[_count];
for (int i = 0; i < _count; i++)
{
if (i < _half)
_values[i] = 128; // 128 significa predefinito, 240 significa selezionato, 0 significa ritaglio
else
_values[i] = 0;
}
_texture.SetPixelData(_values, 0);
List<DataMix> _Mixs = new List<DataMix>();
DataMix _mix01 = new DataMix();
_mix01.editType = EditType.Edit2D;
_mix01.mv = m_camera.worldToCameraMatrix;
_mix01.texture = _texture;
_mix01.mode = SelectMode.normal;
_mix01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_Mixs.Add(_mix01);
// --- Preparazione della selezione 3D ---
var _mat1 = m_Box1.transform.worldToLocalMatrix;
var _mat2 = m_Box2.transform.worldToLocalMatrix;
var _mat3 = m_Box3.transform.worldToLocalMatrix;
var _mat4 = m_Clipsphere.transform.worldToLocalMatrix;
// Selezione Box
DataMix _mix02 = new DataMix();
_mix02.editType = EditType.Edit3D;
_mix02.type = ShapeType.box;
_mix02.operation = OperationMode.normal;
_mix02.mode = SelectMode.normal;
_mix02.invMat = _mat1;
_Mixs.Add(_mix02);
DataMix _mix03 = new DataMix();
_mix03.editType = EditType.Edit3D;
_mix03.type = ShapeType.box;
_mix03.operation = OperationMode.normal;
_mix03.mode = SelectMode.normal;
_mix03.invMat = _mat2;
_Mixs.Add(_mix03);
// Selezione Sfera
DataMix _mix04 = new DataMix();
_mix04.editType = EditType.Edit3D;
_mix04.type = ShapeType.sphere;
_mix04.operation = OperationMode.normal;
_mix04.mode = SelectMode.normal;
_mix04.invMat = _mat4;
_Mixs.Add(_mix04);
// Cancella Box/Sfera (differenza)
DataMix _mix05 = new DataMix();
_mix05.editType = EditType.Edit3D;
_mix05.type = ShapeType.box;
_mix05.operation = OperationMode.erase;
_mix05.mode = SelectMode.normal;
_mix05.invMat = _mat3;
_Mixs.Add(_mix05);
// Inversione (abilita secondo necessità)
DataMix _mix06 = new DataMix();
_mix06.editType = EditType.Edit3D;
_mix06.type = ShapeType.box;
_mix06.mode = SelectMode.invert;
//_Mixs.Add(_mix06);
m_manager.SetClip(_Mixs);
}
Spiegazione del codice: vengono usate 4 geometrie e 1 texture 2D, consentendo l'elaborazione mista 2D e 3D. L'effetto dell'esempio è il seguente:

Effetto del ritaglio in modalità mista
Passaggio 8: esci dal ritaglio
Chiama QuitClipMode() per cancellare il ritaglio corrente e ripristinare la visualizzazione completa della scena.
public void onClearClip()
{
m_manager.QuitClipMode();
}
Punti chiave
I passaggi chiave per eseguire il ritaglio in tempo reale su una scena 3DGS:
- Chiama
SetEditorMode(true)prima di caricare i dati per entrare nello stato di modifica. - Chiama
SetClipdopo che i dati hanno terminato il caricamento (dopo che il callbackonLoadCallbackviene attivato, o tramite un pulsante/evento). - Scegli texture 2D, geometria 3D o modalità mista secondo necessità, e assicurati che l'ordine di aggiunta dell'elenco di selezione corrisponda alle tue aspettative.
- La texture maschera 2D è fissa a 1024 × 1024,
R8canale singolo; riempi i valori dei pixel per convenzione (128mantieni predefinito,0ritaglio). - Quando cancelli o cambi il ritaglio, chiama prima
QuitClipMode().