//----------------------------------------------------------------------------- // Purpose: Default implementation //----------------------------------------------------------------------------- void CBaseFlex::ProcessExpressions( void ) { // slowly decay to netural expression for (int i = 0; i < GetNumFlexControllers(); i++) { SetFlexWeight( i, GetFlexWeight( i ) * 0.95 ); } AddSceneExpressions(); }
void CFlextalkActor::ProcessSceneEvents( void ) { if ( HasSceneEvents() ) { BaseClass::ProcessSceneEvents( ); return; } // only do this if they have more than eyelid movement if (GetNumFlexControllers() > 2) { const char *pszExpression = flex_expression.GetString(); if (pszExpression && pszExpression[0] == '+' && pszExpression[1] != '\0') { int i; int j = atoi( &pszExpression[1] ); for (i = 0; i < GetNumFlexControllers(); i++) { m_flextarget[m_flexnum] = 0; } for (i = 0; i < 35 && predef_flexcontroller_names[i]; i++) { m_flexnum = LookupFlex( predef_flexcontroller_names[i] ); m_flextarget[m_flexnum] = predef_flexcontroller_values[j][i]; // Msg( "%s %.3f\n", predef_flexcontroller_names[i], predef_flexcontroller_values[j][i] ); } } else if (pszExpression && pszExpression[0] != '\0' && strcmp(pszExpression, "+") != 0) { char szExpression[128]; char szTemp[32]; Q_strncpy( szExpression, pszExpression ,sizeof(szExpression)); char *pszExpression = szExpression; while (*pszExpression != '\0') { if (*pszExpression == '+') *pszExpression = ' '; pszExpression++; } pszExpression = szExpression; while (*pszExpression) { if (*pszExpression != ' ') { if (*pszExpression == '-') { for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { m_flextarget[i] = 0; } } else if (*pszExpression == '?') { for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { Msg( "\"%s\" ", GetFlexControllerName( i ) ); } Msg( "\n" ); flex_expression.SetValue( "" ); } else { if (sscanf( pszExpression, "%31s", szTemp ) == 1) { m_flexnum = LookupFlex( szTemp ); if (m_flexnum != -1 && m_flextarget[m_flexnum] != 1) { m_flextarget[m_flexnum] = 1.0; // SetFlexTarget( m_flexnum ); } pszExpression += strlen( szTemp ) - 1; } } } pszExpression++; } } else if (m_flextime < gpGlobals->curtime) { m_flextime = gpGlobals->curtime + random->RandomFloat( 0.3, 0.5 ) * (30.0 / GetNumFlexControllers()); m_flexnum = (LocalFlexController_t)random->RandomInt( 0, GetNumFlexControllers() - 1 ); if (m_flextarget[m_flexnum] == 1) { m_flextarget[m_flexnum] = 0; } else if (stricmp( GetFlexControllerType( m_flexnum ), "phoneme" ) != 0) { if (strstr( GetFlexControllerName( m_flexnum ), "upper_raiser" ) == NULL) { Msg( "%s:%s\n", GetFlexControllerType( m_flexnum ), GetFlexControllerName( m_flexnum ) ); SetFlexTarget( m_flexnum, random->RandomFloat( 0.5, 1.0 ) ); } } } // slide it up. for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { float weight = GetFlexWeight( i ); if (weight != m_flextarget[i]) { weight = weight + (m_flextarget[i] - weight) / random->RandomFloat( 2.0, 4.0 ); } weight = clamp( weight, 0.0f, 1.0f ); SetFlexWeight( i, weight ); } if (flex_talk.GetInt() == -1) { m_istalking = 1; char pszSentence[256]; Q_snprintf( pszSentence,sizeof(pszSentence), "%s%d", STRING(m_iszSentence), m_sentence++ ); int sentenceIndex = engine->SentenceIndexFromName( pszSentence ); if (sentenceIndex >= 0) { Msg( "%d : %s\n", sentenceIndex, pszSentence ); CPASAttenuationFilter filter( this ); CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, SNDLVL_TALKING, 0, PITCH_NORM ); } else { m_sentence = 0; } flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -2) { m_flNextEyeLookTime = gpGlobals->curtime + 1000.0; } else if (flex_talk.GetInt() == -3) { m_flNextEyeLookTime = gpGlobals->curtime; flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -4) { AddLookTarget( UTIL_PlayerByIndex( 1 ), 0.5, flex_looktime.GetFloat() ); flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -5) { PickLookTarget( true ); flex_talk.SetValue( "0" ); } } }
//----------------------------------------------------------------------------- // Purpose: // Input : *expr - // scale - // *pSettinghdr - // *pOverrideHdr - // newexpression - //----------------------------------------------------------------------------- void CBaseFlex::AddExpression( const char *expr, float scale, flexsettinghdr_t *pSettinghdr, flexsettinghdr_t *pOverrideHdr, bool newexpression ) { int i; flexsetting_t const *pSetting = NULL; // Find the named setting in the base for ( i = 0; i < pSettinghdr->numflexsettings; i++ ) { pSetting = pSettinghdr->pSetting( i ); if ( !pSetting ) continue; const char *name = pSetting->pszName(); if ( !stricmp( name, expr ) ) break; } if ( i>=pSettinghdr->numflexsettings ) { return; } // Update markov chain if needed if ( newexpression ) { if ( pSetting->type == FS_MARKOV ) { NewMarkovIndex( pSettinghdr, (flexsetting_t *)pSetting ); } } // Resolve markov chain for the returned setting pSetting = pSettinghdr->pTranslatedSetting( i ); // Check for overrides if ( pOverrideHdr ) { // Get name from setting const char *resolvedName = pSetting->pszName(); if ( resolvedName ) { // See if resolvedName exists in the override file flexsetting_t const *override = FindNamedSetting( pOverrideHdr, resolvedName ); if ( override ) { // If so, point at the override file instead pSettinghdr = pOverrideHdr; pSetting = override; } } } flexweight_t *pWeights = NULL; int truecount = pSetting->psetting( (byte *)pSettinghdr, 0, &pWeights ); if ( !pWeights ) return; for (i = 0; i < truecount; i++, pWeights++) { // Translate to local flex controller // this is translating from the settings's local index to the models local index int index = pSettinghdr->LocalToGlobal( pWeights->key ); // FIXME: this is supposed to blend based on pWeight->influence, but the order is wrong... // float value = GetFlexWeight( index ) * (1 - scale * pWeights->influence) + scale * pWeights->weight; // Add scaled weighting in to total float value = GetFlexWeight( index ) + scale * pWeights->weight; SetFlexWeight( index, value ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *event - //----------------------------------------------------------------------------- void CBaseFlex::AddFlexAnimation( CExpressionInfo *info ) { if ( !info ) return; CChoreoEvent *event = info->m_pEvent; if ( !event ) return; CChoreoScene *scene = info->m_pScene; if ( !scene ) return; if ( !event->GetTrackLookupSet() ) { // Create lookup data for ( int i = 0; i < event->GetNumFlexAnimationTracks(); i++ ) { CFlexAnimationTrack *track = event->GetFlexAnimationTrack( i ); if ( !track ) continue; if ( track->IsComboType() ) { char name[ 512 ]; Q_strncpy( name, "right_" ,sizeof(name)); strcat( name, track->GetFlexControllerName() ); track->SetFlexControllerIndex( 0, FindFlexController( name ), 0 ); Q_strncpy( name, "left_" ,sizeof(name)); strcat( name, track->GetFlexControllerName() ); track->SetFlexControllerIndex( 0, FindFlexController( name ), 1 ); } else { track->SetFlexControllerIndex( 0, FindFlexController( (char *)track->GetFlexControllerName() ) ); } } event->SetTrackLookupSet( true ); } float scenetime = scene->GetTime(); float weight = event->GetIntensity( scenetime ); // Compute intensity for each track in animation and apply // Iterate animation tracks for ( int i = 0; i < event->GetNumFlexAnimationTracks(); i++ ) { CFlexAnimationTrack *track = event->GetFlexAnimationTrack( i ); if ( !track ) continue; // Disabled if ( !track->IsTrackActive() ) continue; // Map track flex controller to global name if ( track->IsComboType() ) { for ( int side = 0; side < 2; side++ ) { int controller = track->GetFlexControllerIndex( side ); // Get spline intensity for controller float flIntensity = track->GetIntensity( scenetime, side ); if ( controller >= 0 ) { float orig = GetFlexWeight( controller ); SetFlexWeight( controller, orig * (1 - weight) + flIntensity * weight ); } } } else { int controller = track->GetFlexControllerIndex( 0 ); // Get spline intensity for controller float flIntensity = track->GetIntensity( scenetime, 0 ); if ( controller >= 0 ) { float orig = GetFlexWeight( controller ); SetFlexWeight( controller, orig * (1 - weight) + flIntensity * weight ); } } } info->m_bStarted = true; }
float CBaseFlex::GetFlexWeight( char *szName ) { return GetFlexWeight( FindFlexController( szName ) ); }