diff options
Diffstat (limited to 'utils/hlfaceposer/expression.cpp')
| -rw-r--r-- | utils/hlfaceposer/expression.cpp | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/utils/hlfaceposer/expression.cpp b/utils/hlfaceposer/expression.cpp new file mode 100644 index 0000000..b710c00 --- /dev/null +++ b/utils/hlfaceposer/expression.cpp @@ -0,0 +1,472 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "hlfaceposer.h" +#include <mxtk/mx.h> +#include "expressions.h" +#include "StudioModel.h" +#include "filesystem.h" +#include "viewersettings.h" +#include "matsyswin.h" +#include "checksum_crc.h" +#include "expclass.h" +#include "ControlPanel.h" +#include "faceposer_models.h" +#include "mdlviewer.h" + +static int g_counter = 0; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CExpression::CExpression( void ) +{ + name[ 0 ] = 0; + index = 0; + description[ 0 ] = 0; + memset( setting, 0, sizeof( setting ) ); + + for ( int i = 0; i < MAX_FP_MODELS; i++ ) + { + m_Bitmap[ i ].valid = false; + } + + m_nUndoCurrent = 0; + m_bModified = false; + + m_bSelected = false; + + m_bDirty = false; + + expressionclass[ 0 ] = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Copy constructor +// Input : from - +//----------------------------------------------------------------------------- +CExpression::CExpression( const CExpression& from ) +{ + int i; + + strcpy( name, from.name ); + index = from.index; + strcpy( description, from.description ); + + for ( i = 0; i < MAX_FP_MODELS; i++ ) + { + m_Bitmap[ i ] = from.m_Bitmap[ i ]; + } + + m_bModified = from.m_bModified; + + for ( i = 0 ; i < from.undo.Size(); i++ ) + { + CExpUndoInfo *newUndo = new CExpUndoInfo(); + *newUndo = *from.undo[ i ]; + undo.AddToTail( newUndo ); + } + + m_nUndoCurrent = from.m_nUndoCurrent; + + m_bSelected = from.m_bSelected; + + m_bDirty = from.m_bDirty; + + strcpy( expressionclass, from.expressionclass ); + + memcpy( setting, from.setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memcpy( weight, from.weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CExpression::~CExpression( void ) +{ + ResetUndo(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CExpression::GetDirty( void ) +{ + return m_bDirty; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : dirty - +//----------------------------------------------------------------------------- +void CExpression::SetDirty( bool dirty ) +{ + m_bDirty = dirty; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : float +//----------------------------------------------------------------------------- +float *CExpression::GetSettings( void ) +{ + return setting; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : float +//----------------------------------------------------------------------------- +float *CExpression::GetWeights( void ) +{ + return weight; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : mod - +//----------------------------------------------------------------------------- +void CExpression::SetModified( bool mod ) +{ + m_bModified = mod; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CExpression::GetModified( void ) +{ + return m_bModified; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : selected - +//----------------------------------------------------------------------------- +void CExpression::SetSelected( bool selected ) +{ + m_bSelected = selected; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CExpression::GetSelected( void ) +{ + return m_bSelected; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CExpression::ResetUndo( void ) +{ + CExpUndoInfo *u; + for ( int i = 0; i < undo.Size(); i++ ) + { + u = undo[ i ]; + delete u; + } + + undo.RemoveAll(); + m_nUndoCurrent = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CExpression::CanRedo( void ) +{ + if ( !undo.Size() ) + return false; + + if ( m_nUndoCurrent == 0 ) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CExpression::CanUndo( void ) +{ + if ( !undo.Size() ) + return false; + + if ( m_nUndoCurrent >= undo.Size() ) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CExpression::UndoLevels( void ) +{ + return undo.Size(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int CExpression::UndoCurrent( void ) +{ + return m_nUndoCurrent; +} + +void ChecksumFlexControllers( bool bSpew, char const *name, CRC32_t &crc, const float *settings, const float *weights ); + +CRC32_t CExpression::GetBitmapCRC() +{ + CRC32_t crc; + + float *s = setting; + float *w = weight; + + // Note, we'll use the pristine values if this has changed + if ( undo.Size() >= 1 ) + { + s = undo[ undo.Size() - 1 ]->setting; + w = undo[ undo.Size() - 1 ]->weight; + } + + // This walks the global controllers sorted by name and only includes values with a setting or value which is != 0.0f + + ChecksumFlexControllers( false, name, crc, s, w ); + + return crc; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : const char +//----------------------------------------------------------------------------- +const char *CExpression::GetBitmapCheckSum() +{ + CRC32_t crc = GetBitmapCRC(); + + // Create string name out of binary data + static char hex[ 9 ]; + Q_binarytohex( (byte *)&crc, sizeof( crc ), hex, sizeof( hex ) ); + return hex; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : const char +//----------------------------------------------------------------------------- +const char *CExpression::GetBitmapFilename( int modelindex ) +{ + static char filename[ 256 ] = { 0 }; + + char const *classname = "error"; + CExpClass *cl = GetExpressionClass(); + if ( cl ) + { + classname = cl->GetBaseName(); + } + + char modelName[512], modelNameTemp[512]; + Q_strncpy( modelNameTemp, models->GetModelName( modelindex ), sizeof( modelNameTemp ) ); + + char const *in = modelNameTemp; + char *out = modelName; + + while ( *in ) + { + if ( V_isalnum( *in ) || + *in == '_' || + *in == '\\' || + *in == '/' || + *in == '.' || + *in == ':' ) + { + *out++ = *in; + } + in++; + } + *out = 0; + + + sprintf( filename, "expressions/%s/%s/%s.bmp", modelName, classname, GetBitmapCheckSum() ); + + Q_FixSlashes( filename ); + strlwr( filename ); + + CreatePath( filename ); + + return filename; +} + +void CExpression::CreateNewBitmap( int modelindex ) +{ + MatSysWindow *pWnd = g_pMatSysWindow; + if ( !pWnd ) + return; + + StudioModel *model = models->GetStudioModel( modelindex ); + if ( !model ) + return; + + CStudioHdr *hdr = models->GetStudioHeader( modelindex ); + if ( !hdr ) + return; + + char filename[ 256 ]; + V_strcpy_safe( filename, GetBitmapFilename( modelindex ) ); + if ( !Q_strstr( filename, ".bmp" ) ) + return; + + models->CreateNewBitmap( modelindex, filename, 0, 128, true, this, &m_Bitmap[ modelindex ] ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *exp - +//----------------------------------------------------------------------------- +void CExpression::PushUndoInformation( void ) +{ + SetModified( true ); + + // A real change to the data wipes out the redo counters + WipeRedoInformation(); + + CExpUndoInfo *newundo = new CExpUndoInfo; + + memcpy( newundo->setting, setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memset( newundo->redosetting, 0, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memcpy( newundo->weight, weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memset( newundo->redoweight, 0, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + + newundo->counter = g_counter++; + + undo.AddToHead( newundo ); + + Assert( m_nUndoCurrent == 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *exp - +//----------------------------------------------------------------------------- +void CExpression::PushRedoInformation( void ) +{ + Assert( undo.Size() >= 1 ); + + CExpUndoInfo *redo = undo[ 0 ]; + memcpy( redo->redosetting, setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memcpy( redo->redoweight, weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *exp - +//----------------------------------------------------------------------------- +void CExpression::Undo( void ) +{ + if ( !CanUndo() ) + return; + + Assert( m_nUndoCurrent < undo.Size() ); + + CExpUndoInfo *u = undo[ m_nUndoCurrent++ ]; + Assert( u ); + + memcpy( setting, u->setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memcpy( weight, u->weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *exp - +//----------------------------------------------------------------------------- +void CExpression::Redo( void ) +{ + if ( !CanRedo() ) + return; + + Assert( m_nUndoCurrent >= 1 ); + Assert( m_nUndoCurrent <= undo.Size() ); + + CExpUndoInfo *u = undo[ --m_nUndoCurrent ]; + Assert( u ); + + memcpy( setting, u->redosetting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memcpy( weight, u->redoweight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *exp - +//----------------------------------------------------------------------------- +void CExpression::WipeRedoInformation( void ) +{ + // Wipe out all stuff newer then m_nUndoCurrent + int level = 0; + while ( level < m_nUndoCurrent ) + { + CExpUndoInfo *u = undo[ 0 ]; + undo.Remove( 0 ); + Assert( u ); + delete u; + level++; + } + + m_nUndoCurrent = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Revert to last saved state +//----------------------------------------------------------------------------- +void CExpression::Revert( void ) +{ + SetDirty( false ); + + if ( undo.Size() <= 0 ) + return; + + // Go back to original data + CExpUndoInfo *u = undo[ undo.Size() - 1 ]; + Assert( u ); + + memcpy( setting, u->setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + memcpy( weight, u->weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) ); + + ResetUndo(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : CExpClass +//----------------------------------------------------------------------------- +CExpClass *CExpression::GetExpressionClass( void ) +{ + CExpClass *cl = expressions->FindClass( expressionclass, false ); + if ( !cl ) + { + Assert( cl ); + } + return cl; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *classname - +//----------------------------------------------------------------------------- +void CExpression::SetExpressionClass( char const *classname ) +{ + strcpy( expressionclass, classname ); +} + |