Serious-Engine/Sources/WorldEditor/DlgTerrainProperties.cpp
2016-03-11 18:20:51 -06:00

418 lines
14 KiB
C++

/* 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. */
// DlgTerrainProperties.cpp : implementation file
//
#include "stdafx.h"
#include "WorldEditor.h"
#include "DlgTerrainProperties.h"
#ifdef _DEBUG
#undef new
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static INDEX _iShadowMapShift=0;
static INDEX _iShadingMapShift=1;
static PIX _pixGlobalPretenderTextureWidth=64;
/////////////////////////////////////////////////////////////////////////////
// CDlgTerrainProperties dialog
CDlgTerrainProperties::CDlgTerrainProperties(CWnd* pParent /*=NULL*/)
: CDialog(CDlgTerrainProperties::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlgTerrainProperties)
m_strHeightmapSize = _T("");
m_strShadowMapSize = _T("");
m_strTerrainPretender = _T("");
m_strTilePretender = _T("");
m_fTerrainLength = 0.0f;
m_fTerrainHeight = 0.0f;
m_fTerrainWidth = 0.0f;
m_fLODSwitch = 0.0f;
m_strShadingMapSize = _T("");
m_strMemoryConsumption = _T("");
m_strLayerMemory = _T("");
m_strEdgeMap = _T("");
//}}AFX_DATA_INIT
CTerrain *ptrTerrain=GetTerrain();
if(ptrTerrain==NULL) return;
_iShadowMapShift=ptrTerrain->tr_iShadowMapSizeAspect;
_iShadingMapShift=ptrTerrain->tr_iShadingMapSizeAspect;
_pixGlobalPretenderTextureWidth=ptrTerrain->tr_pixTopMapWidth;
}
void CDlgTerrainProperties::DoDataExchange(CDataExchange* pDX)
{
CTString strTemp;
CTerrain *ptrTerrain=GetTerrain();
if(ptrTerrain==NULL) return;
// if dialog is recieving data
if( pDX->m_bSaveAndValidate == FALSE && IsWindow(m_ctrlShadowMapSlider))
{
m_fTerrainWidth =ptrTerrain->tr_vTerrainSize(1);
m_fTerrainHeight=ptrTerrain->tr_vTerrainSize(2);
m_fTerrainLength=ptrTerrain->tr_vTerrainSize(3);
INDEX iItemW=m_ctrlHeightMapWidth.GetCurSel();
PIX pixW=m_ctrlHeightMapWidth.GetItemData( iItemW);
INDEX iItemH=m_ctrlHeightMapHeight.GetCurSel();
PIX pixH=m_ctrlHeightMapHeight.GetItemData( iItemH);
INDEX iMemHeightMap=pixW*pixH*sizeof(UWORD)/1024;
strTemp.PrintF("Height map size: %d x %d, Memory: %d KB", pixW, pixH, iMemHeightMap);
m_strHeightmapSize=strTemp;
PrepareGlobalPretenderCombo();
INDEX iShadowMapShift=m_ctrlShadowMapSlider.GetPos();
PIX pixSwW=Clamp(PIX((pixW-1)*pow(2.0f,iShadowMapShift)),PIX(4),PIX(2048));
PIX pixSwH=Clamp(PIX((pixH-1)*pow(2.0f,iShadowMapShift)),PIX(4),PIX(2048));
INDEX iMemShadowMap=pixSwW*pixSwH*sizeof(COLOR)/1024*1.333f;
strTemp.PrintF("Size: %d x %d, Memory: %d KB", pixSwW, pixSwH, iMemShadowMap);
m_strShadowMapSize=strTemp;
INDEX iShadingMapShift=10-m_ctrlShadingMapSlider.GetPos();
PIX pixSdW=Clamp(PIX(pixSwW*pow(2.0f,-iShadingMapShift)),PIX(4),PIX(pixSwW));
PIX pixSdH=Clamp(PIX(pixSwH*pow(2.0f,-iShadingMapShift)),PIX(4),PIX(pixSwH));
INDEX iMemShadingMap=pixSdW*pixSdW*sizeof(UWORD)/1024;
strTemp.PrintF("Size: %d x %d, Memory: %d KB", pixSdW, pixSdH, iMemShadingMap);
m_strShadingMapSize=strTemp;
INDEX iGlobalPretender=m_ctrlGlobalPretenderTexture.GetCurSel();
INDEX pixSize=m_ctrlGlobalPretenderTexture.GetItemData(iGlobalPretender);
INDEX iMemTerrainPretender=pixSize*pixSize*sizeof(UWORD)/1024*1.333f;
strTemp.PrintF("Size: %d x %d, Memory: %d KB", pixSize, pixSize, iMemTerrainPretender);
m_strTerrainPretender=strTemp;
INDEX iTlp=m_ctrlTilePretender.GetCurSel();
PIX pixTlpW=m_ctrlTilePretender.GetItemData( iTlp);
INDEX iMemTilePretender=pixTlpW*pixTlpW*sizeof(UWORD)/1024*1.333f;
strTemp.PrintF("Tile pretender texture (%d KB)", iMemTilePretender);
m_strTilePretender=strTemp;
INDEX ctLayers=ptrTerrain->tr_atlLayers.Count();
INDEX iMemLayers=(pixW*pixH*ctLayers)/1024;
strTemp.PrintF("Layer memory consumption (%d layers): %d KB", ctLayers, iMemLayers);
m_strLayerMemory=strTemp;
INDEX iMemEdgeMap=(pixW*pixH)/1024;
strTemp.PrintF("Edge map memory consumption: %d KB", iMemEdgeMap);
m_strEdgeMap=strTemp;
strTemp.PrintF("Terrain total uncompressed static data memory consumption (without tile pretender textures and geometry): %d KB",
iMemHeightMap+iMemShadowMap+iMemShadingMap+iMemTerrainPretender+iMemLayers+iMemEdgeMap);
m_strMemoryConsumption=strTemp;
m_fLODSwitch=ptrTerrain->tr_fDistFactor;
}
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgTerrainProperties)
DDX_Control(pDX, IDC_GLOBAL_PRETENDER, m_ctrlGlobalPretenderTexture);
DDX_Control(pDX, IDC_TILE_PRETENDER, m_ctrlTilePretender);
DDX_Control(pDX, IDC_SHADING_MAP, m_ctrlShadingMapSlider);
DDX_Control(pDX, IDC_TERRAIN_QUADS_PER_TILE, m_ctrlQuadsPerTile);
DDX_Control(pDX, IDC_TERRAIN_HM_WIDTH, m_ctrlHeightMapWidth);
DDX_Control(pDX, IDC_TERRAIN_HM_HEIGHT, m_ctrlHeightMapHeight);
DDX_Control(pDX, IDC_SHADOW_MAP, m_ctrlShadowMapSlider);
DDX_Text(pDX, IDC_HEIGHTIMAP_SIZE_T, m_strHeightmapSize);
DDX_Text(pDX, IDC_SHADOW_MAP_T, m_strShadowMapSize);
DDX_Text(pDX, IDC_TERRAIN_PRETENDER_T, m_strTerrainPretender);
DDX_Text(pDX, IDC_TILE_PRETENDER_T, m_strTilePretender);
DDX_Text(pDX, IDC_TERRAIN_LENGTH, m_fTerrainLength);
DDV_MinMaxFloat(pDX, m_fTerrainLength, 0.f, 1.e+007f);
DDX_Text(pDX, IDC_TERRAIN_HEIGHT, m_fTerrainHeight);
DDV_MinMaxFloat(pDX, m_fTerrainHeight, 0.f, 1.e+007f);
DDX_Text(pDX, IDC_TERRAIN_WIDTH, m_fTerrainWidth);
DDV_MinMaxFloat(pDX, m_fTerrainWidth, 0.f, 1.e+007f);
DDX_Text(pDX, IDC_TERRAIN_LOD_SWITCH, m_fLODSwitch);
DDV_MinMaxFloat(pDX, m_fLODSwitch, 0.f, 1.e+007f);
DDX_Text(pDX, IDC_SHADING_MAP_T, m_strShadingMapSize);
DDX_Text(pDX, IDC_TERRAIN_MEMORY_T, m_strMemoryConsumption);
DDX_Text(pDX, IDC_LAYER_MEMORY_T, m_strLayerMemory);
DDX_Text(pDX, IDC_TERRAIN_EDGE_MEMORY_T, m_strEdgeMap);
//}}AFX_DATA_MAP
// if dialog is giving data
if( pDX->m_bSaveAndValidate != FALSE)
{
BOOL bUpdateTerrain=FALSE;
// handle heightmap size change
INDEX iItemW=m_ctrlHeightMapWidth.GetCurSel();
PIX pixW=m_ctrlHeightMapWidth.GetItemData( iItemW);
INDEX iItemH=m_ctrlHeightMapHeight.GetCurSel();
PIX pixH=m_ctrlHeightMapHeight.GetItemData( iItemH);
if( ptrTerrain->tr_pixHeightMapWidth != pixW ||
ptrTerrain->tr_pixHeightMapHeight!= pixH )
{
ptrTerrain->ReAllocateHeightMap(pixW, pixH);
bUpdateTerrain=TRUE;
}
// handle terrain size change
if( ptrTerrain->tr_vTerrainSize(1)!=m_fTerrainWidth ||
ptrTerrain->tr_vTerrainSize(2)!=m_fTerrainHeight||
ptrTerrain->tr_vTerrainSize(3)!=m_fTerrainLength)
{
ptrTerrain->SetTerrainSize(FLOAT3D(m_fTerrainWidth,m_fTerrainHeight,m_fTerrainLength));
bUpdateTerrain=TRUE;
}
// handle tile pretender texture size change
INDEX iTlp=m_ctrlTilePretender.GetCurSel();
PIX pixTlpW=m_ctrlTilePretender.GetItemData( iTlp);
if( ptrTerrain->tr_pixFirstMipTopMapWidth != pixTlpW)
{
ptrTerrain->SetTileTopMapSize(pixTlpW);
bUpdateTerrain=TRUE;
}
// handle quads per tile change
INDEX iQuadItem=m_ctrlQuadsPerTile.GetCurSel();
INDEX ctQuads=m_ctrlQuadsPerTile.GetItemData( iQuadItem);
if(ctQuads!=ptrTerrain->tr_ctQuadsInTileRow)
{
ptrTerrain->SetQuadsPerTileRow(ctQuads);
bUpdateTerrain=TRUE;
}
// handle LOD distance change
if( m_fLODSwitch!=ptrTerrain->tr_fDistFactor)
{
ptrTerrain->SetLodDistanceFactor(m_fLODSwitch);
}
// handle global pretender texture change
INDEX iGlobalPretender=m_ctrlGlobalPretenderTexture.GetCurSel();
INDEX pixSize=m_ctrlGlobalPretenderTexture.GetItemData(iGlobalPretender);
if(pixSize!=ptrTerrain->tr_pixTopMapWidth)
{
ptrTerrain->SetGlobalTopMapSize(pixSize);
bUpdateTerrain=TRUE;
}
// handle shadow changes
if( (m_ctrlShadowMapSlider.GetPos()!=_iShadowMapShift) ||
(m_ctrlShadingMapSlider.GetPos()!=10-_iShadingMapShift) )
{
_iShadowMapShift=m_ctrlShadowMapSlider.GetPos();
_iShadingMapShift=10-m_ctrlShadingMapSlider.GetPos();
ptrTerrain->SetShadowMapsSize(_iShadowMapShift,_iShadingMapShift);
bUpdateTerrain=TRUE;
}
// update terrain
if(bUpdateTerrain)
{
ptrTerrain->tr_penEntity->TerrainChangeNotify();
GenerateLayerDistribution(-1);
ptrTerrain->RefreshTerrain();
ptrTerrain->UpdateShadowMap();
theApp.m_ctTerrainPage.MarkChanged();
}
}
}
BEGIN_MESSAGE_MAP(CDlgTerrainProperties, CDialog)
//{{AFX_MSG_MAP(CDlgTerrainProperties)
ON_WM_HSCROLL()
ON_CBN_SELCHANGE(IDC_TERRAIN_HM_WIDTH, OnSelchangeTerrainHmWidth)
ON_CBN_SELCHANGE(IDC_TERRAIN_HM_HEIGHT, OnSelchangeTerrainHmHeight)
ON_CBN_SELCHANGE(IDC_TILE_PRETENDER, OnSelchangeTilePretender)
ON_CBN_SELCHANGE(IDC_GLOBAL_PRETENDER, OnSelchangeGlobalPretender)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgTerrainProperties message handlers
void CDlgTerrainProperties::InitComboBoxes(void)
{
INDEX iToSelect, iWidth;
CTerrain *ptrTerrain=GetTerrain();
if(ptrTerrain==NULL) return;
// prepare quads per tile combo box
m_ctrlQuadsPerTile.ResetContent();
iToSelect=3;
for(INDEX iQuads=4; iQuads<=2048; iQuads*=2)
{
CTString strItem;
strItem.PrintF("%d x %d", iQuads, iQuads);
INDEX iAddedAs=m_ctrlQuadsPerTile.AddString(CString(strItem));
m_ctrlQuadsPerTile.SetItemData(iAddedAs,iQuads);
if(ptrTerrain->tr_ctQuadsInTileRow==iQuads)
{
iToSelect=iAddedAs;
}
}
m_ctrlQuadsPerTile.SetCurSel(iToSelect);
// prepare heightmap size combo boxes
m_ctrlHeightMapWidth.ResetContent();
m_ctrlHeightMapHeight.ResetContent();
INDEX iToSelectW=3;
INDEX iToSelectH=3;
for(iWidth=32; iWidth<=2048; iWidth*=2)
{
CTString strItem;
strItem.PrintF("%d", iWidth+1);
// width
INDEX iW=m_ctrlHeightMapWidth.AddString(CString(strItem));
m_ctrlHeightMapWidth.SetItemData(iW,iWidth+1);
if(ptrTerrain->tr_pixHeightMapWidth==iWidth+1) iToSelectW=iW;
// height
INDEX iH=m_ctrlHeightMapHeight.AddString(CString(strItem));
m_ctrlHeightMapHeight.SetItemData(iH,iWidth+1);
if(ptrTerrain->tr_pixHeightMapHeight==iWidth+1) iToSelectH=iH;
}
m_ctrlHeightMapWidth.SetCurSel( iToSelectW);
m_ctrlHeightMapHeight.SetCurSel(iToSelectH);
PrepareTilePretenderCombo();
PrepareGlobalPretenderCombo();
}
// prepare tile pretender combo boxes
void CDlgTerrainProperties::PrepareTilePretenderCombo(void)
{
CTerrain *ptrTerrain=GetTerrain();
if(ptrTerrain==NULL) return;
m_ctrlTilePretender.ResetContent();
INDEX iToSelect=6;
for(INDEX iWidth=4; iWidth<=2048; iWidth*=2)
{
CTString strItem;
strItem.PrintF("%d x %d", iWidth, iWidth);
INDEX iAddedAs=m_ctrlTilePretender.AddString(CString(strItem));
m_ctrlTilePretender.SetItemData(iAddedAs, iWidth);
if(ptrTerrain->tr_pixFirstMipTopMapWidth==iWidth)
{
iToSelect=iAddedAs;
}
}
m_ctrlTilePretender.SetCurSel(iToSelect);
}
// prepare tile pretender combo boxes
void CDlgTerrainProperties::PrepareGlobalPretenderCombo(void)
{
CTerrain *ptrTerrain=GetTerrain();
if(ptrTerrain==NULL) return;
INDEX iHeightMapWidthItem=m_ctrlHeightMapWidth.GetCurSel();
PIX pixHeightMapWidth=m_ctrlHeightMapWidth.GetItemData(iHeightMapWidthItem);
INDEX iHeightMapHeightItem=m_ctrlHeightMapHeight.GetCurSel();
PIX pixHeightMapHeight=m_ctrlHeightMapHeight.GetItemData(iHeightMapHeightItem);
m_ctrlGlobalPretenderTexture.ResetContent();
INDEX iToSelect=_pixGlobalPretenderTextureWidth;
FLOAT fAspect=FLOAT(pixHeightMapWidth-1)/(pixHeightMapHeight-1);
for(INDEX iWidth=4; iWidth<=2048; iWidth*=2)
{
CTString strItem;
strItem.PrintF("%d x %d", iWidth, INDEX(iWidth/fAspect));
INDEX iAddedAs=m_ctrlGlobalPretenderTexture.AddString(CString(strItem));
m_ctrlGlobalPretenderTexture.SetItemData(iAddedAs, iWidth);
if(_pixGlobalPretenderTextureWidth==iWidth)
{
iToSelect=iAddedAs;
}
}
m_ctrlGlobalPretenderTexture.SetCurSel(iToSelect);
}
BOOL CDlgTerrainProperties::OnInitDialog()
{
CDialog::OnInitDialog();
// initialize combo boxes
InitComboBoxes();
m_ctrlShadowMapSlider.SetRange(-10, 10, TRUE);
m_ctrlShadingMapSlider.SetRange(0, 10, TRUE);
m_ctrlShadowMapSlider.SetPos(_iShadowMapShift);
m_ctrlShadowMapSlider.Invalidate(FALSE);
m_ctrlShadingMapSlider.SetPos(10-_iShadingMapShift);
m_ctrlShadingMapSlider.Invalidate(FALSE);
UpdateData(FALSE);
return TRUE;
}
BOOL _bUpdateDlg=TRUE;
void CDlgTerrainProperties::OnSelchangeTerrainHmWidth()
{
if(_bUpdateDlg)
{
_bUpdateDlg=FALSE;
m_ctrlHeightMapHeight.SetCurSel(m_ctrlHeightMapWidth.GetCurSel());
PrepareGlobalPretenderCombo();
UpdateData(FALSE);
_bUpdateDlg=TRUE;
}
}
void CDlgTerrainProperties::OnSelchangeTerrainHmHeight()
{
if(_bUpdateDlg)
{
_bUpdateDlg=FALSE;
m_ctrlHeightMapWidth.SetCurSel(m_ctrlHeightMapHeight.GetCurSel());
PrepareGlobalPretenderCombo();
UpdateData(FALSE);
_bUpdateDlg=TRUE;
}
}
void CDlgTerrainProperties::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
UpdateData( FALSE);
}
void CDlgTerrainProperties::OnOK()
{
CDialog::OnOK();
}
void CDlgTerrainProperties::OnSelchangeTilePretender()
{
UpdateData( FALSE);
}
void CDlgTerrainProperties::OnSelchangeGlobalPretender()
{
INDEX iItem=m_ctrlGlobalPretenderTexture.GetCurSel();
PIX pixValue=m_ctrlGlobalPretenderTexture.GetItemData(iItem);
_pixGlobalPretenderTextureWidth=pixValue;
}