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

    • PortalCam P1

      • Przegląd produktu
      • Podstawowa obsługa
      • Korzystanie z aplikacji LCC Scan
      • Konserwacja i pielęgnacja
      • FAQ
  • Seria Lixel K

    • Lixel K1

      • Przegląd produktu
      • Podstawowa obsługa
      • Aktywacja i połączenie urządzenia
      • Przebieg skanowania
      • Pozyskiwanie danych chmury punktów ze współrzędnymi bezwzględnymi
      • Fuzja map
      • Zalecenia dotyczące planowania trasy dla typowych scen
      • Środki ostrożności
      • FAQ
    • Lixel K2

      • Przegląd produktu
      • Podstawowa obsługa
      • Aktywacja i połączenie urządzenia
      • Przebieg skanowania
      • Pozyskiwanie danych chmury punktów ze współrzędnymi bezwzględnymi
      • Fuzja map
      • Zalecenia dotyczące planowania trasy dla typowych scen
      • Środki ostrożności
      • FAQ
  • Seria Lixel L

    • Lixel L2 Pro

      • Przegląd produktu
      • Podstawowa obsługa
      • Aktywacja i połączenie urządzenia
      • Proces skanowania
      • Pozyskiwanie danych chmury punktów ze współrzędnymi bezwzględnymi
      • Punkt pomiarowy
      • Dodatek
      • FAQ
    • Lixel L3

      • Przegląd produktu
      • Podstawowe funkcje urządzenia
      • Aktywacja i połączenie urządzenia
      • Przechwytywanie danych
      • Przechwytywanie współrzędnych bezwzględnych
      • Dodatek
  • Akcesoria

    • Stick Light

      • Przewodnik instalacji
      • Podstawowa obsługa
      • Często zadawane pytania
  • Lixel Studio

    • Wersja i prawa autorskie
    • Instalacja i aktywacja
    • Interfejs oprogramowania
    • Operacje na plikach
    • Przetwarzanie projektu
    • Narzędzia
    • Rysowanie 2D
    • Zastosowania
    • Ustawienia
    • Połączenie z urządzeniem
  • 07-plugin-sdk

    • Unity

      • Wprowadzenie do Unity SDK
      • Funkcje techniczne
      • Wymagania środowiska deweloperskiego
      • Przewodnik szybkiego startu dla PC
      • Przewodnik optymalizacji ustawień projektu
      • Przewodnik deweloperski dla Pico 4 Ultra
      • Przewodnik strumieniowania PC dla Pico 4 Ultra
      • Przewodnik deweloperski dla Quest 3
      • Przewodnik strumieniowania PC dla Quest 3
      • Przewodnik deweloperski dla OpenXR
      • Przewodnik Business Streaming dla Pico 4 Ultra
      • Słownik
      • Często zadawane pytania (FAQ)
      • Skontaktuj się z nami
      • Przewodnik programowania funkcji

        • Przewodnik mieszanego renderowania wielu scen
        • Przewodnik odbierania cieni
        • Przewodnik oświetlenia w czasie rzeczywistym
        • Przewodnik renderowania wielokamerowego
        • Przewodnik renderowania obrazów wysokiej rozdzielczości
        • Przewodnik zgodności formatów danych LCC i LCC2
        • Przewodnik efektu ładowania
        • Przewodnik przełączania trybu renderowania Mip
        • Przewodnik przyciągania do krawędzi i narożników
        • Przewodnik dekala projekcyjnego
        • Przewodnik wideo dekala projekcyjnego
        • Przewodnik podświetlania
        • Przewodnik przycinania w czasie rzeczywistym
        • Przewodnik korekcji kolorów
        • Przewodnik pobierania danych siatki sceny
        • Przewodnik trybu edytora
        • Przewodnik konfiguracji parametrów wydajności renderowania
        • Przewodnik współpakowania aplikacji i danych
        • Przewodnik systemu kolizji
        • Przewodnik problemów z uprawnieniami w deweloperstwie na macOS
        • Przewodnik kompilacji i pakowania na urządzenia iOS
      • Dokumentacja API

        • LCCManager
        • Renderer
        • Typy danych
      • Dziennik zmian

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

Przewodnik przyciągania do krawędzi i narożników

LCC Unity SDK obsługuje wykrywanie krawędzi i narożników oraz podgląd przyciągania na powierzchniach 3DGS, co można wykorzystać w scenariuszach interakcji wymagających precyzyjnego pozycjonowania, takich jak pomiary, adnotacje i umieszczanie. Poniżej opisano kompletne kroki implementacji wykrywania krawędzi/narożników i przyciągania.

Uwaga:

Funkcja przyciągania (wykrywanie krawędzi/narożników, podgląd przyciągania i raycasting z przyciąganiem) jest obsługiwana tylko na platformach PC / Mac. Wywoływanie powiązanych API na platformach mobilnych / VR nie ma efektu i wyświetla ostrzeżenie.

Krok 1: Utwórz scenę i GameObjects

Utwórz zupełnie nową scenę w Unity. Unity domyślnie tworzy Kamerę główną i Światło kierunkowe.

Skonfiguruj Kamerę główną

Wybierz Kamerę główną w oknie Hierarchia i ustaw jej właściwości w oknie Inspektor, jak pokazano poniżej.

Ustaw właściwości Kamery głównej

Ustaw właściwości Kamery głównej

Utwórz LCCManager

Kliknij prawym przyciskiem myszy pusty obszar w oknie Hierarchia, wybierz Utwórz pusty z menu podręcznego, aby utworzyć pusty GameObject, nazwij go LCCManager, znormalizuj jego Transform i dodaj do niego skrypt LCCManager przez Dodaj komponent.

Utwórz GameObject LCCManager i dodaj skrypt LCCManager

Utwórz GameObject LCCManager i dodaj skrypt LCCManager

Utwórz LCCRenderer

Kliknij prawym przyciskiem myszy pusty obszar w oknie Hierarchia, wybierz Utwórz pusty, aby utworzyć pusty GameObject, nazwij go LCCRenderer i ustaw jego Transform na Rotation.x = -90 i Scale.x = -1.

Utwórz LCCRenderer i ustaw jego Transform

Utwórz LCCRenderer i ustaw jego Transform (Rotation.x = -90, Scale.x = -1)

Uwaga:

Ustawienia Transform GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) wyrównują go z układem współrzędnych danych LCC. Szczegóły wyrównania układu współrzędnych znajdziesz w sekcji „Układ współrzędnych danych LCC" w Wprowadzenie do Unity SDK.

Krok 2: Dodaj Render Feature

  1. Na pasku menu Unity wybierz Plik → Ustawienia projektu, po lewej stronie wybierz Grafika i potwierdź bieżący Domyślny zasób potoku renderowania. Ten przykład używa URP (Universal Render Pipeline Asset).
Potwierdź Domyślny zasób potoku renderowania w ustawieniach Grafiki

Potwierdź Domyślny zasób potoku renderowania w ustawieniach Grafiki

  1. Kliknij ten zasób, zlokalizuj odpowiedni plik zasobu w oknie Projekt i znajdź jego powiązany Renderer (URP_Renderer.asset w tym przykładzie).

  2. Wybierz ten plik zasobu Renderer, kliknij Dodaj Render Feature w oknie Inspektor i dodaj Snap Frame Capture Feature.

Dodaj funkcję Snap Frame Capture Feature do renderera URP

Dodaj funkcję Snap Frame Capture Feature do renderera URP

Krok 3: Napisz skrypt, aby włączyć przyciąganie

Utwórz nowy skrypt C# o nazwie Snap.cs z następującym kodem:

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("Uruchomiono ");
        m_renderer = m_manager.GetRender(this.transform);
        m_renderer.Load(m_FilePath, onProgress, onComplete);
    }

    private void onProgress(float _progress)
    {
        Debug.Log($"[LCCRenderer] postęp ładowania pliku: {_progress:P1}");
    }

    private void onComplete()
    {
        Debug.Log($"[LCCRenderer] plik załadowany");
        m_loaded = true;
        // Włącz wykrywanie krawędzi/narożników i podgląd przyciągania
        m_manager.SetSnapEnabled(true);
        m_manager.SetSnapPreviewEnabled(true);
    }

    private void Update()
    {
        if (!m_loaded) return;
        // Aktualizuj podgląd przyciągania w czasie rzeczywistym na podstawie bieżącej pozycji myszy
        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);
            }
        }
    }
}

Uwaga:

Wykrywanie krawędzi/narożników (SetSnapEnabled) i podgląd przyciągania (SetSnapPreviewEnabled) muszą być włączone po zakończeniu ładowania sceny LCC, więc oba są wywoływane w wywołaniu zwrotnym onComplete. Podgląd przyciągania musi być również stale aktualizowany przez UpdateSnapPreview w Update.

Powyższy przykład demonstruje następujące punkty:

  • Włącz wykrywanie krawędzi i narożników: m_manager.SetSnapEnabled(true)
  • Włącz podgląd przyciągania: m_manager.SetSnapPreviewEnabled(true)
  • Aktualizuj podgląd przyciągania w czasie rzeczywistym: m_manager.UpdateSnapPreview(Input.mousePosition, m_camera)
  • Wykonaj raycast w punkcie przyciągania i utwórz kulę w punkcie trafienia: m_manager.RaycastWithSnap(...); przy trafieniu w result.hitPos tworzona jest czerwona kula

Krok 4: Dołącz skrypt i ustaw ścieżkę danych

  1. Dołącz skrypt Snap.cs do GameObject LCCRenderer w oknie Hierarchia.
  2. W oknie Inspektor przeciągnij GameObject LCCManager na właściwość Manager skryptu.
  3. Wpisz ścieżkę pliku LCC we właściwości File Path skryptu.

Krok 5: Uruchom

Kliknij przycisk Odtwórz w oknie Gra, aby zobaczyć krawędzie i narożniki wykryte w czasie rzeczywistym oraz ikonę podglądu celu przyciągania. Gdy poruszasz myszą, ikona podglądu podąża za najbliższym celem przyciągania w czasie rzeczywistym; kliknięcie prawym przyciskiem wykonuje raycast w punkcie przyciągania i tworzy czerwoną kulę.

Krawędzie, narożniki i ikona podglądu przyciągania wykryte w czasie rzeczywistym po uruchomieniu

Krawędzie, narożniki i ikona podglądu przyciągania wykryte w czasie rzeczywistym po uruchomieniu

FAQ: Wyłącz tryb zgodności

Jeśli okno Konsola w Unity zgłasza błędy i nie pojawia się ikona podglądu przyciągania, wyłącz tryb zgodności: otwórz panel ustawień przez Edycja → Ustawienia projektu → Grafika, wybierz kartę URP i nie zaznaczaj pola wyboru po Render Graph → Tryb zgodności (Render Graph wyłączony).

Nie zaznaczaj trybu zgodności Render Graph

Nie zaznaczaj trybu zgodności Render Graph (Render Graph wyłączony)

Kluczowe kroki

Kluczowe kroki implementacji wykrywania krawędzi/narożników i przyciągania:

  1. Upewnij się, że Snap Frame Capture Feature została dodana do renderera URP.
  2. Upewnij się, że wykrywanie krawędzi/narożników (SetSnapEnabled(true)) i podgląd przyciągania (SetSnapPreviewEnabled(true)) są włączone w kodzie po zakończeniu ładowania sceny LCC.
  3. Upewnij się, że UpdateSnapPreview jest wywoływane w czasie rzeczywistym w Update, aby aktualizować ikonę podglądu.

API powiązane z przyciąganiem

LCC Unity SDK udostępnia poniższe API powiązane z przyciąganiem przez LCCManager. Są one obsługiwane tylko na platformach PC / Mac — wywoływanie ich na platformach mobilnych / VR nie ma efektu i wyświetla ostrzeżenie — i wszystkie muszą być wywoływane po zakończeniu ładowania sceny LCC.

SetSnapEnabled

// Wartość zwracana: void
public void SetSnapEnabled(bool enable)

Przełącza funkcję przyciągania. Po włączeniu RaycastWithSnap automatycznie wyszukuje pobliskie krawędzie/narożniki do przyciągnięcia.

ParametrTypOpis
enableboolCzy włączyć przyciąganie

Przykład użycia:

m_manager.SetSnapEnabled(true);

Uwagi:

  • Domyślnie wyłączone.
  • Obsługiwane tylko na PC / Mac; wywołanie na mobilnych / VR nie ma efektu i wyświetla ostrzeżenie.
  • Po włączeniu alokowane są zasoby GPU (EdgeDetect / CornerDetect / SnapSearch).

SetSnapRadius

// Wartość zwracana: void
public void SetSnapRadius(float pixels)

Ustawia promień wyszukiwania przyciągania. Najbliższa krawędź/narożnik jest wyszukiwana w tym zakresie pikseli.

ParametrTypOpis
pixelsfloatPromień wyszukiwania przyciągania (piksele)

Przykład użycia:

m_manager.SetSnapRadius(30f);

Uwagi:

  • Domyślnie 20 pikseli.
  • Im większa wartość, tym szerszy zakres wyszukiwania, ale może przyciągać do niezamierzonych celów.
  • Obsługiwane tylko na PC / Mac.

SetEdgeThreshold

// Wartość zwracana: void
public void SetEdgeThreshold(float threshold)

Ustawia próg wykrywania krawędzi Sobel. Im mniejsza wartość, tym więcej krawędzi jest wykrywanych.

ParametrTypOpis
thresholdfloatPróg wykrywania krawędzi

Przykład użycia:

m_manager.SetEdgeThreshold(0.2f);

Uwagi:

  • Domyślnie 0.3.
  • Zalecany zakres [0.1, 0.8].
  • Zbyt mała wartość daje dużo zaszumionych krawędzi.
  • Obsługiwane tylko na PC / Mac.

SetSnapPreviewEnabled

// Wartość zwracana: void
public void SetSnapPreviewEnabled(bool enable)

Przełącza funkcję podglądu przyciągania. Po włączeniu wskaźnik najbliższego celu przyciągania jest wyświetlany w czasie rzeczywistym podczas ruchu myszy.

ParametrTypOpis
enableboolCzy włączyć podgląd przyciągania

Przykład użycia:

m_manager.SetSnapPreviewEnabled(true);

Uwagi:

  • Wymaga wcześniejszego wywołania SetSnapEnabled(true).
  • Podgląd stale zużywa zasoby GPU (wykrywanie co klatkę).
  • Obsługiwane tylko na PC / Mac.

UpdateSnapPreview

// Wartość zwracana: void
public void UpdateSnapPreview(Vector2 mousePos, Camera cam)

Aktualizuje stan podglądu przyciągania. Wywołuj podczas ruchu myszy, aby zaktualizować pozycję wskaźnika podglądu.

ParametrTypOpis
mousePosVector2Bieżąca współrzędna ekranowa myszy
camCameraKamera

Przykład użycia:

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

Uwagi:

  • Wymaga wcześniejszego wywołania SetSnapPreviewEnabled(true).
  • Zaleca się wywoływanie w sposób ciągły w Update.
  • Obsługiwane tylko na PC / Mac.

GetSnapPreviewState

// Wartość zwracana: SnapPreviewState (screenPos jest we współrzędnych ekranu)
public SnapPreviewState GetSnapPreviewState()

Pobiera bieżący stan podglądu przyciągania, w tym informację o tym, czy istnieje cel przyciągania, typ celu, pozycję ekranową celu i odległość w pikselach do myszy.

Przykład użycia:

var state = m_manager.GetSnapPreviewState();
if (state.hasTarget)
{
    // state.snapType: Narożnik / Krawędź
    // state.screenPos: pozycja ekranowa celu przyciągania
    // state.distanceToMouse: odległość w pikselach
}

Uwagi:

  • Wymaga wcześniejszego wywołania SetSnapPreviewEnabled(true) i UpdateSnapPreview.
  • Zwraca default(SnapPreviewState), gdy nie ma celu.
  • screenPos to współrzędna ekranowa, a nie współrzędna świata; jeśli potrzebujesz współrzędnej świata, użyj RaycastWithSnap, aby uzyskać HitResult.hitPos.
  • Obsługiwane tylko na PC / Mac.

RaycastWithSnap

// Wartość zwracana: bool (true = trafienie)
public bool RaycastWithSnap(Vector2 screenPos, Camera cam, out HitResult result)

Raycasting z przyciąganiem. Najpierw wykonuje normalny Raycast, a następnie wyszukuje krawędzie/narożniki w pobliżu punktu trafienia do przyciągnięcia.

ParametrTypOpis
screenPosVector2Współrzędna ekranowa
camCameraKamera
resultout HitResultWynik trafienia (w tym informacje o przyciąganiu)

Przykład użycia:

if (m_manager.RaycastWithSnap(Input.mousePosition, m_camera, out HitResult hit))
{
    // hit.snapType: Narożnik / Krawędź / Brak
    // hit.hitPos: pozycja świata po przyciągnięciu
    // hit.originalHitPos: pierwotny punkt trafienia przed przyciągnięciem
}

Uwagi:

  • Wymaga wcześniejszego wywołania SetSnapEnabled(true).
  • Priorytet przyciągania: Narożnik > Krawędź > Brak.
  • Ten punkt wejścia synchronicznie blokuje wątek główny (czekając na wynik odczytu z GPU); zaleca się wywoływanie tylko przy zdarzeniach interakcji (takich jak kliknięcia), a nie co klatkę.
  • W trybie podglądu (SetSnapPreviewEnabled(true)), jeśli cel przyciągania już istnieje, używana jest bezpośrednio pamięć podręczna podglądu bez ponownego obliczania; w przeciwnym razie używany jest normalny przepływ przyciągania.
  • Obsługiwane tylko na PC / Mac.

Powiązane struktury danych

SnapType

public enum SnapType { None, Edge, Corner }

Typ celu przyciągania: brak / krawędź / narożnik.

SnapPreviewState

public struct SnapPreviewState {
    public bool hasTarget;          // czy istnieje cel przyciągania
    public SnapType snapType;       // Brak / Krawędź / Narożnik
    public Vector2 screenPos;       // pozycja ekranowa celu przyciągania (nie pozycja świata)
    public float distanceToMouse;   // odległość w pikselach do pozycji myszy
}

⚠️ screenPos to współrzędna pikselowa ekranu, a nie współrzędna świata. Jeśli potrzebujesz współrzędnej świata, użyj RaycastWithSnap, aby uzyskać HitResult.hitPos.

HitResult

public struct HitResult {
    public bool isHit;             // czy trafiono
    public float distance;         // odległość
    public Vector3 hitPos;         // pozycja świata punktu trafienia (nazwa pola to hitPos, nie position)
    public Vector3 normal;         // normalna trafienia
    public float hitAlpha;         // alfa trafionej elipsoidy
    public float dist2Origin;      // odległość do początku promienia
    public float scale;            // skala elipsoidy
    public SnapType snapType;      // typ przyciągania (Brak / Krawędź / Narożnik)
    public Vector3 originalHitPos; // pierwotny punkt trafienia przed przyciągnięciem
}

⚠️ Różnica w nazewnictwie pól: pole pozycji świata punktu trafienia to hitPos (a nie position); wywołujący powinni uzyskiwać do niego dostęp przy użyciu rzeczywistej nazwy pola.