Add use haptic feedback; Fix use in 3rd person mode

This commit is contained in:
Petr Bartos 2023-04-01 18:48:42 +02:00
parent fe9891f8db
commit eec46c183d
8 changed files with 81 additions and 23 deletions

View file

@ -513,7 +513,8 @@ void VR_HapticEvent(const char* event, int position, int flags, int intensity, f
{ {
TBXR_Vibrate(400, weaponFireChannel, 1.0); TBXR_Vibrate(400, weaponFireChannel, 1.0);
} }
else if (strcmp(event, "selector_icon") == 0) else if (strcmp(event, "selector_icon") == 0 ||
strcmp(event, "use_button") == 0 )
{ {
//Quick blip //Quick blip
TBXR_Vibrate(50, flags, 1.0); TBXR_Vibrate(50, flags, 1.0);

View file

@ -10,6 +10,7 @@
#define USE_GESTURE_OFF_HAND 1 #define USE_GESTURE_OFF_HAND 1
#define USE_GESTURE_WEAPON_HAND 2 #define USE_GESTURE_WEAPON_HAND 2
#define USE_HAPTIC_FEEDBACK_DELAY 500
typedef struct { typedef struct {
bool loaded; bool loaded;
@ -102,6 +103,7 @@ typedef struct {
float maxHeight; float maxHeight;
float curHeight; float curHeight;
int useGestureState; int useGestureState;
int useHapticFeedbackTime[2];
} vr_client_info_t; } vr_client_info_t;

View file

@ -29,6 +29,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "g_vehicles.h" #include "g_vehicles.h"
#include "b_local.h" #include "b_local.h"
#include "g_navigator.h" #include "g_navigator.h"
#include <JKXR/VrClientInfo.h>
#ifdef _DEBUG #ifdef _DEBUG
#include <float.h> #include <float.h>
@ -1354,7 +1355,7 @@ void ClientImpacts( gentity_t *ent, pmove_t *pm ) {
const float TOUCH_DISTANCE = 1.0f; const float TOUCH_DISTANCE = 1.0f;
const vec3_t TOUCH_RANGE = { 4, 4, 4 }; const vec3_t TOUCH_RANGE = { 4, 4, 4 };
void G_TouchTriggersWithHand( gentity_t *ent, vec3_t src, vec3_t vf ) { void G_TouchTriggersWithHand( bool offHand, gentity_t *ent, vec3_t src, vec3_t vf ) {
vec3_t dest, mins, maxs; vec3_t dest, mins, maxs;
gentity_t *touch[MAX_GENTITIES], *hit; gentity_t *touch[MAX_GENTITIES], *hit;
qboolean touched[MAX_GENTITIES]; qboolean touched[MAX_GENTITIES];
@ -1396,6 +1397,11 @@ void G_TouchTriggersWithHand( gentity_t *ent, vec3_t src, vec3_t vf ) {
touched[i] = qtrue; touched[i] = qtrue;
memset( &trace, 0, sizeof(trace) ); memset( &trace, 0, sizeof(trace) );
if ( hit->e_TouchFunc != touchF_NULL ) { if ( hit->e_TouchFunc != touchF_NULL ) {
int channel = vr->right_handed != offHand ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + USE_HAPTIC_FEEDBACK_DELAY;
}
GEntity_TouchFunc(hit, ent, &trace); GEntity_TouchFunc(hit, ent, &trace);
} }
} }
@ -1540,13 +1546,13 @@ void G_TouchTriggersLerped( gentity_t *ent ) {
vec3_t src, angles, vf; vec3_t src, angles, vf;
BG_CalculateVRWeaponPosition(src, angles); BG_CalculateVRWeaponPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
G_TouchTriggersWithHand( ent, src, vf ); G_TouchTriggersWithHand( false, ent, src, vf );
} }
if( ent->client->usercmd.buttons & BUTTON_ALT_USE ) { if( ent->client->usercmd.buttons & BUTTON_ALT_USE ) {
vec3_t src, angles, vf; vec3_t src, angles, vf;
BG_CalculateVROffHandPosition(src, angles); BG_CalculateVROffHandPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
G_TouchTriggersWithHand( ent, src, vf ); G_TouchTriggersWithHand( true, ent, src, vf );
} }
} }
} }

View file

@ -264,9 +264,9 @@ void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace )
if ( other->client ) if ( other->client )
{ {
if ( (other->client->ps.clientNum == 0) && (self->spawnflags & 4) ) if ( (other->client->ps.clientNum == 0) && (self->spawnflags & 4) && !thirdPersonActive )
{ {
// In case of USE_BUTTON, check facing by controller and not by head // In case of USE_BUTTON, check facing by controller and not by head (if not in 3rd person)
vec3_t origin, angles; vec3_t origin, angles;
BG_CalculateVRWeaponPosition(origin, angles); BG_CalculateVRWeaponPosition(origin, angles);
AngleVectors( angles, forward, NULL, NULL ); AngleVectors( angles, forward, NULL, NULL );
@ -340,6 +340,13 @@ void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace )
if ( self->spawnflags & 4 ) if ( self->spawnflags & 4 )
{//USE_BUTTON {//USE_BUTTON
if (other->client->ps.clientNum == 0 && !useGestureAllowed) {
int channel = vr->right_handed ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + + USE_HAPTIC_FEEDBACK_DELAY;
}
}
NPC_SetAnim( other, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); NPC_SetAnim( other, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
/* /*
if ( !VectorLengthSquared( other->client->ps.velocity ) && !PM_CrouchAnim( other->client->ps.legsAnim ) ) if ( !VectorLengthSquared( other->client->ps.velocity ) && !PM_CrouchAnim( other->client->ps.legsAnim ) )

View file

@ -1759,7 +1759,7 @@ Try and use an entity in the world, directly ahead of us
#define USE_DISTANCE_BUTTON 64.0f #define USE_DISTANCE_BUTTON 64.0f
#define USE_DISTANCE_GESTURE 16.0f #define USE_DISTANCE_GESTURE 16.0f
void TryUse_Internal( gentity_t *ent, vec3_t src, vec3_t vf ) void TryUse_Internal( bool offHand, gentity_t *ent, vec3_t src, vec3_t vf )
{ {
gentity_t *target; gentity_t *target;
trace_t trace; trace_t trace;
@ -1808,6 +1808,13 @@ void TryUse_Internal( gentity_t *ent, vec3_t src, vec3_t vf )
} }
*/ */
//ent->client->ps.weaponTime = ent->client->ps.torsoAnimTimer; //ent->client->ps.weaponTime = ent->client->ps.torsoAnimTimer;
if (ent->client->ps.clientNum == 0) {
int channel = vr->right_handed != offHand ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + + USE_HAPTIC_FEEDBACK_DELAY;
}
}
GEntity_UseFunc( target, ent, ent ); GEntity_UseFunc( target, ent, ent );
return; return;
} }
@ -1818,6 +1825,13 @@ void TryUse_Internal( gentity_t *ent, vec3_t src, vec3_t vf )
&& (target->client->playerTeam == ent->client->playerTeam || target->client->playerTeam == TEAM_NEUTRAL) && (target->client->playerTeam == ent->client->playerTeam || target->client->playerTeam == TEAM_NEUTRAL)
&& !(target->NPC->scriptFlags&SCF_NO_RESPONSE) ) && !(target->NPC->scriptFlags&SCF_NO_RESPONSE) )
{ {
if (ent->client->ps.clientNum == 0) {
int channel = vr->right_handed != offHand ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + + USE_HAPTIC_FEEDBACK_DELAY;
}
}
NPC_UseResponse ( target, ent, qfalse ); NPC_UseResponse ( target, ent, qfalse );
return; return;
} }
@ -1847,15 +1861,16 @@ void TryUse( gentity_t *ent ) {
return; return;
}*/ }*/
bool thirdPersonActive = gi.cvar("cg_thirdPerson", "0", CVAR_TEMP)->integer;
vec3_t src, angles, vf; vec3_t src, angles, vf;
if (ent->client->ps.clientNum == 0) { if (ent->client->ps.clientNum == 0 && !thirdPersonActive) {
BG_CalculateVRWeaponPosition(src, angles); BG_CalculateVRWeaponPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
TryUse_Internal(ent, src, vf); TryUse_Internal(false, ent, src, vf);
} else { } else {
VectorCopy(ent->client->renderInfo.eyePoint, src); VectorCopy(ent->client->renderInfo.eyePoint, src);
AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL); AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL);
TryUse_Internal(ent, src, vf); TryUse_Internal(false, ent, src, vf);
} }
} }
@ -1881,11 +1896,11 @@ void TryAltUse( gentity_t *ent ) {
if (ent->client->ps.clientNum == 0) { if (ent->client->ps.clientNum == 0) {
BG_CalculateVROffHandPosition(src, angles); BG_CalculateVROffHandPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
TryUse_Internal(ent, src, vf); TryUse_Internal(true, ent, src, vf);
} else { } else {
VectorCopy(ent->client->renderInfo.eyePoint, src); VectorCopy(ent->client->renderInfo.eyePoint, src);
AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL); AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL);
TryUse_Internal(ent, src, vf); TryUse_Internal(false, ent, src, vf);
} }
} }

View file

@ -825,7 +825,7 @@ void ClientImpacts( gentity_t *ent, pmove_t *pm ) {
const float TOUCH_DISTANCE = 1.0f; const float TOUCH_DISTANCE = 1.0f;
const vec3_t TOUCH_RANGE = { 4, 4, 4 }; const vec3_t TOUCH_RANGE = { 4, 4, 4 };
void G_TouchTriggersWithHand( gentity_t *ent, vec3_t src, vec3_t vf ) { void G_TouchTriggersWithHand( bool offHand, gentity_t *ent, vec3_t src, vec3_t vf ) {
vec3_t dest, mins, maxs; vec3_t dest, mins, maxs;
gentity_t *touch[MAX_GENTITIES], *hit; gentity_t *touch[MAX_GENTITIES], *hit;
qboolean touched[MAX_GENTITIES]; qboolean touched[MAX_GENTITIES];
@ -867,6 +867,11 @@ void G_TouchTriggersWithHand( gentity_t *ent, vec3_t src, vec3_t vf ) {
touched[i] = qtrue; touched[i] = qtrue;
memset( &trace, 0, sizeof(trace) ); memset( &trace, 0, sizeof(trace) );
if ( hit->e_TouchFunc != touchF_NULL ) { if ( hit->e_TouchFunc != touchF_NULL ) {
int channel = vr->right_handed != offHand ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + USE_HAPTIC_FEEDBACK_DELAY;
}
GEntity_TouchFunc(hit, ent, &trace); GEntity_TouchFunc(hit, ent, &trace);
} }
} }
@ -1003,13 +1008,13 @@ void G_TouchTriggersLerped( gentity_t *ent ) {
vec3_t src, angles, vf; vec3_t src, angles, vf;
BG_CalculateVRWeaponPosition(src, angles); BG_CalculateVRWeaponPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
G_TouchTriggersWithHand( ent, src, vf ); G_TouchTriggersWithHand(false, ent, src, vf );
} }
if( ent->client->usercmd.buttons & BUTTON_ALT_USE ) { if( ent->client->usercmd.buttons & BUTTON_ALT_USE ) {
vec3_t src, angles, vf; vec3_t src, angles, vf;
BG_CalculateVROffHandPosition(src, angles); BG_CalculateVROffHandPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
G_TouchTriggersWithHand( ent, src, vf ); G_TouchTriggersWithHand(true, ent, src, vf );
} }
} }
} }

View file

@ -234,9 +234,9 @@ void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace )
if ( other->client ) if ( other->client )
{ {
if ( (other->client->ps.clientNum == 0) && (self->spawnflags & 4) ) if ( (other->client->ps.clientNum == 0) && (self->spawnflags & 4) && !thirdPersonActive )
{ {
// In case of USE_BUTTON, check facing by controller and not by head // In case of USE_BUTTON, check facing by controller and not by head (if not in 3rd person)
vec3_t origin, angles; vec3_t origin, angles;
BG_CalculateVRWeaponPosition(origin, angles); BG_CalculateVRWeaponPosition(origin, angles);
AngleVectors( angles, forward, NULL, NULL ); AngleVectors( angles, forward, NULL, NULL );
@ -323,6 +323,13 @@ void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace )
if ( self->spawnflags & 4 ) if ( self->spawnflags & 4 )
{//USE_BUTTON {//USE_BUTTON
if (other->client->ps.clientNum == 0 && !useGestureAllowed) {
int channel = vr->right_handed ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + + USE_HAPTIC_FEEDBACK_DELAY;
}
}
NPC_SetAnim( other, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); NPC_SetAnim( other, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
/* /*
if ( !VectorLengthSquared( other->client->ps.velocity ) && !PM_CrouchAnim( other->client->ps.legsAnim ) ) if ( !VectorLengthSquared( other->client->ps.velocity ) && !PM_CrouchAnim( other->client->ps.legsAnim ) )

View file

@ -1525,7 +1525,7 @@ Try and use an entity in the world, directly ahead of us
#define USE_DISTANCE_BUTTON 64.0f #define USE_DISTANCE_BUTTON 64.0f
#define USE_DISTANCE_GESTURE 16.0f #define USE_DISTANCE_GESTURE 16.0f
void TryUse_Internal( gentity_t *ent, vec3_t src, vec3_t vf ) { void TryUse_Internal( bool offHand, gentity_t *ent, vec3_t src, vec3_t vf ) {
gentity_t *target; gentity_t *target;
trace_t trace; trace_t trace;
vec3_t dest; vec3_t dest;
@ -1565,6 +1565,13 @@ void TryUse_Internal( gentity_t *ent, vec3_t src, vec3_t vf ) {
} }
*/ */
//ent->client->ps.weaponTime = ent->client->ps.torsoAnimTimer; //ent->client->ps.weaponTime = ent->client->ps.torsoAnimTimer;
if (ent->client->ps.clientNum == 0) {
int channel = vr->right_handed != offHand ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + + USE_HAPTIC_FEEDBACK_DELAY;
}
}
GEntity_UseFunc( target, ent, ent ); GEntity_UseFunc( target, ent, ent );
return; return;
} }
@ -1575,6 +1582,13 @@ void TryUse_Internal( gentity_t *ent, vec3_t src, vec3_t vf ) {
&& (target->client->playerTeam == ent->client->playerTeam || target->client->playerTeam == TEAM_NEUTRAL) && (target->client->playerTeam == ent->client->playerTeam || target->client->playerTeam == TEAM_NEUTRAL)
&& !(target->NPC->scriptFlags&SCF_NO_RESPONSE) ) && !(target->NPC->scriptFlags&SCF_NO_RESPONSE) )
{ {
if (ent->client->ps.clientNum == 0) {
int channel = vr->right_handed != offHand ? 1 : 2;
if (level.time > vr->useHapticFeedbackTime[channel - 1]) {
cgi_HapticEvent("use_button", 0, channel, 60, 0, 0);
vr->useHapticFeedbackTime[channel - 1] = level.time + + USE_HAPTIC_FEEDBACK_DELAY;
}
}
NPC_UseResponse ( target, ent, qfalse ); NPC_UseResponse ( target, ent, qfalse );
return; return;
} }
@ -1593,15 +1607,16 @@ void TryUse( gentity_t *ent ) {
return; return;
} }
bool thirdPersonActive = gi.cvar("cg_thirdPerson", "0", CVAR_TEMP)->integer;
vec3_t src, angles, vf; vec3_t src, angles, vf;
if (ent->client->ps.clientNum == 0) { if (ent->client->ps.clientNum == 0 && !thirdPersonActive) {
BG_CalculateVRWeaponPosition(src, angles); BG_CalculateVRWeaponPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
TryUse_Internal(ent, src, vf); TryUse_Internal(false, ent, src, vf);
} else { } else {
VectorCopy(ent->client->renderInfo.eyePoint, src); VectorCopy(ent->client->renderInfo.eyePoint, src);
AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL); AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL);
TryUse_Internal(ent, src, vf); TryUse_Internal(false, ent, src, vf);
} }
} }
@ -1616,11 +1631,11 @@ void TryAltUse( gentity_t *ent ) {
if (ent->client->ps.clientNum == 0) { if (ent->client->ps.clientNum == 0) {
BG_CalculateVROffHandPosition(src, angles); BG_CalculateVROffHandPosition(src, angles);
AngleVectors( angles, vf, NULL, NULL ); AngleVectors( angles, vf, NULL, NULL );
TryUse_Internal(ent, src, vf); TryUse_Internal(true, ent, src, vf);
} else { } else {
VectorCopy(ent->client->renderInfo.eyePoint, src); VectorCopy(ent->client->renderInfo.eyePoint, src);
AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL); AngleVectors(ent->client->ps.viewangles, vf, NULL, NULL);
TryUse_Internal(ent, src, vf); TryUse_Internal(false, ent, src, vf);
} }
} }