İçeriğe geç
TREN
Atlıhan Harita

LCC for Unity Kullanım Kılavuzu · Özellik Geliştirme Kılavuzu

Gerçek Zamanlı Kırpma Geliştirme Kılavuzu

Bölüm 15.13 / 17Kılavuz sürümü v2.3.0Türkçe

LCC Unity SDK, 3DGS sahnelerinde vurgulama ve kırpma gibi düzenleme işlemlerini destekler. Bu kılavuz gerçek zamanlı kırpma işlemlerini tanıtır: 2D izdüşüm dokuları, 3D geometri veya her ikisinin karışımıyla bir alan seçilir ve seçilen alan sahneden kırpılır. Normal seçim ve ters seçim desteklenir.

Not:

Mevcut kırpma özelliği yalnızca çalışma zamanı görüntüleme efektidir; özgün veri dosyasını hiçbir şekilde değiştirmez ve düzenleme sonucunu kaydetmeyi veya dışa aktarmayı desteklemez. Veriye renk ayarı yapmak, veriyi kırpmak ve kaydetmek istiyorsanız XGRIDS LCC Editor yazılım aracını kullanın.

Verileri değiştirmek istemiyorsanız işlemleri kaydedebilir ve bir sonraki veri yüklemesi tamamlandıktan sonra yeniden oynatabilirsiniz.

Ön Koşullar

SDK ile bir sahneyi kırpmak için aşağıdaki koşullar gerekir:

  1. Veriyi yüklemeden önce düzenleme durumuna geçin. SDK varsayılan olarak gezinme durumundadır (View). Bu durum en iyi performansı sağlar ve normal gezinme için önerilir. Kırpma gibi düzenleme işlemleri yapmak için Load çağrısından önce SetEditorMode(true) ile düzenleme durumuna geçin. Bu yöntem yalnızca tüm veri yüklenmeden önce çağrılırsa etkili olur.
  2. Kırpma işlemini veri yüklemesi bittikten sonra yapın. Kırpma arayüzü, sahne verisi tamamen yüklendikten sonra çağrılmalıdır.

1. Adım: Sahneyi Hazırlama

Sahnede kırpma için gereken GameObject'leri aşağıda gösterildiği gibi hazırlayın.

Kırpma örneği için sahne hiyerarşisi yapısı

Kırpma örneği için sahne hiyerarşisi yapısı

  • Main Camera: sahne kamerası. 2D kırpma, bu kameranın görünüm ve projeksiyon matrislerini kullanır.
  • LCCManager: Normalleştirilmiş Transform değerine sahip boş bir GameObject nesnesidir ve LCCManager betiği eklenmiştir.
  • LCCRenderer: Transform değeri Rotation.x = -90, Scale.x = -1 olarak ayarlanmış (LCC veri koordinat sistemiyle hizalı) boş bir GameObject. Daha sonra yazılacak Clip betiğini eklemek için kullanılır.
  • 3D seçim geometrisi: 3D kırpma için yardımcı nesneler. Örnekte 3 Cube (Box1, Box2, Box3) ve 1 Sphere (Clipsphere) hazırlanmıştır. Bu nesneleri taşıyarak ve ölçekleyerek kırpma seçiminin konumunu ve boyutunu kontrol edersiniz.

Not:

Görüntüleme kamerası, LCCManager ve LCCRenderer GameObject nesnelerine ilişkin ayarlar için PC Hızlı Başlangıç Kılavuzu ve Proje Ayarları Optimizasyon Kılavuzu bölümlerine bakın.

3D kırpma için kullanılan seçim geometrisi

3D kırpma için kullanılan seçim geometrisi (Box1 / Box2 / Box3 / Clipsphere)

Adım 2: Veri Yapılarını Anlayın

Kırpma üç yöntemle yapılır: 2D, 3D ve 2D/3D karma. Kullanılan enum ve struct yapıları aşağıdadır.

public enum SelectMode    { normal, invert, clip }  // normal selection, invert, real-time clipping
public enum OperationMode { normal, erase }         // normal selection, erase selection
public enum ShapeType     { box, sphere }           // 3D Box selection, 3D Sphere selection
public enum EditType      { Edit2D, Edit3D }        // 2D edit, 3D edit

// 2D texture selection
public struct Data2D
{
    public Texture2D texture;   // 2D mask texture
    public Matrix4x4 mv;        // camera view matrix
    public Matrix4x4 mvp;       // camera view projection matrix
    public SelectMode mode;     // selection mode
}

// 3D geometry selection
public struct Data3D
{
    public ShapeType type;          // geometry type (box / sphere)
    public Matrix4x4 invMat;        // geometry's world-to-local (inverse) matrix
    public OperationMode operation; // operation type (normal union / erase difference)
    public SelectMode mode;         // selection mode
}

// 2D / 3D mixed selection
public struct DataMix
{
    public EditType editType;       // edit type (required; determines whether 2D or 3D fields are used)
    public Texture2D texture;       // 2D mask texture (used by Edit2D)
    public Matrix4x4 mv;            // camera view matrix (used by Edit2D)
    public Matrix4x4 mvp;           // camera view projection matrix (used by Edit2D)
    public ShapeType type;          // geometry type (used by Edit3D)
    public Matrix4x4 invMat;        // geometry inverse matrix (used by Edit3D)
    public OperationMode operation; // operation type (used by Edit3D)
    public SelectMode mode;         // selection mode (required)
}

Seçim listesiyle ilgili dikkat edilmesi gereken üç nokta vardır:

  1. Liste sıralıdır. 2D ya da 3D olsun, listedeki girdiler sırayla uygulanır. Ekleme sırasının beklentinizle uyuştuğundan emin olun.
  2. Invert bir işlem komutudur ve belirli bir seçim verisiyle ilişkilendirilmesi gerekmez. Geçerli seçili alanı ters çevirmek için listeye mode = SelectMode.invert olan bir girdi eklemeniz yeterlidir.
  3. Tek bir listedeki en fazla girdi sayısı 255'tir. Bu sınır aşılırsa bir hata kodu döndürülür.

Adım 3: Kırpma API'lerini Anlama

Kırpmayla ilgili tüm arayüzler LCCManager tarafından sağlanır. Bunlar üç SetClip aşırı yüklemesini ve bir çıkış yöntemini içerir.

SetClip (2D Doku Kırpma)

// Return value: int
// 0: success
// 1: list is null or has 0 elements
// 2: list elements exceed the maximum of 255
public int SetClip(List<Data2D> _2Ds)

Sahneyi 2D izdüşüm dokusu maskesiyle kırpar. İşaretlenen alan sahneden kırpılır.

SetClip (3D Geometri Kırpma)

// Return value: int
// 0: success
// 1: list is null or has 0 elements
// 2: list elements exceed the maximum of 255
// 3: the number of selection geometry boxes is 0
public int SetClip(List<Data3D> _3Ds)

Kırpma alanını 3D geometriyle (kuboid, küp, küre) tanımlar; birleşim ve fark kombinasyonlarını destekler. operation == OperationMode.normal olan en az bir geometri gereklidir.

SetClip (Karma Mod Kırpma)

// Return value: int
// 0: success
// 1: list is null or has 0 elements
// 2: list elements exceed the maximum of 255
public int SetClip(List<DataMix> _Mix)

Kırpma alanını aynı anda 2D dokular ve 3D geometriyle tanımlar. Her giriş, 2D mi 3D mü işleneceğini editType ile belirler.

QuitClipMode

// Return value: void
public void QuitClipMode()

Kırpma modundan çıkar ve tam sahne görüntüsünü geri yükler.

İpucu:

Üç SetClip aşırı yüklemesi birbirini dışlar. Kırpma yöntemini değiştirirken veya mevcut kırpmayı temizlerken önce QuitClipMode() çağırın, ardından yeni kırpmayı ayarlayın.

Adım 4: 2D Maske Dokusu Özellikleri

2D kırpma, seçimi bir maske dokusuyla tanımlar. Dörtgen, üçgen, fırça ve kement gibi çeşitli seçim yöntemlerini destekler; dokudaki ilgili pikselleri kırpma değeriyle işaretlemeniz yeterlidir. 2D işlemlerde kamerayı kilitleyin ve dokuyu sabit bir bakış noktasından işaretleyin. Doku ve piksel değerleri için kurallar şöyledir:

  • Doku 1024 × 1024 boyutunda sabittir; R8 tek kanal, Mipmap yok, nokta filtreleme (FilterMode.Point) ve sınırlı örnekleme (TextureWrapMode.Clamp) kullanılır.
  • Piksel değeri kuralları:
Piksel değeriAnlamı
128Varsayılan (koru)
240Seçili
180Seçimi kaldır (daha önce seçilen alanı sil)
0Kırpma

Kırpma senaryosunda genellikle yalnızca 128 (varsayılan koru) ve 0 (kırp) değerleri kullanılır.

Adım 5: Betiği Yazın

Clip.cs adında yeni bir C# betiği oluşturun. Önce temel iskeleti tamamlayın: Start içinde düzenleme durumuna geçip veriyi yükleyin. Yükleme bitince, sonraki kırpma yöntemlerinin kontrol edeceği yükleme bayrağını ayarlayın.

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);

        // Enter edit mode; must be called before Load
        m_manager.SetEditorMode(true);

        m_renderer = m_manager.GetRender(this.transform);
        if (m_renderer == null)
            Debug.LogError("GetRender failed, check if the manager is set correctly and the file path is valid.");

        m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
    }

    private void onLoadProgress(float value)
    {
        Debug.Log($"loading progress: {value}");
    }

    private void onLoadCallback()
    {
        Debug.Log("data loaded !!!");
        m_isLoaded = true;

        // Disable environment (far-field low-precision point cloud) rendering to better observe the clipping result
        m_renderer.SetEnvironment(false);
    }

    // 2D / 3D / mixed clipping methods below
}

Not:

SetEditorMode(true) etkili olması için Load çağrısından önce çağrılmalıdır. SetClip ise veri yüklemesi bittikten sonra (onLoadCallback geri çağrısı tetiklendikten sonra) çağrılmalıdır. SetEnvironment(false), kırpma sonucunu daha net görmek için uzak alan ortam nokta bulutunu devre dışı bırakır. Çağırıp çağırmamaya ihtiyacınıza göre karar verin.

Adım 6: Betiği Ekleyin ve Özellikleri Ayarlayın

  1. Clip.cs betiğini LCCRenderer GameObject'ine ekleyin.
  2. Inspector penceresinde LCCManager GameObject'ini betiğin Manager özelliğine sürükleyin.
  3. LCC dosya yolunu File Path özelliğine girin.
  4. Sahnedeki Box1, Box2, Box3 ve Clipsphere nesnelerini betiğin ilgili özelliklerine sırasıyla sürükleyin.
Inspector'da Clip betiği özelliklerini ayarlayın

Inspector'da Clip betiği özelliklerini ayarlayın

Adım 7: Kırpma İşlemi Örnekleri

Aşağıdaki yöntemleri Clip sınıfına ekleyin. Uygulamayı çalıştırıp veri yüklemesi bittikten sonra ilgili yöntemi çağırın.

2D Doku Kırpma

İki R8 maske dokusu oluşturun. Kırpılacak pikselleri 0, kalan koruma alanını 128 olarak işaretleyin. Ardından kamera matrisleriyle Data2D oluşturup listeye ekleyin.

public void on2DClip()
{
    // Texture size is fixed at 1024*1024; keep other properties the same as the example
    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 means clipping, 128 means default, 240 means selected
        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);
}

Kod açıklaması: İki maske dokusu oluşturulur. İlk maske ekranın alt yarısını kırpar (ekran orijini sol alt köşedir). İkinci maske ekranın üst yarısının 0,75 ile 0,9 aralığındaki bölgesini kırpar. Örnek efekt aşağıdadır.

Gerçek kullanımda maske üzerinde ilgili konumları seçmek için dikdörtgen, üçgen, fırça ve kement gibi çeşitli seçim araçlarını kullanabilirsiniz.

2D doku kırpma efekti

2D doku kırpma efekti

3D Geometri Kırpma

Geometrinin worldToLocalMatrix değerini seçim ters matrisi olarak kullanın. operation üzerinden birleşim (normal) ve farkı (erase) birleştirin. Ters seçimi ise mode = SelectMode.invert olan bir girdiyle uygulayın.

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;

    // Box selection
    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);

    // Sphere selection
    Data3D _3d04 = new Data3D();
    _3d04.type = ShapeType.sphere;
    _3d04.operation = OperationMode.normal;
    _3d04.mode = SelectMode.normal;
    _3d04.invMat = _mat4;
    _3Ds.Add(_3d04);

    // Erase Box/Sphere (difference)
    Data3D _3d03 = new Data3D();
    _3d03.type = ShapeType.box;
    _3d03.operation = OperationMode.erase;
    _3d03.mode = SelectMode.normal;
    _3d03.invMat = _mat3;
    _3Ds.Add(_3d03);

    // Invert
    //Data3D _3d05 = new Data3D();
    //_3d05.mode = SelectMode.invert;
    //_3Ds.Add(_3d05);

    m_manager.SetClip(_3Ds);
}

Kod açıklaması: 4 geometri kullanılır. Box1, Box2 ve Sphere normal seçimdir; Box3 ise silme seçimidir, yani daha önce seçilen alanı siler. Ters çevirmeyle ilgili kod yorum satırı yapıldığında örnek sonuç şöyledir:

3D geometri kırpma efekti

3D geometri kırpma efekti

Ters çevirmenin etkili olması için ters çevirme kodundaki yorum işaretlerini kaldırın. Örnek sonuç aşağıdaki gibidir. Invert, daha önce seçilen alanı tersine çevirir. Bir komuttur ve işlem verisiyle ilişkilendirilmesi gerekmez.

Özellikle listenin sıralı olduğuna dikkat edin. Farklı işlem adımları farklı nihai sonuçlar üretir.

3D geometri + ters kırpma efekti

3D geometri + ters kırpma efekti

Karma Mod Kırpma

2D doku ve 3D geometri girdilerini aynı listede birleştirin. Her girdi işlenme yöntemini editType ile belirtir.

public void onMixClip()
{
    // --- 2D selection preparation ---
    // Texture size is fixed at 1024*1024; keep other properties the same as the example
    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 means default, 240 means selected, 0 means clipping
        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);

    // --- 3D selection preparation ---
    var _mat1 = m_Box1.transform.worldToLocalMatrix;
    var _mat2 = m_Box2.transform.worldToLocalMatrix;
    var _mat3 = m_Box3.transform.worldToLocalMatrix;
    var _mat4 = m_Clipsphere.transform.worldToLocalMatrix;

    // Box selection
    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);

    // Sphere selection
    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);

    // Erase Box/Sphere (difference)
    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);

    // Invert (enable as needed)
    DataMix _mix06 = new DataMix();
    _mix06.editType = EditType.Edit3D;
    _mix06.type = ShapeType.box;
    _mix06.mode = SelectMode.invert;
    //_Mixs.Add(_mix06);

    m_manager.SetClip(_Mixs);
}

Kod açıklaması: 4 geometri ve 1 adet 2D doku kullanılır. Böylece 2D ve 3D karma işleme yapılabilir. Örnek sonuç şöyledir:

Karma mod kırpma efekti

Karma mod kırpma efekti

Adım 8: Kırpmadan Çıkma

Mevcut kırpmayı temizlemek ve tam sahne görüntüsünü geri yüklemek için QuitClipMode() çağırın.

public void onClearClip()
{
    m_manager.QuitClipMode();
}

Temel Adımlar

3DGS sahnesinde gerçek zamanlı kırpma yapmanın temel adımları:

  1. Düzenleme durumuna girmek için veriyi yüklemeden önce SetEditorMode(true) çağrısını yapın.
  2. SetClip yöntemini veri yüklemesi bittikten sonra çağırın (onLoadCallback geri çağrısı tetiklendikten sonra veya bir düğme/olay aracılığıyla).
  3. İhtiyacınıza göre 2D doku, 3D geometri veya karma modu seçin ve seçim listesinin ekleme sırasının beklentinizle uyuştuğundan emin olun.
  4. 2D maske dokusu 1024 × 1024 olarak sabittir, R8 tek kanallıdır; piksel değerlerini kurala göre doldurun (128 varsayılan koru, 0 kırp).
  5. Kırpmayı temizlerken veya değiştirirken önce QuitClipMode() çağırın.

Bu bölüm XGRIDS'in resmî kullanım kılavuzundan Türkçeye çevrildi; ekran görüntüleri ve arayüz adları özgün haliyle İngilizcedir. İngilizce aslı (yeni sekmede açılır) · Güncelleme:

XGRIDS Türkiye

Kurulumda ve Sahada Yanınızdayız

Atlıhan Harita; cihaz kurulumu, firmware güncellemesi, yazılım kullanımı ve saha uygulamalarında eğitim ve teknik destek verir. Sorunuzu iletin, uzmanımız size dönsün.

+90 216 546 0804