1489 lines
40 KiB
C++
1489 lines
40 KiB
C++
|
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
|||
|
//
|
|||
|
// Purpose:
|
|||
|
//
|
|||
|
// $NoKeywords: $
|
|||
|
//=============================================================================//
|
|||
|
|
|||
|
#include <stdafx.h>
|
|||
|
#include <afxcmn.h>
|
|||
|
#include "hammer.h"
|
|||
|
#include "MainFrm.h"
|
|||
|
#include "GlobalFunctions.h"
|
|||
|
#include "MapDoc.h"
|
|||
|
#include "FaceEdit_DispPage.h"
|
|||
|
#include "MapSolid.h"
|
|||
|
#include "MapFace.h"
|
|||
|
#include "MapDisp.h"
|
|||
|
#include "FaceEditSheet.h"
|
|||
|
#include "MapView3D.h"
|
|||
|
#include "History.h"
|
|||
|
#include "ToolDisplace.h"
|
|||
|
#include "ToolManager.h"
|
|||
|
#include "DispSew.h"
|
|||
|
#include "builddisp.h"
|
|||
|
|
|||
|
// memdbgon must be the last include file in a .cpp file!!!
|
|||
|
#include <tier0/memdbgon.h>
|
|||
|
|
|||
|
CToolDisplace* GetDisplacementTool() { return dynamic_cast<CToolDisplace*>(ToolManager()->GetToolForID(TOOL_FACEEDIT_DISP)); }
|
|||
|
|
|||
|
//=============================================================================
|
|||
|
|
|||
|
IMPLEMENT_DYNAMIC( CFaceEditDispPage, CPropertyPage )
|
|||
|
|
|||
|
BEGIN_MESSAGE_MAP( CFaceEditDispPage, CPropertyPage )
|
|||
|
//{{AFX_MSG_MAP( CFaceEditDispPage )
|
|||
|
ON_BN_CLICKED( ID_DISP_MASK_SELECT, OnCheckMaskSelect )
|
|||
|
ON_BN_CLICKED( ID_DISP_MASK_GRID, OnCheckMaskGrid )
|
|||
|
|
|||
|
ON_BN_CLICKED( ID_DISP_NOPHYSICS_COLL, OnCheckNoPhysicsCollide )
|
|||
|
ON_BN_CLICKED( ID_DISP_NOHULL_COLL, OnCheckNoHullCollide )
|
|||
|
ON_BN_CLICKED( ID_DISP_NORAY_COLL, OnCheckNoRayCollide )
|
|||
|
|
|||
|
ON_BN_CLICKED( ID_DISP_SELECT2, OnButtonSelect )
|
|||
|
ON_BN_CLICKED( ID_DISP_CREATE, OnButtonCreate )
|
|||
|
ON_BN_CLICKED( ID_DISP_DESTROY, OnButtonDestroy )
|
|||
|
ON_BN_CLICKED( ID_DISP_NOISE, OnButtonNoise )
|
|||
|
ON_BN_CLICKED( ID_DISP_SUBDIVIDE, OnButtonSubdivide )
|
|||
|
ON_BN_CLICKED( ID_DISP_SEW, OnButtonSew )
|
|||
|
ON_BN_CLICKED( ID_DISP_PAINT_GEO, OnButtonPaintGeo )
|
|||
|
ON_BN_CLICKED( ID_DISP_PAINT_DATA, OnButtonPaintData )
|
|||
|
ON_BN_CLICKED( ID_DISP_TAG_WALK, OnButtonTagWalkable )
|
|||
|
ON_BN_CLICKED( ID_DISP_TAG_BUILD, OnButtonTagBuildable )
|
|||
|
ON_BN_CLICKED( ID_DISP_INVERT_ALPHA, OnButtonInvertAlpha )
|
|||
|
ON_BN_CLICKED( IDC_SELECT_ADJACENT, OnSelectAdjacent )
|
|||
|
|
|||
|
ON_NOTIFY( UDN_DELTAPOS, ID_SPIN_DISP_POWER, OnSpinUpDown )
|
|||
|
ON_NOTIFY( UDN_DELTAPOS, ID_SPIN_DISP_ELEVATION, OnSpinUpDown )
|
|||
|
ON_BN_CLICKED( ID_DISP_APPLY, OnButtonApply )
|
|||
|
//}}AFX_MSG_MAP
|
|||
|
ON_BN_CLICKED(ID_DISP_SCULPT_PAINT, &CFaceEditDispPage::OnBnClickedDispSculptPaint)
|
|||
|
END_MESSAGE_MAP()
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: Constructor
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
CFaceEditDispPage::CFaceEditDispPage() : CPropertyPage( IDD )
|
|||
|
{
|
|||
|
m_uiTool = FACEEDITTOOL_SELECT;
|
|||
|
|
|||
|
m_bForceShowWalkable = false;
|
|||
|
m_bForceShowBuildable = false;
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: Deconstructor
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
CFaceEditDispPage::~CFaceEditDispPage()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
inline void CFaceEditDispPage::PostToolUpdate( void )
|
|||
|
{
|
|||
|
// update the mapdoc views
|
|||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
|||
|
if( pDoc )
|
|||
|
{
|
|||
|
pDoc->SetModifiedFlag();
|
|||
|
}
|
|||
|
|
|||
|
// update the dialogs data
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::ClickFace( CMapSolid *pSolid, int faceIndex, int cmd, int clickMode )
|
|||
|
{
|
|||
|
m_bIsEditable = ( pSolid ? pSolid->IsEditable() : true );
|
|||
|
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::UpdateEditControls( bool bAllDisps, bool bHasFace )
|
|||
|
{
|
|||
|
//
|
|||
|
// masks - always active!!
|
|||
|
//
|
|||
|
CButton *pcheckSelect = ( CButton* )GetDlgItem( ID_DISP_MASK_SELECT );
|
|||
|
CButton *pcheckGrid = ( CButton* )GetDlgItem( ID_DISP_MASK_GRID );
|
|||
|
pcheckSelect->EnableWindow( TRUE );
|
|||
|
pcheckGrid->EnableWindow( TRUE );
|
|||
|
|
|||
|
//
|
|||
|
// tool buttons
|
|||
|
//
|
|||
|
CButton *pbuttonSelect = ( CButton* )GetDlgItem( ID_DISP_SELECT2 );
|
|||
|
CButton *pbuttonCreate = ( CButton* )GetDlgItem( ID_DISP_CREATE );
|
|||
|
CButton *pbuttonDestroy = ( CButton* )GetDlgItem( ID_DISP_DESTROY );
|
|||
|
CButton *pbuttonPaintGeo = ( CButton* )GetDlgItem( ID_DISP_PAINT_GEO );
|
|||
|
CButton *pbuttonPaintSculpt = ( CButton* )GetDlgItem( ID_DISP_SCULPT_PAINT );
|
|||
|
CButton *pbuttonPaintData = ( CButton* )GetDlgItem( ID_DISP_PAINT_DATA );
|
|||
|
CButton *pbuttonSubdiv = ( CButton* )GetDlgItem( ID_DISP_SUBDIVIDE );
|
|||
|
CButton *pbuttonSew = ( CButton* )GetDlgItem( ID_DISP_SEW );
|
|||
|
CButton *pbuttonNoise = ( CButton* )GetDlgItem( ID_DISP_NOISE );
|
|||
|
CButton *pButtonWalk = ( CButton* )GetDlgItem( ID_DISP_TAG_WALK );
|
|||
|
CButton *pButtonBuild = ( CButton* )GetDlgItem( ID_DISP_TAG_BUILD );
|
|||
|
|
|||
|
pbuttonSelect->EnableWindow( TRUE );
|
|||
|
pbuttonCreate->EnableWindow( FALSE );
|
|||
|
pbuttonDestroy->EnableWindow( FALSE );
|
|||
|
pbuttonPaintGeo->EnableWindow( FALSE );
|
|||
|
pbuttonPaintSculpt->EnableWindow( FALSE );
|
|||
|
pbuttonPaintData->EnableWindow( FALSE );
|
|||
|
pbuttonSubdiv->EnableWindow( FALSE );
|
|||
|
pbuttonSew->EnableWindow( FALSE );
|
|||
|
pbuttonNoise->EnableWindow( FALSE );
|
|||
|
pButtonWalk->EnableWindow( TRUE );
|
|||
|
pButtonBuild->EnableWindow( TRUE );
|
|||
|
|
|||
|
//
|
|||
|
// attributes (displacement info)
|
|||
|
//
|
|||
|
CEdit *peditPower = ( CEdit* )GetDlgItem( ID_DISP_POWER );
|
|||
|
CSpinButtonCtrl *pspinPower = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_POWER );
|
|||
|
CEdit *peditElevation = ( CEdit* )GetDlgItem( ID_DISP_ELEVATION );
|
|||
|
CSpinButtonCtrl *pspinElevation = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_ELEVATION );
|
|||
|
CEdit *peditScale = ( CEdit* )GetDlgItem( ID_DISP_SCALE );
|
|||
|
CButton *pbuttonApply = ( CButton* )GetDlgItem( ID_DISP_APPLY );
|
|||
|
CButton *pbuttonInvertAlpha = ( CButton* )GetDlgItem( ID_DISP_INVERT_ALPHA );
|
|||
|
CButton *pCheckNoPhysicsColl = ( CButton* )GetDlgItem( ID_DISP_NOPHYSICS_COLL );
|
|||
|
CButton *pCheckNoHullColl = ( CButton* )GetDlgItem( ID_DISP_NOHULL_COLL );
|
|||
|
CButton *pCheckNoRayColl = ( CButton* )GetDlgItem( ID_DISP_NORAY_COLL );
|
|||
|
|
|||
|
peditPower->EnableWindow( FALSE );
|
|||
|
pspinPower->EnableWindow( FALSE );
|
|||
|
peditElevation->EnableWindow( FALSE );
|
|||
|
pspinElevation->EnableWindow( FALSE );
|
|||
|
peditScale->EnableWindow( FALSE );
|
|||
|
pbuttonApply->EnableWindow( FALSE );
|
|||
|
pbuttonInvertAlpha->EnableWindow( FALSE );
|
|||
|
pCheckNoPhysicsColl->EnableWindow( FALSE );
|
|||
|
pCheckNoHullColl->EnableWindow( FALSE );
|
|||
|
pCheckNoRayColl->EnableWindow( FALSE );
|
|||
|
|
|||
|
// if there aren't any faces selected then the only active item should be selection
|
|||
|
if( !bHasFace )
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// if not all selected faces are displacements then highlight only
|
|||
|
// SELECTION, CREATE, DESTROY, and SEW
|
|||
|
//
|
|||
|
if ( m_bIsEditable )
|
|||
|
{
|
|||
|
if( !bAllDisps )
|
|||
|
{
|
|||
|
pbuttonCreate->EnableWindow( TRUE );
|
|||
|
pbuttonDestroy->EnableWindow( TRUE );
|
|||
|
pbuttonSew->EnableWindow( TRUE );
|
|||
|
}
|
|||
|
// highlight all tool buttons, but CREATE
|
|||
|
else
|
|||
|
{
|
|||
|
pbuttonDestroy->EnableWindow( TRUE );
|
|||
|
pbuttonPaintGeo->EnableWindow( TRUE );
|
|||
|
pbuttonPaintSculpt->EnableWindow( TRUE );
|
|||
|
pbuttonPaintData->EnableWindow( TRUE );
|
|||
|
pbuttonSubdiv->EnableWindow( TRUE );
|
|||
|
pbuttonSew->EnableWindow( TRUE );
|
|||
|
pbuttonNoise->EnableWindow( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
// active attributes if in selection mode
|
|||
|
if( m_uiTool == FACEEDITTOOL_SELECT )
|
|||
|
{
|
|||
|
peditPower->EnableWindow( TRUE );
|
|||
|
pspinPower->EnableWindow( TRUE );
|
|||
|
peditElevation->EnableWindow( TRUE );
|
|||
|
pspinElevation->EnableWindow( TRUE );
|
|||
|
peditScale->EnableWindow( TRUE );
|
|||
|
pbuttonApply->EnableWindow( TRUE );
|
|||
|
pbuttonInvertAlpha->EnableWindow( TRUE );
|
|||
|
pCheckNoPhysicsColl->EnableWindow( TRUE );
|
|||
|
pCheckNoHullColl->EnableWindow( TRUE );
|
|||
|
pCheckNoRayColl->EnableWindow( TRUE );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::FillEditControls( bool bAllDisps )
|
|||
|
{
|
|||
|
CString strText;
|
|||
|
|
|||
|
//
|
|||
|
// if all selected face have displacements
|
|||
|
//
|
|||
|
if( bAllDisps )
|
|||
|
{
|
|||
|
int power = 0;
|
|||
|
bool bAllPower = true;
|
|||
|
|
|||
|
float elevation = 0.0f;
|
|||
|
bool bAllElevation = true;
|
|||
|
|
|||
|
float scale = 1.0f;
|
|||
|
bool bAllScale = true;
|
|||
|
|
|||
|
bool bAllNoPhysics = true;
|
|||
|
bool bAllNoHull = true;
|
|||
|
bool bAllNoRay = true;
|
|||
|
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount > 0 )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( 0 );
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
|
|||
|
|
|||
|
power = pDisp->GetPower();
|
|||
|
elevation = pDisp->GetElevation();
|
|||
|
scale = pDisp->GetScale();
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// test all faces for "equal" attributes
|
|||
|
//
|
|||
|
for( int faceIndex = 0; faceIndex < faceCount; faceIndex++ )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( faceIndex );
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
|
|||
|
|
|||
|
// test power, elevation, and scale
|
|||
|
if( power != pDisp->GetPower() ) { bAllPower = false; }
|
|||
|
if( elevation != pDisp->GetElevation() ) { bAllElevation = false; }
|
|||
|
if( scale != pDisp->GetScale() ) { bAllScale = false; }
|
|||
|
|
|||
|
if ( !pDisp->CheckFlags( CCoreDispInfo::SURF_NOPHYSICS_COLL ) ) { bAllNoPhysics = false; }
|
|||
|
if ( !pDisp->CheckFlags( CCoreDispInfo::SURF_NOHULL_COLL ) ) { bAllNoHull = false; }
|
|||
|
if ( !pDisp->CheckFlags( CCoreDispInfo::SURF_NORAY_COLL ) ) { bAllNoRay = false; }
|
|||
|
}
|
|||
|
|
|||
|
// set displacement power value to 3 - 9x9
|
|||
|
SetDlgItemText( ID_DISP_POWER, "" );
|
|||
|
if( bAllPower )
|
|||
|
{
|
|||
|
SetDlgItemInt( ID_DISP_POWER, power );
|
|||
|
}
|
|||
|
|
|||
|
// set elevation value
|
|||
|
SetDlgItemText( ID_DISP_ELEVATION, "" );
|
|||
|
if( bAllElevation )
|
|||
|
{
|
|||
|
strText.Format( "%4.2f", elevation );
|
|||
|
SetDlgItemText( ID_DISP_ELEVATION, strText );
|
|||
|
}
|
|||
|
|
|||
|
// set scale value
|
|||
|
SetDlgItemText( ID_DISP_SCALE, "" );
|
|||
|
if( bAllScale )
|
|||
|
{
|
|||
|
strText.Format( "%4.4f", scale );
|
|||
|
SetDlgItemText( ID_DISP_SCALE, strText );
|
|||
|
}
|
|||
|
|
|||
|
CButton *pCheckBox;
|
|||
|
pCheckBox = ( CButton* )GetDlgItem( ID_DISP_NOPHYSICS_COLL );
|
|||
|
pCheckBox->SetCheck( FALSE );
|
|||
|
if ( bAllNoPhysics )
|
|||
|
{
|
|||
|
pCheckBox->SetCheck( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
pCheckBox = ( CButton* )GetDlgItem( ID_DISP_NOHULL_COLL );
|
|||
|
pCheckBox->SetCheck( FALSE );
|
|||
|
if ( bAllNoHull )
|
|||
|
{
|
|||
|
pCheckBox->SetCheck( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
pCheckBox = ( CButton* )GetDlgItem( ID_DISP_NORAY_COLL );
|
|||
|
pCheckBox->SetCheck( FALSE );
|
|||
|
if ( bAllNoRay )
|
|||
|
{
|
|||
|
pCheckBox->SetCheck( TRUE );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// set initial displacement power value to 3 - 9x9
|
|||
|
CSpinButtonCtrl *pSpin = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_POWER );
|
|||
|
pSpin->SetPos( 0 );
|
|||
|
SetDlgItemInt( ID_DISP_POWER, 0 );
|
|||
|
|
|||
|
// set initial elevation value
|
|||
|
pSpin = ( CSpinButtonCtrl* )GetDlgItem( ID_SPIN_DISP_ELEVATION );
|
|||
|
pSpin->SetPos( 0 );
|
|||
|
SetDlgItemText( ID_DISP_ELEVATION, "" );
|
|||
|
|
|||
|
// set initial scale value
|
|||
|
SetDlgItemText( ID_DISP_SCALE, "" );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// get tool specific data for page
|
|||
|
//
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( pDispTool )
|
|||
|
{
|
|||
|
CButton *checkBox;
|
|||
|
checkBox = ( CButton* )GetDlgItem( ID_DISP_MASK_SELECT );
|
|||
|
checkBox->SetCheck( pDispTool->HasSelectMask() );
|
|||
|
checkBox = ( CButton* )GetDlgItem( ID_DISP_MASK_GRID );
|
|||
|
checkBox->SetCheck( pDispTool->HasGridMask() );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::UpdateDialogData( void )
|
|||
|
{
|
|||
|
bool bAllDisps = false;
|
|||
|
bool bHasFace = false;
|
|||
|
|
|||
|
//
|
|||
|
// get face and displacement info
|
|||
|
//
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount > 0 )
|
|||
|
{
|
|||
|
bHasFace = true;
|
|||
|
bAllDisps = true;
|
|||
|
}
|
|||
|
|
|||
|
for( int i = 0; i < faceCount; i++ )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( i );
|
|||
|
if( !pFace->HasDisp() )
|
|||
|
{
|
|||
|
bAllDisps = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// fill in edit controls
|
|||
|
FillEditControls( bAllDisps );
|
|||
|
|
|||
|
// update the edit controls
|
|||
|
UpdateEditControls( bAllDisps, bHasFace );
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::UpdatePaintDialogs( void )
|
|||
|
{
|
|||
|
m_PaintDistDlg.UpdateSpatialData();
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnCheckMaskSelect( void )
|
|||
|
{
|
|||
|
// get the displacement tool
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( pDispTool )
|
|||
|
{
|
|||
|
pDispTool->ToggleSelectMask();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnCheckMaskGrid( void )
|
|||
|
{
|
|||
|
// get the displacement tool
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( pDispTool )
|
|||
|
{
|
|||
|
pDispTool->ToggleGridMask();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnCheckNoPhysicsCollide( void )
|
|||
|
{
|
|||
|
// Toggle marked faces as collidable.
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// Check for a face list.
|
|||
|
int nFaceCount = pSheet->GetFaceListCount();
|
|||
|
if( nFaceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
// Are we setting or reseting the collision flag?
|
|||
|
CButton *pCheckNoCollide = ( CButton* )GetDlgItem( ID_DISP_NOPHYSICS_COLL );
|
|||
|
bool bReset = false;
|
|||
|
if ( !pCheckNoCollide->GetCheck() )
|
|||
|
{
|
|||
|
bReset = true;
|
|||
|
}
|
|||
|
|
|||
|
// Get faces with displacements and toggle the collide flag.
|
|||
|
int iFace = 0;
|
|||
|
for( iFace = 0; iFace < nFaceCount; iFace++ )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
|
|||
|
if( !pFace || !pFace->HasDisp() )
|
|||
|
continue;
|
|||
|
|
|||
|
EditDispHandle_t hDisp = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( hDisp );
|
|||
|
if( pDisp )
|
|||
|
{
|
|||
|
if ( bReset )
|
|||
|
{
|
|||
|
int nFlags = pDisp->GetFlags();
|
|||
|
nFlags &= ~CCoreDispInfo::SURF_NOPHYSICS_COLL;
|
|||
|
pDisp->SetFlags( nFlags );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int nFlags = pDisp->GetFlags();
|
|||
|
nFlags |= CCoreDispInfo::SURF_NOPHYSICS_COLL;
|
|||
|
pDisp->SetFlags( nFlags );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnCheckNoHullCollide( void )
|
|||
|
{
|
|||
|
// Toggle marked faces as collidable.
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// Check for a face list.
|
|||
|
int nFaceCount = pSheet->GetFaceListCount();
|
|||
|
if( nFaceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
// Are we setting or reseting the collision flag?
|
|||
|
CButton *pCheckNoCollide = ( CButton* )GetDlgItem( ID_DISP_NOHULL_COLL );
|
|||
|
bool bReset = false;
|
|||
|
if ( !pCheckNoCollide->GetCheck() )
|
|||
|
{
|
|||
|
bReset = true;
|
|||
|
}
|
|||
|
|
|||
|
// Get faces with displacements and toggle the collide flag.
|
|||
|
int iFace = 0;
|
|||
|
for( iFace = 0; iFace < nFaceCount; iFace++ )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
|
|||
|
if( !pFace || !pFace->HasDisp() )
|
|||
|
continue;
|
|||
|
|
|||
|
EditDispHandle_t hDisp = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( hDisp );
|
|||
|
if( pDisp )
|
|||
|
{
|
|||
|
if ( bReset )
|
|||
|
{
|
|||
|
int nFlags = pDisp->GetFlags();
|
|||
|
nFlags &= ~CCoreDispInfo::SURF_NOHULL_COLL;
|
|||
|
pDisp->SetFlags( nFlags );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int nFlags = pDisp->GetFlags();
|
|||
|
nFlags |= CCoreDispInfo::SURF_NOHULL_COLL;
|
|||
|
pDisp->SetFlags( nFlags );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnCheckNoRayCollide( void )
|
|||
|
{
|
|||
|
// Toggle marked faces as collidable.
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// Check for a face list.
|
|||
|
int nFaceCount = pSheet->GetFaceListCount();
|
|||
|
if( nFaceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
// Are we setting or reseting the collision flag?
|
|||
|
CButton *pCheckNoCollide = ( CButton* )GetDlgItem( ID_DISP_NORAY_COLL );
|
|||
|
bool bReset = false;
|
|||
|
if ( !pCheckNoCollide->GetCheck() )
|
|||
|
{
|
|||
|
bReset = true;
|
|||
|
}
|
|||
|
|
|||
|
// Get faces with displacements and toggle the collide flag.
|
|||
|
int iFace = 0;
|
|||
|
for( iFace = 0; iFace < nFaceCount; iFace++ )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
|
|||
|
if( !pFace || !pFace->HasDisp() )
|
|||
|
continue;
|
|||
|
|
|||
|
EditDispHandle_t hDisp = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( hDisp );
|
|||
|
if( pDisp )
|
|||
|
{
|
|||
|
if ( bReset )
|
|||
|
{
|
|||
|
int nFlags = pDisp->GetFlags();
|
|||
|
nFlags &= ~CCoreDispInfo::SURF_NORAY_COLL;
|
|||
|
pDisp->SetFlags( nFlags );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int nFlags = pDisp->GetFlags();
|
|||
|
nFlags |= CCoreDispInfo::SURF_NORAY_COLL;
|
|||
|
pDisp->SetFlags( nFlags );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::SetTool( unsigned int tool )
|
|||
|
{
|
|||
|
if( m_uiTool == FACEEDITTOOL_PAINTGEO )
|
|||
|
{
|
|||
|
m_PaintDistDlg.DestroyWindow();
|
|||
|
}
|
|||
|
|
|||
|
if( m_uiTool == FACEEDITTOOL_PAINTSCULPT )
|
|||
|
{
|
|||
|
m_PaintSculptDlg.DestroyWindow();
|
|||
|
}
|
|||
|
|
|||
|
if( m_uiTool == FACEEDITTOOL_PAINTDATA )
|
|||
|
{
|
|||
|
m_PaintDataDlg.DestroyWindow();
|
|||
|
}
|
|||
|
|
|||
|
if ( m_uiTool == FACEEDITTOOL_TAG_WALK )
|
|||
|
{
|
|||
|
ResetForceShows();
|
|||
|
}
|
|||
|
|
|||
|
if ( m_uiTool == FACEEDITTOOL_TAG_BUILD )
|
|||
|
{
|
|||
|
ResetForceShows();
|
|||
|
}
|
|||
|
|
|||
|
m_uiTool = tool;
|
|||
|
|
|||
|
// set button checked
|
|||
|
CButton *pbuttonSelect = ( CButton* )GetDlgItem( ID_DISP_SELECT2 );
|
|||
|
CButton *pbuttonCreate = ( CButton* )GetDlgItem( ID_DISP_CREATE );
|
|||
|
CButton *pbuttonDestroy = ( CButton* )GetDlgItem( ID_DISP_DESTROY );
|
|||
|
CButton *pbuttonPaintGeo = ( CButton* )GetDlgItem( ID_DISP_PAINT_GEO );
|
|||
|
CButton *pbuttonPaintSculpt = ( CButton* )GetDlgItem( ID_DISP_SCULPT_PAINT );
|
|||
|
CButton *pbuttonPaintData = ( CButton* )GetDlgItem( ID_DISP_PAINT_DATA );
|
|||
|
CButton *pbuttonSubdiv = ( CButton* )GetDlgItem( ID_DISP_SUBDIVIDE );
|
|||
|
CButton *pbuttonSew = ( CButton* )GetDlgItem( ID_DISP_SEW );
|
|||
|
CButton *pbuttonNoise = ( CButton* )GetDlgItem( ID_DISP_NOISE );
|
|||
|
CButton *pButtonWalk = ( CButton* )GetDlgItem( ID_DISP_TAG_WALK );
|
|||
|
CButton *pButtonBuild = ( CButton* )GetDlgItem( ID_DISP_TAG_BUILD );
|
|||
|
|
|||
|
pbuttonSelect->SetCheck( m_uiTool == FACEEDITTOOL_SELECT );
|
|||
|
pbuttonCreate->SetCheck( m_uiTool == FACEEDITTOOL_CREATE );
|
|||
|
pbuttonDestroy->SetCheck( m_uiTool == FACEEDITTOOL_DESTROY );
|
|||
|
pbuttonPaintGeo->SetCheck( m_uiTool == FACEEDITTOOL_PAINTGEO );
|
|||
|
pbuttonPaintSculpt->SetCheck( m_uiTool == FACEEDITTOOL_PAINTSCULPT );
|
|||
|
pbuttonPaintData->SetCheck( m_uiTool == FACEEDITTOOL_PAINTDATA );
|
|||
|
pbuttonSubdiv->SetCheck( m_uiTool == FACEEDITTOOL_SUBDIV );
|
|||
|
pbuttonSew->SetCheck( m_uiTool == FACEEDITTOOL_SEW );
|
|||
|
pbuttonNoise->SetCheck( m_uiTool == FACEEDITTOOL_NOISE );
|
|||
|
pButtonWalk->SetCheck( m_uiTool == FACEEDITTOOL_TAG_WALK );
|
|||
|
pButtonBuild->SetCheck( m_uiTool == FACEEDITTOOL_TAG_BUILD );
|
|||
|
|
|||
|
// Update button state, etc.
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonSelect( void )
|
|||
|
{
|
|||
|
// set selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
// get the displacement tool and set selection tool active
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( pDispTool )
|
|||
|
{
|
|||
|
pDispTool->SetTool( DISPTOOL_SELECT );
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonCreate( void )
|
|||
|
{
|
|||
|
// set creation tool
|
|||
|
SetTool( FACEEDITTOOL_CREATE );
|
|||
|
|
|||
|
//
|
|||
|
// "create" all selected faces
|
|||
|
//
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// check for faces to create
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// open the dialog and get the desired creation power
|
|||
|
//
|
|||
|
if( m_CreateDlg.DoModal() == IDCANCEL )
|
|||
|
{
|
|||
|
// reset selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// clamped the "power" (range [2..4])
|
|||
|
int power = m_CreateDlg.m_Power;
|
|||
|
|
|||
|
//
|
|||
|
// get the active map doc and displacement manager
|
|||
|
//
|
|||
|
IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
|
|||
|
if( !pDispMgr )
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// create faces
|
|||
|
//
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( !pFace )
|
|||
|
continue;
|
|||
|
|
|||
|
// make sure the face has the appropriate point count
|
|||
|
if( pFace->GetPointCount() != 4 )
|
|||
|
continue;
|
|||
|
|
|||
|
// check to see if the face already has a displacement,
|
|||
|
// ignore it if so
|
|||
|
if( pFace->HasDisp() )
|
|||
|
continue;
|
|||
|
|
|||
|
EditDispHandle_t dispHandle = EditDispMgr()->Create();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( dispHandle );
|
|||
|
if( pDisp )
|
|||
|
{
|
|||
|
// set dependencies
|
|||
|
pFace->SetDisp( dispHandle );
|
|||
|
pDisp->SetParent( pFace );
|
|||
|
|
|||
|
// get surface data
|
|||
|
pDisp->InitDispSurfaceData( pFace, true );
|
|||
|
|
|||
|
// add displacement to world list (this should be done automatically!)
|
|||
|
pDispMgr->AddToWorld( dispHandle );
|
|||
|
|
|||
|
// create a new displacement surface based on data
|
|||
|
pDisp->InitData( power );
|
|||
|
pDisp->Create();
|
|||
|
|
|||
|
// Post a change to the solid.
|
|||
|
CMapSolid *pSolid = ( CMapSolid* )pFace->GetParent();
|
|||
|
pSolid->PostUpdate( Notify_Changed );
|
|||
|
|
|||
|
// Update autovisgroups for the solid
|
|||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
|||
|
pDoc->RemoveFromAutoVisGroups( pSolid );
|
|||
|
pDoc->AddToAutoVisGroup( pSolid );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// reset selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
// update
|
|||
|
PostToolUpdate();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonDestroy( void )
|
|||
|
{
|
|||
|
// set destruction tool
|
|||
|
SetTool( FACEEDITTOOL_DESTROY );
|
|||
|
|
|||
|
//
|
|||
|
// "destroy" all selected faces
|
|||
|
//
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// check for faces to destroy
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
// get the displacement manager
|
|||
|
IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
|
|||
|
if( !pDispMgr )
|
|||
|
return;
|
|||
|
|
|||
|
// mark history position
|
|||
|
pDispMgr->PreUndo( "Displacement Destroy" );
|
|||
|
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
// get the current displacement
|
|||
|
// get current displacement
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( !pFace || !pFace->HasDisp() )
|
|||
|
continue;
|
|||
|
|
|||
|
CMapSolid *pSolid = ( CMapSolid* )pFace->GetParent();
|
|||
|
if ( pSolid && !pSolid->IsVisible() )
|
|||
|
continue;
|
|||
|
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
|
|||
|
// setup for undo
|
|||
|
pDispMgr->Undo( handle, false );
|
|||
|
|
|||
|
pDispMgr->RemoveFromWorld( handle );
|
|||
|
pFace->SetDisp( EDITDISPHANDLE_INVALID );
|
|||
|
|
|||
|
// Post a change to the solid.
|
|||
|
pSolid->PostUpdate( Notify_Changed );
|
|||
|
|
|||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
|||
|
pDoc->RemoveFromAutoVisGroups( pSolid );
|
|||
|
pDoc->AddToAutoVisGroup( pSolid );
|
|||
|
}
|
|||
|
|
|||
|
pDispMgr->PostUndo();
|
|||
|
}
|
|||
|
|
|||
|
// reset selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
// update
|
|||
|
PostToolUpdate();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonNoise( void )
|
|||
|
{
|
|||
|
// set noise tool
|
|||
|
SetTool( FACEEDITTOOL_NOISE );
|
|||
|
|
|||
|
//
|
|||
|
// "noise" all selected faces
|
|||
|
//
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// check for faces to add noise to
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// open the dialog and get the desired noise parameters
|
|||
|
//
|
|||
|
if( m_NoiseDlg.DoModal() == IDCANCEL )
|
|||
|
{
|
|||
|
// reset selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// mark for undo
|
|||
|
// get the displacement manager
|
|||
|
IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
|
|||
|
if( !pDispMgr )
|
|||
|
return;
|
|||
|
|
|||
|
pDispMgr->PreUndo( "Displacement Noise" );
|
|||
|
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
// get current displacement
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( pFace )
|
|||
|
{
|
|||
|
if( pFace->HasDisp() )
|
|||
|
{
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
|
|||
|
// setup for undo
|
|||
|
pDispMgr->Undo( handle, false );
|
|||
|
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
|
|||
|
pDisp->ApplyNoise( m_NoiseDlg.m_Min, m_NoiseDlg.m_Max, 1.0f );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pDispMgr->PostUndo();
|
|||
|
}
|
|||
|
|
|||
|
// reset selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
// update
|
|||
|
PostToolUpdate();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonSubdivide( void )
|
|||
|
{
|
|||
|
// set subdivision tool
|
|||
|
SetTool( FACEEDITTOOL_SUBDIV );
|
|||
|
|
|||
|
//
|
|||
|
// create selection list
|
|||
|
//
|
|||
|
IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
|
|||
|
if( !pDispMgr )
|
|||
|
return;
|
|||
|
|
|||
|
pDispMgr->SelectClear();
|
|||
|
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// check for faces to subdivide
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
// get current displacement
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( pFace )
|
|||
|
{
|
|||
|
if( pFace->HasDisp() )
|
|||
|
{
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
pDispMgr->AddToSelect( handle );
|
|||
|
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
|
|||
|
pDisp->ResetTexelHitIndex();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// subdivide
|
|||
|
pDispMgr->CatmullClarkSubdivide();
|
|||
|
|
|||
|
// reset selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
// update
|
|||
|
PostToolUpdate();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonSew( void )
|
|||
|
{
|
|||
|
// set sew tool
|
|||
|
SetTool( FACEEDITTOOL_SEW );
|
|||
|
|
|||
|
//
|
|||
|
// "sew" all selected faces
|
|||
|
//
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
// check for faces to sew
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
// get the displacement manager
|
|||
|
IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
|
|||
|
if( !pDispMgr )
|
|||
|
return;
|
|||
|
|
|||
|
// mark history position
|
|||
|
pDispMgr->PreUndo( "Displacement Sewing" );
|
|||
|
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
// get the current displacement
|
|||
|
// get current displacement
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( pFace )
|
|||
|
{
|
|||
|
if( pFace->HasDisp() )
|
|||
|
{
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
|
|||
|
// setup for undo
|
|||
|
pDispMgr->Undo( handle, false );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pDispMgr->PostUndo();
|
|||
|
|
|||
|
// sew faces
|
|||
|
FaceListSewEdges();
|
|||
|
|
|||
|
// update the parents - force a rebuild
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
// get current displacement
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( pFace )
|
|||
|
{
|
|||
|
if( pFace->HasDisp() )
|
|||
|
{
|
|||
|
CMapSolid *pSolid = ( CMapSolid* )pFace->GetParent();
|
|||
|
pSolid->PostUpdate( Notify_Rebuild );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// reset selection tool
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
|
|||
|
// update
|
|||
|
PostToolUpdate();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonPaintGeo( void )
|
|||
|
{
|
|||
|
// set selection tool
|
|||
|
SetTool( FACEEDITTOOL_PAINTGEO );
|
|||
|
|
|||
|
// get the displacement tool and set the paint tool active
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( pDispTool )
|
|||
|
{
|
|||
|
pDispTool->SetTool( DISPTOOL_PAINT );
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
if( !m_PaintDistDlg.Create( IDD_DISP_PAINT_DIST, this ) )
|
|||
|
return;
|
|||
|
|
|||
|
m_PaintDistDlg.ShowWindow( SW_SHOW );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: handles the user clicking on the sculpt button
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnBnClickedDispSculptPaint( )
|
|||
|
{
|
|||
|
// set selection tool
|
|||
|
SetTool( FACEEDITTOOL_PAINTSCULPT );
|
|||
|
|
|||
|
// get the displacement tool and set the paint tool active
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( pDispTool )
|
|||
|
{
|
|||
|
pDispTool->SetTool( DISPTOOL_PAINT_SCULPT );
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
if( !m_PaintSculptDlg.Create( IDD_DISP_PAINT_SCULPT, this ) )
|
|||
|
return;
|
|||
|
|
|||
|
m_PaintSculptDlg.ShowWindow( SW_SHOW );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonPaintData( void )
|
|||
|
{
|
|||
|
// set selection tool
|
|||
|
SetTool( FACEEDITTOOL_PAINTDATA );
|
|||
|
|
|||
|
// get the displacement tool and set the paint tool active
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( pDispTool )
|
|||
|
{
|
|||
|
pDispTool->SetTool( DISPTOOL_PAINT );
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
if( !m_PaintDataDlg.Create( IDD_DISP_PAINT_DATA, this ) )
|
|||
|
return;
|
|||
|
|
|||
|
m_PaintDataDlg.ShowWindow( SW_SHOW );
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonTagWalkable( void )
|
|||
|
{
|
|||
|
// Set walkalbe faces viewable -- if they are not already.
|
|||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
|||
|
if ( !pDoc )
|
|||
|
return;
|
|||
|
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( !pDispTool )
|
|||
|
return;
|
|||
|
|
|||
|
// Toggle the functionality.
|
|||
|
if ( GetTool() == FACEEDITTOOL_TAG_WALK )
|
|||
|
{
|
|||
|
// Set the select tool.
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
pDispTool->SetTool( DISPTOOL_SELECT_DISP_FACE );
|
|||
|
|
|||
|
if ( m_bForceShowWalkable )
|
|||
|
{
|
|||
|
pDoc->SetDispDrawWalkable( false );
|
|||
|
m_bForceShowWalkable = false;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Set the tag walkable tool.
|
|||
|
SetTool( FACEEDITTOOL_TAG_WALK );
|
|||
|
pDispTool->SetTool( DISPTOOL_TAG_WALKABLE );
|
|||
|
|
|||
|
if ( !pDoc->IsDispDrawWalkable() )
|
|||
|
{
|
|||
|
pDoc->SetDispDrawWalkable( true );
|
|||
|
m_bForceShowWalkable = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonTagBuildable( void )
|
|||
|
{
|
|||
|
// Set buildalbe faces viewable -- if they are not already.
|
|||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
|||
|
if ( !pDoc )
|
|||
|
return;
|
|||
|
|
|||
|
CToolDisplace *pDispTool = GetDisplacementTool();
|
|||
|
if( !pDispTool )
|
|||
|
return;
|
|||
|
|
|||
|
// Toggle the functionality.
|
|||
|
if ( GetTool() == FACEEDITTOOL_TAG_BUILD )
|
|||
|
{
|
|||
|
// Set the select tool.
|
|||
|
SetTool( FACEEDITTOOL_SELECT );
|
|||
|
pDispTool->SetTool( DISPTOOL_SELECT_DISP_FACE );
|
|||
|
|
|||
|
if ( m_bForceShowBuildable )
|
|||
|
{
|
|||
|
pDoc->SetDispDrawBuildable( false );
|
|||
|
m_bForceShowBuildable = false;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Set the tag walkable tool.
|
|||
|
SetTool( FACEEDITTOOL_TAG_BUILD );
|
|||
|
pDispTool->SetTool( DISPTOOL_TAG_BUILDABLE );
|
|||
|
|
|||
|
if ( !pDoc->IsDispDrawBuildable() )
|
|||
|
{
|
|||
|
pDoc->SetDispDrawBuildable( true );
|
|||
|
m_bForceShowBuildable = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
UpdateDialogData();
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose:
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonInvertAlpha( void )
|
|||
|
{
|
|||
|
// Invert the alpha channel on all the selected displacements.
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
int nFaceCount = pSheet->GetFaceListCount();
|
|||
|
for( int iFace = 0; iFace < nFaceCount; ++iFace )
|
|||
|
{
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( iFace );
|
|||
|
if( pFace )
|
|||
|
{
|
|||
|
if( pFace->HasDisp() )
|
|||
|
{
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
|
|||
|
pDisp->InvertAlpha();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Update
|
|||
|
PostToolUpdate();
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: Select any displacement faces adjacent to the already-selected ones.
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnSelectAdjacent()
|
|||
|
{
|
|||
|
IWorldEditDispMgr *pDispMgr = GetActiveWorldEditDispManager();
|
|||
|
|
|||
|
bool bSelectedAny = false;
|
|||
|
|
|||
|
// For all selected displacements...
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( !pSheet )
|
|||
|
return;
|
|||
|
|
|||
|
// check for faces
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
if( faceCount == 0 )
|
|||
|
return;
|
|||
|
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
// get current displacement
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( !pFace || !pFace->HasDisp() )
|
|||
|
continue;
|
|||
|
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
|
|||
|
|
|||
|
// Now test all other disps in the world. We could do the code commented below, but then
|
|||
|
// we won't be selecting adjacent neighbors of a different power.
|
|||
|
//
|
|||
|
//for ( int iEdge=0; iEdge < 4; iEdge++ )
|
|||
|
//{
|
|||
|
// EditDispHandle_t hNeighbor = pDisp->GetEdgeNeighbor( iEdge );
|
|||
|
|
|||
|
int totalDispCount = pDispMgr->WorldCount();
|
|||
|
for ( int iTestDisp=0; iTestDisp < totalDispCount; iTestDisp++ )
|
|||
|
{
|
|||
|
int edge1[4], edge2[4];
|
|||
|
CMapDisp *pNeighbor = pDispMgr->GetFromWorld( iTestDisp );
|
|||
|
if ( !pNeighbor || pNeighbor == pDisp || pDispMgr->NumSharedPoints( pDisp, pNeighbor, edge1, edge2 ) != 2 )
|
|||
|
continue;
|
|||
|
|
|||
|
// Get its map face and solid.
|
|||
|
CMapFace *pFace = dynamic_cast< CMapFace* >( pNeighbor->GetParent() );
|
|||
|
if ( !pFace || pFace->GetSelectionState() != SELECT_NONE )
|
|||
|
continue;
|
|||
|
|
|||
|
CMapSolid *pSolid = dynamic_cast< CMapSolid* >( pFace->GetParent() );
|
|||
|
if ( !pSolid || !pSolid->IsVisible() )
|
|||
|
continue;
|
|||
|
|
|||
|
// The function we use to select a face wants the face's index into its CMapSolid, so we need that.
|
|||
|
int iFaceIndex = pSolid->GetFaceIndex( pFace );
|
|||
|
if ( iFaceIndex == -1 )
|
|||
|
continue;
|
|||
|
|
|||
|
// Finally, select the face.
|
|||
|
pSheet->ClickFace( pSolid, iFaceIndex, CFaceEditSheet::cfSelect, CFaceEditSheet::ModeSelect );
|
|||
|
bSelectedAny = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( bSelectedAny )
|
|||
|
{
|
|||
|
CMapDoc::GetActiveMapDoc()->UpdateAllViews( MAPVIEW_UPDATE_TOOL );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Resample
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::UpdatePower( CMapDisp *pDisp )
|
|||
|
{
|
|||
|
// input check
|
|||
|
if( !pDisp )
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// get the power from the power edit box
|
|||
|
//
|
|||
|
CString strPower;
|
|||
|
GetDlgItemText( ID_DISP_POWER, strPower );
|
|||
|
int power = atoi( strPower );
|
|||
|
|
|||
|
if( power < 2 ) { power = 2; }
|
|||
|
if( power > 4 ) { power = 4; }
|
|||
|
|
|||
|
// check for a change and resample if need be
|
|||
|
if( power != pDisp->GetPower() )
|
|||
|
{
|
|||
|
pDisp->Resample( power );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::UpdateElevation( CMapDisp *pDisp )
|
|||
|
{
|
|||
|
// input check
|
|||
|
if( !pDisp )
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// get current elevation value
|
|||
|
//
|
|||
|
CString strElevation;
|
|||
|
GetDlgItemText( ID_DISP_ELEVATION, strElevation );
|
|||
|
int elevation = atof( strElevation );
|
|||
|
|
|||
|
// check for change and set new elevation if need be
|
|||
|
if( elevation != pDisp->GetElevation() )
|
|||
|
{
|
|||
|
pDisp->Elevate( elevation );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose:
|
|||
|
// Input : pNMHDR -
|
|||
|
// pResult -
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnSpinUpDown( NMHDR *pNMHDR, LRESULT *pResult )
|
|||
|
{
|
|||
|
//
|
|||
|
// get scroll up down edit box
|
|||
|
//
|
|||
|
NM_UPDOWN *pNMUpDown = ( NM_UPDOWN* )pNMHDR;
|
|||
|
switch( pNMUpDown->hdr.idFrom )
|
|||
|
{
|
|||
|
case ID_SPIN_DISP_POWER:
|
|||
|
{
|
|||
|
CEdit *pEdit = ( CEdit* )GetDlgItem( ID_DISP_POWER );
|
|||
|
CString strPower;
|
|||
|
pEdit->GetWindowText( strPower );
|
|||
|
int power = atoi( strPower );
|
|||
|
power += ( -pNMUpDown->iDelta );
|
|||
|
if( power < 2 ) { power = 2; }
|
|||
|
if( power > 4 ) { power = 4; }
|
|||
|
strPower.Format( "%d", power );
|
|||
|
pEdit->SetWindowText( strPower );
|
|||
|
*pResult = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case ID_SPIN_DISP_ELEVATION:
|
|||
|
{
|
|||
|
CEdit *pEdit = ( CEdit* )GetDlgItem( ID_DISP_ELEVATION );
|
|||
|
CString strElevation;
|
|||
|
pEdit->GetWindowText( strElevation );
|
|||
|
float elevation = atof( strElevation );
|
|||
|
elevation += 0.5f * ( -pNMUpDown->iDelta );
|
|||
|
strElevation.Format( "%4.2f", elevation );
|
|||
|
pEdit->SetWindowText( strElevation );
|
|||
|
*pResult = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::UpdateScale( CMapDisp *pDisp )
|
|||
|
{
|
|||
|
if( !pDisp )
|
|||
|
return;
|
|||
|
|
|||
|
//
|
|||
|
// get the current scale value
|
|||
|
//
|
|||
|
CString strScale;
|
|||
|
GetDlgItemText( ID_DISP_SCALE, strScale );
|
|||
|
float scale = atof( strScale );
|
|||
|
|
|||
|
// check for change and set new scale if need be
|
|||
|
if( scale != pDisp->GetScale() )
|
|||
|
{
|
|||
|
pDisp->Scale( scale );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::OnButtonApply( void )
|
|||
|
{
|
|||
|
//
|
|||
|
// "create" all selected faces
|
|||
|
//
|
|||
|
CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
|
|||
|
if( pSheet )
|
|||
|
{
|
|||
|
int faceCount = pSheet->GetFaceListCount();
|
|||
|
for( int ndxFace = 0; ndxFace < faceCount; ndxFace++ )
|
|||
|
{
|
|||
|
// get current face
|
|||
|
CMapFace *pFace = pSheet->GetFaceListDataFace( ndxFace );
|
|||
|
if( pFace )
|
|||
|
{
|
|||
|
if( pFace->HasDisp() )
|
|||
|
{
|
|||
|
EditDispHandle_t handle = pFace->GetDisp();
|
|||
|
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
|
|||
|
|
|||
|
// update attribs
|
|||
|
UpdatePower( pDisp );
|
|||
|
UpdateElevation( pDisp );
|
|||
|
UpdateScale( pDisp );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// update
|
|||
|
PostToolUpdate();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::CloseAllDialogs( void )
|
|||
|
{
|
|||
|
if( m_uiTool == FACEEDITTOOL_PAINTGEO )
|
|||
|
{
|
|||
|
m_PaintDistDlg.DestroyWindow();
|
|||
|
}
|
|||
|
|
|||
|
if( m_uiTool == FACEEDITTOOL_PAINTSCULPT )
|
|||
|
{
|
|||
|
m_PaintSculptDlg.DestroyWindow();
|
|||
|
}
|
|||
|
|
|||
|
if( m_uiTool == FACEEDITTOOL_PAINTDATA )
|
|||
|
{
|
|||
|
m_PaintDataDlg.DestroyWindow();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void CFaceEditDispPage::ResetForceShows( void )
|
|||
|
{
|
|||
|
// Walkable
|
|||
|
if ( m_bForceShowWalkable )
|
|||
|
{
|
|||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
|||
|
if ( pDoc )
|
|||
|
{
|
|||
|
pDoc->SetDispDrawWalkable( false );
|
|||
|
}
|
|||
|
m_bForceShowWalkable = false;
|
|||
|
}
|
|||
|
|
|||
|
// Buildable
|
|||
|
if ( m_bForceShowBuildable )
|
|||
|
{
|
|||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
|||
|
if ( pDoc )
|
|||
|
{
|
|||
|
pDoc->SetDispDrawBuildable( false );
|
|||
|
}
|
|||
|
m_bForceShowBuildable = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
BOOL CFaceEditDispPage::OnSetActive( void )
|
|||
|
{
|
|||
|
ToolManager()->SetTool( TOOL_FACEEDIT_DISP );
|
|||
|
|
|||
|
// set the selection as the tool to use!!!
|
|||
|
OnButtonSelect();
|
|||
|
|
|||
|
return CPropertyPage::OnSetActive();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
BOOL CFaceEditDispPage::OnKillActive( void )
|
|||
|
{
|
|||
|
CloseAllDialogs();
|
|||
|
ResetForceShows();
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
BOOL CFaceEditDispPage::PreTranslateMessage( MSG *pMsg )
|
|||
|
{
|
|||
|
HACCEL hAccel = GetMainWnd()->GetAccelTable();
|
|||
|
if( !(hAccel && ::TranslateAccelerator( GetMainWnd()->m_hWnd, hAccel, pMsg ) ) )
|
|||
|
{
|
|||
|
return CPropertyPage::PreTranslateMessage( pMsg );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|