Omówienie zestawu SDK do zrozumienia sceny

Zrozumienie sceny przekształca dane czujników środowiska bez struktury, które urządzenie Mixed Reality przechwycić i przekonwertować na zaawansowaną abstrakcyjną reprezentację. Zestaw SDK działa jako warstwa komunikacji między aplikacją a środowiskiem uruchomieniowym usługi Scene Understanding. Jej celem jest naśladowanie istniejących konstrukcji standardowych, takich jak grafy sceny 3D dla reprezentacji 3D oraz prostokąty 2D i panele dla aplikacji 2D. Mimo że konstrukcje, które naśladują scenę, są mapowane na konkretne struktury, ogólnie rzecz biorąc, SceneUnderstanding jest niezależne od struktury, umożliwiając współdziałanie różnych platform, które z nim współdziałają. W przypadku ewolucji funkcji Scene Understanding rolą zestawu SDK jest zapewnienie, że nowe reprezentacje i możliwości będą nadal widoczne w ujednoliconej platformie. W tym dokumencie najpierw przedstawimy koncepcje wysokiego poziomu, które pomogą Ci zapoznać się ze środowiskiem dewelopera/użyciem, a następnie udostępnimy bardziej szczegółową dokumentację dla określonych klas i konstrukcji.

Gdzie mogę uzyskać zestaw SDK?

Zestaw SDK SceneUnderstanding można pobrać za pośrednictwem Mixed Reality Feature Tool.

Uwaga: najnowsza wersja zależy od pakietów w wersji zapoznawczej i należy włączyć pakiety wersji wstępnej, aby je wyświetlić.

W przypadku wersji 0.5.2022-rc i nowszych funkcja Scene Understanding obsługuje projekcje języka dla języków C# i C++, umożliwiając aplikacjom opracowywanie aplikacji dla platform Win32 lub UWP. Od tej wersji funkcja SceneUnderstanding obsługuje obsługę aparatu Unity w edytorze, co oznacza, że serwer SceneObserver jest używany wyłącznie do komunikacji z urządzeniem HoloLens2.

SceneUnderstanding wymaga Windows SDK w wersji 18362 lub wyższej.

Omówienie pojęć

Scena

Urządzenie rzeczywistości mieszanej stale integruje informacje o tym, co widzi w twoim środowisku. Scene Understanding lejkuje wszystkie te źródła danych i tworzy jedną spójną abstrakcję. Scene Understanding generuje sceny, które są kompozycją obiektu SceneObjects, które reprezentują wystąpienie jednej rzeczy (na przykład ściany/limitu/podłogi). Obiekty sceny same w sobie są kompozycją elementów [SceneComponents, które reprezentują bardziej szczegółowe elementy, które stanowią ten obiekt SceneObject. Przykładami składników są czworokąty i siatki, ale w przyszłości mogą reprezentować pola ograniczone, siatki kolizji, metadane itp.

Proces konwersji nieprzetworzonych danych czujnika na scenę jest potencjalnie kosztowną operacją, która może potrwać sekundy w przypadku średnich przestrzeni (ok. 10 x 10 m) do minut w przypadku dużych przestrzeni (ok. 50 x 50 m), a więc nie jest to coś, co jest obliczane przez urządzenie bez żądania aplikacji. Zamiast tego generowanie sceny jest wyzwalane przez aplikację na żądanie. Klasa SceneObserver ma metody statyczne, które mogą obliczać lub deserializować scenę, z którą można następnie wyliczać/wchodzić z nimi w interakcje. Akcja "Obliczenia" jest wykonywana na żądanie i wykonywana na procesorze CPU, ale w osobnym procesie (sterownik Mixed Reality). Jednak podczas przetwarzania w innym procesie wynikowe dane sceny są przechowywane i przechowywane w aplikacji w obiekcie Scene.

Poniżej znajduje się diagram, który ilustruje ten przepływ procesu i pokazuje przykłady dwóch aplikacji połączonych ze środowiskiem uruchomieniowym usługi Scene Understanding.

Diagram procesu

Po lewej stronie znajduje się diagram środowiska uruchomieniowego rzeczywistości mieszanej, które jest zawsze wł. i działa we własnym procesie. To środowisko uruchomieniowe jest odpowiedzialne za śledzenie urządzeń, mapowanie przestrzenne i inne operacje używane przez środowisko Scene Understanding do zrozumienia i zrozumienia świata wokół ciebie. Po prawej stronie diagramu pokazujemy dwie teoretyczne aplikacje, które korzystają z funkcji Scene Understanding. Pierwsze interfejsy aplikacji z mrtk, który używa zestawu SDK do rozpoznawania sceny wewnętrznie, druga aplikacja oblicza i używa dwóch oddzielnych wystąpień sceny. Wszystkie trzy sceny na tym diagramie generują odrębne wystąpienia scen. Sterownik nie śledzi stanu globalnego, który jest współużytkowana przez aplikacje, a obiekty sceny w jednej scenie nie znajdują się w innej. Zrozumienie sceny zapewnia mechanizm śledzenia w czasie, ale odbywa się to przy użyciu zestawu SDK. Kod śledzenia jest już uruchomiony w zestawie SDK w procesie aplikacji.

Ponieważ każda scena przechowuje swoje dane w przestrzeni pamięci aplikacji, można założyć, że wszystkie funkcje obiektu Scene lub jego danych wewnętrznych są zawsze wykonywane w procesie aplikacji.

Layout

Aby pracować z biblioteką Scene Understanding, warto wiedzieć i zrozumieć, jak środowisko uruchomieniowe reprezentuje składniki logicznie i fizycznie. Scena reprezentuje dane o określonym układzie, który został wybrany jako prosty przy zachowaniu podstawowej struktury, która może spełniać przyszłe wymagania bez konieczności większych poprawek. Ta scena robi to, przechowując wszystkie składniki (bloki konstrukcyjne dla wszystkich obiektów sceny) na płaskiej liście oraz definiując hierarchię i kompozycję za pomocą odwołań, gdzie określone składniki odwołują się do innych.

Poniżej przedstawiono przykład struktury w postaci płaskiej i logicznej.

Układ logicznyUkład fizyczny
    Sceny
    • 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

Na tej ilustracji przedstawiono różnicę między fizycznym i logicznym układem sceny. Po lewej stronie widzimy hierarchiczny układ danych, które aplikacja widzi podczas wyliczania sceny. Po prawej stronie widzimy, że scena składa się z 12 odrębnych składników, które w razie potrzeby są dostępne indywidualnie. Podczas przetwarzania nowej sceny oczekujemy, że aplikacje będą logicznie przechodzić przez tę hierarchię, jednak podczas śledzenia między aktualizacjami sceny niektóre aplikacje mogą być zainteresowane tylko określonymi składnikami, które są współdzielone między dwiema scenami.

Przegląd interfejsu API

W poniższej sekcji przedstawiono ogólne omówienie konstrukcji w ujmie sceny. Przeczytanie tej sekcji zawiera informacje na temat sposobu reprezentowania scen i sposobu, w jaki używane są różne składniki. W następnej sekcji przedstawiono konkretne przykłady kodu i dodatkowe szczegóły, które zostały szczegółowo opisane w tym przeglądzie.

Wszystkie typy opisane poniżej znajdują się w przestrzeni Microsoft.MixedReality.SceneUnderstanding nazw .

Składniki SceneComponents

Teraz, gdy rozumiesz logiczny układ scen, możemy przedstawić koncepcję elementów SceneComponents i sposób ich redagowania hierarchii. Składniki SceneComponents to najbardziej szczegółowe dekompozycje w scenieUnderstanding reprezentujące pojedynczy rdzeń, na przykład siatkę, czworokąt lub pole graniczne. Składniki SceneComponents to rzeczy, które można aktualizować niezależnie i do których mogą odwoływać się inne składniki SceneComponents, dlatego mają jedną globalną właściwość, unikatowy identyfikator, która zezwala na ten typ mechanizmu śledzenia/odwoływania się. Identyfikatory są używane do logicznego kompozycji hierarchii sceny, a także trwałości obiektu (działania aktualizacji jednej sceny względem innej).

Jeśli traktujesz każdą nowo obliczoną scenę jako odrębną i po prostu wyliczasz wszystkie dane w tej scenie, identyfikatory są dla Ciebie w dużym stopniu niewidoczne. Jeśli jednak planujesz śledzenie składników za pośrednictwem kilku aktualizacji, użyjesz identyfikatorów do indeksowania i wyszukiwania elementów SceneComponents między obiektami sceny.

SceneObjects

SceneObject to element SceneComponent, który reprezentuje wystąpienie "rzeczy", na przykład ściany, podłogi, limitu itp.... wyrażona przez ich właściwość Kind. Obiekty SceneObject są geometryczne i dlatego mają funkcje i właściwości, które reprezentują ich lokalizację w przestrzeni, jednak nie zawierają żadnej struktury geometrycznej ani logicznej. Zamiast tego sceneObjects odwołują się do innych składników SceneComponents, w szczególności SceneQuads i SceneMeshes, które zapewniają zróżnicowane reprezentacje obsługiwane przez system. Podczas obliczania nowej sceny aplikacja najprawdopodobniej wyliczy wyliczenia SceneObjects sceny, aby przetworzyć to, co cię interesuje.

SceneObjects może mieć jedną z następujących czynności:

SceneObjectKind Opis
TłoWiadomo, że obiekt SceneObject nie jest jednym z innych rozpoznanych rodzajów obiektu sceny. Tej klasy nie należy mylić z nieznaną, gdzie wiadomo, że tło nie jest ściany/podłogą/sufiksem itp.... chociaż nieznany nie jest jeszcze skategoryzowany.
ŚcianyŚciany fizycznej. Zakłada się, że ściany są strukturami środowisk.
FloorPodłogi to wszelkie powierzchnie, na których można przechodzić. Uwaga: poszycie nie jest podłogą. Należy również zauważyć, że podłogi zakładają dowolną powierzchnię chodzną, dlatego nie ma jawnego założenia dotyczącej pojedynczej podłogi. Struktury wielopoziomowe, rampy itp.... wszystkie klasyfikuje się jako podłogę.
CeilingGórna powierzchnia pomieszczenia.
PlatformaDuża płaska powierzchnia, na której można umieścić hologramy. Zazwyczaj reprezentują one tabele, countertops i inne duże poziomye powierzchnie.
ŚwiatZarezerwowana etykieta dla danych geometrycznych, które są niezależne od etykietowania. Siatka wygenerowana przez ustawienie flagi aktualizacji EnableWorldMesh zostałaby sklasyfikowana jako world.
NieznaneTen obiekt sceny nie został jeszcze sklasyfikowany i przypisany do rodzaju. Nie należy jej mylić z obiektem Background, ponieważ ten obiekt może być niczym, dlatego system nie dysponuje jeszcze wystarczająco silną klasyfikacją.

SceneMesh

SceneMesh to składowa SceneComponent, która przybliżona jest geometrią dowolnych obiektów geometrycznych przy użyciu listy trójkątów. SceneMeshes są używane w kilku różnych kontekstach; Mogą one reprezentować składniki struktury komórek wontight lub jako platformę WorldMesh, która reprezentuje niepowiązaną siatkę mapowania przestrzennego skojarzoną ze sceną. Dane indeksu i wierzchołków dostarczane z każdą siatką mają ten sam znany układ co bufory wierzchołków i indeksów, które są używane do renderowania siatek trójkątów we wszystkich nowoczesnych interfejsach API renderowania. W funkcji Scene Understanding siatki używają indeksów 32-bitowych i w przypadku niektórych aparatów renderowania może być konieczne ich rozbicie na fragmenty.

Nawijanie układów kolejności i współrzędnych

Wszystkie siatki produkowane przez usługę Scene Understanding powinny zwracać siatki w układzie współrzędnych Right-Handed zgodnie z ruchem wskazówek zegara.

Uwaga: Kompilacje systemu operacyjnego przed platformą .191105 mogą mieć znaną usterkę, która zwracała siatki "World" w Counter-Clockwise kolejności nawijania, co zostało naprawione.

SceneQuad

SceneQuad to obiekt SceneComponent reprezentujący 2d powierzchni, które zajmują świat 3D. Narzędzie SceneQuads może być używane podobnie do płaszczyzn ARKit ARPlaneAnchor lub ARCore, ale oferuje więcej funkcji wysokiego poziomu, takich jak kanwy 2d, które mają być używane przez płaskie aplikacje lub rozszerzone środowiska użytkownika. Dla czworokąt są dostępne interfejsy API specyficzne dla 2D, które sprawiają, że umieszczanie i układ są proste w użyciu, a opracowywanie (z wyjątkiem renderowania) z czworokątami powinno być bardziej podobne do pracy z kanwami 2d niż z siatkami 3d.

Kształt SceneQuad

Obiekt SceneQuads definiuje ograniczoną prostokątną powierzchnię w 2d. Jednak sceneQuads reprezentują powierzchnię o dowolnych i potencjalnie złożonych kształtach (np. tabeli w kształcie pierścienia). Aby przedstawić złożony kształt powierzchni czworokąt, możesz użyć interfejsu API GetSurfaceMask, aby renderować kształt powierzchni w zapewnianym buforze obrazu. Jeśli projekt SceneObject, który ma czworokąt, również ma siatkę, trójkąty siatki powinny być równoważne temu renderowaneowi obrazu, oba reprezentują rzeczywistą geometrię powierzchni, w współrzędnych 2d lub 3d.

Szczegóły zestawu SDK do zrozumienia sceny i informacje referencyjne

Uwaga

Podczas korzystania z mrTK należy pamiętać, że będziesz wchodzić w interakcję z usługą MRTK i w większości przypadków możesz pominąć tę [`WindowsSceneUnderstandingObserver`](xref:Microsoft.MixedReality.Toolkit.WindowsSceneUnderstanding.Experimental.WindowsSceneUnderstandingObserver) sekcję. Aby uzyskać więcej informacji, zapoznaj się z [tematem MRTK Scene Understanding](/windows/mixed-reality/mrtk-unity/features/spatial-awareness/scene-understanding) (Omówienie sceny mrTK).

W poniższej sekcji zaznajomisz się z podstawami scenyUnderstanding. Ta sekcja powinna dostarczyć podstawowych informacji. W tym momencie kontekst powinien być wystarczający do przeglądania przykładowych aplikacji, aby zobaczyć, jak sceneUnderstanding jest używana całościowo.

Inicjalizacja

Pierwszym krokiem do pracy z obiektem SceneUnderstanding jest uzyskanie odwoływać się do obiektu Scene (Scena) przez aplikację. Można to zrobić na jeden z dwóch sposobów: sterownik może obliczyć scenę lub istniejącą scenę, która została obliczona w przeszłości, można zdese serializować. Ta ostatnia jest przydatna do pracy z scenąOznaki podczas opracowywania, gdzie aplikacje i środowiska mogą być szybko prototypowane bez urządzenia rzeczywistości mieszanej.

Sceny są obliczane przy użyciu serwera SceneObserver. Przed utworzeniem sceny aplikacja powinna odpytować urządzenie, aby upewnić się, że obsługuje aplikację SceneUnderstanding, a także zażądać dostępu użytkownika do informacji, których wymaga sceneUnderstanding.

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

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

Jeśli requestAccessAsync() nie zostanie wywołana, przetwarzanie nowej sceny nie powiedzie się. Następnie obliczymy nową scenę, która jest rootowana wokół Mixed Reality nagłownego i ma 10-miernikowy promień.

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

Inicjowanie z danych (znane również jako. ścieżka komputera)

Chociaż sceny można obliczyć do bezpośredniego użycia, można je również obliczyć w postaci serializowanej do późniejszego użycia. Okazało się to przydatne podczas tworzenia aplikacji, ponieważ umożliwia deweloperom pracę i testowanie funkcji Scene Understanding bez konieczności użycia urządzenia. Serializacja sceny jest niemal identyczna z jej przetwarzaniem. Dane są zwracane do aplikacji zamiast deserializacji lokalnie przez zestaw SDK. Następnie możesz deserializować go samodzielnie lub zapisać do użytku w przyszłości.

// 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, wyliczenie

Teraz, gdy aplikacja ma scenę, będzie ona przyglądać się i wchodzić w interakcje zects SceneObjects. W tym celu należy uzyskać dostęp do właściwości SceneObjects:

SceneObject firstFloor = null;

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

Aktualizacja składników i udoskonalanie składników

Istnieje inna funkcja, która pobiera składniki w scenie o nazwie FindComponent. Ta funkcja jest przydatna podczas aktualizowania obiektów śledzenia i znajdowania ich w późniejszych scenach. Poniższy kod obliczy nową scenę względem poprzedniej sceny, a następnie znajdzie podłogę w nowej scenie.

// 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
}

Uzyskiwanie dostępu do siatek i czworokąt z obiektów sceny

Po odnalezioniu obiektów SceneObject aplikacja najprawdopodobniej będzie chciała uzyskać dostęp do danych zawartych w czworokątach/siatkach, z których składa się. Dostęp do tych danych można uzyskać za pomocą właściwości *Czworokąty _ i *_Siatki**. Poniższy kod wyliczy wszystkie czworokąty i siatki naszego obiektu podłogowego.


// 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
}

Zwróć uwagę, że jest to projekt SceneObject, który ma przekształcenie względem źródła sceny. Wynika to z tego, że obiekt SceneObject reprezentuje wystąpienie "rzeczy" i jest locatable w przestrzeni, a czworokąty i siatki reprezentują geometrię, która jest przekształcana względem ich elementu nadrzędnego. Możliwe jest, aby oddzielne sceneObjects odwoływały się do tych samych składników SceneMesh/SceneQuad SceneComponents, a także możliwe, że projekt SceneObject ma więcej niż jedną platformę SceneMesh/SceneQuad.

Dealing with Transforms

Podczas pracy z przekształceniami w umyśle podjęto próbę wyrównania sceny z tradycyjnymi reprezentacjami sceny 3D. W związku z tym każda scena jest ograniczona do jednego układu współrzędnych, podobnie jak najbardziej typowe reprezentacje środowiskowe 3D. Każdy z nich zapewnia swoją lokalizację względem tego układu współrzędnych. Jeśli twoja aplikacja zajmuje się scenami, które rozciągają granice tego, co zapewnia pojedyncze źródło, może zakotwiczyć sceny SceneObjects do spatialAnchors lub wygenerować kilka scen i scalić je ze sobą, ale dla uproszczenia zakładamy, że sceny wścibskie istnieją we własnym pochodzeniu zlokalizowanym za pomocą jednego węzła NodeId zdefiniowanego przez scene.OriginSpatialGraphNodeId.

Na przykład poniższy kod aparatu Unity pokazuje, jak używać interfejsów API Windows Percepcji i Unity do wyrównywania systemów współrzędnych. Zobacz SpatialCoordinateSystem i SpatialGraphInteropPreview, aby uzyskać szczegółowe informacje na temat interfejsów API percepcji systemu Windows i obiektów natywnych w a aparatu Mixed Reality Unity, aby uzyskać szczegółowe informacje na temat uzyskiwania obiektu SpatialCoordinateSystem odpowiadającego pochodzeniu światowej aparatu Unity.

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);
      HolograhicFrameData holoFrameData =  Marshal.PtrToStructure<HolograhicFrameData>(UnityEngine.XR.XRDevice.GetNativePtr());
      Windows.Perception.Spatial.SpatialCoordinateSystem unityCoordinateSystem = Microsoft.Windows.Perception.Spatial.SpatialCoordinateSystem.FromNativePtr(holoFrameData.ISpatialCoordinateSystemPtr);

      sceneToUnityTransform = sceneCoordinateSystem.TryGetTransformTo(unityCoordinateSystem);

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

    return sceneToUnityTransform;
}

Każdy SceneObject obiekt ma przekształcenie, które jest następnie stosowane do tego obiektu. W a aparatu Unity konwertujemy na współrzędne prawe i przypisujemy lokalne przekształcenia w następujący sposób:

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

Czworokąty zaprojektowano w celu pomocy w scenariuszach umieszczania 2D i należy je uważać za rozszerzenia elementów środowiska użytkownika kanwy 2D. Chociaż czworokąty są składnikami obiektów SceneObject i mogą być renderowane w 3D, same interfejsy API czworokąta zakładają, że czworokąty są strukturami 2D. Oferują one informacje, takie jak zakres, kształt i interfejsy API do umieszczania.

Czworokąty mają prostokątne zakresy, ale reprezentują dowolnie ukształtowane powierzchnie 2D. Aby umożliwić umieszczanie na tych powierzchniach 2D, które współdziałają z czworokątami środowiska 3D, dostępne są narzędzia umożliwiające tę interakcję. Obecnie funkcja Scene Understanding udostępnia dwie takie funkcje: FindCent najbardziej szczegółowePlacement i GetSurfaceMask. FindCentcentPlacement to interfejs API wysokiego poziomu, który znajduje pozycję na czworokącie, w której można umieścić obiekt, i spróbuje znaleźć najlepszą lokalizację dla obiektu, co gwarantuje, że pole granicy, które udostępnisz, pozostanie na bazowej powierzchni.

Uwaga

Współrzędne danych wyjściowych są względne względem czworokąta w "czworokątach" z lewym górnym rogu (x = 0, y = 0), podobnie jak w przypadku innych typów rect okien. Pamiętaj, aby wziąć to pod uwagę podczas pracy ze źródłami własnych obiektów.

W poniższym przykładzie pokazano, jak znaleźć najbardziej wyśrodkowatą lokalizację i zakotwiczyć hologram na czworokącie.

// 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)
            }
        }
    }
}

Kroki 1–4 w dużym stopniu zależą od konkretnej struktury/implementacji, ale motywy powinny być podobne. Należy pamiętać, że czworokąt reprezentuje po prostu ograniczoną płaszczyznę 2D, która jest zlokalizowane w przestrzeni. Dzięki posiadaniu przez aparat/platformę informacje o tym, gdzie znajduje się czworokąt i jak rootuje obiekty względem czworokąta, hologramy będą poprawnie umieszczone w odniesieniu do świata rzeczywistego.

Siatka

Siatki reprezentują geometryczne reprezentacje obiektów lub środowisk. Podobnie jakw przypadku mapowania przestrzennego, dane indeksu siatki i wierzchołków dostarczone z każdą siatką powierzchni przestrzennej mają ten sam znany układ co bufory wierzchołków i indeksów, które są używane do renderowania siatek trójkątów we wszystkich nowoczesnych interfejsach API renderowania. Pozycje wierzchołków znajdują się w układzie współrzędnych Scene obiektu . Konkretne interfejsy API używane do przywoływowania tych danych są następujące:

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

Poniższy kod zawiera przykład generowania listy trójkątów ze struktury siatki:

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

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

Bufory indeks/wierzchołek muszą być >= liczba indeksów/wierzchołków, ale w przeciwnym razie mogą być dowolnie o rozmiarze umożliwiającym efektywne ponowne używanie pamięci.

ColliderMesh

Obiekty sceny zapewniają dostęp do danych siatki i siatki sortowej za pośrednictwem właściwości Meshes i ColliderMeshes. Te siatki będą zawsze zgodne, co oznacza, że i indeks właściwości Meshes reprezentuje tę samą geometrię co indeks I's właściwości ColliderMeshes. Jeśli środowisko uruchomieniowe/obiekt obsługuje siatki sortowników, gwarantuje się, że zostanie uzyskać najmniejsze wielokąty o największym przybliżenie kolejności i dobrą praktyką jest używanie elementów ColliderMeshes wszędzie tam, gdzie aplikacja będzie używać kolidatorów. Jeśli system nie obsługuje kolidatorów, obiekt mesh zwrócony w tabeli ColliderMeshes będzie tym samym obiektem co siatka zmniejszająca ograniczenia pamięci.

Tworzenie przy użyciu zrozumienia sceny

Na tym etapie należy zrozumieć podstawowe bloki konstrukcyjne środowiska uruchomieniowego i zestawu SDK rozpoznawania sceny. Większość mocy i złożoności polega na wzorcach dostępu, interakcji z platformami 3D i narzędziach, które mogą być napisane na podstawie tych interfejsów API w celu wykonywania bardziej zaawansowanych zadań, takich jak planowanie przestrzenne, analiza pomieszczenia, nawigacja, fizyka i tak dalej. Mamy nadzieję, że przechwycimy je w przykładach, które powinny być odpowiednie, aby twoje scenariusze były najsłodsze. Jeśli istnieją przykłady lub scenariusze, które nie są adresami, daj nam znać, a my spróbujemy udokumentować/prototypować to, czego potrzebujesz.

Gdzie można uzyskać przykładowy kod?

Przykładowy kod aparatu Unity dla aparatu Scene Understanding można znaleźć na naszej stronie przykładu aparatu Unity. Ta aplikacja umożliwi komunikowanie się z urządzeniem i renderowanie różnych obiektów sceny lub umożliwi załadowanie serializowanej sceny na komputerze i umożliwi środowisko Scene Understanding bez użycia urządzenia.

Gdzie można uzyskać przykładowe sceny?

Jeśli masz urządzenie HoloLens2, możesz zapisać dowolną przechwyconą scenę, zapisując dane wyjściowe computeSerializedAsync w pliku i deserializując je we własnym dogodnym czasie.

Jeśli nie masz urządzenia HoloLens2, ale chcesz poekspować ze zrozumieniem sceny, musisz pobrać wstępnie przechwyconą scenę. Przykład Scene Understanding jest obecnie dostarczany z serializowanymi scenami, które można pobrać i używać we własnych wygodych. Można je znaleźć tutaj:

Sceny z omówieniem przykładowych scen

Zobacz też