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.
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.
- 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.
- 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) ouXR_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_COARSEno 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
- Versão do Unity: Unity 6 versão 6000.0.58f2 ou mais recente.
- Configuração do projeto: conclua todas as etapas do guia de configuração do projeto do Unity.
- Pacotes do Unity: instale a versão 1.5.0 ou mais recente do pacote Extensões do Android XR para Unity.
Configurar o projeto
- Acesse Edit > Configurações do projeto > XR Plug-in Management > OpenXR.
- Clique em Configurações ao lado de Android XR (Extensions): Session Management e desmarque Immersive XR.
- 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
- Versão do Godot: Godot 4.8-dev ou mais recente.
- Configuração do projeto: conclua todas as etapas do guia de configuração do projeto do Godot Engine.
- Plug-in Godot OpenXR Vendors: instale a versão 5.2 ou mais recente do plug-in Godot OpenXR Vendors.
Configurar o projeto
- Acesse Project > Configurações do projeto, ative Advanced Settings e acesse General > XR > OpenXR > Extensions.
- Na subseção Contêiner espacial, selecione Ativado e configure o Modo de limites e os Limites.
- 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
- Versão do OpenXR: cabeçalhos do OpenXR 1.1 com
XR_EXT_spatial_containereXR_EXT_spatial_container_self_rendering. - Configuração do manifesto: configure o manifesto do app conforme descrito em
Começar a usar o OpenXR para Android XR, usando
XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED.
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
- Usar contêineres espaciais no Unity
- Usar contêineres espaciais no Godot
- Entender as permissões para XR
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.