Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1011 lines
34 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "vstdlib/random.h"
  8. #include "dme_controls/dmedageditpanel.h"
  9. #include "dme_controls/dmedagrenderpanel.h"
  10. #include "dme_controls/dmepanel.h"
  11. #include "vgui_controls/Button.h"
  12. #include "vgui_controls/Splitter.h"
  13. #include "vgui_controls/PropertySheet.h"
  14. #include "vgui_controls/PropertyPage.h"
  15. #include "vgui_controls/Label.h"
  16. #include "vgui_controls/ScrollBar.h"
  17. #include "vgui_controls/Slider.h"
  18. #include "vgui_controls/ScrollableEditablePanel.h"
  19. #include "vgui_controls/ListPanel.h"
  20. #include "vgui_controls/Image.h"
  21. #include "vgui_controls/TextImage.h"
  22. #include "vgui/ISurface.h"
  23. #include "vgui/ischeme.h"
  24. #include "vgui/iinput.h"
  25. #include "vgui/IVGui.h"
  26. #include "vgui/cursor.h"
  27. #include "movieobjects/dmemakefile.h"
  28. #include "movieobjects/dmemdlmakefile.h"
  29. #include "movieobjects/dmedccmakefile.h"
  30. #include "movieobjects/dmedag.h"
  31. #include "movieobjects/dmeclip.h"
  32. #include "movieobjects/dmeanimationlist.h"
  33. #include "movieobjects/dmecombinationoperator.h"
  34. #include "movieobjects/dmeanimationset.h"
  35. #include "tier1/KeyValues.h"
  36. #include "materialsystem/imesh.h"
  37. #include "dme_controls/BaseAnimationSetEditor.h"
  38. #include "dme_controls/BaseAnimSetAttributeSliderPanel.h"
  39. //-----------------------------------------------------------------------------
  40. //
  41. // Hook into the dme panel editor system
  42. //
  43. //-----------------------------------------------------------------------------
  44. IMPLEMENT_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeDag, "DmeDagPreview2", "DmeDag Previewer 2", false );
  45. IMPLEMENT_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeSourceSkin, "DmeSourceSkinPreview2", "MDL Skin Previewer 2", false );
  46. IMPLEMENT_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeSourceAnimation, "DmeSourceAnimationPreview2", "MDL Animation Previewer 2", false );
  47. IMPLEMENT_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeDCCMakefile, "DmeMakeFileOutputPreview2", "DCC MakeFile Output Previewer 2", false );
  48. //-----------------------------------------------------------------------------
  49. // Slider panel
  50. //-----------------------------------------------------------------------------
  51. class CDmeAnimationListPanel : public vgui::EditablePanel
  52. {
  53. DECLARE_CLASS_SIMPLE( CDmeAnimationListPanel, vgui::EditablePanel );
  54. public:
  55. // constructor, destructor
  56. CDmeAnimationListPanel( vgui::Panel *pParent, const char *pName );
  57. virtual ~CDmeAnimationListPanel();
  58. void SetAnimationList( CDmeAnimationList *pList );
  59. void RefreshAnimationList();
  60. const char *GetSelectedAnimation() const;
  61. private:
  62. // Called when the selection changes moves
  63. MESSAGE_FUNC( OnItemSelected, "ItemSelected" );
  64. MESSAGE_FUNC( OnItemDeselected, "ItemDeselected" );
  65. vgui::ListPanel *m_pAnimationList;
  66. CDmeHandle< CDmeAnimationList > m_hAnimationList;
  67. };
  68. static int __cdecl AnimationNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
  69. {
  70. const char *string1 = item1.kv->GetString("name");
  71. const char *string2 = item2.kv->GetString("name");
  72. return Q_stricmp( string1, string2 );
  73. }
  74. //-----------------------------------------------------------------------------
  75. // constructor, destructor
  76. //-----------------------------------------------------------------------------
  77. CDmeAnimationListPanel::CDmeAnimationListPanel( vgui::Panel *pParent, const char *pName ) :
  78. BaseClass( pParent, pName )
  79. {
  80. m_pAnimationList = new vgui::ListPanel( this, "AnimationList" );
  81. m_pAnimationList->AddColumnHeader( 0, "name", "name", 100, 0 );
  82. m_pAnimationList->AddActionSignalTarget( this );
  83. m_pAnimationList->SetSortFunc( 0, AnimationNameSortFunc );
  84. m_pAnimationList->SetSortColumn( 0 );
  85. m_pAnimationList->SetEmptyListText("No animations");
  86. m_pAnimationList->SetMultiselectEnabled( false );
  87. LoadControlSettingsAndUserConfig( "resource/dmeanimationlistpanel.res" );
  88. }
  89. CDmeAnimationListPanel::~CDmeAnimationListPanel()
  90. {
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Sets the combination operator
  94. //-----------------------------------------------------------------------------
  95. void CDmeAnimationListPanel::SetAnimationList( CDmeAnimationList *pList )
  96. {
  97. if ( pList != m_hAnimationList.Get() )
  98. {
  99. m_hAnimationList = pList;
  100. RefreshAnimationList();
  101. }
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Builds the list of animations
  105. //-----------------------------------------------------------------------------
  106. void CDmeAnimationListPanel::RefreshAnimationList()
  107. {
  108. m_pAnimationList->RemoveAll();
  109. if ( !m_hAnimationList.Get() )
  110. return;
  111. int nCount = m_hAnimationList->GetAnimationCount();
  112. for ( int i = 0; i < nCount; ++i )
  113. {
  114. CDmeChannelsClip *pAnimation = m_hAnimationList->GetAnimation( i );
  115. KeyValues *pItemKeys = new KeyValues( "node", "name", pAnimation->GetName() );
  116. m_pAnimationList->AddItem( pItemKeys, 0, false, false );
  117. }
  118. m_pAnimationList->SortList();
  119. }
  120. //-----------------------------------------------------------------------------
  121. // Returns the selected animation
  122. //-----------------------------------------------------------------------------
  123. const char *CDmeAnimationListPanel::GetSelectedAnimation() const
  124. {
  125. if ( m_pAnimationList->GetSelectedItemsCount() == 0 )
  126. return "";
  127. int nIndex = m_pAnimationList->GetSelectedItem( 0 );
  128. KeyValues *pItemKeyValues = m_pAnimationList->GetItem( nIndex );
  129. return pItemKeyValues->GetString( "name" );
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Called when an animation is selected or deselected
  133. //-----------------------------------------------------------------------------
  134. void CDmeAnimationListPanel::OnItemSelected( )
  135. {
  136. const char *pAnimationName = GetSelectedAnimation();
  137. PostActionSignal( new KeyValues( "AnimationSelected", "animationName", pAnimationName ) );
  138. }
  139. void CDmeAnimationListPanel::OnItemDeselected( )
  140. {
  141. PostActionSignal( new KeyValues( "AnimationDeselected" ) );
  142. }
  143. class CDmeCombinationOperatorPanel : public CBaseAnimationSetEditor
  144. {
  145. DECLARE_CLASS_SIMPLE( CDmeCombinationOperatorPanel, CBaseAnimationSetEditor );
  146. public:
  147. CDmeCombinationOperatorPanel( vgui::Panel *parent, const char *panelName );
  148. virtual ~CDmeCombinationOperatorPanel();
  149. virtual void OnTick();
  150. void SetCombinationOperator( CDmeCombinationOperator *pOp );
  151. void RefreshCombinationOperator();
  152. private:
  153. void CreateFakeAnimationSet( );
  154. void DestroyFakeAnimationSet( );
  155. // Adds new controls to the animation set
  156. void AddNewAnimationSetControls();
  157. // Removes a controls from all presets
  158. void RemoveAnimationControlFromPresets( const char *pControlName );
  159. // Removes a controls from all presets
  160. void RemoveAnimationControlFromSelectionGroups( const char *pControlName );
  161. // Removes controls from the animation set that aren't used
  162. void RemoveUnusedAnimationSetControls();
  163. // Modify controls in the presets which have had stereo or multilevel settings changed
  164. void ModifyExistingAnimationSetControls();
  165. // Modify controls in the presets which have had stereo or multilevel settings changed
  166. void ModifyExistingAnimationSetPresets( CDmElement *pControlElement );
  167. // Modify controls which have had stereo or multilevel settings changed
  168. void ModifyExistingAnimationSetControl( CDmElement *pControlElement );
  169. // Creates the procedural presets
  170. void ComputeProceduralPresets();
  171. void RefreshAnimationSet();
  172. // Sort control names to match the combination controls
  173. void SortAnimationSetControls();
  174. // Sets preset values
  175. void GenerateProceduralPresetValues( CDmElement *pPreset, CDmElement *pControl, bool bIdentity, float flForceValue );
  176. void GenerateProceduralPresetValues( CDmElement *pPreset, const CDmrElementArray< CDmElement > &controls, bool bIdentity, float flForceValue = -1.0f );
  177. CDmeHandle< CDmeCombinationOperator > m_hCombinationOperator;
  178. };
  179. //-----------------------------------------------------------------------------
  180. // Constructor/destructor
  181. //-----------------------------------------------------------------------------
  182. CDmeCombinationOperatorPanel::CDmeCombinationOperatorPanel( vgui::Panel *parent, const char *panelName ) :
  183. BaseClass( parent, panelName, false )
  184. {
  185. CreateFakeAnimationSet();
  186. vgui::ivgui()->AddTickSignal( GetVPanel(), 0 );
  187. }
  188. CDmeCombinationOperatorPanel::~CDmeCombinationOperatorPanel()
  189. {
  190. DestroyFakeAnimationSet();
  191. }
  192. //-----------------------------------------------------------------------------
  193. // Create, destroy fake animation sets
  194. //-----------------------------------------------------------------------------
  195. void CDmeCombinationOperatorPanel::CreateFakeAnimationSet( )
  196. {
  197. m_AnimSet = CreateElement< CDmeAnimationSet >( "fakeSet", DMFILEID_INVALID );
  198. m_AnimSet->SetValue( "gameModel", DMELEMENT_HANDLE_INVALID );
  199. g_pDataModel->DontAutoDelete( m_AnimSet->GetHandle() );
  200. }
  201. void CDmeCombinationOperatorPanel::DestroyFakeAnimationSet( )
  202. {
  203. DestroyElement( m_AnimSet, TD_DEEP );
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Sets combination ops + animation sets
  207. //-----------------------------------------------------------------------------
  208. void CDmeCombinationOperatorPanel::SetCombinationOperator( CDmeCombinationOperator *pOp )
  209. {
  210. // The Animation Set Editor Doesn't Handle Passing The Same Animation Set With
  211. // Different Data In It Very Well
  212. DestroyFakeAnimationSet();
  213. CreateFakeAnimationSet();
  214. if ( pOp != m_hCombinationOperator.Get() )
  215. {
  216. m_hCombinationOperator = pOp;
  217. RefreshCombinationOperator();
  218. }
  219. }
  220. //-----------------------------------------------------------------------------
  221. // Sets preset values
  222. //-----------------------------------------------------------------------------
  223. void CDmeCombinationOperatorPanel::GenerateProceduralPresetValues( CDmElement *pPreset, CDmElement *ctrl, bool bForceValue, float flForceValue )
  224. {
  225. bool combo = ctrl->GetValue< bool >( "combo" );
  226. bool multi = ctrl->GetValue< bool >( "multi" );
  227. float flValue, flBalance, flMultilevel;
  228. if ( !bForceValue )
  229. {
  230. flValue = RandomFloat( 0.0f, 1.0f );
  231. flBalance = RandomFloat( 0.25f, 0.75f );
  232. flMultilevel = RandomFloat( 0.0f, 1.0f );
  233. }
  234. else
  235. {
  236. flValue = flBalance = flMultilevel = flForceValue;
  237. }
  238. pPreset->SetValue< float >( "value", flValue );
  239. if ( combo )
  240. {
  241. pPreset->SetValue< float >( "balance", flBalance );
  242. }
  243. else
  244. {
  245. pPreset->RemoveAttribute( "balance" );
  246. }
  247. if ( multi )
  248. {
  249. pPreset->SetValue< float >( "multilevel", flMultilevel );
  250. }
  251. else
  252. {
  253. pPreset->RemoveAttribute( "multilevel" );
  254. }
  255. }
  256. void CDmeCombinationOperatorPanel::GenerateProceduralPresetValues( CDmElement *pPreset, const CDmrElementArray< CDmElement > &controls, bool bIdentity, float flForceValue /*= -1.0f*/ )
  257. {
  258. CDmrElementArray<> values( pPreset, "controlValues" );
  259. Assert( values.IsValid() );
  260. values.RemoveAll();
  261. int c = controls.Count();
  262. for ( int i = 0; i < c ; ++i )
  263. {
  264. CDmElement *pControl = controls[ i ];
  265. CDmElement *pControlValue = CreateElement< CDmElement >( pControl->GetName(), pPreset->GetFileId() );
  266. GenerateProceduralPresetValues( pControlValue, pControl, bIdentity, flForceValue );
  267. values.AddToTail( pControlValue );
  268. }
  269. }
  270. //-----------------------------------------------------------------------------
  271. // Removes a controls from all presets
  272. //-----------------------------------------------------------------------------
  273. void CDmeCombinationOperatorPanel::RemoveAnimationControlFromPresets( const char *pControlName )
  274. {
  275. CDmeAnimationSet *pAnimationSet = m_AnimSet.Get();
  276. CDmrElementArray< CDmePresetGroup > presetGroupList = pAnimationSet->GetPresetGroups();
  277. int nPresetGroupCount = presetGroupList.Count();
  278. for ( int i = 0; i < nPresetGroupCount; ++i )
  279. {
  280. CDmePresetGroup *pPresetGroup = presetGroupList[ i ];
  281. CDmrElementArray< CDmePreset > presetList = pPresetGroup->GetPresets();
  282. int nPresetCount = presetList.Count();
  283. for ( int j = 0; j < nPresetCount; ++j )
  284. {
  285. CDmePreset *pPreset = presetList[ j ];
  286. CDmrElementArray<> controlValues = pPreset->GetControlValues();
  287. int nControlCount = controlValues.Count();
  288. for ( int k = 0; k < nControlCount; ++k )
  289. {
  290. CDmElement *v = controlValues[ k ];
  291. if ( !Q_stricmp( v->GetName(), pControlName ) )
  292. {
  293. controlValues.FastRemove( k );
  294. break;
  295. }
  296. }
  297. }
  298. }
  299. }
  300. //-----------------------------------------------------------------------------
  301. // Removes a controls from all presets
  302. //-----------------------------------------------------------------------------
  303. void CDmeCombinationOperatorPanel::RemoveAnimationControlFromSelectionGroups( const char *pControlName )
  304. {
  305. CDmeAnimationSet *pAnimationSet = m_AnimSet.Get();
  306. CDmrElementArray< > selectionGroupList = pAnimationSet->GetSelectionGroups();
  307. int nGroupCount = selectionGroupList.Count();
  308. for ( int i = 0; i < nGroupCount; ++i )
  309. {
  310. CDmElement *pSelectionGroup = selectionGroupList[ i ];
  311. CDmrStringArray selectedControls( pSelectionGroup, "selectedControls" );
  312. int nControlCount = selectedControls.Count();
  313. for ( int j = 0; j < nControlCount; ++j )
  314. {
  315. if ( !Q_stricmp( selectedControls[ j ], pControlName ) )
  316. {
  317. selectedControls.FastRemove( j );
  318. break;
  319. }
  320. }
  321. }
  322. }
  323. //-----------------------------------------------------------------------------
  324. // Removes controls from the animation set that aren't used
  325. //-----------------------------------------------------------------------------
  326. void CDmeCombinationOperatorPanel::RemoveUnusedAnimationSetControls()
  327. {
  328. CDmeAnimationSet *pAnimationSet = m_AnimSet.Get();
  329. CDmrElementArray< > controls = pAnimationSet->GetControls();
  330. // Remove all controls in the animation set and in presets that don't exist in the combination system
  331. int nAnimSetCount = controls.Count();
  332. for ( int i = nAnimSetCount; --i >= 0; )
  333. {
  334. CDmElement *pControlElement = controls[i];
  335. if ( !pControlElement )
  336. continue;
  337. // Don't do any of this work for transforms
  338. if ( pControlElement->GetValue< bool >( "transform" ) )
  339. continue;
  340. const char *pControlName = pControlElement->GetName();
  341. // Look for a match
  342. if ( m_hCombinationOperator.Get() && m_hCombinationOperator->FindControlIndex( pControlName ) >= 0 )
  343. continue;
  344. // No match, blow the control away.
  345. RemoveAnimationControlFromPresets( pControlName );
  346. RemoveAnimationControlFromSelectionGroups( pControlName );
  347. controls.FastRemove( i );
  348. }
  349. }
  350. //-----------------------------------------------------------------------------
  351. // Modify controls in the presets which have had stereo or multilevel settings changed
  352. //-----------------------------------------------------------------------------
  353. void CDmeCombinationOperatorPanel::ModifyExistingAnimationSetControl( CDmElement *pControlElement )
  354. {
  355. const char *pControlName = pControlElement->GetName();
  356. // Look for a match
  357. int nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName );
  358. Assert( nControlIndex >= 0 );
  359. bool bIsStereoControl = m_hCombinationOperator->IsStereoControl( nControlIndex );
  360. bool bIsAnimControlStereo = pControlElement->GetValue< bool >( "combo" );
  361. if ( bIsAnimControlStereo != bIsStereoControl )
  362. {
  363. pControlElement->SetValue< bool >( "combo", bIsStereoControl );
  364. if ( !bIsStereoControl )
  365. {
  366. pControlElement->RemoveAttribute( "balance" );
  367. }
  368. else
  369. {
  370. const Vector2D &value = m_hCombinationOperator->GetStereoControlValue( nControlIndex );
  371. pControlElement->SetValue< float >( "balance", value.y );
  372. }
  373. }
  374. bool bIsMultiControl = m_hCombinationOperator->IsMultiControl( nControlIndex );
  375. bool bIsAnimMultiControl = pControlElement->GetValue< bool >( "multi" );
  376. if ( bIsAnimMultiControl != bIsMultiControl )
  377. {
  378. pControlElement->SetValue< bool >( "multi", bIsMultiControl );
  379. if ( !bIsMultiControl )
  380. {
  381. pControlElement->RemoveAttribute( "multilevel" );
  382. }
  383. else
  384. {
  385. pControlElement->SetValue< float >( "multilevel", m_hCombinationOperator->GetMultiControlLevel( nControlIndex ) );
  386. }
  387. }
  388. float flDefaultValue = m_hCombinationOperator->GetRawControlCount( nControlIndex ) == 2 ? 0.5f : 0.0f;
  389. pControlElement->SetValue( "defaultValue", flDefaultValue );
  390. pControlElement->SetValue( "defaultBalance", 0.5f );
  391. pControlElement->SetValue( "defaultMultilevel", 0.5f );
  392. }
  393. //-----------------------------------------------------------------------------
  394. // Modify controls in the presets which have had stereo or multilevel settings changed
  395. //-----------------------------------------------------------------------------
  396. void CDmeCombinationOperatorPanel::ModifyExistingAnimationSetPresets( CDmElement *pControlElement )
  397. {
  398. const char *pControlName = pControlElement->GetName();
  399. CDmeAnimationSet *pAnimationSet = m_AnimSet.Get();
  400. const CDmrElementArray< CDmePresetGroup > &presetGroupList = pAnimationSet->GetPresetGroups();
  401. int nPresetGroupCount = presetGroupList.Count();
  402. for ( int g = 0; g < nPresetGroupCount; ++g )
  403. {
  404. CDmePresetGroup *pPresetGroup = presetGroupList[ g ];
  405. const CDmrElementArray< CDmePreset > &presetList = pPresetGroup->GetPresets();
  406. int nPresetCount = presetList.Count();
  407. for ( int i = 0; i < nPresetCount; ++i )
  408. {
  409. CDmePreset *pPreset = presetList[ i ];
  410. const CDmrElementArray< CDmElement > &controlValues = pPreset->GetControlValues( );
  411. int nControlCount = controlValues.Count();
  412. for ( int j = 0; j < nControlCount; ++j )
  413. {
  414. CDmElement *v = controlValues[ j ];
  415. if ( Q_stricmp( v->GetName(), pControlName ) )
  416. continue;
  417. bool bIsAnimControlStereo = pControlElement->GetValue< bool >( "combo" );
  418. if ( bIsAnimControlStereo )
  419. {
  420. if ( !v->HasAttribute( "balance" ) )
  421. {
  422. v->SetValue( "balance", 0.5f );
  423. }
  424. }
  425. else
  426. {
  427. v->RemoveAttribute( "balance" );
  428. }
  429. bool bIsAnimMultiControl = pControlElement->GetValue< bool >( "multi" );
  430. if ( bIsAnimMultiControl )
  431. {
  432. if ( !v->HasAttribute( "multilevel" ) )
  433. {
  434. v->SetValue( "multilevel", 0.5f );
  435. }
  436. }
  437. else
  438. {
  439. v->RemoveAttribute( "multilevel" );
  440. }
  441. }
  442. }
  443. }
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Modify controls which have had stereo or multilevel settings changed
  447. //-----------------------------------------------------------------------------
  448. void CDmeCombinationOperatorPanel::ModifyExistingAnimationSetControls()
  449. {
  450. CDmeAnimationSet *pAnimationSet = m_AnimSet.Get();
  451. const CDmrElementArray< CDmElement > &controls = pAnimationSet->GetControls();
  452. // Update the main controls; update defaults and add or remove combo + multi data
  453. int nAnimSetCount = controls.Count();
  454. for ( int i = nAnimSetCount; --i >= 0; )
  455. {
  456. CDmElement *pControlElement = controls[i];
  457. if ( !pControlElement )
  458. continue;
  459. // Don't do any of this work for transforms
  460. if ( pControlElement->GetValue< bool >( "transform" ) )
  461. continue;
  462. ModifyExistingAnimationSetControl( pControlElement );
  463. ModifyExistingAnimationSetPresets( pControlElement );
  464. }
  465. }
  466. //-----------------------------------------------------------------------------
  467. // Adds new controls to the animation set
  468. //-----------------------------------------------------------------------------
  469. void CDmeCombinationOperatorPanel::AddNewAnimationSetControls()
  470. {
  471. if ( !m_hCombinationOperator.Get() )
  472. return;
  473. CDmeAnimationSet *pAnimationSet = m_AnimSet.Get();
  474. CDmaElementArray< > &controls = pAnimationSet->GetControls();
  475. // Remove all controls in the animation set and in presets that don't exist in the combination system
  476. int nFirstControl = controls.Count();
  477. int nCombinationControlCount = m_hCombinationOperator->GetControlCount();
  478. for ( int i = 0; i < nCombinationControlCount; ++i )
  479. {
  480. const char *pControlName = m_hCombinationOperator->GetControlName( i );
  481. if ( pAnimationSet->FindControl( pControlName ) )
  482. continue;
  483. bool bIsStereoControl = m_hCombinationOperator->IsStereoControl(i);
  484. bool bIsMultiControl = m_hCombinationOperator->IsMultiControl(i);
  485. float flDefaultValue = m_hCombinationOperator->GetRawControlCount(i) == 2 ? 0.5f : 0.0f;
  486. // Add the control to the controls group
  487. CDmElement *pControl = CreateElement< CDmElement >( pControlName, pAnimationSet->GetFileId() );
  488. Assert( pControl );
  489. controls.InsertBefore( i, pControl );
  490. pControl->SetValue( "combo", bIsStereoControl );
  491. pControl->SetValue( "multi", bIsMultiControl );
  492. if ( bIsStereoControl )
  493. {
  494. const Vector2D &value = m_hCombinationOperator->GetStereoControlValue(i);
  495. pControl->SetValue( "value", value.x );
  496. pControl->SetValue( "balance", value.y );
  497. }
  498. else
  499. {
  500. pControl->SetValue( "value", m_hCombinationOperator->GetControlValue(i) );
  501. }
  502. if ( bIsMultiControl )
  503. {
  504. pControl->SetValue( "multilevel", m_hCombinationOperator->GetMultiControlLevel(i) );
  505. }
  506. pControl->SetValue( "defaultValue", flDefaultValue );
  507. pControl->SetValue( "defaultBalance", 0.5f );
  508. pControl->SetValue( "defaultMultilevel", 0.5f );
  509. }
  510. int nLastControl = controls.Count();
  511. if ( nLastControl == nFirstControl )
  512. return;
  513. // Add new controls to the root group
  514. CDmElement *pGroup = pAnimationSet->FindOrAddSelectionGroup( "Root" );
  515. // Fill in members
  516. CDmrStringArray groups( pGroup, "selectedControls" );
  517. for ( int i = nFirstControl; i < nLastControl; ++i )
  518. {
  519. groups.AddToTail( controls[ i ]->GetName() );
  520. }
  521. }
  522. //-----------------------------------------------------------------------------
  523. // Creates the procedural presets
  524. //-----------------------------------------------------------------------------
  525. void CDmeCombinationOperatorPanel::ComputeProceduralPresets()
  526. {
  527. CDmeAnimationSet *pAnimationSet = m_AnimSet.Get();
  528. // Now create some presets
  529. CDmePresetGroup* pPresetGroup = pAnimationSet->FindOrAddPresetGroup( "procedural" );
  530. pPresetGroup->m_bIsReadOnly = true;
  531. // NOTE: Default needs no values set into it since it's the default
  532. CDmElement *pPreset = pPresetGroup->FindOrAddPreset( "Default" );
  533. pPreset = pPresetGroup->FindOrAddPreset( "Zero" );
  534. GenerateProceduralPresetValues( pPreset, pAnimationSet->GetControls(), true, 0.0f );
  535. pPreset = pPresetGroup->FindOrAddPreset( "Half" );
  536. GenerateProceduralPresetValues( pPreset, pAnimationSet->GetControls(), true, 0.5f );
  537. pPreset = pPresetGroup->FindOrAddPreset( "One" );
  538. GenerateProceduralPresetValues( pPreset, pAnimationSet->GetControls(), true, 1.0f );
  539. pPreset = pPresetGroup->FindOrAddPreset( "Random" );
  540. GenerateProceduralPresetValues( pPreset, pAnimationSet->GetControls(), false );
  541. pAnimationSet->EnsureProceduralPresets();
  542. }
  543. //-----------------------------------------------------------------------------
  544. // Sort control names to match the combination controls
  545. //-----------------------------------------------------------------------------
  546. void CDmeCombinationOperatorPanel::SortAnimationSetControls()
  547. {
  548. CDmaElementArray<> &controls = m_AnimSet->GetControls();
  549. int nControlCount = controls.Count();
  550. if ( nControlCount == 0 )
  551. return;
  552. int nCombinationControlCount = m_hCombinationOperator->GetControlCount();
  553. Assert( nControlCount == nCombinationControlCount );
  554. DmElementHandle_t *pElements = (DmElementHandle_t*)_alloca( nControlCount * sizeof(DmElementHandle_t) );
  555. for ( int i = 0; i < nCombinationControlCount; ++i )
  556. {
  557. const char *pControlName = m_hCombinationOperator->GetControlName( i );
  558. CDmElement *pControl = m_AnimSet->FindControl( pControlName );
  559. pElements[i] = pControl->GetHandle();
  560. }
  561. controls.SetMultiple( 0, nControlCount, pElements );
  562. #ifdef _DEBUG
  563. for ( int i = 0; i < nCombinationControlCount; ++i )
  564. {
  565. const char *pControlName = controls[i]->GetName();
  566. const char *pComboName = m_hCombinationOperator->GetControlName( i );
  567. Assert( !Q_stricmp( pControlName, pComboName ) );
  568. }
  569. #endif
  570. }
  571. //-----------------------------------------------------------------------------
  572. // Called when the animation set has to be made to match the combination operator
  573. //-----------------------------------------------------------------------------
  574. void CDmeCombinationOperatorPanel::RefreshAnimationSet()
  575. {
  576. if ( !m_AnimSet.Get() )
  577. return;
  578. CDisableUndoScopeGuard sg;
  579. // Remove all controls in the animation set and in presets that don't exist in the combination system
  580. RemoveUnusedAnimationSetControls();
  581. // Modify controls in the presets which have had stereo or multilevel settings changed
  582. ModifyExistingAnimationSetControls();
  583. // Add all controls not in the animation set but which do exist in the combination system
  584. AddNewAnimationSetControls();
  585. // Resets the procedural presets
  586. ComputeProceduralPresets();
  587. // Sort control names to match the combination controls
  588. SortAnimationSetControls();
  589. // Set that as the current set
  590. BaseClass::ChangeAnimationSet( m_AnimSet );
  591. }
  592. void CDmeCombinationOperatorPanel::RefreshCombinationOperator()
  593. {
  594. RefreshAnimationSet();
  595. }
  596. //-----------------------------------------------------------------------------
  597. // Simulate
  598. //-----------------------------------------------------------------------------
  599. void CDmeCombinationOperatorPanel::OnTick()
  600. {
  601. BaseClass::OnTick();
  602. if ( m_hCombinationOperator )
  603. {
  604. {
  605. CDisableUndoScopeGuard sg;
  606. int c = m_hCombinationOperator->GetControlCount();
  607. for ( int i = 0; i < c; ++i )
  608. {
  609. AttributeValue_t value;
  610. bool bVisible = GetAttributeSlider()->GetSliderValues( &value, i );
  611. if ( !bVisible )
  612. continue;
  613. if ( m_hCombinationOperator->IsStereoControl( i ) )
  614. {
  615. m_hCombinationOperator->SetControlValue( i, value.m_pValue[ANIM_CONTROL_VALUE], value.m_pValue[ANIM_CONTROL_BALANCE] );
  616. }
  617. else
  618. {
  619. m_hCombinationOperator->SetControlValue( i, value.m_pValue[ANIM_CONTROL_VALUE] );
  620. }
  621. if ( m_hCombinationOperator->IsMultiControl( i ) )
  622. {
  623. m_hCombinationOperator->SetMultiControlLevel( i, value.m_pValue[ANIM_CONTROL_MULTILEVEL] );
  624. }
  625. }
  626. }
  627. // FIXME: Shouldn't this happen at the application level?
  628. // run the machinery - apply, resolve, dependencies, operate, resolve
  629. CUtlVector< IDmeOperator* > operators;
  630. operators.AddToTail( m_hCombinationOperator );
  631. CDisableUndoScopeGuard guard;
  632. g_pDmElementFramework->SetOperators( operators );
  633. g_pDmElementFramework->Operate( true );
  634. }
  635. // allow elements and attributes to be edited again
  636. g_pDmElementFramework->BeginEdit();
  637. }
  638. //-----------------------------------------------------------------------------
  639. // Constructor, destructor
  640. //-----------------------------------------------------------------------------
  641. CDmeDagEditPanel::CDmeDagEditPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
  642. {
  643. m_pPropertiesSplitter = new vgui::Splitter( this, "PropertiesSplitter", vgui::SPLITTER_MODE_VERTICAL, 1 );
  644. vgui::Panel *pSplitterLeftSide = m_pPropertiesSplitter->GetChild( 0 );
  645. vgui::Panel *pSplitterRightSide = m_pPropertiesSplitter->GetChild( 1 );
  646. m_pDagRenderPanel = new CDmeDagRenderPanel( pSplitterRightSide, "DagRenderPanel" );
  647. m_pEditorSheet = new vgui::PropertySheet( pSplitterLeftSide, "EditorSheet" );
  648. m_pEditorSheet->AddActionSignalTarget( this );
  649. m_pAnimationPage = new vgui::PropertyPage( m_pEditorSheet, "AnimationPage" );
  650. m_pCombinationPage = new vgui::PropertyPage( m_pEditorSheet, "AnimationSetEditor" );
  651. m_pVertexAnimationPage = new vgui::PropertyPage( m_pEditorSheet, "VertexAnimationPage" );
  652. m_pCombinationPanel = new CDmeCombinationOperatorPanel( m_pCombinationPage, "AnimationSetEditorPanel" );
  653. m_pCombinationPanel->CreateToolsSubPanels();
  654. m_pAnimationListPanel = new CDmeAnimationListPanel( m_pAnimationPage, "AnimationListPanel" );
  655. m_pAnimationListPanel->AddActionSignalTarget( this );
  656. m_pVertexAnimationListPanel = new CDmeAnimationListPanel( m_pVertexAnimationPage, "VertexAnimationListPanel" );
  657. m_pVertexAnimationListPanel->AddActionSignalTarget( this );
  658. m_pCombinationPage->LoadControlSettingsAndUserConfig( "resource/dmedageditpanel_animationseteditorpage.res" );
  659. m_pAnimationPage->LoadControlSettingsAndUserConfig( "resource/dmedageditpanel_animationpage.res" );
  660. m_pVertexAnimationPage->LoadControlSettingsAndUserConfig( "resource/dmedageditpanel_vertexanimationpage.res" );
  661. // Load layout settings; has to happen before pinning occurs in code
  662. LoadControlSettingsAndUserConfig( "resource/dmedageditpanel.res" );
  663. // NOTE: Page adding happens *after* LoadControlSettingsAndUserConfig
  664. // because the layout of the sheet is correct at this point.
  665. m_pEditorSheet->AddPage( m_pAnimationPage, "Animation" );
  666. m_pEditorSheet->AddPage( m_pCombinationPage, "Combination" );
  667. m_pEditorSheet->AddPage( m_pVertexAnimationPage, "Vertex Animation" );
  668. }
  669. CDmeDagEditPanel::~CDmeDagEditPanel()
  670. {
  671. }
  672. //-----------------------------------------------------------------------------
  673. // Set the scene
  674. //-----------------------------------------------------------------------------
  675. void CDmeDagEditPanel::SetDmeElement( CDmeDag *pScene )
  676. {
  677. m_pDagRenderPanel->SetDmeElement( pScene );
  678. }
  679. //-----------------------------------------------------------------------------
  680. // Sets up the various panels in the dag editor
  681. //-----------------------------------------------------------------------------
  682. void CDmeDagEditPanel::SetMakefileRootElement( CDmElement *pRoot )
  683. {
  684. CDmeAnimationList *pAnimationList = pRoot->GetValueElement< CDmeAnimationList >( "animationList" );
  685. SetAnimationList( pAnimationList );
  686. CDmeAnimationList *pVertexAnimationList = pRoot->GetValueElement< CDmeAnimationList >( "vertexAnimationList" );
  687. SetVertexAnimationList( pVertexAnimationList );
  688. CDmeCombinationOperator *pComboOp = pRoot->GetValueElement< CDmeCombinationOperator >( "combinationOperator" );
  689. SetCombinationOperator( pComboOp );
  690. }
  691. //-----------------------------------------------------------------------------
  692. // Other methods which hook into DmePanel
  693. //-----------------------------------------------------------------------------
  694. void CDmeDagEditPanel::SetDmeElement( CDmeSourceSkin *pSkin )
  695. {
  696. m_pDagRenderPanel->SetDmeElement( pSkin );
  697. // First, try to grab the dependent makefile
  698. CDmeMakefile *pSourceMakefile = pSkin->GetDependentMakefile();
  699. if ( !pSourceMakefile )
  700. return;
  701. // Next, try to grab the output of that makefile
  702. CDmElement *pOutput = pSourceMakefile->GetOutputElement( true );
  703. if ( !pOutput )
  704. return;
  705. SetMakefileRootElement( pOutput );
  706. }
  707. void CDmeDagEditPanel::SetDmeElement( CDmeSourceAnimation *pAnimation )
  708. {
  709. m_pDagRenderPanel->SetDmeElement( pAnimation );
  710. // First, try to grab the dependent makefile
  711. CDmeMakefile *pSourceMakefile = pAnimation->GetDependentMakefile();
  712. if ( !pSourceMakefile )
  713. return;
  714. // Next, try to grab the output of that makefile
  715. CDmElement *pOutput = pSourceMakefile->GetOutputElement( true );
  716. if ( !pOutput )
  717. return;
  718. SetMakefileRootElement( pOutput );
  719. // if ( pAnimationList->FindAnimation( pAnimation->m_SourceAnimationName ) < 0 )
  720. // return;
  721. }
  722. void CDmeDagEditPanel::SetDmeElement( CDmeDCCMakefile *pDCCMakefile )
  723. {
  724. m_pDagRenderPanel->SetDmeElement( pDCCMakefile );
  725. // First, try to grab the dependent makefile
  726. CDmElement *pOutput = pDCCMakefile->GetOutputElement( true );
  727. if ( !pOutput )
  728. return;
  729. SetMakefileRootElement( pOutput );
  730. }
  731. CDmeDag *CDmeDagEditPanel::GetDmeElement()
  732. {
  733. return m_pDagRenderPanel->GetDmeElement();
  734. }
  735. //-----------------------------------------------------------------------------
  736. // paint it!
  737. //-----------------------------------------------------------------------------
  738. void CDmeDagEditPanel::Paint()
  739. {
  740. BaseClass::Paint();
  741. }
  742. //-----------------------------------------------------------------------------
  743. // Sets animation
  744. //-----------------------------------------------------------------------------
  745. void CDmeDagEditPanel::SetAnimationList( CDmeAnimationList *pAnimationList )
  746. {
  747. m_pDagRenderPanel->SetAnimationList( pAnimationList );
  748. m_pDagRenderPanel->SelectAnimation( "" );
  749. m_pAnimationListPanel->SetAnimationList( pAnimationList );
  750. }
  751. void CDmeDagEditPanel::SetVertexAnimationList( CDmeAnimationList *pAnimationList )
  752. {
  753. m_pDagRenderPanel->SetVertexAnimationList( pAnimationList );
  754. m_pDagRenderPanel->SelectVertexAnimation( "" );
  755. m_pVertexAnimationListPanel->SetAnimationList( pAnimationList );
  756. }
  757. void CDmeDagEditPanel::SetCombinationOperator( CDmeCombinationOperator *pComboOp )
  758. {
  759. m_pCombinationPanel->SetCombinationOperator( pComboOp );
  760. }
  761. void CDmeDagEditPanel::RefreshCombinationOperator()
  762. {
  763. m_pCombinationPanel->RefreshCombinationOperator();
  764. }
  765. //-----------------------------------------------------------------------------
  766. // Called when the page changes
  767. //-----------------------------------------------------------------------------
  768. void CDmeDagEditPanel::OnPageChanged( )
  769. {
  770. if ( m_pEditorSheet->GetActivePage() == m_pCombinationPage )
  771. {
  772. m_pDagRenderPanel->SelectAnimation( "" );
  773. m_pDagRenderPanel->SelectVertexAnimation( "" );
  774. return;
  775. }
  776. if ( m_pEditorSheet->GetActivePage() == m_pAnimationPage )
  777. {
  778. m_pDagRenderPanel->SelectAnimation( m_pAnimationListPanel->GetSelectedAnimation() );
  779. m_pDagRenderPanel->SelectVertexAnimation( "" );
  780. return;
  781. }
  782. if ( m_pEditorSheet->GetActivePage() == m_pVertexAnimationPage )
  783. {
  784. m_pDagRenderPanel->SelectAnimation( "" );
  785. m_pDagRenderPanel->SelectVertexAnimation( m_pVertexAnimationListPanel->GetSelectedAnimation() );
  786. return;
  787. }
  788. }
  789. //-----------------------------------------------------------------------------
  790. // Called when new animations are selected
  791. //-----------------------------------------------------------------------------
  792. void CDmeDagEditPanel::OnAnimationSelected( KeyValues *pKeyValues )
  793. {
  794. vgui::Panel *pPanel = (vgui::Panel *)pKeyValues->GetPtr( "panel", NULL );
  795. const char *pAnimationName = pKeyValues->GetString( "animationName", "" );
  796. if ( pPanel == m_pAnimationListPanel )
  797. {
  798. m_pDagRenderPanel->SelectAnimation( pAnimationName );
  799. return;
  800. }
  801. if ( pPanel == m_pVertexAnimationListPanel )
  802. {
  803. m_pDagRenderPanel->SelectVertexAnimation( pAnimationName );
  804. return;
  805. }
  806. }
  807. void CDmeDagEditPanel::OnAnimationDeselected( KeyValues *pKeyValues )
  808. {
  809. vgui::Panel *pPanel = (vgui::Panel *)pKeyValues->GetPtr( "panel", NULL );
  810. if ( pPanel == m_pAnimationListPanel )
  811. {
  812. m_pDagRenderPanel->SelectAnimation( "" );
  813. return;
  814. }
  815. if ( pPanel == m_pVertexAnimationListPanel )
  816. {
  817. m_pDagRenderPanel->SelectVertexAnimation( "" );
  818. return;
  819. }
  820. }