Partilhar via


Descrição geral do SDK de compreensão de cenários

A compreensão de cenários transforma os dados do sensor de ambiente não estruturado que o seu dispositivo Mixed Reality captura e converte-os numa poderosa representação abstrata. O SDK funciona como a camada de comunicação entre a sua aplicação e o runtime do Scene Understanding. Destina-se a imitar construções padrão existentes, como gráficos de cena 3D para representações 3D e retângulos e painéis 2D para aplicações 2D. Enquanto as construções que o Scene Understanding imita serão mapeados para estruturas concretas, em geral SceneUnderstanding é agnóstico da arquitetura, permitindo a interoperabilidade entre várias arquiteturas que interagem com ela. À medida que a Compreensão de Cenas evolui, a função do SDK é garantir que as novas representações e capacidades continuam a ser expostas numa arquitetura unificada. Neste documento, vamos primeiro introduzir conceitos de alto nível que o ajudarão a familiarizar-se com o ambiente de desenvolvimento/utilização e, em seguida, forneceremos documentação mais detalhada para classes e construções específicas.

Onde posso obter o SDK?

O SDK SceneUnderstanding é transferível através da Ferramenta de Funcionalidades do Mixed Reality.

Nota: a versão mais recente depende dos pacotes de pré-visualização e terá de ativar os pacotes de pré-lançamento para vê-lo.

Para a versão 0.5.2022-rc e posterior, o Scene Understanding suporta projeções de linguagem para C# e C++ que permitem que as aplicações desenvolvam aplicações para plataformas Win32 ou UWP. A partir desta versão, SceneUnderstanding suporta suporte no editor do Unity, exceto o SceneObserver, que é utilizado apenas para comunicar com o HoloLens2.

O SceneUnderstanding requer a versão 18362 ou superior do Windows SDK.

Descrição Geral Conceptual

A Cena

O seu dispositivo de realidade mista está constantemente a integrar informações sobre o que vê no seu ambiente. A Compreensão de Cenários canaliza todas estas origens de dados e produz uma única abstração coesa. O Scene Understanding gera Cenas, que são uma composição de SceneObjects que representam uma instância de uma única coisa (por exemplo, uma parede/teto/piso.) Os próprios Objetos de Cena são uma composição de [SceneComponents, que representam peças mais granulares que compõem este SceneObject. Exemplos de componentes são quads e malhas, mas no futuro podem representar caixas delimitadoras, malhas de colisão, metadados, etc.

O processo de conversão dos dados de sensores não processados numa Cena é uma operação potencialmente dispendiosa que pode demorar segundos para espaços médios (~10x10m) em minutos para espaços grandes (~50x50m) e, portanto, não é algo que esteja a ser calculado pelo dispositivo sem pedido de aplicação. Em vez disso, a geração de Cenários é acionada pela sua aplicação a pedido. A classe SceneObserver tem métodos estáticos que podem Calcular ou Anular a Serialização de uma cena, com os quais pode enumerar/interagir. A ação "Computação" é executada a pedido e executada na CPU, mas num processo separado (o Controlador de Mixed Reality). No entanto, enquanto efetuamos a computação noutro processo, os dados de Cena resultantes são armazenados e mantidos na sua aplicação no objeto Cena.

Segue-se um diagrama que ilustra este fluxo de processos e mostra exemplos de duas aplicações a interagir com o runtime do Scene Understanding.

Diagrama de Processos

No lado esquerdo encontra-se um diagrama do runtime de realidade mista, que está sempre ativado e em execução no seu próprio processo. Este runtime é responsável pela execução do controlo de dispositivos, mapeamento espacial e outras operações que o Scene Understanding utiliza para compreender e raciocinar sobre o mundo à sua volta. No lado direito do diagrama, mostramos duas aplicações teóricas que utilizam o Scene Understanding. A primeira aplicação interfaces com MRTK, que utiliza internamente o SDK Scene Understanding, a segunda aplicação calcula e utiliza duas instâncias de cena separadas. As três Cenas neste diagrama geram instâncias distintas das cenas. O controlador não está a controlar o estado global que é partilhado entre aplicações e Objetos de Cena numa cena não se encontra noutra. O Scene Understanding fornece um mecanismo para controlar ao longo do tempo, mas isto é feito com o SDK. O código de controlo já está em execução no SDK no processo da sua aplicação.

Uma vez que cada Cena armazena os respetivos dados no espaço de memória da sua aplicação, pode assumir que todas as funções do objeto Cena ou os respetivos dados internos são sempre executadas no processo da sua aplicação.

Layout

Para trabalhar com o Scene Understanding, pode ser útil saber e compreender como o runtime representa os componentes logicamente e fisicamente. A Cena representa dados com um esquema específico que foi escolhido para ser simples, mantendo uma estrutura subjacente que é responsável por cumprir os requisitos futuros sem precisar de revisões importantes. A Cena faz isto ao armazenar todos os Componentes (blocos modulares para todos os Objetos de Cena) numa lista simples e definir hierarquia e composição através de referências em que componentes específicos referenciam outros.

Abaixo apresentamos um exemplo de uma estrutura na sua forma plana e lógica.

Esquema LógicoEsquema Físico
    Cena
    • 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

Esta ilustração realça a diferença entre o esquema físico e lógico da Cena. À esquerda, vemos o esquema hierárquico dos dados que a sua aplicação vê ao enumerar o cenário. À direita, vemos que a cena é composta por 12 componentes distintos que são acessíveis individualmente, se necessário. Ao processar uma nova cena, esperamos que as aplicações percorram esta hierarquia logicamente. No entanto, ao controlar entre atualizações de cenas, algumas aplicações só podem estar interessadas em filtrar componentes específicos que são partilhados entre duas cenas.

Descrição geral da API

A secção seguinte fornece uma descrição geral de alto nível das construções no Scene Understanding. Ler esta secção irá dar-lhe uma compreensão de como as cenas são representadas e para que servem os vários componentes. A secção seguinte irá fornecer exemplos de código concretos e detalhes adicionais que são apresentados nesta descrição geral.

Todos os tipos descritos abaixo residem no Microsoft.MixedReality.SceneUnderstanding espaço de nomes.

SceneComponents

Agora que compreende o esquema lógico das cenas, podemos apresentar o conceito de SceneComponents e como são utilizados para compor a hierarquia. SceneComponents são as decomposições mais granulares em SceneUnderstanding que representam uma única coisa de núcleo, por exemplo, uma malha ou um quad ou uma caixa delimitadora. Os SceneComponents são elementos que podem ser atualizados de forma independente e podem ser referenciados por outros SceneComponents, pelo que têm uma única propriedade global, um ID exclusivo, que permite este tipo de mecanismo de monitorização/referência. Os IDs são utilizados para a composição lógica da hierarquia de cenários, bem como para a persistência de objetos (o ato de atualizar uma cena relativamente a outra).

Se estiver a tratar todas as cenas recentemente calculadas como sendo distintas e simplesmente enumerar todos os dados nela contidos, os IDs são amplamente transparentes para si. No entanto, se estiver a planear controlar os componentes ao longo de várias atualizações, irá utilizar os IDs para indexar e localizar SceneComponents entre objetos de Cena.

SceneObjects

Um SceneObject é um SceneComponent que representa uma instância de uma "coisa", por exemplo, uma parede, um chão, um teto, etc.... expressa pela respetiva propriedade Kind. Os SceneObjects são geométricos e, portanto, têm funções e propriedades que representam a sua localização no espaço, no entanto não contêm nenhuma estrutura geométrica ou lógica. Em vez disso, sceneObjects referenciam outros SceneComponents, especificamente SceneQuads e SceneMeshes, que fornecem as variadas representações que são suportadas pelo sistema. Quando uma nova cena é calculada, a sua aplicação irá provavelmente enumerar os SceneObjects do Cenário para processar aquilo em que está interessado.

Os SceneObjects podem ter um dos seguintes:

SceneObjectKind Descrição
FundoSabe-se que o SceneObject não é um dos outros tipos reconhecidos de objeto de cena. Esta classe não deve ser confundida com Desconhecido onde se sabe que Fundo não é parede/chão/teto, etc.... embora desconhecido ainda não esteja categorizado.
ParedeUma parede física. As paredes são consideradas estruturas ambientais inamovíveis.
FloorOs pisos são todas as superfícies em que se pode andar. Nota: as escadas não são pisos. Note também que os pisos assumem qualquer superfície walkable e, portanto, não há nenhuma suposição explícita de um piso singular. Estruturas de vários níveis, rampas, etc.... todos devem classificar como piso.
CeilingA superfície superior de uma sala.
PlataformaUma superfície plana grande na qual pode colocar hologramas. Estes tendem a representar tabelas, bancadas e outras superfícies horizontais grandes.
InternacionalUma etiqueta reservada para dados geométricos que é agnóstico à etiquetagem. A malha gerada ao definir o sinalizador de atualização EnableWorldMesh seria classificado como mundo.
DesconhecidoEste objeto de cena ainda não foi classificado e atribuiu um tipo. Isto não deve ser confundido com o Fundo, uma vez que este objeto pode ser qualquer coisa, mas o sistema ainda não criou uma classificação suficientemente forte para o mesmo.

SceneMesh

Um SceneMesh é um SceneComponent que se aproxima da geometria de objetos geométricos arbitrários com uma lista de triângulos. Os SceneMeshes são utilizados em vários contextos diferentes; podem representar componentes da estrutura de células estanques ou como WorldMesh, que representa a malha de mapeamento espacial não vinculada associada à Cena. Os dados de índice e vértice fornecidos com cada malha utilizam o mesmo esquema familiar que as memórias intermédias de vértice e índice que são utilizadas para compor malhas de triângulo em todas as APIs de composição modernas. No Scene Understanding, as malhas utilizam índices de 32 bits e podem ter de ser divididas em segmentos para determinados motores de composição.

Ordem de Enrolamento e Coordenar Sistemas

Espera-se que todas as malhas produzidas pelo Scene Understanding devolvam malhas num sistema de coordenadas Right-Handed com ordem de enrolamento no sentido dos ponteiros do relógio.

Nota: as compilações do SO anteriores a .191105 podem ter um erro conhecido em que as malhas "World" estavam a ser devolvidas por Counter-Clockwise ordem de enrolamento, que foi posteriormente corrigida.

SceneQuad

Um SceneQuad é um SceneComponent que representa superfícies 2d que ocupam o mundo 3D. Os SceneQuads podem ser utilizados de forma semelhante a ARKit ARPlaneAnchor ou ARCore Planes, mas oferecem funcionalidades de alto nível como telas 2d para serem utilizadas por aplicações planas ou UX aumentado. As APIs específicas 2D são fornecidas para quads que tornam a colocação e o esquema simples de utilizar e o desenvolvimento (com exceção da composição) com quads deve ser mais semelhante a trabalhar com telas 2d do que malhas 3d.

Forma SceneQuad

SceneQuads definem uma superfície retangular delimitada em 2d. No entanto, os SceneQuads representam superfícies com formas arbitrárias e potencialmente complexas (por exemplo, uma tabela em forma de anel.) Para representar a forma complexa da superfície de um quad, pode utilizar a API GetSurfaceMask para compor a forma da superfície numa memória intermédia de imagem fornecida por si. Se o SceneObject que tem o quad também tiver uma malha, os triângulos de malha devem ser equivalentes a esta imagem composta, ambos representam geometria real da superfície, quer em coordenadas 2d ou 3d.

Referência e detalhes do SDK de compreensão de cenários

Nota

Ao utilizar o MRTK, tenha em atenção que irá interagir com o ['WindowsSceneUnderstandingObserver' do MRTK](xref:Microsoft.MixedReality.Toolkit.WindowsSceneUnderstanding.Experimental.WindowsSceneUnderstandingObserver?view=mixed-reality-toolkit-unity-2020-dotnet-2.8.0&preserve-view=true) e, portanto, pode ignorar esta secção na maioria das circunstâncias. Consulte os documentos [MRTK Scene Understanding](/windows/mixed-reality/mrtk-unity/features/spatial-awareness/scene-understanding) para obter mais informações.

A secção seguinte irá ajudá-lo a familiarizar-se com as noções básicas de SceneUnderstanding. Esta secção deve fornecer-lhe as noções básicas, altura em que deverá ter contexto suficiente para navegar pelas aplicações de exemplo para ver como SceneUnderstanding é utilizado de forma holística.

Inicialização

O primeiro passo para trabalhar com SceneUnderstanding é que a sua aplicação obtenha referência a um objeto Cena. Isto pode ser feito de uma de duas formas, uma Cena pode ser calculada pelo controlador ou uma Cena existente que foi calculada no passado pode ser des serializada. Este último é útil para trabalhar com SceneUnderstanding durante o desenvolvimento, onde as aplicações e experiências podem ser protótipos rapidamente sem um dispositivo de realidade mista.

As cenas são calculadas com um SceneObserver. Antes de criar um Cenário, a sua aplicação deve consultar o seu dispositivo para garantir que suporta SceneUnderstanding, bem como para pedir acesso ao utilizador para obter informações que SceneUnderstanding precisa.

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

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

Se RequestAccessAsync() não for chamado, a computação de uma nova Cena falhará. Em seguida, vamos calcular uma nova cena que está enraizada no headset Mixed Reality e tem um raio de 10 metros.

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

Inicialização a partir de Dados (também conhecido como Caminho do PC)

Embora as Cenas possam ser calculadas para consumo direto, também podem ser calculadas em formato serializado para utilização posterior. Isto provou ser útil para o desenvolvimento, uma vez que permite que os programadores trabalhem e testem o Scene Understanding sem a necessidade de um dispositivo. O ato de serializar uma cena é quase idêntico à sua computação, os dados são devolvidos à sua aplicação em vez de serem desseriais localmente pelo SDK. Em seguida, pode anular a serialização por si próprio ou guardá-la para utilização futura.

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

Enumeração sceneObject

Agora que a sua aplicação tem uma cena, a sua aplicação irá analisar e interagir com SceneObjects. Isto é feito ao aceder à propriedade SceneObjects :

SceneObject firstFloor = null;

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

Componentes de atualização e refinação de componentes

Existe outra função que obtém componentes na Cena denominada FindComponent. Esta função é útil ao atualizar objetos de controlo e encontrá-los em cenas posteriores. O código seguinte irá calcular uma nova cena relativamente a uma cena anterior e, em seguida, encontrar o piso na nova cena.

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

Aceder a Meshes e Quads a partir de Objetos de Cena

Assim que os SceneObjects tiverem sido encontrados, é provável que a sua aplicação queira aceder aos dados contidos nos quads/meshes dos quais é composta. Estes dados são acedidos com as propriedades Quads e Meshes . O código seguinte enumerará todos os quads e malhas do nosso objeto de piso.


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

Repare que é o SceneObject que tem a transformação relativa à origem cena. Isto acontece porque o SceneObject representa uma instância de uma "coisa" e é localizável no espaço, os quads e as malhas representam geometria que é transformada em relação ao respetivo elemento principal. É possível que sceneObjects separados referenciem os mesmos SceneMesh/SceneQuad SceneComponents e também é possível que um SceneObject tenha mais do que um SceneMesh/SceneQuad.

Lidar com Transformações

O Scene Understanding fez uma tentativa deliberada de alinhar com representações de cenas 3D tradicionais ao lidar com transformações. Cada Cena está, portanto, confinada a um único sistema de coordenadas, tal como a maioria das representações ambientais 3D comuns. Os SceneObjects fornecem a sua localização relativamente a esse sistema de coordenadas. Se a sua aplicação estiver a lidar com Cenas que esticam o limite do que uma única origem fornece, pode ancorar SceneObjects a SpatialAnchors ou gerar várias cenas e uni-las, mas, para simplificar, partimos do princípio de que as cenas estanques existem na sua própria origem, localizadas por um NodeId definido por Scene.OriginSpatialGraphNodeId.

O seguinte código do Unity, por exemplo, mostra como utilizar a Perceção do Windows e as APIs do Unity para alinhar os sistemas em conjunto. Veja SpatialCoordinateSystem e SpatialGraphInteropPreview para obter detalhes sobre as APIs de Perceção do Windows e Mixed Reality objetos nativos no Unity para obter detalhes sobre como obter um SpatialCoordinateSystem que corresponda à origem mundial do 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;
}

Cada SceneObject um tem uma transformação, que é depois aplicada a esse objeto. No Unity, convertemos em coordenadas destros e atribuímos transformações locais da seguinte forma:

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

Os quads foram concebidos para ajudar cenários de colocação 2D e devem ser considerados como extensões para elementos UX de tela 2D. Embora quads sejam componentes de SceneObjects e possam ser compostos em 3D, as próprias APIs Quad assumem que quads são estruturas 2D. Oferecem informações como extensão, forma e fornecem APIs para colocação.

Os quads têm extensões retangulares, mas representam superfícies 2D em forma arbitrária. Para ativar a colocação nestas superfícies 2D que interagem com os quads de ambiente 3D, oferecem utilitários para tornar esta interação possível. Atualmente, o Scene Understanding fornece duas dessas funções: FindCentermostPlacement e GetSurfaceMask. FindCentermostPlacement é uma API de alto nível que localiza uma posição no quad onde um objeto pode ser colocado e tentará encontrar a melhor localização para o objeto, garantindo que a caixa delimitadora fornecida permanecerá na superfície subjacente.

Nota

As coordenadas da saída são relativas ao quad no "espaço quad", sendo que o canto superior esquerdo é (x = 0, y = 0), tal como seria com outros tipos de rect windows. Certifique-se de que tem isto em conta ao trabalhar com as origens dos seus próprios objetos.

O exemplo seguinte mostra como encontrar a localização mais centralizável e ancorar um holograma no 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)
            }
        }
    }
}

Os passos 1 a 4 dependem muito da sua arquitetura/implementação específica, mas os temas devem ser semelhantes. É importante ter em atenção que o Quad representa simplesmente um plano 2D vinculado localizado no espaço. Ao fazer com que o seu motor/arquitetura saiba onde está o quad e ao enraizar os objetos em relação ao quad, os hologramas estarão localizados corretamente no que diz respeito ao mundo real.

Malha

As malhas representam representações geométricas de objetos ou ambientes. Tal como o mapeamento espacial, o índice de malha e os dados de vértice fornecidos com cada malha espacial da superfície utilizam o mesmo esquema familiar que as memórias intermédias de vértice e índice utilizadas para compor malhas de triângulo em todas as APIs de composição modernas. As posições de vértice são fornecidas no sistema de coordenadas do Scene. As APIs específicas utilizadas para referenciar estes dados são as seguintes:

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

O código seguinte fornece um exemplo de geração de uma lista de triângulos a partir da estrutura de malha:

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

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

As memórias intermédias de índice/vértice têm de ser >= as contagens de índice/vértice, mas, caso contrário, podem ser dimensionadas arbitrariamente, permitindo uma reutilização eficiente da memória.

ColliderMesh

Os objetos de cena fornecem acesso a dados de malha e malha de colisão através das propriedades Meshes e ColliderMeshes. Estas malhas corresponderão sempre, o que significa que o i'th índice da propriedade Meshes representa a mesma geometria que o i'th índice da propriedade ColliderMeshes. Se o runtime/objeto suportar malhas de colisão, é garantido que obtém o polígono mais baixo e a aproximação da ordem mais alta e é uma boa prática utilizar ColliderMeshes onde quer que a sua aplicação utilize colisores. Se o sistema não suportar colisões, o objeto Mesh devolvido em ColliderMeshes será o mesmo objeto que a malha que reduz as restrições de memória.

Desenvolver com compreensão de cenas

Neste momento, deve compreender os principais blocos modulares do runtime e do SDK de compreensão da cena. A maior parte do poder e complexidade reside em padrões de acesso, interação com arquiteturas 3D e ferramentas que podem ser escritas sobre estas APIs para realizar tarefas mais avançadas, como planeamento espacial, análise de salas, navegação, física, etc. Esperamos capturá-los em amostras que devem guiá-lo na direção adequada para que os seus cenários sejam brilhantes. Se existirem exemplos ou cenários que não estejamos a abordar, informe-nos e tentaremos documentar/criar protótipos do que precisa.

Onde posso obter o código de exemplo?

O código de exemplo do Scene Understanding para o Unity pode ser encontrado na nossa página Página de Exemplo do Unity . Esta aplicação irá permitir-lhe comunicar com o seu dispositivo e compor os vários objetos de cena ou irá permitir-lhe carregar uma cena serializada no seu PC e permitir-lhe experimentar o Scene Understanding sem um dispositivo.

Onde posso obter cenas de exemplo?

Se tiver um HoloLens2, pode guardar qualquer cena que tenha capturado ao guardar a saída de ComputeSerializedAsync para o arquivar e anular a sua serialização por sua própria conveniência.

Se não tiver um dispositivo HoloLens2 mas quiser jogar com o Scene Understanding, terá de transferir uma cena pré-capturada. O exemplo do Scene Understanding é atualmente fornecido com cenas serializadas que podem ser transferidas e utilizadas por sua própria conveniência. Pode encontrá-los aqui:

Cenas de Exemplo de Compreensão de Cenas

Ver também