void CBaseViewModel::CalcIronsights( Vector &pos, QAngle &ang ) { CBaseCombatWeapon *pWeapon = GetOwningWeapon(); if (!pWeapon) return; //get delta time for interpolation float delta = (gpGlobals->curtime - pWeapon->m_flIronsightedTime) * 2.5f; //modify this value to adjust how fast the interpolation is float exp = (pWeapon->IsIronsighted()) ? (delta > 1.0f) ? 1.0f : delta : //normal blending (delta > 1.0f) ? 0.0f : 1.0f - delta; //reverse interpolation if (exp <= 0.001f) //fully not ironsighted; save performance return; Vector newPos = pos; QAngle newAng = ang; Vector vForward, vRight, vUp, vOffset; AngleVectors(newAng, &vForward, &vRight, &vUp); vOffset = pWeapon->GetIronsightPositionOffset(); newPos += vForward * vOffset.x; newPos += vRight * vOffset.y; newPos += vUp * vOffset.z; newAng += pWeapon->GetIronsightAngleOffset(); //fov is handled by CBaseCombatWeapon pos += (newPos - pos) * exp; ang += (newAng - ang) * exp; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CTFViewModel::GetSkin() { int nSkin = BaseClass::GetSkin(); CTFWeaponBase *pWeapon = ( CTFWeaponBase * )GetOwningWeapon(); if ( !pWeapon ) return nSkin; CTFPlayer *pPlayer = ToTFPlayer( GetOwner() ); if ( pPlayer ) { if ( pWeapon->GetTFWpnData().m_bHasTeamSkins_Viewmodel ) { switch( pPlayer->GetTeamNumber() ) { case TF_TEAM_RED: nSkin = 0; break; case TF_TEAM_BLUE: nSkin = 1; break; case TF_TEAM_GREEN: nSkin = 2; break; case TF_TEAM_YELLOW: nSkin = 3; break; } } } return nSkin; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFViewModel::StandardBlendingRules( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime, int boneMask ) { BaseClass::StandardBlendingRules( hdr, pos, q, currentTime, boneMask ); CTFWeaponBase *pWeapon = ( CTFWeaponBase * )GetOwningWeapon(); if ( !pWeapon ) return; if ( pWeapon->GetWeaponID() == TF_WEAPON_MINIGUN ) { CTFMinigun *pMinigun = ( CTFMinigun * )pWeapon; int iBarrelBone = Studio_BoneIndexByName( hdr, "v_minigun_barrel" ); Assert( iBarrelBone != -1 ); if ( iBarrelBone != -1 ) { RadianEuler a; QuaternionAngles( q[iBarrelBone], a ); a.x = pMinigun->GetBarrelRotation(); AngleQuaternion( a, q[iBarrelBone] ); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFViewModel::ProcessMuzzleFlashEvent() { CTFWeaponBase *pWeapon = ( CTFWeaponBase * )GetOwningWeapon(); if ( !pWeapon || C_BasePlayer::ShouldDrawLocalPlayer() ) return; pWeapon->ProcessMuzzleFlashEvent(); }
//----------------------------------------------------------------------------- // Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried // by this player, otherwise draw the worldmodel. //----------------------------------------------------------------------------- int C_BaseViewModel::DrawModel( int flags ) { if ( !m_bReadyToDraw ) return 0; if ( flags & STUDIO_RENDER ) { // Determine blending amount and tell engine float blend = (float)( GetFxBlend() / 255.0f ); // Totally gone if ( blend <= 0.0f ) return 0; // Tell engine render->SetBlend( blend ); float color[3]; GetColorModulation( color ); render->SetColorModulation( color ); } C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); int ret; // If the local player's overriding the viewmodel rendering, let him do it if ( pPlayer && pPlayer->IsOverridingViewmodel() ) { ret = pPlayer->DrawOverriddenViewmodel( this, flags ); } else if ( pWeapon && pWeapon->IsOverridingViewmodel() ) { ret = pWeapon->DrawOverriddenViewmodel( this, flags ); } else { ret = BaseClass::DrawModel( flags ); } // Now that we've rendered, reset the animation restart flag if ( flags & STUDIO_RENDER ) { if ( m_nOldAnimationParity != m_nAnimationParity ) { m_nOldAnimationParity = m_nAnimationParity; } // Tell the weapon itself that we've rendered, in case it wants to do something if ( pWeapon ) { pWeapon->ViewModelDrawn( this ); } } return ret; }
void CBaseViewModel::CalcWalk( Vector &pos, QAngle &ang ) { CBaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( pWeapon ) return; if ( !m_hOwner->IsPlayer() ) { ang = QAngle( 0, m_hOwner->EyeAngles().y, 0); } }
void CBaseViewModel::CalcLimitAim( Vector &pos, QAngle &ang ) { CBaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( !pWeapon ) return; if ( m_hOwner->IsPlayer() ) { ang = QAngle( clamp(m_hOwner->EyeAngles().x, -90, 70), m_hOwner->EyeAngles().y, m_hOwner->EyeAngles().z); } }
//----------------------------------------------------------------------------- // Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool C_BaseViewModel::IsTransparent( void ) { // See if the local player wants to override the viewmodel's rendering C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer && pPlayer->IsOverridingViewmodel() ) { return pPlayer->ViewModel_IsTransparent(); } C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( pWeapon && pWeapon->IsOverridingViewmodel() ) return pWeapon->ViewModel_IsTransparent(); return BaseClass::IsTransparent(); }
//----------------------------------------------------------------------------- // Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- RenderableTranslucencyType_t C_BaseViewModel::ComputeTranslucencyType( void ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( GetOwner() ); // See if the local player wants to override the viewmodel's rendering C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer && pPlayer->IsOverridingViewmodel() ) return pPlayer->ComputeTranslucencyType(); C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( pWeapon && pWeapon->IsOverridingViewmodel() ) return pWeapon->ComputeTranslucencyType(); return BaseClass::ComputeTranslucencyType(); }
//----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- uint8 C_BaseViewModel::OverrideAlphaModulation( uint8 nAlpha ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( GetOwner() ); // See if the local player wants to override the viewmodel's rendering C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer && pPlayer->IsOverridingViewmodel() ) return pPlayer->AlphaProp()->ComputeRenderAlpha(); C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( pWeapon && pWeapon->IsOverridingViewmodel() ) return pWeapon->AlphaProp()->ComputeRenderAlpha(); return nAlpha; }
void CBaseViewModel::CalcAdjustedView(Vector &pos, QAngle &ang) { CBaseCombatWeapon *pWeapon = GetOwningWeapon(); if (!pWeapon) return; Vector vForward, vRight, vUp, vOffset; AngleVectors(ang, &vForward, &vRight, &vUp); vOffset = pWeapon->GetAdjustPositionOffset(); pos += vForward * vOffset.x; pos += vRight * vOffset.y; pos += vUp * vOffset.z; ang += pWeapon->GetAdjustAngleOffset(); //fov is handled by CBaseCombatWeapon }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool C_BaseViewModel::UsesPowerOfTwoFrameBufferTexture( void ) { // See if the local player wants to override the viewmodel's rendering C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer && pPlayer->IsOverridingViewmodel() ) { return pPlayer->ViewModel_IsUsingFBTexture(); } C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( pWeapon && pWeapon->IsOverridingViewmodel() ) { return pWeapon->ViewModel_IsUsingFBTexture(); } return BaseClass::UsesPowerOfTwoFrameBufferTexture(); }
//----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- int C_BaseViewModel::GetFxBlend( void ) { // See if the local player wants to override the viewmodel's rendering C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer && pPlayer->IsOverridingViewmodel() ) { pPlayer->ComputeFxBlend(); return pPlayer->GetFxBlend(); } C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( pWeapon && pWeapon->IsOverridingViewmodel() ) { pWeapon->ComputeFxBlend(); return pWeapon->GetFxBlend(); } return BaseClass::GetFxBlend(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CTFViewModel::GetSkin() { int nSkin = BaseClass::GetSkin(); CTFWeaponBase *pWeapon = ( CTFWeaponBase * )GetOwningWeapon(); if ( !pWeapon ) return nSkin; CTFPlayer *pPlayer = ToTFPlayer( GetOwner() ); if ( pPlayer ) { if ( TFGameRules()->IsDeathmatch() ) { // Merc arms are team colored so use the colored skin for all weapons. nSkin = 4; } else if ( pWeapon->GetTFWpnData().m_bHasTeamSkins_Viewmodel ) { switch ( pPlayer->GetTeamNumber() ) { case TF_TEAM_RED: nSkin = 0; break; case TF_TEAM_BLUE: nSkin = 1; break; case TF_TEAM_GREEN: nSkin = 2; break; case TF_TEAM_YELLOW: nSkin = 3; break; } } } return nSkin; }
void CBaseViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& original_angles ) { Vector vOriginalOrigin = origin; QAngle vOriginalAngles = angles; CBaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( !pWeapon ) return; if ( pWeapon->IsIronsighted() ) { origin = vOriginalOrigin; angles = vOriginalAngles; } else { // Calculate our drift Vector forward; AngleVectors( angles, &forward, NULL, NULL ); if ( gpGlobals->frametime != 0.0f ) { Vector vDifference; VectorSubtract( forward, m_vecLastFacing, vDifference ); float flSpeed = 5.0f; // If we start to lag too far behind, we'll increase the "catch up" speed. Solves the problem with fast cl_yawspeed, m_yaw or joysticks // rotating quickly. The old code would slam lastfacing with origin causing the viewmodel to pop to a new position float flDiff = vDifference.Length(); if ( (flDiff > g_fMaxViewModelLag) && (g_fMaxViewModelLag > 0.0f) ) { float flScale = flDiff / g_fMaxViewModelLag; flSpeed *= flScale; } // FIXME: Needs to be predictable? VectorMA( m_vecLastFacing, flSpeed * gpGlobals->frametime, vDifference, m_vecLastFacing ); // Make sure it doesn't grow out of control!!! VectorNormalize( m_vecLastFacing ); VectorMA( origin, 5.0f, vDifference * -1.0f, origin ); Assert( m_vecLastFacing.IsValid() ); } Vector right, up; AngleVectors( original_angles, &forward, &right, &up ); float pitch = original_angles[ PITCH ]; if ( pitch > 180.0f ) pitch -= 360.0f; else if ( pitch < -180.0f ) pitch += 360.0f; if ( g_fMaxViewModelLag == 0.0f ) { origin = vOriginalOrigin; angles = vOriginalAngles; } //FIXME: These are the old settings that caused too many exposed polys on some models VectorMA( origin, -pitch * 0.035f, forward, origin ); VectorMA( origin, -pitch * 0.03f, right, origin ); VectorMA( origin, -pitch * 0.02f, up, origin); } }
void CBaseViewModel::CalcViewModelView(CBasePlayer *owner, const Vector& eyePosition, const QAngle& eyeAngles) { // UNDONE: Calc this on the server? Disabled for now as it seems unnecessary to have this info on the server #if defined( CLIENT_DLL ) QAngle vmangoriginal = eyeAngles; QAngle vmangles = eyeAngles; Vector vmorigin = eyePosition; //CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); CBaseCombatWeapon *pWeapon = GetOwningWeapon(); //Allow weapon lagging if (pWeapon != NULL) { #if defined( CLIENT_DLL ) if (!prediction->InPrediction()) #endif { // add weapon-specific bob pWeapon->AddViewmodelBob(this, vmorigin, vmangles); //#if defined ( CSTRIKE_DLL ) //CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); //#endif } } // Add model-specific bob even if no weapon associated (for head bob for off hand models) AddViewModelBob(owner, vmorigin, vmangles); //#if !defined ( CSTRIKE_DLL ) // This was causing weapon jitter when rotating in updated CS:S; original Source had this in above InPrediction block 07/14/10 // Add lag //CalcViewModelLag(vmorigin, vmangles, vmangoriginal); //#endif #if defined( CLIENT_DLL ) if (!prediction->InPrediction()) { // Let the viewmodel shake at about 10% of the amplitude of the player's view vieweffects->ApplyShake(vmorigin, vmangles, 0.1); } #endif if( UseVR() ) { g_ClientVirtualReality.OverrideViewModelTransform( vmorigin, vmangles, pWeapon && pWeapon->ShouldUseLargeViewModelVROverride() ); } CalcIronsights(vmorigin, vmangles); CalcAdjustedView(vmorigin, vmangles); SetLocalOrigin(vmorigin); SetLocalAngles(vmangles); #ifdef SIXENSE if( g_pSixenseInput->IsEnabled() && (owner->GetObserverMode()==OBS_MODE_NONE) && !UseVR() ) { const float max_gun_pitch = 20.0f; float viewmodel_fov_ratio = g_pClientMode->GetViewModelFOV(); QAngle gun_angles = g_pSixenseInput->GetViewAngleOffset() * -viewmodel_fov_ratio; // Clamp pitch a bit to minimize seeing back of viewmodel if( gun_angles[PITCH] < -max_gun_pitch ) { gun_angles[PITCH] = -max_gun_pitch; } #ifdef WIN32 // ShouldFlipViewModel comes up unresolved on osx? Mabye because it's defined inline? fixme if( ShouldFlipViewModel() ) { gun_angles[YAW] *= -1.0f; } #endif vmangles = EyeAngles() + gun_angles; SetLocalAngles(vmangles); } #endif #endif }
//----------------------------------------------------------------------------- // Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried // by this player, otherwise draw the worldmodel. //----------------------------------------------------------------------------- int C_BaseViewModel::DrawModel( int flags, const RenderableInstance_t &instance ) { if ( !m_bReadyToDraw ) return 0; if ( flags & STUDIO_RENDER ) { // Determine blending amount and tell engine float blend = (float)( instance.m_nAlpha / 255.0f ); // Totally gone if ( blend <= 0.0f ) return 0; // Tell engine render->SetBlend( blend ); float color[3]; GetColorModulation( color ); render->SetColorModulation( color ); } CMatRenderContextPtr pRenderContext( materials ); if ( ShouldFlipViewModel() ) pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); int ret = 0; C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); // If the local player's overriding the viewmodel rendering, let him do it if ( pPlayer && pPlayer->IsOverridingViewmodel() ) { ret = pPlayer->DrawOverriddenViewmodel( this, flags, instance ); } else if ( pWeapon && pWeapon->IsOverridingViewmodel() ) { ret = pWeapon->DrawOverriddenViewmodel( this, flags, instance ); } else { ret = BaseClass::DrawModel( flags, instance ); } pRenderContext->CullMode( MATERIAL_CULLMODE_CCW ); // Now that we've rendered, reset the animation restart flag if ( flags & STUDIO_RENDER ) { if ( m_nOldAnimationParity != m_nAnimationParity ) { m_nOldAnimationParity = m_nAnimationParity; } // Tell the weapon itself that we've rendered, in case it wants to do something if ( pWeapon ) { pWeapon->ViewModelDrawn( this ); } if ( vm_debug.GetBool() ) { MDLCACHE_CRITICAL_SECTION(); int line = 16; CStudioHdr *hdr = GetModelPtr(); engine->Con_NPrintf( line++, "%s: %s(%d), cycle: %.2f cyclerate: %.2f playbackrate: %.2f\n", (hdr)?hdr->pszName():"(null)", GetSequenceName( GetSequence() ), GetSequence(), GetCycle(), GetSequenceCycleRate( hdr, GetSequence() ), GetPlaybackRate() ); if ( hdr ) { for( int i=0; i < hdr->GetNumPoseParameters(); ++i ) { const mstudioposeparamdesc_t &Pose = hdr->pPoseParameter( i ); engine->Con_NPrintf( line++, "pose_param %s: %f", Pose.pszName(), GetPoseParameter( i ) ); } } // Determine blending amount and tell engine float blend = (float)( instance.m_nAlpha / 255.0f ); float color[3]; GetColorModulation( color ); engine->Con_NPrintf( line++, "blend=%f, color=%f,%f,%f", blend, color[0], color[1], color[2] ); engine->Con_NPrintf( line++, "GetRenderMode()=%d", GetRenderMode() ); engine->Con_NPrintf( line++, "m_nRenderFX=0x%8.8X", GetRenderFX() ); color24 c = GetRenderColor(); unsigned char a = GetRenderAlpha(); engine->Con_NPrintf( line++, "rendercolor=%d,%d,%d,%d", c.r, c.g, c.b, a ); engine->Con_NPrintf( line++, "origin=%f, %f, %f", GetRenderOrigin().x, GetRenderOrigin().y, GetRenderOrigin().z ); engine->Con_NPrintf( line++, "angles=%f, %f, %f", GetRenderAngles()[0], GetRenderAngles()[1], GetRenderAngles()[2] ); if ( IsEffectActive( EF_NODRAW ) ) { engine->Con_NPrintf( line++, "EF_NODRAW" ); } } } return ret; }