123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- // DlgPgPolygon.cpp : implementation file
- //
- #include "stdafx.h"
- #include "DlgPgPolygon.h"
- #ifdef _DEBUG
- #undef new
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CDlgPgPolygon property page
- IMPLEMENT_DYNCREATE(CDlgPgPolygon, CPropertyPage)
- CDlgPgPolygon::CDlgPgPolygon() : CPropertyPage(CDlgPgPolygon::IDD)
- {
- //{{AFX_DATA_INIT(CDlgPgPolygon)
- //}}AFX_DATA_INIT
- }
- CDlgPgPolygon::~CDlgPgPolygon()
- {
- }
- void CDlgPgPolygon::DoDataExchange(CDataExchange* pDX)
- {
- if( theApp.m_bDisableDataExchange) return;
- CPropertyPage::DoDataExchange(pDX);
- // mark that property page has been modified
- SetModified( TRUE);
- // obtain document
- CWorldEditorDoc* pDoc = theApp.GetDocument();
- if( pDoc == NULL) return;
- // polygon mode must be on
- if( pDoc->GetEditingMode() != POLYGON_MODE) return;
- // get flags of control activity
- BOOL bSelectionExists = pDoc->m_selPolygonSelection.Count() != 0;
-
- // if dialog is recieving data and control window is valid
- if( (pDX->m_bSaveAndValidate == FALSE) && IsWindow( m_IsPortal.m_hWnd) )
- {
- // initialize combo boxes
- InitComboBoxes();
- // polygon controls exist if polygon selection exists
- m_IsPortal.EnableWindow( bSelectionExists);
- m_IsOldPortal.EnableWindow( bSelectionExists);
- m_IsOccluder.EnableWindow( bSelectionExists);
- m_IsPassable.EnableWindow( bSelectionExists);
- m_bStairs.EnableWindow( bSelectionExists);
- m_bShootThru.EnableWindow( bSelectionExists);
- m_IsInvisible.EnableWindow( bSelectionExists);
- m_IsDoubleSided.EnableWindow( bSelectionExists);
- m_bIsDetail.EnableWindow( bSelectionExists);
- m_IsTranslucent.EnableWindow( bSelectionExists);
- m_IsTransparent.EnableWindow( bSelectionExists);
- m_ComboMirror.EnableWindow( bSelectionExists);
- m_ComboFriction.EnableWindow( bSelectionExists);
- GetDlgItem( IDC_STATIC_MIRROR)->EnableWindow( bSelectionExists);
- GetDlgItem( IDC_STATIC_FRICTION)->EnableWindow( bSelectionExists);
- GetDlgItem( IDC_PRETENDER_DISTANCE)->EnableWindow( bSelectionExists);
- GetDlgItem( IDC_STATIC_PRETENDER_DISTANCE)->EnableWindow( bSelectionExists);
- // if selection exists, calculate tri-state value of attribute intersection
- if( bSelectionExists)
- {
- // get friction, illumination, mirror and effect properties from first polygon
- UBYTE ubFirstFriction;
- UBYTE ubFirstMirror;
- BOOL bSameFriction = TRUE;
- BOOL bSameMirror = TRUE;
- UWORD uwFirstPretenderDistance;
- m_bPretenderDistance = TRUE;
- ULONG ulFlagsOn = MAX_ULONG;
- ULONG ulFlagsOff = MAX_ULONG;
- INDEX iPolygon = 0;
- // for each of the selected polygons
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- ulFlagsOn &= itbpo->bpo_ulFlags;
- ulFlagsOff &= ~itbpo->bpo_ulFlags;
- if( iPolygon == 0)
- {
- ubFirstFriction = itbpo->bpo_bppProperties.bpp_ubSurfaceType;
- ubFirstMirror = itbpo->bpo_bppProperties.bpp_ubMirrorType;
- uwFirstPretenderDistance = itbpo->bpo_bppProperties.bpp_uwPretenderDistance;
- }
- else
- {
- if( itbpo->bpo_bppProperties.bpp_ubSurfaceType != ubFirstFriction) bSameFriction = FALSE;
- if( itbpo->bpo_bppProperties.bpp_ubMirrorType != ubFirstMirror) bSameMirror = FALSE;
- if( itbpo->bpo_bppProperties.bpp_uwPretenderDistance != uwFirstPretenderDistance) m_bPretenderDistance = FALSE;
- }
- iPolygon++;
- }
- // apply flags to controls
- #define SET_TRI_STATE_TO_CTRL( ctrl, flag)\
- if((ulFlagsOn & flag) && !(ulFlagsOff & flag)) ctrl.SetCheck( 1);\
- else if(!(ulFlagsOn & flag) && (ulFlagsOff & flag)) ctrl.SetCheck( 0);\
- else ctrl.SetCheck( 2);
- SET_TRI_STATE_TO_CTRL( m_IsPortal, BPOF_PORTAL);
- SET_TRI_STATE_TO_CTRL( m_IsOldPortal, OPOF_PORTAL);
- SET_TRI_STATE_TO_CTRL( m_IsOccluder, BPOF_OCCLUDER);
- SET_TRI_STATE_TO_CTRL( m_IsPassable, BPOF_PASSABLE);
- SET_TRI_STATE_TO_CTRL( m_bStairs, BPOF_STAIRS);
- SET_TRI_STATE_TO_CTRL( m_bShootThru, BPOF_SHOOTTHRU);
- SET_TRI_STATE_TO_CTRL( m_IsInvisible, BPOF_INVISIBLE);
- SET_TRI_STATE_TO_CTRL( m_IsDoubleSided, BPOF_DOUBLESIDED);
- SET_TRI_STATE_TO_CTRL( m_bIsDetail, BPOF_DETAILPOLYGON);
- SET_TRI_STATE_TO_CTRL( m_IsTranslucent, BPOF_TRANSLUCENT);
- SET_TRI_STATE_TO_CTRL( m_IsTransparent, BPOF_TRANSPARENT);
- if( bSameFriction) m_ComboFriction.SetCurSel( ubFirstFriction);
- else m_ComboFriction.SetCurSel(-1);
- if( bSameMirror) m_ComboMirror.SetCurSel( ubFirstMirror);
- else m_ComboMirror.SetCurSel(-1);
- if( m_bPretenderDistance) m_fPretenderDistance = uwFirstPretenderDistance;
- }
- // mark that page is updated
- m_udPolygonSelection.MarkUpdated();
- }
- //{{AFX_DATA_MAP(CDlgPgPolygon)
- DDX_Control(pDX, IDC_DOUBLESIDED, m_IsDoubleSided);
- DDX_Control(pDX, IDC_SHOOTTROUGH, m_bShootThru);
- DDX_Control(pDX, IDC_IS_TRANSPARENT, m_IsTransparent);
- DDX_Control(pDX, IDC_STAIRS, m_bStairs);
- DDX_Control(pDX, IDC_IS_OCCLUDER, m_IsOccluder);
- DDX_Control(pDX, IDC_MIRROR_COMBO, m_ComboMirror);
- DDX_Control(pDX, IDC_IS_OLD_PORTAL, m_IsOldPortal);
- DDX_Control(pDX, IDC_IS_DETAIL, m_bIsDetail);
- DDX_Control(pDX, IDC_INVISIBLE, m_IsInvisible);
- DDX_Control(pDX, IDC_IS_TRANSLUSCENT, m_IsTranslucent);
- DDX_Control(pDX, IDC_IS_PASSABLE, m_IsPassable);
- DDX_Control(pDX, IDC_IS_PORTAL, m_IsPortal);
- DDX_Control(pDX, IDC_FRICTION_COMBO, m_ComboFriction);
- //}}AFX_DATA_MAP
- DDX_SkyFloat(pDX, IDC_PRETENDER_DISTANCE, m_fPretenderDistance, m_bPretenderDistance);
- // if dialog is giving data
- if( pDX->m_bSaveAndValidate != FALSE)
- {
- BOOL bFindShadowLayers = FALSE;
- // calculate bounding box for all polygons
- FLOATaabbox3D boxBoundingBoxPolygonSelection;
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- boxBoundingBoxPolygonSelection |= itbpo->bpo_boxBoundingBox;
- if( m_ComboFriction.GetCurSel()!=-1) itbpo->bpo_bppProperties.bpp_ubSurfaceType = m_ComboFriction.GetCurSel();
- INDEX iItemMirror = m_ComboMirror.GetCurSel();
- if( iItemMirror!=CB_ERR)
- {
- if( itbpo->bpo_bppProperties.bpp_ubMirrorType != iItemMirror)
- {
- itbpo->bpo_bppProperties.bpp_ubMirrorType = (UBYTE) iItemMirror;
- }
- }
- // if all polygons have same pretender distance
- if( m_bPretenderDistance)
- {
- itbpo->bpo_bppProperties.bpp_uwPretenderDistance = UWORD (m_fPretenderDistance);
- }
- // set polygon's flags acording witg given tri-state ctrl
- #define TRI_STATE_CTRL_TO_FLAGS( ctrl, flag, bDiscardShd, bFindShdLayers)\
- if( (ctrl.GetCheck() == 1) && !(itbpo->bpo_ulFlags & flag) ) {\
- itbpo->bpo_ulFlags |= flag;\
- if( bDiscardShd) itbpo->DiscardShadows();\
- if( bFindShdLayers) bFindShadowLayers = TRUE;\
- } else if( (ctrl.GetCheck() == 0) && (itbpo->bpo_ulFlags & flag) ) {\
- itbpo->bpo_ulFlags &= ~flag;\
- if( bDiscardShd) itbpo->DiscardShadows();\
- if( bFindShdLayers) bFindShadowLayers = TRUE;\
- }
- ULONG ulFlagsBefore = itbpo->bpo_ulFlags;
- TRI_STATE_CTRL_TO_FLAGS( m_IsPortal, BPOF_PORTAL, TRUE, TRUE);
- TRI_STATE_CTRL_TO_FLAGS( m_IsOccluder, BPOF_OCCLUDER, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_IsOldPortal, OPOF_PORTAL, TRUE, TRUE);
- TRI_STATE_CTRL_TO_FLAGS( m_IsPassable, BPOF_PASSABLE, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_bStairs, BPOF_STAIRS, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_bShootThru, BPOF_SHOOTTHRU, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_IsInvisible, BPOF_INVISIBLE, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_IsDoubleSided, BPOF_DOUBLESIDED, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_bIsDetail, BPOF_DETAILPOLYGON, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_IsTranslucent, BPOF_TRANSLUCENT, FALSE, FALSE);
- TRI_STATE_CTRL_TO_FLAGS( m_IsTransparent, BPOF_TRANSPARENT, FALSE, FALSE);
- ULONG ulFlagsAfter = itbpo->bpo_ulFlags;
- // occluder and detail flags can't be on at the same time
- BOOL bOccluderSet = ((ulFlagsBefore&BPOF_OCCLUDER)!=(ulFlagsAfter&BPOF_OCCLUDER))&&(ulFlagsAfter&BPOF_OCCLUDER);
- BOOL bDetailSet = ((ulFlagsBefore&BPOF_DETAILPOLYGON)!=(ulFlagsAfter&BPOF_DETAILPOLYGON))&&(ulFlagsAfter&BPOF_DETAILPOLYGON);
- BOOL bDoubleSidedSet = ((ulFlagsBefore&BPOF_DOUBLESIDED)!=(ulFlagsAfter&BPOF_DOUBLESIDED))&&(ulFlagsAfter&BPOF_DOUBLESIDED);
-
- // if occluder set
- if( bOccluderSet)
- {
- // turn off detail
- itbpo->bpo_ulFlags &= ~BPOF_DETAILPOLYGON;
- itbpo->bpo_ulFlags |= BPOF_DOESNOTCASTSHADOW;
- }
- // if doublesided set
- if(bDoubleSidedSet)
- {
- // turn on transparent and detail
- itbpo->bpo_ulFlags |= BPOF_TRANSPARENT;
- itbpo->bpo_ulFlags |= BPOF_DETAILPOLYGON;
- }
- // if detail set
- if( bDetailSet)
- {
- // turn off occluder
- itbpo->bpo_ulFlags &= ~BPOF_OCCLUDER;
- }
- }
- // if we should find shadow layers
- if( bFindShadowLayers)
- {
- pDoc->m_woWorld.FindShadowLayers( boxBoundingBoxPolygonSelection);
- }
- // mark that document is changed
- theApp.GetDocument()->SetModifiedFlag( TRUE);
- // redraw to show changes
- pDoc->UpdateAllViews( NULL);
- }
- }
- BEGIN_MESSAGE_MAP(CDlgPgPolygon, CPropertyPage)
- //{{AFX_MSG_MAP(CDlgPgPolygon)
- ON_CBN_SELCHANGE(IDC_FRICTION_COMBO, OnSelchangeFrictionCombo)
- ON_CBN_DROPDOWN(IDC_FRICTION_COMBO, OnDropdownFrictionCombo)
- ON_CBN_SELCHANGE(IDC_MIRROR_COMBO, OnSelchangeMirrorCombo)
- ON_CBN_DROPDOWN(IDC_MIRROR_COMBO, OnDropdownMirrorCombo)
- ON_WM_CONTEXTMENU()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CDlgPgPolygon message handlers
- void CDlgPgPolygon::InitComboBoxes(void)
- {
- CWorldEditorDoc* pDoc = theApp.GetDocument();
- CTString strFrictionName;
- CTString strMirrorName;
- m_ComboFriction.ResetContent();
- m_ComboMirror.ResetContent();
- // add all available frictions
- for(INDEX iFriction=0; iFriction<MAX_UBYTE; iFriction++)
- {
- strFrictionName = pDoc->m_woWorld.wo_astSurfaceTypes[iFriction].st_strName;
- if( strFrictionName == "") break;
- INDEX iAddedAs = m_ComboFriction.AddString( CString(strFrictionName));
- }
- // none must exist
- m_ComboMirror.AddString( L"None");
- // if there is polygon selection
- if( pDoc->m_selPolygonSelection.Count() != 0)
- {
- // obtain first polygon's brush
- CBrush3D *pbrBrush = NULL;
- pDoc->m_selPolygonSelection.Lock();
- if( !pDoc->m_selPolygonSelection.IsMember( pDoc->m_pbpoLastCentered))
- {
- pbrBrush = pDoc->m_selPolygonSelection[0].bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush;
- }
- pDoc->m_selPolygonSelection.Unlock();
- BOOL bEnableMirror = TRUE;
- // for each of the selected polygons
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // disable mirror combo box if all polygons are not from same brush
- if( pbrBrush != itbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush)
- {
- bEnableMirror = FALSE;
- break;
- }
- }
-
- // if mirror combo is enabled
- if( bEnableMirror)
- {
- // add mirrors
- for(INDEX iMirror=1; iMirror<MAX_UBYTE; iMirror++)
- {
- CTString strMirrorName = pbrBrush->br_penEntity->GetMirrorName( iMirror);
- if( strMirrorName == "") break;
- m_ComboMirror.AddString( CString(strMirrorName));
- }
- }
- }
- }
- BOOL CDlgPgPolygon::OnIdle(LONG lCount)
- {
- CWorldEditorDoc* pDoc = theApp.GetDocument();
- if( (pDoc == NULL) || !IsWindow(m_hWnd) )
- {
- return TRUE;
- }
- // if selections have been changed (they are not up to date)
- if( !pDoc->m_chSelections.IsUpToDate( m_udPolygonSelection) )
- {
- // update dialog data
- UpdateData( FALSE);
- }
- return TRUE;
- }
- BOOL CDlgPgPolygon::PreTranslateMessage(MSG* pMsg)
- {
- if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)
- {
- // move data from page to polygon
- UpdateData( TRUE);
- // the message is handled
- return TRUE;
- }
- return CPropertyPage::PreTranslateMessage(pMsg);
- }
- BOOL CDlgPgPolygon::OnInitDialog()
- {
- CPropertyPage::OnInitDialog();
- if( IsWindow( m_ComboFriction.m_hWnd))
- {
- InitComboBoxes();
- }
- m_bIsDetail.SetDialogPtr( this);
- m_IsInvisible.SetDialogPtr( this);
- m_IsDoubleSided.SetDialogPtr( this);
- m_IsTranslucent.SetDialogPtr( this);
- m_IsTransparent.SetDialogPtr( this);
- m_IsPassable.SetDialogPtr( this);
- m_bStairs.SetDialogPtr( this);
- m_bShootThru.SetDialogPtr( this);
- m_IsPortal.SetDialogPtr( this);
- m_IsOldPortal.SetDialogPtr( this);
- m_IsOccluder.SetDialogPtr( this);
- return TRUE;
- }
- void CDlgPgPolygon::OnSelchangeFrictionCombo()
- {
- UpdateData( TRUE);
- }
- void CDlgPgPolygon::OnDropdownFrictionCombo()
- {
- m_ComboFriction.SetDroppedWidth( 256);
- }
- void CDlgPgPolygon::OnSelchangeMirrorCombo()
- {
- UpdateData( TRUE);
- }
- void CDlgPgPolygon::OnDropdownMirrorCombo()
- {
- m_ComboMirror.SetDroppedWidth( 256);
- }
- void CDlgPgPolygon::OnContextMenu(CWnd* pWnd, CPoint point)
- {
- CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
-
- CMenu menu;
- if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- if( menu.LoadMenu(IDR_INFO_POLYGON_POPUP))
- {
- CMenu* pPopup = menu.GetSubMenu(0);
- if( pDoc->m_selPolygonSelection.Count() != 1)
- {
- menu.EnableMenuItem(ID_SET_AS_DEFAULT, MF_DISABLED|MF_GRAYED);
- }
- pPopup->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN,
- point.x, point.y, this);
- }
- }
- }
|