Initial support for OpenXR. Remember to side-load the openxr plugin and set _pext_vrinputs to 1.
This commit is contained in:
parent
5e70290017
commit
9e0f93c796
19 changed files with 580 additions and 18 deletions
|
@ -267,6 +267,30 @@ Cmd_Parse(string sCMD)
|
||||||
case "player_geomtest":
|
case "player_geomtest":
|
||||||
CMD_player_geomtest();
|
CMD_player_geomtest();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* XR binds, engine binds them currently */
|
||||||
|
case "+attack_left":
|
||||||
|
pSeat->m_bMoveForward = true;
|
||||||
|
break;
|
||||||
|
case "-attack_left":
|
||||||
|
pSeat->m_bMoveForward = false;
|
||||||
|
break;
|
||||||
|
case "+menu_left":
|
||||||
|
break;
|
||||||
|
case "-menu_left":
|
||||||
|
break;
|
||||||
|
case "+attack_right":
|
||||||
|
pSeat->m_iInputAttack = true;
|
||||||
|
break;
|
||||||
|
case "-attack_right":
|
||||||
|
pSeat->m_iInputAttack = false;
|
||||||
|
break;
|
||||||
|
case "+menu_right":
|
||||||
|
pSeat->m_iInputReload = TRUE;
|
||||||
|
break;
|
||||||
|
case "-menu_right":
|
||||||
|
pSeat->m_iInputReload = FALSE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -343,4 +367,14 @@ Cmd_Init(void)
|
||||||
/* Requested by Slacer */
|
/* Requested by Slacer */
|
||||||
registercommand("+zoomin");
|
registercommand("+zoomin");
|
||||||
registercommand("-zoomin");
|
registercommand("-zoomin");
|
||||||
|
|
||||||
|
/* XR binds, temporady until the engine standardizes things */
|
||||||
|
registercommand("+attack_left");
|
||||||
|
registercommand("-attack_left");
|
||||||
|
registercommand("+attack_right");
|
||||||
|
registercommand("-attack_right");
|
||||||
|
registercommand("+menu_left");
|
||||||
|
registercommand("-menu_left");
|
||||||
|
registercommand("+menu_right");
|
||||||
|
registercommand("-menu_right");
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,6 +185,7 @@ struct
|
||||||
string m_strPrintBuffer[5];
|
string m_strPrintBuffer[5];
|
||||||
int m_iPrintLines;
|
int m_iPrintLines;
|
||||||
|
|
||||||
|
bool m_iInputAttack;
|
||||||
int m_iInputAttack2;
|
int m_iInputAttack2;
|
||||||
int m_iInputReload;
|
int m_iInputReload;
|
||||||
int m_iInputUse;
|
int m_iInputUse;
|
||||||
|
@ -212,4 +213,7 @@ struct
|
||||||
/* vehicles */
|
/* vehicles */
|
||||||
float m_flVehTransition;
|
float m_flVehTransition;
|
||||||
vector m_vecVehEntry;
|
vector m_vecVehEntry;
|
||||||
|
|
||||||
|
/* new XR helpers */
|
||||||
|
bool m_bMoveForward;
|
||||||
} g_seats[4], *pSeat;
|
} g_seats[4], *pSeat;
|
||||||
|
|
|
@ -272,7 +272,6 @@ CSQC_UpdateView(float w, float h, float focus)
|
||||||
|
|
||||||
View_PreDraw();
|
View_PreDraw();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
addentities(MASK_ENGINE);
|
addentities(MASK_ENGINE);
|
||||||
|
|
||||||
/* ideally move this into a base_player method */
|
/* ideally move this into a base_player method */
|
||||||
|
@ -347,6 +346,7 @@ CSQC_UpdateView(float w, float h, float focus)
|
||||||
addentities(MASK_GLOWS);
|
addentities(MASK_GLOWS);
|
||||||
setproperty(VF_DRAWWORLD, 1);
|
setproperty(VF_DRAWWORLD, 1);
|
||||||
SkyCamera_Setup(getproperty(VF_ORIGIN));
|
SkyCamera_Setup(getproperty(VF_ORIGIN));
|
||||||
|
XR_UpdateView(self);
|
||||||
|
|
||||||
/* draw the viewmodel in a second pass if desired */
|
/* draw the viewmodel in a second pass if desired */
|
||||||
if (autocvar_r_viewmodelpass && pl.health > 0) {
|
if (autocvar_r_viewmodelpass && pl.health > 0) {
|
||||||
|
|
|
@ -207,12 +207,25 @@ View_DrawViewModel(void)
|
||||||
|
|
||||||
/* now apply the scale hack */
|
/* now apply the scale hack */
|
||||||
m_eViewModelL.scale = m_eViewModel.scale = autocvar_r_viewmodelscale;
|
m_eViewModelL.scale = m_eViewModel.scale = autocvar_r_viewmodelscale;
|
||||||
m_eViewModelL.origin = m_eViewModel.origin = pSeat->m_vecPredictedOrigin + pl.view_ofs;
|
m_eViewModelL.origin = pl.m_xrInputLeft.GetOrigin();
|
||||||
|
m_eViewModel.origin = pl.m_xrInputRight.GetOrigin();
|
||||||
|
|
||||||
/* we only calculate bob on the right model, to avoid double speed bobbing */
|
if (XR_Available(pl)) {
|
||||||
Viewmodel_CalcBob();
|
m_eViewModel.angles = pl.m_xrInputLeft.GetAngles();
|
||||||
Viewmodel_ApplyBob(m_eViewModel);
|
m_eViewModelL.angles = pl.m_xrInputRight.GetAngles();
|
||||||
Viewmodel_ApplyBob(m_eViewModelL);
|
} else {
|
||||||
|
/* we only calculate bob on the right model, to avoid double speed bobbing */
|
||||||
|
Viewmodel_CalcBob();
|
||||||
|
Viewmodel_ApplyBob(m_eViewModel);
|
||||||
|
Viewmodel_ApplyBob(m_eViewModelL);
|
||||||
|
|
||||||
|
/* view roll */
|
||||||
|
if (pl.movetype == MOVETYPE_WALK) {
|
||||||
|
Camera_StrafeRoll(view_angles);
|
||||||
|
Camera_RunBob(view_angles);
|
||||||
|
setproperty(VF_ANGLES, view_angles + pl.punchangle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* this is currently broken */
|
/* this is currently broken */
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -260,13 +273,6 @@ View_DrawViewModel(void)
|
||||||
addentity(m_eViewModel);
|
addentity(m_eViewModel);
|
||||||
addentity(m_eViewModelL);
|
addentity(m_eViewModelL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* view roll */
|
|
||||||
if (pl.movetype == MOVETYPE_WALK) {
|
|
||||||
Camera_StrafeRoll(view_angles);
|
|
||||||
Camera_RunBob(view_angles);
|
|
||||||
setproperty(VF_ANGLES, view_angles + pl.punchangle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -5,6 +5,11 @@ base_client:NSSurfacePropEntity
|
||||||
vector origin_net;
|
vector origin_net;
|
||||||
vector velocity_net;
|
vector velocity_net;
|
||||||
|
|
||||||
|
NSXRSpace m_xrSpace;
|
||||||
|
NSXRInput m_xrInputHead;
|
||||||
|
NSXRInput m_xrInputLeft;
|
||||||
|
NSXRInput m_xrInputRight;
|
||||||
|
|
||||||
void(void) base_client;
|
void(void) base_client;
|
||||||
|
|
||||||
/* final input handling of the client */
|
/* final input handling of the client */
|
||||||
|
@ -18,6 +23,8 @@ base_client:NSSurfacePropEntity
|
||||||
virtual bool(void) IsDead;
|
virtual bool(void) IsDead;
|
||||||
virtual bool(void) IsPlayer;
|
virtual bool(void) IsPlayer;
|
||||||
|
|
||||||
|
virtual void(void) OnRemoveEntity;
|
||||||
|
|
||||||
#ifdef CLIENT
|
#ifdef CLIENT
|
||||||
/* gives the chance to override input variables before networking */
|
/* gives the chance to override input variables before networking */
|
||||||
virtual void(void) ClientInputFrame;
|
virtual void(void) ClientInputFrame;
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
void
|
||||||
|
base_client::OnRemoveEntity(void)
|
||||||
|
{
|
||||||
|
XR_Shutdown(this);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
base_client::ClientInput(void)
|
base_client::ClientInput(void)
|
||||||
{
|
{
|
||||||
|
@ -63,7 +69,7 @@ base_client::predraw(void)
|
||||||
void
|
void
|
||||||
base_client::base_client(void)
|
base_client::base_client(void)
|
||||||
{
|
{
|
||||||
|
XR_Init(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../gs-entbase/shared/baseentity.h"
|
#include "../gs-entbase/shared/baseentity.h"
|
||||||
|
#include "../xr/defs.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "spectator.h"
|
#include "spectator.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
|
@ -9,4 +9,5 @@ player.qc
|
||||||
player_pmove.qc
|
player_pmove.qc
|
||||||
propdata.qc
|
propdata.qc
|
||||||
surfaceproperties.qc
|
surfaceproperties.qc
|
||||||
|
../xr/include.src
|
||||||
#endlist
|
#endlist
|
||||||
|
|
|
@ -102,6 +102,8 @@ base_player::PostFrame(void)
|
||||||
void
|
void
|
||||||
base_player::ClientInput(void)
|
base_player::ClientInput(void)
|
||||||
{
|
{
|
||||||
|
XR_InputFrame(this);
|
||||||
|
|
||||||
if (!Client_InIntermission() && IsFakeSpectator()) {
|
if (!Client_InIntermission() && IsFakeSpectator()) {
|
||||||
spectator::ClientInput();
|
spectator::ClientInput();
|
||||||
SpectatorTrackPlayer();
|
SpectatorTrackPlayer();
|
||||||
|
@ -135,6 +137,8 @@ base_player::OnRemoveEntity(void)
|
||||||
{
|
{
|
||||||
if (p_model)
|
if (p_model)
|
||||||
remove(p_model);
|
remove(p_model);
|
||||||
|
|
||||||
|
super::OnRemoveEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -197,6 +201,17 @@ base_player::ClientInputFrame(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* some input overrides for XR */
|
||||||
|
if (XR_Available(this)) {
|
||||||
|
if (pSeat->m_bMoveForward) {
|
||||||
|
input_movevalues[0] = cvar("cl_forwardspeed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSeat->m_iInputAttack) {
|
||||||
|
input_buttons |= INPUT_BUTTON0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* compat*/
|
/* compat*/
|
||||||
if (input_impulse == 201) {
|
if (input_impulse == 201) {
|
||||||
sendevent("Spraylogo", "");
|
sendevent("Spraylogo", "");
|
||||||
|
@ -931,5 +946,6 @@ base_player::InputUse_Up(void)
|
||||||
void
|
void
|
||||||
base_player::base_player(void)
|
base_player::base_player(void)
|
||||||
{
|
{
|
||||||
|
super::spectator();
|
||||||
vehicle = __NULL__;
|
vehicle = __NULL__;
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,6 +330,10 @@ base_player::Physics_Run(void)
|
||||||
input_buttons = saved_input_buttons;
|
input_buttons = saved_input_buttons;
|
||||||
Physics_InputPostMove();
|
Physics_InputPostMove();
|
||||||
|
|
||||||
|
angles[0] = Math_FixDelta(angles[0]);
|
||||||
|
angles[1] = Math_FixDelta(angles[1]);
|
||||||
|
angles[2] = Math_FixDelta(angles[2]);
|
||||||
|
|
||||||
#ifdef SERVER
|
#ifdef SERVER
|
||||||
/* Use Flagger */
|
/* Use Flagger */
|
||||||
vector src, dest;
|
vector src, dest;
|
||||||
|
@ -345,9 +349,9 @@ base_player::Physics_Run(void)
|
||||||
flags |= FL_ONUSABLE;
|
flags |= FL_ONUSABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
angles[0] = Math_FixDelta(angles[0]);
|
|
||||||
angles[1] = Math_FixDelta(angles[1]);
|
m_xrSpace.SetOrigin(origin + view_ofs);
|
||||||
angles[2] = Math_FixDelta(angles[2]);
|
m_xrSpace.SetAngles(angles);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,6 +450,7 @@ spectator::PostFrame(void)
|
||||||
void
|
void
|
||||||
spectator::spectator(void)
|
spectator::spectator(void)
|
||||||
{
|
{
|
||||||
|
super::base_client();
|
||||||
modelindex = 0;
|
modelindex = 0;
|
||||||
flags = FL_CLIENT;
|
flags = FL_CLIENT;
|
||||||
SetSolid(SOLID_NOT);
|
SetSolid(SOLID_NOT);
|
||||||
|
|
59
src/xr/NSXRInput.h
Normal file
59
src/xr/NSXRInput.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2022 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
XR_INPUT_UNKNOWN,
|
||||||
|
XR_INPUT_HEAD,
|
||||||
|
XR_INPUT_LEFT,
|
||||||
|
XR_INPUT_RIGHT
|
||||||
|
} xrinput_e;
|
||||||
|
|
||||||
|
#define XR_STATUS_ORG (1u<<0)
|
||||||
|
#define XR_STATUS_ANG (1u<<1)
|
||||||
|
#define XR_STATUS_VEL (1u<<2)
|
||||||
|
#define XR_STATUS_AVEL (1u<<3)
|
||||||
|
|
||||||
|
class
|
||||||
|
NSXRInput
|
||||||
|
{
|
||||||
|
NSXRSpace m_xrSpace;
|
||||||
|
vector m_vecOrigin;
|
||||||
|
vector m_vecAngles;
|
||||||
|
vector m_vecVelocity;
|
||||||
|
vector m_vecAVelocity;
|
||||||
|
unsigned int m_iStatus;
|
||||||
|
unsigned int m_iWeapon;
|
||||||
|
|
||||||
|
xrinput_e m_inputType;
|
||||||
|
|
||||||
|
void(void) NSXRInput;
|
||||||
|
virtual void(xrinput_e) SetType;
|
||||||
|
virtual void(NSXRSpace) SetParentSpace;
|
||||||
|
|
||||||
|
virtual vector(void) GetOrigin;
|
||||||
|
virtual vector(void) GetAngles;
|
||||||
|
virtual vector(void) GetVelocity;
|
||||||
|
virtual vector(void) GetAngularVelocity;
|
||||||
|
virtual unsigned int(void) GetStatus;
|
||||||
|
virtual unsigned int(void) GetWeapon;
|
||||||
|
virtual xrinput_e (void) GetType;
|
||||||
|
|
||||||
|
virtual bool(void) IsAvailable;
|
||||||
|
virtual void(void) InputFrame;
|
||||||
|
|
||||||
|
virtual void(void) PrintInfo;
|
||||||
|
};
|
149
src/xr/NSXRInput.qc
Normal file
149
src/xr/NSXRInput.qc
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2022 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRInput::GetOrigin(void)
|
||||||
|
{
|
||||||
|
if (!m_xrSpace) {
|
||||||
|
print("WARNING: XR Space not yet present!\n");
|
||||||
|
return [0,0,0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_xrSpace.RoomToWorldOrigin(m_vecOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRInput::GetAngles(void)
|
||||||
|
{
|
||||||
|
if (!m_xrSpace) {
|
||||||
|
print("WARNING: XR Space not yet present!\n");
|
||||||
|
return [0,0,0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_xrSpace.RoomToWorldAngles(m_vecAngles);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRInput::GetVelocity(void)
|
||||||
|
{
|
||||||
|
return m_vecVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRInput::GetAngularVelocity(void)
|
||||||
|
{
|
||||||
|
return m_vecAVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
NSXRInput::GetStatus(void)
|
||||||
|
{
|
||||||
|
return m_iStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
NSXRInput::GetWeapon(void)
|
||||||
|
{
|
||||||
|
return m_iWeapon;
|
||||||
|
}
|
||||||
|
|
||||||
|
xrinput_e
|
||||||
|
NSXRInput::GetType(void)
|
||||||
|
{
|
||||||
|
return m_inputType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRInput::InputFrame(void)
|
||||||
|
{
|
||||||
|
switch (m_inputType) {
|
||||||
|
case XR_INPUT_HEAD:
|
||||||
|
m_vecOrigin = input_head_origin;
|
||||||
|
m_vecAngles = input_head_angles;
|
||||||
|
m_vecVelocity = input_head_velocity;
|
||||||
|
m_vecAVelocity = input_head_avelocity;
|
||||||
|
m_iStatus = input_head_status;
|
||||||
|
m_iWeapon = input_head_weapon;
|
||||||
|
break;
|
||||||
|
case XR_INPUT_LEFT:
|
||||||
|
m_vecOrigin = input_left_origin;
|
||||||
|
m_vecAngles = input_left_angles;
|
||||||
|
m_vecVelocity = input_left_velocity;
|
||||||
|
m_vecAVelocity = input_left_avelocity;
|
||||||
|
m_iStatus = input_left_status;
|
||||||
|
m_iWeapon = input_left_weapon;
|
||||||
|
break;
|
||||||
|
case XR_INPUT_RIGHT:
|
||||||
|
m_vecOrigin = input_right_origin;
|
||||||
|
m_vecAngles = input_right_angles;
|
||||||
|
m_vecVelocity = input_right_velocity;
|
||||||
|
m_vecAVelocity = input_right_avelocity;
|
||||||
|
m_iStatus = input_right_status;
|
||||||
|
m_iWeapon = input_right_weapon;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print(sprintf("NSXRInput: Cannot run InputFrame() on unknown type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//PrintInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NSXRInput::IsAvailable(void)
|
||||||
|
{
|
||||||
|
/* if it's generating new origin/angles, then the device is very clearly available */
|
||||||
|
return (m_iStatus & (XR_STATUS_ORG | XR_STATUS_ANG)) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRInput::SetType(xrinput_e type)
|
||||||
|
{
|
||||||
|
m_inputType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRInput::SetParentSpace(NSXRSpace xrSpace)
|
||||||
|
{
|
||||||
|
m_xrSpace = xrSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRInput::PrintInfo(void)
|
||||||
|
{
|
||||||
|
string deviceType;
|
||||||
|
|
||||||
|
switch (m_inputType) {
|
||||||
|
case XR_INPUT_HEAD:
|
||||||
|
deviceType = "HEAD";
|
||||||
|
break;
|
||||||
|
case XR_INPUT_LEFT:
|
||||||
|
deviceType = "LEFT";
|
||||||
|
break;
|
||||||
|
case XR_INPUT_RIGHT:
|
||||||
|
deviceType = "RIGHT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print(sprintf("NSXRInput: Cannot run PrintInfo() on unknown type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
crossprint(sprintf("%s o: %v a: %v v:%v va:%v s:%i w:%i\n", deviceType, GetOrigin(), GetAngles(), GetVelocity(), GetAngularVelocity(), GetStatus(), GetWeapon()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRInput::NSXRInput(void)
|
||||||
|
{
|
||||||
|
print("registered NSXRInput\n");
|
||||||
|
}
|
37
src/xr/NSXRSpace.h
Normal file
37
src/xr/NSXRSpace.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2022 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* class handling the room to world translations for XR */
|
||||||
|
class
|
||||||
|
NSXRSpace
|
||||||
|
{
|
||||||
|
vector m_vecForward;
|
||||||
|
vector m_vecRight;
|
||||||
|
vector m_vecUp;
|
||||||
|
vector m_vecOrigin;
|
||||||
|
|
||||||
|
void(void) NSXRSpace;
|
||||||
|
|
||||||
|
virtual void(vector) SetOrigin;
|
||||||
|
virtual void(vector) SetAngles;
|
||||||
|
|
||||||
|
virtual vector(void) GetForward;
|
||||||
|
virtual vector(void) GetRight;
|
||||||
|
virtual vector(void) GetUp;
|
||||||
|
|
||||||
|
virtual vector(vector) RoomToWorldOrigin;
|
||||||
|
virtual vector(vector) RoomToWorldAngles;
|
||||||
|
};
|
73
src/xr/NSXRSpace.qc
Normal file
73
src/xr/NSXRSpace.qc
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2022 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRSpace::GetForward(void)
|
||||||
|
{
|
||||||
|
return m_vecForward;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRSpace::GetRight(void)
|
||||||
|
{
|
||||||
|
return m_vecRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRSpace::GetUp(void)
|
||||||
|
{
|
||||||
|
return m_vecUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRSpace::RoomToWorldOrigin(vector vecRoomOrg)
|
||||||
|
{
|
||||||
|
vector vecOut;
|
||||||
|
vecOut = m_vecOrigin;
|
||||||
|
vecOut += (m_vecForward * vecRoomOrg[0]);
|
||||||
|
vecOut -= (m_vecRight * vecRoomOrg[1]);
|
||||||
|
vecOut += (m_vecUp * vecRoomOrg[2]);
|
||||||
|
return vecOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSXRSpace::RoomToWorldAngles(vector vecRoomAng)
|
||||||
|
{
|
||||||
|
makevectors(vecRoomAng);
|
||||||
|
rotatevectorsbyvectors(m_vecForward, m_vecRight, m_vecUp);
|
||||||
|
return vectoangles(v_forward, v_up);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRSpace::SetOrigin(vector vecOrigin)
|
||||||
|
{
|
||||||
|
m_vecOrigin = vecOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRSpace::SetAngles(vector vecAngles)
|
||||||
|
{
|
||||||
|
makevectors(vecAngles);
|
||||||
|
m_vecForward = v_forward;
|
||||||
|
m_vecRight = v_right;
|
||||||
|
m_vecUp = v_up;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSXRSpace::NSXRSpace(void)
|
||||||
|
{
|
||||||
|
print("allocated NSXRSpace\n");
|
||||||
|
}
|
19
src/xr/defs.h
Normal file
19
src/xr/defs.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2022 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NSXRSpace.h"
|
||||||
|
#include "NSXRInput.h"
|
||||||
|
#include "xr.h"
|
5
src/xr/include.src
Normal file
5
src/xr/include.src
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#includelist
|
||||||
|
../xr/NSXRSpace.qc
|
||||||
|
../xr/NSXRInput.qc
|
||||||
|
../xr/xr.qc
|
||||||
|
#endlist
|
24
src/xr/xr.h
Normal file
24
src/xr/xr.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2022 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void XR_Init(entity);
|
||||||
|
void XR_Shutdown(entity);
|
||||||
|
bool XR_Available(entity);
|
||||||
|
void XR_InputFrame(entity);
|
||||||
|
|
||||||
|
#ifdef CLIENT
|
||||||
|
void XR_UpdateView(entity);
|
||||||
|
#endif
|
116
src/xr/xr.qc
Normal file
116
src/xr/xr.qc
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2022 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The engine provides us with 3 devices right now, each giving us
|
||||||
|
their position, angle etc. as well as field stating which bits
|
||||||
|
of information have gotten updated.
|
||||||
|
|
||||||
|
If no updates are happening from the HMD/head, that means we're
|
||||||
|
most like not in VR, or the player has taken the headset off and
|
||||||
|
laid it down.
|
||||||
|
|
||||||
|
If we have no updates from the left and right XR devices, we
|
||||||
|
will use the regular input_angles and view position for weapons.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
XR_Init(entity ePlayer)
|
||||||
|
{
|
||||||
|
base_client pl = (base_client)ePlayer;
|
||||||
|
|
||||||
|
print("--------- Initializing XR ----------\n");
|
||||||
|
pl.m_xrSpace = spawn(NSXRSpace);
|
||||||
|
|
||||||
|
/* the only 3 devices that matter right now */
|
||||||
|
pl.m_xrInputHead = spawn(NSXRInput);
|
||||||
|
pl.m_xrInputHead.SetType(XR_INPUT_HEAD);
|
||||||
|
pl.m_xrInputHead.SetParentSpace(pl.m_xrSpace);
|
||||||
|
pl.m_xrInputLeft = spawn(NSXRInput);
|
||||||
|
pl.m_xrInputLeft.SetType(XR_INPUT_LEFT);
|
||||||
|
pl.m_xrInputLeft.SetParentSpace(pl.m_xrSpace);
|
||||||
|
pl.m_xrInputRight = spawn(NSXRInput);
|
||||||
|
pl.m_xrInputRight.SetType(XR_INPUT_RIGHT);
|
||||||
|
pl.m_xrInputRight.SetParentSpace(pl.m_xrSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XR_Shutdown(entity ePlayer)
|
||||||
|
{
|
||||||
|
base_client pl = (base_client)ePlayer;
|
||||||
|
remove(pl.m_xrInputHead);
|
||||||
|
remove(pl.m_xrInputLeft);
|
||||||
|
remove(pl.m_xrInputRight);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CLIENT
|
||||||
|
void
|
||||||
|
XR_UpdateView(entity ePlayer)
|
||||||
|
{
|
||||||
|
base_client pl = (base_client)ePlayer;
|
||||||
|
|
||||||
|
/* not yet ready */
|
||||||
|
if (!pl.m_xrSpace)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* update our space */
|
||||||
|
pl.m_xrSpace.SetOrigin(pSeat->m_vecPredictedOrigin + pSeat->m_ePlayer.view_ofs);
|
||||||
|
pl.m_xrSpace.SetAngles(input_angles);
|
||||||
|
|
||||||
|
/* now we get the HMD's org/ang and send that off to the renderer */
|
||||||
|
setviewprop(VF_ANGLES, pl.m_xrInputHead.GetAngles());
|
||||||
|
setviewprop(VF_ORIGIN, pl.m_xrInputHead.GetOrigin());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
XR_InputFrame(entity ePlayer)
|
||||||
|
{
|
||||||
|
base_client pl = (base_client)ePlayer;
|
||||||
|
|
||||||
|
/* not yet ready */
|
||||||
|
if (!pl.m_xrSpace)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (autocvar(debug_fakevr, 0)) {
|
||||||
|
input_head_status = (XR_STATUS_ORG | XR_STATUS_ANG);
|
||||||
|
input_left_status = (XR_STATUS_ORG | XR_STATUS_ANG);
|
||||||
|
input_right_status = (XR_STATUS_ORG | XR_STATUS_ANG);
|
||||||
|
|
||||||
|
input_head_angles = [sin(time), sin(time * 1.25) * 5, sin(time * 1.45)];
|
||||||
|
input_left_angles = [cos(time) * 5,cos(time) * 25,sin(time) * 5];
|
||||||
|
input_right_angles = [cos(time) * 5,cos(time) * 25,sin(time) * 5];
|
||||||
|
|
||||||
|
input_head_origin = [sin(time)*5,cos(time)*5,sin(time)*5];
|
||||||
|
input_left_origin = input_head_origin + [cos(time*8) * 2,4,sin(time*8) * 2];
|
||||||
|
input_right_origin = input_head_origin + [cos(time*8) * 2,-4,sin(time*8) * 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the input internals for keeping track*/
|
||||||
|
pl.m_xrInputHead.InputFrame();
|
||||||
|
pl.m_xrInputLeft.InputFrame();
|
||||||
|
pl.m_xrInputRight.InputFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
XR_Available(entity ePlayer)
|
||||||
|
{
|
||||||
|
base_client pl = (base_client)ePlayer;
|
||||||
|
|
||||||
|
/* we only care about the HMD... otherwise why even bother? */
|
||||||
|
return pl.m_xrInputHead.IsAvailable();
|
||||||
|
}
|
Loading…
Reference in a new issue