Recientemente, estoy estudiando el estándar OpenXR e investigando su implementación en Android. Ahora se han implementado las funciones básicas. Resumamos brevemente.
1. Qué es OpenXR:
El sitio web oficial es bastante bueno, por lo que no seré redundante.
https://www.khronos.org/OpenXR La
dirección de especificaciones oficiales es la siguiente:
https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html
1.1 Introducción a la compilación OpenXR Loader y NDK
...
1.2 Diseño e implementación de OpenXR Runtime
...
2. Introducción a la interfaz OpenXR
Para facilitar la comprensión, lo explicaremos con la demostración oficial HelloXR de OpenXR.
2.1 Diagrama de efectos de ejecución de HelloXR
Primero adjunte el efecto de ejecución de Helloxr
2.1 Secuencia de ejecución de HelloXR
HelloXR es una aplicación de Android basada en el marco de NativeActivity. El conocimiento relacionado sobre NativeActivity no se presenta aquí. El diagrama de secuencia de HelloXR es el siguiente:
2.2 Interfaz e implementación de OpenXR
Ahora presentamos brevemente algunos de los métodos y esquemas de implementación más principales en HelloXR
xrCreateInstance
definición
XRAPI_ATTR XrResult XRAPI_CALL xrCreateInstance(
const XrInstanceCreateInfo* createInfo,
XrInstance* instance);
Al llamar a xrCreateInstance en la plataforma Android para crear XrInstance, debe habilitar la extensión XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME y asignar un objeto XrInstanceCreateInfoAndroidKHR a createInfo.next, bajo el código
XrInstanceCreateInfoAndroidKHR instanceCreateInfoAndroid;
instanceCreateInfoAndroid = {
XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR};
//将JavaVm及activity赋值给instanceCreateInfoAndroid
//以传递给Runtime,Runtime会通过该JavaVM及activity获取一些必需的Java对象
//如surface和Choreographer
instanceCreateInfoAndroid.applicationVM = data->applicationVM;
instanceCreateInfoAndroid.applicationActivity = data->applicationActivity;
XrInstanceCreateInfo createInfo{
XR_TYPE_INSTANCE_CREATE_INFO};
createInfo.next = &instanceCreateInfoAndroid;
//extensions必须包含XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME
createInfo.enabledExtensionCount = (uint32_t)extensions.size();
createInfo.enabledExtensionNames = extensions.data();
xrCreateInstance(&createInfo, &m_instance);
En la plataforma Android, cuando OpenXR crea XrInstance en xrCreateInstance, pasa JavaVM y la actividad a Runtime. Runtime luego obtiene la superficie de control de visualización y la señal Vsync que acepta el objeto Choreographer y otros objetos o propiedades Java necesarios a través de JavaVM y la actividad.
xx Definición del sistema de coordenadas OpenXR
El sistema de coordenadas OpenXR define tres sistemas de coordenadas:
-
XR_REFERENCE_SPACE_TYPE_VIEW:
ver el sistema de coordenadas, el origen de las coordenadas es el ojo o el ojo izquierdo de HMD, el eje z se refiere al lado opuesto de la línea de visión, el eje y está hacia arriba verticalmente y x está horizontalmente hacia la derecha. -
XR_REFERENCE_SPACE_TYPE_LOCAL
sistema de coordenadas mundiales -
XR_REFERENCE_SPACE_TYPE_STAGE es
temporalmente igual que XR_REFERENCE_SPACE_TYPE_LOCAL, se puede considerar como XR_REFERENCE_SPACE_TYPE_LOCAL
xx Fórmula de conversión y definición de OpenXR xrLocateViews
- Definición de xrLocateViews
//session,应用创建的XrSession
//viewLocateInfo,主要包含预测时间及应用的基础坐标系
//viewState,表示预测状态标志位, position,orientation是否有效
//viewCapacityInput:view 数量,一般为2,表示左右眼
//views,获取的左右眼位置和姿态信息
XRAPI_ATTR XrResult XRAPI_CALL xrLocateViews(
XrSession session,
const XrViewLocateInfo* viewLocateInfo,
XrViewState* viewState,
uint32_t viewCapacityInput,
uint32_t* viewCountOutput,
XrView* views);
Primero, presentamos la estructura XrViewLocateInfo:
//displayTime:预测时间
//space:应用所在的基础坐标系。
typedef struct XrViewLocateInfo {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrViewConfigurationType viewConfigurationType;
XrTime displayTime;
XrSpace space;
} XrViewLocateInfo;
Antes de llamar a xrLocateViews, primero debe crear el sistema de coordenadas básico de una aplicación y establecer su posición y postura inicial.
El sistema de coordenadas básico m_appSpace de la aplicación Helloxr:
//m_appSpace的初始位置
referenceSpaceType=XR_REFERENCE_SPACE_TYPE_LOCAL
pose.orientaion = {
0,0,0,1}
pose.position= {
0,0,0}
Para la conveniencia del cálculo, se recomienda que m_appSpace tome el valor anterior; de lo contrario, la fórmula de cálculo debe considerar la influencia del espacio base, que es más problemático. ! En los cálculos futuros, todos asumimos que las coordenadas base son m_appSpace
xrLocateViews devuelve las vistas del objeto XrView, que se definen como
//pose:获取的view(表示左眼或者右眼)的位置姿态
//fov:获取的view(表示左眼或者右眼)的fov
typedef struct XrView {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrPosef pose;
XrFovf fov;
} XrView;
La fórmula de cálculo es:
- Lo que devuelve xrLocateViews es la relación de conversión de XrViewLocateInfo.space al sistema de coordenadas XR_REFERENCE_SPACE_TYPE_VIEW. Dado que el sistema de coordenadas base XrViewLocateInfo.space es m_appSpace, el tipo es XR_REFERENCE_SPACE_TYPE_LOCAL, y cuántas xrACEERENCE_SPACE_TYPE_LOCAL devuelve el sistema de coordenadas XRACE_SPACE_RACE_SPACE_REFERENCE_REFERENCE_REF. ¿Hasta qué punto coinciden el ángulo y la traslación con el sistema de coordenadas XR_REFERENCE_SPACE_TYPE_VIEW)
//i=0时,表示左眼
//i=1时,表示右眼
views[i].pose.orientation = head.orientaion*eye[i].orientation
views[i].pose.position = head.orientaion*eye[i].position+ head.position
- Si el tipo del sistema de coordenadas base XrViewLocateInfo.space es XR_REFERENCE_SPACE_TYPE_VIEW, se devuelve
la posición y postura del ojo. Dado que se supone que XrViewLocateInfo.space es m_appSpace, la fórmula no alcanzará
views[i].pose.orientation = eye[i].orientation
views[i].pose.position = eye[i].position
xx Fórmula de conversión y definición de OpenXR xrLocateSpace
- xrLocateSpace definición
//space:物体所在空间的初始位置姿态
//baseSpace:基础坐标空间,helloxr是m_appSpace
//time:预测时间
//location:获取的结果
XRAPI_ATTR XrResult XRAPI_CALL xrLocateSpace(
XrSpace space,
XrSpace baseSpace,
XrTime time,
XrSpaceLocation* location);
Antes de llamar a xrLocateSpace, primero debe pasar dos espacios de coordenadas, el espacio de coordenadas base baseSpace y el espacio espacial donde se encuentra el objeto.
El espacio de coordenadas básico baseSpace de helloxr es m_appSpace = {XR_REFERENCE_SPACE_TYPE_LOCAL, {0,0,0,}, {0,0,0,1}}.
xrLocateSpace devuelve la ubicación del objeto XrSpaceLocation, su definición
//locationFlags 为获取的pose的质量
//pose 为获取的pose
typedef struct XrSpaceLocation {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrSpaceLocationFlags locationFlags;
XrPosef pose;
} XrSpaceLocation;
La fórmula de cálculo es:
- Si el espacio es XR_REFERENCE_SPACE_TYPE_VIEW espacio de coordenadas
location.pose.orientation = head.orientaion*space.orientation
location.pose.position = head.orientation*space.postion+ head.position
- Si el espacio es XR_REFERENCE_SPACE_TYPE_LOCAL espacio de coordenadas
location.pose.orientation = space.orientation
location.pose.position = space.position
xx Cálculo de la matriz de OpenXR MVP
- Cálculo de la matriz ProjectionMatrix: directamente a través de las vistas [i]
fórmula .fov :
ProjectionMatrix=mat4_cast(views[i].fov)
- Cálculo de la matriz ViewMatrix:
al calcular la matriz ViewMatrix, las vistas [i] .pose no se pueden utilizar directamente y es necesario eliminar el 1 inverso.
oficial:
ViewMatrix = mat4_cast(invert(views[i].pose))
- Cálculo de la matriz ModelMatrix:
fórmula:
ModelMatrix= mat4_cast(location.pose)
El motivo de la inversión puede referirse a la siguiente fórmula de rotación bidimensional ↩︎