Overzicht van SDK voor scènes

Scènebegrip transformeert de ongestructureerde omgevingssensorgegevens die uw Mixed Reality apparaat vastlegt 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 standaardconstructies, zoals 3D-scènegrafieken voor 3D-weergaven en 2D-rechthoeken en -panelen voor 2D-toepassingen. Hoewel de constructies Scene Understanding-nabootsingen worden toegewezen aan concrete frameworks, is SceneUnderstanding in het algemeen framework agnostisch waardoor interoperabiliteit mogelijk is tussen verschillende frameworks die ermee communiceren. Naarmate Scènebegrip zich ontwikkelt, is de rol van de SDK om ervoor te zorgen dat nieuwe representaties en mogelijkheden beschikbaar blijven binnen een geïntegreerd framework. In dit document introduceren we eerst concepten op hoog niveau die u helpen vertrouwd te raken met de ontwikkelomgeving/het gebruik en vervolgens gedetailleerdere documentatie voor specifieke klassen en constructies.

Waar vind ik de SDK?

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

Opmerking: de nieuwste release is afhankelijk van preview-pakketten en u moet pre-releasepakketten 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 ondersteunt SceneUnderstanding unity in-editor-ondersteuning, behalve de SceneObserver, die alleen wordt gebruikt voor communicatie met HoloLens2.

Voor SceneUnderstanding is Windows SDK versie 18362 of hoger vereist.

Conceptueel overzicht

De scène

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

Het proces van het converteren van de onbewerkte sensorgegevens naar een scène is een potentieel dure bewerking die seconden kan duren voor middelgrote ruimten (~10x10m) tot minuten voor grote ruimten (~50x50m) en daarom is het niet iets dat zonder toepassingsaanvraag door het apparaat wordt berekend. In plaats daarvan wordt het genereren van scènes op aanvraag geactiveerd door uw toepassing. De klasse SceneObserver heeft statische methoden waarmee u een scène kunt berekenen of deserialiseren, die u vervolgens kunt opsommen/gebruiken. De actie 'Berekenen' wordt uitgevoerd op aanvraag en wordt uitgevoerd op de CPU, maar in een afzonderlijk proces (het Mixed Reality stuurprogramma). Terwijl we echter berekeningen uitvoeren in een ander proces, 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 gekoppeld aan de Scene Understanding-runtime.

Procesdiagram

Aan de linkerkant ziet u een diagram van de mixed reality-runtime, die altijd is ingeschakeld en in een eigen proces wordt uitgevoerd. Deze runtime is verantwoordelijk voor het bijhouden van apparaten, ruimtelijke toewijzingen en andere bewerkingen die Scene Understanding gebruikt om inzicht te krijgen in en te redeneren over de wereld om u heen. Aan de rechterkant van het diagram tonen we twee theoretische toepassingen die gebruikmaken van Scene Understanding. De eerste toepassing maakt een interface met MRTK, die intern gebruikmaakt van de Scene Understanding SDK, de tweede app berekent en gebruikt twee afzonderlijke scène-exemplaren. Alle drie de scènes in dit diagram genereren afzonderlijke exemplaren van de scènes. Het stuurprogramma houdt geen globale status bij die wordt gedeeld tussen toepassingen en scèneobjecten in de ene scène zijn niet gevonden in een andere scène. Scene Understanding biedt een mechanisme om in de loop van 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 opslaat in de geheugenruimte van uw toepassing, kunt u ervan uitgaan dat alle functies van het Scène-object of de interne gegevens altijd worden uitgevoerd in het proces van uw toepassing.

Layout

Als u met Scene Understanding wilt werken, kan het waardevol 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 met behoud van een onderliggende structuur die buigzaam is om te 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 door middel van verwijzingen waarbij specifieke onderdelen naar anderen verwijzen.

Hieronder ziet u een voorbeeld van een structuur 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 ziet u het verschil tussen de fysieke en logische indeling van de scène. Aan de linkerkant zien we de hiërarchische indeling van de gegevens die uw toepassing ziet bij het inventariseren van de scène. Aan de rechterkant zien we dat de scène bestaat uit 12 verschillende onderdelen die indien nodig afzonderlijk toegankelijk zijn. Bij het verwerken van een nieuwe scène verwachten we dat toepassingen deze hiërarchie logisch doorlopen, maar bij het bijhouden tussen scène-updates zijn sommige toepassingen mogelijk alleen geïnteresseerd in specifieke onderdelen die tussen twee scènes worden gedeeld.

API-overzicht

De volgende sectie biedt een algemeen overzicht van de constructies in Scènebegrip. Als u deze sectie leest, krijgt u inzicht in hoe scènes worden weergegeven en waarvoor de verschillende onderdelen worden gebruikt. In de volgende sectie vindt u concrete codevoorbeelden en aanvullende details die in dit overzicht worden verdoezeld.

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

SceneComponents

Nu u de logische indeling van scènes begrijpt, kunnen we het concept scèneonderdelen presenteren en hoe deze worden gebruikt om de hiërarchie samen te stellen. SceneComponents zijn de meest gedetailleerde ontledingen in SceneUnderstanding die één kernonderdeel vertegenwoordigen, bijvoorbeeld een mesh of een quad of een begrenzingsvak. SceneComponents zijn dingen die onafhankelijk kunnen worden bijgewerkt en waarnaar kan worden verwezen door andere SceneComponents. Daarom hebben ze één globale eigenschap, een unieke id, die dit type tracerings-/verwijzingsmechanisme mogelijk maakt. Id's worden gebruikt voor de logische samenstelling van de scènehiërarchie en voor objectpersistentie (het bijwerken van een scène ten opzichte van een andere scène).

Als u elke nieuw berekende scène als uniek behandelt en gewoon alle gegevens hierin opsommen, zijn id's grotendeels transparant voor u. Als u echter van plan bent om onderdelen via verschillende updates bij te houden, gebruikt u de id's om ScèneOnderdelen tussen scèneobjecten te indexeren en te vinden.

SceneObjects

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

SceneObjects kan een van de volgende opties hebben:

SceneObjectKind Beschrijving
AchtergrondHet SceneObject is niet bekend als een van de andere herkende soorten scèneobjecten. Deze klasse moet niet worden verward met Onbekend, waarbij achtergrond bekend staat om niet muur/vloer/plafond enz.... onbekend is nog niet gecategoriseerd.
WandEen fysieke muur. Wanden worden verondersteld onroerende omgevingsstructuren te zijn.
FloorVloeren zijn alle oppervlakken waarop men kan lopen. Let op: trappen zijn geen verdiepingen. Houd er ook rekening mee dat vloeren een beloopbaar oppervlak aannemen en daarom is er geen expliciete veronderstelling van een enkelvoudige vloer. Structuren met meerdere niveaus, hellingen enz.... moet allemaal worden geclassificeerd als vloer.
CeilingHet bovenoppervlak van een kamer.
PlatformEen groot vlak oppervlak waarop u hologrammen kunt plaatsen. Deze vertegenwoordigen meestal tabellen, werkbladen en andere grote horizontale oppervlakken.
WereldEen gereserveerd label voor geometrische gegevens die agnostisch zijn voor labelen. De mesh die wordt gegenereerd door het instellen van de updatevlag EnableWorldMesh, wordt geclassificeerd als wereld.
OnbekendDit scèneobject moet nog worden geclassificeerd en een soort zijn toegewezen. Dit moet niet worden verward met Achtergrond, omdat dit object van alles kan zijn, heeft het systeem er nog geen sterke classificatie voor bedacht.

SceneMesh

Een SceneMesh is een SceneComponent die de geometrie van willekeurige geometrische objecten benadert met behulp van een driehoekslijst. SceneMeshes worden gebruikt in verschillende contexten; ze kunnen componenten van de waterdichte celstructuur vertegenwoordigen of als de WorldMesh, die het niet-gebonden ruimtelijke toewijzingsnet vertegenwoordigt dat is gekoppeld aan de scène. De index- en hoekpuntgegevens die bij elk net worden geleverd, maken gebruik van dezelfde vertrouwde indeling als de hoekpunt- en indexbuffers die worden gebruikt voor het renderen van driehoeksnetten in alle moderne rendering-API's. In Scene Understanding gebruiken meshes 32-bits indexen en moeten ze mogelijk worden opgesplitst in segmenten voor bepaalde rendering-engines.

Wikkelvolgorde en coördinatensystemen

Van alle meshes die door Scene Understanding worden geproduceerd, wordt verwacht dat ze meshes retourneren in een Right-Handed coördinatensysteem met behulp van de wikkelvolgorde met de klok mee.

Opmerking: OS-builds ouder dan .191105 hebben mogelijk een bekende fout waarbij 'World'-meshes in Counter-Clockwise wikkelvolgorde terugkeerden, wat vervolgens is opgelost.

SceneQuad

Een SceneQuad is een SceneComponent die 2d-oppervlakken vertegenwoordigt die de 3D-wereld bezetten. SceneQuads kan op dezelfde manier worden gebruikt als ARKit ARPlaneAnchor of ARCore Planes, maar ze bieden meer functionaliteit op hoog niveau als 2d-canvassen die kunnen worden gebruikt door platte apps of uitgebreide UX. 2D-specifieke API's zijn beschikbaar voor quads die plaatsing en indeling eenvoudig te gebruiken maken, en het ontwikkelen (met uitzondering van rendering) met quads moet meer lijken op het werken met 2d-canvassen dan 3d-meshes.

SceneQuad-shape

SceneQuads definieert een begrensd rechthoekig 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 weergeven, kunt u de Api GetSurfaceMask gebruiken om de vorm van het oppervlak weer te geven op een afbeeldingsbuffer die u opgeeft. Als het ScèneObject met de quad ook een net heeft, moeten de mesh-driehoeken gelijk zijn aan deze weergegeven afbeelding, ze vertegenwoordigen beide de echte geometrie van het oppervlak, in 2d- of 3d-coördinaten.

Scène over SDK-details en -naslaginformatie

Notitie

Wanneer u MRTK gebruikt, moet u er rekening mee houden dat u communiceert met MRTK's ['WindowsSceneUnderstandingObserver'](xref:Microsoft.MixedReality.Toolkit.WindowsSceneUnderstanding.Experimental.WindowsSceneUnderstandingObserver?view=mixed-reality-toolkit-unity-2020-dotnet-2.8.0&preserve-view=true) en dus deze sectie onder de meeste omstandigheden overslaan. Raadpleeg de [MRTK Scene Understanding docs](/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 basisbeginselen, waarna u voldoende context hebt 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 een verwijzing krijgt naar een Scène-object. 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 gedeserialiseerd. Dit laatste is handig voor het werken met SceneUnderstanding tijdens de ontwikkeling, waarbij toepassingen en ervaringen snel kunnen worden geprototypeerd 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 om gebruikerstoegang aan te vragen 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 straal 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 op basis van gegevens (ook wel het pc-pad genoemd)

Hoewel scènes kunnen worden berekend voor direct verbruik, kunnen ze ook in geserialiseerde vorm worden berekend voor later gebruik. Dit is nuttig gebleken voor ontwikkeling, omdat ontwikkelaars hiermee in Scene Understanding kunnen werken en testen zonder dat ze een apparaat nodig hebben. 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 deze 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

Opsomming SceneObject

Nu uw toepassing een scène heeft, bekijkt en communiceert uw toepassing met SceneObjects. 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 verfijnen

Er is een andere functie die onderdelen in de scène ophaalt, genaamd 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 verdieping 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 is gevonden, wil uw toepassing waarschijnlijk toegang krijgen tot de gegevens die zijn opgenomen in de quads/meshes waaruit deze bestaat. Deze gegevens worden geopend met de eigenschappen Quads en Meshes . Met de volgende code worden alle quads en meshes van het vloerobject opgesomd.


// 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 SceneObject is met de transformatie die relatief is ten opzichte van de oorsprong van de scène. Dit komt doordat het SceneObject een exemplaar van een 'ding' vertegenwoordigt en in de ruimte kan worden geplaatst, de quads en meshes de geometrie vertegenwoordigen die ten opzichte van het bovenliggende object wordt getransformeerd. 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

Scènebegrip heeft bewust geprobeerd om af te stemmen op traditionele 3D-scèneweergaven bij transformaties. Elke scène is daarom beperkt tot één coördinatensysteem, net zoals de meeste gangbare 3D-omgevingsweergaven. SceneObjects bieden elk hun locatie ten opzichte van dat coördinatensysteem. Als uw toepassing te maken heeft met scènes die de limiet van wat één oorsprong biedt, kunnen SceneObjects verankeren aan SpatialAnchors, of verschillende scènes genereren en samenvoegen, maar voor het gemak gaan we ervan uit dat waterdichte 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 gebruikt om coördinatensystemen met elkaar uit te lijnen. Zie SpatialCoordinateSystem en SpatialGraphInteropPreview voor meer informatie over de Windows Perception-API's en Mixed Reality systeemeigen objecten in Unity voor meer informatie over het verkrijgen van een SpatialCoordinateSystem dat overeenkomt met de oorsprong van de wereld 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);
    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;
}

Elk SceneObject heeft een transformatie, die vervolgens op dat object wordt toegepast. In Unity converteren we naar rechtshandige coördinaten en wijzen we lokale transformaties als volgt 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 beschouwd als uitbreidingen van 2D-canvas-UX-elementen. Hoewel Quads onderdelen zijn van SceneObjects en in 3D kunnen worden weergegeven, gaan de Quad-API's zelf ervan uit dat Quads 2D-structuren zijn. Ze bieden informatie zoals omvang, vorm en api's voor plaatsing.

Quads hebben rechthoekige gebieden, maar ze vertegenwoordigen willekeurig gevormde 2D-oppervlakken. Om plaatsing in te schakelen op deze 2D-oppervlakken die communiceren met de 3D-omgeving bieden quads 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 waarmee een positie op de quad wordt gevonden waar een object kan worden geplaatst en wordt geprobeerd de beste locatie voor uw object te vinden die garandeert dat het begrenzingsvak dat u opgeeft, op het onderliggende oppervlak blijft.

Notitie

De coördinaten van de uitvoer zijn relatief ten opzichte van de quad in 'quad-ruimte' met de linkerbovenhoek (x = 0, y = 0), net zoals bij andere vensters Rect-typen. Houd hier rekening mee bij het werken met de oorsprong van uw eigen objecten.

In het volgende voorbeeld ziet u hoe u de meest centrale locatie kunt vinden en een hologram aan de quad kunt verankeren.

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

Stap 1-4 is sterk afhankelijk van uw specifieke framework/implementatie, maar de thema's moeten vergelijkbaar zijn. Het is belangrijk te weten dat de Quad eenvoudigweg een begrensd 2D-vlak vertegenwoordigt dat in de ruimte is gelokaliseerd. Door uw motor/framework te laten weten waar de quad is en uw objecten ten opzichte van de quad te rooten, worden uw hologrammen correct geplaatst ten opzichte van de echte wereld.

Mesh

Meshes vertegenwoordigen geometrische representaties van objecten of omgevingen. Net als bij ruimtelijke toewijzing gebruiken mesh-index- en hoekpuntgegevens die bij elk ruimtelijk oppervlaknet worden geleverd dezelfde vertrouwde indeling als de hoekpunt- en indexbuffers die worden gebruikt voor het renderen van driehoeksnetten 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 biedt een voorbeeld van het genereren van een lijst met driehoeken uit 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 = het aantal indexen/hoekpunten zijn >, maar anders kan de grootte willekeurig worden aangepast, zodat het geheugen efficiënt kan worden hergebruikt.

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 eigenschap Meshes dezelfde geometrie vertegenwoordigt als de i'th-index van de eigenschap ColliderMeshes. Als de runtime/het object collider-meshes ondersteunt, krijgt u gegarandeerd de laagste benadering van de veelhoek en de hoogste orde en is het een goede gewoonte om ColliderMeshes overal te gebruiken waar uw toepassing colliders zou gebruiken. Als het systeem geen ondersteuning biedt voor colliers, is het Mesh-object dat wordt geretourneerd in ColliderMeshes hetzelfde object als de geheugenbeperkingen voor mesh-reductie.

Ontwikkelen met inzicht in scènes

Op dit punt moet u de belangrijkste bouwstenen van de scène begrijpen, zoals runtime en SDK. Het grootste deel van de kracht en complexiteit ligt in toegangspatronen, interactie met 3D-frameworks en hulpprogramma's die bovenop deze API's kunnen worden geschreven om geavanceerdere taken uit te voeren, zoals ruimtelijke planning, ruimteanalyse, navigatie, natuurkunde, enzovoort. We hopen deze vast te leggen in voorbeelden die u hopelijk in de juiste richting moeten helpen om uw scenario's te laten schitteren. Als er voorbeelden of scenario's zijn die we niet behandelen, laat het ons dan weten en we proberen te documenteren/prototypen te maken van wat u nodig hebt.

Waar kan ik voorbeeldcode ophalen?

Voorbeeldcode voor Scene Understanding voor Unity vindt u op de pagina Unity-voorbeeldpagina . Met deze toepassing kunt u communiceren met uw apparaat en de verschillende scèneobjecten weergeven, of u kunt een geserialiseerde scène op uw pc laden en u scènebegrip zonder apparaat laten ervaren.

Waar vind ik voorbeeldscènes?

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

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

Scènes begrijpen voorbeeldscènes

Zie ook