Guide de développement du surlignage
Le LCC Unity SDK prend en charge des opérations d'édition telles que le surlignage et la découpe sur les scènes 3DGS. Ce guide présente les opérations liées au surlignage : sélectionner une zone via des textures projetées 2D, une géométrie 3D, ou un mélange des deux, de sorte que la zone sélectionnée soit surlignée, avec prise en charge de la sélection normale et de la sélection inversée.
Remarque :
La fonctionnalité de surlignage actuelle n'est qu'un effet d'affichage à l'exécution ; elle ne modifie en aucune façon le fichier de données d'origine et ne prend pas en charge l'enregistrement ou l'exportation du résultat d'édition. Si vous devez ajuster les couleurs, découper et enregistrer des données, utilisez l'outil logiciel XGRIDS LCC Editor.
Si vous ne souhaitez pas modifier les données, vous pouvez également enregistrer les opérations et les rejouer après la fin du chargement des données la prochaine fois.
Prérequis
Le surlignage d'une scène via le SDK nécessite les conditions suivantes :
- Entrer dans l'état d'édition avant de charger les données. Le SDK est dans l'état de navigation (View) par défaut, qui offre les meilleures performances et est recommandé pour la navigation normale. Pour effectuer des opérations d'édition telles que le surlignage, passez à l'état d'édition via
SetEditorMode(true)avant d'appelerLoad. Cette méthode ne prend effet que si elle est appelée avant le chargement de toutes les données. - Effectuer l'opération de surlignage après la fin du chargement des données. L'interface de surlignage doit être appelée après le chargement complet des données de la scène.
Étape 1 : Configurer la scène
Préparez les GameObjects nécessaires au surlignage dans la scène comme illustré ci-dessous.

Structure de hiérarchie de la scène pour l'exemple de surlignage
- Caméra principale : la caméra de la scène ; le surlignage 2D utilise ses matrices de vue et de projection.
- LCCManager : un GameObject vide avec un Transform normalisé, avec le script
LCCManagerajouté. - LCCRenderer : un GameObject vide avec Transform défini sur Rotation.x = -90, Scale.x = -1 (aligné avec le système de coordonnées des données LCC), utilisé pour attacher le script
Highlightécrit plus tard. - Géométrie de sélection 3D : objets auxiliaires pour le surlignage 3D. L'exemple prépare 3 Cubes (
Box1,Box2,Box3) et 1 Sphère (Clipsphere) ; déplacer et mettre à l'échelle ces objets contrôle la position et la taille de la sélection de surlignage.
Remarque :
Pour les réglages liés à la caméra de rendu, aux GameObjects LCCManager et LCCRenderer, reportez-vous aux sections pertinentes du Guide de démarrage rapide PC et du Guide d'optimisation des paramètres de projet.

Géométrie de sélection utilisée pour le surlignage 3D (Box1 / Box2 / Box3 / Clipsphere)
Étape 2 : Comprendre les structures de données
Le surlignage implique trois méthodes d'opération — 2D, 3D et mixte 2D/3D. Les enums et structs utilisés sont les suivants.
public enum SelectMode { normal, invert, clip } // sélection normale, inversion, découpe en temps réel
public enum OperationMode { normal, erase } // sélection normale, effacement de la sélection
public enum ShapeType { box, sphere } // sélection par boîte 3D, sélection par sphère 3D
public enum EditType { Edit2D, Edit3D } // édition 2D, édition 3D
// Sélection par texture 2D
public struct Data2D
{
public Texture2D texture; // texture de masque 2D
public Matrix4x4 mv; // matrice de vue de la caméra
public Matrix4x4 mvp; // matrice de vue-projection de la caméra
public SelectMode mode; // mode de sélection
}
// Sélection par géométrie 3D
public struct Data3D
{
public ShapeType type; // type de géométrie (box / sphere)
public Matrix4x4 invMat; // matrice monde-vers-local (inverse) de la géométrie
public OperationMode operation; // type d'opération (union normale / différence par effacement)
public SelectMode mode; // mode de sélection
}
// Sélection mixte 2D / 3D
public struct DataMix
{
public EditType editType; // type d'édition (requis ; détermine si les champs 2D ou 3D sont utilisés)
public Texture2D texture; // texture de masque 2D (utilisée par Edit2D)
public Matrix4x4 mv; // matrice de vue de la caméra (utilisée par Edit2D)
public Matrix4x4 mvp; // matrice de vue-projection de la caméra (utilisée par Edit2D)
public ShapeType type; // type de géométrie (utilisé par Edit3D)
public Matrix4x4 invMat; // matrice inverse de la géométrie (utilisée par Edit3D)
public OperationMode operation; // type d'opération (utilisé par Edit3D)
public SelectMode mode; // mode de sélection (requis)
}
Il y a trois points à noter concernant la liste de sélection :
- La liste est ordonnée. Qu'il s'agisse de 2D ou de 3D, les entrées de la liste prennent effet dans l'ordre ; assurez-vous que l'ordre d'ajout correspond à votre attente.
- Invert est une commande d'opération et n'a pas besoin d'être associée à des données de sélection spécifiques. Ajoutez simplement une entrée avec
mode = SelectMode.invertpour inverser la zone actuellement sélectionnée. - Le nombre maximum d'entrées dans une seule liste est de 255. Le dépasser retourne un code d'erreur.
Étape 3 : Comprendre les API de surlignage
Toutes les interfaces liées au surlignage sont fournies par LCCManager, incluant trois surcharges de SetHighlight et une méthode de sortie.
SetHighlight (surlignage par texture 2D)
// Valeur de retour : int
// 0 : succès
// 1 : la liste est nulle ou comporte 0 élément
// 2 : les éléments de la liste dépassent le maximum de 255
public int SetHighlight(List<Data2D> _2Ds)
Surligne la scène à l'aide d'un masque de texture projetée 2D ; la partie en dehors de la zone surlignée est assombrie.
SetHighlight (surlignage par géométrie 3D)
// Valeur de retour : int
// 0 : succès
// 1 : la liste est nulle ou comporte 0 élément
// 2 : les éléments de la liste dépassent le maximum de 255
// 3 : le nombre de boîtes de géométrie de sélection est 0
public int SetHighlight(List<Data3D> _3Ds)
Définit la zone de surlignage à l'aide de la géométrie 3D (cuboïde, cube, sphère), prenant en charge les combinaisons d'union et de différence. Au moins une géométrie avec operation == OperationMode.normal est requise.
SetHighlight (surlignage en mode mixte)
// Valeur de retour : int
// 0 : succès
// 1 : la liste est nulle ou comporte 0 élément
// 2 : les éléments de la liste dépassent le maximum de 255
public int SetHighlight(List<DataMix> _Mix)
Définit la zone de surlignage en utilisant des textures 2D et une géométrie 3D en même temps ; chaque entrée détermine si elle est traitée comme 2D ou 3D via editType.
QuitHighlightMode
// Valeur de retour : void
public void QuitHighlightMode()
Sort du mode de surlignage et restaure l'affichage normal de la scène.
Conseil :
Les trois surcharges de
SetHighlightsont mutuellement exclusives. Lors du changement de méthode de surlignage ou de l'effacement du surlignage actuel, appelez d'abordQuitHighlightMode()puis définissez le nouveau surlignage.
Étape 4 : Spécification de la texture de masque 2D
Le surlignage 2D décrit la sélection via une texture de masque, prenant en charge diverses méthodes de sélection telles que les quadrilatères, les triangles, les pinceaux et les lassos — il suffit de marquer les pixels correspondants dans la texture avec la valeur sélectionnée. Lors de l'utilisation d'opérations 2D, la caméra doit être verrouillée et la texture marquée depuis un point de vue fixe. La texture et les valeurs de pixel suivent les conventions suivantes :
- La texture est fixée à 1024 × 1024,
R8monocanal, sans Mipmap, filtrage par points (FilterMode.Point), et échantillonnage borné (TextureWrapMode.Clamp). - Conventions de valeurs de pixel :
| Valeur de pixel | Signification |
|---|---|
128 | Défaut (non sélectionné) |
240 | Sélectionné |
180 | Désélectionner (effacer la zone déjà sélectionnée) |
0 | Découpe |
Dans un scénario de surlignage, seules les deux valeurs 128 (défaut) et 240 (sélectionné) sont généralement utilisées.
Étape 5 : Écrire le script
Créez un nouveau script C# nommé Highlight.cs. Complétez d'abord le squelette de base : dans Start, entrez dans l'état d'édition et chargez les données ; après la fin du chargement, définissez le drapeau de chargement que les méthodes de surlignage suivantes vérifieront.
using LCCCore;
using System.Collections.Generic;
using UnityEngine;
public class Highlight : 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);
// Entrer en mode édition ; doit être appelé avant Load
m_manager.SetEditorMode(true);
m_renderer = m_manager.GetRender(this.transform);
if (m_renderer == null)
Debug.LogError("Échec de GetRender, vérifiez que le manager est correctement défini et que le chemin du fichier est valide.");
m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
}
private void onLoadProgress(float value)
{
Debug.Log($"progression du chargement : {value}");
}
private void onLoadCallback()
{
Debug.Log("données chargées !!!");
m_isLoaded = true;
}
// Méthodes de surlignage 2D / 3D / mixte ci-dessous
}
Remarque :
SetEditorMode(true)doit être appelé avantLoadpour prendre effet ; etSetHighlightdoit être appelé après la fin du chargement des données (après le déclenchement du callbackonLoadCallback).
Étape 6 : Attacher le script et définir les propriétés
- Attachez le script
Highlight.csau GameObject LCCRenderer. - Dans la fenêtre Inspecteur, faites glisser le GameObject LCCManager sur la propriété Manager du script.
- Renseignez le chemin du fichier LCC dans la propriété File Path.
- Faites glisser
Box1,Box2,Box3etClipspherede la scène sur les propriétés correspondantes du script respectivement.

Définir les propriétés du script Highlight dans l'Inspecteur
Étape 7 : Exemples d'opération de surlignage
Ajoutez les méthodes ci-dessous à la classe Highlight, et appelez la méthode correspondante après l'exécution et après la fin du chargement des données.
Surlignage par texture 2D
Construisez deux textures de masque R8, marquez les pixels à surligner comme 240 et le reste comme 128, puis construisez Data2D avec les matrices de la caméra et ajoutez-les à la liste.
public void on2DHighlight()
{
// La taille de la texture est fixée à 1024*1024 ; gardez les autres propriétés identiques à l'exemple
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] = 240; // 240 signifie sélectionné, 128 signifie défaut, 0 signifie découpe
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] = 240;
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.SetHighlight(_2Ds);
}
Explication du code : deux textures de masque sont construites. Le premier masque sélectionne la moitié inférieure de l'écran (l'origine de l'écran est le coin inférieur gauche), et le second masque sélectionne la région de 0.75 à 0.9 de la moitié supérieure de l'écran. L'effet d'exemple est le suivant.
En utilisation réelle, vous pouvez utiliser divers outils de sélection tels que des rectangles, des triangles, des pinceaux et des lassos pour sélectionner les positions correspondantes sur le masque.

Effet de surlignage par texture 2D
Surlignage par géométrie 3D
Utilisez la worldToLocalMatrix de la géométrie comme matrice inverse de sélection, combinez l'union (normal) et la différence (erase) via operation, et implémentez la sélection inversée via une entrée avec mode = SelectMode.invert.
public void on3DHighlight()
{
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;
// Sélection par boîte
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);
// Sélection par sphère
Data3D _3d04 = new Data3D();
_3d04.type = ShapeType.sphere;
_3d04.operation = OperationMode.normal;
_3d04.mode = SelectMode.normal;
_3d04.invMat = _mat4;
_3Ds.Add(_3d04);
// Effacer boîte/sphère (différence)
Data3D _3d03 = new Data3D();
_3d03.type = ShapeType.box;
_3d03.operation = OperationMode.erase;
_3d03.mode = SelectMode.normal;
_3d03.invMat = _mat3;
_3Ds.Add(_3d03);
// Inverser
//Data3D _3d05 = new Data3D();
//_3d05.mode = SelectMode.invert;
//_3Ds.Add(_3d05);
m_manager.SetHighlight(_3Ds);
}
Explication du code : 4 géométries sont utilisées, où Box1, Box2 et Sphere sont des sélections normales, et Box3 est une sélection d'effacement, c'est-à-dire l'effacement de la zone précédemment sélectionnée. Avec le code lié à l'inversion commenté, l'effet d'exemple est le suivant :

Effet de surlignage par géométrie 3D
Décommentez le code d'inversion pour que l'inversion prenne effet ; l'effet d'exemple est le suivant. Invert inverse la zone précédemment sélectionnée ; c'est une commande et n'a pas besoin d'être associée à des données d'opération.
Notez en particulier que la liste est ordonnée ; différentes étapes d'opération produisent des effets finaux différents.

Effet de surlignage géométrie 3D + inversion
Surlignage en mode mixte
Mélangez des entrées de texture 2D et de géométrie 3D dans la même liste ; chaque entrée spécifie sa méthode de traitement via editType.
public void onMixHighlight()
{
// --- Préparation de la sélection 2D ---
// La taille de la texture est fixée à 1024*1024 ; gardez les autres propriétés identiques à l'exemple
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 signifie défaut, 240 signifie sélectionné, 0 signifie découpe
else
_values[i] = 240;
}
_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);
// --- Préparation de la sélection 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;
// Sélection par boîte
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);
// Sélection par sphère
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);
// Effacer boîte/sphère (différence)
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);
// Inverser (activer selon les besoins)
DataMix _mix06 = new DataMix();
_mix06.editType = EditType.Edit3D;
_mix06.type = ShapeType.box;
_mix06.mode = SelectMode.invert;
//_Mixs.Add(_mix06);
m_manager.SetHighlight(_Mixs);
}
Explication du code : 4 géométries et 1 texture 2D sont utilisées, permettant un traitement mixte 2D et 3D. L'effet d'exemple est le suivant :

Effet de surlignage en mode mixte
Étape 8 : Sortir du surlignage
Appelez QuitHighlightMode() pour effacer le surlignage actuel et restaurer l'affichage normal de la scène.
public void onClearHighlight()
{
m_manager.QuitHighlightMode();
}
Étapes clés
Les étapes clés pour surligner une scène 3DGS :
- Appelez
SetEditorMode(true)avant de charger les données pour entrer dans l'état d'édition. - Appelez
SetHighlightaprès la fin du chargement des données (après le déclenchement du callbackonLoadCallback, ou déclenché via un bouton/événement). - Choisissez la texture 2D, la géométrie 3D ou le mode mixte selon les besoins, et assurez-vous que l'ordre d'ajout de la liste de sélection correspond à votre attente.
- La texture de masque 2D est fixée à 1024 × 1024,
R8monocanal ; remplissez les valeurs de pixel selon la convention (128défaut,240sélectionné). - Lors de l'effacement ou du changement de surlignage, appelez d'abord
QuitHighlightMode().