632 lines
21 KiB
C++
632 lines
21 KiB
C++
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "matsys_controls/mdlpanel.h"
|
|
#include "materialsystem/imaterialsystem.h"
|
|
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
|
#include "materialsystem/imesh.h"
|
|
#include "vgui/IVGui.h"
|
|
#include "tier1/keyvalues.h"
|
|
#include "vgui_controls/Frame.h"
|
|
#include "tier1/convar.h"
|
|
#include "tier0/dbg.h"
|
|
#include "istudiorender.h"
|
|
#include "matsys_controls/matsyscontrols.h"
|
|
#include "vcollide.h"
|
|
#include "vcollide_parse.h"
|
|
#include "bone_setup.h"
|
|
#include "renderparm.h"
|
|
#include "vphysics_interface.h"
|
|
#include "game/client/irendercaptureconfiguration.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
using namespace vgui;
|
|
|
|
DECLARE_BUILD_FACTORY( CMDLPanel );
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Keeps a global clock to autoplay sequences to run from
|
|
// Also deals with speedScale changes
|
|
//-----------------------------------------------------------------------------
|
|
static float GetAutoPlayTime( void )
|
|
{
|
|
static int g_prevTicks;
|
|
static float g_time;
|
|
|
|
int ticks = Plat_MSTime();
|
|
|
|
// limit delta so that float time doesn't overflow
|
|
if (g_prevTicks == 0)
|
|
{
|
|
g_prevTicks = ticks;
|
|
}
|
|
|
|
g_time += ( ticks - g_prevTicks ) / 1000.0f;
|
|
g_prevTicks = ticks;
|
|
|
|
return g_time;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constructor, destructor
|
|
//-----------------------------------------------------------------------------
|
|
CMDLPanel::CMDLPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
|
{
|
|
SetVisible( true );
|
|
|
|
// Used to poll input
|
|
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
|
|
|
SetIdentityMatrix( m_RootMDL.m_MDLToWorld );
|
|
m_bDrawCollisionModel = false;
|
|
m_bWireFrame = false;
|
|
m_bGroundGrid = false;
|
|
m_bLockView = false;
|
|
m_bLookAtCamera = true;
|
|
m_bAnimationPause = false;
|
|
|
|
m_iCameraAttachment = -1;
|
|
m_iRenderCaptureCameraAttachment = -1;
|
|
Q_memset( m_iDirectionalLightAttachments, ~0, sizeof( m_iDirectionalLightAttachments ) );
|
|
|
|
m_flAutoPlayTimeBase = GetAutoPlayTime();
|
|
|
|
m_bCameraOrientOverrideEnabled = false;
|
|
m_bCameraPositionOverrideEnabled = false;
|
|
m_vecCameraOrientOverride.Init();
|
|
m_vecCameraPositionOverride.Init();
|
|
}
|
|
|
|
CMDLPanel::~CMDLPanel()
|
|
{
|
|
m_aMergeMDLs.Purge();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Scheme settings
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
|
{
|
|
BaseClass::ApplySchemeSettings( pScheme );
|
|
SetBackgroundColor( GetBgColor() );
|
|
SetBorder( pScheme->GetBorder( "MenuBorder") );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Rendering options
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::SetCollsionModel( bool bVisible )
|
|
{
|
|
m_bDrawCollisionModel = bVisible;
|
|
}
|
|
|
|
void CMDLPanel::SetGroundGrid( bool bVisible )
|
|
{
|
|
m_bGroundGrid = bVisible;
|
|
}
|
|
|
|
void CMDLPanel::SetWireFrame( bool bVisible )
|
|
{
|
|
m_bWireFrame = bVisible;
|
|
}
|
|
|
|
void CMDLPanel::SetLockView( bool bLocked )
|
|
{
|
|
m_bLockView = bLocked;
|
|
}
|
|
|
|
void CMDLPanel::SetLookAtCamera( bool bLookAtCamera )
|
|
{
|
|
m_bLookAtCamera = bLookAtCamera;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Lock the camera position and angles to an attachment point
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::SetCameraAttachment( const char *pszAttachment )
|
|
{
|
|
// Check to see if we have a valid model to look at.
|
|
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
|
return;
|
|
|
|
SetLookAtCamera( false );
|
|
|
|
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
|
|
|
m_iCameraAttachment = Studio_FindAttachment( &studioHdr, pszAttachment );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Set the light render capture camera position and angles to an attachment point
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::SetRenderCaptureCameraAttachment( const char *pszAttachment )
|
|
{
|
|
// Check to see if we have a valid model to look at.
|
|
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
|
return;
|
|
|
|
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
|
|
|
m_iRenderCaptureCameraAttachment = Studio_FindAttachment( &studioHdr, pszAttachment );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Set the directional light attachment point for direction animation
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::SetDirectionalLightAttachment( int idx, const char *pszAttachment )
|
|
{
|
|
// Check to see if we have a valid model to look at.
|
|
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
|
return;
|
|
if ( idx < 0 || idx >= MATERIAL_MAX_LIGHT_COUNT )
|
|
return;
|
|
|
|
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
|
|
|
m_iDirectionalLightAttachments[idx] = Studio_FindAttachment( &studioHdr, pszAttachment );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Sets the camera to look at the model
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::LookAtMDL()
|
|
{
|
|
// Check to see if we have a valid model to look at.
|
|
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
|
return;
|
|
|
|
if ( m_bLockView )
|
|
return;
|
|
|
|
float flRadius;
|
|
Vector vecCenter;
|
|
GetBoundingSphere( vecCenter, flRadius );
|
|
LookAt( vecCenter, flRadius );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// FIXME: This should be moved into studiorender
|
|
//-----------------------------------------------------------------------------
|
|
static ConVar r_showenvcubemap( "r_showenvcubemap", "0", FCVAR_CHEAT );
|
|
static ConVar r_eyegloss ( "r_eyegloss", "1", FCVAR_ARCHIVE ); // wet eyes
|
|
static ConVar r_eyemove ( "r_eyemove", "1", FCVAR_ARCHIVE ); // look around
|
|
static ConVar r_eyeshift_x ( "r_eyeshift_x", "0", FCVAR_ARCHIVE ); // eye X position
|
|
static ConVar r_eyeshift_y ( "r_eyeshift_y", "0", FCVAR_ARCHIVE ); // eye Y position
|
|
static ConVar r_eyeshift_z ( "r_eyeshift_z", "0", FCVAR_ARCHIVE ); // eye Z position
|
|
static ConVar r_eyesize ( "r_eyesize", "0", FCVAR_ARCHIVE ); // adjustment to iris textures
|
|
static ConVar mat_softwareskin( "mat_softwareskin", "0", FCVAR_CHEAT );
|
|
static ConVar r_nohw ( "r_nohw", "0", FCVAR_CHEAT );
|
|
static ConVar r_nosw ( "r_nosw", "0", FCVAR_CHEAT );
|
|
static ConVar r_teeth ( "r_teeth", "1" );
|
|
static ConVar r_drawentities ( "r_drawentities", "1", FCVAR_CHEAT );
|
|
static ConVar r_flex ( "r_flex", "1" );
|
|
static ConVar r_eyes ( "r_eyes", "1" );
|
|
static ConVar r_skin ( "r_skin","0", FCVAR_CHEAT );
|
|
static ConVar r_maxmodeldecal ( "r_maxmodeldecal", "50" );
|
|
static ConVar r_modelwireframedecal ( "r_modelwireframedecal", "0", FCVAR_CHEAT );
|
|
static ConVar mat_normals ( "mat_normals", "0", FCVAR_CHEAT );
|
|
static ConVar r_eyeglintlodpixels ( "r_eyeglintlodpixels", "0" );
|
|
static ConVar r_rootlod ( "r_rootlod", "0" );
|
|
|
|
static StudioRenderConfig_t s_StudioRenderConfig;
|
|
|
|
void CMDLPanel::UpdateStudioRenderConfig( void )
|
|
{
|
|
memset( &s_StudioRenderConfig, 0, sizeof(s_StudioRenderConfig) );
|
|
|
|
s_StudioRenderConfig.bEyeMove = !!r_eyemove.GetInt();
|
|
s_StudioRenderConfig.fEyeShiftX = r_eyeshift_x.GetFloat();
|
|
s_StudioRenderConfig.fEyeShiftY = r_eyeshift_y.GetFloat();
|
|
s_StudioRenderConfig.fEyeShiftZ = r_eyeshift_z.GetFloat();
|
|
s_StudioRenderConfig.fEyeSize = r_eyesize.GetFloat();
|
|
if( mat_softwareskin.GetInt() || m_bWireFrame )
|
|
{
|
|
s_StudioRenderConfig.bSoftwareSkin = true;
|
|
}
|
|
else
|
|
{
|
|
s_StudioRenderConfig.bSoftwareSkin = false;
|
|
}
|
|
s_StudioRenderConfig.bNoHardware = !!r_nohw.GetInt();
|
|
s_StudioRenderConfig.bNoSoftware = !!r_nosw.GetInt();
|
|
s_StudioRenderConfig.bTeeth = !!r_teeth.GetInt();
|
|
s_StudioRenderConfig.drawEntities = r_drawentities.GetInt();
|
|
s_StudioRenderConfig.bFlex = !!r_flex.GetInt();
|
|
s_StudioRenderConfig.bEyes = !!r_eyes.GetInt();
|
|
s_StudioRenderConfig.bWireframe = m_bWireFrame;
|
|
s_StudioRenderConfig.bDrawNormals = mat_normals.GetBool();
|
|
s_StudioRenderConfig.skin = r_skin.GetInt();
|
|
s_StudioRenderConfig.maxDecalsPerModel = r_maxmodeldecal.GetInt();
|
|
s_StudioRenderConfig.bWireframeDecals = r_modelwireframedecal.GetInt() != 0;
|
|
|
|
s_StudioRenderConfig.fullbright = false;
|
|
s_StudioRenderConfig.bSoftwareLighting = false;
|
|
|
|
s_StudioRenderConfig.bShowEnvCubemapOnly = r_showenvcubemap.GetBool();
|
|
s_StudioRenderConfig.fEyeGlintPixelWidthLODThreshold = r_eyeglintlodpixels.GetFloat();
|
|
|
|
StudioRender()->UpdateConfig( s_StudioRenderConfig );
|
|
}
|
|
|
|
void CMDLPanel::DrawCollisionModel()
|
|
{
|
|
vcollide_t *pCollide = MDLCache()->GetVCollide( m_RootMDL.m_MDL.GetMDL() );
|
|
|
|
if ( !pCollide || pCollide->solidCount <= 0 )
|
|
return;
|
|
|
|
static color32 color = {255,0,0,0};
|
|
|
|
IVPhysicsKeyParser *pParser = g_pPhysicsCollision->VPhysicsKeyParserCreate( pCollide );
|
|
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
|
|
|
matrix3x4_t pBoneToWorld[MAXSTUDIOBONES];
|
|
m_RootMDL.m_MDL.SetUpBones( m_RootMDL.m_MDLToWorld, MAXSTUDIOBONES, pBoneToWorld );
|
|
|
|
// PERFORMANCE: Just parse the script each frame. It's fast enough for tools. If you need
|
|
// this to go faster then cache off the bone index mapping in an array like HLMV does
|
|
while ( !pParser->Finished() )
|
|
{
|
|
const char *pBlock = pParser->GetCurrentBlockName();
|
|
if ( !stricmp( pBlock, "solid" ) )
|
|
{
|
|
solid_t solid;
|
|
|
|
pParser->ParseSolid( &solid, NULL );
|
|
int boneIndex = Studio_BoneIndexByName( &studioHdr, solid.name );
|
|
Vector *outVerts;
|
|
int vertCount = g_pPhysicsCollision->CreateDebugMesh( pCollide->solids[solid.index], &outVerts );
|
|
|
|
if ( vertCount )
|
|
{
|
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|
pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
|
|
// NOTE: assumes these have been set up already by the model render code
|
|
// So this is a little bit of a back door to a cache of the bones
|
|
// this code wouldn't work unless you draw the model this frame before calling
|
|
// this routine. CMDLPanel always does this, but it's worth noting.
|
|
// A better solution would be to move the ragdoll visulization into the CDmeMdl
|
|
// and either draw it there or make it queryable and query/draw here.
|
|
matrix3x4_t xform;
|
|
SetIdentityMatrix( xform );
|
|
if ( boneIndex >= 0 )
|
|
{
|
|
MatrixCopy( pBoneToWorld[ boneIndex ], xform );
|
|
}
|
|
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, GetWireframeMaterial() );
|
|
|
|
CMeshBuilder meshBuilder;
|
|
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, vertCount/3 );
|
|
|
|
for ( int j = 0; j < vertCount; j++ )
|
|
{
|
|
Vector out;
|
|
VectorTransform( outVerts[j].Base(), xform, out.Base() );
|
|
meshBuilder.Position3fv( out.Base() );
|
|
meshBuilder.Color4ub( color.r, color.g, color.b, color.a );
|
|
meshBuilder.TexCoord2f( 0, 0, 0 );
|
|
meshBuilder.AdvanceVertex();
|
|
}
|
|
meshBuilder.End();
|
|
pMesh->Draw();
|
|
}
|
|
|
|
g_pPhysicsCollision->DestroyDebugMesh( vertCount, outVerts );
|
|
}
|
|
else
|
|
{
|
|
pParser->SkipBlock();
|
|
}
|
|
}
|
|
g_pPhysicsCollision->VPhysicsKeyParserDestroy( pParser );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// paint it!
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::OnPaint3D()
|
|
{
|
|
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
|
return;
|
|
|
|
// FIXME: Move this call into DrawModel in StudioRender
|
|
StudioRenderConfig_t oldStudioRenderConfig;
|
|
StudioRender()->GetCurrentConfig( oldStudioRenderConfig );
|
|
|
|
UpdateStudioRenderConfig();
|
|
|
|
CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
|
|
|
|
// We want the models to use their natural alpha, not depth in alpha
|
|
pRenderContext->SetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA, 0 );
|
|
|
|
if ( IsPaint3dForRenderCapture() )
|
|
{
|
|
// We are rendering into flashlight depth texture
|
|
pRenderContext->SetFlashlightMode( false ); // disable shadows since we should be using DEPTH_WRITE material
|
|
}
|
|
else if ( GetRenderingWithFlashlightConfiguration() )
|
|
{
|
|
// Setup shadow state that we configured
|
|
g_pStudioRender->ClearAllShadows();
|
|
// NOTE: flashlight shadow is added post bone setup
|
|
}
|
|
else
|
|
{
|
|
// flashlights can't work in the model panel under queued mode (the state isn't ready yet, so causes a crash)
|
|
pRenderContext->SetFlashlightMode( false );
|
|
}
|
|
|
|
ITexture *pMyCube = materials->FindTexture( "engine/defaultcubemap", TEXTURE_GROUP_CUBE_MAP, true );
|
|
|
|
if ( HasLightProbe() )
|
|
{
|
|
pMyCube = GetLightProbeCubemap( vgui::MaterialSystemHardwareConfig()->GetHDRType() != HDR_TYPE_NONE );
|
|
}
|
|
pRenderContext->BindLocalCubemap( pMyCube );
|
|
|
|
if ( m_bGroundGrid )
|
|
{
|
|
DrawGrid();
|
|
}
|
|
|
|
if ( m_bLookAtCamera )
|
|
{
|
|
matrix3x4_t worldToCamera;
|
|
ComputeCameraTransform( &worldToCamera );
|
|
|
|
Vector vecPosition;
|
|
MatrixGetColumn( worldToCamera, 3, vecPosition );
|
|
m_RootMDL.m_MDL.m_bWorldSpaceViewTarget = true;
|
|
m_RootMDL.m_MDL.m_vecViewTarget = vecPosition;
|
|
}
|
|
|
|
Draw();
|
|
|
|
if ( m_bDrawCollisionModel )
|
|
{
|
|
DrawCollisionModel();
|
|
}
|
|
|
|
if ( IsPaint3dForRenderCapture() )
|
|
{
|
|
// We are finished rendering into flashlight buffer
|
|
}
|
|
else if ( GetRenderingWithFlashlightConfiguration() )
|
|
{
|
|
// Clear all shadow state that we configured and used now
|
|
g_pStudioRender->ClearAllShadows();
|
|
}
|
|
|
|
pRenderContext->Flush();
|
|
StudioRender()->UpdateConfig( oldStudioRenderConfig );
|
|
}
|
|
|
|
void CMDLPanel::OnModelDrawPassStart( int iPass, CStudioHdr *pStudioHdr, int &nFlags )
|
|
{
|
|
if ( IsPaint3dForRenderCapture() )
|
|
nFlags |= STUDIORENDER_SHADOWDEPTHTEXTURE;
|
|
else if ( GetRenderingWithFlashlightConfiguration() )
|
|
nFlags &=~STUDIORENDER_DRAW_NO_SHADOWS;
|
|
}
|
|
|
|
void CMDLPanel::OnModelDrawPassFinished( int iPass, CStudioHdr *pStudioHdr, int &nFlags )
|
|
{
|
|
}
|
|
|
|
void CMDLPanel::OnPostSetUpBonesPreDraw()
|
|
{
|
|
bool bFlashlightPosKnown = false;
|
|
Vector vecPositionFlashlight;
|
|
QAngle anglesFlashlight;
|
|
|
|
bool bCameraPosKnown = false;
|
|
Vector vecPositionCamera;
|
|
QAngle anglesCamera;
|
|
|
|
if ( m_iRenderCaptureCameraAttachment >= 0 )
|
|
{
|
|
matrix3x4_t camera;
|
|
if ( GetAttachment( m_iRenderCaptureCameraAttachment+1, camera ) )
|
|
{
|
|
Vector vecPosition;
|
|
QAngle angles;
|
|
|
|
MatrixPosition( camera, vecPosition );
|
|
MatrixAngles( camera, angles );
|
|
|
|
bFlashlightPosKnown = true;
|
|
vecPositionFlashlight = vecPosition;
|
|
anglesFlashlight = angles;
|
|
}
|
|
}
|
|
|
|
if ( m_iCameraAttachment >= 0 )
|
|
{
|
|
matrix3x4_t camera;
|
|
if ( GetAttachment( m_iCameraAttachment+1, camera ) )
|
|
{
|
|
Vector vecPosition;
|
|
QAngle angles;
|
|
|
|
MatrixPosition( camera, vecPosition );
|
|
MatrixAngles( camera, angles );
|
|
|
|
bCameraPosKnown = true;
|
|
vecPositionCamera = vecPosition;
|
|
anglesCamera = angles;
|
|
|
|
if ( IsCameraPositionOverrideEnabled() )
|
|
{
|
|
vecPositionCamera += m_vecCameraPositionOverride;
|
|
}
|
|
|
|
if ( !bFlashlightPosKnown )
|
|
{
|
|
// DEBUG: move light off from the actual camera
|
|
Vector basisUp, basisRight, basisForward;
|
|
AngleVectors( angles, &basisForward, &basisRight, &basisUp );
|
|
|
|
float flCycle0to1 = ( m_RootMDL.m_MDL.m_flTime - floor( m_RootMDL.m_MDL.m_flTime ) );
|
|
float flDistance = 1.0f + ( flCycle0to1 - 0.5f ) * ( flCycle0to1 - 0.5f ) * 4 * 9;
|
|
vecPosition += basisUp * flDistance;
|
|
|
|
bFlashlightPosKnown = true;
|
|
vecPositionFlashlight = vecPosition;
|
|
anglesFlashlight = angles;
|
|
}
|
|
|
|
if ( IsCameraOrientOverrideEnabled() )
|
|
{
|
|
anglesCamera.x += m_vecCameraOrientOverride.x;
|
|
anglesCamera.y += m_vecCameraOrientOverride.y;
|
|
anglesCamera.z += m_vecCameraOrientOverride.z;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if ( bFlashlightPosKnown && GetRenderingWithFlashlightConfiguration() != NULL )
|
|
{
|
|
CRenderCaptureConfigurationState *pFlashlightInfo = reinterpret_cast< CRenderCaptureConfigurationState * >( GetRenderingWithFlashlightConfiguration() );
|
|
|
|
//
|
|
// Update flashlight position
|
|
//
|
|
{
|
|
pFlashlightInfo->m_renderFlashlightState.m_vecLightOrigin = vecPositionFlashlight;
|
|
AngleQuaternion( anglesFlashlight, pFlashlightInfo->m_renderFlashlightState.m_quatOrientation );
|
|
}
|
|
|
|
//
|
|
// Build world to shadow matrix, then perspective projection and concatenate
|
|
//
|
|
{
|
|
VMatrix matWorldToShadowView, matPerspective;
|
|
matrix3x4_t matOrientation;
|
|
QuaternionMatrix( pFlashlightInfo->m_renderFlashlightState.m_quatOrientation, matOrientation ); // Convert quat to matrix3x4
|
|
PositionMatrix( vec3_origin, matOrientation ); // Zero out translation elements
|
|
|
|
VMatrix matBasis( matOrientation ); // Convert matrix3x4 to VMatrix
|
|
|
|
Vector vForward, vLeft, vUp;
|
|
matBasis.GetBasisVectors( vForward, vLeft, vUp );
|
|
matBasis.SetForward( vLeft ); // Bizarre vector flip inherited from earlier code, WTF?
|
|
matBasis.SetLeft( vUp );
|
|
matBasis.SetUp( vForward );
|
|
matWorldToShadowView = matBasis.Transpose(); // Transpose
|
|
|
|
Vector translation;
|
|
Vector3DMultiply( matWorldToShadowView, pFlashlightInfo->m_renderFlashlightState.m_vecLightOrigin, translation );
|
|
|
|
translation *= -1.0f;
|
|
matWorldToShadowView.SetTranslation( translation );
|
|
|
|
// The the bottom row.
|
|
matWorldToShadowView[3][0] = matWorldToShadowView[3][1] = matWorldToShadowView[3][2] = 0.0f;
|
|
matWorldToShadowView[3][3] = 1.0f;
|
|
|
|
MatrixBuildPerspective( matPerspective, pFlashlightInfo->m_renderFlashlightState.m_fHorizontalFOVDegrees,
|
|
pFlashlightInfo->m_renderFlashlightState.m_fVerticalFOVDegrees,
|
|
pFlashlightInfo->m_renderFlashlightState.m_NearZ, pFlashlightInfo->m_renderFlashlightState.m_FarZ );
|
|
|
|
MatrixMultiply( matPerspective, matWorldToShadowView, pFlashlightInfo->m_renderMatrixWorldToShadow );
|
|
}
|
|
}
|
|
|
|
for ( int j = 0; j < ( int ) MIN( m_LightingState.m_nLocalLightCount, Q_ARRAYSIZE( m_iDirectionalLightAttachments ) ); ++ j )
|
|
{
|
|
if ( m_iDirectionalLightAttachments[j] >= 0 )
|
|
{
|
|
matrix3x4_t camera;
|
|
if ( GetAttachment( m_iDirectionalLightAttachments[j]+1, camera ) )
|
|
{
|
|
Vector vecPosition;
|
|
QAngle angles;
|
|
|
|
MatrixPosition( camera, vecPosition );
|
|
MatrixAngles( camera, angles );
|
|
|
|
Vector vecForward;
|
|
AngleVectors( angles, &vecForward );
|
|
m_LightingState.m_pLocalLightDesc[j].m_Direction = vecForward;
|
|
m_LightingState.m_pLocalLightDesc[j].RecalculateDerivedValues();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( IsPaint3dForRenderCapture() )
|
|
{
|
|
Assert( bFlashlightPosKnown );
|
|
CRenderCaptureConfigurationState *pFlashlightInfo = reinterpret_cast< CRenderCaptureConfigurationState * >( GetRenderingWithFlashlightConfiguration() );
|
|
SetCameraPositionAndAngles( vecPositionFlashlight, anglesFlashlight );
|
|
|
|
Camera_t &cameraSettings = GetCameraSettings();
|
|
float flZnear = cameraSettings.m_flZNear, flZfar = cameraSettings.m_flZFar;
|
|
cameraSettings.m_flZNear = pFlashlightInfo->m_renderFlashlightState.m_NearZ;
|
|
cameraSettings.m_flZFar = pFlashlightInfo->m_renderFlashlightState.m_FarZ;
|
|
SetupRenderStateDelayed(); // Configure view with the updated camera settings and restore Z planes
|
|
cameraSettings.m_flZNear = flZnear, cameraSettings.m_flZFar = flZfar;
|
|
}
|
|
else
|
|
{
|
|
if ( bCameraPosKnown )
|
|
{
|
|
SetCameraPositionAndAngles( vecPositionCamera, anglesCamera );
|
|
}
|
|
SetupRenderStateDelayed();
|
|
if ( GetRenderingWithFlashlightConfiguration() )
|
|
{
|
|
Assert( bFlashlightPosKnown );
|
|
// Add the shadow we rendered in previous pass to our model
|
|
CRenderCaptureConfigurationState *pFlashlightInfo = reinterpret_cast< CRenderCaptureConfigurationState * >( GetRenderingWithFlashlightConfiguration() );
|
|
g_pStudioRender->AddShadow( NULL, NULL, &pFlashlightInfo->m_renderFlashlightState, &pFlashlightInfo->m_renderMatrixWorldToShadow, pFlashlightInfo->m_pFlashlightDepthTexture );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// called when we're ticked...
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::OnTick()
|
|
{
|
|
BaseClass::OnTick();
|
|
float flCurrentTime = GetAutoPlayTime();
|
|
float flMdlTime = flCurrentTime - m_flAutoPlayTimeBase;
|
|
m_flAutoPlayTimeBase = flCurrentTime;
|
|
if ( m_RootMDL.m_MDL.GetMDL() != MDLHANDLE_INVALID && !m_bAnimationPause )
|
|
{
|
|
m_RootMDL.m_MDL.AdjustTime( flMdlTime );
|
|
}
|
|
for ( int k = 0; k < m_aMergeMDLs.Count(); ++ k )
|
|
{
|
|
if ( m_aMergeMDLs[k].m_MDL.GetMDL() != MDLHANDLE_INVALID && !m_bAnimationPause )
|
|
{
|
|
m_aMergeMDLs[k].m_MDL.AdjustTime( flMdlTime );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// input
|
|
//-----------------------------------------------------------------------------
|
|
void CMDLPanel::OnMouseDoublePressed( vgui::MouseCode code )
|
|
{
|
|
float flRadius;
|
|
Vector vecCenter;
|
|
GetBoundingSphere( vecCenter, flRadius );
|
|
LookAt( vecCenter, flRadius );
|
|
|
|
BaseClass::OnMouseDoublePressed( code );
|
|
}
|
|
|
|
|