mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2025-02-16 17:11:15 +00:00
OpenXR projection matrix calculation from example code
This commit is contained in:
parent
ecd50dbcb1
commit
61b3192bce
2 changed files with 71 additions and 72 deletions
|
@ -328,12 +328,6 @@ void VR_DrawFrame( engine_t* engine ) {
|
||||||
vr.weapon_zoomLevel = 1.0f;
|
vr.weapon_zoomLevel = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Projection used for drawing HUD models etc
|
|
||||||
const ovrMatrix4f monoVRMatrix = ovrMatrix4f_CreateProjectionFov(
|
|
||||||
30.0f, 30.0f, 0.0f, 0.0f, 1.0f, 0.0f );
|
|
||||||
const ovrMatrix4f projectionMatrix = ovrMatrix4f_CreateProjectionFov(
|
|
||||||
vr.fov_x / vr.weapon_zoomLevel, vr.fov_y / vr.weapon_zoomLevel, 0.0f, 0.0f, 1.0f, 0.0f );
|
|
||||||
|
|
||||||
GLboolean stageBoundsDirty = GL_TRUE;
|
GLboolean stageBoundsDirty = GL_TRUE;
|
||||||
ovrApp_HandleXrEvents(&engine->appState);
|
ovrApp_HandleXrEvents(&engine->appState);
|
||||||
if (engine->appState.SessionActive == GL_FALSE) {
|
if (engine->appState.SessionActive == GL_FALSE) {
|
||||||
|
@ -395,16 +389,27 @@ void VR_DrawFrame( engine_t* engine ) {
|
||||||
projections));
|
projections));
|
||||||
//
|
//
|
||||||
|
|
||||||
|
XrFovf fov;
|
||||||
XrPosef viewTransform[2];
|
XrPosef viewTransform[2];
|
||||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||||
XrPosef xfHeadFromEye = projections[eye].pose;
|
XrPosef xfHeadFromEye = projections[eye].pose;
|
||||||
XrPosef xfStageFromEye = XrPosef_Multiply(xfStageFromHead, xfHeadFromEye);
|
XrPosef xfStageFromEye = XrPosef_Multiply(xfStageFromHead, xfHeadFromEye);
|
||||||
viewTransform[eye] = XrPosef_Inverse(xfStageFromEye);
|
viewTransform[eye] = XrPosef_Inverse(xfStageFromEye);
|
||||||
|
|
||||||
const XrFovf fov = projections[eye].fov;
|
fov = projections[eye].fov;
|
||||||
vr.fov_x = (fabs(fov.angleLeft) + fabs(fov.angleRight)) * 180.0f / M_PI;
|
|
||||||
vr.fov_y = (fabs(fov.angleUp) + fabs(fov.angleDown)) * 180.0f / M_PI;
|
|
||||||
}
|
}
|
||||||
|
vr.fov_x = (fabs(fov.angleLeft) + fabs(fov.angleRight)) * 180.0f / M_PI;
|
||||||
|
vr.fov_y = (fabs(fov.angleUp) + fabs(fov.angleDown)) * 180.0f / M_PI;
|
||||||
|
|
||||||
|
//Projection used for drawing HUD models etc
|
||||||
|
const ovrMatrix4f monoVRMatrix = ovrMatrix4f_CreateProjectionFov(
|
||||||
|
30.0f, 30.0f, 0.0f, 0.0f, 1.0f, 0.0f );
|
||||||
|
const ovrMatrix4f projectionMatrix = ovrMatrix4f_CreateProjectionFov(
|
||||||
|
fov.angleLeft / vr.weapon_zoomLevel,
|
||||||
|
fov.angleRight / vr.weapon_zoomLevel,
|
||||||
|
fov.angleUp / vr.weapon_zoomLevel,
|
||||||
|
fov.angleDown / vr.weapon_zoomLevel,
|
||||||
|
1.0f, 0.0f );
|
||||||
|
|
||||||
engine->appState.LayerCount = 0;
|
engine->appState.LayerCount = 0;
|
||||||
memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
||||||
|
@ -438,7 +443,7 @@ void VR_DrawFrame( engine_t* engine ) {
|
||||||
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
|
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
|
||||||
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||||
projection_layer_elements[eye].pose = XrPosef_Inverse(viewTransform[eye]);
|
projection_layer_elements[eye].pose = XrPosef_Inverse(viewTransform[eye]);
|
||||||
projection_layer_elements[eye].fov = projections[eye].fov;
|
projection_layer_elements[eye].fov = fov;
|
||||||
|
|
||||||
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
|
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
|
||||||
projection_layer_elements[eye].subImage.swapchain = frameBuffer->ColorSwapChain.Handle;
|
projection_layer_elements[eye].subImage.swapchain = frameBuffer->ColorSwapChain.Handle;
|
||||||
|
|
|
@ -465,82 +465,76 @@ ovrMatrix4f
|
||||||
================================================================================
|
================================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ovrMatrix4f ovrMatrix4f_CreateProjectionFov(
|
||||||
ovrMatrix4f ovrMatrix4f_CreateProjection(
|
const float angleLeft,
|
||||||
const float minX,
|
const float angleRight,
|
||||||
const float maxX,
|
const float angleUp,
|
||||||
float const minY,
|
const float angleDown,
|
||||||
const float maxY,
|
|
||||||
const float nearZ,
|
const float nearZ,
|
||||||
const float farZ) {
|
const float farZ) {
|
||||||
const float width = maxX - minX;
|
|
||||||
const float height = maxY - minY;
|
|
||||||
const float offsetZ = nearZ; // set to zero for a [0,1] clip space
|
|
||||||
|
|
||||||
ovrMatrix4f out;
|
const float tanAngleLeft = tanf(angleLeft);
|
||||||
|
const float tanAngleRight = tanf(angleRight);
|
||||||
|
|
||||||
|
const float tanAngleDown = tanf(angleDown);
|
||||||
|
const float tanAngleUp = tanf(angleUp);
|
||||||
|
|
||||||
|
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
|
||||||
|
|
||||||
|
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y
|
||||||
|
// down (Vulkan). Set to tanAngleUp - tanAngleDown for a clip space with
|
||||||
|
// positive Y up (OpenGL / D3D / Metal).
|
||||||
|
const float tanAngleHeight = tanAngleUp - tanAngleDown;
|
||||||
|
|
||||||
|
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
|
||||||
|
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
|
||||||
|
const float offsetZ = nearZ;
|
||||||
|
|
||||||
|
ovrMatrix4f result;
|
||||||
if (farZ <= nearZ) {
|
if (farZ <= nearZ) {
|
||||||
// place the far plane at infinity
|
// place the far plane at infinity
|
||||||
out.M[0][0] = 2 * nearZ / width;
|
result.M[0][0] = 2 / tanAngleWidth;
|
||||||
out.M[0][1] = 0;
|
result.M[0][1] = 0;
|
||||||
out.M[0][2] = (maxX + minX) / width;
|
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||||
out.M[0][3] = 0;
|
result.M[0][3] = 0;
|
||||||
|
|
||||||
out.M[1][0] = 0;
|
result.M[1][0] = 0;
|
||||||
out.M[1][1] = 2 * nearZ / height;
|
result.M[1][1] = 2 / tanAngleHeight;
|
||||||
out.M[1][2] = (maxY + minY) / height;
|
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||||
out.M[1][3] = 0;
|
result.M[1][3] = 0;
|
||||||
|
|
||||||
out.M[2][0] = 0;
|
result.M[2][0] = 0;
|
||||||
out.M[2][1] = 0;
|
result.M[2][1] = 0;
|
||||||
out.M[2][2] = -1;
|
result.M[2][2] = -1;
|
||||||
out.M[2][3] = -(nearZ + offsetZ);
|
result.M[2][3] = -(nearZ + offsetZ);
|
||||||
|
|
||||||
out.M[3][0] = 0;
|
result.M[3][0] = 0;
|
||||||
out.M[3][1] = 0;
|
result.M[3][1] = 0;
|
||||||
out.M[3][2] = -1;
|
result.M[3][2] = -1;
|
||||||
out.M[3][3] = 0;
|
result.M[3][3] = 0;
|
||||||
} else {
|
} else {
|
||||||
// normal projection
|
// normal projection
|
||||||
out.M[0][0] = 2 * nearZ / width;
|
result.M[0][0] = 2 / tanAngleWidth;
|
||||||
out.M[0][1] = 0;
|
result.M[0][1] = 0;
|
||||||
out.M[0][2] = (maxX + minX) / width;
|
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||||
out.M[0][3] = 0;
|
result.M[0][3] = 0;
|
||||||
|
|
||||||
out.M[1][0] = 0;
|
result.M[1][0] = 0;
|
||||||
out.M[1][1] = 2 * nearZ / height;
|
result.M[1][1] = 2 / tanAngleHeight;
|
||||||
out.M[1][2] = (maxY + minY) / height;
|
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||||
out.M[1][3] = 0;
|
result.M[1][3] = 0;
|
||||||
|
|
||||||
out.M[2][0] = 0;
|
result.M[2][0] = 0;
|
||||||
out.M[2][1] = 0;
|
result.M[2][1] = 0;
|
||||||
out.M[2][2] = -(farZ + offsetZ) / (farZ - nearZ);
|
result.M[2][2] = -(farZ + offsetZ) / (farZ - nearZ);
|
||||||
out.M[2][3] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
|
result.M[2][3] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
|
||||||
|
|
||||||
out.M[3][0] = 0;
|
result.M[3][0] = 0;
|
||||||
out.M[3][1] = 0;
|
result.M[3][1] = 0;
|
||||||
out.M[3][2] = -1;
|
result.M[3][2] = -1;
|
||||||
out.M[3][3] = 0;
|
result.M[3][3] = 0;
|
||||||
}
|
}
|
||||||
return out;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
ovrMatrix4f ovrMatrix4f_CreateProjectionFov(
|
|
||||||
const float fovDegreesX,
|
|
||||||
const float fovDegreesY,
|
|
||||||
const float offsetX,
|
|
||||||
const float offsetY,
|
|
||||||
const float nearZ,
|
|
||||||
const float farZ) {
|
|
||||||
const float halfWidth = nearZ * tanf(fovDegreesX * (M_PI / 180.0f * 0.5f));
|
|
||||||
const float halfHeight = nearZ * tanf(fovDegreesY * (M_PI / 180.0f * 0.5f));
|
|
||||||
|
|
||||||
const float minX = offsetX - halfWidth;
|
|
||||||
const float maxX = offsetX + halfWidth;
|
|
||||||
|
|
||||||
const float minY = offsetY - halfHeight;
|
|
||||||
const float maxY = offsetY + halfHeight;
|
|
||||||
|
|
||||||
return ovrMatrix4f_CreateProjection(minX, maxX, minY, maxY, nearZ, farZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ovrMatrix4f ovrMatrix4f_CreateFromQuaternion(const XrQuaternionf* q) {
|
ovrMatrix4f ovrMatrix4f_CreateFromQuaternion(const XrQuaternionf* q) {
|
||||||
|
|
Loading…
Reference in a new issue