diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /sp/src/game/client/game_controls/basemodel_panel.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/game/client/game_controls/basemodel_panel.cpp')
| -rw-r--r-- | sp/src/game/client/game_controls/basemodel_panel.cpp | 653 |
1 files changed, 653 insertions, 0 deletions
diff --git a/sp/src/game/client/game_controls/basemodel_panel.cpp b/sp/src/game/client/game_controls/basemodel_panel.cpp new file mode 100644 index 00000000..aa82fb94 --- /dev/null +++ b/sp/src/game/client/game_controls/basemodel_panel.cpp @@ -0,0 +1,653 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "cbase.h"
+#include "basemodel_panel.h"
+#include "activitylist.h"
+#include "animation.h"
+#include "vgui/IInput.h"
+#include "matsys_controls/manipulator.h"
+
+using namespace vgui;
+DECLARE_BUILD_FACTORY( CBaseModelPanel );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBaseModelPanel::CBaseModelPanel( vgui::Panel *pParent, const char *pName ): BaseClass( pParent, pName )
+{
+ m_bForcePos = false;
+ m_bMousePressed = false;
+ m_bAllowRotation = false;
+ m_bAllowFullManipulation = false;
+ m_bApplyManipulators = false;
+ m_bForcedCameraPosition = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBaseModelPanel::~CBaseModelPanel()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Load in the model portion of the panel's resource file.
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ApplySettings( KeyValues *inResourceData )
+{
+ BaseClass::ApplySettings( inResourceData );
+
+ // Set whether we render to texture
+ m_bRenderToTexture = inResourceData->GetBool( "render_texture", true );
+
+ // Grab and set the camera FOV.
+ float flFOV = GetCameraFOV();
+ m_BMPResData.m_flFOV = inResourceData->GetInt( "fov", flFOV );
+ SetCameraFOV( m_BMPResData.m_flFOV );
+
+ // Do we allow rotation on these panels.
+ m_bAllowRotation = inResourceData->GetBool( "allow_rot", false );
+
+ // Do we allow full manipulation on these panels.
+ m_bAllowFullManipulation = inResourceData->GetBool( "allow_manip", false );
+
+ // Parse our resource file and apply all necessary updates to the MDL.
+ for ( KeyValues *pData = inResourceData->GetFirstSubKey() ; pData != NULL ; pData = pData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pData->GetName(), "model" ) )
+ {
+ ParseModelResInfo( pData );
+ }
+ }
+
+ SetMouseInputEnabled( m_bAllowFullManipulation || m_bAllowRotation );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ParseModelResInfo( KeyValues *inResourceData )
+{
+ m_bForcePos = ( inResourceData->GetInt( "force_pos", 0 ) == 1 );
+ m_BMPResData.m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
+ m_BMPResData.m_pszModelName_HWM = ReadAndAllocStringValue( inResourceData, "modelname_hwm" );
+ m_BMPResData.m_pszVCD = ReadAndAllocStringValue( inResourceData, "vcd" );
+ m_BMPResData.m_angModelPoseRot.Init( inResourceData->GetFloat( "angles_x", 0.0f ), inResourceData->GetFloat( "angles_y", 0.0f ), inResourceData->GetFloat( "angles_z", 0.0f ) );
+ m_BMPResData.m_vecOriginOffset.Init( inResourceData->GetFloat( "origin_x", 110.0 ), inResourceData->GetFloat( "origin_y", 5.0 ), inResourceData->GetFloat( "origin_z", 5.0 ) );
+ m_BMPResData.m_vecFramedOriginOffset.Init( inResourceData->GetFloat( "frame_origin_x", 110.0 ), inResourceData->GetFloat( "frame_origin_y", 5.0 ), inResourceData->GetFloat( "frame_origin_z", 5.0 ) );
+ m_BMPResData.m_vecViewportOffset.Init();
+ m_BMPResData.m_nSkin = inResourceData->GetInt( "skin", -1 );
+ m_BMPResData.m_bUseSpotlight = ( inResourceData->GetInt( "spotlight", 0 ) == 1 );
+
+ m_angPlayer = m_BMPResData.m_angModelPoseRot;
+ m_vecPlayerPos = m_BMPResData.m_vecOriginOffset;
+
+ for ( KeyValues *pData = inResourceData->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pData->GetName(), "animation" ) )
+ {
+ ParseModelAnimInfo( pData );
+ }
+ else if ( !Q_stricmp( pData->GetName(), "attached_model" ) )
+ {
+ ParseModelAttachInfo( pData );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ParseModelAnimInfo( KeyValues *inResourceData )
+{
+ if ( !inResourceData )
+ return;
+
+ int iAnim = m_BMPResData.m_aAnimations.AddToTail();
+ if ( iAnim == m_BMPResData.m_aAnimations.InvalidIndex() )
+ return;
+
+ m_BMPResData.m_aAnimations[iAnim].m_pszName = ReadAndAllocStringValue( inResourceData, "name" );
+ m_BMPResData.m_aAnimations[iAnim].m_pszSequence = ReadAndAllocStringValue( inResourceData, "sequence" );
+ m_BMPResData.m_aAnimations[iAnim].m_pszActivity = ReadAndAllocStringValue( inResourceData, "activity" );
+ m_BMPResData.m_aAnimations[iAnim].m_bDefault = ( inResourceData->GetInt( "default", 0 ) == 1 );
+
+ for ( KeyValues *pAnimData = inResourceData->GetFirstSubKey(); pAnimData != NULL; pAnimData = pAnimData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pAnimData->GetName(), "pose_parameters" ) )
+ {
+ m_BMPResData.m_aAnimations[iAnim].m_pPoseParameters = pAnimData->MakeCopy();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ParseModelAttachInfo( KeyValues *inResourceData )
+{
+ if ( !inResourceData )
+ return;
+
+ int iAttach = m_BMPResData.m_aAttachModels.AddToTail();
+ if ( iAttach == m_BMPResData.m_aAttachModels.InvalidIndex() )
+ return;
+
+ m_BMPResData.m_aAttachModels[iAttach].m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
+ m_BMPResData.m_aAttachModels[iAttach].m_nSkin = inResourceData->GetInt( "skin", -1 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetupModelDefaults( void )
+{
+ SetupModelAnimDefaults();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetupModelAnimDefaults( void )
+{
+ // Set the move_x parameter so the run activity works
+ SetPoseParameterByName( "move_x", 1.0f );
+
+ // Verify that we have animations for this model.
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ if ( nAnimCount == 0 )
+ return;
+
+ // Find the default animation if one exists.
+ int iIndex = FindDefaultAnim();
+ if ( iIndex == -1 )
+ return;
+
+ SetModelAnim( iIndex );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBaseModelPanel::FindDefaultAnim( void )
+{
+ int iIndex = -1;
+
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ for ( int iAnim = 0; iAnim < nAnimCount; ++iAnim )
+ {
+ if ( m_BMPResData.m_aAnimations[iAnim].m_bDefault )
+ return iAnim;
+ }
+
+ return iIndex;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBaseModelPanel::FindAnimByName( const char *pszName )
+{
+ int iIndex = -1;
+ if ( !pszName )
+ return iIndex;
+
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ for ( int iAnim = 0; iAnim < nAnimCount; ++iAnim )
+ {
+ if ( !Q_stricmp( m_BMPResData.m_aAnimations[iAnim].m_pszName, pszName ) )
+ return iAnim;
+ }
+
+ return iIndex;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBaseModelPanel::FindSequenceFromActivity( CStudioHdr *pStudioHdr, const char *pszActivity )
+{
+ if ( !pStudioHdr )
+ return -1;
+
+ for ( int iSeq = 0; iSeq < pStudioHdr->GetNumSeq(); ++iSeq )
+ {
+ mstudioseqdesc_t &seqDesc = pStudioHdr->pSeqdesc( iSeq );
+ if ( !V_stricmp( seqDesc.pszActivityName(), pszActivity ) )
+ {
+ return iSeq;
+ }
+ }
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetModelAnim( int iAnim )
+{
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ if ( nAnimCount == 0 || !m_BMPResData.m_aAnimations.IsValidIndex( iAnim ) )
+ return;
+
+ MDLCACHE_CRITICAL_SECTION();
+
+ // Get the studio header of the root model.
+ studiohdr_t *pStudioHdr = m_RootMDL.m_MDL.GetStudioHdr();
+ if ( !pStudioHdr )
+ return;
+
+ CStudioHdr studioHdr( pStudioHdr, g_pMDLCache );
+
+ // Do we have an activity or a sequence?
+ int iSequence = ACT_INVALID;
+ if ( m_BMPResData.m_aAnimations[iAnim].m_pszActivity && m_BMPResData.m_aAnimations[iAnim].m_pszActivity[0] )
+ {
+ iSequence = FindSequenceFromActivity( &studioHdr, m_BMPResData.m_aAnimations[iAnim].m_pszActivity );
+ }
+ else if ( m_BMPResData.m_aAnimations[iAnim].m_pszSequence && m_BMPResData.m_aAnimations[iAnim].m_pszSequence[0] )
+ {
+ iSequence = LookupSequence( &studioHdr, m_BMPResData.m_aAnimations[iAnim].m_pszSequence );
+ }
+
+ if ( iSequence != ACT_INVALID )
+ {
+ SetSequence( iSequence );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetMDL( MDLHandle_t handle, void *pProxyData )
+{
+ MDLCACHE_CRITICAL_SECTION();
+ studiohdr_t *pHdr = g_pMDLCache->GetStudioHdr( handle );
+
+ if ( pHdr )
+ {
+ // SetMDL will cause the base CMdl code to set our localtoglobal indices if they aren't set.
+ // We set them up here so that they're left alone by that code.
+ CStudioHdr studioHdr( pHdr, g_pMDLCache );
+ if (studioHdr.numflexcontrollers() > 0 && studioHdr.pFlexcontroller( LocalFlexController_t(0) )->localToGlobal == -1)
+ {
+ for (LocalFlexController_t i = LocalFlexController_t(0); i < studioHdr.numflexcontrollers(); i++)
+ {
+ int j = C_BaseFlex::AddGlobalFlexController( studioHdr.pFlexcontroller( i )->pszName() );
+ studioHdr.pFlexcontroller( i )->localToGlobal = j;
+ }
+ }
+ }
+ else
+ {
+ handle = MDLHANDLE_INVALID;
+ }
+
+ // Clear our current sequence
+ SetSequence( ACT_IDLE );
+
+ BaseClass::SetMDL( handle, pProxyData );
+
+ SetupModelDefaults();
+
+ // Need to invalidate the layout so the panel will adjust is LookAt for the new model.
+ InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetModelAnglesAndPosition( const QAngle &angRot, const Vector &vecPos )
+{
+ BaseClass::SetModelAnglesAndPosition( angRot, vecPos );
+
+ // Cache
+ m_vecPlayerPos = vecPos;
+ m_angPlayer = angRot;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetMDL( const char *pMDLName, void *pProxyData )
+{
+ BaseClass::SetMDL( pMDLName, pProxyData );
+
+ // Need to invalidate the layout so the panel will adjust is LookAt for the new model.
+// InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ if ( m_bForcedCameraPosition )
+ {
+ return;
+ }
+
+ if ( m_bAllowFullManipulation )
+ {
+ // Set this to true if you want to keep the current rotation when changing models or poses
+ const bool bPreserveManipulation = false;
+
+ // Need to look at the target so we can rotate around it
+ const Vector kVecFocalPoint( 0.0f, 0.0f, 60.0f );
+ ResetCameraPivot();
+ SetCameraOffset( -(m_vecPlayerPos + kVecFocalPoint) );
+ SetCameraPositionAndAngles( kVecFocalPoint, vec3_angle, !bPreserveManipulation );
+
+ // We want to move the player to the origin and facing the correct way,
+ // but don't clobber m_angPlayer and m_vecPlayerPos, so use BaseClass.
+ BaseClass::SetModelAnglesAndPosition( m_angPlayer, vec3_origin );
+
+ // Once a manual transform has been done we want to apply it
+ if ( m_bApplyManipulators )
+ {
+ ApplyManipulation();
+ }
+ else
+ {
+ SyncManipulation();
+ }
+ return;
+ }
+
+ if ( m_bForcePos )
+ {
+ ResetCameraPivot();
+ SetCameraOffset( Vector( 0.0f, 0.0f, 0.0f ) );
+ SetCameraPositionAndAngles( vec3_origin, vec3_angle );
+ SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos );
+ }
+
+ // Center and fill the frame with the model?
+ if ( m_bStartFramed )
+ {
+ Vector vecBoundsMin, vecBoundsMax;
+ if ( GetBoundingBox( vecBoundsMin, vecBoundsMax ) )
+ {
+ LookAtBounds( vecBoundsMin, vecBoundsMax );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnKeyCodePressed ( vgui::KeyCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnKeyCodePressed( code );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnKeyCodeReleased( vgui::KeyCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnKeyCodeReleased( code );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnMousePressed ( vgui::MouseCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnMousePressed( code );
+ return;
+ }
+
+ if ( !m_bAllowRotation )
+ return;
+
+ RequestFocus();
+
+ EnableMouseCapture( true, code );
+
+ // Warp the mouse to the center of the screen
+ int width, height;
+ GetSize( width, height );
+ int x = width / 2;
+ int y = height / 2;
+
+ int xpos = x;
+ int ypos = y;
+ LocalToScreen( xpos, ypos );
+ input()->SetCursorPos( xpos, ypos );
+
+ m_nManipStartX = xpos;
+ m_nManipStartY = ypos;
+
+ m_bMousePressed = true;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnMouseReleased( vgui::MouseCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnMouseReleased( code );
+ return;
+ }
+
+ if ( !m_bAllowRotation )
+ return;
+
+ EnableMouseCapture( false );
+ m_bMousePressed = false;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnCursorMoved( int x, int y )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ if ( m_pCurrentManip )
+ {
+ m_bApplyManipulators = true;
+ }
+ BaseClass::OnCursorMoved( x, y );
+ return;
+ }
+
+ if ( !m_bAllowRotation )
+ return;
+
+ if ( m_bMousePressed )
+ {
+ WarpMouse( x, y );
+ int xpos, ypos;
+ input()->GetCursorPos( xpos, ypos );
+
+ // Only want the x delta.
+ float flDelta = xpos - m_nManipStartX;
+
+ // Apply the delta and rotate the player.
+ RotateYaw( flDelta );
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::RotateYaw( float flDelta )
+{
+ m_angPlayer.y += flDelta;
+ if ( m_angPlayer.y > 360.0f )
+ {
+ m_angPlayer.y = m_angPlayer.y - 360.0f;
+ }
+ else if ( m_angPlayer.y < -360.0f )
+ {
+ m_angPlayer.y = m_angPlayer.y + 360.0f;
+ }
+
+ SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+Vector CBaseModelPanel::GetPlayerPos() const
+{
+ return m_vecPlayerPos;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+QAngle CBaseModelPanel::GetPlayerAngles() const
+{
+ return m_angPlayer;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnMouseWheeled( int delta )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnMouseWheeled( delta );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Set the camera to a distance that allows the object to fill the model panel.
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::LookAtBounds( const Vector &vecBoundsMin, const Vector &vecBoundsMax )
+{
+ // Get the model space render bounds.
+ Vector vecMin = vecBoundsMin;
+ Vector vecMax = vecBoundsMax;
+ Vector vecCenter = ( vecMax + vecMin ) * 0.5f;
+ vecMin -= vecCenter;
+ vecMax -= vecCenter;
+
+ // Get the bounds points and transform them by the desired model panel rotation.
+ Vector aBoundsPoints[8];
+ aBoundsPoints[0].Init( vecMax.x, vecMax.y, vecMax.z );
+ aBoundsPoints[1].Init( vecMin.x, vecMax.y, vecMax.z );
+ aBoundsPoints[2].Init( vecMax.x, vecMin.y, vecMax.z );
+ aBoundsPoints[3].Init( vecMin.x, vecMin.y, vecMax.z );
+ aBoundsPoints[4].Init( vecMax.x, vecMax.y, vecMin.z );
+ aBoundsPoints[5].Init( vecMin.x, vecMax.y, vecMin.z );
+ aBoundsPoints[6].Init( vecMax.x, vecMin.y, vecMin.z );
+ aBoundsPoints[7].Init( vecMin.x, vecMin.y, vecMin.z );
+
+ // Translated center point (offset from camera center).
+ Vector vecTranslateCenter = -vecCenter;
+
+ // Build the rotation matrix.
+ matrix3x4_t matRotation;
+ AngleMatrix( m_BMPResData.m_angModelPoseRot, matRotation );
+
+ Vector aXFormPoints[8];
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ VectorTransform( aBoundsPoints[iPoint], matRotation, aXFormPoints[iPoint] );
+ }
+
+ Vector vecXFormCenter;
+ VectorTransform( -vecTranslateCenter, matRotation, vecXFormCenter );
+
+ int w, h;
+ GetSize( w, h );
+ float flW = (float)w;
+ float flH = (float)h;
+
+ float flFOVx = DEG2RAD( m_BMPResData.m_flFOV * 0.5f );
+ float flFOVy = CalcFovY( ( m_BMPResData.m_flFOV * 0.5f ), flW/flH );
+ flFOVy = DEG2RAD( flFOVy );
+
+ float flTanFOVx = tan( flFOVx );
+ float flTanFOVy = tan( flFOVy );
+
+ // Find the max value of x, y, or z
+ Vector2D dist[8];
+ float flDist = 0.0f;
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ float flDistY = fabs( aXFormPoints[iPoint].y / flTanFOVx ) - aXFormPoints[iPoint].x;
+ float flDistZ = fabs( aXFormPoints[iPoint].z / flTanFOVy ) - aXFormPoints[iPoint].x;
+ dist[iPoint].x = flDistY;
+ dist[iPoint].y = flDistZ;
+ float flTestDist = MAX( flDistZ, flDistY );
+ flDist = MAX( flDist, flTestDist );
+ }
+
+ // Screen space points.
+ Vector2D aScreenPoints[8];
+ Vector aCameraPoints[8];
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ aCameraPoints[iPoint] = aXFormPoints[iPoint];
+ aCameraPoints[iPoint].x += flDist;
+
+ aScreenPoints[iPoint].x = aCameraPoints[iPoint].y / ( flTanFOVx * aCameraPoints[iPoint].x );
+ aScreenPoints[iPoint].y = aCameraPoints[iPoint].z / ( flTanFOVy * aCameraPoints[iPoint].x );
+
+ aScreenPoints[iPoint].x = ( aScreenPoints[iPoint].x * 0.5f + 0.5f ) * flW;
+ aScreenPoints[iPoint].y = ( aScreenPoints[iPoint].y * 0.5f + 0.5f ) * flH;
+ }
+
+ // Find the min/max and center of the 2D bounding box of the object.
+ Vector2D vecScreenMin( 99999.0f, 99999.0f ), vecScreenMax( -99999.0f, -99999.0f );
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ vecScreenMin.x = MIN( vecScreenMin.x, aScreenPoints[iPoint].x );
+ vecScreenMin.y = MIN( vecScreenMin.y, aScreenPoints[iPoint].y );
+ vecScreenMax.x = MAX( vecScreenMax.x, aScreenPoints[iPoint].x );
+ vecScreenMax.y = MAX( vecScreenMax.y, aScreenPoints[iPoint].y );
+ }
+
+ // Offset the model to the be the correct distance away from the camera.
+ Vector vecModelPos;
+ vecModelPos.x = flDist - vecXFormCenter.x;
+ vecModelPos.y = -vecXFormCenter.y;
+ vecModelPos.z = -vecXFormCenter.z;
+ SetModelAnglesAndPosition( m_BMPResData.m_angModelPoseRot, vecModelPos );
+ m_vecPlayerPos = vecModelPos;
+
+ // Back project to figure out the camera offset to center the model.
+ Vector2D vecPanelCenter( ( flW * 0.5f ), ( flH * 0.5f ) );
+ Vector2D vecScreenCenter = ( vecScreenMax + vecScreenMin ) * 0.5f;
+
+ Vector2D vecPanelCenterCamera, vecScreenCenterCamera;
+ vecPanelCenterCamera.x = ( ( vecPanelCenter.x / flW ) * 2.0f ) - 0.5f;
+ vecPanelCenterCamera.y = ( ( vecPanelCenter.y / flH ) * 2.0f ) - 0.5f;
+ vecPanelCenterCamera.x *= ( flTanFOVx * flDist );
+ vecPanelCenterCamera.y *= ( flTanFOVy * flDist );
+ vecScreenCenterCamera.x = ( ( vecScreenCenter.x / flW ) * 2.0f ) - 0.5f;
+ vecScreenCenterCamera.y = ( ( vecScreenCenter.y / flH ) * 2.0f ) - 0.5f;
+ vecScreenCenterCamera.x *= ( flTanFOVx * flDist );
+ vecScreenCenterCamera.y *= ( flTanFOVy * flDist );
+
+ Vector2D vecCameraOffset( 0.0f, 0.0f );
+ vecCameraOffset.x = vecPanelCenterCamera.x - vecScreenCenterCamera.x;
+ vecCameraOffset.y = vecPanelCenterCamera.y - vecScreenCenterCamera.y;
+
+ // Clear the camera pivot and set position matrix.
+ ResetCameraPivot();
+ if (m_bAllowRotation )
+ {
+ vecCameraOffset.x = 0.0f;
+ }
+ SetCameraOffset( Vector( 0.0f, -vecCameraOffset.x, -vecCameraOffset.y ) );
+ UpdateCameraTransform();
+}
+
|