|
|
//====== Copyright � 1996-2009, Valve Corporation, All rights reserved. =======
//
// DmeEyeball
//
//=============================================================================
// Standard includes
#include <ctype.h>
// Valve includes
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmecombinationoperator.h"
#include "movieobjects/dmeexpressionoperator.h"
#include "movieobjects/dmeflexrules.h"
// Last include
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeFlexRuleBase, CDmeFlexRuleBase );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleBase::OnConstruction() { m_flResult.Init( this, "result" ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleBase::OnDestruction() { }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleBase::GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs ) { BaseClass::GetInputAttributes( attrs );
CDmeFlexRules *pDmeFlexRules = GetFlexRules(); if ( pDmeFlexRules ) { attrs.AddToTail( pDmeFlexRules->m_vDeltaStateWeights.GetAttribute() ); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleBase::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs ) { BaseClass::GetOutputAttributes( attrs );
attrs.AddToTail( m_flResult.GetAttribute() ); }
//-----------------------------------------------------------------------------
// Returns the first DmeExpressionRules element that refers to this element
//-----------------------------------------------------------------------------
CDmeFlexRules *CDmeFlexRuleBase::GetFlexRules() const { return FindReferringElement< CDmeFlexRules >( this, "deltaStates" ); }
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeFlexRulePassThrough, CDmeFlexRulePassThrough );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRulePassThrough::OnConstruction() { }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRulePassThrough::OnDestruction() { }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRulePassThrough::Operate() { CDmeFlexRules *pDmeFlexRules = GetFlexRules(); if ( !pDmeFlexRules ) return;
const float flResult = pDmeFlexRules->GetDeltaStateWeight( GetName() );
m_flResult.Set( flResult ); }
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeFlexRuleExpression, CDmeFlexRuleExpression );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleExpression::OnConstruction() { m_expr.Init( this, "expr" ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleExpression::OnDestruction() { }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleExpression::Operate() { CDmeFlexRules *pDmeFlexRules = GetFlexRules(); if ( pDmeFlexRules ) { for ( int i = 0; i < m_calc.VariableCount(); ++i ) { m_calc.SetVariable( i, pDmeFlexRules->GetDeltaStateWeight( m_calc.VariableName( i ) ) ); } }
float flVal = 0.0f;
if ( m_calc.Evaluate( flVal ) ) { m_flResult.Set( flVal ); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleExpression::Resolve() { if ( m_expr.IsDirty() ) { m_calc.SetExpression( m_expr.Get() ); m_calc.BuildVariableListFromExpression(); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CDmeFlexRuleExpression::SetExpression( const char *pszExpression ) { if ( !pszExpression || *pszExpression == '\0' ) return false;
bool bReturn = false;
CUtlVector< char *, CUtlMemory< char *, int > > pathStrings; V_SplitString( pszExpression, "=", pathStrings ); if ( pathStrings.Count() == 2 ) { char *pszLhs = pathStrings[0]; while ( V_isspace( *pszLhs ) ) { ++pszLhs; }
for ( char *pszChar = pszLhs + V_strlen( pszLhs ) - 1; V_isspace( *pszChar ) && pszChar >= pszLhs; --pszChar ) { *pszChar = '\0'; }
char *pszRhs = pathStrings[1]; while ( V_isspace( *pszRhs ) ) { ++pszRhs; }
for ( char *pszChar = pszRhs + V_strlen( pszRhs ) - 1; V_isspace( *pszChar ) && pszChar >= pszRhs; --pszChar ) { *pszChar = '\0'; }
m_expr = pszRhs;
Resolve();
// It's assumed the name of the node is the same as the variable on the left hand side of the expression
Assert( !V_strcmp( pszLhs, GetName() ) ); }
pathStrings.PurgeAndDeleteElements();
return bReturn; }
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeFlexRuleLocalVar, CDmeFlexRuleLocalVar );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleLocalVar::OnConstruction() { }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRuleLocalVar::OnDestruction() { }
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeFlexRules, CDmeFlexRules );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::OnConstruction() { // Required to drive this node from a DmeCombinationOperator
m_eDeltaStates.Init( this, "deltaStates" ); m_vDeltaStateWeights.Init( this, "deltaStateWeights" );
m_eTarget.Init( this, "target" ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::OnDestruction() { }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::Operate() { if ( m_deltaToTargetMap.Count() <= 0 ) { Resolve(); }
const int nDeltaCount = MIN( m_eDeltaStates.Count(), m_deltaToTargetMap.Count() );
CDmrArray< Vector2D > targetWeights( m_eTarget, "deltaStateWeights" ); const int nTargetWeightCount = targetWeights.Count();
for ( int i = 0; i < nDeltaCount; ++i ) { const int nTargetIndex = m_deltaToTargetMap[i]; if ( nTargetIndex < 0 || nTargetIndex >= nTargetWeightCount ) continue;
CDmeFlexRuleBase *pDmeFlexRuleBase = m_eDeltaStates[i]; if ( !pDmeFlexRuleBase ) continue;
const CDmAttribute *pDmResultAttr = pDmeFlexRuleBase->ResultAttr(); if ( !pDmResultAttr ) continue;
const float flVal = pDmResultAttr->GetValue< float >();
targetWeights.Set( nTargetIndex, Vector2D( flVal, flVal ) ); // FlexRules ignore the built in stereo
} }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::Resolve() { if ( m_deltaToTargetMap.Count() <= 0 || m_eTarget.IsDirty() || m_eDeltaStates.IsDirty() ) { m_deltaToTargetMap.SetCountNonDestructively( m_eDeltaStates.Count() );
const CDmrElementArrayConst< CDmElement > targetStates( m_eTarget, "deltaStates" );
for ( int i = 0; i < m_eDeltaStates.Count(); ++i ) { m_deltaToTargetMap[i] = -1;
CDmeFlexRuleBase *pDmeFlexRuleBase = m_eDeltaStates[i]; if ( !pDmeFlexRuleBase ) continue;
for ( int j = 0; j < targetStates.Count(); ++j ) { if ( !V_strcmp( targetStates[j]->GetName(), pDmeFlexRuleBase->GetName() ) ) { m_deltaToTargetMap[i] = j; break; } } } } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs ) { attrs.AddToTail( m_eDeltaStates.GetAttribute() ); attrs.AddToTail( m_vDeltaStateWeights.GetAttribute() );
for ( int i = 0; i < m_eDeltaStates.Count(); ++i ) { m_eDeltaStates[i]->GetOutputAttributes( attrs ); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs ) { CDmrArray<Vector2D> targetWeights( m_eTarget, "deltaStateWeights" );
if ( targetWeights.IsValid() ) { attrs.AddToTail( targetWeights.GetAttribute() ); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::AddFlexRule( CDmeFlexRuleBase *pDmeFlexRule ) { if ( !pDmeFlexRule ) return;
m_eDeltaStates.AddToTail( pDmeFlexRule );
m_vDeltaStateWeights.AddToTail(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::RemoveAllRules() { m_eDeltaStates.RemoveAll(); m_vDeltaStateWeights.RemoveAll(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFlexRules::SetTarget( CDmElement *pDmElement ) { if ( !pDmElement ) return;
m_eTarget = pDmElement; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDmeFlexRules::GetDeltaStateIndex( const char *pszDeltaName ) const { for ( int i = 0; i < m_eDeltaStates.Count(); ++i ) { if ( !V_strcmp( pszDeltaName, m_eDeltaStates[i]->GetName() ) ) return i; }
return -1; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
float CDmeFlexRules::GetDeltaStateWeight( const char *pszDeltaName ) const { const int nDeltaStateIndex = GetDeltaStateIndex( pszDeltaName ); if ( nDeltaStateIndex < 0 || nDeltaStateIndex >= m_vDeltaStateWeights.Count() ) return 0.0f;
return m_vDeltaStateWeights[nDeltaStateIndex].x; // Weights are stereo...
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmeCombinationOperator *CDmeFlexRules::GetComboOp() const { return FindReferringElement< CDmeCombinationOperator >( this, m_vDeltaStateWeights.GetAttribute()->GetName() ); }
|