True 6DoF weapons and aiming crosshair (Duke Only)

This commit is contained in:
Simon 2023-02-08 22:48:47 +00:00
parent 00d07de8a7
commit 82b83af956
7 changed files with 198 additions and 49 deletions

View file

@ -46,11 +46,14 @@
extern vec3_t hmdPosition; extern vec3_t hmdPosition;
extern vec3_t hmdOrigin; extern vec3_t hmdOrigin;
extern vec3_t hmdorientation; extern vec3_t hmdorientation;
extern vec3_t weaponangles;
float RazeXR_GetFOV(); float RazeXR_GetFOV();
void VR_GetMove(float *joy_forward, float *joy_side, float *hmd_forward, float *hmd_side, float *up, void VR_GetMove(float *joy_forward, float *joy_side, float *hmd_forward, float *hmd_side, float *up,
float *yaw, float *pitch, float *roll); 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: // Set up 3D-specific console variables:
CVAR(Int, vr_mode, 15, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) 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_two_handed_weapons, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, vr_positional_tracking, 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_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_pickup_haptic_level, 0.2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Float, vr_quake_haptic_level, 0.8, 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(),
-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 float x, y, z, pitch, yaw;
// const float weapon_distance_meters = 0.55f; get_weapon_pos_and_angle(x, y, z, pitch, yaw);
// const float weapon_width_meters = 0.3f; new_projection.translate(-x * weapon_stereo_effect, (z - hmdPosition[1]) * weapon_stereo_effect, -y * weapon_stereo_effect);
new_projection.translate(0.0, 0.0, 1.0);
float weapon_scale = 0.7f; new_projection.rotate(weaponangles[YAW] - hmdorientation[YAW], 0, 1, 0);
new_projection.scale( new_projection.rotate(weaponangles[PITCH], 1, 0, 0);
-weapon_scale,
weapon_scale,
-weapon_scale);
// 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); new_projection.scale(2.0 / width, -2.0 / height, -1.0);
VSMatrix proj = GetProjection(RazeXR_GetFOV(), ratio, fovratio); VSMatrix proj = GetProjection(RazeXR_GetFOV(), ratio, fovratio);

View file

@ -44,7 +44,7 @@ const char *GetVersionString();
#define VERSIONSTR "1.7pre" #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 // The version as seen in the Windows resource
#define RC_FILEVERSION 1,6,9999,0 #define RC_FILEVERSION 1,6,9999,0

View file

@ -278,6 +278,8 @@ enum
STAT_LIGHT = 14, STAT_LIGHT = 14,
STAT_RAROR = 15, STAT_RAROR = 15,
STAT_AIM_SPRITE = 89,
STAT_TEMP = 99, STAT_TEMP = 99,
STAT_DESTRUCT = 100, STAT_DESTRUCT = 100,
STAT_BOWLING = 105, STAT_BOWLING = 105,

View file

@ -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_d(player_struct* p);
void incur_damage_r(player_struct* p); void incur_damage_r(player_struct* p);
void shoot_d(DDukeActor* i, int atwith, PClass* cls); 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(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_d(int snum, int j);
void selectweapon_r(int snum, int j); void selectweapon_r(int snum, int j);
int doincrements_d(player_struct* p); int doincrements_d(player_struct* p);
@ -113,7 +115,8 @@ void SetDispatcher()
move_d, move_d,
incur_damage_d, incur_damage_d,
shoot_d, //shoot_d,
shoot_d_override,
selectweapon_d, selectweapon_d,
doincrements_d, doincrements_d,
checkweapons_d, checkweapons_d,
@ -147,7 +150,8 @@ void SetDispatcher()
move_r, move_r,
incur_damage_r, incur_damage_r,
shoot_r, //shoot_r,
shoot_r_override,
selectweapon_r, selectweapon_r,
doincrements_r, doincrements_r,
checkweapons_r, checkweapons_r,

View file

@ -40,6 +40,10 @@ source as it is released.
#include "dukeactor.h" #include "dukeactor.h"
void get_weapon_pos_and_angle(float &x, float &y, float &z, float &pitch, float &yaw); 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 BEGIN_DUKE_NS
@ -944,28 +948,32 @@ void shoot_d_override(DDukeActor* actor, int atwith, PClass *cls)
{ {
int l, j; int l, j;
int sx, sy, sz, sa, p, vel, zvel, x, dal; 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(); get_weapon_pos_and_angle(px, py, pz, pitch, yaw);
{
float ax, y, z, pitch, yaw; posXY = DVector2(px * vr_hunits_per_meter(), py * vr_hunits_per_meter()).Rotated(-DAngle90 + actor->spr.Angles.Yaw);
get_weapon_pos_and_angle(ax, y, z, pitch, yaw); actor->spr.pos.X -= posXY.X;
backup = ps[p]; actor->spr.pos.Y -= posXY.Y;
ps[p].pos.X += (ax * 16.0f); actor->spr.pos.Z -= (pz * vr_hunits_per_meter()) + actor->viewzoffset;
ps[p].pos.Y += (y * -16.0f);; actor->spr.Angles.Yaw += DAngle::fromDeg(yaw);
ps[p].pos.Z += (z * -256); actor->spr.Angles.Pitch -= DAngle::fromDeg(pitch);
ps[p].angle.ang = degang(-yaw);
ps[p].horizon.horiz = pitchhoriz(-pitch);
}
*/
} }
shoot_d(actor, atwith, cls); 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) void shoot_d(DDukeActor* actor, int atwith, PClass *cls)
@ -2544,6 +2552,57 @@ static void processweapon(int snum, ESyncBits actions)
auto pact = p->GetActor(); auto pact = p->GetActor();
int shrunk = (pact->spr.scale.Y < 0.5); 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 (isNamWW2GI() && (actions & SB_HOLSTER)) // 'Holster Weapon
{ {
if (isWW2GI()) if (isWW2GI())

View file

@ -31,6 +31,13 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
#include "names_r.h" #include "names_r.h"
#include "mapinfo.h" #include "mapinfo.h"
#include "dukeactor.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 BEGIN_DUKE_NS
@ -765,28 +772,32 @@ void shoot_r_override(DDukeActor* actor, int atwith, PClass *cls)
{ {
int l, j; int l, j;
int sx, sy, sz, sa, p, vel, zvel, x, dal; 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(); get_weapon_pos_and_angle(px, py, pz, pitch, yaw);
{
float ax, y, z, pitch, yaw; posXY = DVector2(px * vr_hunits_per_meter(), py * vr_hunits_per_meter()).Rotated(-DAngle90 + actor->spr.Angles.Yaw);
get_weapon_pos_and_angle(ax, y, z, pitch, yaw); actor->spr.pos.X -= posXY.X;
backup = ps[p]; actor->spr.pos.Y -= posXY.Y;
ps[p].pos.X += (ax * 16.0f); actor->spr.pos.Z -= (pz * vr_hunits_per_meter()) + actor->viewzoffset;
ps[p].pos.Y += (y * -16.0f);; actor->spr.Angles.Yaw += DAngle::fromDeg(yaw);
ps[p].pos.Z += (z * -256); actor->spr.Angles.Pitch -= DAngle::fromDeg(pitch);
ps[p].angle.ang = degang(-yaw);
ps[p].horizon.horiz = pitchhoriz(-pitch);
}
*/
} }
shoot_r(actor, atwith, cls); 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) 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(); auto pact = p->GetActor();
int shrunk = (pact->spr.scale.Y < 0.125); 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 (p->detonate_count > 0)
{ {
if (ud.god) if (ud.god)

View file

@ -554,6 +554,8 @@ OptionMenu "VROptionsMenu" protected
Slider "Height Adjust", "vr_height_adjust", 0.0, 1.0, 0.1 Slider "Height Adjust", "vr_height_adjust", 0.0, 1.0, 0.1
StaticText "" StaticText ""
Option "Positional Tracking", "vr_positional_tracking", "YesNo" 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 ""
StaticText "HUD" StaticText "HUD"