1
This commit is contained in:
347
tier3/choreoutils.cpp
Normal file
347
tier3/choreoutils.cpp
Normal file
@ -0,0 +1,347 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Helper methods + classes for file access
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "tier3/choreoutils.h"
|
||||
#include "tier3/tier3.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "studio.h"
|
||||
#include "../game/shared/choreoscene.h"
|
||||
#include "../game/shared/choreoevent.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "bone_setup.h"
|
||||
#include "soundchars.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find sequence by name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int LookupSequence( CStudioHdr *pStudioHdr, const char *pSequenceName )
|
||||
{
|
||||
for ( int i = 0; i < pStudioHdr->GetNumSeq(); i++ )
|
||||
{
|
||||
if ( !Q_stricmp( pSequenceName, pStudioHdr->pSeqdesc( i ).pszLabel() ) )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns sequence flags
|
||||
//-----------------------------------------------------------------------------
|
||||
static int GetSequenceFlags( CStudioHdr *pStudioHdr, int nSequence )
|
||||
{
|
||||
if ( !pStudioHdr || nSequence < 0 || nSequence >= pStudioHdr->GetNumSeq() )
|
||||
return 0;
|
||||
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( nSequence );
|
||||
return seqdesc.flags;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does a sequence loop?
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool DoesSequenceLoop( CStudioHdr *pStudioHdr, int nSequence )
|
||||
{
|
||||
int nFlags = GetSequenceFlags( pStudioHdr, nSequence );
|
||||
bool bLooping = ( nFlags & STUDIO_LOOPING ) ? true : false;
|
||||
return bLooping;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool AutoAddGestureKeys( CChoreoEvent *e, CStudioHdr *pStudioHdr, float *pPoseParameters, bool bCheckOnly )
|
||||
{
|
||||
int iSequence = LookupSequence( pStudioHdr, e->GetParameters() );
|
||||
if ( iSequence < 0 )
|
||||
return false;
|
||||
|
||||
KeyValues *pSeqKeyValues = new KeyValues( "" );
|
||||
if ( !pSeqKeyValues->LoadFromBuffer( pStudioHdr->pszName(), Studio_GetKeyValueText( pStudioHdr, iSequence ) ) )
|
||||
{
|
||||
pSeqKeyValues->deleteThis();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do we have a build point section?
|
||||
KeyValues *pKVAllFaceposer = pSeqKeyValues->FindKey("faceposer");
|
||||
if ( !pKVAllFaceposer )
|
||||
{
|
||||
pSeqKeyValues->deleteThis();
|
||||
return false;
|
||||
}
|
||||
|
||||
int nMaxFrame = Studio_MaxFrame( pStudioHdr, iSequence, pPoseParameters ) - 1;
|
||||
|
||||
// Start grabbing the sounds and slotting them in
|
||||
KeyValues *pkvFaceposer;
|
||||
char szStartLoop[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "loop" };
|
||||
char szEndLoop[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "end" };
|
||||
char szEntry[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "apex" };
|
||||
char szExit[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "end" };
|
||||
|
||||
for ( pkvFaceposer = pKVAllFaceposer->GetFirstSubKey(); pkvFaceposer; pkvFaceposer = pkvFaceposer->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( pkvFaceposer->GetName(), "startloop" ) )
|
||||
{
|
||||
Q_strncpy( szStartLoop, pkvFaceposer->GetString(), sizeof(szStartLoop) );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pkvFaceposer->GetName(), "endloop" ) )
|
||||
{
|
||||
Q_strncpy( szEndLoop, pkvFaceposer->GetString(), sizeof(szEndLoop) );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pkvFaceposer->GetName(), "entrytag" ) )
|
||||
{
|
||||
Q_strncpy( szEntry, pkvFaceposer->GetString(), sizeof(szEntry) );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pkvFaceposer->GetName(), "exittag" ) )
|
||||
{
|
||||
Q_strncpy( szExit, pkvFaceposer->GetString(), sizeof(szExit) );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pkvFaceposer->GetName(), "tags" ) )
|
||||
{
|
||||
if ( nMaxFrame <= 0 )
|
||||
continue;
|
||||
|
||||
KeyValues *pkvTags;
|
||||
for ( pkvTags = pkvFaceposer->GetFirstSubKey(); pkvTags; pkvTags = pkvTags->GetNextKey() )
|
||||
{
|
||||
float flPercentage = (float)pkvTags->GetInt() / nMaxFrame;
|
||||
|
||||
CEventAbsoluteTag *ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, pkvTags->GetName() );
|
||||
if (ptag)
|
||||
{
|
||||
// reposition tag
|
||||
ptag->SetPercentage( flPercentage );
|
||||
}
|
||||
else
|
||||
{
|
||||
e->AddAbsoluteTag( CChoreoEvent::ORIGINAL, pkvTags->GetName(), flPercentage );
|
||||
e->AddAbsoluteTag( CChoreoEvent::PLAYBACK, pkvTags->GetName(), flPercentage );
|
||||
}
|
||||
// lock the original tags so they can't be edited
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, pkvTags->GetName() );
|
||||
Assert( ptag );
|
||||
ptag->SetLocked( true );
|
||||
}
|
||||
e->VerifyTagOrder();
|
||||
e->PreventTagOverlap();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: lookup linear tags in sequence data
|
||||
{
|
||||
CEventAbsoluteTag *ptag;
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szStartLoop );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetLinear( true );
|
||||
}
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szStartLoop );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetLinear( true );
|
||||
}
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szEndLoop );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetLinear( true );
|
||||
}
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szEndLoop );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetLinear( true );
|
||||
}
|
||||
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szEntry );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetEntry( true );
|
||||
}
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szEntry );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetEntry( true );
|
||||
}
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szExit );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetExit( true );
|
||||
}
|
||||
ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szExit );
|
||||
if (ptag)
|
||||
{
|
||||
ptag->SetExit( true );
|
||||
}
|
||||
}
|
||||
|
||||
pSeqKeyValues->deleteThis();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool UpdateGestureLength( CChoreoEvent *e, CStudioHdr *pStudioHdr, float *pPoseParameters, bool bCheckOnly )
|
||||
{
|
||||
Assert( e );
|
||||
if ( !e )
|
||||
return false;
|
||||
|
||||
if ( e->GetType() != CChoreoEvent::GESTURE )
|
||||
return false;
|
||||
|
||||
int iSequence = LookupSequence( pStudioHdr, e->GetParameters() );
|
||||
if ( iSequence < 0 )
|
||||
return false;
|
||||
|
||||
bool bChanged = false;
|
||||
float flSeqDuration = Studio_Duration( pStudioHdr, iSequence, pPoseParameters );
|
||||
float flCurDuration;
|
||||
e->GetGestureSequenceDuration( flCurDuration );
|
||||
if ( flSeqDuration != 0.0f && flSeqDuration != flCurDuration )
|
||||
{
|
||||
bChanged = true;
|
||||
if ( !bCheckOnly )
|
||||
{
|
||||
e->SetGestureSequenceDuration( flSeqDuration );
|
||||
}
|
||||
}
|
||||
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool UpdateSequenceLength( CChoreoEvent *e, CStudioHdr *pStudioHdr, float *pPoseParameters, bool bCheckOnly, bool bVerbose )
|
||||
{
|
||||
Assert( e );
|
||||
if ( !e )
|
||||
return false;
|
||||
|
||||
if ( e->GetType() != CChoreoEvent::SEQUENCE )
|
||||
{
|
||||
if ( bVerbose )
|
||||
{
|
||||
ConMsg( "UpdateSequenceLength: called on non-SEQUENCE event %s\n", e->GetName() );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int iSequence = LookupSequence( pStudioHdr, e->GetParameters() );
|
||||
if ( iSequence < 0 )
|
||||
return false;
|
||||
|
||||
bool bChanged = false;
|
||||
bool bLooping = DoesSequenceLoop( pStudioHdr, iSequence );
|
||||
float flSeqDuration = Studio_Duration( pStudioHdr, iSequence, pPoseParameters );
|
||||
|
||||
if ( bLooping )
|
||||
{
|
||||
if ( e->IsFixedLength() )
|
||||
{
|
||||
if ( bCheckOnly )
|
||||
return true;
|
||||
|
||||
if ( bVerbose )
|
||||
{
|
||||
ConMsg( "UpdateSequenceLength: %s is looping, removing fixed length flag\n", e->GetName() );
|
||||
}
|
||||
bChanged = true;
|
||||
}
|
||||
e->SetFixedLength( false );
|
||||
|
||||
if ( !e->HasEndTime() )
|
||||
{
|
||||
if ( bCheckOnly )
|
||||
return true;
|
||||
|
||||
if ( bVerbose )
|
||||
{
|
||||
ConMsg( "CheckSequenceLength: %s is looping, setting default end time\n", e->GetName() );
|
||||
}
|
||||
e->SetEndTime( e->GetStartTime() + flSeqDuration );
|
||||
bChanged = true;
|
||||
}
|
||||
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
if ( !e->IsFixedLength() )
|
||||
{
|
||||
if ( bCheckOnly )
|
||||
return true;
|
||||
|
||||
if ( bVerbose )
|
||||
{
|
||||
ConMsg( "CheckSequenceLength: %s is fixed length, removing looping flag\n", e->GetName() );
|
||||
}
|
||||
bChanged = true;
|
||||
}
|
||||
e->SetFixedLength( true );
|
||||
|
||||
if ( e->HasEndTime() )
|
||||
{
|
||||
float dt = e->GetDuration();
|
||||
if ( fabs( dt - flSeqDuration ) > 0.01f )
|
||||
{
|
||||
if ( bCheckOnly )
|
||||
return true;
|
||||
if ( bVerbose )
|
||||
{
|
||||
ConMsg( "CheckSequenceLength: %s has wrong duration, changing length from %f to %f seconds\n",
|
||||
e->GetName(), dt, flSeqDuration );
|
||||
}
|
||||
bChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bCheckOnly )
|
||||
return true;
|
||||
if ( bVerbose )
|
||||
{
|
||||
ConMsg( "CheckSequenceLength: %s has wrong duration, changing length to %f seconds\n",
|
||||
e->GetName(), flSeqDuration );
|
||||
}
|
||||
bChanged = true;
|
||||
}
|
||||
|
||||
if ( !bCheckOnly )
|
||||
{
|
||||
e->SetEndTime( e->GetStartTime() + flSeqDuration );
|
||||
}
|
||||
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds sound files associated with events
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *GetSoundForEvent( CChoreoEvent *pEvent, CStudioHdr *pStudioHdr )
|
||||
{
|
||||
const char *pSoundName = pEvent->GetParameters();
|
||||
if ( Q_stristr( pSoundName, ".wav" ) )
|
||||
return PSkipSoundChars( pSoundName );
|
||||
|
||||
const char *pFileName = g_pSoundEmitterSystem->GetWavFileForSound( pSoundName, ( pStudioHdr && pStudioHdr->IsValid() ) ? pStudioHdr->pszName() : NULL );
|
||||
return PSkipSoundChars( pFileName );
|
||||
}
|
459
tier3/mdlutils.cpp
Normal file
459
tier3/mdlutils.cpp
Normal file
@ -0,0 +1,459 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Utility methods for mdl files
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "tier3/mdlutils.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/callqueue.h"
|
||||
#include "tier3/tier3.h"
|
||||
#include "studio.h"
|
||||
#include "istudiorender.h"
|
||||
#include "bone_setup.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the bounding box for the model
|
||||
//-----------------------------------------------------------------------------
|
||||
void GetMDLBoundingBox( Vector *pMins, Vector *pMaxs, MDLHandle_t h, int nSequence )
|
||||
{
|
||||
if ( h == MDLHANDLE_INVALID || !g_pMDLCache )
|
||||
{
|
||||
pMins->Init();
|
||||
pMaxs->Init();
|
||||
return;
|
||||
}
|
||||
|
||||
pMins->Init( FLT_MAX, FLT_MAX );
|
||||
pMaxs->Init( -FLT_MAX, -FLT_MAX );
|
||||
|
||||
studiohdr_t *pStudioHdr = g_pMDLCache->GetStudioHdr( h );
|
||||
if ( !VectorCompare( vec3_origin, pStudioHdr->view_bbmin ) || !VectorCompare( vec3_origin, pStudioHdr->view_bbmax ))
|
||||
{
|
||||
// look for view clip
|
||||
*pMins = pStudioHdr->view_bbmin;
|
||||
*pMaxs = pStudioHdr->view_bbmax;
|
||||
}
|
||||
else if ( !VectorCompare( vec3_origin, pStudioHdr->hull_min ) || !VectorCompare( vec3_origin, pStudioHdr->hull_max ))
|
||||
{
|
||||
// look for hull
|
||||
*pMins = pStudioHdr->hull_min;
|
||||
*pMaxs = pStudioHdr->hull_max;
|
||||
}
|
||||
|
||||
// Else use the sequence box
|
||||
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( nSequence );
|
||||
VectorMin( seqdesc.bbmin, *pMins, *pMins );
|
||||
VectorMax( seqdesc.bbmax, *pMaxs, *pMaxs );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the radius of the model as measured from the origin
|
||||
//-----------------------------------------------------------------------------
|
||||
float GetMDLRadius( MDLHandle_t h, int nSequence )
|
||||
{
|
||||
Vector vecMins, vecMaxs;
|
||||
GetMDLBoundingBox( &vecMins, &vecMaxs, h, nSequence );
|
||||
float flRadius = vecMaxs.Length();
|
||||
float flRadius2 = vecMins.Length();
|
||||
if ( flRadius2 > flRadius )
|
||||
{
|
||||
flRadius = flRadius2;
|
||||
}
|
||||
return flRadius;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a more accurate bounding sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void GetMDLBoundingSphere( Vector *pVecCenter, float *pRadius, MDLHandle_t h, int nSequence )
|
||||
{
|
||||
Vector vecMins, vecMaxs;
|
||||
GetMDLBoundingBox( &vecMins, &vecMaxs, h, nSequence );
|
||||
VectorAdd( vecMins, vecMaxs, *pVecCenter );
|
||||
*pVecCenter *= 0.5f;
|
||||
*pRadius = vecMaxs.DistTo( *pVecCenter );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDL::CMDL()
|
||||
{
|
||||
m_MDLHandle = MDLHANDLE_INVALID;
|
||||
m_Color.SetColor( 255, 255, 255, 255 );
|
||||
m_nSkin = 0;
|
||||
m_nBody = 0;
|
||||
m_nSequence = 0;
|
||||
m_nLOD = 0;
|
||||
m_flPlaybackRate = 30.0f;
|
||||
m_flTime = 0.0f;
|
||||
m_vecViewTarget.Init( 0, 0, 0 );
|
||||
m_bWorldSpaceViewTarget = false;
|
||||
memset( m_pFlexControls, 0, sizeof(m_pFlexControls) );
|
||||
m_pProxyData = NULL;
|
||||
}
|
||||
|
||||
CMDL::~CMDL()
|
||||
{
|
||||
UnreferenceMDL();
|
||||
}
|
||||
|
||||
void CMDL::SetMDL( MDLHandle_t h )
|
||||
{
|
||||
UnreferenceMDL();
|
||||
m_MDLHandle = h;
|
||||
if ( m_MDLHandle != MDLHANDLE_INVALID )
|
||||
{
|
||||
g_pMDLCache->AddRef( m_MDLHandle );
|
||||
|
||||
studiohdr_t *pHdr = g_pMDLCache->LockStudioHdr( m_MDLHandle );
|
||||
|
||||
if ( pHdr )
|
||||
{
|
||||
for ( LocalFlexController_t i = LocalFlexController_t(0); i < pHdr->numflexcontrollers; ++i )
|
||||
{
|
||||
if ( pHdr->pFlexcontroller( i )->localToGlobal == -1 )
|
||||
{
|
||||
pHdr->pFlexcontroller( i )->localToGlobal = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MDLHandle_t CMDL::GetMDL() const
|
||||
{
|
||||
return m_MDLHandle;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Release the MDL handle
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDL::UnreferenceMDL()
|
||||
{
|
||||
if ( !g_pMDLCache )
|
||||
return;
|
||||
|
||||
if ( m_MDLHandle != MDLHANDLE_INVALID )
|
||||
{
|
||||
// XXX need to figure out where it is safe to flush the queue during map change to not crash
|
||||
#if 0
|
||||
if ( ICallQueue *pCallQueue = materials->GetRenderContext()->GetCallQueue() )
|
||||
{
|
||||
// Parallel rendering: don't unlock model data until end of rendering
|
||||
pCallQueue->QueueCall( g_pMDLCache, &IMDLCache::UnlockStudioHdr, m_MDLHandle );
|
||||
pCallQueue->QueueCall( g_pMDLCache, &IMDLCache::Release, m_MDLHandle );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Immediate-mode rendering, can unlock immediately
|
||||
g_pMDLCache->UnlockStudioHdr( m_MDLHandle );
|
||||
g_pMDLCache->Release( m_MDLHandle );
|
||||
}
|
||||
m_MDLHandle = MDLHANDLE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the studiohdr
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t *CMDL::GetStudioHdr()
|
||||
{
|
||||
if ( !g_pMDLCache )
|
||||
return NULL;
|
||||
return g_pMDLCache->GetStudioHdr( m_MDLHandle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws the mesh
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDL::Draw( const matrix3x4_t& rootToWorld, const matrix3x4_t *pBoneToWorld )
|
||||
{
|
||||
if ( !g_pMaterialSystem || !g_pMDLCache || !g_pStudioRender )
|
||||
return;
|
||||
|
||||
if ( m_MDLHandle == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
// Color + alpha modulation
|
||||
Vector white( m_Color.r() / 255.0f, m_Color.g() / 255.0f, m_Color.b() / 255.0f );
|
||||
g_pStudioRender->SetColorModulation( white.Base() );
|
||||
g_pStudioRender->SetAlphaModulation( m_Color.a() / 255.0f );
|
||||
|
||||
DrawModelInfo_t info;
|
||||
info.m_pStudioHdr = g_pMDLCache->GetStudioHdr( m_MDLHandle );
|
||||
info.m_pHardwareData = g_pMDLCache->GetHardwareData( m_MDLHandle );
|
||||
info.m_Decals = STUDIORENDER_DECAL_INVALID;
|
||||
info.m_Skin = m_nSkin;
|
||||
info.m_Body = m_nBody;
|
||||
info.m_HitboxSet = 0;
|
||||
info.m_pClientEntity = m_pProxyData;
|
||||
info.m_pColorMeshes = NULL;
|
||||
info.m_bStaticLighting = false;
|
||||
info.m_Lod = m_nLOD;
|
||||
|
||||
Vector vecWorldViewTarget;
|
||||
if ( m_bWorldSpaceViewTarget )
|
||||
{
|
||||
vecWorldViewTarget = m_vecViewTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorTransform( m_vecViewTarget, rootToWorld, vecWorldViewTarget );
|
||||
}
|
||||
g_pStudioRender->SetEyeViewTarget( info.m_pStudioHdr, info.m_Body, vecWorldViewTarget );
|
||||
|
||||
// FIXME: Why is this necessary!?!?!?
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
|
||||
// Set default flex values
|
||||
float *pFlexWeights = NULL;
|
||||
const int nFlexDescCount = info.m_pStudioHdr->numflexdesc;
|
||||
if ( nFlexDescCount )
|
||||
{
|
||||
CStudioHdr cStudioHdr( info.m_pStudioHdr, g_pMDLCache );
|
||||
|
||||
g_pStudioRender->LockFlexWeights( info.m_pStudioHdr->numflexdesc, &pFlexWeights );
|
||||
cStudioHdr.RunFlexRules( m_pFlexControls, pFlexWeights );
|
||||
g_pStudioRender->UnlockFlexWeights();
|
||||
}
|
||||
|
||||
Vector vecModelOrigin;
|
||||
MatrixGetColumn( rootToWorld, 3, vecModelOrigin );
|
||||
g_pStudioRender->DrawModel( NULL, info, const_cast<matrix3x4_t*>( pBoneToWorld ),
|
||||
pFlexWeights, NULL, vecModelOrigin, STUDIORENDER_DRAW_ENTIRE_MODEL );
|
||||
}
|
||||
|
||||
void CMDL::Draw( const matrix3x4_t &rootToWorld )
|
||||
{
|
||||
if ( !g_pMaterialSystem || !g_pMDLCache || !g_pStudioRender )
|
||||
return;
|
||||
|
||||
if ( m_MDLHandle == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
studiohdr_t *pStudioHdr = g_pMDLCache->GetStudioHdr( m_MDLHandle );
|
||||
|
||||
matrix3x4_t *pBoneToWorld = g_pStudioRender->LockBoneMatrices( pStudioHdr->numbones );
|
||||
SetUpBones( rootToWorld, pStudioHdr->numbones, pBoneToWorld );
|
||||
g_pStudioRender->UnlockBoneMatrices();
|
||||
|
||||
Draw( rootToWorld, pBoneToWorld );
|
||||
}
|
||||
|
||||
|
||||
void CMDL::SetUpBones( const matrix3x4_t& rootToWorld, int nMaxBoneCount, matrix3x4_t *pBoneToWorld, const float *pPoseParameters, MDLSquenceLayer_t *pSequenceLayers, int nNumSequenceLayers )
|
||||
{
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_MDLHandle ), g_pMDLCache );
|
||||
|
||||
float pPoseParameter[MAXSTUDIOPOSEPARAM];
|
||||
if ( pPoseParameters )
|
||||
{
|
||||
V_memcpy( pPoseParameter, pPoseParameters, sizeof(pPoseParameter) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default to middle of the pose parameter range
|
||||
int nPoseCount = studioHdr.GetNumPoseParameters();
|
||||
for ( int i = 0; i < MAXSTUDIOPOSEPARAM; ++i )
|
||||
{
|
||||
pPoseParameter[i] = 0.5f;
|
||||
if ( i < nPoseCount )
|
||||
{
|
||||
const mstudioposeparamdesc_t &Pose = studioHdr.pPoseParameter( i );
|
||||
|
||||
// Want to try for a zero state. If one doesn't exist set it to .5 by default.
|
||||
if ( Pose.start < 0.0f && Pose.end > 0.0f )
|
||||
{
|
||||
float flPoseDelta = Pose.end - Pose.start;
|
||||
pPoseParameter[i] = -Pose.start / flPoseDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nFrameCount = Studio_MaxFrame( &studioHdr, m_nSequence, pPoseParameter );
|
||||
if ( nFrameCount == 0 )
|
||||
{
|
||||
nFrameCount = 1;
|
||||
}
|
||||
float flCycle = ( m_flTime * m_flPlaybackRate ) / nFrameCount;
|
||||
|
||||
// FIXME: We're always wrapping; may want to determing if we should clamp
|
||||
flCycle -= (int)(flCycle);
|
||||
|
||||
Vector pos[MAXSTUDIOBONES];
|
||||
Quaternion q[MAXSTUDIOBONES];
|
||||
|
||||
IBoneSetup boneSetup( &studioHdr, BONE_USED_BY_ANYTHING_AT_LOD( m_nLOD ), pPoseParameter, NULL );
|
||||
boneSetup.InitPose( pos, q );
|
||||
boneSetup.AccumulatePose( pos, q, m_nSequence, flCycle, 1.0f, m_flTime, NULL );
|
||||
|
||||
// Accumulate the additional layers if specified.
|
||||
if ( pSequenceLayers )
|
||||
{
|
||||
int nNumSeq = studioHdr.GetNumSeq();
|
||||
for ( int i = 0; i < nNumSequenceLayers; ++i )
|
||||
{
|
||||
int nSeqIndex = pSequenceLayers[ i ].m_nSequenceIndex;
|
||||
if ( ( nSeqIndex >= 0 ) && ( nSeqIndex < nNumSeq ) )
|
||||
{
|
||||
float flWeight = pSequenceLayers[ i ].m_flWeight;
|
||||
|
||||
float flLayerCycle;
|
||||
int nLayerFrameCount = MAX( 1, Studio_MaxFrame( &studioHdr, nSeqIndex, pPoseParameter ) );
|
||||
|
||||
if ( pSequenceLayers[i].m_bNoLoop )
|
||||
{
|
||||
if ( pSequenceLayers[i].m_flCycleBeganAt == 0 )
|
||||
{
|
||||
pSequenceLayers[i].m_flCycleBeganAt = m_flTime;
|
||||
}
|
||||
|
||||
float flElapsedTime = m_flTime - pSequenceLayers[i].m_flCycleBeganAt;
|
||||
flLayerCycle = ( flElapsedTime * m_flPlaybackRate ) / nLayerFrameCount;
|
||||
|
||||
// Should we keep playing layers that have ended?
|
||||
//if ( flLayerCycle >= 1.0 )
|
||||
//continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
flLayerCycle = ( m_flTime * m_flPlaybackRate ) / nLayerFrameCount;
|
||||
|
||||
// FIXME: We're always wrapping; may want to determing if we should clamp
|
||||
flLayerCycle -= (int)(flLayerCycle);
|
||||
}
|
||||
|
||||
boneSetup.AccumulatePose( pos, q, nSeqIndex, flLayerCycle, flWeight, m_flTime, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Try enabling this?
|
||||
// CalcAutoplaySequences( pStudioHdr, NULL, pos, q, pPoseParameter, BONE_USED_BY_VERTEX_AT_LOD( m_nLOD ), flTime );
|
||||
|
||||
matrix3x4_t temp;
|
||||
|
||||
if ( nMaxBoneCount > studioHdr.numbones() )
|
||||
{
|
||||
nMaxBoneCount = studioHdr.numbones();
|
||||
}
|
||||
|
||||
for ( int i = 0; i < nMaxBoneCount; i++ )
|
||||
{
|
||||
// If it's not being used, fill with NAN for errors
|
||||
#ifdef _DEBUG
|
||||
if ( !(studioHdr.pBone( i )->flags & BONE_USED_BY_ANYTHING_AT_LOD( m_nLOD ) ) )
|
||||
{
|
||||
int j, k;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
pBoneToWorld[i][j][k] = VEC_T_NAN;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
matrix3x4_t boneMatrix;
|
||||
QuaternionMatrix( q[i], boneMatrix );
|
||||
MatrixSetColumn( pos[i], 3, boneMatrix );
|
||||
|
||||
if ( studioHdr.pBone(i)->parent == -1 )
|
||||
{
|
||||
ConcatTransforms( rootToWorld, boneMatrix, pBoneToWorld[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
ConcatTransforms( pBoneToWorld[ studioHdr.pBone(i)->parent ], boneMatrix, pBoneToWorld[i] );
|
||||
}
|
||||
}
|
||||
Studio_RunBoneFlexDrivers( m_pFlexControls, &studioHdr, pos, pBoneToWorld, rootToWorld );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDL::SetupBonesWithBoneMerge( const CStudioHdr *pMergeHdr, matrix3x4_t *pMergeBoneToWorld,
|
||||
const CStudioHdr *pFollow, const matrix3x4_t *pFollowBoneToWorld,
|
||||
const matrix3x4_t &matModelToWorld )
|
||||
{
|
||||
// Default to middle of the pose parameter range
|
||||
int nPoseCount = pMergeHdr->GetNumPoseParameters();
|
||||
float pPoseParameter[MAXSTUDIOPOSEPARAM];
|
||||
for ( int i = 0; i < MAXSTUDIOPOSEPARAM; ++i )
|
||||
{
|
||||
pPoseParameter[i] = 0.5f;
|
||||
if ( i < nPoseCount )
|
||||
{
|
||||
const mstudioposeparamdesc_t &Pose = ((CStudioHdr *)pMergeHdr)->pPoseParameter( i );
|
||||
|
||||
// Want to try for a zero state. If one doesn't exist set it to .5 by default.
|
||||
if ( Pose.start < 0.0f && Pose.end > 0.0f )
|
||||
{
|
||||
float flPoseDelta = Pose.end - Pose.start;
|
||||
pPoseParameter[i] = -Pose.start / flPoseDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nFrameCount = Studio_MaxFrame( pMergeHdr, m_nSequence, pPoseParameter );
|
||||
if ( nFrameCount == 0 )
|
||||
{
|
||||
nFrameCount = 1;
|
||||
}
|
||||
float flCycle = ( m_flTime * m_flPlaybackRate ) / nFrameCount;
|
||||
|
||||
// FIXME: We're always wrapping; may want to determing if we should clamp
|
||||
flCycle -= (int)(flCycle);
|
||||
|
||||
Vector pos[MAXSTUDIOBONES];
|
||||
Quaternion q[MAXSTUDIOBONES];
|
||||
|
||||
IBoneSetup boneSetup( pMergeHdr, BONE_USED_BY_ANYTHING_AT_LOD( m_nLOD ), pPoseParameter );
|
||||
boneSetup.InitPose( pos, q );
|
||||
boneSetup.AccumulatePose( pos, q, m_nSequence, flCycle, 1.0f, m_flTime, NULL );
|
||||
|
||||
// Get the merge bone list.
|
||||
mstudiobone_t *pMergeBones = pMergeHdr->pBone( 0 );
|
||||
for ( int iMergeBone = 0; iMergeBone < pMergeHdr->numbones(); ++iMergeBone )
|
||||
{
|
||||
// Now find the bone in the parent entity.
|
||||
bool bMerged = false;
|
||||
int iParentBoneIndex = Studio_BoneIndexByName( pFollow, pMergeBones[iMergeBone].pszName() );
|
||||
if ( iParentBoneIndex >= 0 )
|
||||
{
|
||||
MatrixCopy( pFollowBoneToWorld[iParentBoneIndex], pMergeBoneToWorld[iMergeBone] );
|
||||
bMerged = true;
|
||||
}
|
||||
|
||||
if ( !bMerged )
|
||||
{
|
||||
// If we get down here, then the bone wasn't merged.
|
||||
matrix3x4_t matBone;
|
||||
QuaternionMatrix( q[iMergeBone], pos[iMergeBone], matBone );
|
||||
|
||||
if ( pMergeBones[iMergeBone].parent == -1 )
|
||||
{
|
||||
ConcatTransforms( matModelToWorld, matBone, pMergeBoneToWorld[iMergeBone] );
|
||||
}
|
||||
else
|
||||
{
|
||||
ConcatTransforms( pMergeBoneToWorld[pMergeBones[iMergeBone].parent], matBone, pMergeBoneToWorld[iMergeBone] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
201
tier3/scenetokenprocessor.cpp
Normal file
201
tier3/scenetokenprocessor.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "../game/shared/choreoscene.h"
|
||||
#include "../game/shared/choreoactor.h"
|
||||
#include "../game/shared/choreochannel.h"
|
||||
#include "../game/shared/choreoevent.h"
|
||||
#include "../game/shared/iscenetokenprocessor.h"
|
||||
#include "characterset.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper for parsing scene data file
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSceneTokenProcessor : public ISceneTokenProcessor
|
||||
{
|
||||
public:
|
||||
CSceneTokenProcessor();
|
||||
|
||||
const char *CurrentToken( void );
|
||||
bool GetToken( bool crossline );
|
||||
bool TokenAvailable( void );
|
||||
void Error( const char *fmt, ... );
|
||||
void SetBuffer( char *buffer );
|
||||
private:
|
||||
|
||||
const char *ParseNextToken (const char *data);
|
||||
|
||||
const char *m_pBuffer;
|
||||
char m_szToken[ 1024 ];
|
||||
|
||||
characterset_t m_BreakSetIncludingColons;
|
||||
};
|
||||
|
||||
CSceneTokenProcessor::CSceneTokenProcessor()
|
||||
{
|
||||
CharacterSetBuild( &m_BreakSetIncludingColons, "{}()':" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : const char
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSceneTokenProcessor::CurrentToken( void )
|
||||
{
|
||||
return m_szToken;
|
||||
}
|
||||
|
||||
const char *CSceneTokenProcessor::ParseNextToken (const char *data)
|
||||
{
|
||||
unsigned char c;
|
||||
int len;
|
||||
characterset_t *breaks;
|
||||
|
||||
breaks = &m_BreakSetIncludingColons;
|
||||
|
||||
len = 0;
|
||||
m_szToken[0] = 0;
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
// skip whitespace
|
||||
skipwhite:
|
||||
while ( (c = *data) <= ' ')
|
||||
{
|
||||
if (c == 0)
|
||||
return NULL; // end of file;
|
||||
data++;
|
||||
}
|
||||
|
||||
// skip // comments
|
||||
if (c=='/' && data[1] == '/')
|
||||
{
|
||||
while (*data && *data != '\n')
|
||||
data++;
|
||||
goto skipwhite;
|
||||
}
|
||||
|
||||
|
||||
// handle quoted strings specially
|
||||
if (c == '\"')
|
||||
{
|
||||
data++;
|
||||
while (1)
|
||||
{
|
||||
c = *data++;
|
||||
if (c=='\"' || !c)
|
||||
{
|
||||
m_szToken[len] = 0;
|
||||
return data;
|
||||
}
|
||||
m_szToken[len] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
// parse single characters
|
||||
if ( IN_CHARACTERSET( *breaks, c ) )
|
||||
{
|
||||
m_szToken[len] = c;
|
||||
len++;
|
||||
m_szToken[len] = 0;
|
||||
return data+1;
|
||||
}
|
||||
|
||||
// parse a regular word
|
||||
do
|
||||
{
|
||||
m_szToken[len] = c;
|
||||
data++;
|
||||
len++;
|
||||
c = *data;
|
||||
if ( IN_CHARACTERSET( *breaks, c ) )
|
||||
break;
|
||||
} while (c>32);
|
||||
|
||||
m_szToken[len] = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : crossline -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSceneTokenProcessor::GetToken( bool crossline )
|
||||
{
|
||||
// NOTE: crossline is ignored here, may need to implement if needed
|
||||
m_pBuffer = ParseNextToken( m_pBuffer );
|
||||
if ( m_szToken[0] )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSceneTokenProcessor::TokenAvailable( void )
|
||||
{
|
||||
const char *search_p = m_pBuffer;
|
||||
|
||||
while ( *search_p <= 32)
|
||||
{
|
||||
if (*search_p == '\n')
|
||||
return false;
|
||||
search_p++;
|
||||
if ( !*search_p )
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (*search_p == ';' || *search_p == '#' || // semicolon and # is comment field
|
||||
(*search_p == '/' && *((search_p)+1) == '/')) // also make // a comment field
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *fmt -
|
||||
// ... -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSceneTokenProcessor::Error( const char *fmt, ... )
|
||||
{
|
||||
char string[ 2048 ];
|
||||
va_list argptr;
|
||||
va_start( argptr, fmt );
|
||||
Q_vsnprintf( string, sizeof(string), fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
Warning( "%s", string );
|
||||
Assert(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *buffer -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSceneTokenProcessor::SetBuffer( char *buffer )
|
||||
{
|
||||
m_pBuffer = buffer;
|
||||
}
|
||||
|
||||
CSceneTokenProcessor g_TokenProcessor;
|
||||
|
||||
ISceneTokenProcessor *GetTokenProcessor()
|
||||
{
|
||||
return &g_TokenProcessor;
|
||||
}
|
||||
|
||||
void SetTokenProcessorBuffer( const char *buf )
|
||||
{
|
||||
g_TokenProcessor.SetBuffer( (char *)buf );
|
||||
}
|
||||
|
47
tier3/studiohdrstub.cpp
Normal file
47
tier3/studiohdrstub.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
//#include "studio.h"
|
||||
#include "studio.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "datamodel/dmelementfactoryhelper.h"
|
||||
#include "istudiorender.h"
|
||||
#include "bone_setup.h"
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FIXME: This trashy glue code is really not acceptable. Figure out a way of making it unnecessary.
|
||||
//-----------------------------------------------------------------------------
|
||||
const studiohdr_t *studiohdr_t::FindModel( void **cache, char const *pModelName ) const
|
||||
{
|
||||
MDLHandle_t handle = g_pMDLCache->FindMDL( pModelName );
|
||||
*cache = (void*)(uintp)handle;
|
||||
return g_pMDLCache->GetStudioHdr( handle );
|
||||
}
|
||||
|
||||
virtualmodel_t *studiohdr_t::GetVirtualModel( void ) const
|
||||
{
|
||||
return g_pMDLCache->GetVirtualModel( (MDLHandle_t)((int)virtualModel&0xffff) );
|
||||
}
|
||||
|
||||
byte *studiohdr_t::GetAnimBlock( int i ) const
|
||||
{
|
||||
return g_pMDLCache->GetAnimBlock( (MDLHandle_t)((int)virtualModel&0xffff), i );
|
||||
}
|
||||
|
||||
int studiohdr_t::GetAutoplayList( unsigned short **pOut ) const
|
||||
{
|
||||
return g_pMDLCache->GetAutoplayList( (MDLHandle_t)((int)virtualModel&0xffff), pOut );
|
||||
}
|
||||
|
||||
const studiohdr_t *virtualgroup_t::GetStudioHdr( void ) const
|
||||
{
|
||||
return g_pMDLCache->GetStudioHdr( (MDLHandle_t)((int)cache&0xffff) );
|
||||
}
|
||||
|
154
tier3/tier3.cpp
Normal file
154
tier3/tier3.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: A higher level link library for general use in the game and tools.
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "tier3/tier3.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "istudiorender.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/IPanel.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "vgui/ISystem.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "datacache/idatacache.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "video/ivideoservices.h"
|
||||
#include "movieobjects/idmemakefileutils.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "ivtex.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// These tier3 libraries must be set by any users of this library.
|
||||
// They can be set by calling ConnectTier3Libraries.
|
||||
// It is hoped that setting this, and using this library will be the common mechanism for
|
||||
// allowing link libraries to access tier3 library interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
IStudioRender *g_pStudioRender = 0;
|
||||
IStudioRender *studiorender = 0;
|
||||
IMatSystemSurface *g_pMatSystemSurface = 0;
|
||||
vgui::IInput *g_pVGuiInput = 0;
|
||||
vgui::ISurface *g_pVGuiSurface = 0;
|
||||
vgui::IPanel *g_pVGuiPanel = 0;
|
||||
vgui::IVGui *g_pVGui = 0;
|
||||
vgui::ILocalize *g_pVGuiLocalize = 0;
|
||||
vgui::ISchemeManager *g_pVGuiSchemeManager = 0;
|
||||
vgui::ISystem *g_pVGuiSystem = 0;
|
||||
IDataCache *g_pDataCache = 0;
|
||||
IMDLCache *g_pMDLCache = 0;
|
||||
IMDLCache *mdlcache = 0;
|
||||
IVideoServices *g_pVideo = NULL;
|
||||
IDmeMakefileUtils *g_pDmeMakefileUtils = 0;
|
||||
IPhysicsCollision *g_pPhysicsCollision = 0;
|
||||
ISoundEmitterSystemBase *g_pSoundEmitterSystem = 0;
|
||||
IVTex *g_pVTex = 0;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Call this to connect to all tier 3 libraries.
|
||||
// It's up to the caller to check the globals it cares about to see if ones are missing
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConnectTier3Libraries( CreateInterfaceFn *pFactoryList, int nFactoryCount )
|
||||
{
|
||||
// Don't connect twice..
|
||||
Assert( !g_pStudioRender && !studiorender && !g_pMatSystemSurface && !g_pVGui && !g_pVGuiPanel && !g_pVGuiInput &&
|
||||
!g_pVGuiSurface && !g_pDataCache && !g_pMDLCache && !mdlcache && !g_pVideo &&
|
||||
!g_pDmeMakefileUtils && !g_pPhysicsCollision && !g_pVGuiLocalize && !g_pSoundEmitterSystem &&
|
||||
!g_pVGuiSchemeManager && !g_pVGuiSystem );
|
||||
|
||||
for ( int i = 0; i < nFactoryCount; ++i )
|
||||
{
|
||||
if ( !g_pStudioRender )
|
||||
{
|
||||
g_pStudioRender = studiorender = ( IStudioRender * )pFactoryList[i]( STUDIO_RENDER_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVGui )
|
||||
{
|
||||
g_pVGui = (vgui::IVGui*)pFactoryList[i]( VGUI_IVGUI_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVGuiInput )
|
||||
{
|
||||
g_pVGuiInput = (vgui::IInput*)pFactoryList[i]( VGUI_INPUT_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVGuiPanel )
|
||||
{
|
||||
g_pVGuiPanel = (vgui::IPanel*)pFactoryList[i]( VGUI_PANEL_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVGuiSurface )
|
||||
{
|
||||
g_pVGuiSurface = (vgui::ISurface*)pFactoryList[i]( VGUI_SURFACE_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVGuiSchemeManager )
|
||||
{
|
||||
g_pVGuiSchemeManager = (vgui::ISchemeManager*)pFactoryList[i]( VGUI_SCHEME_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVGuiSystem )
|
||||
{
|
||||
g_pVGuiSystem = (vgui::ISystem*)pFactoryList[i]( VGUI_SYSTEM_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVGuiLocalize )
|
||||
{
|
||||
g_pVGuiLocalize = (vgui::ILocalize*)pFactoryList[i]( VGUI_LOCALIZE_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pMatSystemSurface )
|
||||
{
|
||||
g_pMatSystemSurface = ( IMatSystemSurface * )pFactoryList[i]( MAT_SYSTEM_SURFACE_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pDataCache )
|
||||
{
|
||||
g_pDataCache = (IDataCache*)pFactoryList[i]( DATACACHE_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pMDLCache )
|
||||
{
|
||||
g_pMDLCache = mdlcache = (IMDLCache*)pFactoryList[i]( MDLCACHE_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVideo )
|
||||
{
|
||||
g_pVideo = (IVideoServices *)pFactoryList[i](VIDEO_SERVICES_INTERFACE_VERSION, NULL);
|
||||
}
|
||||
if ( !g_pDmeMakefileUtils )
|
||||
{
|
||||
g_pDmeMakefileUtils = (IDmeMakefileUtils*)pFactoryList[i]( DMEMAKEFILE_UTILS_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pPhysicsCollision )
|
||||
{
|
||||
g_pPhysicsCollision = ( IPhysicsCollision* )pFactoryList[i]( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pSoundEmitterSystem )
|
||||
{
|
||||
g_pSoundEmitterSystem = ( ISoundEmitterSystemBase* )pFactoryList[i]( SOUNDEMITTERSYSTEM_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
if ( !g_pVTex )
|
||||
{
|
||||
g_pVTex = ( IVTex * )pFactoryList[i]( IVTEX_VERSION_STRING, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisconnectTier3Libraries()
|
||||
{
|
||||
g_pStudioRender = 0;
|
||||
studiorender = 0;
|
||||
g_pVGui = 0;
|
||||
g_pVGuiInput = 0;
|
||||
g_pVGuiPanel = 0;
|
||||
g_pVGuiSurface = 0;
|
||||
g_pVGuiLocalize = 0;
|
||||
g_pVGuiSchemeManager = 0;
|
||||
g_pVGuiSystem = 0;
|
||||
g_pMatSystemSurface = 0;
|
||||
g_pDataCache = 0;
|
||||
g_pMDLCache = 0;
|
||||
mdlcache = 0;
|
||||
g_pVideo = NULL;
|
||||
g_pPhysicsCollision = 0;
|
||||
g_pDmeMakefileUtils = NULL;
|
||||
g_pSoundEmitterSystem = 0;
|
||||
g_pVTex = NULL;
|
||||
}
|
29
tier3/tier3.vpc
Normal file
29
tier3/tier3.vpc
Normal file
@ -0,0 +1,29 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// TIER3.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR ".."
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Project "tier3"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "tier3.cpp"
|
||||
$File "mdlutils.cpp"
|
||||
$File "choreoutils.cpp"
|
||||
$File "scenetokenprocessor.cpp"
|
||||
$File "studiohdrstub.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier3\tier3.h"
|
||||
$File "$SRCDIR\public\tier3\mdlutils.h"
|
||||
$File "$SRCDIR\public\tier3\choreoutils.h"
|
||||
$File "$SRCDIR\public\tier3\scenetokenprocessor.h"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user