⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expressiontool.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::ClearClickedItem( void )
{
	m_nFocusItem = -1;
}



//-----------------------------------------------------------------------------
// Purpose: 
// Input  : force - force vert scrollbar recomputation	
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::LayoutItems( bool force /* = false */ )
{
	int x = TRAY_ITEM_INSET;
	int y = - m_nTopOffset;
	int width = w2() - 2 * TRAY_ITEM_INSET - m_nScrollbarHeight;
	int height;

	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		if ( !item || !item->GetVisible() )
			continue;

		height = item->GetHeight();

		RECT rcBounds;
		rcBounds.left = x;
		rcBounds.top = y;
		rcBounds.right = x + width;
		rcBounds.bottom = y + height;

		item->SetBounds( rcBounds );
		y += height + m_nItemGap;
	}

	if ( force || ( ComputeVPixelsNeeded() != m_nLastVPixelsNeeded ) )
	{
		RepositionVSlider();
	}

	redraw();
}

int CExpressionToolWorkspace::ComputeVPixelsNeeded( void )
{
	int pixels = 0;

	// Count visible
	int c = 0;
	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		if ( !item || !item->GetVisible() )
			continue;

		c += item->GetHeight();
		c += m_nItemGap;
	}

	pixels += c;

	return pixels;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::RepositionVSlider( void )
{
	int pixelsneeded = ComputeVPixelsNeeded();

	if ( pixelsneeded <= ( h2() ))
	{
		m_pVertScrollBar->setVisible( false );
		m_nTopOffset = 0;
	}
	else
	{
		m_pVertScrollBar->setVisible( true );
	}

	m_pVertScrollBar->setBounds( 
		w2() - m_nScrollbarHeight, 
		0, 
		m_nScrollbarHeight, 
		h2() );

	m_nTopOffset = max( 0, m_nTopOffset );
	m_nTopOffset = min( pixelsneeded, m_nTopOffset );

	m_pVertScrollBar->setRange( 0, pixelsneeded );
	m_pVertScrollBar->setValue( m_nTopOffset );
	m_pVertScrollBar->setPagesize( h2() );

	m_nLastVPixelsNeeded = pixelsneeded;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::DisableAllExcept( void )
{
	TimelineItem *keepExpanded = GetClickedItem();
	if ( !keepExpanded )
		return;

	g_pChoreoView->SetDirty( true );
	g_pChoreoView->PushUndo( "Disable All Except" );

	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );

		item->SetActive( item == keepExpanded ? true : false );
	}

	LayoutItems();
	g_pChoreoView->PushRedo( "Disable All Except" );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::EnableValid( void )
{
	g_pChoreoView->SetDirty( true );
	g_pChoreoView->PushUndo( "Enable Valid" );
	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );

		item->SetActive( item->IsValid() );
	}

	LayoutItems();
	g_pChoreoView->PushRedo( "Enable Valid" );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::CollapseAll( TimelineItem *keepExpanded )
{
	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );

		item->SetCollapsed( item == keepExpanded ? false : true );
	}

	LayoutItems();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::ExpandAll( void )
{
	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		item->SetCollapsed( false );
	}

	LayoutItems();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::OnSnapAll()
{
	g_pChoreoView->SetDirty( true );
	g_pChoreoView->PushUndo( "Snap All" );

	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		item->SnapAll();
	}

	g_pChoreoView->PushRedo( "Snap All" );
	redraw();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::OnDeleteColumn()
{
	float t = g_pExpressionTool->GetTimeForClickedPos();

	float snapped = FacePoser_SnapTime( t );
	int scenefps = FacePoser_GetSceneFPS();

	if ( scenefps <= 0 )
	{
		Con_Printf( "Can't delete column, scene fps is <= 0 (%i)\n", scenefps );
		return;
	}

	int clickedframe = ( int ) ( scenefps * snapped + 0.5f );

	// One half of 1/fps on each side
	float epsilon = epsilon = 0.5f / (float)scenefps;

	CInputParams params;
	memset( &params, 0, sizeof( params ) );
	strcpy( params.m_szDialogTitle, "Delete Column" );
	strcpy( params.m_szPrompt, "Frame(s) to delete [e.g., 82 or 81-91 ]:" );
	Q_snprintf( params.m_szInputText, sizeof( params.m_szInputText ), "%i", clickedframe );

	if ( !InputProperties( &params ) )
		return;

	int deleteframestart;
	int deleteframeend;

	char *sep = strstr( params.m_szInputText, "-" );
	if ( sep )
	{
		*sep = 0;
		deleteframestart = atoi( params.m_szInputText );
		deleteframeend = atoi( sep + 1 );
		deleteframeend = max( deleteframestart, deleteframeend );
	}
	else
	{
		deleteframestart = atoi( params.m_szInputText );
		deleteframeend = deleteframestart;
	}

	float start, end;

	start = (float)deleteframestart / (float)scenefps;
	end = (float)deleteframeend / (float)scenefps;

	g_pChoreoView->SetDirty( true );
	g_pChoreoView->PushUndo( "Delete Column" );

	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		item->DeletePoints( start - epsilon, end + epsilon );
	}

	g_pChoreoView->PushRedo( "Delete Column" );
	redraw();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::ExpandValid( void )
{
	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		bool valid = item->IsValid();
		item->SetCollapsed( !valid );
	}

	LayoutItems();
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : int
//-----------------------------------------------------------------------------
int CExpressionToolWorkspace::CountSelectedSamples( void )
{
	int c = 0;
	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		Assert( item );
		item->CountSelected();
		c += item->GetNumSelected();
	}
	return c;
}

void CExpressionToolWorkspace::MoveSelectedSamples( float dfdx, float dfdy, bool snap )
{
	int selecteditems = CountSelectedSamples();
	if ( !selecteditems )
		return;

	CChoreoEvent *e = g_pExpressionTool->GetSafeEvent();
	if ( !e )
		return;

	float eventduration = e->GetDuration();

	for ( int controller = 0; controller < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; controller++ )
	{
		TimelineItem *item = GetItem( controller );
		if ( !item )
			continue;

		CFlexAnimationTrack *track = item->GetSafeTrack();
		if ( !track )
			continue;

		int edittype = item->GetEditType();

		for ( int i = 0; i < (int)track->GetNumSamples( edittype ); i++ )
		{
			CExpressionSample *sample = track->GetSample( i, edittype );
			if ( !sample || !sample->selected )
				continue;

			sample->time += dfdx;
			sample->time = clamp( sample->time, 0.0f, eventduration );

			if ( snap )
			{
				sample->time = FacePoser_SnapTime( sample->time );
			}

			sample->value -= dfdy;
			sample->value = clamp( sample->value, 0.0f, 1.0f );
		}
				
		track->Resort();

		item->DrawSelf();
	}
}

void CExpressionToolWorkspace::DeleteSelectedSamples( void )
{
	int i, t;

	int selecteditems = CountSelectedSamples();
	if ( !selecteditems )
		return;

	g_pChoreoView->SetDirty( true );
	g_pChoreoView->PushUndo( "Delete points" );

	for ( int controller = 0; controller < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; controller++ )
	{
		TimelineItem *item = GetItem( controller );
		if ( !item )
			continue;

		CFlexAnimationTrack *track = item->GetSafeTrack();
		if ( !track )
			continue;

		for ( t = 0; t < 2; t++ )
		{
			for ( i = track->GetNumSamples( t ) - 1; i >= 0 ; i-- )
			{
				CExpressionSample *sample = track->GetSample( i, t );
				if ( !sample->selected )
					continue;

				track->RemoveSample( i, t );
			}
		}

		item->DrawSelf();
	}

	g_pChoreoView->PushRedo( "Delete points" );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CExpressionToolWorkspace::DeselectAll( void )
{
	int i, t;

	int selecteditems = CountSelectedSamples();
	if ( !selecteditems )
		return;

	for ( int controller = 0; controller < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; controller++ )
	{
		TimelineItem *item = GetItem( controller );
		if ( !item )
			continue;

		CFlexAnimationTrack *track = item->GetSafeTrack();
		if ( !track )
			continue;

		for ( t = 0; t < 2; t++ )
		{
			for ( i = track->GetNumSamples( t ) - 1; i >= 0 ; i-- )
			{
				CExpressionSample *sample = track->GetSample( i, t );
				sample->selected = false;
			}
		}

		item->DrawSelf();
	}
}

void CExpressionToolWorkspace::SelectPoints( float start, float end )
{
	int i, t;

	for ( int controller = 0; controller < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; controller++ )
	{
		TimelineItem *item = GetItem( controller );
		if ( !item )
			continue;

		CFlexAnimationTrack *track = item->GetSafeTrack();
		if ( !track )
			continue;

		for ( t = 0; t < 2; t++ )
		{
			for ( i = track->GetNumSamples( t ) - 1; i >= 0 ; i-- )
			{
				CExpressionSample *sample = track->GetSample( i, t );
				bool inrange = ( sample->time >= start && sample->time <= end );
				sample->selected = inrange;
			}
		}

		item->DrawSelf();
	}
}

ExpressionTool::ExpressionTool( mxWindow *parent )
: IFacePoserToolWindow( "ExpressionTool", "Flex Animation" ), mxWindow( parent, 0, 0, 0, 0 )
{
	m_bSuppressLayout = false;

	SetAutoProcess( true );

	m_pWorkspace = new CExpressionToolWorkspace( this );

	m_szEvent[0]		= 0;

	m_flScrub			= 0.0f;
	m_flScrubTarget		= 0.0f;
	m_nDragType			= DRAGTYPE_NONE;

	m_nClickedX			= 0;
	m_nClickedY			= 0;

	m_hPrevCursor		= 0;
	
	m_nStartX			= 0;
	m_nStartY			= 0;

	m_nMinX				= 0;
	m_nMaxX				= 0;
	m_bUseBounds		= false;

	m_pLastEvent		= NULL;

	m_nMousePos[ 0 ] = m_nMousePos[ 1 ] = 0;

	m_flSelection[ 0 ] = m_flSelection[ 1 ] = 0.0f;
	m_bSelectionActive = false;

	m_bLayoutIsValid = false;
	m_flPixelsPerSecond = 500.0f;

	m_flLastDuration = 0.0f;
	m_nTimeZoom = 100;
	m_nScrollbarHeight	= 12;
	m_nLeftOffset = 0;
	m_nLastHPixelsNeeded = -1;
	m_pHorzScrollBar = new mxScrollbar( this, 0, 0, 18, 100, IDC_FLEXHSCROLL, mxScrollbar::Horizontal );
	m_pHorzScrollBar->setVisible( false );

	m_bInSetEvent = false;
	m_flScrubberTimeOffset = 0.0f;
}

ExpressionTool::~ExpressionTool( void )
{
}

void ExpressionTool::DoTrackLookup( CChoreoEvent *event )
{
	if ( !event || !models->GetActiveStudioModel() )
		return;

	//if ( event->GetTrackLookupSet() )
	//	return;

	// Force recompute
	SetEvent( event );
}

#pragma optimize( "g", off )

void ExpressionTool::SetEvent( CChoreoEvent *event )
{
	if ( m_bInSetEvent )
		return;

	m_bInSetEvent = true;

	if ( event == m_pLastEvent )
	{
		if ( event )
		{
			float dur = event->GetDuration();
			if ( dur != m_flLastDuration )
			{
				m_flLastDuration = dur;
				m_nLastHPixelsNeeded = -1;
				m_nLeftOffset = 0;
				InvalidateLayout();
			}
		}
		m_bInSetEvent = false;
		return;
	}

	m_pLastEvent = event;

	m_pWorkspace->HideTimelines();

	m_szEvent[ 0 ] = 0;
	if ( event )
	{
		strcpy( m_szEvent, event->GetName() );
	
		if ( models->GetActiveStudioModel() )
		{
			studiohdr_t *hdr = models->GetActiveStudioModel()->getStudioHeader ();
			if ( hdr )
			{
				// Force re-lookup
				event->SetTrackLookupSet( false );
				
				SetupFlexControllerTracks( hdr, event );

				int itemCount = 0;

				for ( int i = 0; i < event->GetNumFlexAnimationTracks(); i++ )
				{
					CFlexAnimationTrack *track = event->GetFlexAnimationTrack( i );
					Assert( track );
					if ( !track )
						continue;

					TimelineItem *item = m_pWorkspace->GetItem( itemCount++ );
					item->SetExpressionInfo( track, track->GetFlexControllerIndex( 0 ) );
					item->SetCollapsed( track->GetNumSamples( 0 ) <= 0 );
					item->SetVisible( true );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -