From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/game/shared/weapon_ifmbasecamera.cpp | 404 ++++++++++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 mp/src/game/shared/weapon_ifmbasecamera.cpp (limited to 'mp/src/game/shared/weapon_ifmbasecamera.cpp') diff --git a/mp/src/game/shared/weapon_ifmbasecamera.cpp b/mp/src/game/shared/weapon_ifmbasecamera.cpp new file mode 100644 index 00000000..5c130db1 --- /dev/null +++ b/mp/src/game/shared/weapon_ifmbasecamera.cpp @@ -0,0 +1,404 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "cbase.h" +#include "weapon_ifmbasecamera.h" + +#ifdef CLIENT_DLL +#include "view_shared.h" +#include "iviewrender.h" +#include "vgui_controls/Controls.h" +#include "vgui/ISurface.h" + +bool ToolFramework_SetupEngineView( Vector &origin, QAngle &angles, float &fov ); + +#endif + +#define INSET_VIEW_FACTOR 0.3f + +//----------------------------------------------------------------------------- +// CWeaponIFMBaseCamera tables. +//----------------------------------------------------------------------------- +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponIFMBaseCamera, DT_WeaponIFMBaseCamera ) +LINK_ENTITY_TO_CLASS( weapon_ifm_base_camera, CWeaponIFMBaseCamera ); + +BEGIN_NETWORK_TABLE( CWeaponIFMBaseCamera, DT_WeaponIFMBaseCamera ) +#if !defined( CLIENT_DLL ) + SendPropFloat( SENDINFO( m_flRenderAspectRatio ), 0, SPROP_NOSCALE ), + SendPropFloat( SENDINFO( m_flRenderFOV ), 0, SPROP_NOSCALE ), + SendPropFloat( SENDINFO( m_flRenderArmLength ), 0, SPROP_NOSCALE ), + SendPropVector( SENDINFO( m_vecRenderPosition ), 0, SPROP_NOSCALE ), + SendPropQAngles( SENDINFO( m_angRenderAngles ), 0, SPROP_NOSCALE ), +#else + RecvPropFloat( RECVINFO( m_flRenderAspectRatio ) ), + RecvPropFloat( RECVINFO( m_flRenderFOV ) ), + RecvPropFloat( RECVINFO( m_flRenderArmLength ) ), + RecvPropVector( RECVINFO( m_vecRenderPosition ) ), + RecvPropQAngles( RECVINFO( m_angRenderAngles ) ), +#endif +END_NETWORK_TABLE() + +#ifdef CLIENT_DLL + +BEGIN_PREDICTION_DATA( CWeaponIFMBaseCamera ) + DEFINE_PRED_FIELD( m_flFOV, FIELD_FLOAT, 0 ), + DEFINE_PRED_FIELD( m_flArmLength, FIELD_FLOAT, 0 ), + DEFINE_PRED_FIELD( m_vecRelativePosition, FIELD_VECTOR, 0 ), + DEFINE_PRED_FIELD( m_angRelativeAngles, FIELD_VECTOR, 0 ), + DEFINE_PRED_FIELD( m_bFullScreen, FIELD_BOOLEAN, 0 ), +END_PREDICTION_DATA() + +#endif + + +#ifdef GAME_DLL + +BEGIN_DATADESC( CWeaponIFMBaseCamera ) + DEFINE_FIELD( m_flRenderAspectRatio, FIELD_FLOAT ), + DEFINE_FIELD( m_flRenderFOV, FIELD_FLOAT ), + DEFINE_FIELD( m_flRenderArmLength, FIELD_FLOAT ), + DEFINE_FIELD( m_vecRenderPosition, FIELD_VECTOR ), + DEFINE_FIELD( m_angRenderAngles, FIELD_VECTOR ), +END_DATADESC() + +#endif + + +//----------------------------------------------------------------------------- +// CWeaponIFMBaseCamera implementation. +//----------------------------------------------------------------------------- +CWeaponIFMBaseCamera::CWeaponIFMBaseCamera() +{ +#ifdef CLIENT_DLL + m_flFOV = 75.0f; + m_flArmLength = 4; + m_vecRelativePosition.Init(); + m_angRelativeAngles.Init(); + m_bFullScreen = false; + m_nScreenWidth = 0; + m_nScreenHeight = 0; +#endif +} + + +//----------------------------------------------------------------------------- +// +// Specific methods on the server +// +//----------------------------------------------------------------------------- +#ifdef GAME_DLL + +void CWeaponIFMBaseCamera::SetRenderInfo( float flAspectRatio, float flFOV, float flArmLength, const Vector &vecPosition, const QAngle &angles ) +{ + m_flRenderAspectRatio = flAspectRatio; + m_flRenderFOV = flFOV; + m_flRenderArmLength = flArmLength; + m_vecRenderPosition = vecPosition; + m_angRenderAngles = angles; +} + +CON_COMMAND( ifm_basecamera_camerastate, "Set camera state" ) +{ + CBasePlayer *pPlayer = ToBasePlayer( UTIL_GetCommandClient() ); + if ( !pPlayer ) + return; + + if ( args.ArgC() != 10 ) + return; + + Vector vecPosition; + QAngle angAngles; + float flAspectRatio = atof( args[1] ); + float flFOV = atof( args[2] ); + float flArmLength = atof( args[3] ); + vecPosition.x = atof( args[4] ); + vecPosition.y = atof( args[5] ); + vecPosition.z = atof( args[6] ); + angAngles.x = atof( args[7] ); + angAngles.y = atof( args[8] ); + angAngles.z = atof( args[9] ); + + int nCount = pPlayer->WeaponCount(); + for ( int i = 0; i < nCount; ++i ) + { + CWeaponIFMBaseCamera *pCamera = dynamic_cast( pPlayer->GetWeapon( i ) ); + if ( !pCamera ) + continue; + + pCamera->SetRenderInfo( flAspectRatio, flFOV, flArmLength, vecPosition, angAngles ); + } +} + +#endif // GAME_DLL + + +//----------------------------------------------------------------------------- +// +// Specific methods on the client +// +//----------------------------------------------------------------------------- +#ifdef CLIENT_DLL + + +//----------------------------------------------------------------------------- +// Sets up the material to draw with +//----------------------------------------------------------------------------- +void CWeaponIFMBaseCamera::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + if (updateType == DATA_UPDATE_CREATED) + { + m_FrustumMaterial.Init( "effects/steadycamfrustum", TEXTURE_GROUP_OTHER ); + m_FrustumWireframeMaterial.Init( "shadertest/wireframevertexcolor", TEXTURE_GROUP_OTHER ); + } +} + + +//----------------------------------------------------------------------------- +// Transmits render information +//----------------------------------------------------------------------------- +void CWeaponIFMBaseCamera::TransmitRenderInfo() +{ + float flAspectRatio = (m_nScreenHeight != 0) ? (float)m_nScreenWidth / (float)m_nScreenHeight : 1.0f; + float flFOV = m_flFOV; + + Vector position; + QAngle angles; + ComputeAbsCameraTransform( position, angles ); + + // give the toolsystem a chance to override the view + ToolFramework_SetupEngineView( position, angles, flFOV ); + + char pBuf[256]; + Q_snprintf( pBuf, sizeof(pBuf), "ifm_basecamera_camerastate %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f", + flAspectRatio, flFOV, m_flArmLength, position.x, position.y, position.z, + angles.x, angles.y, angles.z ); + + engine->ClientCmd( pBuf ); +} + + +//----------------------------------------------------------------------------- +// Purpose: In 3rd person, draws the cone of the steadycam +//----------------------------------------------------------------------------- +#define FRUSTUM_SIZE 1000 + +int CWeaponIFMBaseCamera::DrawModel( int flags ) +{ + int nRetVal = BaseClass::DrawModel( flags ); + + CBasePlayer *pPlayer = GetPlayerOwner(); + if ( pPlayer && !pPlayer->IsLocalPlayer() ) + { + // Compute endpoints + float flMaxD = 1.0f / tan( M_PI * m_flFOV / 360.0f ); + float ex = flMaxD * FRUSTUM_SIZE; + float ey = flMaxD * FRUSTUM_SIZE / m_flRenderAspectRatio; + + // Compute basis + Vector vecForward, vecUp, vecRight; + AngleVectors( m_angRenderAngles, &vecForward, &vecRight, &vecUp ); + + Vector vecCenter; + VectorMA( m_vecRenderPosition, FRUSTUM_SIZE, vecForward, vecCenter ); + + Vector vecEndPoint[4]; + VectorMA( vecCenter, ex, vecRight, vecEndPoint[0] ); + VectorMA( vecEndPoint[0], ey, vecUp, vecEndPoint[0] ); + VectorMA( vecEndPoint[0], -2.0f * ex, vecRight, vecEndPoint[1] ); + VectorMA( vecEndPoint[1], -2.0f * ey, vecUp, vecEndPoint[2] ); + VectorMA( vecEndPoint[2], 2.0f * ex, vecRight, vecEndPoint[3] ); + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Bind( m_FrustumMaterial ); + IMesh* pMesh = pRenderContext->GetDynamicMesh( true ); + + CMeshBuilder meshBuilder; + meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 4 ); + for ( int i = 0; i < 4; ++i ) + { + meshBuilder.Position3fv( m_vecRenderPosition.Get().Base() ); + meshBuilder.Color4ub( 128, 0, 0, 255 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3fv( vecEndPoint[i].Base() ); + meshBuilder.Color4ub( 128, 0, 0, 255 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3fv( vecEndPoint[(i+1)%4].Base() ); + meshBuilder.Color4ub( 128, 0, 0, 255 ); + meshBuilder.AdvanceVertex(); + } + + meshBuilder.End(); + pMesh->Draw(); + + pRenderContext->Bind( m_FrustumWireframeMaterial ); + pMesh = pRenderContext->GetDynamicMesh( true ); + meshBuilder.Begin( pMesh, MATERIAL_LINES, 8 ); + for ( int i = 0; i < 4; ++i ) + { + meshBuilder.Position3fv( m_vecRenderPosition.Get().Base() ); + meshBuilder.Color4ub( 255, 255, 255, 255 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3fv( vecEndPoint[i].Base() ); + meshBuilder.Color4ub( 255, 255, 255, 255 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3fv( vecEndPoint[i].Base() ); + meshBuilder.Color4ub( 255, 255, 255, 255 ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Position3fv( vecEndPoint[(i+1)%4].Base() ); + meshBuilder.Color4ub( 255, 255, 255, 255 ); + meshBuilder.AdvanceVertex(); + } + + meshBuilder.End(); + pMesh->Draw(); + } + + return nRetVal; +} + + +//----------------------------------------------------------------------------- +// Gets the size of the overlay to draw +//----------------------------------------------------------------------------- +void CWeaponIFMBaseCamera::GetViewportSize( int &w, int &h ) +{ + if ( !m_bFullScreen ) + { + w = m_nScreenWidth * INSET_VIEW_FACTOR; + h = m_nScreenHeight * INSET_VIEW_FACTOR; + } + else + { + w = m_nScreenWidth; + h = m_nScreenHeight; + } +} + + +//----------------------------------------------------------------------------- +// Gets the abs orientation of the camera +//----------------------------------------------------------------------------- +void CWeaponIFMBaseCamera::ComputeAbsCameraTransform( Vector &vecAbsOrigin, QAngle &angAbsRotation ) +{ + CBasePlayer *pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + { + vecAbsOrigin.Init(); + angAbsRotation.Init(); + return; + } + + float flFOV = m_flFOV; + + float flZNear = view->GetZNear(); + float flZFar = view->GetZFar(); + Vector viewOrigin; + QAngle viewAngles; + pPlayer->CalcView( viewOrigin, viewAngles, flZNear, flZFar, flFOV ); + + // Offset the view along the forward direction vector by the arm length + Vector vecForward; + AngleVectors( viewAngles, &vecForward ); + VectorMA( viewOrigin, m_flArmLength, vecForward, viewOrigin ); + + // Use player roll + QAngle angles = m_angRelativeAngles; + angles.z = viewAngles.z; + + // Compute the actual orientation of the view + matrix3x4_t cameraToWorld, overlayToCamera, overlayToWorld; + AngleMatrix( vec3_angle, viewOrigin, cameraToWorld ); + AngleMatrix( angles, m_vecRelativePosition, overlayToCamera ); + ConcatTransforms( cameraToWorld, overlayToCamera, overlayToWorld ); + MatrixAngles( overlayToWorld, angAbsRotation, vecAbsOrigin ); + + // give the toolsystem a chance to override the view + ToolFramework_SetupEngineView( vecAbsOrigin, angAbsRotation, flFOV ); +} + + +//----------------------------------------------------------------------------- +// Gets the bounds of the overlay to draw +//----------------------------------------------------------------------------- +void CWeaponIFMBaseCamera::GetOverlayBounds( int &x, int &y, int &w, int &h ) +{ + const CViewSetup *pViewSetup = view->GetViewSetup(); + if ( !m_bFullScreen ) + { + w = pViewSetup->width * INSET_VIEW_FACTOR; + h = pViewSetup->height * INSET_VIEW_FACTOR; + x = pViewSetup->x + ( pViewSetup->width - w ) / 2; + y = pViewSetup->height - h; + } + else + { + w = pViewSetup->width; + h = pViewSetup->height; + x = pViewSetup->x; + y = pViewSetup->y; + } +} + + +//----------------------------------------------------------------------------- +// When drawing the model, if drawing the viewmodel, draw an overlay of what's being rendered +//----------------------------------------------------------------------------- +void CWeaponIFMBaseCamera::ViewModelDrawn( CBaseViewModel *pBaseViewModel ) +{ + // NOTE: This is not recursively called because we do not draw viewmodels in the overlay + CViewSetup overlayView = *view->GetViewSetup(); + + m_nScreenWidth = overlayView.width; + m_nScreenHeight = overlayView.height; + + GetOverlayBounds( overlayView.x, overlayView.y, overlayView.width, overlayView.height ); + overlayView.m_bRenderToSubrectOfLargerScreen = true; + overlayView.fov = m_flFOV; + + // Compute the location of the camera + ComputeAbsCameraTransform( overlayView.origin, overlayView.angles ); + + // give the toolsystem a chance to override the view + ToolFramework_SetupEngineView( overlayView.origin, overlayView.angles, overlayView.fov ); + + view->QueueOverlayRenderView( overlayView, VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH, RENDERVIEW_UNSPECIFIED ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw the weapon's crosshair +//----------------------------------------------------------------------------- +void CWeaponIFMBaseCamera::DrawCrosshair( void ) +{ + BaseClass::DrawCrosshair(); + + int x, y, w, h; + GetOverlayBounds( x, y, w, h ); + + // Draw the targeting zone around the crosshair + int r, g, b, a; + gHUD.m_clrYellowish.GetColor( r, g, b, a ); + + Color light( r, g, b, 160 ); + + int nBorderSize = 4; + vgui::surface()->DrawSetColor( light ); + vgui::surface()->DrawFilledRect( x-nBorderSize, y-nBorderSize, x+w+nBorderSize, y ); + vgui::surface()->DrawFilledRect( x-nBorderSize, y+h, x+w+nBorderSize, y+h+nBorderSize ); + vgui::surface()->DrawFilledRect( x-nBorderSize, y, x, y+h ); + vgui::surface()->DrawFilledRect( x+w, y, x+w+nBorderSize, y+h ); +} + +#endif // CLIENT_DLL + + -- cgit v1.2.3