Omówienie zestawu SDK opis sceny

Zrozumienie sceny przekształca dane czujnika środowiska bez struktury, które Mixed Reality urządzenie przechwytuje i konwertuje je na zaawansowaną abstrakcyjną reprezentację. Zestaw SDK działa jako warstwa komunikacji między aplikacją a środowiskiem uruchomieniowym usługi Scene Understanding. Ma na celu naśladowanie istniejących konstrukcji standardowych, takich jak wykresy scen 3D dla reprezentacji 3D, prostokąty i panele 2D dla aplikacji 2D. Podczas gdy konstrukcje Scene Understanding naśladują mapę do konkretnych struktur, ogólnie Rzecz biorąc, SceneUnderstanding jest niezależne od struktury, co pozwala na współdziałanie między różnymi strukturami, które z nią współdziałają. W miarę rozwoju usługi Scene Understanding rola zestawu SDK polega na zapewnieniu, że nowe reprezentacje i możliwości będą nadal widoczne w ujednoliconej strukturze. W tym dokumencie najpierw przedstawimy koncepcje wysokiego poziomu, które pomogą Ci zapoznać się ze środowiskiem projektowym/użyciem, a następnie przedstawimy bardziej szczegółową dokumentację dla określonych klas i konstrukcji.

Gdzie mogę uzyskać zestaw SDK?

Zestaw Sdk SceneUnderstanding można pobrać za pośrednictwem narzędzia 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 zobaczyć.

W przypadku wersji 0.5.2022-rc i nowszej usługa Scene Understanding obsługuje projekcje językowe dla języków C# i C++, umożliwiając aplikacjom tworzenie aplikacji dla platform Win32 lub UWP. Zgodnie z tą wersją funkcja SceneUnderstanding obsługuje obsługę aparatu Unity w edytorze, co jest używane wyłącznie do komunikowania się z urządzeniem HoloLens2.

Funkcja SceneUnderstanding wymaga zestawu Windows SDK w wersji 18362 lub nowszej.

Omówienie pojęć

Scena

Urządzenie rzeczywistości mieszanej stale integruje informacje o tym, co widzi w twoim środowisku. Scena Understanding lejki wszystkie te źródła danych i tworzy jedną spójną abstrakcję. Usługa Scene Understanding generuje sceny, które są kompozycją obiektów SceneObject , które reprezentują wystąpienie pojedynczej rzeczy (na przykład ścianę/sufit/podłogę). Same obiekty sceny to kompozycja elementów [SceneComponents, które reprezentują bardziej szczegółowe elementy tworzące ten obiekt SceneObject. Przykłady składników to czworokąta i siatki, ale w przyszłości mogą reprezentować pola ograniczenia, siatki kolizji, metadane itp.

Proces konwertowania nieprzetworzonych danych czujnika na scenę jest potencjalnie kosztowną operacją, która może potrwać kilka sekund dla średnich spacji (~10x10m) do minut w przypadku dużych przestrzeni (~50x50m), dlatego 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ć w interakcję. Akcja "Obliczenia" jest wykonywana na żądanie i wykonywana na procesorze CPU, ale w osobnym procesie (sterownik Mixed Reality). Jednak podczas wykonywania obliczeń w innym procesie wynikowe dane sceny są przechowywane i przechowywane w aplikacji w obiekcie Scena.

Poniżej znajduje się diagram ilustrujący ten przepływ procesu i pokazano przykłady dwóch aplikacji międzyfakcjonujących za pomocą środowiska uruchomieniowego usługi Scene Understanding.

Diagram procesu

Po lewej stronie znajduje się diagram środowiska uruchomieniowego rzeczywistości mieszanej, który jest zawsze włączony i uruchamiany we własnym procesie. To środowisko uruchomieniowe jest odpowiedzialne za wykonywanie śledzenia urządzeń, mapowania przestrzennego i innych operacji używanych przez usługę Scene Understanding do zrozumienia i przyczyny świata wokół Ciebie. Po prawej stronie diagramu przedstawiono dwie teoretyczne aplikacje korzystające z usługi Scene Understanding. Pierwszy interfejs aplikacji z zestawem MRTK, który używa zestawu SDK usługi Scene Understanding 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żytkowany między aplikacjami i obiektami sceny w jednej scenie nie można odnaleźć w innej scenie. Usługa Scene Understanding udostępnia 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 Sceny lub jego dane wewnętrzne są zawsze wykonywane w procesie aplikacji.

Layout

Aby pracować z usługą Scene Understanding, warto wiedzieć i zrozumieć, jak środowisko uruchomieniowe reprezentuje składniki logicznie i fizycznie. Scena reprezentuje dane z określonym układem, który został wybrany jako prosty, zachowując podstawową strukturę, która jest łatwa do spełnienia przyszłych wymagań bez konieczności wprowadzania poważnych poprawek. Scena robi to, przechowując wszystkie składniki (bloki konstrukcyjne dla wszystkich obiektów sceny) na płaskiej liście i definiując hierarchię i kompozycję za pomocą odwołań, w których określone składniki odwołują się do innych.

Poniżej przedstawiono przykład struktury w formie 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 układem fizycznym i logicznym sceny. Po lewej stronie zobaczymy 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 są dostępne indywidualnie w razie potrzeby. Podczas przetwarzania nowej sceny oczekujemy, że aplikacje będą logicznie chodzić o tę hierarchię, jednak podczas śledzenia między aktualizacjami sceny niektóre aplikacje mogą być zainteresowane ukierunkowaniem tylko określonych składników, które są współużytkowane między dwoma scenami.

Przegląd interfejsu API

Poniższa sekcja zawiera ogólne omówienie konstrukcji w rozwiązaniu Scene Understanding. Przeczytaj tę sekcję, aby dowiedzieć się, jak są reprezentowane sceny i jakie są różne składniki do/są używane. W następnej sekcji zostaną podane konkretne przykłady kodu i dodatkowe szczegóły, które zostały przeszytowane w tym omówieniu.

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

Komponenty sceny

Teraz, gdy rozumiesz logiczny układ scen, możemy przedstawić koncepcję elementu SceneComponents i sposób ich użycia do tworzenia hierarchii. SceneComponents to najbardziej szczegółowe dekompozycje w obiekcie SceneUnderstanding reprezentujące jedną podstawową rzecz, na przykład siatkę lub czworokąt lub pole ograniczenia. SceneComponents to rzeczy, które mogą być aktualizowane niezależnie i mogą być przywoływały inne składniki sceny, dlatego mają jedną właściwość globalną, unikatowy identyfikator, który umożliwia korzystanie z tego typu mechanizmu śledzenia/odwoływania się. Identyfikatory są używane do logicznej kompozycji hierarchii sceny, a także trwałości obiektów (aktu aktualizowania jednej sceny względem innej).

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

Obiekty Sceny

Obiekt SceneObject to element SceneComponent, który reprezentuje wystąpienie "rzeczy", na przykład ścianę, podłogę, sufit itp.... wyrażona przez ich właściwość Rodzaj. Obiekty SceneObject są geometryczne i dlatego mają funkcje i właściwości reprezentujące ich lokalizację w przestrzeni, jednak nie zawierają żadnej struktury geometrycznej ani logicznej. Zamiast tego obiekty SceneObject odwołują się do innych obiektów SceneComponents, w szczególności SceneQuads i SceneMeshes, które zapewniają różne reprezentacje obsługiwane przez system. Po obliczeniu nowej sceny aplikacja najprawdopodobniej wyliczyła obiekty SceneObjects sceny, aby przetworzyć interesujące ją elementy.

Obiekty SceneObject mogą mieć dowolną z następujących elementów:

SceneObjectKind Opis
TłoObiekt SceneObject jest znany jako jeden z innych rozpoznanych rodzajów obiektu sceny. Ta klasa nie powinna być mylona z nieznanym, gdzie tło nie jest znane jako ściana/podłoga/sufit itp.... chociaż nieznany nie jest jeszcze kategoryzowany.
ŚcianaŚciana fizyczna. Zakłada się, że ściany są nieruchomymi strukturami środowiskowymi.
FloorPodłogi to wszelkie powierzchnie, na których można chodzić. Uwaga: schody nie są podłogami. Należy również zauważyć, że podłogi zakładają dowolną powierzchnię spacerową i dlatego nie ma wyraźnego założenia pojedynczej podłogi. Struktury wielowymiarowe, rampy itp.... wszystkie powinny być klasyfikowane jako podłoga.
CeilingGórna powierzchnia pokoju.
PlatformaDuża płaska powierzchnia, na której można umieścić hologramy. Mają one tendencję do reprezentowania tabel, blatów i innych dużych powierzchni poziomych.
ŚwiatZarezerwowana etykieta dla danych geometrycznych, które są niezależne od etykietowania. Siatka wygenerowana przez ustawienie flagi aktualizacji EnableWorldMesh zostanie sklasyfikowana jako świat.
NieznaneTen obiekt sceny nie został jeszcze sklasyfikowany i przypisany rodzaj. Nie należy tego mylić z background, ponieważ ten obiekt może być dowolny, system po prostu nie wymyślił wystarczająco silnej klasyfikacji dla niego jeszcze.

SceneMesh

SceneMesh to element SceneComponent, który przybliża geometrię dowolnych obiektów geometrycznych przy użyciu listy trójkątów. SceneMeshes są używane w kilku różnych kontekstach; mogą reprezentować składniki struktury komórki wodoszczelnych lub jako WorldMesh, który reprezentuje niezwiązaną siatkę mapowania przestrzennego skojarzona ze sceną. Dane indeksu i wierzchołka dostarczane z każdą siatką używają tego samego znanego układu co bufory wierzchołków i indeksów , które są używane do renderowania siatki trójkątów we wszystkich nowoczesnych interfejsach API renderowania. W rozwiązaniu Scene Understanding siatki używają indeksów 32-bitowych i mogą być konieczne podziały na fragmenty dla niektórych aparatów renderowania.

Kolejność uzwojenia i układy współrzędnych

Oczekuje się, że wszystkie siatki utworzone przez usługę Scene Understanding będą zwracać siatki w układzie współrzędnych Right-Handed przy użyciu układu uzwojenia zgodnie z ruchem wskazówek zegara.

Uwaga: kompilacje systemu operacyjnego wcześniejsze niż .191105 mogą mieć znaną usterkę polegającą na tym, że siatki "World" powracały w kolejności uzwojenia Counter-Clockwise, co zostało później naprawione.

SceneQuad

SceneQuad jest SceneComponent, który reprezentuje powierzchnie 2d, które zajmują świat 3D. Narzędzia SceneQuads mogą być używane podobnie do ARKit ARPlaneAnchor lub ARCore Planes, ale oferują one bardziej ogólne funkcje jako kanwy 2d do użycia przez aplikacje płaskie lub rozszerzone środowisko użytkownika. Określone interfejsy API 2D są udostępniane dla quadów, które sprawiają, że umieszczanie i układ jest prosty w użyciu, i opracowywanie (z wyjątkiem renderowania) z czworokątami powinno czuć się bardziej zbliżone do pracy z kanwy 2d niż 3d siatki.

Kształt SceneQuad

SceneQuads definiują powiązaną prostokątną powierzchnię w 2d. Jednak obiekt SceneQuads reprezentuje powierzchnie 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ąta, możesz użyć interfejsu API GetSurfaceMask do renderowania kształtu powierzchni na zapewnianym buforze obrazu. Jeśli obiekt SceneObject, który ma czworokąt również siatkę, trójkąty siatki powinny być równoważne temu renderowanemu obrazowi, obie reprezentują rzeczywistą geometrię powierzchni w współrzędnych 2d lub 3d.

Szczegóły i dokumentacja zestawu SDK opis sceny

Uwaga

W przypadku korzystania z zestawu narzędzi MRTK, Należy pamiętać, że będziesz wchodzić w interakcje z elementami [WindowsSceneUnderstandingObserver'](xref:Microsoft.MixedReality.Toolkit.WindowsSceneUnderstanding.Experimental.WindowsSceneUnderstandingObserver?view=mixed-reality-toolkit-unity-2020-dotnet-2.8.0&preserve-view=true) i w związku z tym może pominąć tę sekcję w większości okoliczności. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją [MRTK Scene Understanding](/windows/mixed-reality/mrtk-unity/features/spatial-awareness/scene-understanding).

Poniższa sekcja pomoże Ci zapoznać się z podstawami funkcji SceneUnderstanding. Ta sekcja powinna zawierać podstawowe informacje. W tym momencie należy mieć wystarczającą ilość kontekstu, aby przeglądać przykładowe aplikacje, aby zobaczyć, jak funkcja SceneUnderstanding jest używana całościowo.

Inicjalizacja

Pierwszym krokiem do pracy z elementem SceneUnderstanding jest uzyskanie przez aplikację odwołania do obiektu Scena. Można to zrobić na jeden z dwóch sposobów. Scena może być obliczana przez sterownik lub istniejąca scena, która została obliczona w przeszłości, może zostać zdes serializowana. Ta ostatnia funkcja przydaje się do pracy z rozwiązaniem SceneUnderstanding 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 wysłać zapytanie do urządzenia, aby upewnić się, że obsługuje funkcję SceneUnderstanding, a także zażądać dostępu użytkownika do informacji wymaganych przez funkcję SceneUnderstanding.

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

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

Jeśli funkcja RequestAccessAsync() nie zostanie wywołana, obliczenie nowej sceny zakończy się niepowodzeniem. Następnie obliczymy nową scenę, która jest zakorzeniona wokół zestawu nagłownego Mixed Reality i ma 10-metrowy 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 (nazywanej również ścieżką komputera)

Podczas gdy sceny mogą być obliczane pod kątem bezpośredniego zużycia, można je również obliczyć w postaci serializowanej do późniejszego użycia. Okazało się to przydatne w przypadku programowania, ponieważ umożliwia deweloperom pracę w rozwiązaniu Scene Understanding i testowanie go bez konieczności korzystania z urządzenia. Akt serializacji sceny jest niemal identyczny z przetwarzaniem, dane są zwracane do aplikacji zamiast deserializować lokalnie przez zestaw SDK. Następnie możesz wykonać deserializacji 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ę, aplikacja będzie przeglądać obiekty SceneObject i korzystać z niej. Odbywa się to przez uzyskanie dostępu 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;
    }
}

Składniki aktualizacji i ponownego instalowania 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 kolejnych scenach. Poniższy kod oblicza 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ów z obiektów sceny

Po znalezieniu obiektów SceneObject aplikacja najprawdopodobniej będzie chciała uzyskać dostęp do danych zawartych w czworokątach/siatkach, z których się składa. Te dane są dostępne za pomocą właściwości Czworokąta i Siatki . Poniższy kod wylicza wszystkie czworokąta 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 obiekt SceneObject ma transformację względną względem źródła sceny. Wynika to z tego, że obiekt SceneObject reprezentuje wystąpienie "rzeczy" i jest lokalizowalny w przestrzeni, czworokąta i siatki reprezentują geometrię, która jest przekształcana względem ich elementu nadrzędnego. Istnieje możliwość, aby oddzielne obiekty SceneObject odwoływały się do tego samego obiektu SceneMesh/SceneQuad SceneComponents i istnieje również możliwość, że obiekt SceneObject ma więcej niż jedną scenęMesh/SceneQuad.

Obsługa przekształceń

Usługa Scene Understanding podjęła celową próbę dopasowania do tradycyjnych reprezentacji sceny 3D podczas pracy z transformacjami. Każda scena jest zatem ograniczona do jednego układu współrzędnych, podobnie jak najbardziej typowe reprezentacje środowiskowe 3D. Każdy obiekt SceneObjects udostępnia lokalizację względem tego układu współrzędnych. Jeśli aplikacja ma do czynienia z scenami, które rozciągają limit tego, co zapewnia pojedyncze źródło, może zakotwiczyć obiekty SceneObjects do obiektów SpatialAnchors lub wygenerować kilka scen i scalić je razem, ale dla uproszczenia zakładamy, że sceny oszczególne istnieją we własnym pochodzeniu zlokalizowanym przez jeden identyfikator NodeId zdefiniowany przez Scene.OriginSpatialGraphNodeId.

Poniższy kod aparatu Unity pokazuje na przykład, jak używać interfejsów API percepcji systemu Windows i aparatu Unity w celu wyrównania współrzędnych systemów. Aby uzyskać szczegółowe informacje na temat interfejsów API percepcji systemu Windows, zobacz SpatialCoordinateSystem i SpatialGraphInteropPreview oraz Mixed Reality obiektów natywnych w a unity, aby uzyskać szczegółowe informacje na temat uzyskiwania systemu SpatialCoordinateSystem, który odpowiada światowemu pochodzeniu 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);
    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;
}

Każda z nich SceneObject ma przekształcenie, które jest następnie stosowane do tego obiektu. W a unity konwertujemy na współrzędne praworęczne 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ąta zostały zaprojektowane w celu ułatwienia scenariuszy umieszczania 2D i powinny być uważane za rozszerzenia do elementów środowiska użytkownika kanwy 2D. Chociaż quady są składnikami SceneObjects i mogą być renderowane w 3D, same interfejsy API czworokątów zakładają, że quady są strukturami 2D. Oferują informacje, takie jak zakres, kształt i udostępniają interfejsy API do umieszczania.

Czworokąty mają prostokątne zakresy, ale reprezentują arbitralnie ukształtowane powierzchnie 2D. Aby umożliwić umieszczanie na tych powierzchniach 2D, które współdziałają ze środowiskiem 3D, oferują narzędzia, aby umożliwić tę interakcję. Obecnie usługa Scene Understanding udostępnia dwie takie funkcje: FindCentermostPlacement i GetSurfaceMask. FindCentermostPlacement to interfejs API wysokiego poziomu, który lokalizuje pozycję na czworokącie, w którym można umieścić obiekt i spróbuje znaleźć najlepszą lokalizację dla obiektu, gwarantując, że podane pole ograniczenia pozostanie na powierzchni bazowej.

Uwaga

Współrzędne danych wyjściowych są względne względem czworokąta w obszarze "czworokąt" 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 z źródłami własnych obiektów.

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

// 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 są bardzo zależne od konkretnej struktury/implementacji, ale motywy powinny być podobne. Należy pamiętać, że czworokąt po prostu reprezentuje powiązaną płaszczyznę 2D zlokalizowaną w przestrzeni. Mając aparat/strukturę wiedzą, gdzie znajduje się czworokąt i ukorzeniając obiekty względem czworokąta, hologramy będą prawidłowo znajdować się w odniesieniu do świata rzeczywistego.

Siatka

Siatki reprezentują geometryczne reprezentacje obiektów lub środowisk. Podobnie jak w przypadku mapowania przestrzennego, indeksu siatki i danych wierzchołków dostarczanych z każdą siatką powierzchni przestrzennych używa tego samego znanego układu co bufory wierzchołków i indeksów, które są używane do renderowania siatki trójkątów we wszystkich nowoczesnych interfejsach API renderowania. Położenia wierzchołków są udostępniane w układzie współrzędnych obiektu Scene. Określone interfejsy API używane do odwoływanie się do tych danych są następujące:

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

Poniższy kod przedstawia przykład generowania listy trójkątów na podstawie 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 indeksu/wierzchołka muszą być >= liczba indeksów/wierzchołków, ale w przeciwnym razie może mieć dowolny rozmiar umożliwiający efektywne ponowne użycie pamięci.

ColliderMesh

Obiekty sceny zapewniają dostęp do danych siatki i siatki zderzacza za pośrednictwem właściwości Meshes i ColliderMeshes. Te siatki będą zawsze zgodne, co oznacza, że i'th indeks właściwości Meshes reprezentuje taką samą geometrię jak i'th indeks właściwości ColliderMeshes. Jeśli środowisko uruchomieniowe/obiekt obsługuje siatki zderzaków, gwarantowane jest uzyskanie najniższego wielokąta, najwyższego przybliżenia kolejności i dobrym rozwiązaniem jest użycie colliderMeshes wszędzie tam, gdzie aplikacja będzie używać zderzaczy. Jeśli system nie obsługuje zderzaków, obiekt Mesh zwrócony w ColliderMeshes będzie tym samym obiektem, co siatka zmniejszająca ograniczenia pamięci.

Programowanie z interpretacją sceny

W tym momencie należy poznać podstawowe bloki konstrukcyjne sceny ze środowiskiem uruchomieniowym i zestawem SDK. Większość mocy i złożoności polega na wzorcach dostępu, interakcji z platformami 3D i narzędziach, które można napisać na podstawie tych interfejsów API, aby wykonywać bardziej zaawansowane zadania, takie jak planowanie przestrzenne, analiza pomieszczeń, nawigacja, fizyka itd. Mamy nadzieję, że przechwycimy te dane w próbkach, które powinny miejmy nadzieję, że poprowadzi Cię w odpowiednim kierunku, aby twoje scenariusze świeciły. Jeśli nie mamy przykładów lub scenariuszy, daj nam znać i spróbujemy udokumentować/utworzyć prototyp potrzebnych informacji.

Gdzie mogę uzyskać przykładowy kod?

Przykładowy kod programu Scene Understanding dla aparatu Unity można znaleźć na stronie przykładowej aparatu Unity . Ta aplikacja umożliwia komunikowanie się z urządzeniem i renderowanie różnych obiektów sceny lub, dzięki czemu można załadować serializowaną scenę na komputerze i umożliwić korzystanie z funkcji Scene Understanding bez urządzenia.

Gdzie można uzyskać przykładowe sceny?

Jeśli masz urządzenie HoloLens2, możesz zapisać dowolną scenę przechwyconą przez zapisanie danych wyjściowych funkcji ComputeSerializedAsync do pliku i deserializacji jej we własnej wygodzie.

Jeśli nie masz urządzenia HoloLens2, ale chcesz grać z usługą Scene Understanding, 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łasnej wygodzie. Można je znaleźć tutaj:

Scena z omówieniem przykładowych scen

Zobacz też