Projetando objetos em marcadores com ARKit e RealityKit em SwiftUI.
Existem muitos apps que utilizam a Realidade Aumentada em algum de seus recursos, podendo ser um filtro, a projeção de algum objeto ou qualquer outra forma de "aumentar" a sua realidade, trazendo elementos virtuais para o mundo real.
O que é o ARKit?
ARKit é um framework da Apple responsável pelo processamento e entendimento das imagens recebidas pela câmera e dos dados fornecidos pelos sensores do dispositivo.
E o RealityKit?
RealityKit é outro framework da Apple, construído para realizar renderizações fotorrealistas em realidade aumentada.
Sobre o projeto
Neste artigo, será desenvolvido um app em SwiftUI que consegue detectar marcadores presentes no ambiente e projetar sobre eles elementos em 3D.
Primeiros passos
Para começarmos, vamos criar um projeto no Xcode utilizando o template de RA, com SwiftUI e RealityKit.
Após o projeto ser criado, nós iremos mexer com alguns arquivos:
Assets.xcassets
(para as imagens dos marcadores)Experience.rcproject
(para a criação do modelo 3D)ContentView.swift
(para a implementação das funcionalidades de RA)
Como criar os marcadores e adicioná-los no app?
Para que seu marcador seja fácil de ser encontrado pelos sensores do seu dispositivo, busque algo com um alto contraste e não muito detalhado.
Neste projeto, serão utilizados 12 marcadores diferentes:
Para adicioná-los no código, precisamos criar um AR Resource Group nos assets do projeto:
Em seguida, vamos arrastar as imagens para dentro da pasta "AR Resources" criada e definir suas dimensões. Neste caso, esses marcadores foram impressos com 8cm em sua largura e altura:
Agora, a parte dos assets está pronta. Vamos para o próximo passo.
Criação do modelo 3D
Para começarmos a editar o que será projetado em RA, iremos editar o arquivo Experience.rcproject
, utilizando o Reality Composer:
Por padrão, nós temos esse cubo como um único objeto na cena. Criaremos mais 11, um para cada marcador diferente:
Para podermos identificar cada objeto no código, é necessário que ele tenha um nome, e para facilitar nosso trabalho, iremos nomear os objetos com o nome dos seus respectivos marcadores:
Agora é só salvar o projeto e o arquivo Experience.rcproject
será atualizando automaticamente no Xcode.
Por enquanto, isso é tudo que precisamos fazer no Reality Composer.
Hora de codar!
Vamos agora para a nossa Content View fazer as modificações necessárias para conseguirmos projetar nossos objetos virtuais.
Primeiramente, vamos importar o framework ARKit em nosso arquivo:
import ARKit
Em seguida, vamos editar nossa struct ARViewContainer
para podermos detectar imagens:
Vamos criar uma instancia de uma ARView
dentro da struct:
Em seguida, vamos reescrever o método makeUIView()
para criarmos a configuração de rastreamento de imagem e adicionar as imagens de referência (nossos marcadores):
OBS.: Lembre-se de colocar o nome do AR Resource Group igual está nos assets do projeto (neste caso "AR Resources").
2. Agora basta fazer com que a nossa arView
execute essa configuração:
OBS.: Não se esqueça de retornar a
arView
para conformamos com o protocolo daUIViewRepresentable
.
Um erro deve ter aparecido, pois ainda não fizemos o Coordinator
. Essa classe será responsável por cuidar dos protocolos do ARSessionDelegate
, que cuida da parte de detecção dos objetos através dos sensores e da câmera do dispositivo.
Dentro da ARViewContainer
, criaremos uma classe Coordinator
, com um atributo parent
para podermos nos comunicar com a nossa arView
, e faremos a classe conformar com os protocolos NSObject
e ARSessionDelegate
:
E criaremos o Coordinator
através do método makeCoordinator()
, da seguinte maneira:
Agora está quase tudo pronto, só precisamos implementar dentro da classe um dos métodos do ARSessionDelegate
, o session()
com o parâmetro didAdd
:
Para fazer a detecção das imagens, precisamos ver se conseguimos encontrar uma entidade (um dos objetos em 3D) com o nome da anchor
adicionada, e se sim, adicionar esse objeto na arView
.
Executando o app, já conseguimos colocar as imagens nos marcadores:
Porém, temos um problema. Os objetos não estão ficando em cima de todos os marcadores.
Isso acontece porque em nossa cena no arquivo Experience.rcproject
, os objetos não estão centralizados na origem dela. Para não precisarmos deixar os objetos sobrepostos na origem, podemos arrumar sua posição adicionando a seguinte linha antes de adicionarmos a entidade na arView
:
entity.position = SIMD3(0, 0.05, 0)
OBS.: Para o objeto estar com sua base rente ao marcador, foi adicionado 5cm em seu eixo y (os valores estão em metros). Talvez seja necessário fazer um ajuste fino para cada objeto diferente.
Ao final, o método ficará da seguinte maneira:
Agora os objetos aparecem em cima do marcador corretamente.
Projeto final
Aqui está o repositório no GitHub contento a versão final após realizar todos os passos desse artigo: