Fotografia/Câmara de Vídeo do HoloLens em Unreal
O HoloLens tem uma Câmara de Fotografia/Vídeo (PV) no visor que pode ser utilizada tanto para Mixed Reality Capture (MRC) como para localizar objetos no espaço do mundo irreal a partir de coordenadas de píxeis na moldura da câmara.
Importante
A Câmara PV não é suportada com a Comunicação Remota Holográfica, mas é possível utilizar uma câmara Web anexada ao PC para simular a funcionalidade Câmara PV do HoloLens.
Configuração do Feed de Câmara PV
Importante
A câmara PV é implementada em plug-ins Windows Mixed Reality e OpenXR. No entanto, o OpenXR precisa que o plug-in do Microsoft OpenXR seja instalado. Além disso, o OpenXR para Unreal 4.26 tem uma limitação: a câmara pode funcionar com DIRECTX11 RHI. Esta limitação foi corrigida em Unreal 4.27.1 ou posterior.
- No HoloLens das Definições > do Projeto, ative a capacidade câmara Web :
- Crie um novo ator chamado "CamCapture" e adicione um avião para compor o feed da câmara:
- Adicione o ator à sua cena, crie um novo material chamado CamTextureMaterial com um Parâmetro de Objeto de Textura e uma amostra de textura. Envie os dados rgb da textura para a cor emissiva de saída:
Compor o Feed da Câmara PV
- No esquema CamCapture, ative a Câmara PV:
- Crie uma instância de material dinâmico a partir de CamTextureMaterial e atribua este material ao plano do ator:
- Obtenha a textura do feed da câmara e atribua-a ao material dinâmico, se for válido. Se a textura não for válida, inicie um temporizador e tente novamente após o tempo limite:
- Por fim, dimensione o plano pela proporção da imagem da câmara:
Localizar Posições da Câmara no Espaço Mundial
A câmara no HoloLens 2 é desativada verticalmente do controlo de cabeça do dispositivo. Existem algumas funções para localizar a câmara no espaço mundial para contabilizar o desvio.
GetPVCameraToWorldTransform obtém a transformação no espaço mundial da Câmara de PV e será posicionado na lente da câmara:
GetWorldSpaceRayFromCameraPoint lança um raio da lente da câmara para a cena no espaço do mundo irreal para encontrar o conteúdo de um pixel na moldura da câmara:
GetPVCameraIntrinsics devolve os valores intrínsecos da câmara, que podem ser utilizados ao fazer o processamento de imagem digitalizada numa moldura da câmara:
Para encontrar o que existe no espaço mundial numa coordenada de píxeis específica, utilize um rastreio de linha com o raio espacial mundial:
Aqui lançamos um raio de 2 metros da lente da câmara para a posição de espaço da câmara 1/4 a partir do canto superior esquerdo da moldura. Em seguida, utilize o resultado de êxito para compor algo em que o objeto exista no espaço mundial:
Ao utilizar o mapeamento espacial, esta posição de acesso corresponderá à superfície que a câmara está a ver.
Compor o Feed de Câmara PV em C++
- Criar um novo ator C++ chamado CamCapture
- No build.cs do projeto, adicione "AugmentedReality" à lista PublicDependencyModuleNames:
PublicDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore",
"AugmentedReality"
});
- Em CamCapture.h, inclua ARBlueprintLibrary.h
#include "ARBlueprintLibrary.h"
- Também tem de adicionar variáveis locais para a malha e o material:
private:
UStaticMesh* StaticMesh;
UStaticMeshComponent* StaticMeshComponent;
UMaterialInstanceDynamic* DynamicMaterial;
bool IsTextureParamSet = false;
- Em CamCapture.cpp, atualize o construtor para adicionar uma malha estática à cena:
ACamCapture::ACamCapture()
{
PrimaryActorTick.bCanEverTick = true;
// Load a mesh from the engine to render the camera feed to.
StaticMesh = LoadObject<UStaticMesh>(nullptr, TEXT("/Engine/EngineMeshes/Cube.Cube"), nullptr, LOAD_None, nullptr);
// Create a static mesh component to render the static mesh
StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CameraPlane"));
StaticMeshComponent->SetStaticMesh(StaticMesh);
// Scale and add to the scene
StaticMeshComponent->SetWorldScale3D(FVector(0.1f, 1, 1));
this->SetRootComponent(StaticMeshComponent);
}
Em BeginPlay, crie uma instância de material dinâmico a partir do material da câmara do projeto, aplique-a ao componente de malha estática e inicie a câmara HoloLens.
No editor, clique com o botão direito do rato no CamTextureMaterial no browser de conteúdos e selecione "Copiar Referência" para obter a cadeia para CameraMatPath.
void ACamCapture::BeginPlay()
{
Super::BeginPlay();
// Create a dynamic material instance from the game's camera material.
// Right-click on a material in the project and select "Copy Reference" to get this string.
FString CameraMatPath("Material'/Game/Materials/CamTextureMaterial.CamTextureMaterial'");
UMaterial* BaseMaterial = (UMaterial*)StaticLoadObject(UMaterial::StaticClass(), nullptr, *CameraMatPath, nullptr, LOAD_None, nullptr);
DynamicMaterial = UMaterialInstanceDynamic::Create(BaseMaterial, this);
// Use the dynamic material instance when rendering the camera mesh.
StaticMeshComponent->SetMaterial(0, DynamicMaterial);
// Start the webcam.
UARBlueprintLibrary::ToggleARCapture(true, EARCaptureType::Camera);
}
Em Tique, obtenha a textura da câmara, defina-a para o parâmetro de textura no material CamTextureMaterial e dimensione o componente de malha estática pela proporção da moldura da câmara:
void ACamCapture::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Dynamic material instance only needs to be set once.
if(IsTextureParamSet)
{
return;
}
// Get the texture from the camera.
UARTexture* ARTexture = UARBlueprintLibrary::GetARTexture(EARTextureType::CameraImage);
if(ARTexture != nullptr)
{
// Set the shader's texture parameter (named "Param") to the camera image.
DynamicMaterial->SetTextureParameterValue("Param", ARTexture);
IsTextureParamSet = true;
// Get the camera instrincs
FARCameraIntrinsics Intrinsics;
UARBlueprintLibrary::GetCameraIntrinsics(Intrinsics);
// Scale the camera mesh by the aspect ratio.
float R = (float)Intrinsics.ImageResolution.X / (float)Intrinsics.ImageResolution.Y;
StaticMeshComponent->SetWorldScale3D(FVector(0.1f, R, 1));
}
}
Próximo Ponto de Verificação de Desenvolvimento
Se estiver a seguir o percurso de desenvolvimento irreal que definimos, está a explorar as capacidades e APIs da plataforma Mixed Reality. A partir daqui, pode continuar para o tópico seguinte:
Em alternativa, avance diretamente para a implementação da sua aplicação num dispositivo ou emulador:
Pode sempre voltar aos pontos de verificação de desenvolvimento irreais em qualquer altura.