Weapons working

Thanks to Fishbiter for the OpenVR port which showed me how to do it!
This commit is contained in:
Simon 2020-03-15 08:36:32 +00:00
parent 1ba20da2de
commit c4c2ffbb7a
7 changed files with 99 additions and 77 deletions

View file

@ -766,13 +766,13 @@ void GetAnglesFromVectors(const ovrVector3f forward, const ovrVector3f right, co
NormalizeAngles(angles);
}
void QuatToYawPitchRoll(ovrQuatf q, float pitchAdjust, vec3_t out) {
void QuatToYawPitchRoll(ovrQuatf q, vec3_t rotation, vec3_t out) {
ovrMatrix4f mat = ovrMatrix4f_CreateFromQuaternion( &q );
if (pitchAdjust != 0.0f)
if (rotation[0] != 0.0f || rotation[1] != 0.0f || rotation[2] != 0.0f)
{
ovrMatrix4f rot = ovrMatrix4f_CreateRotation(radians(pitchAdjust), 0.0f, 0.0f);
ovrMatrix4f rot = ovrMatrix4f_CreateRotation(radians(rotation[0]), radians(rotation[1]), radians(rotation[2]));
mat = ovrMatrix4f_Multiply(&mat, &rot);
}
@ -1528,7 +1528,8 @@ void getHMDOrientation(ovrTracking2 *tracking) {//Get orientation
// to allow "additional" yaw manipulation with mouse/controller.
const ovrQuatf quatHmd = (*tracking).HeadPose.Pose.Orientation;
const ovrVector3f positionHmd = (*tracking).HeadPose.Pose.Position;
QuatToYawPitchRoll(quatHmd, 0.0f, hmdorientation);
vec3_t rotation = {0};
QuatToYawPitchRoll(quatHmd, rotation, hmdorientation);
setHMDPosition(positionHmd.x, positionHmd.y, positionHmd.z, hmdorientation[YAW]);
//TODO: fix - set to use HMD position for world position

View file

@ -68,7 +68,7 @@ float length(float x, float y);
float nonLinearFilter(float in);
bool between(float min, float val, float max);
void rotateAboutOrigin(float v1, float v2, float rotation, vec2_t out);
void QuatToYawPitchRoll(ovrQuatf q, float pitchAdjust, vec3_t out);
void QuatToYawPitchRoll(ovrQuatf q, vec3_t rotation, vec3_t out);
bool useScreenLayer();
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key);
void VR_GetScreenRes(uint32_t *width, uint32_t *height);

View file

@ -45,8 +45,8 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
disable_clock_gettime = !disable_clock_gettime;
}
//Menu button
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, KEY_ESCAPE);
//Menu button - invoke menu
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, KEY_ESCAPE);
if (getGameState() != 0 || isMenuActive()) //gamestate != GS_LEVEL
{
@ -61,6 +61,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, KEY_PAD_A);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, ovrButton_Trigger, KEY_PAD_A);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, KEY_PAD_B);
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, KEY_PAD_B);
}
else
{
@ -94,16 +95,17 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
{
vec2_t v;
rotateAboutOrigin(-weaponoffset[0], weaponoffset[2], VR_GetRawYaw(), v);
weaponoffset[0] = v[0];
weaponoffset[2] = v[1];
rotateAboutOrigin(weaponoffset[0], weaponoffset[2], -(doomYaw - hmdorientation[YAW]), v);
weaponoffset[0] = v[1];
weaponoffset[2] = v[0];
}
//Set gun angles - We need to calculate all those we might need (including adjustments) for the client to then take its pick
//Set gun angles
const ovrQuatf quatRemote = pDominantTracking->HeadPose.Pose.Orientation;
QuatToYawPitchRoll(quatRemote, vr_weapon_pitchadjust, weaponangles);
weaponangles[YAW] -= VR_GetRawYaw();
weaponangles[ROLL] = 0.0f; // remove roll for weapons
vec3_t rotation = {0};
rotation[PITCH] = vr_weapon_pitchadjust;
//rotation[YAW] = (doomYaw - hmdorientation[YAW]);
QuatToYawPitchRoll(quatRemote, rotation, weaponangles);
if (weaponStabilised)
@ -114,7 +116,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
float zxDist = length(x, z);
if (zxDist != 0.0f && z != 0.0f) {
VectorSet(weaponangles, -degrees(atanf(y / zxDist)), VR_GetRawYaw() - degrees(atan2f(x, -z)), 0.0f);
VectorSet(weaponangles, -degrees(atanf(y / zxDist)), (-(doomYaw - hmdorientation[YAW])) - degrees(atan2f(x, -z)), 0.0f);
}
}
}
@ -128,11 +130,12 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
offhandoffset[2] = pOffTracking->HeadPose.Pose.Position.z - hmdPosition[2];
vec2_t v;
rotateAboutOrigin(-offhandoffset[0], offhandoffset[2], VR_GetRawYaw(), v);
offhandoffset[0] = v[0];
offhandoffset[2] = v[1];
rotateAboutOrigin(offhandoffset[0], offhandoffset[2], -(doomYaw - hmdorientation[YAW]), v);
offhandoffset[0] = v[1];
offhandoffset[2] = v[0];
QuatToYawPitchRoll(pOffTracking->HeadPose.Pose.Orientation, 0.0f, offhandangles);
vec3_t rotation = {0};
QuatToYawPitchRoll(pOffTracking->HeadPose.Pose.Orientation, rotation, offhandangles);
if (vr_walkdirection == 0) {
controllerYawHeading = offhandangles[YAW] - hmdorientation[YAW];
@ -141,8 +144,6 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
{
controllerYawHeading = 0.0f;
}
offhandangles[YAW] -= VR_GetRawYaw();
}
//Positional movement

View file

@ -1506,7 +1506,8 @@ public:
//For VR, override firing position - Thank-you Fishbiter for this code!!
bool OverrideAttackPosDir;
DVector3 AttackPos;
DVector3 AttackDir;
//DVector3 AttackDir;
DVector3 (*AttackDir)(AActor* actor, DAngle yaw, DAngle pitch);
};
class FActorIterator

View file

@ -91,39 +91,13 @@ namespace s3d
dispose();
}
static void vSMatrixFromOvrMatrix(VSMatrix& m1, const ovrMatrix4f& m2)
{
float tmp[16];
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
tmp[4 * i + j] = m2.M[i][j];
}
}
int i = 3;
for (int j = 0; j < 4; ++j) {
tmp[4 * i + j] = 0;
}
tmp[15] = 1;
m1.loadMatrix(&tmp[0]);
}
/* virtual */
void OculusQuestEyePose::GetViewShift(FLOATTYPE yaw, FLOATTYPE outViewShift[3]) const
{
outViewShift[0] = outViewShift[1] = outViewShift[2] = 0;
// Pitch and Roll are identical between OpenVR and Doom worlds.
// But yaw can differ, depending on starting state, and controller movement.
float doomYawDegrees = r_viewpoint.Angles.Yaw.Degrees;
while (doomYawDegrees > 180)
doomYawDegrees -= 360;
while (doomYawDegrees < -180)
doomYawDegrees += 360;
vec3_t angles;
VectorSet(angles, -GLRenderer->mAngles.Pitch.Degrees, doomYawDegrees, GLRenderer->mAngles.Roll.Degrees);
VectorSet(angles, -GLRenderer->mAngles.Pitch.Degrees, doomYaw, GLRenderer->mAngles.Roll.Degrees);
vec3_t v_forward, v_right, v_up;
AngleVectors(angles, v_forward, v_right, v_up);
@ -242,7 +216,6 @@ namespace s3d
void OculusQuestEyePose::AdjustHud() const
{
// Draw crosshair on a separate quad, before updating HUD matrix
const Stereo3DMode * mode3d = &Stereo3DMode::getCurrentMode();
if (mode3d->IsMono())
return;
@ -320,7 +293,7 @@ namespace s3d
float scale = 0.000625f * vr_weaponScale;
gl_RenderState.mModelMatrix.scale(scale, -scale, scale);
gl_RenderState.mModelMatrix.translate(-viewwidth / 2, -viewheight * 3 / 4, 0.0f);
gl_RenderState.mModelMatrix.translate(-viewwidth / 2, -viewheight * 3 / 4, 0.0f); // What dis?!
gl_RenderState.EnableModelMatrix(true);
}
@ -330,40 +303,50 @@ namespace s3d
gl_RenderState.EnableModelMatrix(false);
}
static void vSMatrixFromOvrMatrix(VSMatrix& m1, const ovrMatrix4f& m2)
{
float tmp[16];
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
//Do the transpose step at the same time
tmp[4 * j + 1] = m2.M[i][j];
}
}
m1.loadMatrix(&tmp[0]);
}
bool OculusQuestMode::GetHandTransform(int hand, VSMatrix* mat) const
{
AActor* playermo = r_viewpoint.camera->player->mo;
DVector3 pos = playermo->InterpolatedPosition(r_viewpoint.TicFrac);
{
mat->loadIdentity();
AActor* playermo = r_viewpoint.camera->player->mo;
DVector3 pos = playermo->InterpolatedPosition(r_viewpoint.TicFrac);
mat->translate(pos.X, pos.Z, pos.Y);
mat->scale(vr_vunits_per_meter, vr_vunits_per_meter, -vr_vunits_per_meter);
float doomYawDegrees = r_viewpoint.Angles.Yaw.Degrees;
while (doomYawDegrees > 180)
doomYawDegrees -= 360;
while (doomYawDegrees < -180)
doomYawDegrees += 360;
if ((vr_control_scheme < 10 && hand == 1)
|| (vr_control_scheme > 10 && hand == 0)) {
mat->translate(-weaponoffset[0], hmdPosition[1] + weaponoffset[1] - vr_floor_offset, weaponoffset[2]);
mat->rotate(-weaponangles[ROLL], 1, 0, 0);
mat->rotate(-weaponangles[PITCH], 0, 1, 0);
mat->rotate(-doomYawDegrees-weaponangles[YAW], 0, 0, 1);
mat->rotate(-90 + (doomYaw - hmdorientation[YAW]) + weaponangles[YAW], 0, 1, 0);
mat->rotate(-weaponangles[PITCH], 1, 0, 0);
mat->rotate(-weaponangles[ROLL], 0, 0, 1);
}
else
{
//mat->rotate(-offhandangles[ROLL], 1, 0, 0);
//mat->rotate(-offhandangles[PITCH], 0, 1, 0);
//mat->rotate(-offhandangles[YAW], 0, 0, 1);
mat->rotate(-90 + (doomYaw - hmdorientation[YAW]) + offhandangles[YAW], 0, 1, 0);
mat->rotate(-offhandangles[PITCH], 1, 0, 0);
mat->rotate(-offhandangles[ROLL], 0, 0, 1);
mat->translate(offhandoffset[0], hmdPosition[1] + offhandoffset[1] - vr_floor_offset, -offhandoffset[2]);
}
return true;
}
return false;
@ -398,7 +381,40 @@ namespace s3d
return int(m);
}
/* virtual */
static DVector3 MapAttackDir(AActor* actor, DAngle yaw, DAngle pitch)
{
LSMatrix44 mat;
if (!s3d::Stereo3DMode::getCurrentMode().GetWeaponTransform(&mat))
{
double pc = pitch.Cos();
DVector3 direction = { pc * yaw.Cos(), pc * yaw.Sin(), -pitch.Sin() };
return direction;
}
double pc = pitch.Cos();
yaw -= actor->Angles.Yaw;
//ignore specified pitch (would need to compensate for auto aim and no (vanilla) Doom weapon varies this)
//pitch -= actor->Angles.Pitch;
pitch.Degrees = 0;
pc = pitch.Cos();
LSVec3 local = { (float)(pc * yaw.Cos()), (float)(pc * yaw.Sin()), (float)(-pitch.Sin()), 0.0f };
DVector3 dir;
dir.X = local.x * -mat[2][0] + local.y * -mat[0][0] + local.z * -mat[1][0];
dir.Y = local.x * -mat[2][2] + local.y * -mat[0][2] + local.z * -mat[1][2];
dir.Z = local.x * -mat[2][1] + local.y * -mat[0][1] + local.z * -mat[1][1];
dir.MakeUnit();
return dir;
}
/* virtual */
void OculusQuestMode::SetUp() const
{
super::SetUp();
@ -432,7 +448,7 @@ namespace s3d
//Some crazy stuff to ascertain the actual yaw that doom is using at the right times!
if (gamestate != GS_LEVEL || isMenuActive() || (gamestate == GS_LEVEL && resetDoomYaw))
{
doomYaw = r_viewpoint.Angles.Yaw.Degrees;
doomYaw = (float)r_viewpoint.Angles.Yaw.Degrees;
if (gamestate == GS_LEVEL && resetDoomYaw) {
resetDoomYaw = false;
}
@ -446,15 +462,20 @@ namespace s3d
{
if (player)
{
//Weapon firing tracking - Thanks Fishbiter!
//Weapon firing tracking - Thanks Fishbiter for the inspiration of how/where to use this!
{
player->mo->OverrideAttackPosDir = true;
player->mo->AttackPos.X = player->mo->X() + weaponoffset[0];
player->mo->AttackPos.Y = player->mo->Y() + weaponoffset[1];
player->mo->AttackPos.Z = player->mo->Z() + weaponoffset[2];
player->mo->AttackPos.X = player->mo->X() - (weaponoffset[0] * vr_vunits_per_meter);
player->mo->AttackPos.Y = player->mo->Y() + (weaponoffset[2] * vr_vunits_per_meter);
player->mo->AttackPos.Z = player->mo->Z() + ((hmdPosition[1] + weaponoffset[1] + vr_floor_offset) * vr_vunits_per_meter);
player->mo->AttackDir = DVector3(weaponangles[0], weaponangles[1], weaponangles[2]);
vec3_t angles;
VectorSet(angles, -GLRenderer->mAngles.Pitch.Degrees, (doomYaw - hmdorientation[YAW]) + weaponangles[YAW], 0);
vec3_t v_forward, v_right, v_up;
AngleVectors(angles, v_forward, v_right, v_up);
player->mo->AttackDir = MapAttackDir;//DVector3(v_forward[0], v_forward[1], v_forward[2]);
}
//Positional Movement

View file

@ -4495,12 +4495,10 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
// LAF_ABSOFFSET: Ignore the angle.
DVector3 tempos;
if (t1->player != NULL && t1->player->mo->OverrideAttackPosDir)
{
tempos = t1->player->mo->AttackPos;
direction = t1->player->mo->AttackDir;
direction = t1->player->mo->AttackDir(t1, angle, pitch);
}
else if (flags & LAF_ABSPOSITION)
{

View file

@ -6748,7 +6748,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, double x, double y, double z,
if (source->player != NULL && source->player->mo->OverrideAttackPosDir)
{
pos = source->player->mo->AttackPos;
DVector3 dir = source->player->mo->AttackDir;
DVector3 dir = source->player->mo->AttackDir(source, angle, pitch);
an = dir.Angle();
pitch = -dir.Pitch();
}