From bcd7f5b98be5cf1ecda2f54e3452b03ae327533a Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 18 Feb 2020 22:59:11 +0000 Subject: [PATCH] Support for hand models... ...when not holding torch or holding weapon. --- .../jni/src/Lambda1VR/L1VR_SurfaceView.c | 1 + Projects/Android/jni/src/Lambda1VR/VrCvars.h | 1 + .../src/Xash3D/xash3d/engine/client/client.h | 3 +- .../Xash3D/xash3d/engine/client/gl_local.h | 1 + .../Xash3D/xash3d/engine/client/gl_rmain.c | 3 + .../Xash3D/xash3d/engine/client/gl_studio.c | 98 +++++++++++++++++-- .../Xash3D/xash3d/mainui/menus/Controls.cpp | 7 ++ .../drbeef/lambda1vr/GLES3JNIActivity.java | 1 + 8 files changed, 107 insertions(+), 8 deletions(-) diff --git a/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c b/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c index 7651bc0..a53d509 100644 --- a/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c +++ b/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c @@ -1450,6 +1450,7 @@ void VR_Init() vr_enable_crouching = Cvar_Get( "vr_enable_crouching", "0.85", CVAR_ARCHIVE, "To enable real-world crouching trigger, set this to a value that multiplied by the user's height will trigger crouch mechanic" ); vr_height_adjust = Cvar_Get( "vr_height_adjust", "0.0", CVAR_ARCHIVE, "Additional height adjustment for in-game player (in metres)" ); vr_flashlight_model = Cvar_Get( "vr_flashlight_model", "1", CVAR_ARCHIVE, "Set to 0 to prevent drawing the flashlight model" ); + vr_hand_model = Cvar_Get( "vr_hand_model", "1", CVAR_ARCHIVE, "Set to 0 to prevent drawing the hand models" ); vr_mirror_weapons = Cvar_Get( "vr_mirror_weapons", "0", CVAR_ARCHIVE, "Set to 1 to mirror the weapon models (for left handed use)" ); vr_weapon_backface_culling = Cvar_Get( "vr_weapon_backface_culling", "0", CVAR_ARCHIVE, "Use to enable whether back face culling is used on weapon viewmodel" ); vr_comfort_mask = Cvar_Get( "vr_comfort_mask", "0.0", CVAR_ARCHIVE, "Use to reduce motion sickness, 0.0 is off, 1.0 is fully obscured, probably go with 0.7, anything less than 0.5 is barely visible" ); diff --git a/Projects/Android/jni/src/Lambda1VR/VrCvars.h b/Projects/Android/jni/src/Lambda1VR/VrCvars.h index 303c437..ecd936d 100644 --- a/Projects/Android/jni/src/Lambda1VR/VrCvars.h +++ b/Projects/Android/jni/src/Lambda1VR/VrCvars.h @@ -16,6 +16,7 @@ convar_t *vr_control_scheme; convar_t *vr_enable_crouching; convar_t *vr_height_adjust; convar_t *vr_flashlight_model; +convar_t *vr_hand_model; convar_t *vr_mirror_weapons; convar_t *vr_weapon_backface_culling; convar_t *vr_comfort_mask; diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h index c61405b..c8a40a1 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h @@ -414,7 +414,8 @@ typedef struct efrag_t *free_efrags; // linked efrags cl_entity_t viewent; // viewmodel - cl_entity_t flashlightEntity; // flashlight + cl_entity_t flashlightent; // flashlight + cl_entity_t handent; // hands } clgame_static_t; typedef struct diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_local.h b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_local.h index 6118ff3..14e5946 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_local.h +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_local.h @@ -495,6 +495,7 @@ void GL_SetRenderMode( int mode ); void R_RunViewmodelEvents( void ); void R_DrawViewModel( void ); void R_DrawFlashlightModel( void ); +void R_DrawHandModel( int hand ); // 0 = left int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame ); void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, vec3_t saxis, float scale ); void R_RemoveEfrags( struct cl_entity_s *ent ); diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c index a0132f8..199b6f4 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c @@ -1204,6 +1204,9 @@ void R_DrawEntitiesOnList( void ) pglDepthMask( GL_TRUE ); pglDisable( GL_BLEND ); // Trinity Render issues + R_DrawHandModel(0); // left + R_DrawHandModel(1); // right + R_DrawViewModel(); R_DrawFlashlightModel(); diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c index d27d6ff..c2c2c84 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c @@ -3792,6 +3792,90 @@ void R_DrawViewModel( void ) RI.currentmodel = NULL; } +extern convar_t *vr_hand_model; +extern convar_t *vr_control_scheme; + +void R_DrawHandModel( int hand ) +{ + if( RI.refdef.onlyClientDraw || r_drawviewmodel->integer == 0 || vr_hand_model->integer == 0 || bScopeEngaged()) + return; + + // ignore in thirdperson, camera view or client is died + if( cl.thirdperson || cl.refdef.health <= 0 || cl.refdef.viewentity != ( cl.playernum + 1 )) + return; + + if( RI.params & RP_NONVIEWERREF ) + return; + + //Check whether we have weapon or flashlight + if ((hand == 0 && (cl.frame.client.flags & FL_HAS_FLASHLIGHT || cl.refdef.weapon.flags == 1)) || + (hand == 1 && clgame.viewent.model)) + return; + + clgame.handent.model = Mod_ForName("models/v_hand.mdl", false); + if (!clgame.handent.model) { + return; + } + + RI.currententity = &clgame.handent; + RI.currentmodel = RI.currententity->model; + RI.currententity->curstate.renderamt = 192; + RI.currententity->curstate.renderfx = kRenderFxNoDissipation; + RI.currententity->curstate.rendermode = kRenderGlow; + + //If left hand, set mirror weapons cvar + float mirror = vr_mirror_weapons->value; + if (hand == 0) + { + Cvar_Set2("vr_mirror_weapons", "1", true); + } + + g_iBackFaceCull = hand == 0; + + RI.currententity->curstate.scale = 1.0f; + RI.currententity->curstate.frame = 0; + RI.currententity->curstate.framerate = 1.0f; + RI.currententity->curstate.animtime = cl.time; + RI.currententity->curstate.sequence = 0; + + int off_hand = (vr_control_scheme->integer >= 10) ? 1 : 0; + if (hand == off_hand) + { + //Off hand + VectorAdd(cl.refdef.vieworg, cl.refdef.flashlight.org, clgame.handent.origin); + VectorCopy(cl.refdef.flashlight.angles.adjusted, clgame.handent.curstate.angles); + clgame.handent.curstate.angles[0] *= -1.0f; + } else + { + //Dominant hand + VectorAdd(cl.refdef.vieworg, cl.refdef.weapon.org, clgame.handent.origin); + VectorCopy(cl.refdef.weapon.angles.adjusted, clgame.handent.curstate.angles); + } + + //Optional culling for the viewmodel + clgame.ds.cullMode = GL_NONE; + pglDisable(GL_CULL_FACE); + + pStudioDraw->StudioDrawModel( STUDIO_RENDER | STUDIO_VIEWMODEL ); + + clgame.ds.cullMode = GL_FRONT; + pglEnable(GL_CULL_FACE); + + if (hand == 0) + { + //restore cvar + Cvar_Set2("vr_mirror_weapons", mirror != 0.0 ? "1" : "0", true); + } + + + // backface culling for left-handed weapons + g_iBackFaceCull = false; // GL_FrontFace is called in RestoreStudioRenderer + + RI.currententity = NULL; + RI.currentmodel = NULL; +} + + /* ================= R_DrawFlashlightModel @@ -3817,18 +3901,18 @@ void R_DrawFlashlightModel( void ) vr_flashlight_model->integer && vr_headtorch->value == 0.0f) { - clgame.flashlightEntity.model = Mod_ForName("models/v_torch.mdl", false); - if (!clgame.flashlightEntity.model) { + clgame.flashlightent.model = Mod_ForName("models/v_torch.mdl", false); + if (!clgame.flashlightent.model) { MsgDev(D_INFO, "No model for flashlight!\n"); return; } - VectorAdd(cl.refdef.vieworg, cl.refdef.flashlight.org, clgame.flashlightEntity.origin); - VectorCopy(cl.refdef.flashlight.angles.adjusted, clgame.flashlightEntity.curstate.angles); - clgame.flashlightEntity.curstate.angles[0] *= -1.0f; + VectorAdd(cl.refdef.vieworg, cl.refdef.flashlight.org, clgame.flashlightent.origin); + VectorCopy(cl.refdef.flashlight.angles.adjusted, clgame.flashlightent.curstate.angles); + clgame.flashlightent.curstate.angles[0] *= -1.0f; - RI.currententity = &clgame.flashlightEntity; - RI.currentmodel = clgame.flashlightEntity.model; + RI.currententity = &clgame.flashlightent; + RI.currentmodel = clgame.flashlightent.model; RI.currententity->curstate.renderamt = 192; // hack the depth range to prevent flashlight model from poking into walls diff --git a/Projects/Android/jni/src/Xash3D/xash3d/mainui/menus/Controls.cpp b/Projects/Android/jni/src/Xash3D/xash3d/mainui/menus/Controls.cpp index c3705e8..507d79b 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/mainui/menus/Controls.cpp +++ b/Projects/Android/jni/src/Xash3D/xash3d/mainui/menus/Controls.cpp @@ -66,6 +66,7 @@ private: CMenuCheckBox hmdWalkDirection; CMenuCheckBox mirrorWeapons; CMenuCheckBox headTorch; + CMenuCheckBox handModels; CMenuCheckBox quickCrouchJump; CMenuSlider snapTurnAngle; @@ -108,6 +109,10 @@ void CMenuControls::_Init( void ) mirrorWeapons.SetCoord( 320, 510 ); mirrorWeapons.LinkCvar( "vr_mirror_weapons" ); + handModels.SetNameAndStatus( "Draw Hand Models", "Check to enable controllers rendered as hand models" ); + handModels.SetCoord( 720, 510 ); + handModels.LinkCvar( "vr_hand_model" ); + headTorch.SetNameAndStatus( "Head-based Torch", "Check to enable head-torch (Half-life & Blueshift only)" ); headTorch.SetCoord( 320, 570 ); headTorch.LinkCvar( "vr_headtorch" ); @@ -125,6 +130,7 @@ void CMenuControls::_Init( void ) AddItem( quickCrouchJump ); AddItem( mirrorWeapons ); AddItem( headTorch ); + AddItem( handModels ); AddItem( snapTurnAngle ); } @@ -154,6 +160,7 @@ void CMenuControls::SetConfig( ) quickCrouchJump.WriteCvar(); mirrorWeapons.WriteCvar(); headTorch.WriteCvar(); + handModels.WriteCvar(); snapTurnAngle.WriteCvar(); // We're done now, just close diff --git a/java/com/drbeef/lambda1vr/GLES3JNIActivity.java b/java/com/drbeef/lambda1vr/GLES3JNIActivity.java index 688f764..74936a6 100644 --- a/java/com/drbeef/lambda1vr/GLES3JNIActivity.java +++ b/java/com/drbeef/lambda1vr/GLES3JNIActivity.java @@ -311,6 +311,7 @@ import static android.system.Os.setenv; copy_asset("/sdcard/xash/" + game + "/", "sound/weapons/cbar_miss1.wav", true); copy_asset("/sdcard/xash/" + game + "/", "models/v_torch.mdl", true); + copy_asset("/sdcard/xash/" + game + "/", "models/v_hand.mdl", true); } //Copy Opposing Force specific models