mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-22 03:51:40 +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;
|
||||
}
|
||||
|
||||
//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;
|
||||
ovrApp_HandleXrEvents(&engine->appState);
|
||||
if (engine->appState.SessionActive == GL_FALSE) {
|
||||
|
@ -395,16 +389,27 @@ void VR_DrawFrame( engine_t* engine ) {
|
|||
projections));
|
||||
//
|
||||
|
||||
XrFovf fov;
|
||||
XrPosef viewTransform[2];
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
XrPosef xfHeadFromEye = projections[eye].pose;
|
||||
XrPosef xfStageFromEye = XrPosef_Multiply(xfStageFromHead, xfHeadFromEye);
|
||||
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;
|
||||
}
|
||||
|
||||
//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;
|
||||
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));
|
||||
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||
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));
|
||||
projection_layer_elements[eye].subImage.swapchain = frameBuffer->ColorSwapChain.Handle;
|
||||
|
|
|
@ -465,82 +465,76 @@ ovrMatrix4f
|
|||
================================================================================
|
||||
*/
|
||||
|
||||
|
||||
ovrMatrix4f ovrMatrix4f_CreateProjection(
|
||||
const float minX,
|
||||
const float maxX,
|
||||
float const minY,
|
||||
const float maxY,
|
||||
ovrMatrix4f ovrMatrix4f_CreateProjectionFov(
|
||||
const float angleLeft,
|
||||
const float angleRight,
|
||||
const float angleUp,
|
||||
const float angleDown,
|
||||
const float nearZ,
|
||||
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) {
|
||||
// place the far plane at infinity
|
||||
out.M[0][0] = 2 * nearZ / width;
|
||||
out.M[0][1] = 0;
|
||||
out.M[0][2] = (maxX + minX) / width;
|
||||
out.M[0][3] = 0;
|
||||
result.M[0][0] = 2 / tanAngleWidth;
|
||||
result.M[0][1] = 0;
|
||||
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result.M[0][3] = 0;
|
||||
|
||||
out.M[1][0] = 0;
|
||||
out.M[1][1] = 2 * nearZ / height;
|
||||
out.M[1][2] = (maxY + minY) / height;
|
||||
out.M[1][3] = 0;
|
||||
result.M[1][0] = 0;
|
||||
result.M[1][1] = 2 / tanAngleHeight;
|
||||
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result.M[1][3] = 0;
|
||||
|
||||
out.M[2][0] = 0;
|
||||
out.M[2][1] = 0;
|
||||
out.M[2][2] = -1;
|
||||
out.M[2][3] = -(nearZ + offsetZ);
|
||||
result.M[2][0] = 0;
|
||||
result.M[2][1] = 0;
|
||||
result.M[2][2] = -1;
|
||||
result.M[2][3] = -(nearZ + offsetZ);
|
||||
|
||||
out.M[3][0] = 0;
|
||||
out.M[3][1] = 0;
|
||||
out.M[3][2] = -1;
|
||||
out.M[3][3] = 0;
|
||||
result.M[3][0] = 0;
|
||||
result.M[3][1] = 0;
|
||||
result.M[3][2] = -1;
|
||||
result.M[3][3] = 0;
|
||||
} else {
|
||||
// normal projection
|
||||
out.M[0][0] = 2 * nearZ / width;
|
||||
out.M[0][1] = 0;
|
||||
out.M[0][2] = (maxX + minX) / width;
|
||||
out.M[0][3] = 0;
|
||||
result.M[0][0] = 2 / tanAngleWidth;
|
||||
result.M[0][1] = 0;
|
||||
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result.M[0][3] = 0;
|
||||
|
||||
out.M[1][0] = 0;
|
||||
out.M[1][1] = 2 * nearZ / height;
|
||||
out.M[1][2] = (maxY + minY) / height;
|
||||
out.M[1][3] = 0;
|
||||
result.M[1][0] = 0;
|
||||
result.M[1][1] = 2 / tanAngleHeight;
|
||||
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result.M[1][3] = 0;
|
||||
|
||||
out.M[2][0] = 0;
|
||||
out.M[2][1] = 0;
|
||||
out.M[2][2] = -(farZ + offsetZ) / (farZ - nearZ);
|
||||
out.M[2][3] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
|
||||
result.M[2][0] = 0;
|
||||
result.M[2][1] = 0;
|
||||
result.M[2][2] = -(farZ + offsetZ) / (farZ - nearZ);
|
||||
result.M[2][3] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
|
||||
|
||||
out.M[3][0] = 0;
|
||||
out.M[3][1] = 0;
|
||||
out.M[3][2] = -1;
|
||||
out.M[3][3] = 0;
|
||||
result.M[3][0] = 0;
|
||||
result.M[3][1] = 0;
|
||||
result.M[3][2] = -1;
|
||||
result.M[3][3] = 0;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
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);
|
||||
return result;
|
||||
}
|
||||
|
||||
ovrMatrix4f ovrMatrix4f_CreateFromQuaternion(const XrQuaternionf* q) {
|
||||
|
|
Loading…
Reference in a new issue