Panoramica di Scene Understanding SDK

La comprensione della scena trasforma i dati dei sensori di ambiente non strutturati acquisiti dal dispositivo Realtà mista e lo converte in una potente rappresentazione astratta. L'SDK funge da livello di comunicazione tra l'applicazione e il runtime di Scene Understanding. È destinato a simulare costrutti standard esistenti, ad esempio grafici della scena 3D per le rappresentazioni 3D e rettangoli 2D e pannelli per le applicazioni 2D. Mentre i costrutti Scene Understanding simulano il mapping a framework concreti, in generale SceneUnderstanding è indipendente dal framework che consente l'interoperabilità tra framework diversi che interagiscono con esso. Man mano che Scene Understanding evolve il ruolo dell'SDK, è garantire che le nuove rappresentazioni e funzionalità continuino a essere esposte all'interno di un framework unificato. In questo documento verranno presentati innanzitutto concetti di alto livello che consentiranno di acquisire familiarità con l'ambiente di sviluppo o l'utilizzo e quindi fornire una documentazione più dettagliata per classi e costrutti specifici.

Dove si ottiene l'SDK?

SceneUnderstanding SDK è scaricabile tramite lo strumento di funzionalità Realtà mista.

Nota: la versione più recente dipende dai pacchetti di anteprima e sarà necessario abilitare i pacchetti non definitive per visualizzarlo.

Per la versione 0.5.2022 rc e successive, Scene Understanding supporta proiezioni del linguaggio per C# e C++ che consentono alle applicazioni di sviluppare applicazioni per piattaforme Win32 o UWP. A partire da questa versione, SceneUnderstanding supporta unity nell'editor supportando la barra di SceneObserver, che viene usata esclusivamente per comunicare con HoloLens2.

SceneUnderstanding richiede Windows SDK versione 18362 o successiva.

Panoramica dei concetti

La scena

Il dispositivo di realtà mista integra costantemente informazioni su ciò che vede nell'ambiente. Scene Understanding imbuto tutte queste origini dati e produce un'unica astrazione coesa. Scene Understanding genera scene, che sono una composizione di SceneObject che rappresentano un'istanza di una singola cosa, ad esempio un muro/soffitto/pavimento. Gli oggetti scena stessi sono una composizione di [SceneComponents, che rappresentano parti più granulari che costituiscono questo SceneObject. Esempi di componenti sono quad e mesh, ma in futuro potrebbero rappresentare rettangoli di selezione, mesh di collisione, metadati e così via.

Il processo di conversione dei dati del sensore non elaborati in una scena è un'operazione potenzialmente costosa che potrebbe richiedere secondi per spazi medi (~10x10m) in minuti per spazi di grandi dimensioni (~50x50m) e pertanto non è qualcosa che viene calcolato dal dispositivo senza richiesta dell'applicazione. La generazione della scena viene invece attivata dall'applicazione su richiesta. La classe SceneObserver include metodi statici in grado di calcolare o deserializzare una scena, che è quindi possibile enumerare/interagire con. L'azione "Calcolo" viene eseguita su richiesta ed eseguita sulla CPU, ma in un processo separato (il driver Realtà mista). Tuttavia, mentre si esegue il calcolo in un altro processo, i dati della scena risultanti vengono archiviati e gestiti nell'applicazione nell'oggetto Scene.

Di seguito è riportato un diagramma che illustra questo flusso di processo e mostra esempi di due applicazioni che si interfacciano con il runtime di Scene Understanding.

Diagramma del processo

Sul lato sinistro è un diagramma del runtime di realtà mista, che è sempre attivo e in esecuzione nel proprio processo. Questo runtime è responsabile dell'esecuzione del rilevamento dei dispositivi, del mapping spaziale e di altre operazioni usate da Scene Understanding per comprendere e ragionare sul mondo intorno all'utente. Sul lato destro del diagramma vengono illustrate due applicazioni teorice che usano Scene Understanding. La prima interfaccia dell'applicazione con MRTK, che usa internamente Scene Understanding SDK, la seconda app calcola e usa due istanze della scena separate. Tutte e tre le scene in questo diagramma generano istanze distinte delle scene, il driver non rileva lo stato globale condiviso tra applicazioni e oggetti scena in una scena non viene trovato in un'altra. Scene Understanding fornisce un meccanismo per tenere traccia nel tempo, ma questa operazione viene eseguita usando l'SDK. Il codice di rilevamento è già in esecuzione nell'SDK nel processo dell'app.

Poiché ogni scena archivia i dati nello spazio di memoria dell'applicazione, è possibile presupporre che tutte le funzioni dell'oggetto Scene o i relativi dati interni vengano sempre eseguiti nel processo dell'applicazione.

Layout

Per lavorare con Scene Understanding, può essere utile conoscere e comprendere in che modo il runtime rappresenta i componenti in modo logico e fisico. La scena rappresenta i dati con un layout specifico che è stato scelto per essere semplice mantenendo una struttura sottostante in grado di soddisfare i requisiti futuri senza dover apportare revisioni importanti. La scena esegue questa operazione archiviando tutti i componenti (blocchi predefiniti per tutti gli oggetti scena) in un elenco semplice e definendo gerarchia e composizione tramite riferimenti in cui i componenti specifici fanno riferimento ad altri.

Di seguito viene presentato un esempio di struttura sia in forma piatta che logica.

Layout logicoLayout fisico
    Scene
    • 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

Questa figura evidenzia la differenza tra il layout fisico e logico della scena. A sinistra viene visualizzato il layout gerarchico dei dati visualizzati dall'applicazione durante l'enumerazione della scena. A destra si noterà che la scena è costituita da 12 componenti distinti accessibili singolarmente, se necessario. Durante l'elaborazione di una nuova scena, ci aspettiamo che le applicazioni eseguino logicamente questa gerarchia, tuttavia quando si esegue il rilevamento tra gli aggiornamenti della scena, alcune applicazioni potrebbero essere interessate solo alla destinazione di componenti specifici condivisi tra due scene.

Panoramica delle API

La sezione seguente offre una panoramica generale dei costrutti in Comprensione della scena. La lettura di questa sezione offre una comprensione del modo in cui vengono rappresentate le scene e di cosa fanno/vengono usati i vari componenti. La sezione successiva fornirà esempi di codice concreti e dettagli aggiuntivi illustrati in questa panoramica.

Tutti i tipi descritti di seguito risiedono nello spazio dei Microsoft.MixedReality.SceneUnderstanding nomi .

SceneComponents

Dopo aver compreso il layout logico delle scene, è possibile presentare il concetto di SceneComponents e il modo in cui vengono usati per comporre la gerarchia. SceneComponents sono le scomposizione più granulari in SceneUnderstanding che rappresentano una singola cosa di base, ad esempio una mesh o un quad o un rettangolo di selezione. SceneComponents sono elementi che possono essere aggiornati in modo indipendente e a cui possono fare riferimento altri SceneComponents, di conseguenza hanno una singola proprietà globale, un ID univoco, che consentono questo tipo di meccanismo di rilevamento/riferimento. Gli ID vengono usati per la composizione logica della gerarchia della scena e per la persistenza degli oggetti (l'azione di aggiornamento di una scena rispetto a un'altra).

Se si tratta ogni scena appena calcolata come distinta e si enumera semplicemente tutti i dati al suo interno, gli ID sono in gran parte trasparenti per l'utente. Tuttavia, se si prevede di tenere traccia dei componenti in diversi aggiornamenti, si useranno gli ID per indicizzare e trovare SceneComponents tra gli oggetti Scene.

SceneObjects

SceneObject è un Oggetto SceneComponent che rappresenta un'istanza di una "cosa", ad esempio una parete, un pavimento, un soffitto e così via. espressa dalla loro proprietà Kind. SceneObjects sono geometrici e pertanto hanno funzioni e proprietà che rappresentano la loro posizione nello spazio, ma non contengono alcuna struttura geometrica o logica. SceneObjects fa invece riferimento ad altri SceneComponents, in particolare SceneQuads e SceneMeshes, che forniscono le varie rappresentazioni supportate dal sistema. Quando viene calcolata una nuova scena, è probabile che l'applicazione enumeri gli Oggetti Scene della scena per elaborare ciò che interessa.

SceneObjects può avere uno dei seguenti elementi:

SceneObjectKind Descrizione
SfondoSceneObject è noto come non uno degli altri tipi riconosciuti di oggetto scena. Questa classe non deve essere confusa con Sconosciuto dove Background non è noto per essere muro/pavimento/soffitto ecc.... mentre sconosciuto non è ancora categorizzato.
PareteUn muro fisico. Si presuppone che le pareti siano strutture ambientali rimovibili.
PianoI pavimenti sono superfici su cui si può camminare. Nota: le scale non sono pavimenti. Si noti anche che i pavimenti presuppongono qualsiasi superficie camminabile e pertanto non esiste alcun presupposto esplicito di un pavimento singolare. Strutture multilivello, rampe e così via... deve classificare tutti come piano.
CeilingSuperficie superiore di una stanza.
PiattaformaUna grande superficie piatta su cui è possibile posizionare ologrammi. Questi tendono a rappresentare tabelle, controtop e altre superfici orizzontali di grandi dimensioni.
WorldEtichetta riservata per i dati geometrici che sono agnostici per l'etichettatura. La mesh generata impostando il flag di aggiornamento EnableWorldMesh verrebbe classificato come mondo.
SconosciutoQuesto oggetto scena deve essere ancora classificato e assegnato un tipo. Questo non dovrebbe essere confuso con Background, perché questo oggetto potrebbe essere qualsiasi cosa, il sistema non ha appena creato una classificazione abbastanza forte per esso ancora.

SceneMesh

SceneMesh è un oggetto SceneComponent che approssima la geometria di oggetti geometrici arbitrari usando un elenco di triangoli. SceneMeshes vengono usati in diversi contesti; possono rappresentare i componenti della struttura della cella impermeabile o come WorldMesh, che rappresenta la mesh di mapping spaziale non associato alla scena. I dati di indice e vertice forniti con ogni mesh usano lo stesso layout familiare dei vertex e dei buffer di indice usati per il rendering di mesh triangolari in tutte le API di rendering moderne. In Comprensione scena le mesh usano indici a 32 bit e possono essere suddivisi in blocchi per determinati motori di rendering.

Sistemi di ordine di avvolgimento e coordinate

Tutte le mesh prodotte da Scene Understanding devono restituire mesh in un Right-Handed sistema di coordinate usando un ordine di avvolgimento orario.

Nota: le compilazioni del sistema operativo prima di .191105 potrebbero avere un bug noto in cui le mesh "World" venivano restituite in Counter-Clockwise ordine di avvolgimento, che successivamente è stato risolto.

SceneQuad

SceneQuad è un oggetto SceneComponent che rappresenta le superfici 2d che occupano il mondo 3D. SceneQuads può essere usato in modo simile a ARKit ARPlaneAnchor o ARCore Planes, ma offrono funzionalità più elevate come canvas 2d da usare da app flat o UX aumentata. Le API specifiche 2D sono fornite per quad che rendono il posizionamento e il layout semplici da usare e lo sviluppo (con l'eccezione del rendering) con quad dovrebbero essere più simili a lavorare con canvas 2d rispetto a mesh 3d.

Forma SceneQuad

SceneQuads definisce una superficie rettangolare delimitata in 2d. Tuttavia, SceneQuads rappresenta le superfici con forme arbitrarie e potenzialmente complesse (ad esempio una tabella a forma di donut). Per rappresentare la forma complessa della superficie di un quad, è possibile usare l'API GetSurfaceMask per eseguire il rendering della forma della superficie in un buffer di immagini fornito. Se sceneObject con il quad ha anche una mesh, i triangoli mesh devono essere equivalenti a questa immagine di rendering, entrambi rappresentano la geometria reale della superficie, in coordinate 2d o 3d.

Informazioni dettagliate sull'SDK sulla scena e informazioni di riferimento

Nota

Quando si usa MRTK, Si noti che si interagisce con mrTK ''WindowsSceneUnderstandingObserver'](xref:Microsoft.MixedReality.Toolkit.WindowsSceneUnderstanding.Experimental.WindowsSceneUndersceneUnderstandingObserver?view=mixed-reality-toolkit-unity-2020-dotnet-2.8.0&preserve-view=true) e quindi ignorare questa sezione nella maggior parte dei casi. Per altre informazioni, vedere la documentazione [MRTK Scene Understanding](/windows/mixed-reality/mrtk-unity/features/spatial-awareness/scene-understanding).

La sezione seguente consente di acquisire familiarità con le nozioni di base di SceneUnderstanding. Questa sezione deve fornire le nozioni di base, a questo punto è necessario avere un contesto sufficiente per esplorare le applicazioni di esempio per vedere come viene usata SceneUnderstanding in modo olistico.

Inizializzazione

Il primo passaggio per l'uso di SceneUnderstanding consiste nel ottenere riferimento a un oggetto Scene. Questa operazione può essere eseguita in uno dei due modi, una scena può essere calcolata dal driver o da una scena esistente calcolata in passato può essere de serializzata. Quest'ultimo è utile per lavorare con SceneUnderstanding durante lo sviluppo, dove le applicazioni e le esperienze possono essere prototipi rapidamente senza un dispositivo di realtà mista.

Le scene vengono calcolate usando un server SceneOb. Prima di creare una scena, l'applicazione deve eseguire una query sul dispositivo per assicurarsi che supporti SceneUnderstanding, nonché per richiedere l'accesso dell'utente per informazioni necessarie da SceneUnderstanding.

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

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

Se RequestAccessAsync() non viene chiamato, il calcolo di una nuova scena avrà esito negativo. Verrà quindi calcolata una nuova scena radicata intorno al visore Realtà mista e ha un raggio di 10 metri.

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

Inizializzazione da Dati (noto anche come percorso PC)

Anche se le scene possono essere calcolate per il consumo diretto, possono essere calcolate anche in formato serializzato per un uso successivo. Questo è stato dimostrato utile per lo sviluppo perché consente agli sviluppatori di lavorare in e testare Scene Understanding senza la necessità di un dispositivo. L'atto di serializzazione di una scena è quasi identico al calcolo, i dati vengono restituiti all'applicazione anziché deserializzati localmente dall'SDK. È quindi possibile deserializzare se stessi o salvarlo per un uso futuro.

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

Enumerazione SceneObject

Ora che l'applicazione ha una scena, l'applicazione esaminerà e interagisce con SceneObjects. Questa operazione viene eseguita accedendo alla proprietà SceneObjects :

SceneObject firstFloor = null;

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

Componenti di aggiornamento e perfezionamento dei componenti

Esiste un'altra funzione che recupera i componenti nella scena denominata FindComponent. Questa funzione è utile durante l'aggiornamento degli oggetti di rilevamento e la ricerca in scene successive. Il codice seguente calcola una nuova scena rispetto a una scena precedente e quindi trova il pavimento nella nuova scena.

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

Accesso a mesh e quad da oggetti scena

Dopo aver trovato SceneObjects, l'applicazione vuole più probabilmente accedere ai dati contenuti nei quads/mesh composti dall'applicazione. Questi dati vengono accessibili con le proprietà Quad e Mesh . Il codice seguente enumera tutti i quad e le mesh dell'oggetto floor.


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

Si noti che è l'oggetto SceneObject che ha la trasformazione relativa all'origine della scena. Questo è dovuto al fatto che SceneObject rappresenta un'istanza di "thing" ed è locatable nello spazio, i quad e le mesh rappresentano la geometria trasformata rispetto al padre. È possibile che sceneObject separati faccia riferimento allo stesso SceneMesh/SceneQuad SceneComponents ed è anche possibile che sceneObject abbia più sceneMesh/SceneQuad.

Gestione delle trasformazioni

La comprensione della scena ha fatto un tentativo intenzionale di allinearsi alle rappresentazioni della scena 3D tradizionali durante la gestione delle trasformazioni. Ogni scena è quindi limitata a un singolo sistema di coordinate molto simile alla rappresentazione ambientale 3D più comune. SceneObjects specifica la posizione relativa a tale sistema di coordinate. Se l'applicazione si occupa di Scene che estendono il limite di quello che fornisce un'unica origine può ancorare SceneObjects a SpatialAnchors o generare diverse scene e unire loro insieme, ma per semplicità si presuppone che esistano scene in acqua nella propria origine localizzate da un NodeId definito da Scene.OriginSpatialGraphNodeId.

Il codice Unity seguente, ad esempio, illustra come usare le API di Windows Perception e Unity per allineare i sistemi di coordinate insieme. Vedere SpatialCoordinateSystem e SpatialGraphInteropPreview per informazioni dettagliate sulle API di Percezione di Windows e Realtà mista oggetti nativi in Unity per informazioni dettagliate sull'acquisizione di un sistema SpatialCoordinate che corrisponde all'origine mondiale di 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;
}

Ogni SceneObject oggetto ha una trasformazione, che viene quindi applicata a tale oggetto. In Unity si converte in coordinate a destra e si assegnano trasformazioni locali in questo modo:

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

I quad sono stati progettati per aiutare gli scenari di posizionamento 2D e devono essere considerati come estensioni agli elementi dell'esperienza utente dell'area di disegno 2D. Mentre i quad sono componenti di SceneObjects e possono essere sottoposti a rendering in 3D, le API Quad si presuppongono che i quad siano strutture 2D. Offrono informazioni come extent, forma e forniscono API per la posizione.

I quad hanno estensioni rettangolari, ma rappresentano superfici 2D a forma arbitraria. Per abilitare la posizionamento su queste superfici 2D che interagiscono con i quad dell'ambiente 3D offrono utilità per rendere possibile questa interazione. Attualmente Scene Understanding offre due funzioni, FindCentermostPlacement e GetSurfaceMask. FindCentermostPlacement è un'API di alto livello che individua una posizione sul quad in cui un oggetto può essere posizionato e cercherà di trovare la posizione migliore per l'oggetto garantendo che il rettangolo di selezione fornito rimarrà sulla superficie sottostante.

Nota

Le coordinate dell'output sono relative al quad in "spazio quad" con l'angolo superiore sinistro (x = 0, y = 0), così come sarebbe con altri tipi di windows Rect. Assicurarsi di prendere in considerazione questo problema quando si lavora con le origini dei propri oggetti.

Nell'esempio seguente viene illustrato come trovare la posizione posizionabile più centrale e ancorare un ologramma al 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)
            }
        }
    }
}

I passaggi da 1 a 4 dipendono fortemente dal framework o dall'implementazione specifica, ma i temi devono essere simili. È importante notare che il quad rappresenta semplicemente un piano 2D delimitato localizzato nello spazio. Avendo il motore o il framework conoscendo dove si trova il quad e radicendo gli oggetti relativi al quad, gli ologrammi si trovano correttamente rispetto al mondo reale.

Mesh

Le mesh rappresentano rappresentazioni geometriche di oggetti o ambienti. Analogamente al mapping spaziale, agli indici mesh e ai dati dei vertici forniti con ogni mesh di superficie spaziale viene usato lo stesso layout familiare dei buffer di vertice e indice usati per il rendering di mesh triangolari in tutte le API di rendering moderne. Le posizioni dei vertici vengono fornite nel sistema di coordinate dell'oggetto Scene. Le API specifiche usate per fare riferimento a questi dati sono le seguenti:

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

Il codice seguente fornisce un esempio di generazione di un elenco di triangoli dalla struttura mesh:

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

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

I buffer di indice/vertice devono essere >= i conteggi di indici/vertici, ma in caso contrario possono essere ridimensionati arbitrariamente, consentendo un riutilizzo efficiente della memoria.

ColliderMesh

Gli oggetti Scene forniscono l'accesso ai dati mesh e mesh collider tramite le proprietà Mesh e ColliderMeshes. Queste mesh corrispondono sempre, significa che l'indice i'th della proprietà Meshes rappresenta la stessa geometria dell'indice i'th della proprietà ColliderMeshes. Se il runtime/oggetto supporta le mesh collider, è garantito ottenere il poligono più basso, l'approssimazione più elevata dell'ordine e è consigliabile usare ColliderMeshes ovunque l'applicazione usi collider. Se il sistema non supporta collideri, l'oggetto Mesh restituito in ColliderMeshes sarà lo stesso oggetto della mesh che riduce i vincoli di memoria.

Sviluppo con la comprensione della scena

A questo punto, è necessario comprendere i blocchi predefiniti principali del runtime di comprensione della scena e dell'SDK. La maggior parte della potenza e della complessità si trova in modelli di accesso, interazione con framework 3D e strumenti che possono essere scritti sopra queste API per eseguire attività più avanzate come pianificazione spaziale, analisi della stanza, navigazione, fisica e così via. Ci auguriamo di acquisire questi esempi che dovrebbero guidarvi nella direzione appropriata per rendere gli scenari più brillanti. Se sono presenti esempi o scenari che non vengono affrontati, informarci e provare a documentare/prototipo ciò che è necessario.

Dove è possibile ottenere il codice di esempio?

Il codice di esempio di Analisi delle scene per Unity è disponibile nella pagina della pagina di esempio unity . Questa applicazione ti permetterà di comunicare con il dispositivo e di eseguire il rendering dei vari oggetti scena oppure ti permetterà di caricare una scena serializzata sul tuo PC e ti permetterà di sperimentare La comprensione delle scene senza un dispositivo.

Dove è possibile ottenere scene di esempio?

Se si dispone di un oggetto HoloLens2, è possibile salvare qualsiasi scena acquisita salvando l'output di ComputeSerializedAsync in file e deserializzandolo in modo pratico.

Se non si dispone di un dispositivo HoloLens2 ma si vuole giocare con Scene Understanding, sarà necessario scaricare una scena pre-acquisizione. L'esempio di Scene Understanding attualmente viene fornito con scene serializzate che possono essere scaricate e usate in modo pratico. Sono disponibili qui:

Scene Understanding Sample Scenes

Vedere anche