Az SDK jelenetfelismerési áttekintése

A jelenetfelismerés átalakítja a Mixed Reality eszköz által rögzített strukturálatlan környezeti érzékelőadatokat, és hatékony absztrakt ábrázolássá alakítja őket. Az SDK kommunikációs rétegként működik az alkalmazás és a Scene Understanding futtatókörnyezet között. Célja a meglévő szabványos szerkezetek utánzata, például a térhatású ábrázolások 3D-jelenetdiagramjai, valamint a 2D-s alkalmazások 2D-s téglalapjai és paneljei. Bár a Scene Understanding mimics szerkezetek konkrét keretrendszerekre lesznek leképezve, a SceneUnderstanding általában keretrendszer-agnosztikát jelent, amely lehetővé teszi az együttműködést a vele együttműködő különböző keretrendszerek között. A Scene Understanding fejlődésével az SDK szerepe annak biztosítása, hogy az új reprezentációk és képességek továbbra is egységes keretrendszerben legyenek közzétéve. Ebben a dokumentumban először olyan magas szintű fogalmakat mutatunk be, amelyek segítenek megismerkedni a fejlesztési környezettel/használattal, majd részletesebb dokumentációt nyújtunk bizonyos osztályokhoz és szerkezetekhez.

Hol szerezhetem be az SDK-t?

A SceneUnderstanding SDK a Mixed Reality funkcióeszközön keresztül tölthető le.

Megjegyzés: a legújabb kiadás az előzetes csomagoktól függ, és engedélyeznie kell a kiadás előtti csomagokat a megtekintéséhez.

A 0.5.2022-rc és újabb verziók esetében a Scene Understanding támogatja a C# és a C++ nyelvi kivetítéseit, amelyek lehetővé teszik az alkalmazások számára, hogy alkalmazásokat fejlesszenek Win32- vagy UWP-platformokhoz. Ebben a verzióban a SceneUnderstanding támogatja a Unity szerkesztőn belüli támogatását, amely kizárja a SceneObservert, amelyet kizárólag a HoloLens2-vel való kommunikációhoz használnak.

A SceneUnderstanding használatához a Windows SDK 18362-es vagy újabb verziója szükséges.

Fogalmi áttekintés

A jelenet

A vegyes valóságú eszköz folyamatosan integrál információkat arról, hogy mit lát a környezetben. A Scene Understanding ezen adatforrások mindegyikét tölcsérként értelmezi, és egyetlen egységes absztrakciót hoz létre. A Scene Understanding jeleneteket hoz létre, amelyek a SceneObjects olyan kompozíciói, amelyek egyetlen dolog egy példányát képviselik (például fal/mennyezet/padló).) A Jelenetobjektumok maguk a [SceneComponents] kompozíciói, amelyek részletesebb darabokat jelölnek, amelyek alkotják ezt a SceneObjectet. Az összetevők közé tartoznak például a quadok és a hálók, de a jövőben határolókereteket, ütközési hálókat, metaadatokat stb. jelenthetnek.

A nyers érzékelőadatok jelenetté alakításának folyamata egy potenciálisan költséges művelet, amely a közepes (~10x10 m) helyeken másodpercekig is eltarthat nagy (~50x50m) helyek esetén, ezért az eszköz alkalmazáskérés nélkül nem számítja ki. Ehelyett a jelenetgenerálást az alkalmazás aktiválja igény szerint. A SceneObserver osztály statikus metódusokkal rendelkezik, amelyekkel kiszámíthat vagy deszerializálhat egy jelenetet, amelyekkel aztán számba vehet/használhat. A "Compute" műveletet igény szerint hajtja végre a rendszer, és a processzoron, de egy külön folyamatban (az Mixed Reality illesztőprogramban) hajtja végre. Ha azonban egy másik folyamat során végezünk számítást, az eredményként kapott jelenetadatok tárolása és karbantartása az alkalmazásban a Scene objektumban történik.

Az alábbiakban egy diagram szemlélteti ezt a folyamatot, és példákat mutat be két alkalmazásra, amelyek a Scene Understanding futtatókörnyezettel működnek együtt.

Folyamatábra

A bal oldalon a vegyes valóság futtatókörnyezetének diagramja látható, amely mindig a saját folyamatában fut. Ez a futtatókörnyezet felel az eszközkövetésért, a térbeli leképezésért és más műveletekért, amelyeket a Scene Understanding a körülöttünk lévő világ megértésére és okára használ. A diagram jobb oldalán két elméleti alkalmazást mutatunk be, amelyek a Jelenetfelismerést használják. Az első alkalmazás az MRTK-val rendelkezik, amely belsőleg használja a Scene Understanding SDK-t, a második alkalmazás pedig két különálló jelenetpéldányt használ. A diagram mindhárom jelenete külön példányokat hoz létre a jelenetekből, az illesztőprogram nem követi nyomon az alkalmazások és a jelenetobjektumok között megosztott globális állapotot az egyik jelenetben, a másikban nem található. A Scene Understanding lehetővé teszi az idő múlásával történő nyomon követés mechanizmusát, de ez az SDK használatával történik. A nyomkövetési kód már fut az SDK-ban az alkalmazás folyamatában.

Mivel minden jelenet az alkalmazás memóriaterületén tárolja az adatait, feltételezheti, hogy a Jelenet objektum vagy belső adatainak összes függvénye mindig az alkalmazás folyamatában lesz végrehajtva.

Layout

A Scene Understanding használatához hasznos lehet tudni és megérteni, hogy a futtatókörnyezet hogyan képviseli az összetevőket logikailag és fizikailag. A Jelenet egy adott elrendezésű adatokat jelöl, amelyek egyszerűnek választották, miközben olyan mögöttes struktúrát tartanak fenn, amely várhatóan megfelel a jövőbeli követelményeknek anélkül, hogy nagyobb változatokra lenne szükség. A jelenet ezt úgy teszi meg, hogy az összes összetevőt (az összes jelenetobjektum építőelemeit) egy egyszerű listában tárolja, és hierarchiát és kompozíciót határoz meg olyan hivatkozásokon keresztül, amelyekben bizonyos összetevők hivatkoznak másokra.

Az alábbiakban egy példát mutatunk be egy szerkezetre a lapos és a logikai formájában is.

Logikai elrendezésFizikai elrendezés
    Jelenet
    • SceneObject_1
      • SceneMesh_1
      • SceneQuad_1
      • SceneQuad_2
    • SceneObject_2
      • SceneQuad_1
      • SceneQuad_3
    • SceneObject_3
      • SceneMesh_3
  • SceneObject_1
  • SceneObject_2
  • SceneObject_3
  • SceneQuad_1
  • SceneQuad_2
  • SceneQuad_3
  • SceneMesh_1
  • SceneMesh_2

Ez az ábra a Jelenet fizikai és logikai elrendezése közötti különbséget mutatja be. A bal oldalon az alkalmazás által a jelenet számbavételekor látható adatok hierarchikus elrendezése látható. A jobb oldalon látható, hogy a jelenet 12 különböző összetevőből áll, amelyek szükség esetén egyenként érhetők el. Új jelenet feldolgozásakor elvárjuk, hogy az alkalmazások logikusan járják végig ezt a hierarchiát, azonban a jelenetfrissítések közötti nyomon követés során egyes alkalmazások csak a két jelenet között megosztott bizonyos összetevőket célozhatják meg.

Az API áttekintése

Az alábbi szakasz magas szintű áttekintést nyújt a Scene Understanding szerkezetéről. Ebből a szakaszból megtudhatja, hogyan jelennek meg a jelenetek, és hogy mire használják a különböző összetevőket. A következő szakaszban konkrét kód példákat és további részleteket mutatunk be, amelyeket ebben az áttekintésben ismertetünk.

Az alább leírt összes típus a Microsoft.MixedReality.SceneUnderstanding névtérben található.

SceneComponents

Most, hogy megismerte a jelenetek logikai elrendezését, bemutathatjuk a SceneComponents fogalmát és a hierarchia összeállításához való használatuk módját. A SceneComponents a SceneUnderstanding legrészletesebb felbontása, amely egyetlen alapvető dolgot, például hálót, quadot vagy határolókeretet jelöl. A SceneComponents olyan dolgok, amelyek egymástól függetlenül frissíthetők, és más SceneComponent-ek hivatkozhatnak rájuk, ezért egyetlen globális tulajdonságuk van, egy egyedi azonosítójuk, amely lehetővé teszi az ilyen típusú nyomkövetési/hivatkozási mechanizmust. Az azonosítókat a jelenethierarchia logikai összetételére és az objektummegőrzésre (az egyik jelenet egy másikhoz viszonyított frissítésére) használják.

Ha minden újonnan kiszámított jelenetet különállóként kezel, és egyszerűen az összes adat számbavételét teszi lehetővé, akkor az azonosítók nagyrészt átláthatóak. Ha azonban több frissítésen keresztül szeretné nyomon követni az összetevőket, az azonosítókkal indexelheti és megkeresheti a Jelenetobjektumok között található SceneComponents objektumokat.

SceneObjects

A SceneObject egy SceneComponent, amely egy "dolog" egy példányát jelöli, például egy falat, egy padlót, egy mennyezetet stb.... a Kind tulajdonságuk alapján kifejezve. A SceneObjects geometriai, ezért olyan függvényekkel és tulajdonságokkal rendelkezik, amelyek helyüket a térben jelölik, de nem tartalmaznak geometriai vagy logikai szerkezetet. Ehelyett a SceneObjects más SceneComponentekre, különösen a SceneQuadsra és a SceneMeshesre hivatkozik, amelyek a rendszer által támogatott változatos ábrázolásokat biztosítják. Új jelenet kiszámításakor az alkalmazás nagy valószínűséggel számba veszi a Jelenet jeleneteObjects függvényt, hogy feldolgozhassa, ami érdekli.

A SceneObjects az alábbiak bármelyikével rendelkezhet:

SceneObjectKind Description
HáttérA SceneObject ismert, hogy nem tartozik a többi felismert jelenetobjektum közé. Ezt az osztályt nem szabad összekeverni az Ismeretlennel, ahol a háttér ismert, hogy nem fal/padló/mennyezet stb.... míg az ismeretlen még nincs kategorizálva.
FalEgy fizikai fal. A falak a feltételezések szerint ingó környezeti struktúrák.
FloorA padlók olyan felületek, amelyeken lehet járni. Megjegyzés: a lépcsők nem padlók. Azt is vegye figyelembe, hogy a padlók bármilyen járható felületet feltételeznek, ezért nincs explicit feltételezés a különálló padlóról. Többszintű struktúrák, rámpák stb. az összesnek padlónak kell besorolnia.
CeilingA szoba felső felülete.
PlatformEgy nagy lapos felület, amelyen hologramokat helyezhet el. Ezek általában táblákat, munkalapokat és más nagy vízszintes felületeket jelölnek.
VilágA geometriai adatok számára fenntartott címke, amely a címkézéshez agnosztikus. Az EnableWorldMesh frissítési jelző beállításával létrehozott háló világként lesz besorolva.
IsmeretlenEzt a jelenetobjektumot még nem sorolták be, és hozzárendelték egy fajtához. Ezt nem szabad összekeverni a háttérrel, mivel ez az objektum bármi lehet, a rendszer még nem hozott létre elég erős besorolást.

SceneMesh

A SceneMesh egy SceneComponent, amely egy háromszöglistával közelíti meg tetszőleges geometriai objektumok geometriáját. A SceneMeshes számos különböző környezetben használatos; a vízmentes cellaszerkezet összetevőit vagy a WorldMesh-et jelölhetik, amely a Jelenethez társított kötetlen térbeli leképezési hálót jelöli. Az egyes hálókhoz biztosított index- és csúcspontadatok ugyanazt a jól ismert elrendezést használják, mint a csúcspont és az indexpufferek , amelyek a háromszöghálók renderelésére szolgálnak az összes modern renderelési API-ban. A Scene Understandingben a hálók 32 bites indexeket használnak, és előfordulhat, hogy egyes renderelőmotorokhoz darabokat kell bontani.

Tekercselési sorrend és koordinátarendszerek

A Scene Understanding által előállított összes hálónak az óramutató járásával megegyező irányban kell visszaadnia a hálókat egy Right-Handed koordinátarendszerben.

Megjegyzés: A .191105 előtti operációsrendszer-buildek ismert hibát okozhatnak, amikor a "World" hálók Counter-Clockwise tekercselési sorrendben térnek vissza, amelyet később kijavítottak.

SceneQuad

A SceneQuad egy SceneComponent, amely 2d felületeket jelöl, amelyek elfoglalják a 3D világot. A SceneQuads ugyanúgy használható, mint az ARKit ARPlaneAnchor vagy az ARCore Planes, de magasabb szintű funkciókat kínálnak 2d vászonként, amelyeket lapos alkalmazások vagy kibővített UX-k használhatnak. A 2D specifikus API-k olyan quadokhoz érhetők el, amelyek egyszerűvé teszik az elhelyezést és az elrendezést, és a quadokkal való fejlesztés (a renderelés kivételével) jobban hasonlít a 2d vászonokra, mint a 3d hálókra.

SceneQuad alakzat

A SceneQuads egy 2d-ben megadott téglalap alakú, határolókeretes felületet határoz meg. A SceneQuads azonban tetszőleges és esetleg összetett alakzatokkal (például fánk alakú táblázattal) rendelkező felületeket jelöl. A quadok felületének összetett alakját a GetSurfaceMask API-val jelenítheti meg egy ön által megadott képpufferbe. Ha a quadot tartalmazó SceneObject is rendelkezik hálóval, a háló háromszögeinek egyenértékűnek kell lenniük ezzel a renderelt képpel, mindkettő a felület valós geometriája, akár 2d, akár 3d koordinátákban.

Jelenet az SDK részleteinek és hivatkozásainak ismertetése

Megjegyzés

AZ MRTK használatakor kérjük, vegye figyelembe, hogy az MRTK -t a "WindowsSceneUnderstandingObserver"(xref:Microsoft.MixedReality.Toolkit.WindowsSceneUnderstanding.Experimental.WindowsSceneUnderstandingObserver?view=mixed-reality-toolkit-unity-2020-dotnet-2.8.0&preserve-view=true) használja, így a legtöbb esetben kihagyhatja ezt a szakaszt. További információt az [MRTK Scene Understanding docs](/windows/mixed-reality/mrtk-unity/features/spatial-awareness/scene-understanding) című cikkben talál.

Az alábbi szakasz segít megismerni a SceneUnderstanding alapjait. Ennek a szakasznak meg kell adnia az alapokat, ahol elegendő környezettel kell rendelkeznie ahhoz, hogy végigböngészhesse a mintaalkalmazásokat, hogy lássa, hogyan használják holisztikusan a SceneUnderstandingot.

Inicializálás

A SceneUnderstanding használatának első lépése az, hogy az alkalmazás hivatkozni szeretne egy Jelenet objektumra. Ez kétféleképpen végezhető el, a jelenetet vagy az illesztőprogram számítja ki, vagy a korábban kiszámított meglévő jelenetet lehet szerializálni. Ez utóbbi hasznos a SceneUnderstanding használatához a fejlesztés során, ahol az alkalmazások és a tapasztalatok gyorsan prototípusíthatók vegyes valóságú eszköz nélkül.

A jelenetek a SceneObserver használatával vannak kiszámítva. Jelenet létrehozása előtt az alkalmazásnak le kell kérdeznie az eszközét, hogy biztosan támogatja-e a SceneUnderstanding használatát, valamint hogy felhasználói hozzáférést kérjen a SceneUnderstanding által igényelt információkhoz.

if (!SceneObserver.IsSupported())
{
    // Handle the error
}

// This call should grant the access we need.
await SceneObserver.RequestAccessAsync();

Ha a RequestAccessAsync() nincs meghívva, az új jelenet számítása sikertelen lesz. Ezután egy új jelenetet fogunk kiszámolni, amely a Mixed Reality headset körül gyökerezik, és 10 méteres sugarú.

// Create Query settings for the scene update
SceneQuerySettings querySettings;

querySettings.EnableSceneObjectQuads = true;                                       // Requests that the scene updates quads.
querySettings.EnableSceneObjectMeshes = true;                                      // Requests that the scene updates watertight mesh data.
querySettings.EnableOnlyObservedSceneObjects = false;                              // Do not explicitly turn off quad inference.
querySettings.EnableWorldMesh = true;                                              // Requests a static version of the spatial mapping mesh.
querySettings.RequestedMeshLevelOfDetail = SceneMeshLevelOfDetail.Fine;            // Requests the finest LOD of the static spatial mapping mesh.

// Initialize a new Scene
Scene myScene = SceneObserver.ComputeAsync(querySettings, 10.0f).GetAwaiter().GetResult();

Inicializálás adatokból (más néven a PC elérési útja)

Bár a jelenetek közvetlen felhasználás céljából is kiszámolhatók, szerializált formában is kiszámolhatók későbbi használatra. Ez hasznosnak bizonyult a fejlesztéshez, mivel lehetővé teszi a fejlesztők számára, hogy eszköz nélkül dolgoznak és teszteljék a Scene Understandingt. A jelenet szerializálása majdnem megegyezik a számítástechnikával, az adatokat a rendszer visszaadja az alkalmazásnak ahelyett, hogy az SDK helyben deszerializálja őket. Ezután saját maga is deszerializálhatja, vagy mentheti későbbi használatra.

// Create Query settings for the scene update
SceneQuerySettings querySettings;

// Compute a scene but serialized as a byte array
SceneBuffer newSceneBuffer = SceneObserver.ComputeSerializedAsync(querySettings, 10.0f).GetAwaiter().GetResult();

// If we want to use it immediately we can de-serialize the scene ourselves
byte[] newSceneData = new byte[newSceneBuffer.Size];
newSceneBuffer.GetData(newSceneData);
Scene mySceneDeSerialized = Scene.Deserialize(newSceneData);

// Save newSceneData for later

SceneObject Enumerálás

Most, hogy az alkalmazás rendelkezik jelenettel, az alkalmazás a SceneObjectset fogja nézni és használni. Ez a SceneObjects tulajdonság eléréséhez szükséges:

SceneObject firstFloor = null;

// Find the first floor object
foreach (var sceneObject in myScene.SceneObjects)
{
    if (sceneObject.Kind == SceneObjectKind.Floor)
    {
        firstFloor = sceneObject;
        break;
    }
}

Összetevők frissítése és finomítása

Van egy másik függvény, amely lekéri a FindComponent nevű jelenet összetevőit. Ez a függvény akkor hasznos, ha frissíti a nyomkövetési objektumokat, és később megkeresi őket. Az alábbi kód kiszámít egy új jelenetet egy korábbi jelenethez képest, majd megkeresi a padlót az új jelenetben.

// Compute a new scene, and tell the system that we want to compute relative to the previous scene
Scene myNextScene = SceneObserver.ComputeAsync(querySettings, 10.0f, myScene).GetAwaiter().GetResult();

// Use the Id for the floor we found last time, and find it again
firstFloor = (SceneObject)myNextScene.FindComponent(firstFloor.Id);

if (firstFloor != null)
{
    // We found it again, we can now update the transforms of all objects we attached to this floor transform
}

Hálók és quadok elérése jelenetobjektumokból

A SceneObjects megtalálása után az alkalmazás valószínűleg hozzá szeretne férni az abban található quadokban/hálókban található adatokhoz. Ezek az adatok a Quads és a Meshes tulajdonsággal érhetők el. Az alábbi kód számba veszi a padlóobjektum összes quadját és hálóját.


// Get the transform for the SceneObject
System.Numerics.Matrix4x4 objectToSceneOrigin = firstFloor.GetLocationAsMatrix();

// Enumerate quads
foreach (var quad in firstFloor.Quads)
{
    // Process quads
}

// Enumerate meshes
foreach (var mesh in firstFloor.Meshes)
{
    // Process meshes
}

Figyelje meg, hogy a SceneObject a Jelenet forrásához viszonyított átalakítással rendelkezik. Ennek az az oka, hogy a SceneObject egy "dolog" egy példányát jelöli, és a térben, a quadok és a hálók a szülőhöz képest átalakított geometriát jelölnek. Lehetséges, hogy a sceneObjects külön hivatkozik ugyanarra a SceneMesh/SceneQuad SceneComponentsre, és az is lehetséges, hogy a SceneObject több SceneMesh/SceneQuad elemből áll.

Átalakítások kezelése

A Scene Understanding szándékosan megkísérelt igazodni a hagyományos 3D jelenetábrázolásokhoz az átalakítások kezelésekor. Ezért minden jelenet egyetlen koordinátarendszerre korlátozódik, hasonlóan a leggyakoribb 3D környezeti ábrázolásokhoz. A SceneObjects mindegyik a koordinátarendszerhez viszonyítva adja meg a helyét. Ha az alkalmazás olyan jelenetekkel foglalkozik, amelyek az egyetlen forrás által biztosított korlátot nyújtják, akkor a SceneObjectset rögzítheti a SpatialAnchorshoz, vagy létrehozhat több jelenetet, és egyesítheti őket, de az egyszerűség kedvéért feltételezzük, hogy a vízmentes jelenetek a saját forrásukban vannak, amelyet a Scene.OriginSpatialGraphNodeId által meghatározott egyetlen NodeId honosít.

Az alábbi Unity-kód például bemutatja, hogyan lehet a Windows Perception és a Unity API-k használatával összehangolni a koordinátarendszereket. A Unity világának megfelelő SpatialCoordinateSystem és SpatialGraphInteropPreview című témakörben talál részleteket a Windows Perception API-król és a Unity natív objektumainak Mixed Reality.

private System.Numerics.Matrix4x4? GetSceneToUnityTransformAsMatrix4x4(SceneUnderstanding.Scene scene)
{
    System.Numerics.Matrix4x4? sceneToUnityTransform = System.Numerics.Matrix4x4.Identity;

    
    Windows.Perception.Spatial.SpatialCoordinateSystem sceneCoordinateSystem = Microsoft.Windows.Perception.Spatial.Preview.SpatialGraphInteropPreview.CreateCoordinateSystemForNode(scene.OriginSpatialGraphNodeId);
    Windows.Perception.Spatial.SpatialCoordinateSystem unityCoordinateSystem = Microsoft.Windows.Perception.Spatial.SpatialCoordinateSystem.FromNativePtr(UnityEngine.XR.WindowsMR.WindowsMREnvironment.OriginSpatialCoordinateSystem);

    sceneToUnityTransform = sceneCoordinateSystem.TryGetTransformTo(unityCoordinateSystem);

    if (sceneToUnityTransform != null)
    {
        sceneToUnityTransform = ConvertRightHandedMatrix4x4ToLeftHanded(sceneToUnityTransform.Value);
    }
    else
    {
        return null;
    }
            
    return sceneToUnityTransform;
}

Mindegyiknek SceneObject van egy átalakítója, amelyet aztán az objektumra alkalmaz. A Unityben jobbkezes koordinátákká alakítjuk át a helyi átalakításokat a következőképpen:

private System.Numerics.Matrix4x4 ConvertRightHandedMatrix4x4ToLeftHanded(System.Numerics.Matrix4x4 matrix)
{
    matrix.M13 = -matrix.M13;
    matrix.M23 = -matrix.M23;
    matrix.M43 = -matrix.M43;

    matrix.M31 = -matrix.M31;
    matrix.M32 = -matrix.M32;
    matrix.M34 = -matrix.M34;

    return matrix;
}

 private void SetUnityTransformFromMatrix4x4(Transform targetTransform, System.Numerics.Matrix4x4 matrix, bool updateLocalTransformOnly = false)
 {
    if(targetTransform == null)
    {
        return;
    }

    Vector3 unityTranslation;
    Quaternion unityQuat;
    Vector3 unityScale;

    System.Numerics.Vector3 vector3;
    System.Numerics.Quaternion quaternion;
    System.Numerics.Vector3 scale;

    System.Numerics.Matrix4x4.Decompose(matrix, out scale, out quaternion, out vector3);

    unityTranslation = new Vector3(vector3.X, vector3.Y, vector3.Z);
    unityQuat        = new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
    unityScale       = new Vector3(scale.X, scale.Y, scale.Z);

    if(updateLocalTransformOnly)
    {
        targetTransform.localPosition = unityTranslation;
        targetTransform.localRotation = unityQuat;
    }
    else
    {
        targetTransform.SetPositionAndRotation(unityTranslation, unityQuat);
    }
}

// Assume we have an SU object called suObject and a unity equivalent unityObject

System.Numerics.Matrix4x4 converted4x4LocationMatrix = ConvertRightHandedMatrix4x4ToLeftHanded(suObject.GetLocationAsMatrix());
SetUnityTransformFromMatrix4x4(unityObject.transform, converted4x4LocationMatrix, true);
        

Quad

A quadokat úgy tervezték, hogy segítsenek a 2D elhelyezési forgatókönyvekben, és úgy kell tekinteni, mint a 2D vászon UX-elemek bővítményei. Míg a quadok a SceneObjects összetevői, és 3D-ben renderelhetők, a Quad API-k maguk feltételezik, hogy a Quadok 2D struktúrák. Olyan információkat kínálnak, mint a mérték, az alakzat, és API-kat biztosítanak az elhelyezéshez.

A quadok téglalap alakúak, de tetszőlegesen formázott 2D felületeket jelölnek. A 3D környezet quadjaival interakcióba lépő 2D felületeken való elhelyezés engedélyezéséhez segédprogramok biztosítják ezt az interakciót. A Scene Understanding jelenleg két ilyen funkciót biztosít: a FindCentermostPlacement és a GetSurfaceMask. A FindCentermostPlacement egy magas szintű API, amely egy helyet keres a quadon, ahol elhelyezhető egy objektum, és megpróbálja megtalálni az objektum legjobb helyét, garantálva, hogy a megadott határolókeret a mögöttes felületen marad.

Megjegyzés

A kimenet koordinátái a "quad térbeli" quadhoz viszonyítva jelennek meg, a bal felső sarokban pedig (x = 0, y = 0), ahogyan a többi Windows Rect típus esetében is. Ezt mindenképpen vegye figyelembe a saját objektumok eredetének használatakor.

Az alábbi példa bemutatja, hogyan keresheti meg a legpontozhatóbb helyet, és hogyan rögzíthet hologramot a quadhoz.

// This code assumes you already have a "Root" object that attaches the Scene's Origin.

// Find the first quad
foreach (var sceneObject in myScene.SceneObjects)
{
    // Find a wall
    if (sceneObject.Kind == SceneObjectKind.Wall)
    {
        // Get the quad
        var quads = sceneObject.Quads;
        if (quads.Count > 0)
        {
            // Find a good location for a 1mx1m object  
            System.Numerics.Vector2 location;
            if (quads[0].FindCentermostPlacement(new System.Numerics.Vector2(1.0f, 1.0f), out location))
            {
                // We found one, anchor something to the transform
                // Step 1: Create a new game object for the quad itself as a child of the scene root
                // Step 2: Set the local transform from quads[0].Position and quads[0].Orientation
                // Step 3: Create your hologram and set it as a child of the quad's game object
                // Step 4: Set the hologram's local transform to a translation (location.x, location.y, 0)
            }
        }
    }
}

Az 1–4. lépés nagymértékben függ az adott keretrendszertől/megvalósítástól, de a témáknak hasonlónak kell lenniük. Fontos megjegyezni, hogy a Quad egyszerűen egy térben honosított, határolt 2D síkot jelöl. Ha tudatja a motorral/keretrendszerrel, hogy hol van a quad, és a quadhoz képest gyökerezteti az objektumokat, a hologramok helyesen lesznek elhelyezve a valós világhoz képest.

Teljes

A hálók objektumok vagy környezetek geometriai ábrázolását jelölik. A térbeli leképezéshez hasonlóan az egyes térbeli felületi hálókhoz biztosított hálóindex és csúcspontadatok is ugyanazt a jól ismert elrendezést használják, mint a csúcspont és az indexpufferek, amelyeket a háromszöghálók megjelenítéséhez használnak az összes modern renderelési API-ban. A csúcspontok helye a koordinátarendszerben van megadva.Scene Az adatokra való hivatkozáshoz használt api-k a következők:

void GetTriangleIndices(int[] indices);
void GetVertices(System.Numerics.Vector3[] vertices);

Az alábbi kód egy példa egy háromszöglista létrehozására a hálószerkezetből:

uint[] indices = new uint[mesh.TriangleIndexCount];
System.Numerics.Vector3[] positions = new System.Numerics.Vector3[mesh.VertexCount];

mesh.GetTriangleIndices(indices);
mesh.GetVertexPositions(positions);

Az index-/csúcspontpuffereknek = az index/csúcspontok számának kell lenniük >, de máskülönben tetszőlegesen méretezhetők, ami lehetővé teszi a memória hatékony újrafelhasználását.

ColliderMesh

A jelenetobjektumok a Meshes és a ColliderMeshes tulajdonságokon keresztül biztosítanak hozzáférést a háló- és ütköztetőháló-adatokhoz. Ezek a hálók mindig egyeznek, ami azt jelenti, hogy a Meshes tulajdonság i'th indexe ugyanazt a geometriát jelöli, mint a ColliderMeshes tulajdonság i'th indexe. Ha a futtatókörnyezet/objektum támogatja a ütközőhálókat, akkor garantáltan a legalacsonyabb sokszöget és a legmagasabb szintű közelítést kapja, és ajánlott a ColliderMeshest használni, ahol az alkalmazás ütközőket használna. Ha a rendszer nem támogatja a collidereket, a ColliderMeshesben visszaadott Mesh-objektum ugyanaz lesz, mint a hálóra vonatkozó memóriakorlátok csökkentése.

Fejlesztés jelenetfelismeréssel

Ezen a ponton meg kell értenie a jelenet alapvető építőelemeit a futtatókörnyezet és az SDK megértéséhez. Az energia és az összetettség nagy része a hozzáférési mintákban, a 3D-keretrendszerekkel való interakcióban és az ezen API-kra írható eszközökben rejlik, hogy fejlettebb feladatokat végezzenek, például a tértervezést, a helyiségelemzést, a navigációt, a fizikát stb. Reméljük, hogy ezeket olyan mintákban fogjuk rögzíteni, amelyek remélhetőleg elvezetik Önt a megfelelő irányba, hogy a forgatókönyvek ragyogjanak. Ha vannak olyan minták vagy forgatókönyvek, amelyeket nem foglalkozunk, tudassa velünk, és megpróbáljuk dokumentálni/prototípusként használni, amire szüksége van.

Hol szerezhetek be mintakódot?

A Unity mintakódját a Unity mintalapján találja. Ez az alkalmazás lehetővé teszi, hogy kommunikáljon az eszközével, és renderelje a különböző jelenetobjektumokat, vagy lehetővé teszi egy szerializált jelenet betöltését a pc-n, és lehetővé teszi a Jelenetfelismerés eszköz nélküli használatát.

Hol szerezhetek be mintajeleneteket?

Ha Rendelkezik HoloLens2-sel, a rögzített jeleneteket mentheti úgy, hogy a ComputeSerializedAsync kimenetét fájlba menti, és saját kényelme szerint deszerializálja.

Ha nem rendelkezik HoloLens2-eszközzel, de játszani szeretne a Scene Understanding szolgáltatással, le kell töltenie egy előre rögzített jelenetet. A Scene Understanding minta jelenleg szerializált jelenetekkel rendelkezik, amelyek saját kényelme érdekében letölthetők és használhatók. Ezeket itt találja:

Jelenetfelismerési mintajelenetek

Lásd még