Criar com contêineres espaciais

Dispositivos XR relevantes
Estas orientações ajudam você a criar experiências para esses tipos de dispositivos XR.
Headsets XR
Óculos XR com fio

Os contêineres espaciais trazem janelas volumétricas para o OpenXR. Definido pelas extensões XR_EXT_spatial_container e XR_EXT_spatial_container_self_rendering no OpenXR 1.1, um contêiner espacial é uma região volumétrica 3D gerenciada pelo sistema no espaço do usuário em que o app renderiza conteúdo 3D usando camadas de composição padrão do OpenXR.

Tradicionalmente, uma sessão do OpenXR reivindica acesso exclusivo a todo o campo de visão do usuário. Os contêineres espaciais permitem que seu app renderize conteúdo 3D do OpenXR dentro de uma caixa 3D limitada no ambiente do usuário ou faça a transição para uma experiência imersiva ilimitada em tela cheia a qualquer momento.

Sobre os contêineres espaciais

Um contêiner espacial é uma região 3D limitada ou ilimitada gerenciada pelo sistema Android XR e renderizada pelo app OpenXR:

  • Modo limitado: o app sugere dimensões 3D (largura, altura e profundidade em metros), e o sistema aloca uma caixa delimitadora 3D no ambiente do usuário. O app renderiza conteúdo 3D estéreo dentro do volume, e o sistema corta o conteúdo renderizado nos limites da caixa 3D.
  • Modo imersivo: o contêiner espacial se expande para limites infinitos, oferecendo ao app todo o campo de visão do usuário, como uma sessão tradicional do OpenXR em tela cheia.
Três contêineres espaciais em execução simultânea no Modo de Espaço Ampliado: um contêiner de terreno 3D laranja fixado ao chão, um modelo de pato 3D azul com uma interface 2D anexada e um contêiner de interface 2D verde.
Figura 1. Vários contêineres espaciais no Modo de Espaço Ampliado: um volume de terreno 3D fixo no chão (à esquerda), um volume de pato 3D pareado com uma UI 2D (no centro) e um contêiner de UI 2D (à direita).

Como os usuários interagem com os contêineres espaciais

O sistema Android XR gerencia os controles de janela do contêiner espacial e o posicionamento no espaço físico, oferecendo um modelo de interação consistente em todos os apps:

  • Mover e reposicionar: os usuários podem usar gestos com as mãos (como pinça) ou controles de movimento para mover o identificador do sistema de um contêiner espacial e reposicioná-lo no espaço 3D.
  • Minimizar e fechar: os controles de janela do sistema permitem que os usuários minimizem ou fechem contêineres espaciais individuais. Quando um usuário fecha um contêiner, o sistema notifica o app para que ele possa limpar os recursos.
  • Bloqueio no chão com compreensão de cena: quando o app declara e solicita a permissão android.permission.SCENE_UNDERSTANDING_COARSE, o sistema ativa automaticamente o ajuste de superfície para que os usuários possam colocar e bloquear um contêiner espacial no chão físico sem outras configurações do app, como mostrado pelo contêiner de terreno laranja na Figura 1.
  • Interação 3D direta: quando um contêiner está em foco e é interativo, os usuários podem interagir diretamente com o conteúdo 3D dentro do volume usando captura de movimentos das mãos, olhar ou controles 6DoF.
Um usuário interagindo com um pato 3D dentro de um contêiner espacial azul delimitado usando a captura de movimentos das mãos.
Figura 2. Um usuário interagindo com conteúdo 3D dentro de um contêiner espacial limitado usando a captura de movimentos das mãos.
  • Transição entre os modos limitado e imersivo: o usuário ou o app pode alternar um contêiner entre uma caixa 3D limitada e uma visualização imersiva em tela cheia sem reiniciar a sessão do OpenXR.
A cena do pato em 3D após a transição de um contêiner espacial limitado para uma visualização imersiva em tela cheia ilimitada.
Figura 3. O contêiner espacial após a transição do modo limitado para o modo imersivo, preenchendo o campo de visão do usuário.
  • Modo de acompanhamento em movimento: como o sistema controla a pose do espaço de coordenadas de cada contêiner espacial (xrCreateSpatialContainerSpaceEXT), os usuários podem ativar o modo de acompanhamento nos controles da janela do sistema para que um contêiner 3D limitado os siga automaticamente e permaneça no campo de visão enquanto eles se movem, sem exigir nenhuma configuração adicional no app.

Como usar contêineres espaciais no Android XR

Ao criar um app com contêineres espaciais, projete sua cena considerando os limites do contêiner, as mudanças de estado e o modo de mesclagem do plano de fundo.

Adaptar o conteúdo 3D aos limites do contêiner

No modo limitado, a origem (0, 0, 0) do espaço do contêiner espacial (xrCreateSpatialContainerSpaceEXT) fica no centro da caixa delimitadora 3D. Como o sistema gerencia a pose do espaço do contêiner no ambiente do usuário, seu app renderiza o conteúdo 3D em relação a (0, 0, 0), enquanto o sistema lida com o reposicionamento do usuário e o modo de acompanhamento. O sistema corta qualquer geometria renderizada fora da largura, altura ou profundidade da caixa para que o conteúdo permaneça dentro do volume atribuído.

O app precisa detectar eventos de mudança de limites do ambiente de execução e dimensionar ou reposicionar a cena 3D para que o conteúdo principal se ajuste às dimensões atuais do contêiner. Quando o contêiner faz a transição para o modo imersivo, os limites se tornam infinitos, e você pode restaurar a cena para a escala mundial completa de 1:1.

Responder a mudanças de estado do contêiner

Em vez de gerenciar a visibilidade e o foco apenas no nível do aplicativo, cada contêiner espacial informa o próprio estado para que o app possa reagir de acordo:

  • Visibilidade: indica se o contêiner está sendo mostrado ou ocultado. Pause animações, áudio ou atualizações de simulação enquanto o contêiner estiver oculto. O app também pode solicitar que um contêiner seja mostrado ou ocultado.
  • Interatividade: indica se o contêiner está em foco e recebendo entrada do usuário por captura de movimentos das mãos, controles ou olhar. Ative ou desative os destaques interativos e o processamento de entrada quando o foco mudar.
  • Modo de limites: indica se o contêiner está em XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT (cortado em uma caixa 3D) ou XR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT (tela cheia sem limites). Atualize a escala da cena e alterne os recursos visuais do ambiente (como skyboxes ou passthrough) quando o modo mudar. O app também pode solicitar transições entre os modos limitado e imersivo a qualquer momento.

Usar transparência com mesclagem alfa no modo limitado

No modo limitado, um plano de fundo transparente permite que o ambiente físico do usuário e outras janelas permaneçam visíveis ao redor dos modelos 3D. Configure a câmera ou janela de visualização com um plano de fundo transparente e use o modo de mesclagem de ambiente com mesclagem alfa. Ao mudar para o modo imersivo, você pode manter o passthrough ativado ou mudar para um ambiente de skybox opaco.

Verificar a disponibilidade dos recursos e configurar o manifesto

Os contêineres espaciais exigem um dispositivo Android XR com suporte ao nível 4 da API espacial ou mais recente. Em vez de verificar o nível da API do Android diretamente, consulte o ambiente de execução do OpenXR para determinar se os contêineres espaciais são compatíveis chamando xrEnumerateInstanceExtensionProperties para verificar se XR_EXT_spatial_container e XR_EXT_spatial_container_self_rendering estão disponíveis e chamando xrGetSystemProperties com XrSystemSpatialContainerPropertiesEXT para inspecionar supportsBounded e supportsImmersive.

Antes de criar um app que use contêineres espaciais, configure o modo de início da atividade e as permissões específicas do recurso em AndroidManifest.xml.

Ativar o Modo de Espaço Ampliado no AndroidManifest.xml

Os contêineres espaciais exigem o modo de Espaço Ampliado Gerenciado, mesmo para apps OpenXR independentes. Os apps OpenXR tradicionais em tela cheia declaram XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED para assumir o controle exclusivo da tela sem o gerenciamento de janelas do sistema. Por outro lado, um app que usa contêineres espaciais depende do compositor do sistema Android XR para gerenciar volumes 3D limitados, controles de janela e posicionamento espacial no Modo de Espaço Ampliado, e precisa definir android.window.PROPERTY_XR_ACTIVITY_START_MODE como XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ...>
        <!-- Spatial Containers require Full Space Managed mode -->
        <property
            android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
            android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED" />

        <activity android:name=".MainActivity" ...>
            <!-- Optional hint declaring which bounds modes the activity uses -->
            <property
                android:name="org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_USED_BOUNDS_MODES"
                android:value="XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT|XR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT" />
        </activity>
    </application>
</manifest>

Declarar e solicitar permissões específicas de recursos

A criação e a renderização de um contêiner espacial básico não exigem permissões de execução perigosas. No entanto, recursos específicos exigem a declaração e a solicitação das permissões correspondentes do Android XR:

  • Para bloquear e fixar um contêiner espacial no chão físico usando a compreensão de cena, declare e solicite a permissão perigosa android.permission.SCENE_UNDERSTANDING_COARSE no momento da execução.
  • Para rastrear a pose da cabeça do usuário no OpenXR, declare e solicite android.permission.HEAD_TRACKING.
<uses-permission android:name="android.permission.HEAD_TRACKING" />
<uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />

Consulte Noções básicas sobre permissões para XR para saber como declarar e solicitar permissões perigosas de XR no momento da execução.

Ativar contêineres espaciais no projeto

É possível criar com contêineres espaciais usando o Unity, o Godot ou diretamente com o OpenXR em C++. Selecione uma guia para conferir os pré-requisitos, a configuração do editor e o exemplo de código para seu ambiente preferido:

Unity

Pré-requisitos

Configurar o projeto

  1. Acesse Edit > Configurações do projeto > XR Plug-in Management > OpenXR.
  2. Clique em Configurações ao lado de Android XR (Extensions): Session Management e desmarque Immersive XR.
  3. Na lista OpenXR Feature Groups, ative Spatial Container.

Use XRSpatialContainerFeature em C# para consultar limites, responder a eventos de contêiner e alternar entre os modos limitado e imersivo:

void OnEnable()
{
    XRSpatialContainerFeature.OnSpatialContainerBoundsChanged += OnBoundsChanged;
}

private void OnBoundsChanged(Vector3 bounds, bool infiniteBounds)
{
    float minScale = Mathf.Min(bounds.x, bounds.y, bounds.z);
    transform.localScale = infiniteBounds ? Vector3.one : Vector3.one * minScale;
}

public void SetImmersiveMode(bool immersive)
{
    XRSpatialContainerFeature.TryRequestBoundsMode(immersive);
}

Para conferir as etapas completas de configuração do projeto, do manifesto e do processamento de permissões, consulte Usar contêineres espaciais no Unity.

Godot

Pré-requisitos

Configurar o projeto

  1. Acesse Project > Configurações do projeto, ative Advanced Settings e acesse General > XR > OpenXR > Extensions.
  2. Na subseção Contêiner espacial, selecione Ativado e configure o Modo de limites e os Limites.
  3. Acesse Projeto > Exportar... > Android e selecione Use Experimental Features em Android XR Features.

Use o singleton OpenXRSpatialContainerExtension no GDScript para responder aos limites do contêiner e às mudanças de modo:

func _ready() -> void:
    if OpenXRSpatialContainerExtension.is_enabled():
        OpenXRSpatialContainerExtension.spatial_container_bounds_changed.connect(
            _on_bounds_changed
        )

func _on_bounds_changed(_rid: RID, bounds: Vector3) -> void:
    scale = Vector3.ONE * min(bounds.x, bounds.y, bounds.z)

func set_immersive_mode() -> void:
    OpenXRSpatialContainerExtension.request_main_spatial_container_bounds_mode(
        OpenXRSpatialContainerState.IMMERSIVE
    )

Para ver as configurações completas do projeto, as permissões de exportação e os exemplos de GDScript, consulte Usar contêineres espaciais no Godot.

OpenXR

Pré-requisitos

Ative XR_EXT_spatial_container e XR_EXT_spatial_container_self_rendering ao criar o XrInstance. Em seguida, crie e renderize o contêiner espacial:

// 1. Enable the Spatial Container extensions during xrCreateInstance
const char* enabledExtensions[] = {
    XR_EXT_SPATIAL_CONTAINER_EXTENSION_NAME,
    XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME,
};

// 2. Configure and create a self-rendering spatial container
XrSpatialContainerConfigurationSelfRenderingEXT selfRenderingConfig{
    .type = XR_TYPE_SPATIAL_CONTAINER_CONFIGURATION_SELF_RENDERING_EXT,
    .next = nullptr,
    .viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
    .suggestedBounds = {1.5f, 1.5f, 1.5f}, // Width, height, depth in meters
};

XrSpatialContainerCreateInfoEXT createInfo{
    .type = XR_TYPE_SPATIAL_CONTAINER_CREATE_INFO_EXT,
    .next = &selfRenderingConfig,
    .spatialContainerConfig =
        reinterpret_cast<const XrSpatialContainerConfigurationBaseHeaderEXT*>(
            &selfRenderingConfig),
};

XrSpatialContainerEXT spatialContainer = XR_NULL_HANDLE;
xrCreateSpatialContainerEXT(session, &createInfo, &spatialContainer);

// 3. Request bounded mode and make the container visible
xrRequestSpatialContainerBoundsModeEXT(
    spatialContainer, XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT);
xrRequestSpatialContainerVisibilityEXT(spatialContainer, XR_TRUE);

Consulte também


OpenXR™ e o logotipo do OpenXR são marcas registradas do The Khronos Group Inc. e são registradas como marcas na China, na União Europeia, no Japão e no Reino Unido.