You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
404 lines
13 KiB
404 lines
13 KiB
//========= 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<CWeaponIFMBaseCamera*>( 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 |
|
|
|
|
|
|