diff --git a/source/common/rendering/hwrenderer/data/hw_vrmodes.cpp b/source/common/rendering/hwrenderer/data/hw_vrmodes.cpp index f70882ee7..410926cd6 100644 --- a/source/common/rendering/hwrenderer/data/hw_vrmodes.cpp +++ b/source/common/rendering/hwrenderer/data/hw_vrmodes.cpp @@ -46,11 +46,14 @@ extern vec3_t hmdPosition; extern vec3_t hmdOrigin; extern vec3_t hmdorientation; +extern vec3_t weaponangles; float RazeXR_GetFOV(); void VR_GetMove(float *joy_forward, float *joy_side, float *hmd_forward, float *hmd_side, float *up, float *yaw, float *pitch, float *roll); +void get_weapon_pos_and_angle(float &x, float &y, float &z, float &pitch, float &yaw); + // Set up 3D-specific console variables: CVAR(Int, vr_mode, 15, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) @@ -78,6 +81,8 @@ CVAR(Bool, vr_secondary_button_mappings, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, vr_two_handed_weapons, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, vr_positional_tracking, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, vr_crouch_use_button, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, vr_6dof_weapons, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, vr_6dof_crosshair, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Float, vr_pickup_haptic_level, 0.2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Float, vr_quake_haptic_level, 0.8, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -274,21 +279,37 @@ VSMatrix VREyeInfo::GetPlayerSpriteProjection(int width, int height) const vr_hunits_per_meter(), -vr_hunits_per_meter()); - new_projection.rotate(-hmdorientation[ROLL], 0, 0, 1); + if (isDuke() && vr_6dof_weapons) + { + new_projection.rotate(-hmdorientation[PITCH], 1, 0, 0); + new_projection.rotate(-hmdorientation[ROLL], 0, 0, 1); - // hmd coordinates (meters) from ndc coordinates - // const float weapon_distance_meters = 0.55f; - // const float weapon_width_meters = 0.3f; - new_projection.translate(0.0, 0.0, 1.0); + float x, y, z, pitch, yaw; + get_weapon_pos_and_angle(x, y, z, pitch, yaw); + new_projection.translate(-x * weapon_stereo_effect, (z - hmdPosition[1]) * weapon_stereo_effect, -y * weapon_stereo_effect); - float weapon_scale = 0.7f; - new_projection.scale( - -weapon_scale, - weapon_scale, - -weapon_scale); + new_projection.rotate(weaponangles[YAW] - hmdorientation[YAW], 0, 1, 0); + new_projection.rotate(weaponangles[PITCH], 1, 0, 0); - // ndc coordinates from pixel coordinates - new_projection.translate(-1.0, 1.0, 0); + + float weapon_scale = 0.5f; + new_projection.scale(-weapon_scale, weapon_scale, -weapon_scale); + + // ndc coordinates from pixel coordinates + new_projection.translate(-1.5, 1.5, -0.5); + } + else + { + new_projection.rotate(-hmdorientation[ROLL], 0, 0, 1); + + new_projection.translate(0.0, 0.0, 1.0); + + float weapon_scale = 0.7f; + new_projection.scale(-weapon_scale, weapon_scale, -weapon_scale); + + // ndc coordinates from pixel coordinates + new_projection.translate(-1.0, 1.0, 0); + } new_projection.scale(2.0 / width, -2.0 / height, -1.0); VSMatrix proj = GetProjection(RazeXR_GetFOV(), ratio, fovratio); diff --git a/source/core/version.h b/source/core/version.h index b39036d07..de962bb43 100644 --- a/source/core/version.h +++ b/source/core/version.h @@ -44,7 +44,7 @@ const char *GetVersionString(); #define VERSIONSTR "1.7pre" -#define RAZEXR_VERSIONSTR "RazeXR 0.1.3" +#define RAZEXR_VERSIONSTR "RazeXR 0.1.4" // The version as seen in the Windows resource #define RC_FILEVERSION 1,6,9999,0 diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 3cf06df77..cde100998 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -278,6 +278,8 @@ enum STAT_LIGHT = 14, STAT_RAROR = 15, + STAT_AIM_SPRITE = 89, + STAT_TEMP = 99, STAT_DESTRUCT = 100, STAT_BOWLING = 105, diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index d015ed9b9..35f4feefb 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -65,7 +65,9 @@ void move_r(DDukeActor* i, int g_p, int g_x); void incur_damage_d(player_struct* p); void incur_damage_r(player_struct* p); void shoot_d(DDukeActor* i, int atwith, PClass* cls); +void shoot_d_override(DDukeActor* i, int atwith, PClass* cls); void shoot_r(DDukeActor* i, int atwith, PClass* cls); +void shoot_r_override(DDukeActor* i, int atwith, PClass* cls); void selectweapon_d(int snum, int j); void selectweapon_r(int snum, int j); int doincrements_d(player_struct* p); @@ -113,7 +115,8 @@ void SetDispatcher() move_d, incur_damage_d, - shoot_d, + //shoot_d, + shoot_d_override, selectweapon_d, doincrements_d, checkweapons_d, @@ -147,7 +150,8 @@ void SetDispatcher() move_r, incur_damage_r, - shoot_r, + //shoot_r, + shoot_r_override, selectweapon_r, doincrements_r, checkweapons_r, diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index c9921713b..512ced3ef 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -40,6 +40,10 @@ source as it is released. #include "dukeactor.h" void get_weapon_pos_and_angle(float &x, float &y, float &z, float &pitch, float &yaw); +float vr_hunits_per_meter(); + +EXTERN_CVAR(Bool, vr_6dof_weapons); +EXTERN_CVAR(Bool, vr_6dof_crosshair); BEGIN_DUKE_NS @@ -944,28 +948,32 @@ void shoot_d_override(DDukeActor* actor, int atwith, PClass *cls) { int l, j; int sx, sy, sz, sa, p, vel, zvel, x, dal; - player_struct backup; - if (actor->isPlayer()) + + float px, py, pz, pitch, yaw; + + DVector2 posXY; + if (actor->isPlayer() && vr_6dof_weapons) { -/* p = actor->PlayerIndex(); - { - float ax, y, z, pitch, yaw; - get_weapon_pos_and_angle(ax, y, z, pitch, yaw); - backup = ps[p]; - ps[p].pos.X += (ax * 16.0f); - ps[p].pos.Y += (y * -16.0f);; - ps[p].pos.Z += (z * -256); - ps[p].angle.ang = degang(-yaw); - ps[p].horizon.horiz = pitchhoriz(-pitch); - } - */ + get_weapon_pos_and_angle(px, py, pz, pitch, yaw); + + posXY = DVector2(px * vr_hunits_per_meter(), py * vr_hunits_per_meter()).Rotated(-DAngle90 + actor->spr.Angles.Yaw); + actor->spr.pos.X -= posXY.X; + actor->spr.pos.Y -= posXY.Y; + actor->spr.pos.Z -= (pz * vr_hunits_per_meter()) + actor->viewzoffset; + actor->spr.Angles.Yaw += DAngle::fromDeg(yaw); + actor->spr.Angles.Pitch -= DAngle::fromDeg(pitch); } + shoot_d(actor, atwith, cls); -/* if (actor->isPlayer()) + + if (actor->isPlayer() && vr_6dof_weapons) { - ps[p] = backup; + actor->spr.pos.X += posXY.X; + actor->spr.pos.Y += posXY.Y; + actor->spr.pos.Z += (pz * vr_hunits_per_meter()) + actor->viewzoffset; + actor->spr.Angles.Yaw -= DAngle::fromDeg(yaw); + actor->spr.Angles.Pitch += DAngle::fromDeg(pitch); } - */ } void shoot_d(DDukeActor* actor, int atwith, PClass *cls) @@ -2544,6 +2552,57 @@ static void processweapon(int snum, ESyncBits actions) auto pact = p->GetActor(); int shrunk = (pact->spr.scale.Y < 0.5); + //Aiming decal?! + if (pact) + { + if (p->curr_weapon != KNEE_WEAPON) + { + if (pact->isPlayer() && vr_6dof_weapons && vr_6dof_crosshair) + { + float x, y, z, pitch, yaw; + get_weapon_pos_and_angle(x, y, z, pitch, yaw); + + DAngle sang = pact->spr.Angles.Yaw + DAngle::fromDeg(yaw); + + DVector3 spos = pact->spr.pos.plusZ(-(z * vr_hunits_per_meter())); + DVector2 posXY(x * vr_hunits_per_meter(), y * vr_hunits_per_meter()); + posXY = posXY.Rotated(-DAngle90 + pact->spr.Angles.Yaw); + spos.X -= posXY.X; + spos.Y -= posXY.Y; + + HitInfo hit{}; + + auto sectp = pact->sector(); + double vel = 1024, zvel = 0; + setFreeAimVelocity(vel, zvel, p->Angles.getPitchWithView() - DAngle::fromDeg(pitch), 16.); + + pact->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; + hitscan(spos, sectp, DVector3(sang.ToVector() * vel, zvel * 64), hit, CLIPMASK1); + pact->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; + + if (hit.hitSector != nullptr) + { + double length = (hit.hitpos.XY() - pact->spr.pos.XY()).Length(); + + //Update the existing aiming sprites if there is one + DukeStatIterator it(STAT_AIM_SPRITE); + DDukeActor* spark = it.Next(); + if (spark) + { + //update position + SetActorZ(spark, hit.hitpos); + spark->spr.scale = DVector2(0.1 + length/512.0, 0.1 + length/512.0); + } + else + { + CreateActor(hit.hitSector, hit.hitpos, DTILE_CROSSHAIR, -15, DVector2(0.1, 0.1), sang, 0., 0., pact, STAT_AIM_SPRITE); + } + } + } + } + } + + if (isNamWW2GI() && (actions & SB_HOLSTER)) // 'Holster Weapon { if (isWW2GI()) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index ae740a06f..cbfdd9c74 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -31,6 +31,13 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms #include "names_r.h" #include "mapinfo.h" #include "dukeactor.h" +#include "names_d.h" + +void get_weapon_pos_and_angle(float &x, float &y, float &z, float &pitch, float &yaw); +float vr_hunits_per_meter(); + +EXTERN_CVAR(Bool, vr_6dof_weapons); +EXTERN_CVAR(Bool, vr_6dof_crosshair); BEGIN_DUKE_NS @@ -765,28 +772,32 @@ void shoot_r_override(DDukeActor* actor, int atwith, PClass *cls) { int l, j; int sx, sy, sz, sa, p, vel, zvel, x, dal; - player_struct backup; - if (actor->isPlayer()) + + float px, py, pz, pitch, yaw; + + DVector2 posXY; + if (actor->isPlayer() && vr_6dof_weapons) { -/* p = actor->PlayerIndex(); - { - float ax, y, z, pitch, yaw; - get_weapon_pos_and_angle(ax, y, z, pitch, yaw); - backup = ps[p]; - ps[p].pos.X += (ax * 16.0f); - ps[p].pos.Y += (y * -16.0f);; - ps[p].pos.Z += (z * -256); - ps[p].angle.ang = degang(-yaw); - ps[p].horizon.horiz = pitchhoriz(-pitch); - } - */ + get_weapon_pos_and_angle(px, py, pz, pitch, yaw); + + posXY = DVector2(px * vr_hunits_per_meter(), py * vr_hunits_per_meter()).Rotated(-DAngle90 + actor->spr.Angles.Yaw); + actor->spr.pos.X -= posXY.X; + actor->spr.pos.Y -= posXY.Y; + actor->spr.pos.Z -= (pz * vr_hunits_per_meter()) + actor->viewzoffset; + actor->spr.Angles.Yaw += DAngle::fromDeg(yaw); + actor->spr.Angles.Pitch -= DAngle::fromDeg(pitch); } + shoot_r(actor, atwith, cls); -/* if (actor->isPlayer()) + + if (actor->isPlayer() && vr_6dof_weapons) { - ps[p] = backup; + actor->spr.pos.X += posXY.X; + actor->spr.pos.Y += posXY.Y; + actor->spr.pos.Z += (pz * vr_hunits_per_meter()) + actor->viewzoffset; + actor->spr.Angles.Yaw -= DAngle::fromDeg(yaw); + actor->spr.Angles.Pitch += DAngle::fromDeg(pitch); } - */ } void shoot_r(DDukeActor* actor, int atwith, PClass* cls) @@ -3155,6 +3166,56 @@ static void processweapon(int snum, ESyncBits actions, sectortype* psectp) auto pact = p->GetActor(); int shrunk = (pact->spr.scale.Y < 0.125); + //Aiming decal?! + if (pact) + { + if (p->curr_weapon != KNEE_WEAPON) + { + if (pact->isPlayer() && vr_6dof_weapons && vr_6dof_crosshair) + { + float x, y, z, pitch, yaw; + get_weapon_pos_and_angle(x, y, z, pitch, yaw); + + DAngle sang = pact->spr.Angles.Yaw + DAngle::fromDeg(yaw); + + DVector3 spos = pact->spr.pos.plusZ(-(z * vr_hunits_per_meter())); + DVector2 posXY(x * vr_hunits_per_meter(), y * vr_hunits_per_meter()); + posXY = posXY.Rotated(-DAngle90 + pact->spr.Angles.Yaw); + spos.X -= posXY.X; + spos.Y -= posXY.Y; + + HitInfo hit{}; + + auto sectp = pact->sector(); + double vel = 1024, zvel = 0; + setFreeAimVelocity(vel, zvel, p->Angles.getPitchWithView() - DAngle::fromDeg(pitch), 16.); + + pact->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; + hitscan(spos, sectp, DVector3(sang.ToVector() * vel, zvel * 64), hit, CLIPMASK1); + pact->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; + + if (hit.hitSector != nullptr) + { + double length = (hit.hitpos.XY() - pact->spr.pos.XY()).Length(); + + //Update the existing aiming sprites if there is one + DukeStatIterator it(STAT_AIM_SPRITE); + DDukeActor* spark = it.Next(); + if (spark) + { + //update position + SetActorZ(spark, hit.hitpos); + spark->spr.scale = DVector2(0.1 + length/512.0, 0.1 + length/512.0); + } + else + { + CreateActor(hit.hitSector, hit.hitpos, DTILE_CROSSHAIR, -15, DVector2(0.1, 0.1), sang, 0., 0., pact, STAT_AIM_SPRITE); + } + } + } + } + } + if (p->detonate_count > 0) { if (ud.god) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 5cda49c94..950279a1c 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -554,6 +554,8 @@ OptionMenu "VROptionsMenu" protected Slider "Height Adjust", "vr_height_adjust", 0.0, 1.0, 0.1 StaticText "" Option "Positional Tracking", "vr_positional_tracking", "YesNo" + Option "6DoF Weapons (Duke Only)", "vr_6dof_weapons", "YesNo" + Option "VR Crosshair (Duke Only)", "vr_6dof_crosshair", "YesNo" StaticText "" StaticText "HUD"