Obter resultados de execução de sessão
Durante a execução de uma sessão, as transformações de alguns objetos na cena são modificadas, assim como as imagens da câmera. Em alguns casos, essas modificações podem não atender totalmente às necessidades do aplicativo, podendo ser necessário obter os resultados de execução da sessão por quadro e processar esses dados secundariamente. Este artigo explica como obter e usar esses dados de resultado.
Antes de começar
- Compreenda os conceitos básicos, componentes e fluxo de trabalho da sessão por meio de Introdução ao ARSession
- Saiba como criar uma sessão
- Saiba como acessar componentes de recursos AR
Obter atualizações de InputFrame
Você pode usar o evento InputFrameUpdate para obter atualizações de InputFrame. Este evento é acionado apenas quando o InputFrame nos dados de saída da sessão por quadro sofre alterações.
Nota
InputFrameUpdate só é válido em sessões onde o desenho da imagem é feito pelo EasyAR. Geralmente, é inválido ao usar AR Foundation ou headsets, sendo necessário usar os métodos fornecidos por essas bibliotecas de terceiros para obter atualizações de dados.
Usando InputFrame você pode obter a imagem da câmera física, parâmetros da câmera, timestamp, transformação da câmera física em relação ao sistema de coordenadas mundial e estado de rastreamento, entre outros. No entanto, como a transformação da câmera já é aplicada pela sessão à câmera virtual e a outros objetos, geralmente não é necessário obter a transformação da câmera através de InputFrame.
Obter a imagem da câmera física do quadro atual
Você pode usar o método InputFrame.image() para obter dados de imagem da câmera física do tipo Image.
Por exemplo, o código a seguir pode obter a imagem da câmera física quando o InputFrame é atualizado:
Session.InputFrameUpdate += (inputFrame) => {
using (var image = inputFrame.image())
{
}
};
Cuidado
Ao usar dados do tipo Image e outros dados do tipo class obtidos a partir dele, é necessário garantir que Dispose() seja chamado corretamente (a instrução using no código acima garante isso). Caso contrário, podem ocorrer vazamentos de memória ou até mesmo paradas na atualização da imagem.
Se for necessário reter InputFrame ou Image para uso em quadros subsequentes, é necessário aumentar o valor de ARAssembly.ExtraBufferCapacity de acordo com a quantidade de dados retidos. Caso contrário, a obtenção de dados pode falhar devido à capacidade insuficiente do buffer.
Se for necessário reter InputFrame, você também deve chamar o método Clone() para criar uma cópia de referência e, em seguida, chamar Dispose() na cópia quando ela não for mais necessária.
Como a taxa de quadros da câmera física geralmente é menor que a taxa de renderização, nem todo quadro de renderização receberá o evento InputFrameUpdate. Da mesma forma, a renderização da imagem da câmera física também não é atualizada em todos os quadros de renderização. Em todos os quadros de renderização antes do próximo evento InputFrameUpdate, o conteúdo da imagem será consistente com a imagem do InputFrame atual.
Nota
A imagem em InputFrame sempre corresponde ao plano de fundo da câmera virtual no quadro atual. No entanto, durante a renderização do plano de fundo, pode ocorrer redimensionamento e recorte, portanto, é normal que a imagem obtida tenha tamanho ou proporção diferente da exibida na tela.
Além disso, é importante notar que os dados de imagem retornados por InputFrame.image() são legíveis pela CPU e não são texturas GPU. Se você precisar usar os dados da imagem na GPU, será necessário carregá-los em uma textura GPU ou obter a textura GPU diretamente por meio da interface CameraImageRenderer.RequestTargetTexture(Action<Camera, RenderTexture>).
[Opcional] Interceptar a renderização da imagem da câmera física
Você pode usar ARAssembly.CameraImageRenderer para controlar o desenho da imagem da câmera física.
O código a seguir pode interromper o desenho da imagem da câmera física:
if (Session.Assembly != null && Session.Assembly.CameraImageRenderer.OnSome)
{
Session.Assembly.CameraImageRenderer.Value.enabled = false;
}
Observe que é necessário verificar primeiro se ARAssembly.CameraImageRenderer existe.
Nota
Só é possível interromper a atualização da imagem usando o método acima em sessões onde o desenho da imagem é feito pelo EasyAR. Geralmente, é inválido ao usar AR Foundation ou headsets, sendo necessário usar os métodos fornecidos por essas bibliotecas de terceiros para implementar a funcionalidade correspondente.
Após interromper o desenho da imagem da câmera física, o aplicativo pode usar InputFrame para obter dados de imagem da câmera física e usá-los para um desenho personalizado.
Obter atualizações de transform
Você pode usar o evento PostSessionUpdate para obter dados de transform dos objetos na cena após cada atualização de quadro da sessão.
Nota
Para alguns recursos (como Mega), mesmo que a imagem não mude e nenhum serviço seja explicitamente solicitado para atualização, os cálculos AR são executados a cada quadro de renderização. Portanto, se for necessário obter todas as alterações de transform, é essencial obter os dados de transform a cada quadro, e não apenas em quadros específicos.
Obter a transform da câmera virtual
Você pode obter a transform da câmera na cena por meio de ARAssembly.Camera.
Session.PostSessionUpdate += () =>
{
var position = Session.Assembly.Camera.transform.position;
var rotation = Session.Assembly.Camera.transform.rotation;
};
Obter a transform do target
Você pode obter a transform do target na cena por meio do objeto de target específico em uso. Por exemplo, para rastreamento de imagem, esse target é o objeto onde o componente ImageTargetController está localizado.
Session.PostSessionUpdate += () =>
{
var position = target.transform.position;
var rotation = target.transform.rotation;
};
[Opcional] Obter pose
Pose é uma estrutura de dados que descreve a posição e orientação de um objeto, geralmente composta por position e rotation. Em aplicativos AR, a pose é normalmente usada para descrever a posição e orientação da câmera física ou de um alvo rastreado em relação a algum sistema de referência.
O Unity não fornece dados de pose originais, pois a pose geralmente é usada para impulsionar o movimento de objetos na cena, o que é feito automaticamente pela sessão. Para cálculos e renderização de conteúdo, apenas transform é suficiente.
Importante
Antes de ler os métodos abaixo, reflita novamente: os dados de transform da câmera, alvos rastreados e outros objetos na cena atendem às suas necessidades? Geralmente, dados de pose adicionais não são necessários.
Se, por algum motivo, você realmente precisar de dados de pose, pode calcular o valor de pose necessário por meio de transform no evento PostSessionUpdate. Normalmente, a transform relativa entre target e camera obtida em PostSessionUpdate é a pose.
O código a seguir mostra como obter a transform da camera e do target e calcular a pose relativa entre eles:
Session.PostSessionUpdate += () =>
{
Pose cameraToWorld = new(Session.Assembly.Camera.transform.position, Session.Assembly.Camera.transform.rotation);
Pose targetToWorld = new(target.transform.position, target.transform.rotation);
Pose worldToTarget = new()
{
position = Quaternion.Inverse(targetToWorld.rotation) * (-targetToWorld.position),
rotation = Quaternion.Inverse(targetToWorld.rotation)
};
Pose cameraToTarget = cameraToWorld.GetTransformedBy(worldToTarget);
};
Cuidado
Se você estiver usando simultaneamente AR Foundation, headsets ou outras bibliotecas de terceiros que também estão em execução, elas podem modificar a transform da câmera na cena. É necessário garantir que a lógica de atualização dessas bibliotecas seja concluída antes de realizar cálculos de pose relacionados. Caso contrário, os resultados podem ser incorretos. Nesses cenários, a pose relativa entre target e origin em PostSessionUpdate ainda será precisa.
[Opcional] Interceptar atualizações de transform
Durante a execução de recursos AR, a transform de objetos como câmeras e alvos rastreados no Unity geralmente é atualizada automaticamente pela sessão. Esses processos de atualização garantem a correção e consistência da renderização AR, portanto não há métodos disponíveis para interceptar essas atualizações.
No entanto, se você precisar de lógica personalizada para atualizar a transform de objetos, pode fazê-lo monitorando o evento PostSessionUpdate. Isso requer uma abordagem mais complexa:
- Embora normalmente o conteúdo de renderização deva ser anexado como subnós ou componentes adicionais aos objetos controlados pela sessão, se você precisar atualizar a transform de objetos de forma personalizada, será necessário remover esses objetos da hierarquia de objetos controlados pela sessão. Ou seja, esses objetos não devem ser subnós de objetos controlados pela sessão.
- No evento PostSessionUpdate, registre a transform dos objetos que deseja atualizar de forma personalizada.
- Por fim, no evento PostSessionUpdate, use os dados fornecidos pela sessão para atualizar a transform desses objetos com sua lógica personalizada.
Nota
O uso do evento PostSessionUpdate é essencial, pois somente após esse momento a sessão deixa de operar nos objetos da cena.
Note que este método não pode ser usado para modificar a câmera, exigindo lógica mais complexa para lidar com atualizações personalizadas da câmera.
Além disso, este método só pode ser usado para atualizar a transform de objetos de forma personalizada, não para modificar a transform de objetos controlados pela sessão. Se a transform de objetos controlados pela sessão for modificada externamente, a sessão ainda substituirá essas modificações na próxima atualização de quadro, o que pode afetar a correção de alguns cálculos.
Cuidado
Usar este método requer que você garanta a correção da transform dos objetos, caso contrário, pode causar erros na renderização AR.
Se você estiver usando simultaneamente AR Foundation, headsets ou outras bibliotecas de terceiros, elas também podem modificar a transform de objetos na cena. É necessário garantir que a lógica de atualização dessas bibliotecas não entre em conflito com sua lógica personalizada, caso contrário, podem ocorrer resultados imprevisíveis.
Tópicos relacionados
- O modo central restringe quais objetos terão sua transform modificada pela sessão
- Introdução aos componentes básicos AR