Overzicht van Scene Understanding SDK

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 scènebegrip-nabootsingen worden toegewezen aan concrete frameworks, is ScèneUnderstanding in het algemeen agnostisch framework dat interoperabiliteit mogelijk maakt tussen verschillende frameworks die ermee communiceren. Naarmate Scènebegrip zich ontwikkelt, wordt de rol van de SDK ontwikkeld om ervoor te zorgen dat nieuwe weergaven en mogelijkheden binnen een geïntegreerd framework beschikbaar blijven. 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 te bieden voor specifieke klassen en constructies.

Waar krijg 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++ waarmee toepassingen kunnen worden ontwikkeld voor Win32- of UWP-platforms. Vanaf deze versie ondersteunt SceneUnderstanding unity in-editor ondersteuning voor het blokkeren van de SceneObserver, die uitsluitend 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 leidt al deze gegevensbronnen 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 wand/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 vertegenwoordigen.

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 wordt berekend door het apparaat zonder aanvraag. In plaats daarvan wordt het genereren van scènes geactiveerd door uw toepassing op aanvraag. De klasse SceneObserver heeft statische methoden waarmee u een scène kunt berekenen of deserialiseren, waarmee u vervolgens kunt inventariseren/werken. De 'Compute'-actie wordt op aanvraag uitgevoerd en uitgevoerd op de CPU, maar in een afzonderlijk proces (het Mixed Reality stuurprogramma). Hoewel 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.

Process Diagram

Aan de linkerkant ziet u een diagram van de mixed reality-runtime, die altijd actief is en in een eigen proces wordt uitgevoerd. Deze runtime is verantwoordelijk voor het uitvoeren van apparaattracking, ruimtelijke toewijzing en andere bewerkingen die Scene Understanding gebruikt om inzicht te krijgen en reden te geven over de wereld om u heen. Aan de rechterkant van het diagram tonen we twee theoretische toepassingen die gebruikmaken van Scene Understanding. De eerste toepassingsinterfaces met MRTK, die intern gebruikmaken van de Scene Understanding SDK, berekent de tweede app en maakt gebruik van twee afzonderlijke scène-exemplaren. Alle drie de scènes in dit diagram genereren afzonderlijke exemplaren van de scènes. Het stuurprogramma houdt de globale status niet bij die wordt gedeeld tussen toepassingen en scèneobjecten in de ene scène. Scene Understanding biedt wel een mechanisme om na verloop van 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 in de geheugenruimte van uw toepassing opslaat, 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

Om te werken met Scene Understanding, 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 is gekozen om eenvoudig te zijn, terwijl een onderliggende structuur behouden blijft die flexibel 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 via verwijzingen waar specifieke onderdelen naar anderen verwijzen.

Hieronder presenteren we 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 wordt het verschil tussen de fysieke en logische indeling van de scène gemarkeerd. 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 afzonderlijke 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 het richten op specifieke onderdelen die tussen twee scènes worden gedeeld.

API-overzicht

In de volgende sectie vindt u een overzicht van de constructies in Scene Understanding. Als u deze sectie leest, krijgt u inzicht in de weergave van scènes en wat de verschillende onderdelen doen/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ènecomponents presenteren en hoe ze worden gebruikt voor het opstellen van een hiërarchie. SceneComponents zijn de meest gedetailleerde decomposities in SceneUnderstanding die één kernpunt 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 objectpersistentie (het bijwerken van de ene scène ten opzichte van een andere scène).

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

SceneObjects

Een SceneObject is een SceneComponent die een exemplaar van een 'ding' vertegenwoordigt, bijvoorbeeld een muur, een vloer, een plafond, enzovoort... uitgedrukt door hun soort eigendom. 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 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 inventariseren om te verwerken waar deze in geïnteresseerd is.

SceneObjects kan een van de volgende opties hebben:

SceneObjectKind Beschrijving
AchtergrondHet SceneObject is bekend dat het geen van de andere herkende soorten scèneobject is. Deze klasse mag niet worden verward met Onbekend waar Achtergrond bekend is dat het geen muur/ vloer/plafond enz.... hoewel onbekend nog niet is gecategoriseerd.
MuurEen fysieke muur. Wanden worden verondersteld onroerende omgevingsstructuren te zijn.
FloorVloeren zijn eventuele oppervlakken waarop men kan lopen. Opmerking: trappen zijn geen verdiepingen. Houd er ook rekening mee dat vloeren elk loopbaar oppervlak aannemen en daarom is er geen expliciete aanname van een enkelvoudige vloer. Structuren op meerdere niveaus, hellingen enz.... moeten allemaal als vloer worden geclassificeerd.
CeilingHet bovenste oppervlak van een kamer.
PlatformEen groot vlak oppervlak waarop u hologrammen kunt plaatsen. Deze vormen meestal tabellen, werkbladen en andere grote horizontale oppervlakken.
WereldEen gereserveerd label voor geometrische gegevens die agnostisch zijn voor labelen. Het mesh dat wordt gegenereerd door het instellen van de updatevlag EnableWorldMesh, wordt geclassificeerd als wereld.
OnbekendDit scèneobject moet nog een soort worden geclassificeerd en toegewezen. Dit moet niet worden verward met Achtergrond, omdat dit object iets kan zijn, het systeem heeft alleen nog geen sterke classificatie voor het.

SceneMesh

Een SceneMesh is een SceneComponent die de geometrie van willekeurige geometrische objecten benadert met behulp van een driehoekslijst. SceneMeshes worden in verschillende contexten gebruikt; ze kunnen onderdelen van de waterdichte celstructuur of als de WorldMesh vertegenwoordigen, die het niet-gebonden ruimtelijke toewijzingsnet vertegenwoordigen dat is gekoppeld aan de Scène. De index- en hoekpuntgegevens die bij elk mesh worden geleverd, maken gebruik van dezelfde vertrouwde indeling als het hoekpunt en de indexbuffers die worden gebruikt voor het weergeven van driehoeksgaas 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.

Wikkelingsvolgorde- en coördinaatsystemen

Alle meshes die door Scene Understanding worden geproduceerd, zullen naar verwachting meshes retourneren in een Right-Handed coördinaatsysteem met behulp van de volgorde van de klokgewijze wikkeling.

Opmerking: os-builds vóór .191105 kunnen een bekende bug hebben waarbij "World" meshes terugkeerden in Counter-Clockwise wikkelingsvolgorde, die 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-canvass die moeten worden gebruikt door platte apps of augmented UX. 2D-specifieke API's zijn beschikbaar voor quads die plaatsing en indeling eenvoudig te gebruiken maken, en ontwikkelen (met uitzondering van rendering) met quads moeten meer lijken op het werken met 2d canvass dan 3d meshes.

ScèneQuad-vorm

SceneQuads definiëren 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 GetSurfaceMask-API gebruiken om de vorm van het oppervlak weer te geven op een afbeeldingsbuffer die u opgeeft. Als het SceneObject met de quad ook een mesh heeft, moeten de mesh-driehoeken gelijk zijn aan deze gerenderde afbeelding, ze beide vertegenwoordigen echte geometrie van het oppervlak, hetzij in 2d- of 3d-coördinaten.

Informatie over SDK-details en -naslaginformatie over scènes

Notitie

Wanneer u MRTK gebruikt, moet u contact opnemen met MRTK's ['WindowsSceneUnderstandingObserver'](xref:Microsoft.MixedReality.Toolkit. WindowsSceneUnderstanding.Experimental.WindowsSceneUnderstandingObserver) en kan deze sectie dus 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 basisprincipes van SceneUnderstanding. In deze sectie krijgt u de basisbeginselen. Op dat moment moet u voldoende context hebben om door de voorbeeldtoepassingen te bladeren om te zien hoe SceneUnderstanding holistisch wordt gebruikt.

Initialisatie

De eerste stap bij het werken met SceneUnderstanding is dat uw toepassing verwijst 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. Het laatste is handig voor het werken met SceneUnderstanding tijdens de ontwikkeling, waarbij toepassingen en ervaringen snel kunnen worden prototypen 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 het ScèneUnderstanding ondersteunt, 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 gaan we een nieuwe scène berekenen 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 van gegevens (ook wel bekend als het pc-pad)

Hoewel scènes kunnen worden berekend voor direct verbruik, kunnen ze ook worden berekend in geserialiseerde vorm voor later gebruik. Dit is nuttig gebleken voor ontwikkeling, omdat ontwikkelaars hiermee scèneinzicht kunnen werken en testen zonder dat ze een apparaat nodig hebben. De handeling van 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. Vervolgens kunt u het 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 Scèneobject

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 waarmee onderdelen worden opgehaald in de Scène 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 van scèneobjecten

Zodra SceneObjects is gevonden, wilt uw toepassing waarschijnlijk toegang krijgen tot de gegevens die zijn opgenomen in de quads/meshes waarvan deze bestaat. Deze gegevens worden geopend met de eigenschappen Quads en Meshes . Met de volgende code worden alle quads en meshes van ons 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 het SceneObject is dat de transformatie heeft die relatief is ten opzichte van de scène-oorsprong. Dit komt doordat het SceneObject een exemplaar van een 'ding' vertegenwoordigt en kan worden gelocateerbaar in de ruimte, de quads en meshes vertegenwoordigen geometrie die ten opzichte van hun 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 opzettelijk geprobeerd om in overeenstemming te komen met traditionele 3D-scèneweergaven bij het omgaan met transformaties. Elke scène is daarom beperkt tot één coördinaatsysteem, net zoals de meest voorkomende 3D-omgevingsweergaven. SceneObjects bieden elk hun locatie ten opzichte van dat coördinaatsysteem. Als uw toepassing te maken heeft met Scènes die de limiet van wat één oorsprong biedt, kan ScèneObjects ankeren naar SpatialAnchors, of verschillende scènes genereren en deze samenvoegen, maar voor het gemak gaan we ervan uit dat er 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 kunt gebruiken om coördinaatsystemen 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 SpatialCodinaSystem 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 extensies 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, vorm, en bieden API's voor plaatsing.

Quads hebben rechthoekige gebieden, maar ze vertegenwoordigen willekeurige 2D-oppervlakken. Om plaatsing mogelijk te maken 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 functies, FindCentermostPlacement en GetSurfaceMask. FindCentermostPlacement is een API op hoog niveau die een positie op de quad zoekt waar een object kan worden geplaatst en zal proberen 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 wanneer u met de oorsprong van uw eigen objecten werkt.

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

// 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 om te weten dat de Quad gewoon een gebonden 2D-vlak vertegenwoordigt dat in de ruimte is gelokaliseerd. Door uw engine/framework te laten weten waar de quad zich bevindt en uw objecten verwortelt ten opzichte van de quad, bevinden uw hologrammen zich correct met betrekking tot de echte wereld.

Mesh

Meshes vertegenwoordigen geometrische representaties van objecten of omgevingen. Net als bij ruimtelijke toewijzing, mesh-index en hoekpuntgegevens die bij elke ruimtelijke surface mesh worden geleverd, wordt dezelfde vertrouwde indeling gebruikt als de hoekpunt- en indexbuffers die worden gebruikt voor het weergeven van driehoeksgaas in alle moderne rendering-API's. Hoekpuntposities worden verstrekt in het coördinaatsysteem 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 bevat een voorbeeld van het genereren van een driehoekslijst 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 willekeurig worden aangepast, waardoor efficiënt geheugen 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 het runtime/object collider meshes ondersteunt, krijgt u gegarandeerd de laagste veelhoek, de hoogste order benadering en is het een goede gewoonte om ColliderMeshes te gebruiken waar uw toepassing ook colliders zou gebruiken. Als het systeem geen colliders ondersteunt, is het Mesh-object dat wordt geretourneerd in ColliderMeshes hetzelfde object als het mesh dat geheugenbeperkingen vermindert.

Ontwikkelen met inzicht in scènes

Op dit moment moet u inzicht krijgen in de belangrijkste bouwstenen van de scène waarin runtime en SDK worden begrepen. 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, fysica, enzovoort. We hopen deze vast te leggen in voorbeelden die u hopelijk in de juiste richting moeten begeleiden om uw scenario's te laten schitteren. Als er voorbeelden of scenario's zijn die we niet aanpakken, laat het ons dan weten en proberen we te documenteren/prototypen te maken wat u nodig hebt.

Waar kan ik voorbeeldcode ophalen?

Scene Understanding-voorbeeldcode voor Unity vindt u op onze pagina Unity-voorbeeldpagina . Met deze toepassing kunt u communiceren met uw apparaat en de verschillende scèneobjecten weergeven, of u kunt hiermee een geserialiseerde scène op uw pc laden en scènes begrijpen zonder een apparaat.

Waar kan ik voorbeeldscènes krijgen?

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

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

Scènes begrijpen voorbeeldscènes

Zie ook