From 348bd46f6297bb2805fc2bf637bf6c3267557a18 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 2 Feb 2023 22:53:34 +0000 Subject: [PATCH] Support for first person sabers - including dual wield and two-handed needs more work, but going well --- Projects/Android/jni/JKVR/VrClientInfo.h | 1 + Projects/Android/jni/JKVR/VrInputDefault.cpp | 1 + .../Android/jni/JKVR/VrInputWeaponAlign.cpp | 3 +- .../jni/OpenJK/code/cgame/cg_players.cpp | 131 +++++++++++++----- .../Android/jni/OpenJK/code/cgame/cg_view.cpp | 1 + .../jni/OpenJK/code/cgame/cg_weapons.cpp | 15 +- .../Android/jni/OpenJK/code/game/bg_local.h | 2 +- .../Android/jni/OpenJK/code/game/bg_misc.cpp | 11 +- .../jni/OpenJK/code/qcommon/q_shared.h | 2 + 9 files changed, 123 insertions(+), 44 deletions(-) diff --git a/Projects/Android/jni/JKVR/VrClientInfo.h b/Projects/Android/jni/JKVR/VrClientInfo.h index 990a979..5d7a79a 100644 --- a/Projects/Android/jni/JKVR/VrClientInfo.h +++ b/Projects/Android/jni/JKVR/VrClientInfo.h @@ -75,6 +75,7 @@ typedef struct { vec3_t offhandangles; vec3_t offhandangles_last; // Don't use this, it is just for calculating delta! vec3_t offhandangles_delta; + vec3_t offhandangles_saber; vec3_t offhandposition[5]; // store last 5 vec3_t offhandoffset; diff --git a/Projects/Android/jni/JKVR/VrInputDefault.cpp b/Projects/Android/jni/JKVR/VrInputDefault.cpp index bf2a4cc..d3e3a61 100644 --- a/Projects/Android/jni/JKVR/VrInputDefault.cpp +++ b/Projects/Android/jni/JKVR/VrInputDefault.cpp @@ -97,6 +97,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, if (vr.saberBlockDebounce < cl.serverTime) { rotation[PITCH] = 45; QuatToYawPitchRoll(pWeapon->Pose.orientation, rotation, vr.weaponangles_saber); + QuatToYawPitchRoll(pOff->Pose.orientation, rotation, vr.offhandangles_saber); } rotation[PITCH] = vr_weapon_pitchadjust->value; QuatToYawPitchRoll(pWeapon->Pose.orientation, rotation, vr.weaponangles); diff --git a/Projects/Android/jni/JKVR/VrInputWeaponAlign.cpp b/Projects/Android/jni/JKVR/VrInputWeaponAlign.cpp index da660bd..4430d41 100644 --- a/Projects/Android/jni/JKVR/VrInputWeaponAlign.cpp +++ b/Projects/Android/jni/JKVR/VrInputWeaponAlign.cpp @@ -43,8 +43,9 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote { //Set gun angles - We need to calculate all those we might need (including adjustments) for the client to then take its pick vec3_t rotation = {0}; - rotation[PITCH] = 10; + rotation[PITCH] = 45; QuatToYawPitchRoll(pDominantTracking->Pose.orientation, rotation, vr.weaponangles_saber); + QuatToYawPitchRoll(pOffTracking->Pose.orientation, rotation, vr.offhandangles_saber); rotation[PITCH] = vr_weapon_pitchadjust->value; QuatToYawPitchRoll(pDominantTracking->Pose.orientation, rotation, vr.weaponangles); diff --git a/Projects/Android/jni/OpenJK/code/cgame/cg_players.cpp b/Projects/Android/jni/OpenJK/code/cgame/cg_players.cpp index 2298b1b..a599d4c 100644 --- a/Projects/Android/jni/OpenJK/code/cgame/cg_players.cpp +++ b/Projects/Android/jni/OpenJK/code/cgame/cg_players.cpp @@ -6118,6 +6118,21 @@ Ghoul2 Insert Start gi.G2API_GiveMeVectorFromMatrix(boltMatrix, NEGATIVE_X, axis_[0]);//front (was NEGATIVE_Y, but the md3->glm exporter screws up this tag somethin' awful) gi.G2API_GiveMeVectorFromMatrix(boltMatrix, NEGATIVE_Y, axis_[1]);//right gi.G2API_GiveMeVectorFromMatrix(boltMatrix, POSITIVE_Z, axis_[2]);//up + + if (!cent->gent->client->ps.saberInFlight && + CG_getPlayer1stPersonSaber(cent) && + cent->gent->client->ps.saberLockEnemy == ENTITYNUM_NONE) + { + vec3_t angles; + BG_CalculateVRSaberPosition(saberNum, org_, angles); + AnglesToAxis(angles, axis_); + if (bladeNum == 1) + { + VectorSubtract( vec3_origin, axis_[0], axis_[0] ); + } + float dist = (cent->gent->client->ps.saber[saberNum].numBlades > 1) ? 12.0f : 5.5f; + VectorMA(org_, dist, axis_[0], org_); + } } //Now figure out where this info will be next frame @@ -6603,10 +6618,7 @@ Ghoul2 Insert End */ if ( !client->ps.saber[saberNum].blade[bladeNum].active && client->ps.saber[saberNum].blade[bladeNum].length <= 0 ) { - if (vr->saberBlockDebounce > cg.time) - { - //saberColor = SABER_RED; - } + return; } if ( (!WP_SaberBladeUseSecondBladeStyle( &client->ps.saber[saberNum], bladeNum ) && client->ps.saber[saberNum].trailStyle < 2 ) @@ -7353,7 +7365,7 @@ extern vmCvar_t cg_thirdPersonAlpha; if ( !cg.renderingThirdPerson && cent->gent->client->ps.clientNum == 0 && (cg.snap->ps.weapon == WP_SABER||cg.snap->ps.weapon == WP_MELEE)) { vec3_t angles; - BG_CalculateVRSaberPosition(cent->gent->client->renderInfo.muzzlePoint, angles); + BG_CalculateVRSaberPosition(0, cent->gent->client->renderInfo.muzzlePoint, angles); AngleVectors( angles, cent->gent->client->renderInfo.muzzleDir, NULL, NULL ); } } @@ -7373,7 +7385,7 @@ extern vmCvar_t cg_thirdPersonAlpha; if (!cg.renderingThirdPerson && !cent->gent->client->ps.saberInFlight && cent->gent->client->ps.clientNum == 0) { vec3_t angles; - BG_CalculateVRSaberPosition(cent->gent->client->renderInfo.handRPoint, angles); + BG_CalculateVRSaberPosition(0, cent->gent->client->renderInfo.handRPoint, angles); } } if ( cent->gent->handLBolt != -1 ) @@ -7386,7 +7398,7 @@ extern vmCvar_t cg_thirdPersonAlpha; if (!cg.renderingThirdPerson && !cent->gent->client->ps.saberInFlight && cent->gent->client->ps.clientNum == 0) { vec3_t angles; - BG_CalculateVROffHandPosition(cent->gent->client->renderInfo.handLPoint, angles); + BG_CalculateVRSaberPosition(1, cent->gent->client->renderInfo.handLPoint, angles); } } if ( cent->gent->footLBolt != -1 ) @@ -7507,7 +7519,8 @@ extern vmCvar_t cg_thirdPersonAlpha; //this returns qfalse if it doesn't exist or isn't being rendered if ( G_GetRootSurfNameWithVariant( cent->gent, "r_hand", handName, sizeof(handName) ) ) //!gi.G2API_GetSurfaceRenderStatus( ¢->gent->ghoul2[cent->gent->playerModel], "r_hand" ) )//surf is still on { - CG_AddSaberBladeGo( cent, cent, NULL, ent.renderfx, cent->gent->weaponModel[saberNum], ent.origin, tempAngles, saberNum, bladeNum ); + CG_AddSaberBladeGo( cent, cent, NULL, CG_getPlayer1stPersonSaber(cent) ? 0 : ent.renderfx, + cent->gent->weaponModel[saberNum], ent.origin, tempAngles, saberNum, bladeNum ); //CG_AddSaberBlades( cent, ent.renderfx, ent.origin, tempAngles, saberNum ); }//else, the limb will draw the blade itself } @@ -7516,7 +7529,8 @@ extern vmCvar_t cg_thirdPersonAlpha; //this returns qfalse if it doesn't exist or isn't being rendered if ( G_GetRootSurfNameWithVariant( cent->gent, "l_hand", handName, sizeof(handName) ) ) //!gi.G2API_GetSurfaceRenderStatus( ¢->gent->ghoul2[cent->gent->playerModel], "l_hand" ) )//surf is still on { - CG_AddSaberBladeGo( cent, cent, NULL, ent.renderfx, cent->gent->weaponModel[saberNum], ent.origin, tempAngles, saberNum, bladeNum ); + CG_AddSaberBladeGo( cent, cent, NULL, CG_getPlayer1stPersonSaber(cent) ? 0 : ent.renderfx, + cent->gent->weaponModel[saberNum], ent.origin, tempAngles, saberNum, bladeNum ); //CG_AddSaberBlades( cent, ent.renderfx, ent.origin, tempAngles, saberNum ); }//else, the limb will draw the blade itself } @@ -8356,7 +8370,7 @@ Ghoul2 Insert End if ( cent->gent->client->ps.saber[saberNum].length > 0 ) { if ( !cent->gent->client->ps.saberInFlight ) - {//holding the saber in-hand + {//holding the saber in-hand. CG_AddSaberBlade( cent, cent, &gun, renderfx, 0, NULL, NULL ); calcedMp = qtrue; } @@ -8469,33 +8483,78 @@ Ghoul2 Insert End if (CG_getPlayer1stPersonSaber(cent) && !cent->currentState.saberInFlight && !vr->item_selector && cent->gent->client->ps.saberLockEnemy == ENTITYNUM_NONE) { -/* refEntity_t hiltEnt; - memset( &hiltEnt, 0, sizeof(refEntity_t) ); - - hiltEnt.hModel = cgs.media.saberHilt; - - BG_CalculateVRSaberPosition(hiltEnt.origin, hiltEnt.angles); - - vec3_t axis[3]; - AnglesToAxis(hiltEnt.angles, axis); - VectorSubtract(vec3_origin, axis[2], hiltEnt.axis[0]); - VectorCopy(axis[1], hiltEnt.axis[1]); - VectorCopy(axis[0], hiltEnt.axis[2]); - VectorMA(hiltEnt.origin, 1.0f, hiltEnt.axis[2], hiltEnt.origin); - VectorCopy(hiltEnt.origin, hiltEnt.oldorigin); - - for (auto & axi : hiltEnt.axis) - VectorScale(axi, 0.85f, axi); - - cgi_R_AddRefEntityToScene(&hiltEnt); -*/ - - //Should be a much better place to do this... - static int playingSaberSwingSound = 0; - if (vr->primaryVelocityTriggeredAttack && ((cg.time - playingSaberSwingSound) > 800)) + int numSabers = 1; + if ( cent->gent->client->ps.dualSabers ) { - //cgi_S_StartSound ( hiltEnt.origin, cent->gent->s.number, CHAN_AUTO, cgi_S_RegisterSound( va( "sound/weapons/saber/saberhup%d.wav", Q_irand( 1, 9 ) ) ) ); - playingSaberSwingSound = cg.time; + numSabers = 2; + } + for ( int saberNum = 0; saberNum < numSabers; saberNum++ ) + { + gentity_t *main_saber = &g_entities[cent->gent->client->ps.saberEntityNum]; + + refEntity_t hiltEnt; + memset( &hiltEnt, 0, sizeof(refEntity_t) ); + + BG_CalculateVRSaberPosition(saberNum, hiltEnt.origin, hiltEnt.angles); + + //Force it to use the ghoul2 model!? + if (saberNum == 0) + { + hiltEnt.ghoul2 = &main_saber->ghoul2; + } + else + { + static CGhoul2Info_v ghoul2; + if (ghoul2.size() == 0) + { + int saber2 = + G_ModelIndex( cent->gent->client->ps.saber[1].model ); + gi.G2API_InitGhoul2Model( ghoul2, cent->gent->client->ps.saber[1].model, saber2 , NULL_HANDLE, NULL_HANDLE, 0, 0 ); + } + hiltEnt.ghoul2 = &ghoul2; + } + hiltEnt.hModel = cgs.model_draw[0]; + VectorCopy( main_saber->modelScale, hiltEnt.modelScale); + hiltEnt.radius = 60; + + vec3_t axis[3]; + AnglesToAxis(hiltEnt.angles, axis); + VectorSubtract(vec3_origin, axis[2], hiltEnt.axis[0]); + VectorCopy(axis[1], hiltEnt.axis[1]); + VectorCopy(axis[0], hiltEnt.axis[2]); + //VectorMA(hiltEnt.origin, 1.0f, hiltEnt.axis[2], hiltEnt.origin); + VectorCopy(hiltEnt.origin, hiltEnt.oldorigin); + + cgi_R_AddRefEntityToScene(&hiltEnt); +/* +// if (cent->gent->weaponModel[saberNum] > 0) +// { +// gi.G2API_RemoveGhoul2Model(cent->gent->ghoul2, cent->gent->weaponModel[saberNum]); +// cent->gent->weaponModel[saberNum] = -1; +// } + //draw it + saber->s.eFlags &= ~EF_NODRAW; + saber->svFlags |= SVF_BROADCAST; + saber->svFlags &= ~SVF_NOCLIENT; + BG_CalculateVRSaberPosition(saberNum, saber->currentOrigin, saber->currentAngles); + VectorCopy(saber->currentOrigin, saber->s.pos.trBase); + + vec3_t axis[3], _axis[3]; + AnglesToAxis(saber->currentAngles, axis); + VectorSubtract(vec3_origin, axis[2], _axis[0]); + VectorCopy(axis[1], _axis[1]); + VectorCopy(axis[0], _axis[2]); + //vectoangles(_axis[2], saber->currentAngles); + + + VectorCopy(saber->currentAngles, saber->s.apos.trBase); + saber->s.pos.trTime = level.time; + saber->s.pos.trType = TR_STATIONARY; + saber->s.apos.trTime = level.time; + saber->s.apos.trType = TR_STATIONARY; + VectorClear(saber->s.pos.trDelta); + VectorClear(saber->s.apos.trDelta); + gi.linkentity(saber);*/ } } diff --git a/Projects/Android/jni/OpenJK/code/cgame/cg_view.cpp b/Projects/Android/jni/OpenJK/code/cgame/cg_view.cpp index cf4f603..1994739 100644 --- a/Projects/Android/jni/OpenJK/code/cgame/cg_view.cpp +++ b/Projects/Android/jni/OpenJK/code/cgame/cg_view.cpp @@ -2248,6 +2248,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView ) { if (!in_camera && !cg.renderingThirdPerson && cg.predicted_player_state.stats[STAT_HEALTH] > 0 + && (cg.snap->ps.viewEntity < ENTITYNUM_WORLD && g_entities[cg.snap->ps.viewEntity].client && !g_entities[cg.snap->ps.viewEntity].client->ps.dualSabers) && cg.snap->ps.weapon != WP_MELEE && !vr->weapon_stabilised && !vr->in_vehicle diff --git a/Projects/Android/jni/OpenJK/code/cgame/cg_weapons.cpp b/Projects/Android/jni/OpenJK/code/cgame/cg_weapons.cpp index 058433e..e9d31aa 100644 --- a/Projects/Android/jni/OpenJK/code/cgame/cg_weapons.cpp +++ b/Projects/Android/jni/OpenJK/code/cgame/cg_weapons.cpp @@ -2859,13 +2859,20 @@ void CG_ToggleSaber_f( ) { if (player->client->ps.saber->Active()) { - //G_SoundOnEnt( player, CHAN_WEAPON, "sound/weapons/saber/saberon.wav" ); - player->client->ps.saber->Deactivate(); + player->client->ps.saber[0].Deactivate(); + if (player->client->ps.dualSabers) + { + player->client->ps.saber[1].Deactivate(); + } + G_SoundOnEnt( player, CHAN_WEAPON, "sound/weapons/saber/saberoffquick.wav" ); } else { - player->client->ps.saber->Activate(); - //G_SoundOnEnt( player, CHAN_WEAPON, "sound/weapons/saber/saberoff.wav" ); + player->client->ps.saber[0].Activate(); + if (player->client->ps.dualSabers) + { + player->client->ps.saber[1].Activate(); + } } } diff --git a/Projects/Android/jni/OpenJK/code/game/bg_local.h b/Projects/Android/jni/OpenJK/code/game/bg_local.h index eb02e4f..e95b1a2 100644 --- a/Projects/Android/jni/OpenJK/code/game/bg_local.h +++ b/Projects/Android/jni/OpenJK/code/game/bg_local.h @@ -81,7 +81,7 @@ void PM_StepSlideMove( float gravity ); void rotateAboutOrigin(float x, float y, float rotation, vec2_t out); bool BG_UseVRPosition( gentity_t *ent ); void BG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles ); -void BG_CalculateVRSaberPosition( vec3_t origin, vec3_t angles ); +void BG_CalculateVRSaberPosition( int saberNum, vec3_t origin, vec3_t angles ); void BG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles ); void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out); void BG_CalculateVRPositionInWorld( const vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles ); diff --git a/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp b/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp index 10d2f8f..4e61b37 100644 --- a/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp +++ b/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp @@ -765,9 +765,16 @@ void BG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles ) BG_CalculateVRPositionInWorld(vr->weaponposition, vr->weaponoffset, vr->weaponangles, origin, angles); } -void BG_CalculateVRSaberPosition( vec3_t origin, vec3_t angles ) +void BG_CalculateVRSaberPosition( int saberNum, vec3_t origin, vec3_t angles ) { - BG_CalculateVRPositionInWorld(vr->weaponposition, vr->weaponoffset, vr->weaponangles_saber, origin, angles); + if (saberNum == 0) + { + BG_CalculateVRPositionInWorld(vr->weaponposition, vr->weaponoffset, vr->weaponangles_saber, origin, angles); + } + else + { + BG_CalculateVRPositionInWorld(vr->offhandposition[0], vr->offhandoffset, vr->offhandangles_saber, origin, angles); + } } bool BG_UseVRPosition( gentity_t *ent ) diff --git a/Projects/Android/jni/OpenJK/code/qcommon/q_shared.h b/Projects/Android/jni/OpenJK/code/qcommon/q_shared.h index f69be38..5008b99 100644 --- a/Projects/Android/jni/OpenJK/code/qcommon/q_shared.h +++ b/Projects/Android/jni/OpenJK/code/qcommon/q_shared.h @@ -1827,6 +1827,8 @@ public: int saberLockTime; int saberLockEnemy; + int saber2EntityNum; + #ifndef JK2_MODE int saberStylesKnown; #endif // !JK2_MODE