Overzicht scène-inzicht in SDK

Scènebegrip transformeert de ongestructureerde omgevingssensorgegevens die uw Mixed Reality vast leggen en converteert deze naar een krachtige abstracte weergave. De SDK fungeert als de communicatielaag tussen uw toepassing en de Scene Understanding-runtime. Het is gericht op het nabootsen van bestaande standaard constructies, zoals 3D-scènegrafieken voor 3D-weergaven en 2D-rechthoeken en panelen voor 2D-toepassingen. Hoewel de constructs Scene Understanding-nabootsingen aan concrete frameworks worden toe te wijden, is SceneUnderstanding in het algemeen frameworkneagnostisch, wat interoperabiliteit mogelijk maakt tussen verschillende frameworks die erop reageren. Naarmate Scene Understanding zich verder ontwikkelt, is de rol van de SDK ervoor te zorgen dat nieuwe representaties en mogelijkheden binnen een uniform framework blijven worden getoond. In dit document introduceren we eerst algemene concepten die u helpen vertrouwd te raken met de ontwikkelomgeving/het gebruik en vervolgens gedetailleerdere documentatie te bieden voor specifieke klassen en constructies.

Waar vind ik de SDK?

De SceneUnderstanding SDK kan worden gedownload via Mixed Reality Feature Tool.

Opmerking: de nieuwste release is afhankelijk van preview-pakketten en u moet pre-release-pakketten inschakelen om deze te zien.

Voor versie 0.5.2022-rc en hoger ondersteunt Scene Understanding taalprojecties voor C# en C++ zodat toepassingen toepassingen kunnen ontwikkelen voor Win32- of UWP-platforms. Vanaf deze versie biedt SceneUnderstanding ondersteuning voor Unity in de editor, waarbij de SceneObserver wordt gebruikt voor communicatie met HoloLens2.

SceneUnderstanding vereist Windows SDK-versie 18362 of hoger.

Conceptueel overzicht

De scène

Uw mixed reality apparaat integreert voortdurend informatie over wat het in uw omgeving ziet. Scene Understanding trechtert al deze gegevensbronnen en produceert één samenhangende abstractie. Scene Understanding genereert scènes, een samenstelling van SceneObjects die een exemplaar van één ding vertegenwoordigen (bijvoorbeeld een wand/plafond/vloer).) Scèneobjecten zelf zijn een samenstelling van [SceneComponents, die meer gedetailleerde onderdelen vertegenwoordigen waaruit dit SceneObject is samengesteld. Voorbeelden van onderdelen zijn quads en meshes, maar in de toekomst kunnen begrenzen, meshes, metagegevens, enzovoort worden weergegeven.

Het proces van het converteren van de onbewerkte sensorgegevens naar een scène is een potentieel kostbare bewerking die enkele seconden kan duren voor middelgrote ruimten (ongeveer 10x10 m) naar minuten voor grote ruimten (ongeveer 50x50 m) en daarom is het niet iets dat door het apparaat wordt berekend zonder toepassingsaanvraag. In plaats daarvan wordt het genereren van scène door uw toepassing op aanvraag geactiveerd. De klasse SceneObserver heeft statische methoden waarmee u een scène kunt berekenen of deserialiseren, die u vervolgens kunt opsemuleren/gebruiken. De actie 'Compute' wordt op aanvraag uitgevoerd en uitgevoerd op de CPU, maar in een afzonderlijk proces (het Mixed Reality Stuurprogramma). Terwijl we echter in een ander proces berekenen, worden de resulterende scènegegevens opgeslagen en onderhouden in uw toepassing in het Scène-object.

Hieronder ziet u een diagram dat deze processtroom illustreert en voorbeelden toont van twee toepassingen die zijn verbonden met de Scene Understanding-runtime.

Procesdiagram

Aan de linkerkant staat een diagram van de mixed reality runtime, die altijd in zijn eigen proces wordt uitgevoerd. Deze runtime is verantwoordelijk voor het bijhouden van apparaten, ruimtelijke toewijzing en andere bewerkingen die Scene Understanding gebruikt om de wereld om u heen te begrijpen en te beredeneren. Aan de rechterkant van het diagram laten we twee theoretische toepassingen zien die gebruikmaken van Scene Understanding. De eerste toepassing interfaces met MRTK, waarbij intern gebruik wordt gemaakt van de Scene Understanding SDK, berekent de tweede app en gebruikt twee afzonderlijke scène-exemplaren. Alle drie scènes in dit diagram genereren afzonderlijke exemplaren van de scènes. Het stuurprogramma volgt de algemene status niet die wordt gedeeld tussen toepassingen en Scèneobjecten in de ene scène worden niet gevonden in een andere scène. Scene Understanding biedt een mechanisme om in de tijd bij te houden, maar dit wordt gedaan met behulp van de SDK. Traceringscode wordt al uitgevoerd in de SDK in het proces van uw app.

Omdat elke scène de gegevens opgeslagen in de geheugenruimte van uw toepassing, kunt u ervan uitgaan dat alle functies van het Scène-object of de interne gegevens ervan altijd worden uitgevoerd in het proces van uw toepassing.

Layout

Als u wilt werken met Scene Understanding, kan het nuttig zijn om te weten en te begrijpen hoe de runtime onderdelen logisch en fysiek vertegenwoordigt. De scène vertegenwoordigt gegevens met een specifieke indeling die eenvoudig is gekozen, terwijl er een onderliggende structuur wordt onderhouden die kan voldoen aan toekomstige vereisten zonder dat er grote revisies nodig zijn. De scène doet dit door alle onderdelen (bouwstenen voor alle scèneobjecten) op te slaan in een platte lijst en hiërarchie en samenstelling te definiëren via verwijzingen waar specifieke onderdelen naar anderen verwijzen.

Hieronder wordt een voorbeeld van een structuur weergegeven in zowel de platte als logische vorm.

Logische indelingFysieke indeling
    Scène
    • 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

In deze afbeelding wordt het verschil tussen de fysieke en logische indeling van de scène belicht. Aan de linkerkant zien we de hiërarchische indeling van de gegevens die uw toepassing ziet bij het opsnoemen van de scène. Aan de rechterkant zien we dat de scène bestaat uit 12 afzonderlijke onderdelen die indien nodig afzonderlijk toegankelijk zijn. Bij het verwerken van een nieuwe scène verwachten we dat toepassingen deze hiërarchie logisch kunnen volgen, maar bij het bijhouden tussen scène-updates zijn sommige toepassingen mogelijk alleen geïnteresseerd in specifieke onderdelen die worden gedeeld tussen twee scènes.

API-overzicht

De volgende sectie biedt een overzicht op hoog niveau van de constructies in Scene Understanding. Als u deze sectie leest, krijgt u inzicht in hoe scènes worden weergegeven en waarvoor de verschillende onderdelen werken/worden gebruikt. In de volgende sectie vindt u concrete codevoorbeelden en aanvullende details die in dit overzicht worden belijst.

Alle typen die hieronder worden beschreven, bevinden zich in Microsoft.MixedReality.SceneUnderstanding de naamruimte .

SceneComponents

Nu u de logische indeling van scènes begrijpt, kunnen we het concept sceneComponents presenteren en laten zien hoe deze worden gebruikt om een hiërarchie samen te stellen. SceneComponents zijn de meest gedetailleerde uitcomposities in SceneUnderstanding die één kernding vertegenwoordigen, bijvoorbeeld een mesh of een quad of een begrensvak. SceneComponents zijn zaken die onafhankelijk kunnen worden bijgewerkt en waarnaar kan worden verwezen door andere SceneComponents. Daarom hebben ze één globale eigenschap, een unieke id, waarmee dit type tracerings-/verwijzingsmechanisme mogelijk is. ID's worden gebruikt voor de logische samenstelling van scènehiërarchie en object persistentie (het bijwerken van de ene scène ten opzichte van de andere).

Als u elke nieuw berekende scène als uniek behandelt en simpelweg alle gegevens in de scène opsnoemt, zijn de ID's grotendeels transparant voor u. Als u echter van plan bent onderdelen bij te houden voor verschillende updates, gebruikt u de -ID's om SceneComponents tussen scèneobjecten te indexeren en te vinden.

SceneObjects

Een SceneObject is een SceneComponent die een instantie van een 'ding' vertegenwoordigt, bijvoorbeeld een wand, een vloer, een plafond, enzovoort... uitgedrukt door hun eigenschap Kind. SceneObjects zijn geometrisch en hebben daarom functies en eigenschappen die hun locatie in ruimte vertegenwoordigen, maar ze bevatten geen geometrische of logische structuur. In plaats daarvan verwijzen SceneObjects naar andere SceneComponents, met name SceneQuads en SceneMeshes, die de gevarieerde weergaven bieden die door het systeem worden ondersteund. Wanneer een nieuwe scène wordt berekend, zal uw toepassing waarschijnlijk de SceneObjects van de scène opsnoemen om te verwerken waarin deze is geïnteresseerd.

SceneObjects kunnen een van de volgende opties hebben:

SceneObjectKind Description
AchtergrondHet sceneobject is niet een van de andere herkende soorten scèneobjecten. Deze klasse mag niet worden verward met Onbekend, waarbij voor de achtergrond bekend is dat deze geen wand/vloer/plafond is, enzovoort. hoewel onbekend nog niet is gecategoriseerd.
MuurEen fysieke wand. Er wordt van uitgegaan dat muren onveranderbare omgevingsstructuren zijn.
FloorVerdiepingen zijn alle vlakken waarop u kunt lopen. Opmerking: dit zijn geen verdiepingen. Houd er ook rekening mee dat verdiepingen uitgaan van een beloopbaar oppervlak en dat er daarom geen expliciete veronderstelling van een enkele verdieping is. Structuren op meerdere niveau, hellingen, enzovoort... moet allemaal worden geclassificeerd als floor.
CeilingHet bovenste oppervlak van een ruimte.
PlatformEen groot plat oppervlak waarop u hologrammen kunt plaatsen. Deze staan meestal voor tabellen, werkbladen en andere grote horizontale oppervlakken.
WereldEen gereserveerd label voor geometrische gegevens die agnostisch zijn voor labelen. De mesh die wordt gegenereerd door de updatevlag EnableWorldMesh in te stellen, wordt geclassificeerd als wereld.
OnbekendDit scèneobject moet nog worden geclassificeerd en toegewezen aan een soort. Dit mag niet worden verward met Background, omdat dit object van alles kan zijn. Het systeem heeft er nog niet voldoende classificatie voor ontwikkeld.

SceneMesh

Een SceneMesh is een SceneComponent die de geometrie van willekeurige geometrische objecten benadert met behulp van een driehoekenlijst. SceneMeshes worden gebruikt in verschillende contexten; Ze kunnen onderdelen van de watertight-celstructuur vertegenwoordigen of als de WorldMesh, die de niet-gebonden mesh voor ruimtelijke toewijzing vertegenwoordigt die is gekoppeld aan de scène. De index- en hoekpuntgegevens die bij elke mesh worden geleverd, gebruiken dezelfde vertrouwde indeling als de hoekpunt- en indexbuffers die worden gebruikt voor het weergeven van driehoek meshes in alle moderne rendering-API's. In Scene Understanding gebruiken meshes 32-bits indexen en moeten ze mogelijk worden opgesplitst in segmenten voor bepaalde renderingenen.

Systemen voor windingsorders en coördinaten

Alle meshes die door Scene Understanding worden geproduceerd, retourneren naar verwachting meshes in een Right-Handed coördinaatsysteem met de klok mee draaiende volgorde.

Opmerking: os-builds vóór .191105 hebben mogelijk een bekende fout waarbij 'World'-meshes werden retourneert in Counter-Clockwise volgorde van winding, die vervolgens is opgelost.

SceneQuad

Een SceneQuad is een SceneComponent die staat voor 2d surfaces die de 3D-wereld in beslag nemen. SceneQuads kunnen op dezelfde manier worden gebruikt als ARKit ARPlaneAnchor of ARCore-vlakken, maar bieden meer functionaliteit op hoog niveau als 2d-canvass die kunnen worden gebruikt door platte apps of uitgebreide UX. Er zijn 2D-specifieke API's beschikbaar voor quads die plaatsing en lay-out eenvoudig te gebruiken maken, en ontwikkelen (met uitzondering van rendering) met quads moet meer vergelijkbaar zijn met het werken met 2d-canvass dan 3d-meshes.

SceneQuad-vorm

SceneQuads definiëren een rechthoekig begrensd oppervlak in 2d. SceneQuads vertegenwoordigen echter oppervlakken met willekeurige en mogelijk complexe vormen (bijvoorbeeld een ringvormige tabel.) Als u de complexe vorm van het oppervlak van een quad wilt vertegenwoordigen, kunt u de GetSurfaceMask-API gebruiken om de vorm van het oppervlak weer te geven op een afbeeldingsbuffer die u op geeft. Als het SceneObject met de quad ook een mesh heeft, moeten de mesh-driehoeken gelijk zijn aan deze gerenderde afbeelding. Ze vertegenwoordigen beide de echte geometrie van het oppervlak, in 2d- of 3d-coördinaten.

Scène over SDK-details en -verwijzing

Notitie

Wanneer u MRTK gebruikt, moet u er rekening mee hebben dat u met MRTK's communiceert en deze sectie daarom onder de meeste omstandigheden [`WindowsSceneUnderstandingObserver`](xref:Microsoft.MixedReality.Toolkit.WindowsSceneUnderstanding.Experimental.WindowsSceneUnderstandingObserver) kan overslaan. Raadpleeg de [MRTK Scene Understanding-documenten](/windows/mixed-reality/mrtk-unity/features/spatial-awareness/scene-understanding) voor meer informatie.

De volgende sectie helpt u vertrouwd te raken met de basisbeginselen van SceneUnderstanding. In deze sectie vindt u de basisprincipes, op welk punt u voldoende context moet hebben om door de voorbeeldtoepassingen te bladeren om te zien hoe SceneUnderstanding holistisch wordt gebruikt.

Initialisatie

De eerste stap voor het werken met SceneUnderstanding is dat uw toepassing verwijzing naar een Scène-object krijgt. Dit kan op twee manieren worden gedaan: een scène kan worden berekend door het stuurprogramma of een bestaande scène die in het verleden is berekend, kan worden gedeser serialiseerd. Het laatste is handig voor het werken met SceneUnderstanding tijdens de ontwikkeling, waarbij snel prototypen van toepassingen en ervaringen kunnen worden gemaakt zonder een mixed reality apparaat.

Scènes worden berekend met behulp van een SceneObserver. Voordat u een scène maakt, moet uw toepassing een query uitvoeren op uw apparaat om ervoor te zorgen dat sceneunderstanding wordt ondersteund, en moet u gebruikerstoegang aanvragen voor informatie die sceneUnderstanding nodig heeft.

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

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

Als RequestAccessAsync() niet wordt aangeroepen, mislukt het berekenen van een nieuwe scène. Vervolgens berekenen we een nieuwe scène die is geroot rond de Mixed Reality headset en een radius van 10 meter heeft.

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

Initialisatie vanuit gegevens (ook wel bekend als . het pc-pad)

Scènes kunnen worden berekend voor direct gebruik, maar ze kunnen ook in geser serialiseerde vorm worden berekend voor later gebruik. Dit is nuttig gebleken voor ontwikkeling omdat ontwikkelaars hiermee scène Understanding kunnen gebruiken en testen zonder dat er een apparaat nodig is. Het serialiseren van een scène is bijna identiek aan het berekenen ervan. De gegevens worden geretourneerd naar uw toepassing in plaats van lokaal te worden gedeserialiseerd door de SDK. U kunt het vervolgens zelf deserialiseren of opslaan voor toekomstig gebruik.

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

Nu uw toepassing een scène heeft, kijkt uw toepassing naar sceneObjects en communiceert deze met deze scène. Dit wordt gedaan door toegang te krijgen tot de eigenschap SceneObjects:

SceneObject firstFloor = null;

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

Onderdelen bijwerken en opnieuw zoeken

Er is een andere functie die onderdelen in de scène op haalt met de naam FindComponent. Deze functie is handig bij het bijwerken van traceringsobjecten en het vinden ervan in latere scènes. Met de volgende code wordt een nieuwe scène berekend ten opzichte van een vorige scène en wordt vervolgens de vloer in de nieuwe scène gevonden.

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

Toegang tot Meshes en Quads vanuit scèneobjecten

Zodra SceneObjects zijn gevonden, wil uw toepassing waarschijnlijk toegang krijgen tot de gegevens in de quads/meshes waar deze uit bestaat. Deze gegevens zijn toegankelijk met de eigenschappen Quads _ en _ Meshes . Met de volgende code worden alle quads en meshes van ons vloerobject opsnoemd.


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

U ziet dat het ScèneObject de transformatie heeft die relatief is ten opzichte van de oorsprong van de scène. Dit komt doordat het SceneObject een instantie van een 'ding' vertegenwoordigt en lokaleerbaar is in de ruimte, de quads en meshes geometrie vertegenwoordigen die wordt getransformeerd ten opzichte van het bovenliggende object. Het is mogelijk dat afzonderlijke SceneObjects verwijzen naar dezelfde SceneMesh/SceneQuad SceneComponents, en het is ook mogelijk dat een SceneObject meer dan één SceneMesh/SceneQuad heeft.

Omgaan met transformaties

Scene Understanding heeft een opzettelijke poging gedaan om af te stemmen op traditionele 3D-scèneweergaven bij het omgaan met transformaties. Elke scène is daarom beperkt tot één coördinatensysteem dat lijkt op de meest voorkomende 3D-omgevingsweergaven. SceneObjects geven elk hun locatie ten opzichte van dat coördinaatsysteem. Als uw toepassing te maken heeft met scènes die de limiet van één oorsprong uitstrekken, kan het SceneObjects aan SpatialAnchors ankeren of verschillende scènes genereren en samenvoegen, maar om het eenvoudig te houden, gaan we ervan uit dat watertight-scènes bestaan in hun eigen oorsprong, die is gelokaliseerd door één NodeId die is gedefinieerd door Scene.OriginSpatialGraphNodeId.

De volgende Unity-code laat bijvoorbeeld zien hoe u Windows Perception- en Unity-API's kunt gebruiken om coördinatensystemen op elkaar af te stemmen. Zie SpatialCoordinateSystem en SpatialGraphInteropPreview voor meer informatie over de Windows Perception-API's en Mixed Reality native objecten in Unity voor meer informatie over het verkrijgen van een SpatialCoordinateSystem dat overeenkomt met de oorsprong van 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;
}

Elk SceneObject heeft een transformatie, die vervolgens wordt toegepast op dat object. In Unity converteren we naar rechtshandige coördinaten en wijzen we als het volgende lokale transformaties toe:

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

Quads zijn ontworpen om 2D-plaatsingsscenario's te helpen en moeten worden gebruikt als uitbreidingen voor 2D-canvas UX-elementen. Hoewel Quads onderdelen van SceneObjects zijn en kunnen worden weergegeven in 3D, gaan de Quad-API's zelf ervan uit dat Quads 2D-structuren zijn. Ze bieden informatie zoals omvang, vormen en bieden API's voor plaatsing.

Quads hebben rechthoekige gebied, maar ze vertegenwoordigen willekeurig gevormde 2D-oppervlakken. Plaatsing inschakelen op deze 2D-oppervlakken die communiceren met de 3D-omgeving quads bieden hulpprogramma's om deze interactie mogelijk te maken. Scene Understanding biedt momenteel twee van dergelijke functies: FindCentermostPlacement en GetSurfaceMask. FindCentermostPlacement is een API op hoog niveau die een positie op de quad zoekt waar een object kan worden geplaatst. Er wordt geprobeerd de beste locatie voor uw object te vinden, zodat het begrendingsvak dat u opsteert, op het onderliggende oppervlak blijft.

Notitie

De coördinaten van de uitvoer zijn relatief ten opzichte van de quad in 'quad space' met de linkerbovenhoek (x = 0, y = 0), net als bij andere windows Rect-typen. Zorg ervoor dat u hiermee rekening houdt wanneer u werkt met de oorsprong van uw eigen objecten.

In het volgende voorbeeld ziet u hoe u de meest centrale plaats vindt en een hologram aan de quad ankert.

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

Stappen 1-4 zijn sterk afhankelijk van uw specifieke framework/implementatie, maar de thema's moeten vergelijkbaar zijn. Het is belangrijk te weten dat de Quad simpelweg een begrensd 2D-vlak vertegenwoordigt dat in de ruimte is gelokaliseerd. Door uw engine/framework te laten weten waar de quad zich bevindt en uw objecten ten opzichte van de quad te rooten, bevinden uw hologrammen zich op de juiste manier ten opzichte van de echte wereld.

Mesh

Meshes vertegenwoordigen geometrische weergaven van objecten of omgevingen. Net alsbij ruimtelijke toewijzing gebruiken mesh-index- en hoekpuntgegevens die bij elke spatial surface mesh worden geleverd, dezelfde vertrouwde indeling als de hoekpunt- en indexbuffers die worden gebruikt voor het weergeven van driehoek-meshes in alle moderne rendering-API's. Hoekpuntposities worden opgegeven in het coördinatensysteem van de Scene . De specifieke API's die worden gebruikt om naar deze gegevens te verwijzen, zijn als volgt:

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

De volgende code geeft een voorbeeld van het genereren van een driehoekenlijst op basis van de mesh-structuur:

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

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

De index-/hoekpuntbuffers moeten worden >= het aantal index/hoekpunt, maar anders kan willekeurig worden geformatteerd, waardoor het geheugen efficiënt opnieuw kan worden gebruikt.

ColliderMesh

Scèneobjecten bieden toegang tot mesh- en collider mesh-gegevens via de eigenschappen Meshes en ColliderMeshes. Deze meshes komen altijd overeen, wat betekent dat de i'th-index van de meshes-eigenschap dezelfde geometrie vertegenwoordigt als de i'th-index van de eigenschap ColliderMeshes. Als de runtime/het object ondersteuning biedt voor collider-meshes, krijgt u gegarandeerd de laagste benadering van de polygoon met de hoogste volgorde en is het een goed idee om ColliderMeshes te gebruiken, waar uw toepassing dan ook gebruik zou maken van colliders. Als het systeem geen ondersteuning biedt voor colliders, is het Mesh-object dat wordt geretourneerd in ColliderMeshes hetzelfde object als de mesh die geheugenbeperkingen vermindert.

Ontwikkelen met scènekennis

Op dit punt moet u de kernbouwstenen van de scène begrijpen voor runtime en SDK. Het merendeel van de kracht en complexiteit ligt in toegangspatronen, interactie met 3D-frameworks en hulpprogramma's die boven op deze API's kunnen worden geschreven om geavanceerdere taken uit te voeren, zoals ruimtelijke planning, ruimteanalyse, navigatie, fysica, en meer. We hopen deze vast te leggen in voorbeelden die u hopelijk in de juiste richting kunnen leiden om uw scenario's te laten uitblinken. Als er voorbeelden of scenario's zijn die we niet aanpakken, laat het ons dan weten en proberen we vast te maken wat u nodig hebt.

Waar vind ik voorbeeldcode?

Scene Understanding-voorbeeldcode voor Unity vindt u op onze pagina Voorbeeld van Unity. Met deze toepassing kunt u communiceren met uw apparaat en de verschillende scèneobjecten renderen, of kunt u een geseraliseerde scène op uw pc laden en Scene Understanding zonder apparaat ervaren.

Waar vind ik voorbeeldscènes?

Als u een HoloLens2 hebt, kunt u elke scène opslaan die u hebt vastgelegd door de uitvoer van ComputeSerializedAsync op te slaan in een bestand en deze op uw eigen gemak te deserialiseren.

Als u geen HoloLens2-apparaat hebt, maar wel wilt spelen met Scene Understanding, moet u een vooraf vastgelegde scène downloaden. Het Scene Understanding-voorbeeld wordt momenteel geleverd met geseraliseerde scènes die op uw eigen gemak kunnen worden gedownload en gebruikt. U vindt deze hier:

Scène-inzicht in voorbeeldscènes

Zie ook