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.

1531 lines
41 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <stdafx.h>
  8. #include <afxcmn.h>
  9. #include "hammer.h"
  10. #include "MainFrm.h"
  11. #include "GlobalFunctions.h"
  12. #include "MapDoc.h"
  13. #include "FaceEdit_DispPage.h"
  14. #include "MapSolid.h"
  15. #include "MapFace.h"
  16. #include "MapDisp.h"
  17. #include "FaceEditSheet.h"
  18. #include "MapView3D.h"
  19. #include "History.h"
  20. #include "ToolDisplace.h"
  21. #include "ToolManager.h"
  22. #include "DispSew.h"
  23. #include "builddisp.h"
  24. // memdbgon must be the last include file in a .cpp file!!!
  25. #include <tier0/memdbgon.h>
  26. CToolDisplace* GetDisplacementTool() { return dynamic_cast<CToolDisplace*>(ToolManager()->GetToolForID(TOOL_FACEEDIT_DISP)); }
  27. //=============================================================================
  28. IMPLEMENT_DYNAMIC( CFaceEditDispPage, CPropertyPage )
  29. BEGIN_MESSAGE_MAP( CFaceEditDispPage, CPropertyPage )
  30. //{{AFX_MSG_MAP( CFaceEditDispPage )
  31. ON_BN_CLICKED( ID_DISP_MASK_SELECT, OnCheckMaskSelect )
  32. ON_BN_CLICKED( ID_DISP_MASK_GRID, OnCheckMaskGrid )
  33. ON_BN_CLICKED( ID_DISP_NOPHYSICS_COLL, OnCheckNoPhysicsCollide )
  34. ON_BN_CLICKED( ID_DISP_NOHULL_COLL, OnCheckNoHullCollide )
  35. ON_BN_CLICKED( ID_DISP_NORAY_COLL, OnCheckNoRayCollide )
  36. ON_BN_CLICKED( ID_DISP_SELECT2, OnButtonSelect )
  37. ON_BN_CLICKED( ID_DISP_CREATE, OnButtonCreate )
  38. ON_BN_CLICKED( ID_DISP_DESTROY, OnButtonDestroy )
  39. ON_BN_CLICKED( ID_DISP_NOISE, OnButtonNoise )
  40. ON_BN_CLICKED( ID_DISP_SUBDIVIDE, OnButtonSubdivide )
  41. ON_BN_CLICKED( ID_DISP_SEW, OnButtonSew )
  42. ON_BN_CLICKED( ID_DISP_PAINT_GEO, OnButtonPaintGeo )
  43. ON_BN_CLICKED( ID_DISP_PAINT_DATA, OnButtonPaintData )
  44. ON_BN_CLICKED( ID_DISP_TAG_WALK, OnButtonTagWalkable )
  45. ON_BN_CLICKED( ID_DISP_TAG_BUILD, OnButtonTagBuildable )
  46. ON_BN_CLICKED( ID_DISP_TAG_REMOVE, OnButtonTagRemove )
  47. ON_BN_CLICKED( ID_DISP_INVERT_ALPHA, OnButtonInvertAlpha )
  48. ON_BN_CLICKED( IDC_SELECT_ADJACENT, OnSelectAdjacent )
  49. ON_NOTIFY( UDN_DELTAPOS, ID_SPIN_DISP_POWER, OnSpinUpDown )
  50. ON_NOTIFY( UDN_DELTAPOS, ID_SPIN_DISP_ELEVATION, OnSpinUpDown )
  51. ON_BN_CLICKED( ID_DISP_APPLY, OnButtonApply )
  52. //}}AFX_MSG_MAP
  53. ON_BN_CLICKED(ID_DISP_SCULPT_PAINT, &CFaceEditDispPage::OnBnClickedDispSculptPaint)
  54. END_MESSAGE_MAP()
  55. //-----------------------------------------------------------------------------
  56. // Purpose: Constructor
  57. //-----------------------------------------------------------------------------
  58. CFaceEditDispPage::CFaceEditDispPage() : CPropertyPage( IDD )
  59. {
  60. m_uiTool = FACEEDITTOOL_SELECT;
  61. m_bForceShowWalkable = false;
  62. m_bForceShowBuildable = false;
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose: Deconstructor
  66. //-----------------------------------------------------------------------------
  67. CFaceEditDispPage::~CFaceEditDispPage()
  68. {
  69. }
  70. //-----------------------------------------------------------------------------
  71. //-----------------------------------------------------------------------------
  72. inline void CFaceEditDispPage::PostToolUpdate( void )
  73. {
  74. // update the mapdoc views
  75. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  76. if( pDoc )
  77. {
  78. pDoc->SetModifiedFlag();
  79. }
  80. // update the dialogs data
  81. UpdateDialogData();
  82. }
  83. //-----------------------------------------------------------------------------
  84. //-----------------------------------------------------------------------------
  85. void CFaceEditDispPage::ClickFace( CMapSolid *pSolid, int faceIndex, int cmd, int clickMode )
  86. {
  87. m_bIsEditable = ( pSolid ? pSolid->IsEditable() : true );
  88. UpdateDialogData();
  89. }
  90. //-----------------------------------------------------------------------------
  91. //-----------------------------------------------------------------------------
  92. void CFaceEditDispPage::UpdateEditControls( bool bAllDisps, bool bHasFace )
  93. {
  94. //
  95. // masks - always active!!
  96. //
  97. CButton *pcheckSelect = ( CButton* )GetDlgItem( ID_DISP_MASK_SELECT );
  98. CButton *pcheckGrid = ( CButton* )GetDlgItem( ID_DISP_MASK_GRID );
  99. pcheckSelect->EnableWindow( TRUE );
  100. pcheckGrid->EnableWindow( TRUE );
  101. //
  102. // tool buttons
  103. //
  104. CButton *pbuttonSelect = ( CButton* )GetDlgItem( ID_DISP_SELECT2 );
  105. CButton *pbuttonCreate = ( CButton* )GetDlgItem( ID_DISP_CREATE );
  106. CButton *pbuttonDestroy = ( CButton* )GetDlgItem( ID_DISP_DESTROY );
  107. CButton *pbuttonPaintGeo = ( CButton* )GetDlgItem( ID_DISP_PAINT_GEO );
  108. CButton *pbuttonPaintSculpt = ( CButton* )GetDlgItem( ID_DISP_SCULPT_PAINT );
  109. CButton *pbuttonPaintData = ( CButton* )GetDlgItem( ID_DISP_PAINT_DATA );
  110. CButton *pbuttonSubdiv = ( CButton* )GetDlgItem( ID_DISP_SUBDIVIDE );
  111. CButton *pbuttonSew = ( CButton* )GetDlgItem( ID_DISP_SEW );
  112. CButton *pbuttonNoise = ( CButton* )GetDlgItem( ID_DISP_NOISE );
  113. CButton *pButtonWalk = ( CButton* )GetDlgItem( ID_DISP_TAG_WALK );
  114. CButton *pButtonBuild = ( CButton* )GetDlgItem( ID_DISP_TAG_BUILD );
  115. pbuttonSelect->EnableWindow( TRUE );
  116. pbuttonCreate->EnableWindow( FALSE );
  117. pbuttonDestroy->EnableWindow( FALSE );
  118. pbuttonPaintGeo->EnableWindow( FALSE );
  119. pbuttonPaintSculpt->EnableWindow( FALSE );
  120. pbuttonPaintData->EnableWindow( FALSE );
  121. pbuttonSubdiv->EnableWindow( FALSE );
  122. pbuttonSew->EnableWindow( FALSE );
  123. pbuttonNoise->EnableWindow( FALSE );
  124. pButtonWalk->EnableWindow( TRUE );
  125. pButtonBuild->EnableWindow( TRUE );
  126. //
  127. // attributes (displacement info)
  128. //
  129. CEdit *peditPower = ( CEdit* )GetDlgItem( ID_DISP_POWER );
  130. CSpinButtonCtrl *pspinPower = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_POWER );
  131. CEdit *peditElevation = ( CEdit* )GetDlgItem( ID_DISP_ELEVATION );
  132. CSpinButtonCtrl *pspinElevation = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_ELEVATION );
  133. CEdit *peditScale = ( CEdit* )GetDlgItem( ID_DISP_SCALE );
  134. CButton *pbuttonApply = ( CButton* )GetDlgItem( ID_DISP_APPLY );
  135. CButton *pbuttonInvertAlpha = ( CButton* )GetDlgItem( ID_DISP_INVERT_ALPHA );
  136. CButton *pCheckNoPhysicsColl = ( CButton* )GetDlgItem( ID_DISP_NOPHYSICS_COLL );
  137. CButton *pCheckNoHullColl = ( CButton* )GetDlgItem( ID_DISP_NOHULL_COLL );
  138. CButton *pCheckNoRayColl = ( CButton* )GetDlgItem( ID_DISP_NORAY_COLL );
  139. peditPower->EnableWindow( FALSE );
  140. pspinPower->EnableWindow( FALSE );
  141. peditElevation->EnableWindow( FALSE );
  142. pspinElevation->EnableWindow( FALSE );
  143. peditScale->EnableWindow( FALSE );
  144. pbuttonApply->EnableWindow( FALSE );
  145. pbuttonInvertAlpha->EnableWindow( FALSE );
  146. pCheckNoPhysicsColl->EnableWindow( FALSE );
  147. pCheckNoHullColl->EnableWindow( FALSE );
  148. pCheckNoRayColl->EnableWindow( FALSE );
  149. // if there aren't any faces selected then the only active item should be selection
  150. if( !bHasFace )
  151. return;
  152. //
  153. // if not all selected faces are displacements then highlight only
  154. // SELECTION, CREATE, DESTROY, and SEW
  155. //
  156. if ( m_bIsEditable )
  157. {
  158. if( !bAllDisps )
  159. {
  160. pbuttonCreate->EnableWindow( TRUE );
  161. pbuttonDestroy->EnableWindow( TRUE );
  162. pbuttonSew->EnableWindow( TRUE );
  163. }
  164. // highlight all tool buttons, but CREATE
  165. else
  166. {
  167. pbuttonDestroy->EnableWindow( TRUE );
  168. pbuttonPaintGeo->EnableWindow( TRUE );
  169. pbuttonPaintSculpt->EnableWindow( TRUE );
  170. pbuttonPaintData->EnableWindow( TRUE );
  171. pbuttonSubdiv->EnableWindow( TRUE );
  172. pbuttonSew->EnableWindow( TRUE );
  173. pbuttonNoise->EnableWindow( TRUE );
  174. }
  175. // active attributes if in selection mode
  176. if( m_uiTool == FACEEDITTOOL_SELECT )
  177. {
  178. peditPower->EnableWindow( TRUE );
  179. pspinPower->EnableWindow( TRUE );
  180. peditElevation->EnableWindow( TRUE );
  181. pspinElevation->EnableWindow( TRUE );
  182. peditScale->EnableWindow( TRUE );
  183. pbuttonApply->EnableWindow( TRUE );
  184. pbuttonInvertAlpha->EnableWindow( TRUE );
  185. pCheckNoPhysicsColl->EnableWindow( TRUE );
  186. pCheckNoHullColl->EnableWindow( TRUE );
  187. pCheckNoRayColl->EnableWindow( TRUE );
  188. }
  189. }
  190. }
  191. //-----------------------------------------------------------------------------
  192. //-----------------------------------------------------------------------------
  193. void CFaceEditDispPage::FillEditControls( bool bAllDisps )
  194. {
  195. CString strText;
  196. //
  197. // if all selected face have displacements
  198. //
  199. if( bAllDisps )
  200. {
  201. int power = 0;
  202. bool bAllPower = true;
  203. float elevation = 0.0f;
  204. bool bAllElevation = true;
  205. float scale = 1.0f;
  206. bool bAllScale = true;
  207. bool bAllNoPhysics = true;
  208. bool bAllNoHull = true;
  209. bool bAllNoRay = true;
  210. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  211. if( pSheet )
  212. {
  213. int faceCount = pSheet->GetFaceListCount();
  214. if( faceCount > 0 )
  215. {
  216. CMapFace *pFace = pSheet->GetFaceListDataFace( 0 );
  217. EditDispHandle_t handle = pFace->GetDisp();
  218. CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
  219. power = pDisp->GetPower();
  220. elevation = pDisp->GetElevation();
  221. scale = pDisp->GetScale();
  222. }
  223. //
  224. // test all faces for "equal" attributes
  225. //
  226. for( int faceIndex = 0; faceIndex < faceCount; faceIndex++ )
  227. {
  228. CMapFace *pFace = pSheet->GetFaceListDataFace( faceIndex );
  229. EditDispHandle_t handle = pFace->GetDisp();
  230. CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
  231. // test power, elevation, and scale
  232. if( power != pDisp->GetPower() ) { bAllPower = false; }
  233. if( elevation != pDisp->GetElevation() ) { bAllElevation = false; }
  234. if( scale != pDisp->GetScale() ) { bAllScale = false; }
  235. if ( !pDisp->CheckFlags( CCoreDispInfo::SURF_NOPHYSICS_COLL ) ) { bAllNoPhysics = false; }
  236. if ( !pDisp->CheckFlags( CCoreDispInfo::SURF_NOHULL_COLL ) ) { bAllNoHull = false; }
  237. if ( !pDisp->CheckFlags( CCoreDispInfo::SURF_NORAY_COLL ) ) { bAllNoRay = false; }
  238. }
  239. // set displacement power value to 3 - 9x9
  240. SetDlgItemText( ID_DISP_POWER, "" );
  241. if( bAllPower )
  242. {
  243. SetDlgItemInt( ID_DISP_POWER, power );
  244. }
  245. // set elevation value
  246. SetDlgItemText( ID_DISP_ELEVATION, "" );
  247. if( bAllElevation )
  248. {
  249. strText.Format( "%4.2f", elevation );
  250. SetDlgItemText( ID_DISP_ELEVATION, strText );
  251. }
  252. // set scale value
  253. SetDlgItemText( ID_DISP_SCALE, "" );
  254. if( bAllScale )
  255. {
  256. strText.Format( "%4.4f", scale );
  257. SetDlgItemText( ID_DISP_SCALE, strText );
  258. }
  259. CButton *pCheckBox;
  260. pCheckBox = ( CButton* )GetDlgItem( ID_DISP_NOPHYSICS_COLL );
  261. pCheckBox->SetCheck( FALSE );
  262. if ( bAllNoPhysics )
  263. {
  264. pCheckBox->SetCheck( TRUE );
  265. }
  266. pCheckBox = ( CButton* )GetDlgItem( ID_DISP_NOHULL_COLL );
  267. pCheckBox->SetCheck( FALSE );
  268. if ( bAllNoHull )
  269. {
  270. pCheckBox->SetCheck( TRUE );
  271. }
  272. pCheckBox = ( CButton* )GetDlgItem( ID_DISP_NORAY_COLL );
  273. pCheckBox->SetCheck( FALSE );
  274. if ( bAllNoRay )
  275. {
  276. pCheckBox->SetCheck( TRUE );
  277. }
  278. }
  279. }
  280. else
  281. {
  282. // set initial displacement power value to 3 - 9x9
  283. CSpinButtonCtrl *pSpin = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_POWER );
  284. pSpin->SetPos( 0 );
  285. SetDlgItemInt( ID_DISP_POWER, 0 );
  286. // set initial elevation value
  287. pSpin = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_ELEVATION );
  288. pSpin->SetPos( 0 );
  289. SetDlgItemText( ID_DISP_ELEVATION, "" );
  290. // set initial scale value
  291. SetDlgItemText( ID_DISP_SCALE, "" );
  292. }
  293. //
  294. // get tool specific data for page
  295. //
  296. CToolDisplace *pDispTool = GetDisplacementTool();
  297. if( pDispTool )
  298. {
  299. CButton *checkBox;
  300. checkBox = ( CButton* )GetDlgItem( ID_DISP_MASK_SELECT );
  301. checkBox->SetCheck( pDispTool->HasSelectMask() );
  302. checkBox = ( CButton* )GetDlgItem( ID_DISP_MASK_GRID );
  303. checkBox->SetCheck( pDispTool->HasGridMask() );
  304. }
  305. }
  306. //-----------------------------------------------------------------------------
  307. //-----------------------------------------------------------------------------
  308. void CFaceEditDispPage::UpdateDialogData( void )
  309. {
  310. bool bAllDisps = false;
  311. bool bHasFace = false;
  312. //
  313. // get face and displacement info
  314. //
  315. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  316. if( pSheet )
  317. {
  318. int faceCount = pSheet->GetFaceListCount();
  319. if( faceCount > 0 )
  320. {
  321. bHasFace = true;
  322. bAllDisps = true;
  323. }
  324. for( int i = 0; i < faceCount; i++ )
  325. {
  326. CMapFace *pFace = pSheet->GetFaceListDataFace( i );
  327. if( !pFace->HasDisp() )
  328. {
  329. bAllDisps = false;
  330. }
  331. }
  332. }
  333. // fill in edit controls
  334. FillEditControls( bAllDisps );
  335. // update the edit controls
  336. UpdateEditControls( bAllDisps, bHasFace );
  337. }
  338. //-----------------------------------------------------------------------------
  339. //-----------------------------------------------------------------------------
  340. void CFaceEditDispPage::UpdatePaintDialogs( void )
  341. {
  342. m_PaintDistDlg.UpdateSpatialData();
  343. }
  344. //-----------------------------------------------------------------------------
  345. //-----------------------------------------------------------------------------
  346. void CFaceEditDispPage::OnCheckMaskSelect( void )
  347. {
  348. // get the displacement tool
  349. CToolDisplace *pDispTool = GetDisplacementTool();
  350. if( pDispTool )
  351. {
  352. pDispTool->ToggleSelectMask();
  353. }
  354. }
  355. //-----------------------------------------------------------------------------
  356. //-----------------------------------------------------------------------------
  357. void CFaceEditDispPage::OnCheckMaskGrid( void )
  358. {
  359. // get the displacement tool
  360. CToolDisplace *pDispTool = GetDisplacementTool();
  361. if( pDispTool )
  362. {
  363. pDispTool->ToggleGridMask();
  364. }
  365. }
  366. //-----------------------------------------------------------------------------
  367. //-----------------------------------------------------------------------------
  368. void CFaceEditDispPage::OnCheckNoPhysicsCollide( void )
  369. {
  370. // Toggle marked faces as collidable.
  371. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  372. if( pSheet )
  373. {
  374. // Check for a face list.
  375. int nFaceCount = pSheet->GetFaceListCount();
  376. if( nFaceCount == 0 )
  377. return;
  378. // Are we setting or reseting the collision flag?
  379. CButton *pCheckNoCollide = ( CButton* )GetDlgItem( ID_DISP_NOPHYSICS_COLL );
  380. bool bReset = false;
  381. if ( !pCheckNoCollide->GetCheck() )
  382. {
  383. bReset = true;
  384. }
  385. // Get faces with displacements and toggle the collide flag.
  386. int iFace = 0;
  387. for( iFace = 0; iFace < nFaceCount; iFace++ )
  388. {
  389. CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
  390. if( !pFace || !pFace->HasDisp() )
  391. continue;
  392. EditDispHandle_t hDisp = pFace->GetDisp();
  393. CMapDisp *pDisp = EditDispMgr()->GetDisp( hDisp );
  394. if( pDisp )
  395. {
  396. if ( bReset )
  397. {
  398. int nFlags = pDisp->GetFlags();
  399. nFlags &= ~CCoreDispInfo::SURF_NOPHYSICS_COLL;
  400. pDisp->SetFlags( nFlags );
  401. }
  402. else
  403. {
  404. int nFlags = pDisp->GetFlags();
  405. nFlags |= CCoreDispInfo::SURF_NOPHYSICS_COLL;
  406. pDisp->SetFlags( nFlags );
  407. }
  408. }
  409. }
  410. }
  411. }
  412. //-----------------------------------------------------------------------------
  413. //-----------------------------------------------------------------------------
  414. void CFaceEditDispPage::OnCheckNoHullCollide( void )
  415. {
  416. // Toggle marked faces as collidable.
  417. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  418. if( pSheet )
  419. {
  420. // Check for a face list.
  421. int nFaceCount = pSheet->GetFaceListCount();
  422. if( nFaceCount == 0 )
  423. return;
  424. // Are we setting or reseting the collision flag?
  425. CButton *pCheckNoCollide = ( CButton* )GetDlgItem( ID_DISP_NOHULL_COLL );
  426. bool bReset = false;
  427. if ( !pCheckNoCollide->GetCheck() )
  428. {
  429. bReset = true;
  430. }
  431. // Get faces with displacements and toggle the collide flag.
  432. int iFace = 0;
  433. for( iFace = 0; iFace < nFaceCount; iFace++ )
  434. {
  435. CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
  436. if( !pFace || !pFace->HasDisp() )
  437. continue;
  438. EditDispHandle_t hDisp = pFace->GetDisp();
  439. CMapDisp *pDisp = EditDispMgr()->GetDisp( hDisp );
  440. if( pDisp )
  441. {
  442. if ( bReset )
  443. {
  444. int nFlags = pDisp->GetFlags();
  445. nFlags &= ~CCoreDispInfo::SURF_NOHULL_COLL;
  446. pDisp->SetFlags( nFlags );
  447. }
  448. else
  449. {
  450. int nFlags = pDisp->GetFlags();
  451. nFlags |= CCoreDispInfo::SURF_NOHULL_COLL;
  452. pDisp->SetFlags( nFlags );
  453. }
  454. }
  455. }
  456. }
  457. }
  458. //-----------------------------------------------------------------------------
  459. //-----------------------------------------------------------------------------
  460. void CFaceEditDispPage::OnCheckNoRayCollide( void )
  461. {
  462. // Toggle marked faces as collidable.
  463. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  464. if( pSheet )
  465. {
  466. // Check for a face list.
  467. int nFaceCount = pSheet->GetFaceListCount();
  468. if( nFaceCount == 0 )
  469. return;
  470. // Are we setting or reseting the collision flag?
  471. CButton *pCheckNoCollide = ( CButton* )GetDlgItem( ID_DISP_NORAY_COLL );
  472. bool bReset = false;
  473. if ( !pCheckNoCollide->GetCheck() )
  474. {
  475. bReset = true;
  476. }
  477. // Get faces with displacements and toggle the collide flag.
  478. int iFace = 0;
  479. for( iFace = 0; iFace < nFaceCount; iFace++ )
  480. {
  481. CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
  482. if( !pFace || !pFace->HasDisp() )
  483. continue;
  484. EditDispHandle_t hDisp = pFace->GetDisp();
  485. CMapDisp *pDisp = EditDispMgr()->GetDisp( hDisp );
  486. if( pDisp )
  487. {
  488. if ( bReset )
  489. {
  490. int nFlags = pDisp->GetFlags();
  491. nFlags &= ~CCoreDispInfo::SURF_NORAY_COLL;
  492. pDisp->SetFlags( nFlags );
  493. }
  494. else
  495. {
  496. int nFlags = pDisp->GetFlags();
  497. nFlags |= CCoreDispInfo::SURF_NORAY_COLL;
  498. pDisp->SetFlags( nFlags );
  499. }
  500. }
  501. }
  502. }
  503. }
  504. //-----------------------------------------------------------------------------
  505. //-----------------------------------------------------------------------------
  506. void CFaceEditDispPage::SetTool( unsigned int tool )
  507. {
  508. if( m_uiTool == FACEEDITTOOL_PAINTGEO )
  509. {
  510. m_PaintDistDlg.DestroyWindow();
  511. }
  512. if( m_uiTool == FACEEDITTOOL_PAINTSCULPT )
  513. {
  514. m_PaintSculptDlg.DestroyWindow();
  515. }
  516. if( m_uiTool == FACEEDITTOOL_PAINTDATA )
  517. {
  518. m_PaintDataDlg.DestroyWindow();
  519. }
  520. if ( ( m_uiTool == FACEEDITTOOL_TAG_WALK ) ||
  521. ( m_uiTool == FACEEDITTOOL_TAG_BUILD ) ||
  522. ( m_uiTool == FACEEDITTOOL_TAG_REMOVE ) )
  523. {
  524. ResetForceShows();
  525. }
  526. m_uiTool = tool;
  527. // set button checked
  528. CButton *pbuttonSelect = ( CButton* )GetDlgItem( ID_DISP_SELECT2 );
  529. CButton *pbuttonCreate = ( CButton* )GetDlgItem( ID_DISP_CREATE );
  530. CButton *pbuttonDestroy = ( CButton* )GetDlgItem( ID_DISP_DESTROY );
  531. CButton *pbuttonPaintGeo = ( CButton* )GetDlgItem( ID_DISP_PAINT_GEO );
  532. CButton *pbuttonPaintSculpt = ( CButton* )GetDlgItem( ID_DISP_SCULPT_PAINT );
  533. CButton *pbuttonPaintData = ( CButton* )GetDlgItem( ID_DISP_PAINT_DATA );
  534. CButton *pbuttonSubdiv = ( CButton* )GetDlgItem( ID_DISP_SUBDIVIDE );
  535. CButton *pbuttonSew = ( CButton* )GetDlgItem( ID_DISP_SEW );
  536. CButton *pbuttonNoise = ( CButton* )GetDlgItem( ID_DISP_NOISE );
  537. CButton *pButtonWalk = ( CButton* )GetDlgItem( ID_DISP_TAG_WALK );
  538. CButton *pButtonBuild = ( CButton* )GetDlgItem( ID_DISP_TAG_BUILD );
  539. CButton *pButtonRemove = ( CButton* )GetDlgItem( ID_DISP_TAG_REMOVE );
  540. pbuttonSelect->SetCheck( m_uiTool == FACEEDITTOOL_SELECT );
  541. pbuttonCreate->SetCheck( m_uiTool == FACEEDITTOOL_CREATE );
  542. pbuttonDestroy->SetCheck( m_uiTool == FACEEDITTOOL_DESTROY );
  543. pbuttonPaintGeo->SetCheck( m_uiTool == FACEEDITTOOL_PAINTGEO );
  544. pbuttonPaintSculpt->SetCheck( m_uiTool == FACEEDITTOOL_PAINTSCULPT );
  545. pbuttonPaintData->SetCheck( m_uiTool == FACEEDITTOOL_PAINTDATA );
  546. pbuttonSubdiv->SetCheck( m_uiTool == FACEEDITTOOL_SUBDIV );
  547. pbuttonSew->SetCheck( m_uiTool == FACEEDITTOOL_SEW );
  548. pbuttonNoise->SetCheck( m_uiTool == FACEEDITTOOL_NOISE );
  549. pButtonWalk->SetCheck( m_uiTool == FACEEDITTOOL_TAG_WALK );
  550. pButtonBuild->SetCheck( m_uiTool == FACEEDITTOOL_TAG_BUILD );
  551. pButtonRemove->SetCheck( m_uiTool == FACEEDITTOOL_TAG_REMOVE );
  552. // Update button state, etc.
  553. UpdateDialogData();
  554. }
  555. //-----------------------------------------------------------------------------
  556. //-----------------------------------------------------------------------------
  557. void CFaceEditDispPage::OnButtonSelect( void )
  558. {
  559. // set selection tool
  560. SetTool( FACEEDITTOOL_SELECT );
  561. // get the displacement tool and set selection tool active
  562. CToolDisplace *pDispTool = GetDisplacementTool();
  563. if( pDispTool )
  564. {
  565. pDispTool->SetTool( DISPTOOL_SELECT );
  566. UpdateDialogData();
  567. }
  568. }
  569. //-----------------------------------------------------------------------------
  570. //-----------------------------------------------------------------------------
  571. void CFaceEditDispPage::OnButtonCreate( void )
  572. {
  573. // set creation tool
  574. SetTool( FACEEDITTOOL_CREATE );
  575. //
  576. // "create" all selected faces
  577. //
  578. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  579. if( pSheet )
  580. {
  581. // check for faces to create
  582. int faceCount = pSheet->GetFaceListCount();
  583. if( faceCount == 0 )
  584. return;
  585. //
  586. // open the dialog and get the desired creation power
  587. //
  588. if( m_CreateDlg.DoModal() == IDCANCEL )
  589. {
  590. // reset selection tool
  591. SetTool( FACEEDITTOOL_SELECT );
  592. return;
  593. }
  594. // clamped the "power" (range [2..4])
  595. int power = m_CreateDlg.m_Power;
  596. //
  597. // get the active map doc and displacement manager
  598. //
  599. IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
  600. if( !pDispMgr )
  601. return;
  602. //
  603. // create faces
  604. //
  605. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  606. {
  607. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  608. if( !pFace )
  609. continue;
  610. // make sure the face has the appropriate point count
  611. if( pFace->GetPointCount() != 4 )
  612. continue;
  613. // check to see if the face already has a displacement,
  614. // ignore it if so
  615. if( pFace->HasDisp() )
  616. continue;
  617. EditDispHandle_t dispHandle = EditDispMgr()->Create();
  618. CMapDisp *pDisp = EditDispMgr()->GetDisp( dispHandle );
  619. if( pDisp )
  620. {
  621. // set dependencies
  622. pFace->SetDisp( dispHandle );
  623. pDisp->SetParent( pFace );
  624. // get surface data
  625. pDisp->InitDispSurfaceData( pFace, true );
  626. // add displacement to world list (this should be done automatically!)
  627. pDispMgr->AddToWorld( dispHandle );
  628. // create a new displacement surface based on data
  629. pDisp->InitData( power );
  630. pDisp->Create();
  631. // Post a change to the solid.
  632. CMapSolid *pSolid = ( CMapSolid* )pFace->GetParent();
  633. pSolid->PostUpdate( Notify_Changed );
  634. // Update autovisgroups for the solid
  635. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  636. pDoc->RemoveFromAutoVisGroups( pSolid );
  637. pDoc->AddToAutoVisGroup( pSolid );
  638. }
  639. }
  640. }
  641. // reset selection tool
  642. SetTool( FACEEDITTOOL_SELECT );
  643. // update
  644. PostToolUpdate();
  645. }
  646. //-----------------------------------------------------------------------------
  647. //-----------------------------------------------------------------------------
  648. void CFaceEditDispPage::OnButtonDestroy( void )
  649. {
  650. // set destruction tool
  651. SetTool( FACEEDITTOOL_DESTROY );
  652. //
  653. // "destroy" all selected faces
  654. //
  655. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  656. if( pSheet )
  657. {
  658. // check for faces to destroy
  659. int faceCount = pSheet->GetFaceListCount();
  660. if( faceCount == 0 )
  661. return;
  662. // get the displacement manager
  663. IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
  664. if( !pDispMgr )
  665. return;
  666. // mark history position
  667. pDispMgr->PreUndo( "Displacement Destroy" );
  668. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  669. {
  670. // get the current displacement
  671. // get current displacement
  672. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  673. if( !pFace || !pFace->HasDisp() )
  674. continue;
  675. CMapSolid *pSolid = ( CMapSolid* )pFace->GetParent();
  676. if ( pSolid && !pSolid->IsVisible() )
  677. continue;
  678. EditDispHandle_t handle = pFace->GetDisp();
  679. // setup for undo
  680. pDispMgr->Undo( handle, false );
  681. pDispMgr->RemoveFromWorld( handle );
  682. pFace->SetDisp( EDITDISPHANDLE_INVALID );
  683. // Post a change to the solid.
  684. pSolid->PostUpdate( Notify_Changed );
  685. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  686. pDoc->RemoveFromAutoVisGroups( pSolid );
  687. pDoc->AddToAutoVisGroup( pSolid );
  688. }
  689. pDispMgr->PostUndo();
  690. }
  691. // reset selection tool
  692. SetTool( FACEEDITTOOL_SELECT );
  693. // update
  694. PostToolUpdate();
  695. }
  696. //-----------------------------------------------------------------------------
  697. //-----------------------------------------------------------------------------
  698. void CFaceEditDispPage::OnButtonNoise( void )
  699. {
  700. // set noise tool
  701. SetTool( FACEEDITTOOL_NOISE );
  702. //
  703. // "noise" all selected faces
  704. //
  705. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  706. if( pSheet )
  707. {
  708. // check for faces to add noise to
  709. int faceCount = pSheet->GetFaceListCount();
  710. if( faceCount == 0 )
  711. return;
  712. //
  713. // open the dialog and get the desired noise parameters
  714. //
  715. if( m_NoiseDlg.DoModal() == IDCANCEL )
  716. {
  717. // reset selection tool
  718. SetTool( FACEEDITTOOL_SELECT );
  719. return;
  720. }
  721. // mark for undo
  722. // get the displacement manager
  723. IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
  724. if( !pDispMgr )
  725. return;
  726. pDispMgr->PreUndo( "Displacement Noise" );
  727. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  728. {
  729. // get current displacement
  730. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  731. if( pFace )
  732. {
  733. if( pFace->HasDisp() )
  734. {
  735. EditDispHandle_t handle = pFace->GetDisp();
  736. // setup for undo
  737. pDispMgr->Undo( handle, false );
  738. CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
  739. pDisp->ApplyNoise( m_NoiseDlg.m_Min, m_NoiseDlg.m_Max, 1.0f );
  740. }
  741. }
  742. }
  743. pDispMgr->PostUndo();
  744. }
  745. // reset selection tool
  746. SetTool( FACEEDITTOOL_SELECT );
  747. // update
  748. PostToolUpdate();
  749. }
  750. //-----------------------------------------------------------------------------
  751. //-----------------------------------------------------------------------------
  752. void CFaceEditDispPage::OnButtonSubdivide( void )
  753. {
  754. // set subdivision tool
  755. SetTool( FACEEDITTOOL_SUBDIV );
  756. //
  757. // create selection list
  758. //
  759. IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
  760. if( !pDispMgr )
  761. return;
  762. pDispMgr->SelectClear();
  763. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  764. if( pSheet )
  765. {
  766. // check for faces to subdivide
  767. int faceCount = pSheet->GetFaceListCount();
  768. if( faceCount == 0 )
  769. return;
  770. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  771. {
  772. // get current displacement
  773. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  774. if( pFace )
  775. {
  776. if( pFace->HasDisp() )
  777. {
  778. EditDispHandle_t handle = pFace->GetDisp();
  779. pDispMgr->AddToSelect( handle );
  780. CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
  781. pDisp->ResetTexelHitIndex();
  782. }
  783. }
  784. }
  785. }
  786. // subdivide
  787. pDispMgr->CatmullClarkSubdivide();
  788. // reset selection tool
  789. SetTool( FACEEDITTOOL_SELECT );
  790. // update
  791. PostToolUpdate();
  792. }
  793. //-----------------------------------------------------------------------------
  794. //-----------------------------------------------------------------------------
  795. void CFaceEditDispPage::OnButtonSew( void )
  796. {
  797. // set sew tool
  798. SetTool( FACEEDITTOOL_SEW );
  799. //
  800. // "sew" all selected faces
  801. //
  802. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  803. if( pSheet )
  804. {
  805. // check for faces to sew
  806. int faceCount = pSheet->GetFaceListCount();
  807. if( faceCount == 0 )
  808. return;
  809. // get the displacement manager
  810. IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
  811. if( !pDispMgr )
  812. return;
  813. // mark history position
  814. pDispMgr->PreUndo( "Displacement Sewing" );
  815. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  816. {
  817. // get the current displacement
  818. // get current displacement
  819. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  820. if( pFace )
  821. {
  822. if( pFace->HasDisp() )
  823. {
  824. EditDispHandle_t handle = pFace->GetDisp();
  825. // setup for undo
  826. pDispMgr->Undo( handle, false );
  827. }
  828. }
  829. }
  830. pDispMgr->PostUndo();
  831. // sew faces
  832. FaceListSewEdges();
  833. // update the parents - force a rebuild
  834. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  835. {
  836. // get current displacement
  837. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  838. if( pFace )
  839. {
  840. if( pFace->HasDisp() )
  841. {
  842. CMapSolid *pSolid = ( CMapSolid* )pFace->GetParent();
  843. pSolid->PostUpdate( Notify_Rebuild );
  844. }
  845. }
  846. }
  847. }
  848. // reset selection tool
  849. SetTool( FACEEDITTOOL_SELECT );
  850. // update
  851. PostToolUpdate();
  852. }
  853. //-----------------------------------------------------------------------------
  854. //-----------------------------------------------------------------------------
  855. void CFaceEditDispPage::OnButtonPaintGeo( void )
  856. {
  857. // set selection tool
  858. SetTool( FACEEDITTOOL_PAINTGEO );
  859. // get the displacement tool and set the paint tool active
  860. CToolDisplace *pDispTool = GetDisplacementTool();
  861. if( pDispTool )
  862. {
  863. pDispTool->SetTool( DISPTOOL_PAINT );
  864. UpdateDialogData();
  865. }
  866. if( !m_PaintDistDlg.Create( IDD_DISP_PAINT_DIST, this ) )
  867. return;
  868. m_PaintDistDlg.ShowWindow( SW_SHOW );
  869. }
  870. //-----------------------------------------------------------------------------
  871. // Purpose: handles the user clicking on the sculpt button
  872. //-----------------------------------------------------------------------------
  873. void CFaceEditDispPage::OnBnClickedDispSculptPaint( )
  874. {
  875. // set selection tool
  876. SetTool( FACEEDITTOOL_PAINTSCULPT );
  877. // get the displacement tool and set the paint tool active
  878. CToolDisplace *pDispTool = GetDisplacementTool();
  879. if( pDispTool )
  880. {
  881. pDispTool->SetTool( DISPTOOL_PAINT_SCULPT );
  882. UpdateDialogData();
  883. }
  884. if( !m_PaintSculptDlg.Create( IDD_DISP_PAINT_SCULPT, this ) )
  885. return;
  886. m_PaintSculptDlg.ShowWindow( SW_SHOW );
  887. }
  888. //-----------------------------------------------------------------------------
  889. //-----------------------------------------------------------------------------
  890. void CFaceEditDispPage::OnButtonPaintData( void )
  891. {
  892. // set selection tool
  893. SetTool( FACEEDITTOOL_PAINTDATA );
  894. // get the displacement tool and set the paint tool active
  895. CToolDisplace *pDispTool = GetDisplacementTool();
  896. if( pDispTool )
  897. {
  898. pDispTool->SetTool( DISPTOOL_PAINT );
  899. UpdateDialogData();
  900. }
  901. if( !m_PaintDataDlg.Create( IDD_DISP_PAINT_DATA, this ) )
  902. return;
  903. m_PaintDataDlg.ShowWindow( SW_SHOW );
  904. }
  905. //-----------------------------------------------------------------------------
  906. //-----------------------------------------------------------------------------
  907. void CFaceEditDispPage::OnButtonTagWalkable( void )
  908. {
  909. // Set walkalbe faces viewable -- if they are not already.
  910. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  911. if ( !pDoc )
  912. return;
  913. CToolDisplace *pDispTool = GetDisplacementTool();
  914. if( !pDispTool )
  915. return;
  916. // Toggle the functionality.
  917. if ( GetTool() == FACEEDITTOOL_TAG_WALK )
  918. {
  919. // Set the select tool.
  920. SetTool( FACEEDITTOOL_SELECT );
  921. pDispTool->SetTool( DISPTOOL_SELECT_DISP_FACE );
  922. if ( m_bForceShowWalkable )
  923. {
  924. pDoc->SetDispDrawWalkable( false );
  925. m_bForceShowWalkable = false;
  926. }
  927. }
  928. else
  929. {
  930. // Set the tag walkable tool.
  931. SetTool( FACEEDITTOOL_TAG_WALK );
  932. pDispTool->SetTool( DISPTOOL_TAG_WALKABLE );
  933. if ( !pDoc->IsDispDrawWalkable() )
  934. {
  935. pDoc->SetDispDrawWalkable( true );
  936. m_bForceShowWalkable = true;
  937. }
  938. }
  939. UpdateDialogData();
  940. }
  941. //-----------------------------------------------------------------------------
  942. //-----------------------------------------------------------------------------
  943. void CFaceEditDispPage::OnButtonTagBuildable( void )
  944. {
  945. // Set buildalbe faces viewable -- if they are not already.
  946. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  947. if ( !pDoc )
  948. return;
  949. CToolDisplace *pDispTool = GetDisplacementTool();
  950. if( !pDispTool )
  951. return;
  952. // Toggle the functionality.
  953. if ( GetTool() == FACEEDITTOOL_TAG_BUILD )
  954. {
  955. // Set the select tool.
  956. SetTool( FACEEDITTOOL_SELECT );
  957. pDispTool->SetTool( DISPTOOL_SELECT_DISP_FACE );
  958. if ( m_bForceShowBuildable )
  959. {
  960. pDoc->SetDispDrawBuildable( false );
  961. m_bForceShowBuildable = false;
  962. }
  963. }
  964. else
  965. {
  966. // Set the tag buildable tool.
  967. SetTool( FACEEDITTOOL_TAG_BUILD );
  968. pDispTool->SetTool( DISPTOOL_TAG_BUILDABLE );
  969. if ( !pDoc->IsDispDrawBuildable() )
  970. {
  971. pDoc->SetDispDrawBuildable( true );
  972. m_bForceShowBuildable = true;
  973. }
  974. }
  975. UpdateDialogData();
  976. }
  977. //-----------------------------------------------------------------------------
  978. // Purpose:
  979. //-----------------------------------------------------------------------------
  980. void CFaceEditDispPage::OnButtonTagRemove( void )
  981. {
  982. // Set removed faces viewable -- if they are not already.
  983. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  984. if ( !pDoc )
  985. return;
  986. CToolDisplace *pDispTool = GetDisplacementTool();
  987. if( !pDispTool )
  988. return;
  989. // Toggle the functionality.
  990. if ( GetTool() == FACEEDITTOOL_TAG_REMOVE )
  991. {
  992. // Set the select tool.
  993. SetTool( FACEEDITTOOL_SELECT );
  994. pDispTool->SetTool( DISPTOOL_SELECT_DISP_FACE );
  995. pDoc->SetDispDrawRemove( false );
  996. }
  997. else
  998. {
  999. // Set the tag remove tool.
  1000. SetTool( FACEEDITTOOL_TAG_REMOVE );
  1001. pDispTool->SetTool( DISPTOOL_TAG_REMOVE );
  1002. if ( !pDoc->IsDispDrawRemove() )
  1003. {
  1004. pDoc->SetDispDrawRemove( true );
  1005. }
  1006. }
  1007. UpdateDialogData();
  1008. }
  1009. //-----------------------------------------------------------------------------
  1010. // Purpose:
  1011. //-----------------------------------------------------------------------------
  1012. void CFaceEditDispPage::OnButtonInvertAlpha( void )
  1013. {
  1014. // Invert the alpha channel on all the selected displacements.
  1015. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  1016. if( pSheet )
  1017. {
  1018. int nFaceCount = pSheet->GetFaceListCount();
  1019. for( int iFace = 0; iFace < nFaceCount; ++iFace )
  1020. {
  1021. CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
  1022. if( pFace )
  1023. {
  1024. if( pFace->HasDisp() )
  1025. {
  1026. EditDispHandle_t handle = pFace->GetDisp();
  1027. CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
  1028. pDisp->InvertAlpha();
  1029. }
  1030. }
  1031. }
  1032. }
  1033. // Update
  1034. PostToolUpdate();
  1035. }
  1036. //-----------------------------------------------------------------------------
  1037. // Purpose: Select any displacement faces adjacent to the already-selected ones.
  1038. //-----------------------------------------------------------------------------
  1039. void CFaceEditDispPage::OnSelectAdjacent()
  1040. {
  1041. IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
  1042. bool bSelectedAny = false;
  1043. // For all selected displacements...
  1044. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  1045. if( !pSheet )
  1046. return;
  1047. // check for faces
  1048. int faceCount = pSheet->GetFaceListCount();
  1049. if( faceCount == 0 )
  1050. return;
  1051. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  1052. {
  1053. // get current displacement
  1054. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  1055. if( !pFace || !pFace->HasDisp() )
  1056. continue;
  1057. EditDispHandle_t handle = pFace->GetDisp();
  1058. CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
  1059. // Now test all other disps in the world. We could do the code commented below, but then
  1060. // we won't be selecting adjacent neighbors of a different power.
  1061. //
  1062. //for ( int iEdge=0; iEdge < 4; iEdge++ )
  1063. //{
  1064. // EditDispHandle_t hNeighbor = pDisp->GetEdgeNeighbor( iEdge );
  1065. int totalDispCount = pDispMgr->WorldCount();
  1066. for ( int iTestDisp=0; iTestDisp < totalDispCount; iTestDisp++ )
  1067. {
  1068. int edge1[4], edge2[4];
  1069. CMapDisp *pNeighbor = pDispMgr->GetFromWorld( iTestDisp );
  1070. if ( !pNeighbor || pNeighbor == pDisp || pDispMgr->NumSharedPoints( pDisp, pNeighbor, edge1, edge2 ) != 2 )
  1071. continue;
  1072. // Get its map face and solid.
  1073. pFace = dynamic_cast< CMapFace* >( pNeighbor->GetParent() );
  1074. if ( !pFace || pFace->GetSelectionState() != SELECT_NONE )
  1075. continue;
  1076. CMapSolid *pSolid = dynamic_cast< CMapSolid* >( pFace->GetParent() );
  1077. if ( !pSolid || !pSolid->IsVisible() )
  1078. continue;
  1079. // The function we use to select a face wants the face's index into its CMapSolid, so we need that.
  1080. int iFaceIndex = pSolid->GetFaceIndex( pFace );
  1081. if ( iFaceIndex == -1 )
  1082. continue;
  1083. // Finally, select the face.
  1084. pSheet->ClickFace( pSolid, iFaceIndex, CFaceEditSheet::cfSelect, CFaceEditSheet::ModeSelect );
  1085. bSelectedAny = true;
  1086. }
  1087. }
  1088. if ( bSelectedAny )
  1089. {
  1090. CMapDoc::GetActiveMapDoc()->UpdateAllViews( MAPVIEW_UPDATE_TOOL );
  1091. }
  1092. }
  1093. //-----------------------------------------------------------------------------
  1094. // Resample
  1095. //-----------------------------------------------------------------------------
  1096. void CFaceEditDispPage::UpdatePower( CMapDisp *pDisp )
  1097. {
  1098. // input check
  1099. if( !pDisp )
  1100. return;
  1101. //
  1102. // get the power from the power edit box
  1103. //
  1104. CString strPower;
  1105. GetDlgItemText( ID_DISP_POWER, strPower );
  1106. int power = atoi( strPower );
  1107. if( power < 2 ) { power = 2; }
  1108. if( power > 4 ) { power = 4; }
  1109. // check for a change and resample if need be
  1110. if( power != pDisp->GetPower() )
  1111. {
  1112. pDisp->Resample( power );
  1113. }
  1114. }
  1115. //-----------------------------------------------------------------------------
  1116. //-----------------------------------------------------------------------------
  1117. void CFaceEditDispPage::UpdateElevation( CMapDisp *pDisp )
  1118. {
  1119. // input check
  1120. if( !pDisp )
  1121. return;
  1122. //
  1123. // get current elevation value
  1124. //
  1125. CString strElevation;
  1126. GetDlgItemText( ID_DISP_ELEVATION, strElevation );
  1127. int elevation = atof( strElevation );
  1128. // check for change and set new elevation if need be
  1129. if( elevation != pDisp->GetElevation() )
  1130. {
  1131. pDisp->Elevate( elevation );
  1132. }
  1133. }
  1134. //-----------------------------------------------------------------------------
  1135. // Purpose:
  1136. // Input : pNMHDR -
  1137. // pResult -
  1138. //-----------------------------------------------------------------------------
  1139. void CFaceEditDispPage::OnSpinUpDown( NMHDR *pNMHDR, LRESULT *pResult )
  1140. {
  1141. //
  1142. // get scroll up down edit box
  1143. //
  1144. NM_UPDOWN *pNMUpDown = ( NM_UPDOWN* )pNMHDR;
  1145. switch( pNMUpDown->hdr.idFrom )
  1146. {
  1147. case ID_SPIN_DISP_POWER:
  1148. {
  1149. CEdit *pEdit = ( CEdit* )GetDlgItem( ID_DISP_POWER );
  1150. CString strPower;
  1151. pEdit->GetWindowText( strPower );
  1152. int power = atoi( strPower );
  1153. power += ( -pNMUpDown->iDelta );
  1154. if( power < 2 ) { power = 2; }
  1155. if( power > 4 ) { power = 4; }
  1156. strPower.Format( "%d", power );
  1157. pEdit->SetWindowText( strPower );
  1158. *pResult = 0;
  1159. break;
  1160. }
  1161. case ID_SPIN_DISP_ELEVATION:
  1162. {
  1163. CEdit *pEdit = ( CEdit* )GetDlgItem( ID_DISP_ELEVATION );
  1164. CString strElevation;
  1165. pEdit->GetWindowText( strElevation );
  1166. float elevation = atof( strElevation );
  1167. elevation += 0.5f * ( -pNMUpDown->iDelta );
  1168. strElevation.Format( "%4.2f", elevation );
  1169. pEdit->SetWindowText( strElevation );
  1170. *pResult = 0;
  1171. break;
  1172. }
  1173. }
  1174. }
  1175. //-----------------------------------------------------------------------------
  1176. //-----------------------------------------------------------------------------
  1177. void CFaceEditDispPage::UpdateScale( CMapDisp *pDisp )
  1178. {
  1179. if( !pDisp )
  1180. return;
  1181. //
  1182. // get the current scale value
  1183. //
  1184. CString strScale;
  1185. GetDlgItemText( ID_DISP_SCALE, strScale );
  1186. float scale = atof( strScale );
  1187. // check for change and set new scale if need be
  1188. if( scale != pDisp->GetScale() )
  1189. {
  1190. pDisp->Scale( scale );
  1191. }
  1192. }
  1193. //-----------------------------------------------------------------------------
  1194. //-----------------------------------------------------------------------------
  1195. void CFaceEditDispPage::OnButtonApply( void )
  1196. {
  1197. //
  1198. // "create" all selected faces
  1199. //
  1200. CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
  1201. if( pSheet )
  1202. {
  1203. int faceCount = pSheet->GetFaceListCount();
  1204. for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
  1205. {
  1206. // get current face
  1207. CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
  1208. if( pFace )
  1209. {
  1210. if( pFace->HasDisp() )
  1211. {
  1212. EditDispHandle_t handle = pFace->GetDisp();
  1213. CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
  1214. // update attribs
  1215. UpdatePower( pDisp );
  1216. UpdateElevation( pDisp );
  1217. UpdateScale( pDisp );
  1218. }
  1219. }
  1220. }
  1221. }
  1222. // update
  1223. PostToolUpdate();
  1224. }
  1225. //-----------------------------------------------------------------------------
  1226. //-----------------------------------------------------------------------------
  1227. void CFaceEditDispPage::CloseAllDialogs( void )
  1228. {
  1229. if( m_uiTool == FACEEDITTOOL_PAINTGEO )
  1230. {
  1231. m_PaintDistDlg.DestroyWindow();
  1232. }
  1233. if( m_uiTool == FACEEDITTOOL_PAINTSCULPT )
  1234. {
  1235. m_PaintSculptDlg.DestroyWindow();
  1236. }
  1237. if( m_uiTool == FACEEDITTOOL_PAINTDATA )
  1238. {
  1239. m_PaintDataDlg.DestroyWindow();
  1240. }
  1241. }
  1242. //-----------------------------------------------------------------------------
  1243. //-----------------------------------------------------------------------------
  1244. void CFaceEditDispPage::ResetForceShows( void )
  1245. {
  1246. // Get the active map doc.
  1247. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  1248. // Walkable
  1249. if ( m_bForceShowWalkable )
  1250. {
  1251. if ( pDoc )
  1252. {
  1253. pDoc->SetDispDrawWalkable( false );
  1254. }
  1255. m_bForceShowWalkable = false;
  1256. }
  1257. // Buildable
  1258. if ( m_bForceShowBuildable )
  1259. {
  1260. if ( pDoc )
  1261. {
  1262. pDoc->SetDispDrawBuildable( false );
  1263. }
  1264. m_bForceShowBuildable = false;
  1265. }
  1266. // Always force this off!
  1267. if ( pDoc )
  1268. {
  1269. pDoc->SetDispDrawRemove( false );
  1270. }
  1271. }
  1272. //-----------------------------------------------------------------------------
  1273. //-----------------------------------------------------------------------------
  1274. BOOL CFaceEditDispPage::OnSetActive( void )
  1275. {
  1276. ToolManager()->SetTool( TOOL_FACEEDIT_DISP );
  1277. // set the selection as the tool to use!!!
  1278. OnButtonSelect();
  1279. return CPropertyPage::OnSetActive();
  1280. }
  1281. //-----------------------------------------------------------------------------
  1282. //-----------------------------------------------------------------------------
  1283. BOOL CFaceEditDispPage::OnKillActive( void )
  1284. {
  1285. CloseAllDialogs();
  1286. ResetForceShows();
  1287. return TRUE;
  1288. }
  1289. //-----------------------------------------------------------------------------
  1290. //-----------------------------------------------------------------------------
  1291. BOOL CFaceEditDispPage::PreTranslateMessage( MSG *pMsg )
  1292. {
  1293. HACCEL hAccel = GetMainWnd()->GetAccelTable();
  1294. if( !(hAccel && ::TranslateAccelerator( GetMainWnd()->m_hWnd, hAccel, pMsg ) ) )
  1295. {
  1296. return CPropertyPage::PreTranslateMessage( pMsg );
  1297. }
  1298. else
  1299. {
  1300. return TRUE;
  1301. }
  1302. }