OpenXR stuff should be a little more usable now.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5850 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
13d524a30b
commit
f35928f4fd
25 changed files with 360 additions and 353 deletions
|
@ -49,7 +49,8 @@ static cvar_t cl_sendchatstate = CVARD("cl_sendchatstate", "1", "Announce your c
|
|||
|
||||
cvar_t cl_prydoncursor = CVAR("cl_prydoncursor", ""); //for dp protocol
|
||||
cvar_t cl_instantrotate = CVARF("cl_instantrotate", "1", CVAR_SEMICHEAT);
|
||||
cvar_t in_xflip = {"in_xflip", "0"};
|
||||
cvar_t in_xflip = CVAR("in_xflip", "0");
|
||||
cvar_t in_vraim = CVARD("in_vraim", "1", "When set to 1, the 'view' angle sent to the server is controlled by your vr headset instead of separately. This is for fallback behaviour and blocks mouse+joy+gamepad aiming.");
|
||||
|
||||
cvar_t prox_inmenu = CVAR("prox_inmenu", "0");
|
||||
|
||||
|
@ -915,7 +916,7 @@ void CL_BaseMove (usercmd_t *cmd, int pnum, float priortime, float extratime)
|
|||
float nscale = extratime?extratime / (extratime+priortime):0;
|
||||
float oscale = 1 - nscale;
|
||||
|
||||
cmd->fservertime = cl.time*1000;
|
||||
cmd->fservertime = cl.time;
|
||||
cmd->servertime = cl.time*1000;
|
||||
|
||||
//
|
||||
|
@ -940,7 +941,7 @@ void CL_BaseMove (usercmd_t *cmd, int pnum, float priortime, float extratime)
|
|||
CL_GatherButtons(cmd, pnum);
|
||||
}
|
||||
|
||||
static void CL_ClampPitch (int pnum, float frametime)
|
||||
void CL_ClampPitch (int pnum, float frametime)
|
||||
{
|
||||
float mat[16];
|
||||
float roll;
|
||||
|
@ -1097,6 +1098,30 @@ static void CL_ClampPitch (int pnum, float frametime)
|
|||
pv->viewangles[YAW] *= 360;
|
||||
VectorClear(pv->viewanglechange);
|
||||
|
||||
if (in_vraim.ival && (pv->vrdev[VRDEV_HEAD].status&VRSTATUS_ANG))
|
||||
{ //overcomplicated code to replace the pitch+roll angles and add to the yaw angle.
|
||||
#if 0
|
||||
matrix3x4 base, head, res;
|
||||
vec3_t na = {0, pv->viewangles[YAW], 0};
|
||||
vec3_t f,l,u,o;
|
||||
Matrix3x4_RM_FromAngles(na, vec3_origin, base[0]);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
na[i] = SHORT2ANGLE(pv->vrdev[VRDEV_HEAD].angles[i]);
|
||||
Matrix3x4_RM_FromAngles(na, pv->vrdev[VRDEV_HEAD].origin, head[0]);
|
||||
Matrix3x4_Multiply(head[0], base[0], res[0]);
|
||||
Matrix3x4_RM_ToVectors(res[0], f,l,u,o);
|
||||
VectorAngles(f,u,pv->aimangles,false);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
cmd->angles[i] = ANGLE2SHORT(na[i]);
|
||||
#else
|
||||
pv->aimangles[PITCH] = SHORT2ANGLE(pv->vrdev[VRDEV_HEAD].angles[PITCH]);
|
||||
pv->aimangles[YAW] = SHORT2ANGLE(pv->vrdev[VRDEV_HEAD].angles[YAW]) + pv->viewangles[YAW];
|
||||
pv->aimangles[ROLL] = SHORT2ANGLE(pv->vrdev[VRDEV_HEAD].angles[ROLL]);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
VectorCopy(pv->viewangles, pv->aimangles);
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
|
@ -1129,6 +1154,11 @@ static void CL_ClampPitch (int pnum, float frametime)
|
|||
pv->viewangles[PITCH] = cl.maxpitch;
|
||||
if (pv->viewangles[PITCH] < cl.minpitch)
|
||||
pv->viewangles[PITCH] = cl.minpitch;
|
||||
|
||||
if (pv->aimangles[PITCH] > cl.maxpitch)
|
||||
pv->aimangles[PITCH] = cl.maxpitch;
|
||||
if (pv->aimangles[PITCH] < cl.minpitch)
|
||||
pv->aimangles[PITCH] = cl.minpitch;
|
||||
}
|
||||
|
||||
// if (cl.viewangles[pnum][ROLL] > 50)
|
||||
|
@ -1169,7 +1199,10 @@ static void CL_FinishMove (usercmd_t *cmd, int pnum)
|
|||
CL_GatherButtons(cmd, pnum);
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
cmd->angles[i] = ((int)(cl.playerview[pnum].viewangles[i]*65536.0/360)&65535);
|
||||
cmd->angles[i] = (int)(ANGLE2SHORT(cl.playerview[pnum].aimangles[i]))&65535;
|
||||
cmd->vr[VRDEV_LEFT] = cl.playerview[pnum].vrdev[VRDEV_LEFT];
|
||||
cmd->vr[VRDEV_RIGHT] = cl.playerview[pnum].vrdev[VRDEV_RIGHT];
|
||||
cmd->vr[VRDEV_HEAD] = cl.playerview[pnum].vrdev[VRDEV_HEAD];
|
||||
|
||||
if (in_impulsespending[pnum] && !cl.paused)
|
||||
{
|
||||
|
@ -2559,6 +2592,7 @@ void CL_InitInput (void)
|
|||
|
||||
Cvar_Register (&cl_fastaccel, inputnetworkcvargroup);
|
||||
Cvar_Register (&in_xflip, inputnetworkcvargroup);
|
||||
Cvar_Register (&in_vraim, inputnetworkcvargroup);
|
||||
Cvar_Register (&cl_nodelta, inputnetworkcvargroup);
|
||||
|
||||
Cvar_Register (&prox_inmenu, inputnetworkcvargroup);
|
||||
|
|
|
@ -5978,55 +5978,6 @@ qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CL_UpdateHeadAngles(void)
|
||||
{
|
||||
/*FIXME: no idea what I'm doing with this. lets just not break anything for now
|
||||
//identity, for now
|
||||
vec3_t headchange[3] =
|
||||
{
|
||||
{1,0,0},
|
||||
{0,1,0},
|
||||
{0,0,1}
|
||||
};
|
||||
vec3_t tmp[3], tmp2[3];
|
||||
playerview_t *pv = &cl.playerview[0];
|
||||
|
||||
tmp2[0][0] = 0;
|
||||
tmp2[0][1] = host_frametime*90;
|
||||
tmp2[0][2] = 0;
|
||||
AngleVectorsFLU(tmp2[0], headchange[0], headchange[1], headchange[2]);
|
||||
|
||||
switch(cl_headmode.ival)
|
||||
{
|
||||
case 3: //head angles change both
|
||||
R_ConcatRotations(headchange, r_refdef.headaxis, tmp);
|
||||
break;
|
||||
case 2: //head changes are entirely relative to the 'view' angle
|
||||
R_ConcatRotations(headchange, r_refdef.headaxis, tmp);
|
||||
memcpy(r_refdef.headaxis, tmp, sizeof(r_refdef.headaxis));
|
||||
break;
|
||||
case 1: //head changes change the view angle directly.
|
||||
|
||||
AngleVectorsFLU(pv->viewangles, tmp[0], tmp[1], tmp[2]);
|
||||
R_ConcatRotations(headchange, tmp, tmp2);
|
||||
VectorAngles(tmp2[0], tmp2[2], pv->viewangles);
|
||||
pv->viewangles[0] *= r_meshpitch.value;
|
||||
pv->viewangles[2] *= r_meshroll.value;
|
||||
|
||||
//fall through
|
||||
default:
|
||||
case 0: //off
|
||||
VectorSet(r_refdef.headaxis[0], 1, 0, 0);
|
||||
VectorSet(r_refdef.headaxis[1], 0, 1, 0);
|
||||
VectorSet(r_refdef.headaxis[2], 0, 0, 1);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
VectorSet(r_refdef.headaxis[0], 1, 0, 0);
|
||||
VectorSet(r_refdef.headaxis[1], 0, 1, 0);
|
||||
VectorSet(r_refdef.headaxis[2], 0, 0, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_Frame
|
||||
|
@ -6363,8 +6314,6 @@ double Host_Frame (double time)
|
|||
if (emscriptenfte_getvrframedata())
|
||||
r_refdef.stereomethod = STEREO_WEBVR;
|
||||
#endif
|
||||
CL_UpdateHeadAngles();
|
||||
|
||||
{
|
||||
RSpeedMark();
|
||||
vid.ime_allow = false;
|
||||
|
|
|
@ -1036,7 +1036,7 @@ void CL_PredictMovePNum (int seat)
|
|||
else
|
||||
{
|
||||
lerpangles = (cls.demoplayback == DPB_QUAKEWORLD);
|
||||
VectorCopy (pv->viewangles, pv->simangles);
|
||||
VectorCopy (pv->aimangles, pv->simangles);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -661,6 +661,7 @@ struct playerview_s
|
|||
// the client maintains its own idea of view angles, which are
|
||||
// sent to the server each frame. And only reset at level change
|
||||
// and teleport times
|
||||
vec3_t aimangles; //angles actually being sent to the server (different due to in_vraim)
|
||||
vec3_t viewangles; //current angles
|
||||
vec3_t viewanglechange; //angles set by input code this frame
|
||||
vec3_t intermissionangles; //absolute angles for intermission
|
||||
|
@ -773,6 +774,8 @@ struct playerview_s
|
|||
size_t reverbtype;
|
||||
vec3_t velocity;
|
||||
} audio;
|
||||
|
||||
struct vrdevinfo_s vrdev[VRDEV_COUNT];
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
@ -1092,6 +1092,7 @@ qboolean IN_SetHandPosition(const char *devname, vec3_t org, vec3_t ang, vec3_t
|
|||
{
|
||||
int dtype;
|
||||
int seat;
|
||||
struct vrdevinfo_s *dev;
|
||||
if (!strncmp(devname, "left", 4))
|
||||
{
|
||||
seat = atoi(devname+4);
|
||||
|
@ -1111,23 +1112,35 @@ qboolean IN_SetHandPosition(const char *devname, vec3_t org, vec3_t ang, vec3_t
|
|||
return false; //no idea what you're talking about.
|
||||
if (seat < 0 || seat >= MAX_SPLITS)
|
||||
return false; //duuuude!
|
||||
cl_pendingcmd[seat].vr[dtype].status =
|
||||
dev = &cl.playerview[seat].vrdev[dtype];
|
||||
|
||||
if (org)
|
||||
VectorCopy(org, dev->origin);
|
||||
else
|
||||
VectorClear(dev->origin);
|
||||
if (ang)
|
||||
{
|
||||
dev->angles[0] = ANGLE2SHORT(ang[0]),
|
||||
dev->angles[1] = ANGLE2SHORT(ang[1]),
|
||||
dev->angles[2] = ANGLE2SHORT(ang[2]);
|
||||
}
|
||||
else
|
||||
VectorClear(dev->angles);
|
||||
if (vel)
|
||||
VectorCopy(vel, dev->velocity);
|
||||
else
|
||||
VectorClear(dev->velocity);
|
||||
if (avel)
|
||||
dev->avelocity[0] = ANGLE2SHORT(avel[0]),
|
||||
dev->avelocity[1] = ANGLE2SHORT(avel[1]),
|
||||
dev->avelocity[2] = ANGLE2SHORT(avel[2]);
|
||||
else
|
||||
VectorClear(dev->avelocity);
|
||||
|
||||
dev->status =
|
||||
(org ?VRSTATUS_ORG:0)|
|
||||
(ang ?VRSTATUS_ANG:0)|
|
||||
(vel ?VRSTATUS_VEL:0)|
|
||||
(avel?VRSTATUS_AVEL:0);
|
||||
|
||||
if (org)
|
||||
VectorCopy(org, cl_pendingcmd[seat].vr[dtype].origin);
|
||||
if (ang)
|
||||
cl_pendingcmd[seat].vr[dtype].angles[0] = ANGLE2SHORT(ang[0]),
|
||||
cl_pendingcmd[seat].vr[dtype].angles[1] = ANGLE2SHORT(ang[1]),
|
||||
cl_pendingcmd[seat].vr[dtype].angles[2] = ANGLE2SHORT(ang[2]);
|
||||
if (vel)
|
||||
VectorCopy(vel, cl_pendingcmd[seat].vr[dtype].velocity);
|
||||
if (avel)
|
||||
cl_pendingcmd[seat].vr[dtype].avelocity[0] = ANGLE2SHORT(avel[0]),
|
||||
cl_pendingcmd[seat].vr[dtype].avelocity[1] = ANGLE2SHORT(avel[1]),
|
||||
cl_pendingcmd[seat].vr[dtype].avelocity[2] = ANGLE2SHORT(avel[2]);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ cvar_t pr_csqc_formenus = CVAR("pr_csqc_formenus", "0");
|
|||
#endif
|
||||
static cvar_t dpcompat_csqcinputeventtypes = CVARD("dpcompat_csqcinputeventtypes", "999999", "Specifies the first csqc input event that the mod does not recognise. This should never have been a thing, but some mods are simply too buggy.");
|
||||
extern cvar_t dpcompat_stats;
|
||||
extern cvar_t in_vraim;
|
||||
|
||||
// standard effect cvars/sounds
|
||||
extern cvar_t r_explosionlight;
|
||||
|
@ -2244,6 +2245,12 @@ nogameaccess:
|
|||
*r = r_refdef.viewangles[parametertype-VF_ANGLES_X];
|
||||
break;
|
||||
|
||||
case VF_VRBASEORIENTATION:
|
||||
if (csqc_nogameaccess && prinst == csqc_world.progs)
|
||||
goto nogameaccess;
|
||||
VectorCopy(r_refdef.base_angles, r);
|
||||
break;
|
||||
|
||||
case VF_CL_VIEWANGLES_V:
|
||||
if (csqc_nogameaccess && prinst == csqc_world.progs)
|
||||
goto nogameaccess;
|
||||
|
@ -2510,6 +2517,13 @@ void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
r_refdef.viewangles[parametertype-VF_ANGLES_X] = *p;
|
||||
break;
|
||||
|
||||
case VF_VRBASEORIENTATION:
|
||||
in_vraim.ival = 0; //csqc mod with explicit vr stuff.
|
||||
r_refdef.base_known = true;
|
||||
VectorCopy(p, r_refdef.base_angles);
|
||||
VectorCopy(G_VECTOR(OFS_PARM2), r_refdef.base_origin);
|
||||
break;
|
||||
|
||||
case VF_CL_VIEWANGLES_V:
|
||||
if (csqc_playerview)
|
||||
VectorCopy(p, csqc_playerview->viewangles);
|
||||
|
@ -3823,7 +3837,7 @@ static void cs_set_input_state (usercmd_t *cmd)
|
|||
if (csqcg.input_servertime)
|
||||
*csqcg.input_servertime = cmd->fservertime;
|
||||
if (csqcg.input_clienttime)
|
||||
*csqcg.input_clienttime = cmd->fclienttime/1000.0f;
|
||||
*csqcg.input_clienttime = cmd->fclienttime;
|
||||
|
||||
if (csqcg.input_cursor_screen)
|
||||
{
|
||||
|
@ -3922,7 +3936,10 @@ static void cs_get_input_state (usercmd_t *cmd)
|
|||
if (csqcg.input_weapon)
|
||||
cmd->weapon = *csqcg.input_weapon;
|
||||
if (csqcg.input_servertime)
|
||||
{
|
||||
cmd->fservertime = *csqcg.input_servertime;
|
||||
cmd->servertime = *csqcg.input_servertime*1000;
|
||||
}
|
||||
|
||||
if (csqcg.input_cursor_screen)
|
||||
Vector2Copy(csqcg.input_cursor_screen, cmd->cursor_screen);
|
||||
|
@ -4064,6 +4081,11 @@ static void QCBUILTIN PF_cs_getinputstate (pubprogfuncs_t *prinst, struct global
|
|||
if (!cmd->msec)
|
||||
*cmd = cl.outframes[(f-1)&UPDATE_MASK].cmd[seat];
|
||||
cmd->msec = (realtime - cl.outframes[(f-1)&UPDATE_MASK].senttime)*1000;
|
||||
|
||||
//make sure we have the latest info...
|
||||
cmd->vr[VRDEV_LEFT] = csqc_playerview->vrdev[VRDEV_LEFT];
|
||||
cmd->vr[VRDEV_RIGHT] = csqc_playerview->vrdev[VRDEV_RIGHT];
|
||||
cmd->vr[VRDEV_HEAD] = csqc_playerview->vrdev[VRDEV_HEAD];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7752,6 +7774,8 @@ void CSQC_Shutdown(void)
|
|||
memset(&csqc_world, 0, sizeof(csqc_world));
|
||||
memset(&csqcg, 0, sizeof(csqcg));
|
||||
|
||||
in_vraim.ival = in_vraim.value; //csqc mod with explicit vr stuff.
|
||||
|
||||
if (csqc_deprecated_warned>1)
|
||||
{
|
||||
if (!cl_csqc_nodeprecate.ival)
|
||||
|
|
|
@ -260,10 +260,12 @@ typedef struct
|
|||
vec3_t vieworg; /*logical view center*/
|
||||
vec3_t viewangles;
|
||||
vec3_t viewaxis[3]; /*forward, left, up (NOT RIGHT)*/
|
||||
vec3_t headaxis[3]; /*this is for head mounted displays. this is relative to the view*/
|
||||
vec3_t eyeoffset; /*world space, for vr screenies*/
|
||||
vec2_t projectionoffset; /*for off-centre rendering*/
|
||||
|
||||
qboolean base_known; /*otherwise we do some fallback behaviour (ie: viewangles.0y0 and forcing input_angles)*/
|
||||
vec3_t base_angles, base_origin; /*for vr output, overrides per-eye viewangles according to that eye's matrix.*/
|
||||
|
||||
float fov_x, fov_y, afov;
|
||||
float fovv_x, fovv_y; //viewmodel fovs
|
||||
float mindist, maxdist; //maxdist may be 0, for 'infinite', in which case mindist probably isn't valid either.
|
||||
|
|
|
@ -326,7 +326,11 @@ void V_DriftPitch (playerview_t *pv)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef QUAKESTATS
|
||||
delta = pv->statsf[STAT_IDEALPITCH] - pv->viewangles[PITCH];
|
||||
#else
|
||||
delta = 0 - pv->viewangles[PITCH];
|
||||
#endif
|
||||
|
||||
if (!delta)
|
||||
{
|
||||
|
|
|
@ -74,7 +74,7 @@ typedef struct plugvrfuncs_s
|
|||
qboolean (*Prepare) (vrsetup_t *setupinfo); //called before graphics context init
|
||||
qboolean (*Init) (vrsetup_t *setupinfo, rendererstate_t *info); //called after graphics context init
|
||||
qboolean (*SyncFrame)(double *frametime); //called in the client's main loop, to block/tweak frame times. True means the game should render as fast as possible.
|
||||
qboolean (*Render) (void(*rendereye)(texid_t tex, vec4_t fovoverride, matrix3x4 axisorg));
|
||||
qboolean (*Render) (void(*rendereye)(texid_t tex, vec4_t fovoverride, vec3_t angorg[2]));
|
||||
void (*Shutdown) (void);
|
||||
#define plugvrfuncs_name "VR"
|
||||
} plugvrfuncs_t;
|
||||
|
|
|
@ -245,10 +245,10 @@ typedef struct
|
|||
int position;
|
||||
int size;
|
||||
} texwadlump_t;
|
||||
int numwadtextures;
|
||||
static int numwadtextures;
|
||||
static texwadlump_t texwadlump[TEXWAD_MAXIMAGES];
|
||||
|
||||
wadfile_t *openwadfiles;
|
||||
static wadfile_t *openwadfiles;
|
||||
|
||||
void Wads_Flush (void)
|
||||
{
|
||||
|
|
|
@ -772,6 +772,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define fte_alignof(type) sizeof(qintptr_t)
|
||||
#endif
|
||||
|
||||
//WARNING: FTE_CONSTRUCTOR things are unordered.
|
||||
#ifdef __cplusplus
|
||||
//use standard constructors in any c++ code...
|
||||
#define FTE_CONSTRUCTOR(fn) \
|
||||
static void fn(void); \
|
||||
class atinit_##fn {atinit_##fn(void){fn();}}; \
|
||||
static void fn(void)
|
||||
#elif _MSC_VER
|
||||
#pragma section(".CRT$XCU",read)
|
||||
#if _MSC_VER >= 1500 //use '/include' so it doesn't get stripped from linker optimisations
|
||||
#define INITIALIZER2_(f,p) \
|
||||
static void f(void); \
|
||||
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
|
||||
__pragma(comment(linker,"/include:" p #f "_")) \
|
||||
static void f(void)
|
||||
#else // '/include' doesn't exist, hope there's no linker optimisations.
|
||||
#define INITIALIZER2_(f,p) \
|
||||
static void f(void); \
|
||||
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
|
||||
static void f(void)
|
||||
#endif
|
||||
#ifdef _WIN64
|
||||
#define INITIALIZER(f) INITIALIZER2_(f,"")
|
||||
#else
|
||||
#define INITIALIZER(f) INITIALIZER2_(f,"_")
|
||||
#endif
|
||||
#else
|
||||
//assume gcc/clang...
|
||||
#define FTE_CONSTRUCTOR(fn) \
|
||||
__attribute__((constructor)) static void fn(void)
|
||||
#endif
|
||||
|
||||
|
||||
//safeswitch(foo){safedefault: break;}
|
||||
//switch, but errors for any omitted enum values despite the presence of a default case.
|
||||
//(gcc will generally give warnings without the default, but sometimes you don't have control over the source of your enumeration values)
|
||||
|
|
|
@ -500,7 +500,7 @@ typedef struct
|
|||
|
||||
#define FTECONTENTS_EMPTY 0x00000000
|
||||
#define FTECONTENTS_SOLID 0x00000001
|
||||
//q2window 0x00000002
|
||||
#define FTECONTENTS_WINDOW 0x00000002 //solid to bullets, but not sight/agro
|
||||
//q2aux 0x00000004
|
||||
#define FTECONTENTS_LAVA 0x00000008
|
||||
#define FTECONTENTS_SLIME 0x00000010
|
||||
|
@ -656,8 +656,8 @@ typedef struct
|
|||
|
||||
// content masks. Allow q2contents_window in here
|
||||
//#define MASK_ALL (-1)
|
||||
#define MASK_WORLDSOLID (FTECONTENTS_SOLID|Q2CONTENTS_WINDOW) /*default trace type for something simple that ignores non-bsp stuff*/
|
||||
#define MASK_POINTSOLID (FTECONTENTS_SOLID|Q2CONTENTS_WINDOW|FTECONTENTS_BODY) /*default trace type for an entity of no size*/
|
||||
#define MASK_WORLDSOLID (FTECONTENTS_SOLID|FTECONTENTS_WINDOW) /*default trace type for something simple that ignores non-bsp stuff*/
|
||||
#define MASK_POINTSOLID (FTECONTENTS_SOLID|FTECONTENTS_WINDOW|FTECONTENTS_BODY) /*default trace type for an entity of no size*/
|
||||
#define MASK_BOXSOLID (FTECONTENTS_SOLID|FTECONTENTS_PLAYERCLIP|Q2CONTENTS_WINDOW|FTECONTENTS_BODY) /*default trace type for an entity that does have size*/
|
||||
#define MASK_PLAYERSOLID MASK_BOXSOLID
|
||||
//#define MASK_DEADSOLID (Q2CONTENTS_SOLID|Q2CONTENTS_PLAYERCLIP|Q2CONTENTS_WINDOW)
|
||||
|
|
|
@ -787,12 +787,12 @@ typedef enum
|
|||
VF_SKYROOM_CAMERA = 222,
|
||||
VF_PIXELPSCALE = 223, //[dpi_x, dpi_y, dpi_y/dpi_x]
|
||||
VF_PROJECTIONOFFSET = 224, //allows for off-axis projections.
|
||||
VF_VRBASEORIENTATION= 225, //specifies the worldspace coords+angles of the VR room space.
|
||||
//WARNING: update fteqcc when new entries are added.
|
||||
|
||||
|
||||
VF_DP_CLEARSCREEN = 201, //misnomer - NOTOVERLAY would be a better name. when set to false prevents any and all post-proc things that might write colour values in areas with no geometry there.
|
||||
//fuck DP and their complete lack of respect for existing implemenetations
|
||||
VF_DP_FOG_DENSITY = 202, //misassigned
|
||||
VF_DP_FOG_DENSITY = 202, //misassigned - fuck DP and their complete lack of respect for existing implemenetations
|
||||
VF_DP_FOG_COLOR = 203, //misassigned
|
||||
VF_DP_FOG_COLOR_R = 204, //misassigned
|
||||
VF_DP_FOG_COLOR_G = 205, //misassigned
|
||||
|
@ -802,7 +802,7 @@ typedef enum
|
|||
VF_DP_FOG_END = 209, //misassigned
|
||||
VF_DP_FOG_HEIGHT = 210, //misassigned
|
||||
VF_DP_FOG_FADEDEPTH = 211, //misassigned
|
||||
VF_DP_MAINVIEW = 400, // defective. should be a viewid instead, allowing for per-view motionblur instead of disabling it outright
|
||||
VF_DP_MAINVIEW = 400, // defective. should have been a 1-based viewid instead, allowing for per-view motionblur instead of disabling it outright
|
||||
VF_DP_MINFPS_QUALITY = 401, //multiplier for lod and culling to try to reduce costs.
|
||||
} viewflags;
|
||||
|
||||
|
|
|
@ -1189,6 +1189,22 @@ typedef struct
|
|||
size_t bonedatamax;
|
||||
} packet_entities_t;
|
||||
|
||||
struct vrdevinfo_s
|
||||
{
|
||||
unsigned int status;
|
||||
#define VRSTATUS_ORG (1u<<0)
|
||||
#define VRSTATUS_ANG (1u<<1)
|
||||
#define VRSTATUS_VEL (1u<<2)
|
||||
#define VRSTATUS_AVEL (1u<<3)
|
||||
short angles[3];
|
||||
short avelocity[3];
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
#define VRDEV_LEFT 0
|
||||
#define VRDEV_RIGHT 1
|
||||
#define VRDEV_HEAD 2
|
||||
#define VRDEV_COUNT 3
|
||||
};
|
||||
typedef struct usercmd_s
|
||||
{
|
||||
//the first members of this structure MUST match the q2 version
|
||||
|
@ -1214,21 +1230,7 @@ typedef struct usercmd_s
|
|||
unsigned int cursor_entitynumber;
|
||||
|
||||
//vr things
|
||||
struct
|
||||
{
|
||||
unsigned int status;
|
||||
#define VRSTATUS_ORG (1u<<0)
|
||||
#define VRSTATUS_ANG (1u<<1)
|
||||
#define VRSTATUS_VEL (1u<<2)
|
||||
#define VRSTATUS_AVEL (1u<<3)
|
||||
short angles[3];
|
||||
short avelocity[3];
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
#define VRDEV_LEFT 0
|
||||
#define VRDEV_RIGHT 1
|
||||
#define VRDEV_HEAD 2
|
||||
} vr[3]; //left, right, head.
|
||||
struct vrdevinfo_s vr[VRDEV_COUNT]; //left, right, head.
|
||||
} usercmd_t;
|
||||
|
||||
typedef struct q2usercmd_s
|
||||
|
|
|
@ -88,6 +88,7 @@ Zone block
|
|||
#else
|
||||
#define VALGRIND_MAKE_MEM_UNDEFINED(ptr,sz) //as an alternative to memzero..
|
||||
#define VALGRIND_MAKE_MEM_NOACCESS(ptr,sz)
|
||||
#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(ptr,sz) //undo VALGRIND_MAKE_MEM_UNDEFINED, to make sure we don't read past the end of buffers.
|
||||
#endif
|
||||
|
||||
void Memory_Init (void);
|
||||
|
|
|
@ -435,7 +435,7 @@ void R_RotateForEntity (float *m, float *modelview, const entity_t *e, const mod
|
|||
R_SetupGL
|
||||
=============
|
||||
*/
|
||||
static void R_SetupGL (matrix3x4 eyematrix, vec4_t fovoverrides, float projmatrix[16]/*for webvr*/, texid_t fbo)
|
||||
static void R_SetupGL (vec3_t eyeangorg[2], vec4_t fovoverrides, float projmatrix[16]/*for webvr*/, texid_t fbo)
|
||||
{
|
||||
int x, x2, y2, y, w, h;
|
||||
vec3_t newa;
|
||||
|
@ -450,14 +450,32 @@ static void R_SetupGL (matrix3x4 eyematrix, vec4_t fovoverrides, float projmatri
|
|||
newa[0] = r_refdef.viewangles[0];
|
||||
newa[1] = r_refdef.viewangles[1];
|
||||
newa[2] = r_refdef.viewangles[2] + gl_screenangle.value;
|
||||
if (eyematrix)
|
||||
if (eyeangorg)
|
||||
{
|
||||
matrix3x4 headmatrix;
|
||||
extern cvar_t in_vraim;
|
||||
matrix3x4 basematrix;
|
||||
matrix3x4 eyematrix;
|
||||
matrix3x4 viewmatrix;
|
||||
Matrix3x4_RM_FromAngles(newa, r_refdef.vieworg, headmatrix[0]);
|
||||
Matrix3x4_Multiply(headmatrix[0], eyematrix[0], viewmatrix[0]);
|
||||
Matrix3x4_RM_ToVectors(viewmatrix[0], vpn, vright, vup, r_origin);
|
||||
VectorNegate(vright, vright);
|
||||
|
||||
Matrix3x4_RM_FromAngles(eyeangorg[0], eyeangorg[1], eyematrix[0]);
|
||||
if (r_refdef.base_known)
|
||||
{ //mod is specifying its own base ang+org.
|
||||
Matrix3x4_RM_FromAngles(r_refdef.base_angles, r_refdef.base_origin, basematrix[0]);
|
||||
Matrix3x4_Multiply(eyematrix[0], basematrix[0], viewmatrix[0]);
|
||||
Matrix3x4_RM_ToVectors(viewmatrix[0], vpn, vright, vup, r_origin);
|
||||
VectorNegate(vright, vright);
|
||||
}
|
||||
else
|
||||
{ //mod provides no info.
|
||||
//client will fiddle with input_angles
|
||||
newa[0] = newa[2] = 0; //ignore player pitch+roll. sorry. apply the eye's transform on top.
|
||||
if (in_vraim.ival)
|
||||
newa[1] -= SHORT2ANGLE(r_refdef.playerview->vrdev[VRDEV_HEAD].angles[YAW]);
|
||||
Matrix3x4_RM_FromAngles(newa, r_refdef.vieworg, basematrix[0]);
|
||||
Matrix3x4_Multiply(eyematrix[0], basematrix[0], viewmatrix[0]);
|
||||
Matrix3x4_RM_ToVectors(viewmatrix[0], vpn, vright, vup, r_origin);
|
||||
VectorNegate(vright, vright);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -717,7 +735,7 @@ static void R_RenderScene_Internal(void)
|
|||
|
||||
depthcleared = false; //whatever is in the depth buffer is no longer useful.
|
||||
}
|
||||
static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, matrix3x4 eyematrix)
|
||||
static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, vec3_t eyeangorg[2])
|
||||
{
|
||||
extern qboolean depthcleared;
|
||||
refdef_t refdef = r_refdef;
|
||||
|
@ -725,6 +743,11 @@ static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, matrix3x
|
|||
int ph = vid.fbpheight;
|
||||
int r = 0;
|
||||
|
||||
extern void CL_ClampPitch (int pnum, float frametime);
|
||||
/*the vr code tends to be somewhat laggy with its head angles, leaving it to the last minute, so redo this to reduce latency*/
|
||||
if ((size_t)(refdef.playerview-cl.playerview) < MAX_SPLITS)
|
||||
CL_ClampPitch (refdef.playerview-cl.playerview, 0);
|
||||
|
||||
if (rendertarget)
|
||||
{
|
||||
r = GLBE_FBO_Update(&fbo_vr, FBO_RB_DEPTH, &rendertarget, 1, r_nulltex, rendertarget->width, rendertarget->height, 0);
|
||||
|
@ -735,10 +758,10 @@ static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, matrix3x
|
|||
vid.fbpheight = rendertarget->height;
|
||||
}
|
||||
|
||||
R_SetupGL (eyematrix, fovoverride, NULL, rendertarget);
|
||||
R_SetupGL (eyeangorg, fovoverride, NULL, rendertarget);
|
||||
R_RenderScene_Internal();
|
||||
|
||||
//if (eyematrix)
|
||||
/*//if (eyematrix)
|
||||
{
|
||||
vec3_t newa, newo;
|
||||
matrix3x4 headmatrix; //position of the head in local space
|
||||
|
@ -774,7 +797,7 @@ static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, matrix3x
|
|||
if (R2D_Flush)
|
||||
R2D_Flush();
|
||||
GL_SetShaderState2D(false);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (rendertarget)
|
||||
{
|
||||
|
@ -795,8 +818,7 @@ static void R_RenderScene (void)
|
|||
int i;
|
||||
int cull = r_refdef.flipcull;
|
||||
unsigned int colourmask = r_refdef.colourmask;
|
||||
vec3_t ang, org;
|
||||
matrix3x4 eyematrix;
|
||||
vec3_t eyeangorg[2];
|
||||
extern qboolean depthcleared;
|
||||
|
||||
r_refdef.colourmask = 0u;
|
||||
|
@ -914,12 +936,11 @@ static void R_RenderScene (void)
|
|||
}
|
||||
r_framecount++; //view position changes, if only slightly. which means we need to rebuild vis info. :(
|
||||
|
||||
ang[0] = 0;
|
||||
ang[1] = r_stereo_convergence.value * (i?0.5:-0.5);
|
||||
ang[2] = 0;
|
||||
VectorSet(org, 0, stereooffset[i], 0);
|
||||
Matrix3x4_RM_FromAngles(ang, org, eyematrix[0]);
|
||||
R_SetupGL (eyematrix, NULL, NULL, NULL);
|
||||
eyeangorg[0][0] = 0;
|
||||
eyeangorg[0][1] = r_stereo_convergence.value * (i?0.5:-0.5);
|
||||
eyeangorg[0][2] = 0;
|
||||
VectorSet(eyeangorg[1], 0, stereooffset[i], 0);
|
||||
R_SetupGL (eyeangorg, NULL, NULL, NULL);
|
||||
R_RenderScene_Internal ();
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ cvar_t r_shadow_realtime_world = CVARFD ("r_shadow_realtime_world", "0", CVAR
|
|||
cvar_t r_shadow_realtime_world_shadows = CVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_shadow_realtime_world_lightmaps = CVARFD ("r_shadow_realtime_world_lightmaps", "0", 0, "Specifies how much of the map's normal lightmap to retain when using world realtime lights. 0 completely replaces lighting.");
|
||||
cvar_t r_shadow_realtime_world_importlightentitiesfrommap = CVARFD ("r_shadow_realtime_world_importlightentitiesfrommap", "0", CVAR_ARCHIVE, "Controls default loading of map-based realtime lights.\n0: Load explicit .rtlight files only.\n1: Load explicit lights then try fallback to parsing the entities lump.\n2: Load only the entities lump.");
|
||||
cvar_t r_shadow_realtime_dlight = CVARFD ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE, "Enables the use of dynamic realtime lights, allowing explosions to use bumpmaps etc properly.");
|
||||
cvar_t r_shadow_realtime_dlight = CVARAFD ("r_shadow_realtime_dlight", "1", "r_shadow_realtime_dynamic", CVAR_ARCHIVE, "Enables the use of dynamic realtime lights, allowing explosions to use bumpmaps etc properly.");
|
||||
cvar_t r_shadow_realtime_dlight_shadows = CVARFD ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE, "Allows dynamic realtime lights to cast shadows as they move.");
|
||||
cvar_t r_shadow_realtime_dlight_ambient = CVAR ("r_shadow_realtime_dlight_ambient", "0");
|
||||
cvar_t r_shadow_realtime_dlight_diffuse = CVAR ("r_shadow_realtime_dlight_diffuse", "1");
|
||||
|
|
|
@ -1594,7 +1594,10 @@ void DL_DeThread(void)
|
|||
{
|
||||
dl->threadenable = false;
|
||||
if (dl->threadctx)
|
||||
{
|
||||
Sys_WaitOnThread(dl->threadctx);
|
||||
dl->threadctx = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -6147,7 +6147,7 @@ static void QCC_VerifyArgs_setviewprop (const char *funcname, QCC_ref_t **arglis
|
|||
{"VF_CL_VIEWANGLES_X", 35, ev_float},
|
||||
{"VF_CL_VIEWANGLES_X", 36, ev_float},
|
||||
{"VF_PERSPECTIVE", 200, ev_float},
|
||||
//201
|
||||
// {"VF_DP_CLEARSCENE", 201, ev_float},
|
||||
{"VF_ACTIVESEAT", 202, ev_float, ev_float},
|
||||
{"VF_AFOV", 203, ev_float},
|
||||
// {"VF_SCREENVSIZE", 204, ev_vector},
|
||||
|
@ -6171,6 +6171,10 @@ static void QCC_VerifyArgs_setviewprop (const char *funcname, QCC_ref_t **arglis
|
|||
{"VF_SKYROOM_CAMERA", 222, ev_vector},
|
||||
// {"VF_PIXELPSCALE", 223, ev_vector},
|
||||
{"VF_PROJECTIONOFFSET", 224, ev_vector},
|
||||
{"VF_VRBASEORIENTATION",225, ev_vector, ev_vector},
|
||||
|
||||
{"VF_DP_MAINVIEW", 400, ev_float},
|
||||
// {"VF_DP_MINFPS_QUALITY", 401, ev_float},
|
||||
};
|
||||
|
||||
char temp[256];
|
||||
|
|
|
@ -5069,8 +5069,6 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
|
|||
if (QCC_PR_CheckToken("="))
|
||||
{
|
||||
paramlist[numparms].defltvalue = QCC_PR_ParseDefaultInitialiser(paramlist[numparms].type);
|
||||
if (!paramlist[numparms].defltvalue.sym->constant)
|
||||
QCC_PR_ParseError(0, "Default initialiser is not constant\n");
|
||||
QCC_FreeTemp(paramlist[numparms].defltvalue);
|
||||
}
|
||||
numparms++;
|
||||
|
|
|
@ -10291,9 +10291,109 @@ void SV_SetEntityButtons(edict_t *ent, unsigned int buttonbits)
|
|||
}
|
||||
}
|
||||
|
||||
static void SV_SetSSQCInputs(usercmd_t *ucmd)
|
||||
{
|
||||
pr_global_struct->input_timelength = ucmd->msec/1000.0f * sv.gamespeed;
|
||||
pr_global_struct->input_impulse = ucmd->impulse;
|
||||
//precision inaccuracies. :(
|
||||
#define ANGLE2SHORT(x) (x) * (65536/360.0)
|
||||
if (sv_player->v->fixangle)
|
||||
{
|
||||
(pr_global_struct->input_angles)[0] = sv_player->v->v_angle[0];
|
||||
(pr_global_struct->input_angles)[1] = sv_player->v->v_angle[1];
|
||||
(pr_global_struct->input_angles)[2] = sv_player->v->v_angle[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
(pr_global_struct->input_angles)[0] = SHORT2ANGLE(ucmd->angles[0]);
|
||||
(pr_global_struct->input_angles)[1] = SHORT2ANGLE(ucmd->angles[1]);
|
||||
(pr_global_struct->input_angles)[2] = SHORT2ANGLE(ucmd->angles[2]);
|
||||
}
|
||||
|
||||
(pr_global_struct->input_movevalues)[0] = ucmd->forwardmove;
|
||||
(pr_global_struct->input_movevalues)[1] = ucmd->sidemove;
|
||||
(pr_global_struct->input_movevalues)[2] = ucmd->upmove;
|
||||
pr_global_struct->input_buttons = ucmd->buttons;
|
||||
if (pr_global_ptrs->input_weapon)
|
||||
pr_global_struct->input_weapon = ucmd->weapon;
|
||||
if (pr_global_ptrs->input_lightlevel)
|
||||
pr_global_struct->input_lightlevel = ucmd->lightlevel;
|
||||
|
||||
if (pr_global_ptrs->input_cursor_screen)
|
||||
VectorSet(pr_global_struct->input_cursor_screen, ucmd->cursor_screen[0], ucmd->cursor_screen[1], 0);
|
||||
if (pr_global_ptrs->input_cursor_trace_start)
|
||||
VectorCopy(ucmd->cursor_start, pr_global_struct->input_cursor_trace_start);
|
||||
if (pr_global_ptrs->input_cursor_trace_endpos)
|
||||
VectorCopy(ucmd->cursor_impact, pr_global_struct->input_cursor_trace_endpos);
|
||||
if (pr_global_ptrs->input_cursor_entitynumber)
|
||||
pr_global_struct->input_cursor_entitynumber = ucmd->cursor_entitynumber;
|
||||
|
||||
if (pr_global_ptrs->input_head_status)
|
||||
pr_global_struct->input_head_status = ucmd->vr[VRDEV_HEAD].status;
|
||||
if (pr_global_ptrs->input_head_origin)
|
||||
VectorCopy(ucmd->vr[VRDEV_HEAD].origin, pr_global_struct->input_head_origin);
|
||||
if (pr_global_ptrs->input_head_velocity)
|
||||
VectorCopy(ucmd->vr[VRDEV_HEAD].velocity, pr_global_struct->input_head_velocity);
|
||||
if (pr_global_ptrs->input_head_angles)
|
||||
{
|
||||
(pr_global_struct->input_head_angles)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].angles[0]);
|
||||
(pr_global_struct->input_head_angles)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].angles[1]);
|
||||
(pr_global_struct->input_head_angles)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].angles[2]);
|
||||
}
|
||||
if (pr_global_ptrs->input_head_avelocity)
|
||||
{
|
||||
(pr_global_struct->input_head_avelocity)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].avelocity[0]);
|
||||
(pr_global_struct->input_head_avelocity)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].avelocity[1]);
|
||||
(pr_global_struct->input_head_avelocity)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].avelocity[2]);
|
||||
}
|
||||
|
||||
if (pr_global_ptrs->input_left_status)
|
||||
pr_global_struct->input_left_status = ucmd->vr[VRDEV_LEFT].status;
|
||||
if (pr_global_ptrs->input_left_origin)
|
||||
VectorCopy(ucmd->vr[VRDEV_LEFT].origin, pr_global_struct->input_left_origin);
|
||||
if (pr_global_ptrs->input_left_velocity)
|
||||
VectorCopy(ucmd->vr[VRDEV_LEFT].velocity, pr_global_struct->input_left_velocity);
|
||||
if (pr_global_ptrs->input_left_angles)
|
||||
{
|
||||
(pr_global_struct->input_left_angles)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].angles[0]);
|
||||
(pr_global_struct->input_left_angles)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].angles[1]);
|
||||
(pr_global_struct->input_left_angles)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].angles[2]);
|
||||
}
|
||||
if (pr_global_ptrs->input_left_avelocity)
|
||||
{
|
||||
(pr_global_struct->input_left_avelocity)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].avelocity[0]);
|
||||
(pr_global_struct->input_left_avelocity)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].avelocity[1]);
|
||||
(pr_global_struct->input_left_avelocity)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].avelocity[2]);
|
||||
}
|
||||
|
||||
if (pr_global_ptrs->input_right_status)
|
||||
pr_global_struct->input_right_status = ucmd->vr[VRDEV_RIGHT].status;
|
||||
if (pr_global_ptrs->input_right_origin)
|
||||
VectorCopy(ucmd->vr[VRDEV_RIGHT].origin, pr_global_struct->input_right_origin);
|
||||
if (pr_global_ptrs->input_right_velocity)
|
||||
VectorCopy(ucmd->vr[VRDEV_RIGHT].velocity, pr_global_struct->input_right_velocity);
|
||||
if (pr_global_ptrs->input_right_angles)
|
||||
{
|
||||
(pr_global_struct->input_right_angles)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].angles[0]);
|
||||
(pr_global_struct->input_right_angles)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].angles[1]);
|
||||
(pr_global_struct->input_right_angles)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].angles[2]);
|
||||
}
|
||||
if (pr_global_ptrs->input_right_avelocity)
|
||||
{
|
||||
(pr_global_struct->input_right_avelocity)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].avelocity[0]);
|
||||
(pr_global_struct->input_right_avelocity)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].avelocity[1]);
|
||||
(pr_global_struct->input_right_avelocity)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].avelocity[2]);
|
||||
}
|
||||
}
|
||||
|
||||
//EXT_CSQC_1 (called when a movement command is received. runs full acceleration + movement)
|
||||
qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
|
||||
{
|
||||
if (ucmd->vr[VRDEV_HEAD].status & VRSTATUS_ANG)
|
||||
sv_player->xv->idealpitch = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].angles[0]);
|
||||
else
|
||||
sv_player->xv->idealpitch = 0;
|
||||
SV_SetSSQCInputs(ucmd); //make sure its available for PlayerPreThink.
|
||||
if (gfuncs.RunClientCommand)
|
||||
{
|
||||
vec3_t startangle;
|
||||
|
@ -10352,107 +10452,6 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
|
|||
V_CalcRoll (sv_player->v->angles, sv_player->v->velocity)*4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pr_global_struct->input_timelength = ucmd->msec/1000.0f * sv.gamespeed;
|
||||
pr_global_struct->input_impulse = ucmd->impulse;
|
||||
//precision inaccuracies. :(
|
||||
#define ANGLE2SHORT(x) (x) * (65536/360.0)
|
||||
if (sv_player->v->fixangle)
|
||||
{
|
||||
(pr_global_struct->input_angles)[0] = sv_player->v->v_angle[0];
|
||||
(pr_global_struct->input_angles)[1] = sv_player->v->v_angle[1];
|
||||
(pr_global_struct->input_angles)[2] = sv_player->v->v_angle[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
(pr_global_struct->input_angles)[0] = SHORT2ANGLE(ucmd->angles[0]);
|
||||
(pr_global_struct->input_angles)[1] = SHORT2ANGLE(ucmd->angles[1]);
|
||||
(pr_global_struct->input_angles)[2] = SHORT2ANGLE(ucmd->angles[2]);
|
||||
}
|
||||
|
||||
(pr_global_struct->input_movevalues)[0] = ucmd->forwardmove;
|
||||
(pr_global_struct->input_movevalues)[1] = ucmd->sidemove;
|
||||
(pr_global_struct->input_movevalues)[2] = ucmd->upmove;
|
||||
pr_global_struct->input_buttons = ucmd->buttons;
|
||||
if (pr_global_ptrs->input_weapon)
|
||||
pr_global_struct->input_weapon = ucmd->weapon;
|
||||
if (pr_global_ptrs->input_lightlevel)
|
||||
pr_global_struct->input_lightlevel = ucmd->lightlevel;
|
||||
|
||||
if (pr_global_ptrs->input_cursor_screen)
|
||||
VectorSet(pr_global_struct->input_cursor_screen, ucmd->cursor_screen[0], ucmd->cursor_screen[1], 0);
|
||||
if (pr_global_ptrs->input_cursor_trace_start)
|
||||
VectorCopy(ucmd->cursor_start, pr_global_struct->input_cursor_trace_start);
|
||||
if (pr_global_ptrs->input_cursor_trace_endpos)
|
||||
VectorCopy(ucmd->cursor_impact, pr_global_struct->input_cursor_trace_endpos);
|
||||
if (pr_global_ptrs->input_cursor_entitynumber)
|
||||
pr_global_struct->input_cursor_entitynumber = ucmd->cursor_entitynumber;
|
||||
|
||||
if (pr_global_ptrs->input_head_status)
|
||||
pr_global_struct->input_head_status = ucmd->vr[VRDEV_HEAD].status;
|
||||
if (pr_global_ptrs->input_head_origin)
|
||||
VectorCopy(ucmd->vr[VRDEV_HEAD].origin, pr_global_struct->input_head_origin);
|
||||
if (pr_global_ptrs->input_head_velocity)
|
||||
VectorCopy(ucmd->vr[VRDEV_HEAD].velocity, pr_global_struct->input_head_velocity);
|
||||
if (pr_global_ptrs->input_head_angles)
|
||||
{
|
||||
(pr_global_struct->input_head_angles)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].angles[0]);
|
||||
(pr_global_struct->input_head_angles)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].angles[1]);
|
||||
(pr_global_struct->input_head_angles)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].angles[2]);
|
||||
}
|
||||
if (pr_global_ptrs->input_head_avelocity)
|
||||
{
|
||||
(pr_global_struct->input_head_avelocity)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].avelocity[0]);
|
||||
(pr_global_struct->input_head_avelocity)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].avelocity[1]);
|
||||
(pr_global_struct->input_head_avelocity)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_HEAD].avelocity[2]);
|
||||
}
|
||||
|
||||
if (pr_global_ptrs->input_left_status)
|
||||
pr_global_struct->input_left_status = ucmd->vr[VRDEV_LEFT].status;
|
||||
if (pr_global_ptrs->input_left_origin)
|
||||
VectorCopy(ucmd->vr[VRDEV_LEFT].origin, pr_global_struct->input_left_origin);
|
||||
if (pr_global_ptrs->input_left_velocity)
|
||||
VectorCopy(ucmd->vr[VRDEV_LEFT].velocity, pr_global_struct->input_left_velocity);
|
||||
if (pr_global_ptrs->input_left_angles)
|
||||
{
|
||||
(pr_global_struct->input_left_angles)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].angles[0]);
|
||||
(pr_global_struct->input_left_angles)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].angles[1]);
|
||||
(pr_global_struct->input_left_angles)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].angles[2]);
|
||||
}
|
||||
if (pr_global_ptrs->input_left_avelocity)
|
||||
{
|
||||
(pr_global_struct->input_left_avelocity)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].avelocity[0]);
|
||||
(pr_global_struct->input_left_avelocity)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].avelocity[1]);
|
||||
(pr_global_struct->input_left_avelocity)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_LEFT].avelocity[2]);
|
||||
}
|
||||
|
||||
if (pr_global_ptrs->input_right_status)
|
||||
pr_global_struct->input_right_status = ucmd->vr[VRDEV_RIGHT].status;
|
||||
if (pr_global_ptrs->input_right_origin)
|
||||
VectorCopy(ucmd->vr[VRDEV_RIGHT].origin, pr_global_struct->input_right_origin);
|
||||
if (pr_global_ptrs->input_right_velocity)
|
||||
VectorCopy(ucmd->vr[VRDEV_RIGHT].velocity, pr_global_struct->input_right_velocity);
|
||||
if (pr_global_ptrs->input_right_angles)
|
||||
{
|
||||
(pr_global_struct->input_right_angles)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].angles[0]);
|
||||
(pr_global_struct->input_right_angles)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].angles[1]);
|
||||
(pr_global_struct->input_right_angles)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].angles[2]);
|
||||
}
|
||||
if (pr_global_ptrs->input_right_avelocity)
|
||||
{
|
||||
(pr_global_struct->input_right_avelocity)[0] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].avelocity[0]);
|
||||
(pr_global_struct->input_right_avelocity)[1] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].avelocity[1]);
|
||||
(pr_global_struct->input_right_avelocity)[2] = SHORT2ANGLE(ucmd->vr[VRDEV_RIGHT].avelocity[2]);
|
||||
}
|
||||
|
||||
//prethink should be consistant with what the engine normally does
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, client->edict);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
|
||||
|
|
|
@ -2271,6 +2271,7 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf
|
|||
}
|
||||
|
||||
statsf[STAT_VIEWHEIGHT] = ent->v->view_ofs[2];
|
||||
statsf[STAT_IDEALPITCH] = ent->xv->idealpitch;
|
||||
|
||||
statsf[STAT_PUNCHANGLE_X] = ent->xv->punchangle[0];
|
||||
statsf[STAT_PUNCHANGLE_Y] = ent->xv->punchangle[1];
|
||||
|
|
|
@ -8113,9 +8113,9 @@ void SV_ExecuteClientMessage (client_t *cl)
|
|||
else while (split->lastruncmd < newcmd.servertime)
|
||||
{
|
||||
//try to find the oldest (valid) command.
|
||||
if (split->lastcmd.servertime < oldest.servertime)
|
||||
if (split->lastruncmd < oldest.servertime)
|
||||
c = &oldest;
|
||||
else if (split->lastcmd.servertime < oldcmd.servertime)
|
||||
else if (split->lastruncmd < oldcmd.servertime)
|
||||
c = &oldcmd;
|
||||
else
|
||||
c = &newcmd;
|
||||
|
|
|
@ -2656,7 +2656,7 @@ static qboolean VK_R_RenderScene_Cubemap(struct vk_rendertarg *fb)
|
|||
return true;
|
||||
}
|
||||
|
||||
void VK_R_RenderEye(texid_t image, vec4_t fovoverride, matrix3x4 axisorg)
|
||||
void VK_R_RenderEye(texid_t image, vec4_t fovoverride, vec3_t eyeangorg[2])
|
||||
{
|
||||
struct vk_rendertarg *rt;
|
||||
|
||||
|
|
176
plugins/openxr.c
176
plugins/openxr.c
|
@ -126,36 +126,6 @@ static cvar_t *xr_skipregularview;
|
|||
#define METRES_TO_QUAKE(x) ((x)*xr_metresize->value)
|
||||
#define QUAKE_TO_METRES(x) ((x)/xr_metresize->value)
|
||||
|
||||
static void Matrix3x4_FromAngles (const vec3_t angles, const vec3_t org, float *fte_restrict transform)
|
||||
{
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
angle = angles[YAW] * (M_PI*2 / 360);
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
transform[0+0] = cp*cy;
|
||||
transform[0+1] = cp*sy;
|
||||
transform[0+2] = -sp;
|
||||
transform[0+3] = org[0];
|
||||
|
||||
transform[4+0] = (-1*sr*sp*cy+-1*cr*-sy);
|
||||
transform[4+1] = (-1*sr*sp*sy+-1*cr*cy);
|
||||
transform[4+2] = -1*sr*cp;
|
||||
transform[4+3] = org[1];
|
||||
|
||||
transform[8+0] = (cr*sp*cy+-sr*-sy);
|
||||
transform[8+1] = (cr*sp*sy+-sr*cy);
|
||||
transform[8+2] = cr*cp;
|
||||
transform[8+3] = org[2];
|
||||
}
|
||||
static void XR_PoseToAngOrg(const XrPosef *pose, vec3_t ang, vec3_t org)
|
||||
{
|
||||
XrQuaternionf q = pose->orientation;
|
||||
|
@ -178,62 +148,6 @@ static void XR_PoseToAngOrg(const XrPosef *pose, vec3_t ang, vec3_t org)
|
|||
org[2] = METRES_TO_QUAKE(pose->position.z);
|
||||
#endif
|
||||
}
|
||||
static void XR_PoseToTransform(const XrPosef *pose, float *fte_restrict transform)
|
||||
{
|
||||
vec3_t ang, org;
|
||||
XR_PoseToAngOrg(pose, ang, org);
|
||||
Matrix3x4_FromAngles(ang, org, transform);
|
||||
}
|
||||
static void Matrix3x4_Invert_XR (const float *in1, float *fte_restrict out)
|
||||
{
|
||||
// we only support uniform scaling, so assume the first row is enough
|
||||
// (note the lack of sqrt here, because we're trying to undo the scaling,
|
||||
// this means multiplying by the inverse scale twice - squaring it, which
|
||||
// makes the sqrt a waste of time)
|
||||
#if 1
|
||||
double scale = 1.0 / (in1[0] * in1[0] + in1[1] * in1[1] + in1[2] * in1[2]);
|
||||
#else
|
||||
double scale = 3.0 / sqrt
|
||||
(in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]
|
||||
+ in1->m[1][0] * in1->m[1][0] + in1->m[1][1] * in1->m[1][1] + in1->m[1][2] * in1->m[1][2]
|
||||
+ in1->m[2][0] * in1->m[2][0] + in1->m[2][1] * in1->m[2][1] + in1->m[2][2] * in1->m[2][2]);
|
||||
scale *= scale;
|
||||
#endif
|
||||
|
||||
// invert the rotation by transposing and multiplying by the squared
|
||||
// recipricol of the input matrix scale as described above
|
||||
out[0] = in1[0] * scale;
|
||||
out[1] = in1[4] * scale;
|
||||
out[2] = in1[8] * scale;
|
||||
out[4] = in1[1] * scale;
|
||||
out[5] = in1[5] * scale;
|
||||
out[6] = in1[9] * scale;
|
||||
out[8] = in1[2] * scale;
|
||||
out[9] = in1[6] * scale;
|
||||
out[10] = in1[10] * scale;
|
||||
|
||||
// invert the translate
|
||||
out[3] = -(in1[3] * out[0] + in1[7] * out[1] + in1[11] * out[2]);
|
||||
out[7] = -(in1[3] * out[4] + in1[7] * out[5] + in1[11] * out[6]);
|
||||
out[11] = -(in1[3] * out[8] + in1[7] * out[9] + in1[11] * out[10]);
|
||||
}
|
||||
static void Matrix3x4_Multiply_XR(const float *a, const float *b, float *fte_restrict out)
|
||||
{
|
||||
out[0] = a[0] * b[0] + a[4] * b[1] + a[8] * b[2];
|
||||
out[1] = a[1] * b[0] + a[5] * b[1] + a[9] * b[2];
|
||||
out[2] = a[2] * b[0] + a[6] * b[1] + a[10] * b[2];
|
||||
out[3] = a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + b[3];
|
||||
|
||||
out[4] = a[0] * b[4] + a[4] * b[5] + a[8] * b[6];
|
||||
out[5] = a[1] * b[4] + a[5] * b[5] + a[9] * b[6];
|
||||
out[6] = a[2] * b[4] + a[6] * b[5] + a[10] * b[6];
|
||||
out[7] = a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + b[7];
|
||||
|
||||
out[8] = a[0] * b[8] + a[4] * b[9] + a[8] * b[10];
|
||||
out[9] = a[1] * b[8] + a[5] * b[9] + a[9] * b[10];
|
||||
out[10] = a[2] * b[8] + a[6] * b[9] + a[10] * b[10];
|
||||
out[11] = a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + b[11];
|
||||
}
|
||||
|
||||
#define VectorAngles VectorAnglesPluginsSuck
|
||||
static void VectorAngles(const float *forward, const float *up, float *result, qboolean meshpitch) //up may be NULL
|
||||
|
@ -1037,32 +951,14 @@ static int QDECL XR_BindProfileFile(const char *fname, qofs_t fsize, time_t mtim
|
|||
return false;
|
||||
}
|
||||
|
||||
static void XR_SetupInputs(void)
|
||||
static const struct
|
||||
{
|
||||
unsigned int h;
|
||||
XrResult res;
|
||||
|
||||
//begin instance-level init
|
||||
{
|
||||
XrActionSetCreateInfo info = {XR_TYPE_ACTION_SET_CREATE_INFO};
|
||||
Q_strlcpy(info.actionSetName, "actions", sizeof(info.actionSetName));
|
||||
Q_strlcpy(info.localizedActionSetName, FULLENGINENAME" Actions", sizeof(info.localizedActionSetName));
|
||||
info.priority = 0;
|
||||
|
||||
xr.actionset.subactionPath = XR_NULL_PATH;
|
||||
res = xrCreateActionSet(xr.instance, &info, &xr.actionset.actionSet);
|
||||
if (XR_FAILED(res))
|
||||
Con_Printf("openxr: Unable to create actionset - %s\n", XR_StringForResult(res));
|
||||
}
|
||||
|
||||
h = 0;
|
||||
if (fsfuncs)
|
||||
fsfuncs->EnumerateFiles("oxr_*.binds", XR_BindProfileFile, &h);
|
||||
if (!h) //no user bindings defined, use fallbacks. probably this needs to be per-mod.
|
||||
{
|
||||
//FIXME: set up some proper bindings!
|
||||
XR_BindProfileStr("khr_simple",
|
||||
"/interaction_profiles/khr/simple_controller /user/hand/left/ /user/hand/right/\n"
|
||||
const char *name;
|
||||
const char *script;
|
||||
} xr_knownprofiles[] =
|
||||
{
|
||||
//FIXME: set up some proper bindings!
|
||||
{"khr_simple", "/interaction_profiles/khr/simple_controller /user/hand/left/ /user/hand/right/\n"
|
||||
"+attack_left \"Left Attack\" button input/select/click /user/hand/left\n"
|
||||
"+attack_right \"Right Attack\" button input/select/click /user/hand/right\n"
|
||||
"+menu_left \"Left Menu\" button input/menu/click /user/hand/left\n"
|
||||
|
@ -1072,10 +968,9 @@ static void XR_SetupInputs(void)
|
|||
// "grip_pose \"Grip Pose\" pose input/grip/pose\n"
|
||||
// "aim_pose \"Aim Pose\" pose input/aim/pose\n"
|
||||
"vibrate \"A Vibrator\" vibration output/haptic\n"
|
||||
);
|
||||
},
|
||||
|
||||
/* XR_BindProfileStr("valve_index",
|
||||
"/interaction_profiles/valve/index_controller /user/hand/left/ /user/hand/right/\n"
|
||||
/* {"valve_index", "/interaction_profiles/valve/index_controller /user/hand/left/ /user/hand/right/\n"
|
||||
//"unbound \"Unused Button\" button input/system/click\n"
|
||||
//"unbound \"Unused Button\" button input/system/touch\n"
|
||||
//"unbound \"Unused Button\" button input/a/click\n"
|
||||
|
@ -1096,10 +991,9 @@ static void XR_SetupInputs(void)
|
|||
//"unbound \"Unused Button\" pose input/grip/pose\n"
|
||||
//"unbound \"Unused Button\" pose input/aim/pose\n"
|
||||
//"unbound \"Unused Button\" vibration output/haptic\n"
|
||||
);
|
||||
},
|
||||
*/
|
||||
/* XR_BindProfileStr("htc_vive",
|
||||
"/interaction_profiles/htc/vive_controller /user/hand/left/ /user/hand/right/\n"
|
||||
/* {"htc_vive", "/interaction_profiles/htc/vive_controller /user/hand/left/ /user/hand/right/\n"
|
||||
//"unbound \"Unused Button\" button input/system/click\n"
|
||||
//"unbound \"Unused Button\" button input/squeeze/click\n"
|
||||
//"unbound \"Unused Button\" button input/menu/click\n"
|
||||
|
@ -1113,8 +1007,7 @@ static void XR_SetupInputs(void)
|
|||
//"unbound \"Unused Button\" vibration output/haptic\n"
|
||||
);
|
||||
*/
|
||||
/* XR_BindProfileStr("htc_vive_pro",
|
||||
"/interaction_profiles/htc/vive_pro /user/head/\n"
|
||||
/* {"htc_vive_pro", "/interaction_profiles/htc/vive_pro /user/head/\n"
|
||||
//"unbound \"Unused Button\" button input/system/click\n"
|
||||
//"unbound \"Unused Button\" button input/volume_up/click\n"
|
||||
//"unbound \"Unused Button\" button input/volume_down/click\n"
|
||||
|
@ -1123,7 +1016,7 @@ static void XR_SetupInputs(void)
|
|||
*/
|
||||
|
||||
//FIXME: map to quake's keys.
|
||||
XR_BindProfileStr("gamepad", "/interaction_profiles/microsoft/xbox_controller /user/gamepad/\n"
|
||||
{"gamepad", "/interaction_profiles/microsoft/xbox_controller /user/gamepad/\n"
|
||||
"togglemenu Menu button input/menu/click\n"
|
||||
//"unbound \"Unused Button\" button input/view/click\n"
|
||||
//"unbound \"Unused Button\" button input/a/click\n"
|
||||
|
@ -1148,7 +1041,34 @@ static void XR_SetupInputs(void)
|
|||
//"unbound \"Unused Vibrator\" vibration output/haptic_left_trigger\n"
|
||||
//"unbound \"Unused Vibrator\" vibration output/haptic_right\n"
|
||||
//"unbound \"Unused Vibrator\" vibration output/haptic_right_trigger\n"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
static void XR_SetupInputs(void)
|
||||
{
|
||||
unsigned int h;
|
||||
XrResult res;
|
||||
|
||||
//begin instance-level init
|
||||
{
|
||||
XrActionSetCreateInfo info = {XR_TYPE_ACTION_SET_CREATE_INFO};
|
||||
Q_strlcpy(info.actionSetName, "actions", sizeof(info.actionSetName));
|
||||
Q_strlcpy(info.localizedActionSetName, FULLENGINENAME" Actions", sizeof(info.localizedActionSetName));
|
||||
info.priority = 0;
|
||||
|
||||
xr.actionset.subactionPath = XR_NULL_PATH;
|
||||
res = xrCreateActionSet(xr.instance, &info, &xr.actionset.actionSet);
|
||||
if (XR_FAILED(res))
|
||||
Con_Printf("openxr: Unable to create actionset - %s\n", XR_StringForResult(res));
|
||||
}
|
||||
|
||||
h = 0;
|
||||
if (fsfuncs)
|
||||
fsfuncs->EnumerateFiles("oxr_*.binds", XR_BindProfileFile, &h);
|
||||
if (!h) //no user bindings defined, use fallbacks. probably this needs to be per-mod.
|
||||
{
|
||||
for (h = 0; h < countof(xr_knownprofiles); h++)
|
||||
XR_BindProfileStr(xr_knownprofiles[h].name, xr_knownprofiles[h].script);
|
||||
}
|
||||
|
||||
//begin session specific. stuff
|
||||
|
@ -1295,8 +1215,7 @@ static void XR_UpdateInputs(XrTime time)
|
|||
(loc.locationFlags&XR_SPACE_LOCATION_ORIENTATION_VALID_BIT)?angles:NULL,
|
||||
(vel.velocityFlags&XR_SPACE_VELOCITY_LINEAR_VALID_BIT)?lvel:NULL,
|
||||
(vel.velocityFlags&XR_SPACE_VELOCITY_ANGULAR_VALID_BIT)?avel:NULL))
|
||||
if (transform[3][0] || transform[3][1] || transform[3][2])
|
||||
{
|
||||
{ //custom poses that mods might want to handle themselves...
|
||||
vec3_t angles;
|
||||
char cmd[256];
|
||||
VectorAngles(transform[0], transform[2], angles, false);
|
||||
|
@ -1695,7 +1614,7 @@ static qboolean XR_SyncFrame(double *frametime)
|
|||
|
||||
return true;
|
||||
}
|
||||
static qboolean XR_Render(void(*rendereye)(texid_t tex, vec4_t fovoverride, matrix3x4 axisorg))
|
||||
static qboolean XR_Render(void(*rendereye)(texid_t tex, vec4_t fovoverride, vec3_t angorg[2]))
|
||||
{
|
||||
XrFrameEndInfo endframeinfo = {XR_TYPE_FRAME_END_INFO};
|
||||
unsigned int u;
|
||||
|
@ -1762,7 +1681,6 @@ static qboolean XR_Render(void(*rendereye)(texid_t tex, vec4_t fovoverride, matr
|
|||
XrViewState viewstate = {XR_TYPE_VIEW_STATE};
|
||||
XrViewLocateInfo locateinfo = {XR_TYPE_VIEW_LOCATE_INFO};
|
||||
XrView eyeview[MAX_VIEW_COUNT]={};
|
||||
matrix3x4 transform, eyetransform, inv;
|
||||
for (u = 0; u < MAX_VIEW_COUNT; u++)
|
||||
eyeview[u].type = XR_TYPE_VIEW;
|
||||
|
||||
|
@ -1802,8 +1720,6 @@ static qboolean XR_Render(void(*rendereye)(texid_t tex, vec4_t fovoverride, matr
|
|||
apose.position.y /= xr.viewcount;
|
||||
apose.position.z /= xr.viewcount;
|
||||
XR_PoseToAngOrg(&apose, ang, org);
|
||||
Matrix3x4_FromAngles(ang, org, transform[0]);
|
||||
Matrix3x4_Invert_XR(transform[0], inv[0]);
|
||||
inputfuncs->SetHandPosition("head", org, ang, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -1812,6 +1728,7 @@ static qboolean XR_Render(void(*rendereye)(texid_t tex, vec4_t fovoverride, matr
|
|||
vec4_t fovoverride;
|
||||
XrSwapchainImageWaitInfo waitinfo = {XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO};
|
||||
unsigned int imgidx = 0;
|
||||
vec3_t orientation[2];
|
||||
res = xrAcquireSwapchainImage(xr.eye[u].swapchain, NULL, &imgidx);
|
||||
if (XR_FAILED(res))
|
||||
Con_Printf("xrAcquireSwapchainImage: %s\n", XR_StringForResult(res));
|
||||
|
@ -1822,8 +1739,7 @@ static qboolean XR_Render(void(*rendereye)(texid_t tex, vec4_t fovoverride, matr
|
|||
projviews[u].fov = eyeview[u].fov;
|
||||
projviews[u].subImage = xr.eye[u].subimage;
|
||||
|
||||
XR_PoseToTransform(&eyeview[u].pose, transform[0]);
|
||||
Matrix3x4_Multiply_XR(transform[0], inv[0], eyetransform[0]);
|
||||
XR_PoseToAngOrg(&eyeview[u].pose, orientation[0], orientation[1]);
|
||||
|
||||
fovoverride[0] = eyeview[u].fov.angleLeft * (180/M_PI);
|
||||
fovoverride[1] = eyeview[u].fov.angleRight * (180/M_PI);
|
||||
|
@ -1834,7 +1750,7 @@ static qboolean XR_Render(void(*rendereye)(texid_t tex, vec4_t fovoverride, matr
|
|||
res = xrWaitSwapchainImage(xr.eye[u].swapchain, &waitinfo);
|
||||
if (XR_FAILED(res))
|
||||
Con_Printf("xrWaitSwapchainImage: %s\n", XR_StringForResult(res));
|
||||
rendereye(&xr.eye[u].swapimages[imgidx], fovoverride, eyetransform);
|
||||
rendereye(&xr.eye[u].swapimages[imgidx], fovoverride, orientation);
|
||||
//GL note: the OpenXR specification says NOTHING about the application having to glFlush or glFinish.
|
||||
// I take this to mean that the openxr runtime is responsible for setting up barriers or w/e inside ReleaseSwapchainImage.
|
||||
//VK note: the OpenXR spec does say that it needs to be color_attachment_optimal+owned by queue. which it is.
|
||||
|
|
Loading…
Reference in a new issue