Unity'de uzamsal eşleme
Uzamsal eşleme , HoloLens cihazının etrafındaki dünyadaki yüzeyleri temsil eden üçgen kafesleri almanıza olanak tanır. 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:
- Uzamsal eşlemeye başlamak için kullanışlı ve hızlı bir yol sağlayan MixedRealityToolkit'te bulunan uzamsal eşleme bileşenleri
- 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:
- Unity Düzenleyicisi'nde "Player Ayarları" bölmesini açın (Proje Ayarları > Oynatıcısını Düzenle>)
- "Windows Mağazası" sekmesinden seçin
- "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:
- Visual Studio'da, Çözüm Gezgini Package.appxmanifest'e sağ tıklayın ve Kodu Görüntüle'yi seçin
- TargetDeviceFamily değerini belirten satırı bulun ve MaxVersionTested="10.0.10240.0" değerini MaxVersionTested="10.0.10586.0" olarak değiştirin
- 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 kullanmaya başlama 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 anlama sahnesi hakkında bilgi için Sahneyi anlama gözlemci kılavuzuna bakın.
Üst düzey mesh analizi: Uzamsal Anlama
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, uzamsal haritalamanın örgü ve yüzey düzlemlerinin ötesine geçmek genellikle tercih edilir. Yerleştirme 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 göre iyileştirme olanağına da sahipsiniz.
Young Conker ve Fragments'in geliştirilmesi sırasında Asobo Studios, 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ızlı bir şekilde bulmanızı, tavana nesneler yerleştirmenizi, karaktere oturacak şekilde yerleştirilmenizi ve çok sayıda diğer uzamsal anlama sorgularını tanımlamanızı sağlar.
Tüm kaynak kodlar dahil edilir ve bu sayede kodu ihtiyaçlarınıza göre özelleştirebilir ve iyileştirmelerinizi toplulukla paylaşabilirsiniz. C++ çözücü kodu bir UWP dll'sine sarmalanmış ve Unity'ye MixedRealityToolkit içinde bulunan bir bırakma ile 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 arabirimi kullanılabilir ve özel bir su geçirmez 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
İşlev bir ışın alır ve ışın bilinen bir yüzeyle çakışırsa ve öyleyse, bu yüzey hakkındaki bilgiler şeklinde RaycastResult
dö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, playspace'in hesaplanan 8 cm küplü voksel gösterimine göre hesaplanır. Her voksel, işlenmiş topoloji verilerine (yani yüzey yüzeylerine) sahip bir dizi yüzey öğesi içerir. Kesişen voksel hücresinde bulunan yüzeyseller 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 karede bir ışın oluşturur. İlk olarak Unity'nin collider'lerine karşı. İkincisi, modülün dünya temsilini anlama. Son olarak da kullanıcı arabirimi öğeleri. Bu uygulamada kullanıcı arabirimi önceliği alır, daha sonra anlama sonucunu ve son olarak Unity'nin harmanlamalarını alır. SurfaceType, imlecin yanında metin olarak bildirilir.
Surface türü imlecin yanında etiketlenmiştir
Topoloji Sorguları
DLL'nin içinde topoloji yöneticisi ortamın etiketlenmesiyle ilgilenir. Yukarıda belirtildiği gibi, verilerin çoğu bir voxel hacminin içinde yer alan yüzeylerde 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 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 birimin en düşük yüksekliğini ve genişliğini, zeminin üzerinde minimum yerleştirme yüksekliğini ve birimin önündeki minimum boşluk 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, geçirilen dizinin uzunluğunu belirtir. Dönüş değeri, döndürülen konum sayısını bildirir. Bu sayı hiçbir zaman "locationCount" parametresinde geçirilenden büyük değildir.
"TopologyResult", döndürülen birimin orta konumunu, karşılıklı 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 sabit, bu sorguların her biri için parametreleri makul değerlere kodlar. Daha fazla örnek için örnek kodun SpaceVisualizer.cs 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 koltuğun 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üzey hizalanmış ve bağlanmış durumdadır. API terminolojisini kullanarak koltuk koltuğu ve arka üst şekil bileşenleridir ve hizalama gereksinimleri ş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 (çünkü yalnızca bir bileşen vardır).
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 (bu örnekte 0 ve 1) dizinleriyle tanımlanır.
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 "ShapeComponentConstraint" ve "ShapeConstraint" yapıları içinde "SpatialUnderstandingDll.cs" bulunabilir.
Dikdörtgen şekli bu yüzeyde bulunur
Nesne Yerleştirme Çözücü
Nesne yerleştirme çözücü, nesnelerinizi yerleştirmek için fiziksel odadaki ideal konumları belirlemek için kullanılabilir. Çözücü, nesne kuralları ve kısıtlamaları göz önünde bulundurulduğunda en uygun konumu bulur. Buna ek olarak, nesne "Solver_RemoveObject" veya "Solver_RemoveAllObjects" çağrılarıyla kaldırılana kadar nesne sorguları kalıcı olur ve çok nesneli yerleştirme kısıtlanır. Nesne yerleştirme sorguları üç bölümden oluşur: parametrelerle yerleştirme türü, kural 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 yapımını kolaylaştırmak için inşaat 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şturmaya yönelik bir dizi statik yardımcı işlev içerir. Örneğin, bir nesneyi yere yerleştirebileceğ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, önceki diğer yer nesnelerinden uzakta ve odanın merkezine yakın bir yerde yarım metre küpü bir yüzeyin kenarına koyacak bir yer arıyor.
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.
Şekil 3: Mavi kutular, zemin sorgularında üç yerden elde edilen sonucun kamera konumu kurallarından uzak olduğunu gösterir
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 tüm gamının ihtiyaçlarını karşılayacak kadar genel olacak şekilde tasarlanmış olsa da uzamsal anlama modülü, belirli iki oyunun gereksinimlerini destekleyecek şekilde oluşturulmuştu. Çözümü, aşağıda özetlenen belirli bir süreç ve varsayım 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 dahil edilmelidir. Oluşturulan ağ, 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 ikincil eksen boyunca mesh döşemesini 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'ı, ardından UpdateScan'ı her kareyi çağırır. İstatistik sorgusu makul kapsamı bildirdiğinde, tarama aşamasının sonunu belirtmek için kullanıcının RequestFinish çağrısı yapmak için airtap'a izin verilir. UpdateScan, dönüş değeri dll dosyasının işlenmesinin tamamlandığını belirtene kadar çağrılmaya devam eder.
Mesh'i anlama
Anlama dll'i, oyun alanını 8 cm boyutunda voksel küplerden 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 her saniye bir mesh oluşturulur.
Voxel hacminden üretilen mesh
Sorun giderme
- SpatialPerception özelliğini ayarladığınızdan emin olun
- İzleme kaybolduğunda, sonraki OnSurfaceChanged olayı tüm kafesleri kaldırır.
Karma Gerçeklik Araç Seti'nde Uzamsal Eşleme
Karma Gerçeklik Araç Seti ile Uzamsal Eşleme 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ı
Sunduğ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şına devam edebilirsiniz:
İsterseniz Karma Gerçeklik platform özelliklerine ve API'lerine atlayabiliriz:
İstediğiniz zaman Unity geliştirme denetim noktalarına geri dönebilirsiniz.