Several good fixes / improvements

- Positional tracking in Death Cam mode (so much nicer now)
- All 2D HUD elements now draw in both eyes
- HUD elements based on models are now 3D (face etc)
- Better 4:3 screen for virtual screen
This commit is contained in:
Simon 2022-02-03 21:32:09 +00:00
parent 6f3875e9a2
commit 2c9b286da5
13 changed files with 115 additions and 57 deletions

View file

@ -2670,12 +2670,8 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
vec3_t baseOrg;
VectorCopy( cg.refdef.vieworg, baseOrg );
float worldscale = trap_Cvar_VariableValue("vr_worldscale");
if ( cg.snap->ps.stats[STAT_HEALTH] <= 0 )
{
worldscale *= 50;
}
float worldscale = trap_Cvar_VariableValue("vr_worldscale") *
(( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) ? DEATH_WORLDSCALE_MULTIPLIER : 1.0f);
float ipd = 0.065f;
float separation = stereoView == STEREO_LEFT ?

View file

@ -61,7 +61,7 @@ void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) {
float screenXScale = cgs.screenXScale / 2.75f;
float screenYScale = cgs.screenYScale / 2.25f;
int xoffset = -60;
int xoffset = -120;
if (hudStereoView == STEREO_LEFT) {
xoffset *= -1;
}

View file

@ -76,6 +76,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define NUM_CROSSHAIRS 10
//multiplying size you go to when dead looking down on the match
#define DEATH_WORLDSCALE_MULTIPLIER 40
#define PLAYER_HEIGHT 48
#define TEAM_OVERLAY_MAXNAME_WIDTH 12
#define TEAM_OVERLAY_MAXLOCATION_WIDTH 16
@ -627,6 +632,7 @@ typedef struct {
float v_dmg_time;
float v_dmg_pitch;
float v_dmg_roll;
vec3_t v_death_origin;
// temp working variables for player view
float bobfracsin;
@ -1362,7 +1368,9 @@ void CG_NextWeapon_f( void );
void CG_PrevWeapon_f( void );
void CG_Weapon_f( void );
void rotateAboutOrigin(float x, float y, float rotation, vec2_t out);
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out);
void CG_RegisterWeapon( int weaponNum );
void CG_RegisterItemVisuals( int itemNum );
@ -1501,6 +1509,7 @@ void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *def
void trap_Cvar_Update( vmCvar_t *vmCvar );
void trap_Cvar_Set( const char *var_name, const char *value );
void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
float trap_Cvar_VariableValue( const char *var_name );
// ServerCommand and ConsoleCommand parameter access
int trap_Argc( void );

View file

@ -23,7 +23,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// cg_view.c -- setup all the parameters (position, angle, etc)
// for a 3D rendering
#include "cg_local.h"
#include "../vr/vr_clientinfo.h"
extern vr_clientinfo_t* cgVR;
/*
=============================================================================
@ -216,6 +218,25 @@ static void CG_CalcVrect (void) {
//==============================================================================
/*
===============
CG_OffsetDeathView
===============
*/
static void CG_OffsetDeathView( void ) {
vec3_t position_delta;
VectorNegate(cgVR->hmdposition_delta, position_delta);
CG_ConvertFromVR(position_delta, NULL, position_delta);
position_delta[2] = 0;
VectorScale(position_delta, (DEATH_WORLDSCALE_MULTIPLIER / 2), position_delta);
VectorAdd(cg.v_death_origin, position_delta, cg.v_death_origin);
VectorCopy(cg.v_death_origin, cg.refdef.vieworg);
cg.refdef.vieworg[2] += DEATH_WORLDSCALE_MULTIPLIER * cg.predictedPlayerState.viewheight;
}
/*
===============
CG_OffsetThirdPersonView
@ -234,16 +255,12 @@ static void CG_OffsetThirdPersonView( void ) {
float focusDist;
float forwardScale, sideScale;
VectorCopy(cg.refdef.vieworg, cg.v_death_origin);
cg.refdef.vieworg[2] += cg.predictedPlayerState.viewheight;
VectorCopy( cg.refdefViewAngles, focusAngles );
if ( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) {
//Be 50 times taller
cg.refdef.vieworg[2] += 50 * cg.predictedPlayerState.viewheight;
return;
}
if ( focusAngles[PITCH] > 45 ) {
focusAngles[PITCH] = 45; // don't go too far overhead
}
@ -331,11 +348,7 @@ static void CG_OffsetFirstPersonView( void ) {
origin = cg.refdef.vieworg;
angles = cg.refdefViewAngles;
if ( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) {
//Be 50 times taller
origin[2] += 50 * cg.predictedPlayerState.viewheight;
return;
}
VectorCopy(cg.refdef.vieworg, cg.v_death_origin);
// add angles based on damage kick
if ( cg.damageTime ) {
@ -671,7 +684,10 @@ static int CG_CalcViewValues( void ) {
}
}
if ( cg.renderingThirdPerson ) {
if (cg.snap->ps.stats[STAT_HEALTH] <= 0) {
//If dead, view the map from above
CG_OffsetDeathView();
} else if ( cg.renderingThirdPerson ) {
// back away from character
CG_OffsetThirdPersonView();
} else {
@ -799,7 +815,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
// decide on third person view
cg.renderingThirdPerson = cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR
&& (cg_thirdPerson.integer || (cg.snap->ps.stats[STAT_HEALTH] <= 0));
&& cg_thirdPerson.integer;
// build cg.refdef
inwater = CG_CalcViewValues();

View file

@ -224,7 +224,7 @@ float trap_Cvar_VariableValue( const char *var_name ) {
return atof(buf);
}
void convertFromVR(vec3_t in, vec3_t offset, vec3_t out)
void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
{
vec3_t vrSpace;
VectorSet(vrSpace, in[2], in[0], in[1] );
@ -247,7 +247,7 @@ void convertFromVR(vec3_t in, vec3_t offset, vec3_t out)
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles )
{
convertFromVR(cgVR->calculated_weaponoffset, cg.refdef.vieworg, origin);
CG_ConvertFromVR(cgVR->calculated_weaponoffset, cg.refdef.vieworg, origin);
float worldscale = trap_Cvar_VariableValue("vr_worldscale");
origin[2] -= PLAYER_HEIGHT;

View file

@ -90,7 +90,8 @@ typedef struct {
void (*EndFrame)( int *frontEndMsec, int *backEndMsec );
#if __ANDROID__
void (*SetVRHeadsetParms)( const ovrMatrix4f *projectionMatrix, int renderBufferL, int renderBufferR );
void (*SetVRHeadsetParms)( const ovrMatrix4f *projectionMatrixLeft, const ovrMatrix4f *projectionMatrixRight,
int renderBufferL, int renderBufferR );
#endif
int (*MarkFragments)( int numPoints, const vec3_t *points, const vec3_t projection,

View file

@ -1769,6 +1769,10 @@ const void* RB_SwitchEye( const void* data ) {
tr.renderFbo->frameBuffer = cmd->eye;
// finish any 2D drawing if needed
if(tess.numIndexes)
RB_EndSurface();
// Not calling FBO_Bind explicitly, since we just update the frameBuffer
// within the struct.
if (tr.renderFbo == glState.currentFBO)

View file

@ -584,8 +584,10 @@ void R_Mat4Transpose( const float in[4][4], float* out ) {
}
void RE_SetVRHeadsetParms( const ovrMatrix4f *projectionMatrix, int renderBufferL, int renderBufferR ) {
R_Mat4Transpose(projectionMatrix->M, tr.vrParms.projection);
void RE_SetVRHeadsetParms( const ovrMatrix4f *projectionMatrixLeft, const ovrMatrix4f *projectionMatrixRight,
int renderBufferL, int renderBufferR ) {
R_Mat4Transpose(projectionMatrixLeft->M, tr.vrParms.projectionL);
R_Mat4Transpose(projectionMatrixRight->M, tr.vrParms.projectionR);
tr.vrParms.renderBufferL = renderBufferL;
tr.vrParms.renderBufferR = renderBufferR;
tr.vrParms.valid = qtrue;

View file

@ -841,7 +841,8 @@ typedef struct {
typedef struct {
qboolean valid;
float projection[16];
float projectionL[16];
float projectionR[16];
int renderBufferL;
int renderBufferR;
int renderBufferOriginal;
@ -2504,7 +2505,8 @@ void RE_StretchPic ( float x, float y, float w, float h,
void RE_BeginFrame( stereoFrame_t stereoFrame );
void RE_EndFrame( int *frontEndMsec, int *backEndMsec );
#if __ANDROID__
void RE_SetVRHeadsetParms( const ovrMatrix4f *projectionMatrix, int renderBufferL, int renderBufferR );
void RE_SetVRHeadsetParms( const ovrMatrix4f *projectionMatrixLeft, const ovrMatrix4f *projectionMatrixRight,
int renderBufferL, int renderBufferR );
#endif
void RE_SaveJPG(char * filename, int quality, int image_width, int image_height,
unsigned char *image_buffer, int padding);

View file

@ -765,15 +765,12 @@ void R_SetupProjection(viewParms_t *dest, float zProj, float zFar, qboolean comp
height = ymax - ymin;
if (tr.vrParms.valid) {
memcpy(&dest->projectionMatrix, &tr.vrParms.projection, sizeof(dest->projectionMatrix));
/*
if (dest->stereoFrame == STEREO_LEFT) {
memcpy(&dest->projectionMatrix, &tr.vrParms.projectionL, sizeof(dest->projectionMatrix));
}
else {
memcpy(&dest->projectionMatrix, &tr.vrParms.projectionR, sizeof(dest->projectionMatrix));
}
*/
} else {
/*
* offset the view origin of the viewer for stereo rendering

View file

@ -5,8 +5,6 @@
#include "vr_types.h"
#define PLAYER_HEIGHT 48
engine_t* VR_Init( ovrJava java );
void VR_InitCvars( void );
void VR_Destroy( engine_t* engine );

View file

@ -175,13 +175,17 @@ void QuatToYawPitchRoll(ovrQuatf q, vec3_t rotation, vec3_t out) {
GetAnglesFromVectors(forwardNormal, rightNormal, upNormal, out);
}
void sendButtonActionSimple(const char* action)
static void sendButtonActionSimple(const char* action)
{
char command[256];
snprintf( command, sizeof( command ), "%s\n", action );
Cbuf_AddText( command );
}
static float length(float x, float y)
{
return sqrtf(powf(x, 2.0f) + powf(y, 2.0f));
}
void IN_VRInit( void )
{
@ -202,7 +206,6 @@ static void IN_VRController( qboolean isRightController, ovrTracking remoteTrack
VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta);
VectorCopy(vr.weaponangles, vr.weaponangles_last);
//Record recent weapon position for trajectory based stuff
for (int i = (NUM_WEAPON_SAMPLES-1); i != 0; --i)
{
@ -220,8 +223,29 @@ static void IN_VRController( qboolean isRightController, ovrTracking remoteTrack
//Just copy to calculated offset, used to use this in case we wanted to apply any modifiers, but don't any more
VectorCopy(vr.current_weaponoffset, vr.calculated_weaponoffset);
} else {
vec3_t rotation = {0};
rotation[PITCH] =-20.0f;
QuatToYawPitchRoll(remoteTracking.HeadPose.Pose.Orientation, rotation, vr.offhandangles);
///location relative to view
vr.offhandoffset[0] = remoteTracking.HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.offhandoffset[1] = remoteTracking.HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.offhandoffset[2] = remoteTracking.HeadPose.Pose.Position.z - vr.hmdposition[2];
}
if (vr.weapon_stabilised)
{
float x = vr.offhandoffset[0] - vr.calculated_weaponoffset[0];
float y = vr.offhandoffset[1] - vr.calculated_weaponoffset[1];
float z = vr.offhandoffset[2] - vr.calculated_weaponoffset[2];
float zxDist = length(x, z);
if (zxDist != 0.0f && z != 0.0f) {
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
-degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / 2.0f); //Dampen roll on stabilised weapon
}
}
}
static void IN_VRJoystick( qboolean isRightController, float joystickX, float joystickY )
@ -320,12 +344,20 @@ static void IN_VRButtonsChanged( qboolean isRightController, uint32_t buttons )
{
vrController_t* controller = isRightController == qtrue ? &rightController : &leftController;
if (isRightController == qfalse)
{
if ((buttons & ovrButton_Enter) && !(controller->buttons & ovrButton_Enter)) {
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qtrue, 0, NULL);
} else if (!(buttons & ovrButton_Enter) && (controller->buttons & ovrButton_Enter)) {
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qfalse, 0, NULL);
if (isRightController == qfalse) {
if ((buttons & ovrButton_Enter) && !(controller->buttons & ovrButton_Enter)) {
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qtrue, 0, NULL);
} else if (!(buttons & ovrButton_Enter) && (controller->buttons & ovrButton_Enter)) {
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qfalse, 0, NULL);
}
}
if (isRightController != (vr_righthanded->integer != 0))
{
if ((buttons & ovrButton_GripTrigger) && !(controller->buttons & ovrButton_GripTrigger)) {
vr.weapon_stabilised = qtrue;
} else if (!(buttons & ovrButton_GripTrigger) && (controller->buttons & ovrButton_GripTrigger)) {
vr.weapon_stabilised = qfalse;
}
}
@ -453,13 +485,13 @@ void IN_VRInputFrame( void )
continue;
}
if (controller->buttons ^ state.Buttons) {
IN_VRButtonsChanged(isRight, state.Buttons);
}
IN_VRController(isRight, remoteTracking);
IN_VRJoystick(isRight, state.Joystick.x, state.Joystick.y);
IN_VRTriggers(isRight, state.IndexTrigger);
if (controller->buttons ^ state.Buttons) {
IN_VRButtonsChanged(isRight, state.Buttons);
}
}
in_vrEventTime = Sys_Milliseconds( );

View file

@ -7,6 +7,7 @@
#include "../VrApi/Include/VrApi_Types.h"
#include "vr_clientinfo.h"
#include "vr_types.h"
//#include "../SDL2/include/SDL_opengles2_gl2.h"
#pragma clang diagnostic push
@ -46,8 +47,8 @@ void VR_GetResolution(engine_t* engine, int *pWidth, int *pHeight)
if (engine)
{
*pHeight = height = *pWidth = width = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH) * SUPER_SAMPLE;
//*pHeight = height = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT) * SUPER_SAMPLE;
*pWidth = width = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH) * SUPER_SAMPLE;
*pHeight = height = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT) * SUPER_SAMPLE;
}
else
{
@ -228,13 +229,6 @@ void VR_DrawFrame( engine_t* engine ) {
engine->predictedDisplayTime = vrapi_GetPredictedDisplayTime(engine->ovr, engine->frameIndex);
engine->tracking = vrapi_GetPredictedTracking2(engine->ovr, engine->predictedDisplayTime);
//Now using a symmetrical render target, based on the horizontal FOV
float fov = vrapi_GetSystemPropertyInt( engine->ovr, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y);
// Setup the projection matrix.
const ovrMatrix4f projectionMatrix = ovrMatrix4f_CreateProjectionFov(
fov, fov, 0.0f, 0.0f, 1.0f, 0.0f );
static int playerYaw = 0;
int eyeW, eyeH;
@ -247,7 +241,7 @@ void VR_DrawFrame( engine_t* engine ) {
// Add a simple cylindrical layer
cylinderLayer.Cylinder =
BuildCylinderLayer(engine, eyeW, eyeW, &engine->tracking, radians(playerYaw) );
BuildCylinderLayer(engine, eyeW, eyeW * 0.75f, &engine->tracking, radians(playerYaw) );
const ovrLayerHeader2* layers[] = {
&cylinderLayer.Header
@ -264,7 +258,14 @@ void VR_DrawFrame( engine_t* engine ) {
const framebuffer_t* framebuffers = engine->framebuffers;
re.SetVRHeadsetParms(&projectionMatrix,
//Now using a symmetrical render target, based on the horizontal FOV
float fov = vrapi_GetSystemPropertyInt( engine->ovr, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y);
// Setup the projection matrix.
const ovrMatrix4f projectionMatrix = ovrMatrix4f_CreateProjectionFov(
fov, fov, 0.0f, 0.0f, 1.0f, 0.0f );
re.SetVRHeadsetParms(&projectionMatrix, &projectionMatrix,
framebuffers[0].framebuffers[framebuffers[0].swapchainIndex],
framebuffers[1].framebuffers[framebuffers[1].swapchainIndex]);
@ -288,7 +289,7 @@ void VR_DrawFrame( engine_t* engine ) {
for (int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; ++eye) {
layer.Textures[eye].ColorSwapChain = engine->framebuffers[eye].colorTexture;
layer.Textures[eye].SwapChainIndex = engine->framebuffers[eye].swapchainIndex;
layer.Textures[eye].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection(&projectionMatrix);
layer.Textures[eye].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection(&engine->tracking.Eye[eye].ProjectionMatrix);
}
@ -297,7 +298,7 @@ void VR_DrawFrame( engine_t* engine ) {
VR_ClearFrameBuffer(framebuffers[0].framebuffers[framebuffers[0].swapchainIndex], eyeW, eyeH);
VR_ClearFrameBuffer(framebuffers[1].framebuffers[framebuffers[1].swapchainIndex], eyeW, eyeH);
re.SetVRHeadsetParms(&projectionMatrix,
re.SetVRHeadsetParms(&engine->tracking.Eye[0].ProjectionMatrix, &engine->tracking.Eye[1].ProjectionMatrix,
framebuffers[0].framebuffers[framebuffers[0].swapchainIndex],
framebuffers[1].framebuffers[framebuffers[1].swapchainIndex]);