Unity'de uzamsal eşleme

Uzamsal eşleme , HoloLens cihazının etrafındaki dünyadaki yüzeyleri temsil eden üçgen çizgiler almanızı sağlar. Unity projelerinize fazladan bir daldırma dozu vermek için surface verilerini yerleştirme, tıkanıklık ve oda analizi için kullanabilirsiniz.

Unity, geliştiricilere aşağıdaki yollarla sunulan uzamsal eşleme için tam destek içerir:

  1. Uzamsal eşlemeye başlamak için kullanışlı ve hızlı bir yol sağlayan MixedRealityToolkit'te bulunan uzamsal eşleme bileşenleri
  2. Tam denetim sağlayan ve uygulamaya özgü daha gelişmiş özelleştirme sağlayan alt düzey uzamsal eşleme API'leri

Uygulamanızda uzamsal eşlemeyi kullanmak için SpatialPerception özelliğinin AppxManifest'inizde ayarlanması gerekir.

Cihaz desteği

Özellik HoloLens (ilk nesil) HoloLens 2 Çevreleyici kulaklıklar
Uzamsal eşleme ✔️ ✔️

SpatialPerception özelliğini ayarlama

Bir uygulamanın uzamsal eşleme verilerini tüketmesi için SpatialPerception özelliğinin etkinleştirilmesi gerekir.

SpatialPerception özelliğini etkinleştirme:

  1. Unity Düzenleyicisi'nde "Yürütücü Ayarları" bölmesini açın (Proje Ayarları > Oynatıcısını Düzenle>)
  2. "Windows Mağazası" sekmesinden
  3. "Yayımlama Ayarları"nı genişletin ve "Özellikler" listesinde "SpatialPerception" özelliğini denetleyin

Not

Unity projenizi zaten bir Visual Studio çözümüne aktardıysanız, yeni bir klasöre aktarmanız veya bu özelliği Visual Studio'daki AppxManifest'te el ile ayarlamanız gerekir.

Uzamsal eşleme ayrıca en az 10.0.10586.0 MaxVersionTested gerektirir:

  1. Visual Studio'da, Çözüm Gezgini Package.appxmanifest'e sağ tıklayın ve Kodu Görüntüle'yi seçin
  2. TargetDeviceFamily değerini belirten satırı bulun ve MaxVersionTested="10.0.10240.0" değerini MaxVersionTested="10.0.10586.0" olarak değiştirin
  3. Package.appxmanifest dosyasını kaydedin.

Unity'de eşleme ekleme

Uzamsal farkındalık sistemi

MRTK'da çeşitli uzamsal ağ gözlemcileri ayarlama hakkında bilgi için Uzamsal farkındalık başlangıç kılavuzuna bakın.

Cihaz içi gözlemciler hakkında bilgi için Cihaz için mesh gözlemcilerini yapılandırma kılavuzuna bakın.

Gözlemcileri anlayarak sahne hakkında bilgi edinmek için Sahneyi anlama gözlemci kılavuzuna bakın.

Üst düzey mesh analizi: Spatial Understanding

Dikkat

Spatial Understanding, Scene Understanding'in lehine kullanım dışı bırakılmıştır.

MixedRealityToolkit, Unity'nin holografik API'leri üzerine kurulu holografik geliştirme için bir yardımcı program kodu koleksiyonudur.

Uzamsal Anlama

Hologramları fiziksel dünyaya yerleştirirken genellikle uzamsal haritalamanın ağ ve yüzey düzlemlerinin ötesine geçmek tercih edilir. Yerleştirme işlemi yordamsal olarak yapıldığında, daha yüksek bir çevre anlayışı düzeyi arzu edilir. Bu genellikle zemin, tavan ve duvarlar hakkında kararlar almayı gerektirir. Ayrıca holografik nesneler için en iyi fiziksel konumları belirlemek üzere bir dizi yerleştirme kısıtlamasına karşı iyileştirme olanağına da sahipsiniz.

Asobo Studios, Young Conker ve Fragments'in geliştirilmesi sırasında bir oda çözücü geliştirerek bu sorunla karşılaştı. Bu oyunların her birinin oyuna özgü ihtiyaçları vardı, ancak temel uzamsal anlama teknolojisini paylaştılar. HoloToolkit.SpatialUnderstanding kitaplığı bu teknolojiyi kapsülleyerek duvarlardaki boş alanları hızla bulmanızı, tavana nesneler yerleştirmenizi, karakterin oturacak şekilde yerleştirilmelerini belirlemenizi ve çok sayıda diğer uzamsal anlama sorgularını tanımlamanızı sağlar.

Kaynak kodun tamamı dahil edilir ve bu sayede kodu ihtiyaçlarınıza göre özelleştirebilir ve geliştirmelerinizi toplulukla paylaşabilirsiniz. C++ çözücü kodu bir UWP dll'sine sarmalanmış ve MixedRealityToolkit içinde yer alan prefab içinde bir bırakma ile Unity'ye kullanıma sunuldu.

Modülleri Anlama

Modülün sunduğu üç birincil arabirim vardır: basit yüzey ve uzamsal sorgular için topoloji, nesne algılama şekli ve nesne kümelerinin kısıtlama tabanlı yerleşimi için nesne yerleştirme çözücü. Bunların her biri aşağıda açıklanmıştır. Üç birincil modül arabirimine ek olarak, etiketli yüzey türlerini almak için bir ışın döküm arayüzü kullanılabilir ve özel bir watertight playspace ağı kopyalanabilir.

Ray Casting

Oda taraması tamamlandıktan sonra zemin, tavan ve duvarlar gibi yüzeyler için dahili olarak etiketler oluşturulur. PlayspaceRaycast işlevi bir ışını alır ve ışını bilinen bir yüzeyle çarpışırsa ve eğer öyleyse, bu yüzeyle ilgili bilgiler şeklinde RaycastResultdöndürür.

struct RaycastResult
{
    enum SurfaceTypes
    {
        Invalid,    // No intersection
        Other,
        Floor,
        FloorLike,  // Not part of the floor topology,
                    //  but close to the floor and looks like the floor
        Platform,   // Horizontal platform between the ground and
                    //  the ceiling
        Ceiling,
        WallExternal,
        WallLike,   // Not part of the external wall surface,
                    //  but vertical surface that looks like a
                    //  wall structure
    };
    SurfaceTypes SurfaceType;
    float SurfaceArea;  // Zero if unknown
                        //  (i.e. if not part of the topology analysis)
    DirectX::XMFLOAT3 IntersectPoint;
    DirectX::XMFLOAT3 IntersectNormal;
};

Dahili olarak, raycast, oyun alanının hesaplanan 8 cm küplü voksel gösterimine göre hesaplanır. Her voksel, işlenen topoloji verilerine (diğer adıyla sörfçüler) sahip bir dizi yüzey öğesi içerir. Kesişen voksel hücresinde bulunan sörfçüler karşılaştırılır ve topoloji bilgilerini aramak için kullanılan en iyi eşleşmedir. Bu topoloji verileri, "SurfaceTypes" sabit listesi biçiminde döndürülen etiketlemeyi ve kesişen yüzeyin yüzey alanını içerir.

Unity örneğinde, imleç her kareyi bir ışın atar. Önce Unity'nin collider'larına karşı. İkinci olarak, modülün dünya temsilini anlama. Son olarak da kullanıcı arabirimi öğeleri. Bu uygulamada kullanıcı arabirimi öncelik alır, daha sonra sonucu anlar ve son olarak Unity'nin harmanlamalarını alır. SurfaceType, imlecin yanında metin olarak bildirilir.

Surface türü imlecin yanında etiketlenmiştir
Surface türü imlecin yanında etiketlenmiştir

Topoloji Sorguları

DLL'nin içinde topoloji yöneticisi ortamın etiketlerini işler. Yukarıda belirtildiği gibi, verilerin büyük bir kısmı voksel hacmi içinde yer alan sörfçülerde depolanır. Buna ek olarak, "PlaySpaceInfos" yapısı, dünya hizalaması (aşağıda bununla ilgili daha fazla ayrıntı), zemin ve tavan yüksekliği dahil olmak üzere oyun alanı hakkındaki bilgileri depolamak için kullanılır. Buluşsal yöntemler zemin, tavan ve duvarları belirlemek için kullanılır. Örneğin, 1 m2'den büyük yüzey alanına sahip en büyük ve en düşük yatay yüzey zemin olarak kabul edilir.

Not

Tarama işlemi sırasında kamera yolu da bu işlemde kullanılır.

Topoloji yöneticisi tarafından kullanıma sunulan sorguların bir alt kümesi dll aracılığıyla kullanıma sunulur. Kullanıma sunulan topoloji sorguları aşağıdaki gibidir.

QueryTopology_FindPositionsOnWalls
QueryTopology_FindLargePositionsOnWalls
QueryTopology_FindLargestWall
QueryTopology_FindPositionsOnFloor
QueryTopology_FindLargestPositionsOnFloor
QueryTopology_FindPositionsSittable

Sorguların her biri, sorgu türüne özgü bir parametre kümesine sahiptir. Aşağıdaki örnekte, kullanıcı istenen hacmin minimum yükseklik & genişliğini, zeminin üzerindeki minimum yerleştirme yüksekliğini ve birimin önündeki minimum izin miktarını belirtir. Tüm ölçümler metre şeklindedir.

EXTERN_C __declspec(dllexport) int QueryTopology_FindPositionsOnWalls(
    _In_ float minHeightOfWallSpace,
    _In_ float minWidthOfWallSpace,
    _In_ float minHeightAboveFloor,
    _In_ float minFacingClearance,
    _In_ int locationCount,
    _Inout_ Dll_Interface::TopologyResult* locationData)

Bu sorguların her biri önceden ayrılmış bir "TopologyResult" yapı dizisi alır. "locationCount" parametresi, dizide geçirilen uzunluğu belirtir. Dönüş değeri, döndürülen konumların sayısını bildirir. Bu sayı hiçbir zaman "locationCount" parametresinde geçirilenden büyük değildir.

"TopologyResult" döndürülen birimin merkez konumunu, bakan yönü (normal) ve bulunan alanın boyutlarını içerir.

struct TopologyResult
{
    DirectX::XMFLOAT3 position;
    DirectX::XMFLOAT3 normal;
    float width;
    float length;
};

Not

Unity örneğinde, bu sorguların her biri sanal kullanıcı arabirimi panelindeki bir düğmeye bağlanır. Örnek, bu sorguların her birinin parametrelerini makul değerlere kodlar. Daha fazla örnek için örnek koddaki SpaceVisualizer.cs dosyasına bakın.

Şekil Sorguları

Dll'de, şekil çözümleyicisi ("ShapeAnalyzer_W") topoloji çözümleyicisini kullanarak kullanıcı tarafından tanımlanan özel şekillerle eşleşir. Unity örneği bir şekil kümesi tanımlar ve sonuçları, şekil sekmesinin içindeki uygulama içi sorgu menüsünden kullanıma sunar. Amaç, kullanıcının kendi nesne şekli sorgularını tanımlayabilmesi ve bunları kendi uygulaması için gerekli olduğu şekilde kullanabilmesidir.

Şekil analizi yalnızca yatay yüzeylerde çalışır. Örneğin, bir kanepe, düz koltuk yüzeyi ve kanepenin arkasının düz üst kısmı ile tanımlanır. Şekil sorgusu, belirli bir boyut, yükseklik ve en boy aralığındaki iki yüzeyi arar ve iki yüzeyi hizalanır ve bağlanır. API terminolojisini kullanarak koltuk koltuğu ve arka üst şekil bileşenleri, hizalama gereksinimleri ise şekil bileşeni kısıtlamalarıdır.

Unity örneğinde (ShapeDefinition.cs) "sittable" nesneleri için tanımlanan örnek sorgu aşağıdaki gibidir.

shapeComponents = new List<ShapeComponent>()
{
    new ShapeComponent(
        new List<ShapeComponentConstraint>()
        {
            ShapeComponentConstraint.Create_SurfaceHeight_Between(0.2f, 0.6f),
            ShapeComponentConstraint.Create_SurfaceCount_Min(1),
            ShapeComponentConstraint.Create_SurfaceArea_Min(0.035f),
        }
    ),
};
AddShape("Sittable", shapeComponents);

Her şekil sorgusu, her biri bileşen kısıtlamaları kümesine ve bileşenler arasındaki bağımlılıkları listeleyen bir şekil kısıtlamaları kümesine sahip bir şekil bileşenleri kümesi tarafından tanımlanır. Bu örnek, tek bir bileşen tanımında üç kısıtlama içerir ve bileşenler arasında şekil kısıtlaması yoktur (tek bir bileşen olduğu için).

Buna karşılık, kanepe şeklinin iki şekil bileşeni ve dört şekil kısıtlaması vardır. Bileşenler, kullanıcının bileşen listesindeki dizinlerine göre tanımlanır (bu örnekte 0 ve 1).

shapeConstraints = new List<ShapeConstraint>()
{
    ShapeConstraint.Create_RectanglesSameLength(0, 1, 0.6f),
    ShapeConstraint.Create_RectanglesParallel(0, 1),
    ShapeConstraint.Create_RectanglesAligned(0, 1, 0.3f),
    ShapeConstraint.Create_AtBackOf(1, 0),
};

Sarmalayıcı işlevleri, özel şekil tanımlarının kolayca oluşturulması için Unity modülünde sağlanır. Bileşen ve şekil kısıtlamalarının tam listesi "SpatialUnderstandingDll.cs" içinde "ShapeComponentConstraint" ve "ShapeConstraint" yapılarında bulunabilir.

Dikdörtgen şekli bu yüzeyde bulunur
Dikdörtgen şekli bu yüzeyde bulunur

Nesne Yerleştirme Çözücü

Nesne yerleştirme çözücü, fiziksel odada nesnelerinizi yerleştirmek için ideal konumları belirlemek için kullanılabilir. Çözücü, nesne kuralları ve kısıtlamalarına göre en uygun konumu bulur. Buna ek olarak, nesne "Solver_RemoveObject" veya "Solver_RemoveAllObjects" çağrılarıyla kaldırılana kadar nesne sorguları devam eder ve kısıtlanmış çok nesneli yerleştirmeye izin verir. Nesne yerleştirme sorguları üç bölümden oluşur: parametrelerle yerleştirme türü, kurallar listesi ve kısıtlamaların listesi. Sorgu çalıştırmak için aşağıdaki API'yi kullanın.

public static int Solver_PlaceObject(
            [In] string objectName,
            [In] IntPtr placementDefinition,        // ObjectPlacementDefinition
            [In] int placementRuleCount,
            [In] IntPtr placementRules,             // ObjectPlacementRule
            [In] int constraintCount,
            [In] IntPtr placementConstraints,       // ObjectPlacementConstraint
            [Out] IntPtr placementResult)

Bu işlev bir nesne adı, yerleştirme tanımı ve kural ve kısıtlamaların listesini alır. C# sarmalayıcıları, kural ve kısıtlama oluşturma işlemini kolaylaştırmak için yapı yardımcı işlevleri sağlar. Yerleştirme tanımı aşağıdakilerden biri olan sorgu türünü içerir.

public enum PlacementType
{
    Place_OnFloor,
    Place_OnWall,
    Place_OnCeiling,
    Place_OnShape,
    Place_OnEdge,
    Place_OnFloorAndCeiling,
    Place_RandomInAir,
    Place_InMidAir,
    Place_UnderFurnitureEdge,
};

Yerleştirme türlerinin her biri, türüne özgü bir parametre kümesine sahiptir. "ObjectPlacementDefinition" yapısı, bu tanımları oluşturmak için bir dizi statik yardımcı işlev içerir. Örneğin, bir nesneyi yere koyabileceğiniz bir yer bulmak için aşağıdaki işlevi kullanabilirsiniz. public static ObjectPlacementDefinition Create_OnFloor(Vector3 halfDims) Yerleştirme türüne ek olarak, bir dizi kural ve kısıtlama sağlayabilirsiniz. Kurallar ihlal edilemez. Türü ve kuralları karşılayan olası yerleştirme konumları daha sonra en uygun yerleştirme konumunu seçmek için kısıtlamalar kümesine göre iyileştirilir. Kuralların ve kısıtlamaların her biri, sağlanan statik oluşturma işlevleri tarafından oluşturulabilir. Aşağıda örnek bir kural ve kısıtlama oluşturma işlevi verilmiştir.

public static ObjectPlacementRule Create_AwayFromPosition(
    Vector3 position, float minDistance)
public static ObjectPlacementConstraint Create_NearPoint(
    Vector3 position, float minDistance = 0.0f, float maxDistance = 0.0f)

Aşağıdaki nesne yerleştirme sorgusu, yarım metre küpü bir yüzeyin kenarına, daha önce yerleştirilen diğer nesnelerden uzağa ve odanın merkezine yakın bir yere yerleştirmek için bir yer arar.

List<ObjectPlacementRule> rules =
    new List<ObjectPlacementRule>() {
        ObjectPlacementRule.Create_AwayFromOtherObjects(1.0f),
    };

List<ObjectPlacementConstraint> constraints =
    new List<ObjectPlacementConstraint> {
        ObjectPlacementConstraint.Create_NearCenter(),
    };

Solver_PlaceObject(
    “MyCustomObject”,
    new ObjectPlacementDefinition.Create_OnEdge(
        new Vector3(0.25f, 0.25f, 0.25f),
        new Vector3(0.25f, 0.25f, 0.25f)),
    rules.Count,
    UnderstandingDLL.PinObject(rules.ToArray()),
    constraints.Count,
    UnderstandingDLL.PinObject(constraints.ToArray()),
    UnderstandingDLL.GetStaticObjectPlacementResultPtr());

Başarılı olursa yerleştirme konumunu, boyutlarını ve yönlendirmesini içeren bir "ObjectPlacementResult" yapısı döndürülür. Buna ek olarak, yerleştirme dll'nin yerleştirilen nesneler iç listesine eklenir. Sonraki yerleştirme sorguları bu nesneyi hesaba katacaktır. Unity örneğindeki "LevelSolver.cs" dosyası daha fazla örnek sorgu içerir.

Nesne yerleştirme sonuçları
Şekil 3: Mavi kutular, zemindeki üç yerden elde edilen sonucun kamera konumu kurallarından uzakta sorgular oluşturması

Bir düzey veya uygulama senaryosu için gereken birden çok nesnenin yerleştirme konumunu çözerken, bir alanın bulunma olasılığını en üst düzeye çıkarmak için önce vazgeçilmez ve büyük nesneleri çözün. Yerleştirme sırası önemlidir. Nesne yerleştirmeleri bulunamazsa daha az kısıtlanmış yapılandırmaları deneyin. Bir dizi geri dönüş yapılandırmasına sahip olmak, birçok oda yapılandırmasında işlevselliği desteklemek için kritik öneme sahiptir.

Oda Tarama İşlemi

HoloLens tarafından sağlanan uzamsal haritalama çözümü, sorun alanlarının tamamının ihtiyaçlarını karşılayacak kadar genel olacak şekilde tasarlanmış olsa da uzamsal anlama modülü, belirli iki oyunun ihtiyaçlarını destekleyecek şekilde oluşturulmuştu. Çözümü, aşağıda özetlenen belirli bir süreç ve varsayımlar kümesi etrafında yapılandırılmıştır.

Fixed size playspace – The user specifies the maximum playspace size in the init call.

One-time scan process –
    The process requires a discrete scanning phase where the user walks around,
    defining the playspace.
    Query functions will not function until after the scan has been finalized.

Kullanıcı odaklı oyun alanı "boyama" – Tarama aşamasında, kullanıcı oyun hızını hareket eder ve etrafa bakar, alanları etkili bir şekilde boyar ve bu da dahil edilmelidir. Oluşturulan mesh, bu aşamada kullanıcı geri bildirimi sağlamak için önemlidir. İç mekan ev veya ofis kurulumu – Sorgu işlevleri düz yüzeylerin ve duvarların çevresinde dik açılarda tasarlanmıştır. Bu geçici bir sınırlamadır. Ancak tarama aşamasında ana ve küçük eksenler boyunca mesh tessellation'ı iyileştirmek için bir birincil eksen analizi tamamlanır. Eklenen SpatialUnderstanding.cs dosyası tarama aşaması işlemini yönetir. Aşağıdaki işlevleri çağırır.

SpatialUnderstanding_Init – Called once at the start.

GeneratePlayspace_InitScan – Indicates that the scan phase should begin.

GeneratePlayspace_UpdateScan_DynamicScan –
    Called each frame to update the scanning process. The camera position and
    orientation is passed in and is used for the playspace painting process,
    described above.

GeneratePlayspace_RequestFinish –
    Called to finalize the playspace. This will use the areas “painted” during
    the scan phase to define and lock the playspace. The application can query
    statistics during the scanning phase as well as query the custom mesh for
    providing user feedback.

Import_UnderstandingMesh –
    During scanning, the “SpatialUnderstandingCustomMesh” behavior provided by
    the module and placed on the understanding prefab will periodically query the
    custom mesh generated by the process. In addition, this is done once more
    after scanning has been finalized.

"SpatialUnderstanding" davranışı tarafından yönlendiren tarama akışı InitScan'ı ve ardından UpdateScan'ı her kareye çağırır. İstatistik sorgusu makul kapsamı raporladığında, tarama aşamasının sonunu belirtmek için kullanıcının RequestFinish çağrısı yapmak için airtap'a izin verilir. Dönüş değeri dll dosyasının işlenmesinin tamamlandığını gösterene kadar UpdateScan çağrılmaya devam eder.

Mesh'i anlama

Understanding dll, oyun alanını 8 cm boyutlu voksel küplerinden oluşan bir kılavuz olarak dahili olarak depolar. Taramanın ilk bölümünde, odanın eksenlerini belirlemek için birincil bileşen analizi tamamlanır. Dahili olarak, voksel alanını bu eksenlere hizalanmış olarak depolar. Voksel hacminden izosurface ayıklanarak yaklaşık olarak her saniyede bir mesh oluşturulur.

Voxel hacminden üretilen mesh
Voxel hacminden üretilen mesh

Sorun giderme

  • SpatialPerception özelliğini ayarladığınızdan emin olun
  • İzleme kaybolduğunda, sonraki OnSurfaceChanged olayı tüm tireleri kaldırır.

Karma Gerçeklik Araç Seti'nde Uzamsal Eşleme

Karma Gerçeklik Toolkit ile Uzamsal Eşleme'yi kullanma hakkında daha fazla bilgi için MRTK belgelerinin uzamsal farkındalık bölümüne bakın.

Sonraki Geliştirme Denetim Noktası

Ortaya koyduğumuz Unity geliştirme yolculuğunu takip ediyorsanız MRTK temel yapı taşları keşfetmenin tam ortasındasınız demektir. Buradan sonraki yapı taşıyla devam edebilirsiniz:

Veya Karma Gerçeklik platform özelliklerine ve API'lerine atlayın:

İstediğiniz zaman Unity geliştirme denetim noktalarına geri dönebilirsiniz.

Ayrıca bkz.