//-----------------------------------------------------------------------------
// 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();
}
Example #2
0
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 ) );
}