Realidade Aumentada para Android: ARCore e Sceneform
Published: 2020-04-19 20:31:53

Com a quantidade de aplicativos e soluções digitais atualmente, os usuários estão exigindo cada vez mais interações mais imersivas e que sejam cada vez mais próxima da realidade. Com isso, vemos crescer o número de aplicações com o uso de realidade aumentada.

## O que é Realidade Aumentada?

Realidade Aumentada é uma experiência interativa em que objetos do mundo virtual sobrepõe o mundo real e, dessa forma, os dois coexistem e podem interagir entre si.

Um aplicativo bem famoso que usa esse recurso é o Pokémon GO.

![Pokemon Go](https://dev-to-uploads.s3.amazonaws.com/i/d6inpecl7sf8bcma2qqa.jpg)
<figcaption>Aplicativo Pókemon GO usando Realidade Aumentada. Fonte: Tumisu from Pixabay</figcaption>

Também é usado em aplicativos de lojas de móveis e acessórios pra casa, para que se possa visualizar o objeto no ambiente real.

![Furniture in AR](https://anacoimbra.dev/media/arcore-sceneform/furniture.gif)
<figcaption>Posicionamento de móveis usando realidade aumentada</figcaption>

Com o avanço dos hardwares disponíveis em diversos dispositivos do mercado, principalmente nos smartphones intermediários, essa tem se tornado uma tecnologia emergente que muitas empresas estão investindo.Se quiser saber mais informações, fiz também um [texto](https://dev.to/anacoimbrag/realidade-aumentada-fundamentos-e-conceitos-1e84) mais teórico sobre realidade aumentada.

* * *

## Google ARCore

[ARCore](https://developers.google.com/ar/) é a plataforma da Google pra construir experiências em realidade aumentada para Android, Unit, e até mesmo pra web. Para deixar a interação entre mundo real e virtual mais completa, faz uso de três características principais através da câmera do dispositivo:

- O **rastreamento de movimento** permite entender e rastrear a posição do dispositivo em relação ao espaço.
- O **entendimento do ambiente** permite que o dispositivo reconheça o tamanho e localização de todos os tipos de superfícies disponíveis.
- A **estimativa de luz** permite que o dispositivo estime as condições atuais de luz ambiente.

Basicamente, o _ARCore_ rastreia posição do dispositivo conforme ele se move e ao mesmo tempo constrói seu entendimento do mundo real. Para fazer isso ele utiliza pontos chaves ( **feature points** ) na imagem da câmera que ajudam a detectar diversos tipos de superfícies e também as mudanças de localização.

Se tem vontade de aprender mais a fundo sobre o _ARCore_ e seus fundamentos, basta verificar a sua [documentação](https://developers.google.com/ar/discover/concepts).

### Limitações

Para uma boa experiência, é necessário demonstrar ao usuário o espaço necessário para o pleno funcionamento da aplicação. No caso de grandes espaços e lugares públicos, o grande desafio é, principalmente, a **oclusão** , quando um objeto virtual sobrepõe objetos físicos mas na verdade não deveria. No caso do ARCore atualmente não é possível tratar esse problema, mas a Google já anunciou o desenvolvimento da [ARCore Depth API](https://developers.google.com/ar/develop/call-for-collaborators#depth-api).

Um dos fatores essenciais em algumas aplicações com ARCore é a **detecção do(s) plano(s)** onde serão inseridos os objetos virtuais. Contudo alguns fatores podem limitar ou dificultar a detecção destes planos:

- Superfícies muito lisas e sem textura como uma parede branca
- Ambientes com pouca iluminação
- Ambientes com iluminação em excesso
- Superfícies refletivas ou transparentes como espelho ou vidro
- Superfícies em movimento como aqueles robôs que varrem a casa
- Superfícies verticais são mais difíceis de serem detectadas que as horizontais

Nestes casos, pode ser que o plano demore muito a ser detectado ou nem aconteça e para ajudar o usuário a entender o que está acontecendo, e ele não achar que é um “erro no sistema” sempre deixe claro as condições necessárias.

![Plane detection](https://anacoimbra.dev/media/arcore-sceneform/plane-detection.gif)
<figcaption>Visualização da detecção de plano - Fonte: Google</figcaption>

Quando acionado, o ARCore está sempre ampliando seu entendimento do ambiente e, com isso, pode ser que as primeiras detecções de _feature points_ não sejam tão fidedignas ao mundo real mas, com o tempo isso é ajustado a medida que a aplicação entende melhor o ambiente. Esse ponto pode causar frustração no usuário, tendo em vista que os objetos a serem inseridos em um plano detectado precocemente podem estar fora de escala com o mundo real. Portanto, é recomendado que, após a primeira detecção do plano, o usuário saiba que precisa continuar movendo o dispositivo para o pleno entendimento do ambiente pela aplicação.

### Boas práticas

Diversas experiências com realidade aumentada acabam ocorrendo em ambientes não controlados e o usuário é livre para fazer o que bem entende durante sua interação. Portanto, é necessário deixar bem claro pra ele qual o espaço necessário para que os objetos virtuais tenham uma boa visualização dentro do mundo real.

Além disso, essa relação entre mundo virtual e físico precisa ser coerente, por exemplo: não é estranho um guarda-roupa virtual aparecer em cima de um banco? Pois é, por isso é necessário que a pessoa interagindo com o aplicativo saiba qual o espaço ela deve usar: se é uma mesa, um cômodo ou um espaço ao ar livre, por exemplo. Lembrando que também é necessário ser responsivo tendo em vista que existem inúmeros tamanhos de mesa, de cômodos, etc.

Durante a detecção de plano, informe na interface que é necessário mover o dispositivo com imagens e animações. Após o(s) plano(s) ser(em) detectado(s) informe o que o usuário deve fazer em seguida como, por exemplo, adicionar um objeto à cena ao clicar em um plano. Além disso, é necessário realçar a(s) superfície(s) encontrada(s) para que o usuário saiba o espaço que possui pra interagir, mas apenas uma superfície por vez e apenas se o usuário estiver apontando para ela.

Usuários de smartphones estão acostumados a usarem aplicativos de forma estática ou seja, não saem do lugar ou de sua posição. Contudo, em uma aplicação com ARCore, é possível (e recomendado) que a pessoa se movimente e explore o ambiente e tudo que cerca o mundo virtual inserido no mundo físico. Por isso, é dar indicações para que ela se mova e tenha uma experiência mais imersiva (que é o principal propósito da realidade aumentada).

![Moving clues](https://anacoimbra.dev/media/arcore-sceneform/move-clues.gif)
<figcaption>Pistas na cena para o usuário saber que pode se movimentar - Fonte: Google</figcaption>

É claro que terão momentos em que o usuário não estará habilitado a se movimentar, para isso é recomendado dar alternativas para que ele possa imergir na experiência também, como opção de rotacionar, transladar e escalonar os objetos virtuais da cena.

Os usuários quando estão interagindo com uma experiência de realidade aumentada tendem a ficar tão imersos nela que acabam esquecendo do (resto do) mundo real. Por isso, é imprescindível mantê-lo seguro:

- Nunca faça o usuário andar para trás, ele não verá se tem algum obstáculo e pode colidir e/ou sofrer uma queda.
- Evite experiências que duram um longo período de tempo pois o indivíduo pode se sentir cansado e ter dores após um uso intenso de uma aplicação com realidade aumentada. Proponha pontos de “parada” para que ele tire um tempo para descansar.

![Backwards movement](https://anacoimbra.dev/media/arcore-sceneform/backward-movement.gif)
<figcaption>Evite situações que o usuário tenha que andar para trás - Fonte: Google</figcaption>
* * *

## Sceneform

Sceneform é uma biblioteca _opensource_ que permite utilizar todos os recursos do **ARCore no Android** sem a necessidade direta de manipulação das informações no **OpenGL**. Ela já nos oferece diversas facilidades também se tratando de funcionalidades padrões de uma aplicação em realidade aumentada como: posicionamento de um objeto no ambiente, renderização de um objeto através de augmented image que utiliza uma imagem como padrão para reconhecer o espaço e determinar posicionamento e orientação, também chamado de _fiducial marker_.

### Histórico

Até a versão [1.15.0](https://github.com/google-ar/sceneform-android-sdk/tree/v1.15.0) do Sceneform, a bibilioteca não era totalmente _opensource_ e, portanto tínhamos total acesso apenas às funcionalidades diretamente relacionadas a interface com usuário e alguns exemplos de código. Agora, a partir da versão [1.16.0](https://github.com/google-ar/sceneform-android-sdk/tree/v1.16.0%C2%A0) ela está 100% _opensource_ e os códigos de exemplos anteriores foram descontinuados. Antes, existiam duas formas de carregar um modelo: uma utilizando um arquivo  **.sfb** , que era obtido pelo plugin da própria biblioteca no Android Studio e o outra é utilizando um arquivo  **.glTF** ou **.glb** que não necessita a utilização do plugin e pode ser carregado diretamente via url do arquivo. O suporte a utilização de arquivos .sfb foi descontinuada e agora só é possível através da segunda forma, por isso os exemplos anteriores foram removidos.

![Sceneform](https://anacoimbra.dev/media/arcore-sceneform/sceneform.gif)
<figcaption>Exemplo Sceneform - Fonte: Google</figcaption>

## Conceitos

O _Sceneform_ facilita muito o desenvolvimento de aplicações com ARCore, mas mesmo assim, ainda trás alguns conceitos importantes que devem ser entendidos bem para um bom funcionamento da experiência.

* * *

- **Renderable** é a classe base para renderizar qualquer objeto dentro do mundo 3D. Pode ser dois tipos: **ViewRenderable** que renderiza componentes visuais como _TextView_, _Button_ dentro do espaço e o **ModelRenderable** que renderiza objetos 3D em geral, como um cubo, esfera ou qualquer objeto no formato _.gLTF_ ou _.glb_.
- **Node** representa um item de transformação dentro da cena. Pode ter um renderable atrelado a ele que será apresentado na cena. Um node pode ter inúmeros nodes “filhos” e um “pai”, que pode ser outro _node_ ou a cena(_scene_).Além de ser possível personalizar o próprio _node_, existem vários tipos já pré-determinados: _AnchorNode_, que é automaticamente posicionado na cena de acordo com seu ponto âncora atrelado; _AugmentedFaceNode_, usado para renderizar funcionalidades de reconhecimento de face e contém dois componentes: _face mash_ que utiliza imagens em 2D e coloca na face reconhecida e renderables para regiões da face e aí é possível detectar pontos como nariz, boca, olhos, etc.; _TransformableNode_ que é um node que pode ser manipulado no espaço com rotação, translação e escala; _Camera_ representa a câmera virtual e mostra a perspectiva pela qual a cena vai ser renderizada; _SkeletonNode_ representa as partes do “esqueleto” de um _ModelRenderable_; _Sun_ representa o “sol” da cena que nada mais é que uma luz direcional.
- **Scene** mantém a estrutura de dados dos componentes da cena, que nada mais é que um grafo, mais especificamente uma árvore, que tem como raíz a cena(_scene_) e tem inúmeros filhos(_nodes_) que por sua vez podem ter outros filhos _nodes_.
- **Light** representa a luz aplicada a um node. Pode ser direcional ( **DIRECTIONAL** ) que representa uma luz infinitamente longe; pontual ( **POINT** ) que irradia raios de luz em todas as direções a partir de um único ponto de luz; holofote ( **SPOTLIGHT** ) que é parecida com a luz pontual mas irradia os raios em um cone; holofote focado ( **FOCUSE\_SPOTLIGHT** ) é igual ao holofote normal mas a percepção da intensidade é a mesma independente do angulo do cone.
- **Plane** descreve os atributos de uma superfície planar identificada pela aplicação. É possível que mais de um plano sejam fundidos em um plano “pai” que por sua vez é mais amplo que seus “filhos”. Para visualizar os planos detectados, é usado o **PlaneRenderer**.
- **_Anchor_** ou **âncora** descreve uma posição fixa no mundo real, contento localização (coordenadas) e direção e também ajuda no entendimento do ambiente feito pelo _ARCore_.
- **CollisionShape** possui a representação matemática de alguma forma geométrica que é usada em cálculo de colisões ou tamanho relativo entre os objetos (virtuais) da cena. Pode ser um cubo, uma esfera ou um raio.

* * *

## Conclusão

O **ARCore** tem se tornado uma excelente ferramenta para criação de experiências com Realidade Aumentada para diversas plataformas, principalmente o Android. Apesar de ainda ter algumas limitações, tem resolvido de forma eficiente as demandas de aplicações em RA que tenho observado. Além disso, essas limitações conseguem ter menos impacto quando mantemos o usuário sempre informado do que está acontecendo e do que ele pode e/ou precisa fazer para melhorar a experiência.

Além disso, com o **Sceneform** é possível fazer excelentes experiências com realidade aumentada de forma simples e rápida. Contudo, fazer customizações de visualização e renderização pode ser um grande desafio, tendo em vista que a documentação tem certa limitação em relação aos componentes da cena e também não se encontra muito material avançado sobre o assunto.