void C_BaseViewModel::ApplyBoneMatrixTransform( matrix3x4_t& transform ) { if ( ShouldFlipViewModel() ) { matrix3x4_t viewMatrix, viewMatrixInverse; // We could get MATERIAL_VIEW here, but this is called sometimes before the renderer // has set that matrix. Luckily, this is called AFTER the CViewSetup has been initialized. const CViewSetup *pSetup = view->GetPlayerViewSetup(); AngleMatrix( pSetup->angles, pSetup->origin, viewMatrixInverse ); MatrixInvert( viewMatrixInverse, viewMatrix ); // Transform into view space. matrix3x4_t temp, temp2; ConcatTransforms( viewMatrix, transform, temp ); // Flip it along X. // (This is the slower way to do it, and it equates to negating the top row). //matrix3x4_t mScale; //SetIdentityMatrix( mScale ); //mScale[0][0] = 1; //mScale[1][1] = -1; //mScale[2][2] = 1; //ConcatTransforms( mScale, temp, temp2 ); temp[1][0] = -temp[1][0]; temp[1][1] = -temp[1][1]; temp[1][2] = -temp[1][2]; temp[1][3] = -temp[1][3]; // Transform back out of view space. ConcatTransforms( viewMatrixInverse, temp, transform ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int C_BaseViewModel::InternalDrawModel( int flags ) { CMatRenderContextPtr pRenderContext( materials ); if ( ShouldFlipViewModel() ) pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); int ret = BaseClass::InternalDrawModel( flags ); pRenderContext->CullMode( MATERIAL_CULLMODE_CCW ); return ret; }
const Vector &C_BaseViewModel::GetRenderOrigin() { m_vecRender = BaseClass::GetRenderOrigin(); if ( ShouldFlipViewModel() ) { int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT(); Assert( nSlot != -1 ); const CViewSetup *pViewSetup = view->GetPlayerViewSetup( nSlot ); Vector right, delta = m_vecRender - pViewSetup->origin; AngleVectors( pViewSetup->angles, NULL, &right, NULL ); float flRight = DotProduct( right, delta ); m_vecRender += right * flRight * -2.0f; } return m_vecRender; }
//----------------------------------------------------------------------------- // 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 ); } CMatRenderContextPtr pRenderContext( materials ); if ( ShouldFlipViewModel() ) pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); 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 ); } 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 ); } } return ret; }
//----------------------------------------------------------------------------- // 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; }
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(); //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() ); } 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()/owner->GetFOV(); 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 }