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.

1791 lines
53 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // CSceneViewerPanel Definition
  4. //
  5. //=============================================================================
  6. // Standard includes
  7. #include <direct.h>
  8. // Valve includes
  9. #include "tier1/utldict.h"
  10. #include "tier1/KeyValues.h"
  11. #include "tier3/tier3.h"
  12. #include "vstdlib/random.h"
  13. #include "vgui/IVGui.h"
  14. #include "vgui/ISurface.h"
  15. #include "vgui/ISystem.h"
  16. #include "vgui_controls/MenuButton.h"
  17. #include "vgui_controls/FileOpenDialog.h"
  18. #include "vgui_controls/MessageBox.h"
  19. #include "movieobjects/dmechannel.h"
  20. #include "movieobjects/dmeclip.h"
  21. #include "movieobjects/dmefaceset.h"
  22. #include "movieobjects/dmematerial.h"
  23. #include "movieobjects/dmobjserializer.h"
  24. #include "dme_controls/dmedagrenderpanel.h"
  25. #include "vgui/keycode.h"
  26. #include "filesystem.h"
  27. // Local includes
  28. #include "SceneViewerPanel.h"
  29. #define DEFAULT_FILE_FORMAT "model"
  30. //-----------------------------------------------------------------------------
  31. // Creates the scene viewer panel
  32. //-----------------------------------------------------------------------------
  33. vgui::Panel *CreateSceneViewerPanel()
  34. {
  35. // add our main window
  36. vgui::Panel *pSceneViewer = new CSceneViewerPanel;
  37. pSceneViewer->SetParent( g_pVGuiSurface->GetEmbeddedPanel() );
  38. return pSceneViewer;
  39. }
  40. //-----------------------------------------------------------------------------
  41. //
  42. //-----------------------------------------------------------------------------
  43. class CSceneViewerMenuButton : public vgui::MenuButton
  44. {
  45. DECLARE_CLASS_SIMPLE( CSceneViewerMenuButton, vgui::MenuButton );
  46. public:
  47. CSceneViewerMenuButton( CSceneViewerPanel *parent, const char *panelName, const char *text );
  48. virtual void OnShowMenu(vgui::Menu *menu) = 0;
  49. // Add a simple text item to the menu
  50. virtual int AddMenuItem( char const *itemName, const char *itemText, KeyValues *message, Panel *target, const KeyValues *userData = NULL );
  51. virtual int AddCheckableMenuItem( char const *itemName, const char *itemText, KeyValues *message, Panel *target, const KeyValues *userData = NULL );
  52. void Reset();
  53. protected:
  54. vgui::Menu *m_pMenu;
  55. vgui::Panel *m_pActionTarget;
  56. CSceneViewerPanel *m_pUI;
  57. CUtlDict< int, unsigned short > m_Items;
  58. };
  59. //-----------------------------------------------------------------------------
  60. //
  61. //-----------------------------------------------------------------------------
  62. CSceneViewerMenuButton::CSceneViewerMenuButton(
  63. CSceneViewerPanel *parent,
  64. const char *panelName,
  65. const char *text )
  66. : BaseClass( (vgui::Panel * )parent, panelName, text )
  67. , m_pUI( parent )
  68. , m_pActionTarget( (vgui::Panel *)parent )
  69. {
  70. m_pMenu = new vgui::Menu( this, "Menu" );
  71. }
  72. //-----------------------------------------------------------------------------
  73. //
  74. //-----------------------------------------------------------------------------
  75. void CSceneViewerMenuButton::Reset()
  76. {
  77. m_Items.RemoveAll();
  78. m_pMenu->DeleteAllItems();
  79. }
  80. //-----------------------------------------------------------------------------
  81. //
  82. //-----------------------------------------------------------------------------
  83. int CSceneViewerMenuButton::AddMenuItem( char const *itemName, const char *itemText, KeyValues *message, Panel *target, const KeyValues *userData /*= NULL*/ )
  84. {
  85. int id = m_pMenu->AddMenuItem(itemText, message, target, userData);
  86. m_Items.Insert( itemName, id );
  87. return id;
  88. }
  89. //-----------------------------------------------------------------------------
  90. //
  91. //-----------------------------------------------------------------------------
  92. int CSceneViewerMenuButton::AddCheckableMenuItem( char const *itemName, const char *itemText, KeyValues *message, Panel *target, const KeyValues *userData /*= NULL*/ )
  93. {
  94. int id = m_pMenu->AddCheckableMenuItem(itemText, message, target, userData);
  95. m_Items.Insert( itemName, id );
  96. return id;
  97. }
  98. //-----------------------------------------------------------------------------
  99. //
  100. //-----------------------------------------------------------------------------
  101. class CSceneViewerEditMenuButton : public CSceneViewerMenuButton
  102. {
  103. DECLARE_CLASS_SIMPLE( CSceneViewerEditMenuButton, CSceneViewerMenuButton );
  104. public:
  105. CSceneViewerEditMenuButton( CSceneViewerPanel *parent, const char *panelName, const char *text );
  106. virtual void OnShowMenu(vgui::Menu *menu);
  107. private:
  108. vgui::Menu *m_pRecentFiles;
  109. int m_nRecentFiles;
  110. };
  111. //-----------------------------------------------------------------------------
  112. //
  113. //-----------------------------------------------------------------------------
  114. class CSceneViewerMenuBar : public vgui::MenuBar
  115. {
  116. DECLARE_CLASS_SIMPLE( CSceneViewerMenuBar, vgui::MenuBar );
  117. public:
  118. CSceneViewerMenuBar(Panel *parent, const char *panelName);
  119. virtual void PerformLayout();
  120. void SetFileName( char const *filename );
  121. private:
  122. vgui::Label *m_pFileName;
  123. };
  124. //-----------------------------------------------------------------------------
  125. //
  126. //-----------------------------------------------------------------------------
  127. CSceneViewerMenuBar::CSceneViewerMenuBar(Panel *parent, const char *panelName) :
  128. BaseClass( parent, panelName )
  129. {
  130. m_pFileName = new vgui::Label( this, "IFMFileName", "" );
  131. }
  132. //-----------------------------------------------------------------------------
  133. //
  134. //-----------------------------------------------------------------------------
  135. void CSceneViewerMenuBar::PerformLayout()
  136. {
  137. BaseClass::PerformLayout();
  138. int w, h;
  139. GetSize( w, h );
  140. int barx, bary;
  141. GetContentSize( barx, bary );
  142. int faredge = w - 2;
  143. int nearedge = barx + 2;
  144. int mid = ( nearedge + faredge ) * 0.5f;
  145. int cw, ch;
  146. m_pFileName->GetContentSize( cw, ch );
  147. m_pFileName->SetBounds( mid - cw * 0.5f, 0, cw, h );
  148. }
  149. //-----------------------------------------------------------------------------
  150. //
  151. //-----------------------------------------------------------------------------
  152. void CSceneViewerMenuBar::SetFileName( char const *name )
  153. {
  154. m_pFileName->SetText( name );
  155. InvalidateLayout();
  156. }
  157. //-----------------------------------------------------------------------------
  158. // Constructor, destructor
  159. //-----------------------------------------------------------------------------
  160. CSceneViewerPanel::CSceneViewerPanel()
  161. : vgui::Panel( NULL, "SceneViewer" )
  162. {
  163. m_pMenuBar = new CSceneViewerMenuBar( this, "Main Menu Bar" );
  164. m_pMenuBar->SetSize( 10, 28 );
  165. // Next create a menu
  166. vgui::Menu *pMenu = new vgui::Menu(NULL, "File Menu");
  167. pMenu->AddMenuItem( "&New", new KeyValues( "New" ), this );
  168. pMenu->AddMenuItem( "&Open", new KeyValues( "Open" ), this );
  169. pMenu->AddMenuItem( "&Save", new KeyValues( "Save" ), this );
  170. pMenu->AddMenuItem( "Save &As", new KeyValues( "SaveAs" ), this );
  171. pMenu->AddMenuItem( "Save &Current As", new KeyValues( "SaveCurrentAs" ), this );
  172. pMenu->AddMenuItem( "E&xit", new KeyValues( "Exit" ), this );
  173. m_pMenuBar->AddMenu( "&File", pMenu );
  174. CSceneViewerEditMenuButton *editMenu = new CSceneViewerEditMenuButton( this, "Edit Menu", "&Edit" );
  175. m_pMenuBar->AddButton( editMenu );
  176. vgui::Menu *pWindowMenu = new vgui::Menu( NULL, "Windows Menu" );
  177. pWindowMenu->AddMenuItem( "3D &View", new KeyValues( "Show3DView" ), this );
  178. pWindowMenu->AddMenuItem( "&Combo Editor", new KeyValues( "ShowComboEditor" ), this );
  179. pWindowMenu->AddMenuItem( "&Asset Builder", new KeyValues( "ShowAssetBuilder" ), this );
  180. pWindowMenu->AddMenuItem( "&Nerd Editor", new KeyValues( "ShowNerdEditor" ), this );
  181. pWindowMenu->AddMenuItem( "C&onsole", new KeyValues( "ShowConsole" ), this );
  182. m_pMenuBar->AddMenu( "&Windows", pWindowMenu );
  183. m_pClientArea = new vgui::Panel( this, "ClientArea" ) ;
  184. m_pClipViewPanel = new CClipViewPanel( m_pClientArea, "Clip Viewer" );
  185. m_pClipViewPanel->SetBounds( 10, 40, 500, 500 );
  186. m_pCombinationEditor = new CDmeCombinationSystemEditorFrame( m_pClientArea, "Combination Control Builder" );
  187. m_pCombinationEditor->SetBounds( 100, 100, 512, 512 );
  188. m_pCombinationEditor->SetVisible( false );
  189. m_pCombinationEditor->SetDeleteSelfOnClose( false );
  190. m_pCombinationEditor->AddActionSignalTarget( this );
  191. m_pAssetBuilder = new CAssetBuilderFrame( m_pClientArea, "Asset Builder" );
  192. m_pAssetBuilder->SetParent( g_pVGuiSurface->GetEmbeddedPanel() );
  193. m_pAssetBuilder->SetVisible( false );
  194. m_pAssetBuilder->SetBounds( 50, 50, 512, 512 );
  195. m_pAssetBuilder->SetDeleteSelfOnClose( false );
  196. m_pNerdEditor = new CElementPropertiesTree( m_pClientArea, this, NULL );
  197. m_pNerdEditor->SetParent( g_pVGuiSurface->GetEmbeddedPanel() );
  198. m_pNerdEditor->SetVisible( false );
  199. m_pNerdEditor->SetBounds( 50, 50, 512, 512 );
  200. m_pNerdEditor->SetDeleteSelfOnClose( false );
  201. m_pFileOpenStateMachine = new vgui::FileOpenStateMachine( this, this );
  202. m_pFileOpenStateMachine->AddActionSignalTarget( this );
  203. m_pConsole = new vgui::CConsoleDialog( this, "ConsoleDialog", false );
  204. m_pConsole->AddActionSignalTarget( this );
  205. m_bConsolePositioned = false;
  206. m_pRoot = NULL;
  207. }
  208. //-----------------------------------------------------------------------------
  209. //
  210. //-----------------------------------------------------------------------------
  211. CSceneViewerEditMenuButton::CSceneViewerEditMenuButton( CSceneViewerPanel *parent, const char *panelName, const char *text )
  212. : BaseClass( parent, panelName, text )
  213. {
  214. AddMenuItem( "undo", "&Undo", new KeyValues ( "Command", "command", "OnUndo"), parent);
  215. AddMenuItem( "redo", "&Redo", new KeyValues ("Command", "command", "OnRedo"), parent);
  216. AddMenuItem( "describe", "Describe Undo Stack", new KeyValues( "Command", "command", "OnDescribeUndoStack" ), parent );
  217. AddMenuItem( "properties", "&Properties...", new KeyValues( "Command", "command", "OnEdit" ), parent );
  218. SetMenu(m_pMenu);
  219. }
  220. //-----------------------------------------------------------------------------
  221. //
  222. //-----------------------------------------------------------------------------
  223. void CSceneViewerEditMenuButton::OnShowMenu(vgui::Menu *menu)
  224. {
  225. // Update the menu
  226. // new and exit are always active
  227. // Open is avail if there's no open document
  228. // save and saveas are active it there's a document and it's dirty
  229. // close is active if there's a document
  230. int id;
  231. char sz[ 512 ];
  232. id = m_Items.Find( "undo" );
  233. if ( g_pDataModel->CanUndo() )
  234. {
  235. m_pMenu->SetItemEnabled( id, true );
  236. Q_snprintf( sz, sizeof( sz ), "Undo '%s'", g_pDataModel->GetUndoDesc() );
  237. m_pMenu->UpdateMenuItem( id, sz, new KeyValues( "Command", "command", "OnUndo" ) );
  238. }
  239. else
  240. {
  241. m_pMenu->SetItemEnabled( id, false );
  242. m_pMenu->UpdateMenuItem( id, "Undo...", new KeyValues( "Command", "command", "OnUndo" ) );
  243. }
  244. id = m_Items.Find( "redo" );
  245. if ( g_pDataModel->CanRedo() )
  246. {
  247. m_pMenu->SetItemEnabled( id, true );
  248. Q_snprintf( sz, sizeof( sz ), "Redo '%s'", g_pDataModel->GetRedoDesc() );
  249. m_pMenu->UpdateMenuItem( id, sz, new KeyValues( "Command", "command", "OnRedo" ) );
  250. }
  251. else
  252. {
  253. m_pMenu->SetItemEnabled( id, false );
  254. m_pMenu->UpdateMenuItem( id, "Redo...", new KeyValues( "Command", "command", "OnRedo" ) );
  255. }
  256. id = m_Items.Find( "describe" );
  257. if ( g_pDataModel->CanUndo() )
  258. {
  259. m_pMenu->SetItemEnabled( id, true );
  260. }
  261. else
  262. {
  263. m_pMenu->SetItemEnabled( id, false );
  264. }
  265. id = m_Items.Find( "properties" );
  266. m_pMenu->SetItemEnabled( id, m_pUI->GetScene() ? true : false );
  267. }
  268. //-----------------------------------------------------------------------------
  269. //
  270. //-----------------------------------------------------------------------------
  271. CSceneViewerPanel::~CSceneViewerPanel()
  272. {
  273. if ( m_pRoot )
  274. {
  275. g_pDataModel->UnloadFile( m_pRoot->GetFileId() );
  276. }
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Console support
  280. //-----------------------------------------------------------------------------
  281. void CSceneViewerPanel::OnCommandSubmitted( const char *command )
  282. {
  283. CCommand args;
  284. args.Tokenize( command );
  285. ConCommandBase *pCommandBase = g_pCVar->FindCommandBase( args[0] );
  286. if ( !pCommandBase )
  287. {
  288. ConWarning( "Unknown command or convar '%s'!\n", args[0] );
  289. return;
  290. }
  291. if ( pCommandBase->IsCommand() )
  292. {
  293. ConCommand *pCommand = static_cast<ConCommand*>( pCommandBase );
  294. pCommand->Dispatch( args );
  295. return;
  296. }
  297. ConVar *pConVar = static_cast< ConVar* >( pCommandBase );
  298. if ( args.ArgC() == 1)
  299. {
  300. if ( pConVar->IsFlagSet( FCVAR_NEVER_AS_STRING ) )
  301. {
  302. ConMsg( "%s = %f\n", args[0], pConVar->GetFloat() );
  303. }
  304. else
  305. {
  306. ConMsg( "%s = %s\n", args[0], pConVar->GetString() );
  307. }
  308. return;
  309. }
  310. if ( pConVar->IsFlagSet( FCVAR_NEVER_AS_STRING ) )
  311. {
  312. pConVar->SetValue( (float)atof( args[1] ) );
  313. }
  314. else
  315. {
  316. pConVar->SetValue( args.ArgS() );
  317. }
  318. }
  319. //-----------------------------------------------------------------------------
  320. // The clip viewer has key focus
  321. //-----------------------------------------------------------------------------
  322. vgui::VPANEL CSceneViewerPanel::GetCurrentKeyFocus()
  323. {
  324. return m_pClipViewPanel->GetVPanel();
  325. }
  326. //-----------------------------------------------------------------------------
  327. //
  328. //-----------------------------------------------------------------------------
  329. vgui::VPANEL CSceneViewerPanel::GetCurrentMouseFocus()
  330. {
  331. return m_pClipViewPanel->GetVPanel();
  332. }
  333. //-----------------------------------------------------------------------------
  334. //
  335. //-----------------------------------------------------------------------------
  336. void CSceneViewerPanel::OnKeyCodePressed( vgui::KeyCode code )
  337. {
  338. BaseClass::OnKeyCodePressed( code );
  339. if ( code == KEY_BACKQUOTE )
  340. {
  341. if ( !m_pConsole->IsVisible() )
  342. {
  343. m_pConsole->Activate();
  344. }
  345. else
  346. {
  347. m_pConsole->Hide();
  348. }
  349. }
  350. else if ( code == KEY_F5 )
  351. {
  352. Reload();
  353. }
  354. }
  355. //-----------------------------------------------------------------------------
  356. // VGUI commands
  357. //-----------------------------------------------------------------------------
  358. void CSceneViewerPanel::OnCommand( char const *cmd )
  359. {
  360. if ( !Q_stricmp( cmd, "OnEdit" ) )
  361. {
  362. OnEdit();
  363. }
  364. else if ( !Q_stricmp( cmd, "OnUndo" ) )
  365. {
  366. OnUndo();
  367. }
  368. else if ( !Q_stricmp( cmd, "OnRedo" ) )
  369. {
  370. OnRedo();
  371. }
  372. else
  373. {
  374. BaseClass::OnCommand( cmd );
  375. }
  376. }
  377. //-----------------------------------------------------------------------------
  378. // Callback From m_pFileOpenStateMachine
  379. //-----------------------------------------------------------------------------
  380. void CSceneViewerPanel::SetupFileOpenDialog(
  381. vgui::FileOpenDialog *pDialog,
  382. bool bOpenFile, const char *pFileFormat,
  383. KeyValues *pContextKeyValues )
  384. {
  385. if ( m_fileDirectory.IsEmpty() )
  386. {
  387. char pStartingDir[ MAX_PATH ];
  388. if ( !vgui::system()->GetRegistryString(
  389. "HKEY_CURRENT_USER\\Software\\Valve\\sceneviewer\\dmxfiles\\opendir", pStartingDir, sizeof( pStartingDir ) ) )
  390. {
  391. // Compute starting directory
  392. _getcwd( pStartingDir, sizeof( pStartingDir ) );
  393. }
  394. m_fileDirectory = pStartingDir;
  395. }
  396. pDialog->SetStartDirectoryContext( "sceneviewer_browser", m_fileDirectory.Get() );
  397. if ( !bOpenFile && !Q_strcmp( pContextKeyValues->GetName(), "SaveCurrentAs" ) )
  398. {
  399. pDialog->AddFilter( "*.obj", "OBJ File (*.obj)", false, "obj" );
  400. pDialog->AddFilter( "*.*", "All Files (*.*)", !bOpenFile, "obj" );
  401. pDialog->SetTitle( "Save Current State As OBJ File", true );
  402. }
  403. else
  404. {
  405. pDialog->AddFilter( "*.obj", "OBJ File (*.obj)", false, "obj" );
  406. pDialog->AddFilter( "*.dmx", "DMX File (*.dmx)", bOpenFile, DEFAULT_FILE_FORMAT );
  407. pDialog->AddFilter( "*.*", "All Files (*.*)", !bOpenFile, DEFAULT_FILE_FORMAT );
  408. if ( bOpenFile )
  409. {
  410. pDialog->SetTitle( "Open DMX/OBJ File", true );
  411. }
  412. else
  413. {
  414. pDialog->SetTitle( "Save DMX/OBJ File As", true );
  415. }
  416. }
  417. }
  418. //-----------------------------------------------------------------------------
  419. // Callback From m_pFileOpenStateMachine
  420. //-----------------------------------------------------------------------------
  421. bool CSceneViewerPanel::OnReadFileFromDisk(
  422. const char *pFileName,
  423. const char *pFileFormat,
  424. KeyValues *pContextKeyValues )
  425. {
  426. // Regardless if the file sucessfully loaded or not, save the directory portion to use next time
  427. {
  428. char buf[ MAX_PATH ];
  429. Q_strncpy( buf, pFileName, sizeof( buf ) );
  430. Q_FixSlashes( buf );
  431. Q_StripFilename( buf );
  432. m_fileDirectory = buf;
  433. _fullpath( buf, m_fileDirectory, sizeof( buf ) );
  434. m_fileDirectory = buf;
  435. vgui::system()->SetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\sceneviewer\\dmxfiles\\opendir", m_fileDirectory.Get() );
  436. }
  437. return Load( pFileName );
  438. }
  439. //-----------------------------------------------------------------------------
  440. //
  441. //-----------------------------------------------------------------------------
  442. bool CSceneViewerPanel::SaveCurrentAs(
  443. const char *pFilename )
  444. {
  445. if ( !m_pRoot )
  446. return false;
  447. // Find each mesh under pRoot
  448. CDmeDag *pModel = m_pRoot->GetValueElement< CDmeDag >( "model" );
  449. if ( !pModel )
  450. return false;
  451. CDmeDag *pDag;
  452. CDmeMesh *pMesh;
  453. // Loop through each mesh and set the bind state to something funny
  454. CUtlStack< CDmeDag * > traverseStack;
  455. traverseStack.Push( pModel );
  456. while ( traverseStack.Count() )
  457. {
  458. traverseStack.Pop( pDag );
  459. if ( !pDag )
  460. continue;
  461. // Push all children onto stack in reverse order
  462. for ( int nChildIndex = pDag->GetChildCount() - 1; nChildIndex >= 0; --nChildIndex )
  463. {
  464. traverseStack.Push( pDag->GetChild( nChildIndex ) );
  465. }
  466. // See if there's a mesh associated with this dag
  467. pMesh = CastElement< CDmeMesh >( pDag->GetShape() );
  468. if ( !pMesh )
  469. continue;
  470. // Create a new base state
  471. CDmeVertexData *pBind = pMesh->FindBaseState( "bind" );
  472. if ( !pBind )
  473. continue;
  474. CDmeVertexData *pNewBind = pMesh->FindOrCreateBaseState( "__sceneviewer_newBind" );
  475. pBind->CopyTo( pNewBind );
  476. pBind->SetName( "__sceneviewer_oldBind" );
  477. pNewBind->SetName( "bind" );
  478. pMesh->SetBaseStateToDeltas( pNewBind );
  479. }
  480. CDmObjSerializer().WriteOBJ( pFilename, m_pRoot, false );
  481. traverseStack.Push( pModel );
  482. while ( traverseStack.Count() )
  483. {
  484. traverseStack.Pop( pDag );
  485. if ( !pDag )
  486. continue;
  487. // Push all children onto stack in reverse order
  488. for ( int nChildIndex = pDag->GetChildCount() - 1; nChildIndex >= 0; --nChildIndex )
  489. {
  490. traverseStack.Push( pDag->GetChild( nChildIndex ) );
  491. }
  492. // See if there's a mesh associated with this dag
  493. pMesh = CastElement< CDmeMesh >( pDag->GetShape() );
  494. if ( !pMesh )
  495. continue;
  496. CDmeVertexData *pOldBind = pMesh->FindBaseState( "__sceneviewer_oldBind" );
  497. CDmeVertexData *pNewBind = pMesh->FindBaseState( "bind" );
  498. if ( !pOldBind || !pNewBind )
  499. continue;
  500. pMesh->DeleteBaseState( "bind" );
  501. pOldBind->SetName( "bind" );
  502. g_pDataModel->DestroyElement( pNewBind->GetHandle() );
  503. }
  504. return true;
  505. }
  506. //-----------------------------------------------------------------------------
  507. // Callback From m_pFileOpenStateMachine
  508. //-----------------------------------------------------------------------------
  509. bool CSceneViewerPanel::OnWriteFileToDisk(
  510. const char *pFilename,
  511. const char *pPassedFileFormat,
  512. KeyValues *pContextKeyValues )
  513. {
  514. if ( !m_pRoot )
  515. return false;
  516. if ( !Q_strcmp( pContextKeyValues->GetName(), "SaveCurrentAs" ) )
  517. return SaveCurrentAs( pFilename );
  518. if ( !Q_stricmp( pPassedFileFormat, "obj" ) )
  519. return CDmObjSerializer().WriteOBJ( pFilename, m_pRoot, true );
  520. const int fLen( Q_strlen( pFilename ) );
  521. if ( fLen > 4 && !Q_stricmp( pFilename + fLen - 4, ".obj" ) )
  522. return CDmObjSerializer().WriteOBJ( pFilename, m_pRoot, true );
  523. const char *pEncoding = g_pDataModel->GetDefaultEncoding( pPassedFileFormat );
  524. if ( pEncoding == NULL || g_pDataModel->FindSerializer( pEncoding ) == NULL )
  525. {
  526. // I'd like a better way to figure out what the 'default' format should be
  527. pEncoding = "binary";
  528. }
  529. bool retVal = g_pDataModel->SaveToFile( pFilename, NULL, pEncoding, pPassedFileFormat, m_pRoot );
  530. if ( !retVal || !g_pFullFileSystem->FileExists( pFilename ) )
  531. {
  532. char pBuf[1024];
  533. Q_snprintf( pBuf, sizeof(pBuf), "DMX Write Failed!\n\nCouldn't Save \"%s\"\n\nAs DMX Format \"%s\"", pFilename, pPassedFileFormat );
  534. vgui::MessageBox *pMessageBox = new vgui::MessageBox( "DMX Write Failed", pBuf, GetParent() );
  535. pMessageBox->AddActionSignalTarget( this );
  536. pMessageBox->SetOKButtonVisible( true );
  537. pMessageBox->SetOKButtonText( "Ok" );
  538. pMessageBox->DoModal();
  539. retVal = false;
  540. }
  541. return retVal;
  542. }
  543. //-----------------------------------------------------------------------------
  544. // Removes all references to Dme stuff from the vgui elements
  545. //-----------------------------------------------------------------------------
  546. void CSceneViewerPanel::Clear()
  547. {
  548. if ( m_pClipViewPanel )
  549. {
  550. m_pClipViewPanel->SetScene( NULL );
  551. m_pClipViewPanel->SetAnimationList( NULL );
  552. m_pClipViewPanel->SetVertexAnimationList( NULL );
  553. m_pClipViewPanel->SetCombinationOperator( NULL );
  554. }
  555. if ( m_pCombinationEditor )
  556. {
  557. m_pCombinationEditor->SetCombinationOperator( NULL );
  558. }
  559. if ( m_pNerdEditor )
  560. {
  561. m_pNerdEditor->SetObject( NULL );
  562. }
  563. // Unload Any Old Model
  564. if ( m_pRoot )
  565. {
  566. CDisableUndoScopeGuard guard;
  567. g_pDataModel->RemoveFileId( m_pRoot->GetFileId() );
  568. }
  569. m_pRoot = NULL;
  570. m_filename = "";
  571. }
  572. //-----------------------------------------------------------------------------
  573. // Import combination rules from this operator
  574. //-----------------------------------------------------------------------------
  575. void GetComboVals( CDmeCombinationOperator *pComboOp, CUtlStringMap< Vector > &controlValues )
  576. {
  577. controlValues.Clear();
  578. const int nControls = pComboOp->GetControlCount();
  579. for ( int i = 0; i < nControls; ++i )
  580. {
  581. Vector &cVal = controlValues[ pComboOp->GetControlName( i ) ];
  582. const Vector2D &sVal = pComboOp->GetStereoControlValue( i, COMBO_CONTROL_NORMAL );
  583. cVal.x = sVal.x;
  584. cVal.y = sVal.y;
  585. cVal.z = pComboOp->GetMultiControlLevel( i, COMBO_CONTROL_NORMAL );
  586. }
  587. }
  588. //-----------------------------------------------------------------------------
  589. //
  590. //-----------------------------------------------------------------------------
  591. void SetComboVals( CDmeCombinationOperator *pComboOp, CUtlStringMap< Vector > &controlValues )
  592. {
  593. const int nControls = pComboOp->GetControlCount();
  594. for ( int i = 0; i < nControls; ++i )
  595. {
  596. if ( !controlValues.Defined( pComboOp->GetControlName( i ) ) )
  597. continue;
  598. const Vector &cVal = controlValues[ pComboOp->GetControlName( i ) ];
  599. pComboOp->SetControlValue( i, cVal.AsVector2D(), COMBO_CONTROL_NORMAL );
  600. pComboOp->SetMultiControlLevel( i, cVal.z, COMBO_CONTROL_NORMAL );
  601. }
  602. }
  603. //-----------------------------------------------------------------------------
  604. //
  605. //-----------------------------------------------------------------------------
  606. void CSceneViewerPanel::SendFrameToDagRenderPanel( vgui::Panel *pPanel )
  607. {
  608. const int nChildren = pPanel->GetChildCount();
  609. for ( int i = 0; i < nChildren; ++i )
  610. {
  611. vgui::Panel *pChild = pPanel->GetChild( i );
  612. CDmeDagRenderPanel *pDagRenderPanel = dynamic_cast< CDmeDagRenderPanel * >( pChild );
  613. if ( pDagRenderPanel )
  614. {
  615. KeyValues *pKV( new KeyValues( "Frame" ) );
  616. pPanel->PostMessage( pDagRenderPanel, pKV );
  617. return;
  618. }
  619. SendFrameToDagRenderPanel( pChild );
  620. }
  621. }
  622. //-----------------------------------------------------------------------------
  623. // Load a Dme file from disk ( or OBJ )
  624. //-----------------------------------------------------------------------------
  625. bool CSceneViewerPanel::Load( const char *pFilename, CUtlStringMap< Vector > *pOldComboVals )
  626. {
  627. CDisableUndoScopeGuard guard;
  628. // Remove any old data
  629. Clear();
  630. CDmElement *pRoot( NULL );
  631. const int fLen( Q_strlen( pFilename ) );
  632. if ( fLen > 4 && !Q_stricmp( pFilename + fLen - 4, ".obj" ) )
  633. {
  634. pRoot = CDmObjSerializer().ReadOBJ( pFilename );
  635. }
  636. else {
  637. // Load the Dme file from disk
  638. g_pDataModel->RestoreFromFile( pFilename, NULL, NULL, &pRoot );
  639. }
  640. if ( !pRoot )
  641. return false;
  642. if ( pOldComboVals )
  643. {
  644. CDmeCombinationOperator *pComboOp = pRoot->GetValueElement< CDmeCombinationOperator >( "combinationOperator" );
  645. if ( pComboOp )
  646. {
  647. SetComboVals( pComboOp, *pOldComboVals );
  648. }
  649. }
  650. m_filename = pFilename;
  651. m_pRoot = pRoot;
  652. SetScene();
  653. return true;
  654. }
  655. //-----------------------------------------------------------------------------
  656. // Reloads a DMX scene from disk, hopefully leaving the GUI intact!
  657. //-----------------------------------------------------------------------------
  658. bool CSceneViewerPanel::Reload()
  659. {
  660. if ( m_filename.IsEmpty() )
  661. {
  662. Error( "ERROR: Reload() Failed - No File loaded\n" );
  663. return false;
  664. }
  665. Msg( "Reload( \"%s\" )\n", m_filename.Get() );
  666. CDmeCombinationOperator *pComboOp = m_pRoot->GetValueElement< CDmeCombinationOperator >( "combinationOperator" );
  667. CUtlStringMap< Vector > oldComboVals;
  668. if ( pComboOp )
  669. {
  670. GetComboVals( pComboOp, oldComboVals );
  671. }
  672. CUtlString tmpFilename( m_filename );
  673. const bool retVal = Load( tmpFilename, oldComboVals.GetNumStrings() > 0 ? &oldComboVals : NULL );
  674. return retVal;
  675. }
  676. //-----------------------------------------------------------------------------
  677. // Sets all of the various editors to reference the right stuff
  678. //-----------------------------------------------------------------------------
  679. void CSceneViewerPanel::SetScene()
  680. {
  681. CDmeDag *pDag = m_pRoot->GetValueElement< CDmeModel >( "model" );
  682. if ( !pDag )
  683. {
  684. pDag = m_pRoot->GetValueElement< CDmeDag >( "skeleton" );
  685. }
  686. m_pClipViewPanel->SetScene( pDag );
  687. m_pClipViewPanel->SetAnimationList( m_pRoot->GetValueElement< CDmeAnimationList >( "animationList" ) );
  688. m_pClipViewPanel->SetVertexAnimationList( m_pRoot->GetValueElement< CDmeAnimationList >( "vertexAnimationList" ) );
  689. CDmeCombinationOperator *pComboOp = m_pRoot->GetValueElement< CDmeCombinationOperator >( "combinationOperator" );
  690. m_pClipViewPanel->SetCombinationOperator( pComboOp );
  691. m_pCombinationEditor->SetCombinationOperator( pComboOp );
  692. if ( m_pNerdEditor )
  693. {
  694. m_pNerdEditor->SetObject( m_pRoot );
  695. }
  696. if ( pComboOp && pComboOp->GetControlCount() != 0 )
  697. {
  698. // TODO: Show the right TAB...
  699. // Generate wrinkle data only if it doesn't already exist
  700. pComboOp->GenerateWrinkleDeltas( false );
  701. }
  702. SendFrameToDagRenderPanel( m_pClipViewPanel );
  703. }
  704. //-----------------------------------------------------------------------------
  705. // Data for a cube
  706. //-----------------------------------------------------------------------------
  707. static Vector g_pPosition[8] =
  708. {
  709. Vector( -10.0f, -10.0f, -10.0f ),
  710. Vector( 10.0f, -10.0f, -10.0f ),
  711. Vector( -10.0f, 10.0f, -10.0f ),
  712. Vector( 10.0f, 10.0f, -10.0f ),
  713. Vector( -10.0f, -10.0f, 10.0f ),
  714. Vector( 10.0f, -10.0f, 10.0f ),
  715. Vector( -10.0f, 10.0f, 10.0f ),
  716. Vector( 10.0f, 10.0f, 10.0f ),
  717. };
  718. static float g_pBalance[8] =
  719. {
  720. 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f
  721. };
  722. static float g_pSpeed[8] =
  723. {
  724. 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f
  725. };
  726. static int g_pBoneIndices[] =
  727. {
  728. 0, 0, 0,
  729. 0, 0, 0,
  730. 0, 0, 0,
  731. 0, 0, 0,
  732. 1, 0, 0,
  733. 1, 0, 0,
  734. 1, 0, 0,
  735. 1, 0, 0,
  736. };
  737. static float g_pBoneWeights[] =
  738. {
  739. 1.0f, 0.0f, 0.0f,
  740. 1.0f, 0.0f, 0.0f,
  741. 1.0f, 0.0f, 0.0f,
  742. 1.0f, 0.0f, 0.0f,
  743. 1.0f, 0.0f, 0.0f,
  744. 1.0f, 0.0f, 0.0f,
  745. 1.0f, 0.0f, 0.0f,
  746. 1.0f, 0.0f, 0.0f,
  747. };
  748. static Vector g_pNormal[24] =
  749. {
  750. Vector( -1.0f, 0.0f, 0.0f ),
  751. Vector( -1.0f, 0.0f, 0.0f ),
  752. Vector( -1.0f, 0.0f, 0.0f ),
  753. Vector( -1.0f, 0.0f, 0.0f ),
  754. Vector( 1.0f, 0.0f, 0.0f ),
  755. Vector( 1.0f, 0.0f, 0.0f ),
  756. Vector( 1.0f, 0.0f, 0.0f ),
  757. Vector( 1.0f, 0.0f, 0.0f ),
  758. Vector( 0.0f, -1.0f, 0.0f ),
  759. Vector( 0.0f, -1.0f, 0.0f ),
  760. Vector( 0.0f, -1.0f, 0.0f ),
  761. Vector( 0.0f, -1.0f, 0.0f ),
  762. Vector( 0.0f, 1.0f, 0.0f ),
  763. Vector( 0.0f, 1.0f, 0.0f ),
  764. Vector( 0.0f, 1.0f, 0.0f ),
  765. Vector( 0.0f, 1.0f, 0.0f ),
  766. Vector( 0.0f, 0.0f, -1.0f ),
  767. Vector( 0.0f, 0.0f, -1.0f ),
  768. Vector( 0.0f, 0.0f, -1.0f ),
  769. Vector( 0.0f, 0.0f, -1.0f ),
  770. Vector( 0.0f, 0.0f, 1.0f ),
  771. Vector( 0.0f, 0.0f, 1.0f ),
  772. Vector( 0.0f, 0.0f, 1.0f ),
  773. Vector( 0.0f, 0.0f, 1.0f ),
  774. };
  775. static Vector2D g_pUV[4] =
  776. {
  777. Vector2D( 1.0f, 1.0f ),
  778. Vector2D( 0.0f, 1.0f ),
  779. Vector2D( 0.0f, 0.0f ),
  780. Vector2D( 1.0f, 0.0f ),
  781. };
  782. static Color g_pColor[8] =
  783. {
  784. Color( 0, 0, 0, 255 ),
  785. Color( 255, 0, 0, 255 ),
  786. Color( 0, 255, 0, 255 ),
  787. Color( 255, 255, 0, 255 ),
  788. Color( 0, 0, 255, 255 ),
  789. Color( 255, 0, 255, 255 ),
  790. Color( 0, 255, 255, 255 ),
  791. Color( 255, 255, 255, 255 ),
  792. };
  793. static int g_pPositionIndices[24] =
  794. {
  795. 0, 4, 6, 2, // -x face
  796. 1, 3, 7, 5, // +x face
  797. 0, 1, 5, 4, // -y face
  798. 2, 6, 7, 3, // +y face
  799. 0, 2, 3, 1, // -z face
  800. 4, 5, 7, 6, // +z face
  801. };
  802. static int g_pBalanceIndices[24] =
  803. {
  804. 0, 4, 6, 2, // -x face
  805. 1, 3, 7, 5, // +x face
  806. 0, 1, 5, 4, // -y face
  807. 2, 6, 7, 3, // +y face
  808. 0, 2, 3, 1, // -z face
  809. 4, 5, 7, 6, // +z face
  810. };
  811. static int g_pSpeedIndices[24] =
  812. {
  813. 0, 4, 6, 2, // -x face
  814. 1, 3, 7, 5, // +x face
  815. 0, 1, 5, 4, // -y face
  816. 2, 6, 7, 3, // +y face
  817. 0, 2, 3, 1, // -z face
  818. 4, 5, 7, 6, // +z face
  819. };
  820. static int g_pNormalIndices[24] =
  821. {
  822. 0, 1, 2, 3,
  823. 4, 5, 6, 7,
  824. 8, 9, 10, 11,
  825. 12, 13, 14, 15,
  826. 16, 17, 18, 19,
  827. 20, 21, 22, 23,
  828. };
  829. static int g_pUVIndices[24] =
  830. {
  831. 0, 1, 2, 3,
  832. 0, 1, 2, 3,
  833. 0, 1, 2, 3,
  834. 0, 1, 2, 3,
  835. 0, 1, 2, 3,
  836. 0, 1, 2, 3,
  837. };
  838. static int g_pColorIndices[24] =
  839. {
  840. 6, 6, 6, 6, // -x face
  841. 1, 1, 1, 1, // +x face
  842. 2, 2, 2, 2, // -y face
  843. 3, 3, 3, 3, // +y face
  844. 4, 4, 4, 4, // -z face
  845. 5, 5, 5, 5, // +z face
  846. };
  847. static int g_pFaceIndices[] =
  848. {
  849. 0, 1, 2, 3, -1,
  850. 4, 5, 6, 7, -1,
  851. 8, 9, 10, 11, -1,
  852. 12, 13, 14, 15, -1,
  853. 16, 17, 18, 19, -1,
  854. 20, 21, 22, 23, -1,
  855. };
  856. static Vector g_pPositionDelta[] =
  857. {
  858. Vector( 20.0f, 0.0f, 0.0f ),
  859. Vector( 20.0f, 0.0f, 0.0f ),
  860. Vector( 20.0f, 0.0f, 0.0f ),
  861. Vector( 20.0f, 0.0f, 0.0f ),
  862. };
  863. static int g_pPositionDeltaIndices[] =
  864. {
  865. 1, 3, 5, 7
  866. };
  867. static Vector g_pPositionDelta1a[] =
  868. {
  869. Vector( -10.0f, 0.0f, 0.0f ),
  870. Vector( -10.0f, 0.0f, 0.0f ),
  871. Vector( -10.0f, 0.0f, 0.0f ),
  872. Vector( -10.0f, 0.0f, 0.0f ),
  873. };
  874. static int g_pPositionDeltaIndices1a[] =
  875. {
  876. 1, 3, 5, 7
  877. };
  878. static Vector g_pPositionDelta2a[] =
  879. {
  880. Vector( 0.0f, 0.0f, 20.0f ),
  881. Vector( 0.0f, 0.0f, 20.0f ),
  882. };
  883. static int g_pPositionDeltaIndices2a[] =
  884. {
  885. 4, 6
  886. };
  887. static Vector g_pPositionDelta2[] =
  888. {
  889. Vector( 0.0f, 0.0f, 20.0f ),
  890. Vector( 0.0f, 0.0f, 20.0f ),
  891. Vector( 0.0f, 0.0f, 20.0f ),
  892. Vector( 0.0f, 0.0f, 20.0f ),
  893. };
  894. static int g_pPositionDeltaIndices2[] =
  895. {
  896. 4, 5, 6, 7
  897. };
  898. static Vector g_pPositionDelta2c[] =
  899. {
  900. Vector( 0.0f, 0.0f, 20.0f ),
  901. Vector( 0.0f, 0.0f, 20.0f ),
  902. };
  903. static int g_pPositionDeltaIndices2c[] =
  904. {
  905. 5, 7
  906. };
  907. static Vector g_pPositionDelta12[] =
  908. {
  909. Vector( -20.0f, 0.0f, -20.0f ),
  910. Vector( -20.0f, 0.0f, -20.0f ),
  911. };
  912. static int g_pPositionDeltaIndices12[] =
  913. {
  914. 5, 7
  915. };
  916. static Vector g_pPositionDelta3[] =
  917. {
  918. Vector( 0.0f, 20.0f, 0.0f ),
  919. Vector( 0.0f, 20.0f, 0.0f ),
  920. Vector( 0.0f, 20.0f, 0.0f ),
  921. Vector( 0.0f, 20.0f, 0.0f ),
  922. Vector( 0.0f, 20.0f, 0.0f ),
  923. Vector( 0.0f, 20.0f, 0.0f ),
  924. Vector( 0.0f, 20.0f, 0.0f ),
  925. Vector( 0.0f, 20.0f, 0.0f ),
  926. };
  927. static int g_pPositionDeltaIndices3[] =
  928. {
  929. 0, 1, 2, 3, 4, 5, 6, 7
  930. };
  931. //-----------------------------------------------------------------------------
  932. // Sets up a new mesh dag
  933. //-----------------------------------------------------------------------------
  934. CDmeModel *CSceneViewerPanel::CreateNewMeshDag( CDmeMesh **ppMesh, DmFileId_t fileid )
  935. {
  936. KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
  937. pVMTKeyValues->SetString( "$basetexture", "effects/laser1" );
  938. pVMTKeyValues->SetInt( "$additive", 1 );
  939. pVMTKeyValues->SetInt( "$translucent", 1 );
  940. pVMTKeyValues->SetInt( "$vertexcolor", 1 );
  941. pVMTKeyValues->SetInt( "$model", 1 );
  942. g_pMaterialSystem->CreateMaterial( "__sceneViewerTest", pVMTKeyValues );
  943. CDmeModel *pModel = CreateElement< CDmeModel >( "New Model", fileid );
  944. pModel->AddJoint( "joint0" );
  945. pModel->AddJoint( "joint1" );
  946. CDmeDag *pMeshDag = CreateElement< CDmeDag >( "New Mesh Dag", fileid );
  947. CDmeMesh *pMesh = CreateElement< CDmeMesh >( "New Mesh", fileid );
  948. CDmeVertexData *pVertexData = pMesh->FindOrCreateBaseState( "bind" );
  949. CDmeFaceSet *pFaceSet = CreateElement< CDmeFaceSet >( "New Face Set", fileid );
  950. CDmeMaterial *pMaterial = CreateElement< CDmeMaterial >( "New Material", fileid );
  951. pMaterial->SetMaterial( "__sceneViewerTest" );
  952. pMesh->SetCurrentBaseState( "bind" );
  953. int nPerVertexBoneCount = 3;
  954. FieldIndex_t jointWeight, jointIndex;
  955. FieldIndex_t pos = pVertexData->CreateField( CDmeVertexData::FIELD_POSITION );
  956. FieldIndex_t norm = pVertexData->CreateField( CDmeVertexData::FIELD_NORMAL );
  957. FieldIndex_t uv = pVertexData->CreateField( CDmeVertexData::FIELD_TEXCOORD );
  958. FieldIndex_t color = pVertexData->CreateField( CDmeVertexData::FIELD_COLOR );
  959. FieldIndex_t balance = pVertexData->CreateField( CDmeVertexData::FIELD_BALANCE );
  960. FieldIndex_t speed = pVertexData->CreateField( CDmeVertexData::FIELD_MORPH_SPEED );
  961. pVertexData->CreateJointWeightsAndIndices( nPerVertexBoneCount, &jointWeight, &jointIndex );
  962. int nPosCount = ARRAYSIZE(g_pPosition);
  963. int nNormCount = ARRAYSIZE(g_pNormal);
  964. int nUVCount = ARRAYSIZE(g_pUV);
  965. int nColorCount = ARRAYSIZE(g_pColor);
  966. int nBalanceCount = ARRAYSIZE(g_pBalance);
  967. int nSpeedCount = ARRAYSIZE(g_pSpeed);
  968. int nBoneIndices = ARRAYSIZE(g_pBoneIndices);
  969. int nBoneWeights = ARRAYSIZE(g_pBoneWeights);
  970. Assert( nBoneIndices == nPerVertexBoneCount * nPosCount );
  971. Assert( nBoneWeights == nPerVertexBoneCount * nPosCount );
  972. pVertexData->AddVertexData( pos, nPosCount );
  973. pVertexData->SetVertexData( pos, 0, nPosCount, AT_VECTOR3, g_pPosition );
  974. pVertexData->AddVertexData( jointIndex, nBoneIndices );
  975. pVertexData->SetVertexData( jointIndex, 0, nBoneIndices, AT_INT, g_pBoneIndices );
  976. pVertexData->AddVertexData( jointWeight, nBoneWeights );
  977. pVertexData->SetVertexData( jointWeight, 0, nBoneWeights, AT_FLOAT, g_pBoneWeights );
  978. pVertexData->AddVertexData( norm, nNormCount );
  979. pVertexData->SetVertexData( norm, 0, nNormCount, AT_VECTOR3, g_pNormal );
  980. pVertexData->AddVertexData( uv, nUVCount );
  981. pVertexData->SetVertexData( uv, 0, nUVCount, AT_VECTOR2, g_pUV );
  982. pVertexData->AddVertexData( color, nColorCount );
  983. pVertexData->SetVertexData( color, 0, nColorCount, AT_COLOR, g_pColor );
  984. pVertexData->AddVertexData( balance, nBalanceCount );
  985. pVertexData->SetVertexData( balance, 0, nBalanceCount, AT_FLOAT, g_pBalance );
  986. pVertexData->AddVertexData( speed, nSpeedCount );
  987. pVertexData->SetVertexData( speed, 0, nSpeedCount, AT_FLOAT, g_pSpeed );
  988. int nIndexCount = ARRAYSIZE(g_pPositionIndices);
  989. Assert( nIndexCount == ARRAYSIZE(g_pNormalIndices) );
  990. Assert( nIndexCount == ARRAYSIZE(g_pUVIndices) );
  991. Assert( nIndexCount == ARRAYSIZE(g_pColorIndices) );
  992. Assert( nIndexCount == ARRAYSIZE(g_pBalanceIndices) );
  993. Assert( nIndexCount == ARRAYSIZE(g_pSpeedIndices) );
  994. pVertexData->AddVertexIndices( nIndexCount );
  995. pVertexData->SetVertexIndices( pos, 0, nIndexCount, g_pPositionIndices );
  996. pVertexData->SetVertexIndices( norm, 0, nIndexCount, g_pNormalIndices );
  997. pVertexData->SetVertexIndices( uv, 0, nIndexCount, g_pUVIndices );
  998. pVertexData->SetVertexIndices( color, 0, nIndexCount, g_pColorIndices );
  999. pVertexData->SetVertexIndices( balance, 0, nIndexCount, g_pBalanceIndices );
  1000. pVertexData->SetVertexIndices( speed, 0, nIndexCount, g_pSpeedIndices );
  1001. int nFaceIndexCount = ARRAYSIZE(g_pFaceIndices);
  1002. pFaceSet->AddIndices( nFaceIndexCount );
  1003. pFaceSet->SetIndices( 0, nFaceIndexCount, g_pFaceIndices );
  1004. pFaceSet->SetMaterial( pMaterial );
  1005. CDmeVertexDeltaData *pDeltaData = pMesh->FindOrCreateDeltaState( "delta1" );
  1006. FieldIndex_t deltaPos = pDeltaData->CreateField( CDmeVertexDeltaData::FIELD_POSITION );
  1007. int nDeltaPosCount = ARRAYSIZE( g_pPositionDelta );
  1008. pDeltaData->AddVertexData( deltaPos, nDeltaPosCount );
  1009. pDeltaData->SetVertexData( deltaPos, 0, nDeltaPosCount, AT_VECTOR3, g_pPositionDelta );
  1010. pDeltaData->SetVertexIndices( deltaPos, 0, nDeltaPosCount, g_pPositionDeltaIndices );
  1011. pDeltaData = pMesh->FindOrCreateDeltaState( "delta1a" );
  1012. deltaPos = pDeltaData->CreateField( CDmeVertexDeltaData::FIELD_POSITION );
  1013. nDeltaPosCount = ARRAYSIZE( g_pPositionDelta1a );
  1014. pDeltaData->AddVertexData( deltaPos, nDeltaPosCount );
  1015. pDeltaData->SetVertexData( deltaPos, 0, nDeltaPosCount, AT_VECTOR3, g_pPositionDelta1a );
  1016. pDeltaData->SetVertexIndices( deltaPos, 0, nDeltaPosCount, g_pPositionDeltaIndices1a );
  1017. CDmeVertexDeltaData *pDeltaData2 = pMesh->FindOrCreateDeltaState( "delta2" );
  1018. FieldIndex_t deltaPos2 = pDeltaData2->CreateField( CDmeVertexDeltaData::FIELD_POSITION );
  1019. int nDeltaPosCount2 = ARRAYSIZE( g_pPositionDelta2 );
  1020. pDeltaData2->AddVertexData( deltaPos2, nDeltaPosCount2 );
  1021. pDeltaData2->SetVertexData( deltaPos2, 0, nDeltaPosCount2, AT_VECTOR3, g_pPositionDelta2 );
  1022. pDeltaData2->SetVertexIndices( deltaPos2, 0, nDeltaPosCount2, g_pPositionDeltaIndices2 );
  1023. pDeltaData2 = pMesh->FindOrCreateDeltaState( "delta2a" );
  1024. deltaPos2 = pDeltaData2->CreateField( CDmeVertexDeltaData::FIELD_POSITION );
  1025. nDeltaPosCount2 = ARRAYSIZE( g_pPositionDelta2a );
  1026. pDeltaData2->AddVertexData( deltaPos2, nDeltaPosCount2 );
  1027. pDeltaData2->SetVertexData( deltaPos2, 0, nDeltaPosCount2, AT_VECTOR3, g_pPositionDelta2a );
  1028. pDeltaData2->SetVertexIndices( deltaPos2, 0, nDeltaPosCount2, g_pPositionDeltaIndices2a );
  1029. pDeltaData2 = pMesh->FindOrCreateDeltaState( "delta2c" );
  1030. deltaPos2 = pDeltaData2->CreateField( CDmeVertexDeltaData::FIELD_POSITION );
  1031. nDeltaPosCount2 = ARRAYSIZE( g_pPositionDelta2c );
  1032. pDeltaData2->AddVertexData( deltaPos2, nDeltaPosCount2 );
  1033. pDeltaData2->SetVertexData( deltaPos2, 0, nDeltaPosCount2, AT_VECTOR3, g_pPositionDelta2c );
  1034. pDeltaData2->SetVertexIndices( deltaPos2, 0, nDeltaPosCount2, g_pPositionDeltaIndices2c );
  1035. CDmeVertexDeltaData *pDeltaData12 = pMesh->FindOrCreateDeltaState( "delta1_delta2" );
  1036. FieldIndex_t deltaPos12 = pDeltaData12->CreateField( CDmeVertexDeltaData::FIELD_POSITION );
  1037. int nDeltaPosCount12 = ARRAYSIZE( g_pPositionDelta12 );
  1038. pDeltaData12->AddVertexData( deltaPos12, nDeltaPosCount12 );
  1039. pDeltaData12->SetVertexData( deltaPos12, 0, nDeltaPosCount12, AT_VECTOR3, g_pPositionDelta12 );
  1040. pDeltaData12->SetVertexIndices( deltaPos12, 0, nDeltaPosCount12, g_pPositionDeltaIndices12 );
  1041. CDmeVertexDeltaData *pDeltaData3 = pMesh->FindOrCreateDeltaState( "delta3" );
  1042. FieldIndex_t deltaPos3 = pDeltaData3->CreateField( CDmeVertexDeltaData::FIELD_POSITION );
  1043. int nDeltaPosCount3 = ARRAYSIZE( g_pPositionDelta3 );
  1044. pDeltaData3->AddVertexData( deltaPos3, nDeltaPosCount3 );
  1045. pDeltaData3->SetVertexData( deltaPos3, 0, nDeltaPosCount3, AT_VECTOR3, g_pPositionDelta3 );
  1046. pDeltaData3->SetVertexIndices( deltaPos3, 0, nDeltaPosCount3, g_pPositionDeltaIndices3 );
  1047. // Test offset in dag
  1048. matrix3x4_t meshOffset;
  1049. SetIdentityMatrix( meshOffset );
  1050. MatrixSetColumn( Vector( 0, 5, 0 ), 3, meshOffset );
  1051. pMeshDag->GetTransform()->SetTransform( meshOffset );
  1052. pMesh->AddFaceSet( pFaceSet );
  1053. pModel->AddChild( pMeshDag );
  1054. pModel->CaptureJointsToBaseState( "bind" );
  1055. pMeshDag->SetShape( pMesh );
  1056. pMesh->ComputeDeltaStateNormals();
  1057. *ppMesh = pMesh;
  1058. return pModel;
  1059. }
  1060. //-----------------------------------------------------------------------------
  1061. // Sets up a new mesh animation
  1062. //-----------------------------------------------------------------------------
  1063. CDmeAnimationList *CSceneViewerPanel::CreateNewJointAnimation( CDmeModel *pModel )
  1064. {
  1065. CDmeAnimationList *pAnimationList = CreateElement< CDmeAnimationList >( "New Animation List" );
  1066. CDmeChannelsClip *pAnimation = CreateElement< CDmeChannelsClip >( "New Animation" );
  1067. pAnimationList->AddAnimation( pAnimation );
  1068. CDmeChannel *pChannel = CreateElement< CDmeChannel >( "New Channel" );
  1069. pAnimation->m_Channels.AddToTail( pChannel );
  1070. pChannel->SetOutput( pModel->GetJointTransform(1), "position" );
  1071. CDmeVector3Log *pLog = pChannel->CreateLog<Vector>( );
  1072. DmeTime_t time( 0 );
  1073. Vector pos;
  1074. pAnimation->SetStartTime( time );
  1075. for ( int i = 0; i < 30; ++i )
  1076. {
  1077. pos.Random( -20, 20 );
  1078. pLog->SetKey( time, pos );
  1079. time += DmeTime_t( 1.0f );
  1080. }
  1081. pAnimation->SetDuration( time - pAnimation->GetStartTime() );
  1082. return pAnimationList;
  1083. }
  1084. //-----------------------------------------------------------------------------
  1085. // Create random animation
  1086. //-----------------------------------------------------------------------------
  1087. static void CreateRandomAnimation( CDmeChannelsClip *pAnimation, const char *pName, CDmeCombinationOperator *pComboOp )
  1088. {
  1089. CDmeChannel *pChannel = CreateElement< CDmeChannel >( "Vertex Anim Channel" );
  1090. pAnimation->m_Channels.AddToTail( pChannel );
  1091. int nControlIndex = pComboOp->FindControlIndex( pName );
  1092. if ( nControlIndex >= 0 )
  1093. {
  1094. pComboOp->AttachChannelToControlValue( nControlIndex, COMBO_CONTROL_NORMAL, pChannel );
  1095. }
  1096. CDmeVector2Log *pLog = pChannel->CreateLog<Vector2D>( );
  1097. DmeTime_t time( 0 );
  1098. Vector pos;
  1099. for ( int i = 0; i < 30; ++i )
  1100. {
  1101. float flValue = RandomFloat( 0.0f, 1.0f );
  1102. float flValue2 = RandomFloat( 0.0f, 1.0f );
  1103. pLog->SetKey( time, Vector2D( flValue, flValue2 ) );
  1104. time += DmeTime_t( 1.0f );
  1105. }
  1106. CreateLaggedVertexAnimation( pAnimation, 30 );
  1107. }
  1108. //-----------------------------------------------------------------------------
  1109. // Sets up a new vertex animation
  1110. //-----------------------------------------------------------------------------
  1111. CDmeAnimationList *CSceneViewerPanel::CreateNewVertexAnimation( CDmeMesh *pMesh, CDmeCombinationOperator *pComboOp )
  1112. {
  1113. CDmeAnimationList *pAnimationList = CreateElement< CDmeAnimationList >( "New Vertex Animation List" );
  1114. CDmeChannelsClip *pAnimation = CreateElement< CDmeChannelsClip >( "New Vertex Animation" );
  1115. pAnimationList->AddAnimation( pAnimation );
  1116. CreateRandomAnimation( pAnimation, "delta1", pComboOp );
  1117. CreateRandomAnimation( pAnimation, "delta2", pComboOp );
  1118. CreateRandomAnimation( pAnimation, "delta3", pComboOp );
  1119. pAnimation->SetStartTime( DMETIME_ZERO );
  1120. pAnimation->SetDuration( DmeTime_t( 30.0f ) - pAnimation->GetStartTime() );
  1121. return pAnimationList;
  1122. }
  1123. //-----------------------------------------------------------------------------
  1124. // Sets up a new clip
  1125. //-----------------------------------------------------------------------------
  1126. void CSceneViewerPanel::OnNew()
  1127. {
  1128. Clear();
  1129. return;
  1130. // This is not undoable...
  1131. CDisableUndoScopeGuard guard;
  1132. Vector vecTranslation;
  1133. matrix3x4_t mat;
  1134. DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "new.dmx" );
  1135. CDmeMesh *pMesh;
  1136. CDmeModel *pModel = CreateNewMeshDag( &pMesh, fileid );
  1137. CDmeCombinationOperator *pComboOp = CreateElement< CDmeCombinationOperator >( "New Combination Operator", fileid );
  1138. ControlIndex_t nIndex = pComboOp->FindOrCreateControl( "delta1", true );
  1139. pComboOp->AddRawControl( nIndex, "delta1" );
  1140. pComboOp->AddRawControl( nIndex, "delta1a" );
  1141. nIndex = pComboOp->FindOrCreateControl( "delta2", true );
  1142. pComboOp->AddRawControl( nIndex, "delta2a" );
  1143. pComboOp->AddRawControl( nIndex, "delta2" );
  1144. pComboOp->AddRawControl( nIndex, "delta2c" );
  1145. pComboOp->FindOrCreateControl( "delta3", false, true );
  1146. pComboOp->UsingLaggedData( true );
  1147. pComboOp->AddTarget( pModel );
  1148. const char *ppDominators[] = { "delta1", "delta2" };
  1149. const char *ppSuppressors[] = { "delta3" };
  1150. pComboOp->AddDominationRule( ARRAYSIZE(ppDominators), ppDominators, ARRAYSIZE(ppSuppressors), ppSuppressors );
  1151. pComboOp->AddDominationRule( ARRAYSIZE(ppSuppressors), ppSuppressors, ARRAYSIZE(ppDominators), ppDominators );
  1152. CDmeAnimationList *pAnimationList = CreateNewJointAnimation( pModel );
  1153. CDmeAnimationList *pVertexAnimationList = CreateNewVertexAnimation( pMesh, pComboOp );
  1154. m_pClipViewPanel->SetScene( pModel );
  1155. m_pClipViewPanel->SetCombinationOperator( pComboOp );
  1156. m_pClipViewPanel->SetAnimationList( pAnimationList );
  1157. m_pClipViewPanel->SetVertexAnimationList( pVertexAnimationList );
  1158. // NOTE: The root element here is what we expect to see in a file
  1159. CDmElement *pRoot = CreateElement< CDmElement >( "root", fileid );
  1160. pRoot->SetValue( "skeleton", pModel );
  1161. pRoot->SetValue( "model", pModel );
  1162. pRoot->SetValue( "animationList", pAnimationList );
  1163. pRoot->SetValue( "vertexAnimationList", pVertexAnimationList );
  1164. pRoot->SetValue( "combinationOperator", pComboOp );
  1165. m_pCombinationEditor->SetCombinationOperator( pComboOp );
  1166. // Unload any old model
  1167. if ( m_pRoot )
  1168. {
  1169. g_pDataModel->RemoveFileId( m_pRoot->GetFileId() );
  1170. }
  1171. m_pRoot = pRoot;
  1172. }
  1173. //-----------------------------------------------------------------------------
  1174. //
  1175. //-----------------------------------------------------------------------------
  1176. void CSceneViewerPanel::OnOpen()
  1177. {
  1178. int nFlags = 0;
  1179. const char *pFileName = NULL;
  1180. if ( m_pRoot )
  1181. {
  1182. nFlags = vgui::FOSM_SHOW_PERFORCE_DIALOGS;
  1183. pFileName = g_pDataModel->GetFileName( m_pRoot->GetFileId() );
  1184. }
  1185. KeyValues *pContextKeyValues = new KeyValues( "FileOpen" );
  1186. m_pFileOpenStateMachine->OpenFile( DEFAULT_FILE_FORMAT, pContextKeyValues, pFileName, NULL, nFlags );
  1187. }
  1188. //-----------------------------------------------------------------------------
  1189. //
  1190. //-----------------------------------------------------------------------------
  1191. void CSceneViewerPanel::OnSave()
  1192. {
  1193. if ( !m_pRoot )
  1194. {
  1195. OnSaveAs();
  1196. return;
  1197. }
  1198. KeyValues *pContextKeyValues = new KeyValues( "FileSave" );
  1199. m_pFileOpenStateMachine->SaveFile(
  1200. pContextKeyValues,
  1201. g_pDataModel->GetFileName( m_pRoot->GetFileId() ),
  1202. DEFAULT_FILE_FORMAT,
  1203. vgui::FOSM_SHOW_PERFORCE_DIALOGS );
  1204. }
  1205. //-----------------------------------------------------------------------------
  1206. // Save As Dialog Box
  1207. //-----------------------------------------------------------------------------
  1208. void CSceneViewerPanel::OnSaveAs()
  1209. {
  1210. if ( !m_pRoot )
  1211. {
  1212. vgui::MessageBox *pError = new vgui::MessageBox(
  1213. "#SceneViewer_NothingToSave",
  1214. "#SceneViewer_NothingToSave", this );
  1215. pError->DoModal();
  1216. return;
  1217. }
  1218. KeyValues *pContextKeyValues = new KeyValues( "FileSave" );
  1219. m_pFileOpenStateMachine->SaveFile( pContextKeyValues, NULL, DEFAULT_FILE_FORMAT, vgui::FOSM_SHOW_PERFORCE_DIALOGS );
  1220. }
  1221. //-----------------------------------------------------------------------------
  1222. // Save Current As Dialog Box
  1223. //-----------------------------------------------------------------------------
  1224. void CSceneViewerPanel::OnSaveCurrentAs()
  1225. {
  1226. if ( !m_pRoot )
  1227. {
  1228. vgui::MessageBox *pError = new vgui::MessageBox(
  1229. "#SceneViewer_NothingToSave",
  1230. "#SceneViewer_NothingToSave", this );
  1231. pError->DoModal();
  1232. return;
  1233. }
  1234. KeyValues *pContextKeyValues = new KeyValues( "SaveCurrentAs" );
  1235. m_pFileOpenStateMachine->SaveFile( pContextKeyValues, NULL, DEFAULT_FILE_FORMAT, vgui::FOSM_SHOW_PERFORCE_DIALOGS );
  1236. }
  1237. //-----------------------------------------------------------------------------
  1238. // Exit Application
  1239. //-----------------------------------------------------------------------------
  1240. void CSceneViewerPanel::OnExit()
  1241. {
  1242. vgui::ivgui()->Stop();
  1243. }
  1244. //-----------------------------------------------------------------------------
  1245. // Save As Dialog Box
  1246. //-----------------------------------------------------------------------------
  1247. void CSceneViewerPanel::OnDescribeUndoStack()
  1248. {
  1249. CUtlVector< UndoInfo_t > list;
  1250. g_pDataModel->GetUndoInfo( list );
  1251. Msg( "%i operations in stack\n", list.Count() );
  1252. for ( int i = list.Count() - 1; i >= 0; --i )
  1253. {
  1254. UndoInfo_t& entry = list[ i ];
  1255. if ( entry.terminator )
  1256. {
  1257. Msg( "[ '%s' ] - %i operations\n", entry.undo, entry.numoperations );
  1258. }
  1259. Msg( " +%s\n", entry.desc );
  1260. }
  1261. }
  1262. //-----------------------------------------------------------------------------
  1263. //
  1264. //-----------------------------------------------------------------------------
  1265. void CSceneViewerPanel::OnSizeChanged( int /* newWidth */, int /* newHeight */ )
  1266. {
  1267. if ( m_pClipViewPanel->GetAutoResize() != AUTORESIZE_NO )
  1268. {
  1269. OnPinAndZoomIt();
  1270. }
  1271. }
  1272. //-----------------------------------------------------------------------------
  1273. //
  1274. //-----------------------------------------------------------------------------
  1275. void CSceneViewerPanel::OnPinAndZoomIt()
  1276. {
  1277. int mx, my;
  1278. m_pMenuBar->GetPos( mx, my );
  1279. int mw, mh;
  1280. m_pMenuBar->GetSize( mw, mh );
  1281. m_pClipViewPanel->SetPinCorner( PIN_TOPLEFT, 0, my + mh + 2 );
  1282. m_pClipViewPanel->SetAutoResize( PIN_TOPLEFT, AUTORESIZE_DOWNANDRIGHT, 0, my + mh + 2, 0, 0 );
  1283. int w, h;
  1284. this->GetSize( w, h );
  1285. m_pClipViewPanel->SetBounds( 0, my + mh + 2, w, h - ( my + mh + 2 ) );
  1286. }
  1287. //-----------------------------------------------------------------------------
  1288. //
  1289. //-----------------------------------------------------------------------------
  1290. void CSceneViewerPanel::OnLoadFile( const char *fullpath )
  1291. {
  1292. Load( fullpath );
  1293. }
  1294. //-----------------------------------------------------------------------------
  1295. //
  1296. //-----------------------------------------------------------------------------
  1297. void CSceneViewerPanel::OnUndo()
  1298. {
  1299. g_pDataModel->Undo();
  1300. if ( m_hProperties.Get() )
  1301. {
  1302. m_hProperties->Refresh();
  1303. }
  1304. }
  1305. //-----------------------------------------------------------------------------
  1306. //
  1307. //-----------------------------------------------------------------------------
  1308. void CSceneViewerPanel::OnRedo()
  1309. {
  1310. g_pDataModel->Redo();
  1311. if ( m_hProperties.Get() )
  1312. {
  1313. m_hProperties->Refresh();
  1314. }
  1315. }
  1316. //-----------------------------------------------------------------------------
  1317. //
  1318. //-----------------------------------------------------------------------------
  1319. void CSceneViewerPanel::OnEdit()
  1320. {
  1321. if ( m_hProperties.Get() )
  1322. {
  1323. m_hProperties.Get()->MoveToFront();
  1324. return;
  1325. }
  1326. if ( m_hProperties.Get() )
  1327. {
  1328. delete m_hProperties.Get();
  1329. }
  1330. m_hProperties = new CElementPropertiesTree( this, NULL, GetScene() );
  1331. if ( m_hProperties.Get() )
  1332. {
  1333. m_hProperties->Init();
  1334. }
  1335. }
  1336. //-----------------------------------------------------------------------------
  1337. //
  1338. //-----------------------------------------------------------------------------
  1339. void CSceneViewerPanel::OnShow3DView()
  1340. {
  1341. if ( m_pClipViewPanel )
  1342. {
  1343. m_pClipViewPanel->SetVisible( true );
  1344. m_pClipViewPanel->MoveToFront();
  1345. }
  1346. }
  1347. //-----------------------------------------------------------------------------
  1348. //
  1349. //-----------------------------------------------------------------------------
  1350. void CSceneViewerPanel::OnHide3DView()
  1351. {
  1352. if ( m_pClipViewPanel )
  1353. {
  1354. m_pClipViewPanel->SetVisible( false );
  1355. }
  1356. }
  1357. //-----------------------------------------------------------------------------
  1358. //
  1359. //-----------------------------------------------------------------------------
  1360. void CSceneViewerPanel::OnShowComboEditor()
  1361. {
  1362. if ( m_pCombinationEditor )
  1363. {
  1364. m_pCombinationEditor->SetVisible( true );
  1365. m_pCombinationEditor->MoveToFront();
  1366. }
  1367. }
  1368. //-----------------------------------------------------------------------------
  1369. //
  1370. //-----------------------------------------------------------------------------
  1371. void CSceneViewerPanel::OnHideComboEditor()
  1372. {
  1373. if ( m_pCombinationEditor )
  1374. {
  1375. m_pCombinationEditor->SetVisible( false );
  1376. }
  1377. }
  1378. //-----------------------------------------------------------------------------
  1379. //
  1380. //-----------------------------------------------------------------------------
  1381. void CSceneViewerPanel::OnShowAssetBuilder()
  1382. {
  1383. if ( m_pAssetBuilder )
  1384. {
  1385. m_pAssetBuilder->SetVisible( true );
  1386. m_pAssetBuilder->MoveToFront();
  1387. }
  1388. }
  1389. //-----------------------------------------------------------------------------
  1390. //
  1391. //-----------------------------------------------------------------------------
  1392. void CSceneViewerPanel::OnHideAssetBuilder()
  1393. {
  1394. if ( m_pAssetBuilder )
  1395. {
  1396. m_pAssetBuilder->SetVisible( false );
  1397. }
  1398. }
  1399. //-----------------------------------------------------------------------------
  1400. //
  1401. //-----------------------------------------------------------------------------
  1402. void CSceneViewerPanel::OnShowConsole()
  1403. {
  1404. if ( !m_pAssetBuilder )
  1405. return;
  1406. m_pConsole->SetVisible( true );
  1407. m_pConsole->MoveToFront();
  1408. }
  1409. //-----------------------------------------------------------------------------
  1410. //
  1411. //-----------------------------------------------------------------------------
  1412. void CSceneViewerPanel::OnHideConsole()
  1413. {
  1414. if ( !m_pConsole )
  1415. return;
  1416. m_pConsole->SetVisible( false );
  1417. }
  1418. //-----------------------------------------------------------------------------
  1419. //
  1420. //-----------------------------------------------------------------------------
  1421. void CSceneViewerPanel::OnShowNerdEditor()
  1422. {
  1423. if ( m_pNerdEditor )
  1424. {
  1425. m_pNerdEditor->SetVisible( true );
  1426. m_pNerdEditor->MoveToFront();
  1427. }
  1428. }
  1429. //-----------------------------------------------------------------------------
  1430. //
  1431. //-----------------------------------------------------------------------------
  1432. void CSceneViewerPanel::OnHideNerdEditor()
  1433. {
  1434. if ( m_pNerdEditor )
  1435. {
  1436. m_pNerdEditor->SetVisible( false );
  1437. }
  1438. }
  1439. //-----------------------------------------------------------------------------
  1440. //
  1441. //-----------------------------------------------------------------------------
  1442. void CSceneViewerPanel::OnCombinationOperatorChanged()
  1443. {
  1444. if ( m_pClipViewPanel )
  1445. {
  1446. m_pClipViewPanel->RefreshCombinationOperator();
  1447. }
  1448. }
  1449. //-----------------------------------------------------------------------------
  1450. // The editor panel should always fill the space...
  1451. //-----------------------------------------------------------------------------
  1452. void CSceneViewerPanel::PerformLayout()
  1453. {
  1454. // Make the editor panel fill the space
  1455. int iWidth, iHeight;
  1456. vgui::VPANEL parent = GetParent() ? GetParent()->GetVPanel() : vgui::surface()->GetEmbeddedPanel();
  1457. vgui::ipanel()->GetSize( parent, iWidth, iHeight );
  1458. SetSize( iWidth, iHeight );
  1459. m_pMenuBar->SetSize( iWidth, 28 );
  1460. // Make the client area also fill the space not used by the menu bar
  1461. int iTemp, iMenuHeight;
  1462. m_pMenuBar->GetSize( iTemp, iMenuHeight );
  1463. m_pClientArea->SetPos( 0, iMenuHeight );
  1464. m_pClientArea->SetSize( iWidth, iHeight - iMenuHeight );
  1465. if ( !m_bConsolePositioned )
  1466. {
  1467. m_pConsole->SetSize( iWidth / 2, iHeight / 2 );
  1468. m_pConsole->MoveToCenterOfScreen();
  1469. m_bConsolePositioned = true;
  1470. }
  1471. }
  1472. //-----------------------------------------------------------------------------
  1473. //
  1474. //-----------------------------------------------------------------------------
  1475. void CSceneViewerPanel::NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags )
  1476. {
  1477. // Do nothing for now... need to add IDmNotify support from DagRenderPanel
  1478. }