mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-12-22 17:08:43 +00:00
958 lines
26 KiB
C++
958 lines
26 KiB
C++
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU Affero General Public License as
|
||
|
// published by the Free Software Foundation, either version 3 of the
|
||
|
// License, or (at your option) any later version.
|
||
|
//
|
||
|
// 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 Affero General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Affero General Public License
|
||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
#include "std_afx.h"
|
||
|
|
||
|
#include "object_viewer.h"
|
||
|
#include "vegetable_dlg.h"
|
||
|
#include "vegetable_density_page.h"
|
||
|
#include "vegetable_apperance_page.h"
|
||
|
#include "vegetable_scale_page.h"
|
||
|
#include "vegetable_rotate_page.h"
|
||
|
#include "vegetable_copy_dlg.h"
|
||
|
#include "vegetable_edit_tools.h"
|
||
|
#include "vegetable_wind_dlg.h"
|
||
|
#include "nel/3d/vegetable.h"
|
||
|
#include "nel/3d/tile_vegetable_desc.h"
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CVegetableDlg dialog
|
||
|
|
||
|
|
||
|
CVegetableDlg::CVegetableDlg(CObjectViewer *viewer, CWnd* pParent /*=NULL*/)
|
||
|
: CDialog(CVegetableDlg::IDD, pParent), _ObjView(viewer),
|
||
|
_PropertySheet(NULL), _VegetableDensityPage(NULL), _VegetableApperancePage(NULL),
|
||
|
_VegetableScalePage(NULL), _VegetableRotatePage(NULL),
|
||
|
_VegetableWindDlg(NULL)
|
||
|
{
|
||
|
nlassert(viewer);
|
||
|
|
||
|
_LastVegetSetName= "*.vegetset";
|
||
|
|
||
|
// init VegetableList
|
||
|
VegetableList.VegetableDlg= this;
|
||
|
|
||
|
//{{AFX_DATA_INIT(CVegetableDlg)
|
||
|
//}}AFX_DATA_INIT
|
||
|
}
|
||
|
|
||
|
|
||
|
void CVegetableDlg::DoDataExchange(CDataExchange* pDX)
|
||
|
{
|
||
|
CDialog::DoDataExchange(pDX);
|
||
|
//{{AFX_DATA_MAP(CVegetableDlg)
|
||
|
DDX_Control(pDX, IDC_LIST_VEGETABLE, VegetableList);
|
||
|
DDX_Control(pDX, IDC_STATIC_VEGETABLE_PERF, StaticPolyCount);
|
||
|
DDX_Control(pDX, IDC_CHECK_VEGETABLE_SNAPTOGROUND, CheckSnapToGround);
|
||
|
DDX_Control(pDX, IDC_CHECK_VEGETABLE_ENABLE, CheckEnableVegetable);
|
||
|
DDX_Control(pDX, IDC_CHECK_VEGETABLE_AUTOMATIC, CheckAutomaticRefresh);
|
||
|
DDX_Control(pDX, IDC_BUTTON_VEGETABLE_REFRESH, ButtonRefreshLandscape);
|
||
|
DDX_Control(pDX, IDC_CHECK_VEGETABLE_SHOW, CheckShowLandscape);
|
||
|
DDX_Control(pDX, IDC_STATIC_SELECT_VEGETABLE, SelectVegetableStaticText);
|
||
|
//}}AFX_DATA_MAP
|
||
|
}
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CVegetableDlg, CDialog)
|
||
|
//{{AFX_MSG_MAP(CVegetableDlg)
|
||
|
ON_WM_DESTROY()
|
||
|
ON_LBN_SELCHANGE(IDC_LIST_VEGETABLE, OnSelchangeListVegetable)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_ADD, OnButtonVegetableAdd)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_CLEAR, OnButtonVegetableClear)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_INSERT, OnButtonVegetableInsert)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_LOAD_DESC, OnButtonVegetableLoadDesc)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_LOAD_SET, OnButtonVegetableLoadSet)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_REMOVE, OnButtonVegetableRemove)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_SAVE_DESC, OnButtonVegetableSaveDesc)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_SAVE_SET, OnButtonVegetableSaveSet)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_APPEND_SET, OnButtonVegetableAppendSet)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_COPY, OnButtonVegetableCopy)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_REFRESH, OnButtonVegetableRefresh)
|
||
|
ON_BN_CLICKED(IDC_CHECK_VEGETABLE_SHOW, OnCheckVegetableShow)
|
||
|
ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_SETUP_WIND, OnButtonVegetableSetupWind)
|
||
|
ON_BN_CLICKED(IDC_CHECK_VEGETABLE_AUTOMATIC, OnCheckVegetableAutomatic)
|
||
|
ON_BN_CLICKED(IDC_CHECK_VEGETABLE_ENABLE, OnCheckVegetableEnable)
|
||
|
ON_BN_CLICKED(IDC_CHECK_VEGETABLE_SNAPTOGROUND, OnCheckVegetableSnaptoground)
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CVegetableDlg message handlers
|
||
|
|
||
|
void CVegetableDlg::OnDestroy()
|
||
|
{
|
||
|
setRegisterWindowState (this, REGKEY_OBJ_VIEW_VEGETABLE_DLG);
|
||
|
|
||
|
CDialog::OnDestroy();
|
||
|
|
||
|
// TODO: Add your message handler code here
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
CVegetableDlg::~CVegetableDlg()
|
||
|
{
|
||
|
#define REMOVE_WND(wnd) if (wnd) { wnd->DestroyWindow(); delete wnd; }
|
||
|
REMOVE_WND(_VegetableDensityPage);
|
||
|
REMOVE_WND(_VegetableApperancePage);
|
||
|
REMOVE_WND(_VegetableScalePage);
|
||
|
REMOVE_WND(_VegetableRotatePage);
|
||
|
REMOVE_WND(_PropertySheet);
|
||
|
// destroy and remove wind dialog
|
||
|
REMOVE_WND(_VegetableWindDlg);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
// ***************************************************************************
|
||
|
// ***************************************************************************
|
||
|
// ***************************************************************************
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::doRefreshVegetableDisplay()
|
||
|
{
|
||
|
NL3D::CTileVegetableDesc vegetSet;
|
||
|
|
||
|
// first build the vegetSet, but don't keep <default> shapeName. and skip Hiden vegetables too
|
||
|
buildVegetableSet(vegetSet, false, false);
|
||
|
|
||
|
// then refresh window.
|
||
|
_ObjView->refreshVegetableLandscape(vegetSet);
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::refreshVegetableDisplay()
|
||
|
{
|
||
|
// if automatic refresh is checked.
|
||
|
if(CheckAutomaticRefresh.GetCheck()==1)
|
||
|
// then do it
|
||
|
doRefreshVegetableDisplay();
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::setVegetableToEdit(NL3D::CVegetable *vegetable)
|
||
|
{
|
||
|
if(vegetable == NULL)
|
||
|
{
|
||
|
// Show the SelectVegetableStaticText
|
||
|
SelectVegetableStaticText.ShowWindow(true);
|
||
|
|
||
|
// Hide the property sheet.
|
||
|
_PropertySheet->ShowWindow(false);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Hide the SelectVegetableStaticText
|
||
|
SelectVegetableStaticText.ShowWindow(false);
|
||
|
|
||
|
// Setup 3 property pages.
|
||
|
_VegetableDensityPage->setVegetableToEdit(vegetable);
|
||
|
_VegetableApperancePage->setVegetableToEdit(vegetable);
|
||
|
_VegetableScalePage->setVegetableToEdit(vegetable);
|
||
|
_VegetableRotatePage->setVegetableToEdit(vegetable);
|
||
|
|
||
|
// Show the property sheet.
|
||
|
_PropertySheet->ShowWindow(true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
uint CVegetableDlg::getNumVegetables() const
|
||
|
{
|
||
|
return (uint)_Vegetables.size();
|
||
|
}
|
||
|
// ***************************************************************************
|
||
|
std::string CVegetableDlg::getVegetableName(uint id) const
|
||
|
{
|
||
|
nlassert(id<_Vegetables.size());
|
||
|
return _Vegetables[id].VegetableName;
|
||
|
}
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::updateCurSelVegetableName()
|
||
|
{
|
||
|
sint id= VegetableList.GetCurSel();
|
||
|
if(id!=LB_ERR)
|
||
|
{
|
||
|
_Vegetables[id].updateVegetableName();
|
||
|
// replace name in the listBox: must delete, and re-insert
|
||
|
VegetableList.DeleteString(id);
|
||
|
VegetableList.InsertString(id, _Vegetables[id].VegetableName.c_str());
|
||
|
VegetableList.SetCurSel(id);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
NL3D::CVegetable *CVegetableDlg::getVegetable(uint id) const
|
||
|
{
|
||
|
nlassert(id<_Vegetables.size());
|
||
|
return _Vegetables[id].Vegetable;
|
||
|
}
|
||
|
|
||
|
|
||
|
static const char *NL_DefaultVegetName= "<default>";
|
||
|
|
||
|
// ***************************************************************************
|
||
|
CVegetableDlg::CVegetableDesc::CVegetableDesc()
|
||
|
{
|
||
|
Vegetable= NULL;
|
||
|
VegetableName= NL_DefaultVegetName;
|
||
|
Visible= true;
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::CVegetableDesc::initDefaultVegetable()
|
||
|
{
|
||
|
Vegetable= new NL3D::CVegetable;
|
||
|
// update vegetableName according to Vegetable
|
||
|
updateVegetableName();
|
||
|
|
||
|
// init Vegetable with some good default values.
|
||
|
|
||
|
// General/Density.
|
||
|
// Density.
|
||
|
Vegetable->Density.Abs= NL_VEGETABLE_DENSITY_ABS_DEFAULT;
|
||
|
Vegetable->Density.Rand= NL_VEGETABLE_DENSITY_RAND_DEFAULT;
|
||
|
Vegetable->Density.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
// disable MaxDensity
|
||
|
Vegetable->MaxDensity= -1;
|
||
|
// Leave ShapeName to ""
|
||
|
// Default DistType is always 0.
|
||
|
Vegetable->DistType= 0;
|
||
|
|
||
|
|
||
|
// Apperance
|
||
|
// BendPhase
|
||
|
Vegetable->BendPhase.Abs= NL_VEGETABLE_BENDPHASE_ABS_DEFAULT;
|
||
|
Vegetable->BendPhase.Rand= NL_VEGETABLE_BENDPHASE_RAND_DEFAULT;
|
||
|
Vegetable->BendPhase.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
// BendFactor
|
||
|
Vegetable->BendFactor.Abs= NL_VEGETABLE_BENDFACTOR_ABS_DEFAULT;
|
||
|
Vegetable->BendFactor.Rand= NL_VEGETABLE_BENDFACTOR_RAND_DEFAULT;
|
||
|
Vegetable->BendFactor.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
// Color
|
||
|
Vegetable->Color.NoiseValue.Abs= NL_VEGETABLE_COLOR_ABS_DEFAULT;
|
||
|
Vegetable->Color.NoiseValue.Rand= NL_VEGETABLE_COLOR_RAND_DEFAULT;
|
||
|
Vegetable->Color.NoiseValue.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
|
||
|
// Scale
|
||
|
// ScaleXY
|
||
|
Vegetable->Sxy.Abs= NL_VEGETABLE_SCALE_ABS_DEFAULT;
|
||
|
Vegetable->Sxy.Rand= NL_VEGETABLE_SCALE_RAND_DEFAULT;
|
||
|
Vegetable->Sxy.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
// ScaleZ.
|
||
|
Vegetable->Sz.Abs= NL_VEGETABLE_SCALE_ABS_DEFAULT;
|
||
|
Vegetable->Sz.Rand= NL_VEGETABLE_SCALE_RAND_DEFAULT;
|
||
|
Vegetable->Sz.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
|
||
|
// Rotate
|
||
|
// RotateX
|
||
|
Vegetable->Rx.Abs= NL_VEGETABLE_ROTATEX_ABS_DEFAULT;
|
||
|
Vegetable->Rx.Rand= NL_VEGETABLE_ROTATEX_RAND_DEFAULT;
|
||
|
Vegetable->Rx.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
// RotateY
|
||
|
Vegetable->Ry.Abs= NL_VEGETABLE_ROTATEY_ABS_DEFAULT;
|
||
|
Vegetable->Ry.Rand= NL_VEGETABLE_ROTATEY_RAND_DEFAULT;
|
||
|
Vegetable->Ry.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
|
||
|
// RotateZ
|
||
|
Vegetable->Rz.Abs= NL_VEGETABLE_ROTATEZ_ABS_DEFAULT;
|
||
|
Vegetable->Rz.Rand= NL_VEGETABLE_ROTATEZ_RAND_DEFAULT;
|
||
|
Vegetable->Rz.Frequency= NL_VEGETABLE_ROTATEZ_FREQ_DEFAULT;
|
||
|
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::CVegetableDesc::initVegetable(const NL3D::CVegetable &vegetable)
|
||
|
{
|
||
|
Vegetable= new NL3D::CVegetable(vegetable);
|
||
|
// update vegetableName according to Vegetable
|
||
|
updateVegetableName();
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::CVegetableDesc::updateVegetableName()
|
||
|
{
|
||
|
// Build the vegetable Name according to the ShapeName
|
||
|
if(Vegetable->ShapeName=="")
|
||
|
{
|
||
|
VegetableName= NL_DefaultVegetName;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
std::string::size_type pos= Vegetable->ShapeName.find(".veget");
|
||
|
VegetableName= Vegetable->ShapeName.substr(0, pos);
|
||
|
// And (to be clearer) append distance of creation.
|
||
|
char str[256];
|
||
|
sprintf(str, " - %dm", (Vegetable->DistType+1)*10);
|
||
|
VegetableName+= str;
|
||
|
// NB: if you add info with other parameters, you must use updateCurSelVegetableName() if they change
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::CVegetableDesc::deleteVegetable()
|
||
|
{
|
||
|
delete Vegetable;
|
||
|
Vegetable= NULL;
|
||
|
VegetableName= NL_DefaultVegetName;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::clearVegetables()
|
||
|
{
|
||
|
// delete all vegetables.
|
||
|
for(uint i=0; i<_Vegetables.size(); i++)
|
||
|
{
|
||
|
_Vegetables[i].deleteVegetable();
|
||
|
}
|
||
|
_Vegetables.clear();
|
||
|
|
||
|
// update view
|
||
|
VegetableList.ResetContent();
|
||
|
setVegetableToEdit(NULL);
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
bool CVegetableDlg::loadVegetableSet(NL3D::CTileVegetableDesc &vegetSet, const char *title)
|
||
|
{
|
||
|
vegetSet.clear();
|
||
|
bool ok= false;
|
||
|
|
||
|
CFileDialog fd(TRUE, ".vegetset", "*.vegetset", 0, NULL, this) ;
|
||
|
fd.m_ofn.lpstrTitle= title;
|
||
|
if (fd.DoModal() == IDOK)
|
||
|
{
|
||
|
NLMISC::CIFile f;
|
||
|
|
||
|
ok= true;
|
||
|
|
||
|
if( f.open((const char*)fd.GetPathName()) )
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
// read the vegetable
|
||
|
f.serial(vegetSet);
|
||
|
// bkup fileName.
|
||
|
_LastVegetSetName= (const char*)fd.GetFileName();
|
||
|
}
|
||
|
catch(NLMISC::EStream &)
|
||
|
{
|
||
|
ok= false;
|
||
|
MessageBox("Failed to load file!");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ok= false;
|
||
|
MessageBox("Failed to open file!");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::buildVegetableSet(NL3D::CTileVegetableDesc &vegetSet, bool keepDefaultShapeName, bool keepHiden )
|
||
|
{
|
||
|
vegetSet.clear();
|
||
|
float degToRad= (float)(NLMISC::Pi / 180.f);
|
||
|
|
||
|
// build the list.
|
||
|
std::vector<NL3D::CVegetable> vegetables;
|
||
|
for(uint i=0;i<_Vegetables.size();i++)
|
||
|
{
|
||
|
// if don't want to keep <default> ShapeNames, skip them.
|
||
|
if(!keepDefaultShapeName && _Vegetables[i].Vegetable->ShapeName=="")
|
||
|
continue;
|
||
|
// if don't want to keep hiden vegetables, skip them.
|
||
|
if(!keepHiden && !_Vegetables[i].Visible)
|
||
|
continue;
|
||
|
|
||
|
vegetables.push_back(*_Vegetables[i].Vegetable);
|
||
|
// get dst index.
|
||
|
uint dstId= (uint)vegetables.size()-1;
|
||
|
// transform degrees in radians.
|
||
|
vegetables[dstId].Rx.Abs*= degToRad;
|
||
|
vegetables[dstId].Rx.Rand*= degToRad;
|
||
|
vegetables[dstId].Ry.Abs*= degToRad;
|
||
|
vegetables[dstId].Ry.Rand*= degToRad;
|
||
|
vegetables[dstId].Rz.Abs*= degToRad;
|
||
|
vegetables[dstId].Rz.Rand*= degToRad;
|
||
|
}
|
||
|
|
||
|
// build the set.
|
||
|
vegetSet.build(vegetables);
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::appendVegetableSet(NL3D::CTileVegetableDesc &vegetSet)
|
||
|
{
|
||
|
float radToDeg= (float)(180.f / NLMISC::Pi);
|
||
|
|
||
|
// for all distances Types.
|
||
|
for(uint distType=0; distType<NL3D_VEGETABLE_BLOCK_NUMDIST; distType++)
|
||
|
{
|
||
|
// retrieve list of vegetable
|
||
|
const std::vector<NL3D::CVegetable> &vegetList= vegetSet.getVegetableList(distType);
|
||
|
|
||
|
// for all of them
|
||
|
for(uint i=0;i<vegetList.size();i++)
|
||
|
{
|
||
|
// append the vegetable to the list.
|
||
|
NL3D::CVegetable veget= vegetList[i];
|
||
|
|
||
|
// transform radians into degrees.
|
||
|
veget.Rx.Abs*= radToDeg;
|
||
|
veget.Rx.Rand*= radToDeg;
|
||
|
veget.Ry.Abs*= radToDeg;
|
||
|
veget.Ry.Rand*= radToDeg;
|
||
|
veget.Rz.Abs*= radToDeg;
|
||
|
veget.Rz.Rand*= radToDeg;
|
||
|
|
||
|
// Add a new vegetable to the list.
|
||
|
_Vegetables.push_back( CVegetableDesc ());
|
||
|
uint id= (uint)_Vegetables.size()-1;
|
||
|
_Vegetables[id].initVegetable(veget);
|
||
|
|
||
|
// update view
|
||
|
VegetableList.AddString(_Vegetables[id].VegetableName.c_str());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
// ***************************************************************************
|
||
|
// CVegetableDlg message handlers
|
||
|
// ***************************************************************************
|
||
|
// ***************************************************************************
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
BOOL CVegetableDlg::OnInitDialog()
|
||
|
{
|
||
|
CDialog::OnInitDialog();
|
||
|
|
||
|
|
||
|
_PropertySheet= new CPropertySheet();
|
||
|
|
||
|
// Create the 4 pages.
|
||
|
// density
|
||
|
_VegetableDensityPage= new CVegetableDensityPage();
|
||
|
_VegetableDensityPage->initVegetableDlg(this);
|
||
|
_PropertySheet->AddPage(_VegetableDensityPage);
|
||
|
// appearance
|
||
|
_VegetableApperancePage= new CVegetableApperancePage();
|
||
|
_VegetableApperancePage->initVegetableDlg(this);
|
||
|
_PropertySheet->AddPage(_VegetableApperancePage);
|
||
|
// scale
|
||
|
_VegetableScalePage= new CVegetableScalePage();
|
||
|
_VegetableScalePage->initVegetableDlg(this);
|
||
|
_PropertySheet->AddPage(_VegetableScalePage);
|
||
|
// rot
|
||
|
_VegetableRotatePage= new CVegetableRotatePage();
|
||
|
_VegetableRotatePage->initVegetableDlg(this);
|
||
|
_PropertySheet->AddPage(_VegetableRotatePage);
|
||
|
|
||
|
// Create the _PropertySheet in the DialogBox.
|
||
|
_PropertySheet->Create(this, WS_CHILD | DS_CONTROL | WS_VISIBLE, 0);
|
||
|
// Enlarge at max size of the PropertySheet
|
||
|
_PropertySheet->MoveWindow(160, 0, 1000, 570);
|
||
|
|
||
|
|
||
|
// Force creation of the 4 pages, by selecting them.
|
||
|
_PropertySheet->SetActivePage(0);
|
||
|
_PropertySheet->SetActivePage(1);
|
||
|
_PropertySheet->SetActivePage(2);
|
||
|
_PropertySheet->SetActivePage(3);
|
||
|
// Start with Density page selected.
|
||
|
_PropertySheet->SetActivePage(0);
|
||
|
|
||
|
|
||
|
// Init the Dlg with no vegetable to edit.
|
||
|
setVegetableToEdit(NULL);
|
||
|
|
||
|
// Enable the Automatic update by default.
|
||
|
CheckAutomaticRefresh.SetCheck(1);
|
||
|
CheckEnableVegetable.SetCheck(1);
|
||
|
CheckSnapToGround.SetCheck(1);
|
||
|
|
||
|
// Disable the refresh button, because landscape not displayed by default
|
||
|
ButtonRefreshLandscape.EnableWindow(false);
|
||
|
|
||
|
|
||
|
return TRUE; // return TRUE unless you set the focus to a control
|
||
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::OnSelchangeListVegetable()
|
||
|
{
|
||
|
// set the new vegetable to edit.
|
||
|
sint id= VegetableList.GetCurSel();
|
||
|
if(id==LB_ERR)
|
||
|
setVegetableToEdit( NULL );
|
||
|
else
|
||
|
setVegetableToEdit( _Vegetables[id].Vegetable );
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableAdd()
|
||
|
{
|
||
|
// Add a new vegetable to the list.
|
||
|
_Vegetables.push_back(CVegetableDesc ());
|
||
|
uint id= (uint)_Vegetables.size()-1;
|
||
|
_Vegetables[id].initDefaultVegetable();
|
||
|
|
||
|
// update view
|
||
|
VegetableList.AddString(_Vegetables[id].VegetableName.c_str());
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableClear()
|
||
|
{
|
||
|
if(_Vegetables.size()==0)
|
||
|
return;
|
||
|
|
||
|
if( MessageBox("Clear all the list?", "Clear List", MB_OKCANCEL | MB_ICONWARNING | MB_APPLMODAL)==IDOK )
|
||
|
{
|
||
|
clearVegetables();
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableInsert()
|
||
|
{
|
||
|
sint id= VegetableList.GetCurSel();
|
||
|
if(id!=LB_ERR)
|
||
|
{
|
||
|
// Add a new vegetable to the list.
|
||
|
_Vegetables.insert(_Vegetables.begin()+id, CVegetableDesc());
|
||
|
_Vegetables[id].initDefaultVegetable();
|
||
|
|
||
|
// update view
|
||
|
VegetableList.InsertString(id, _Vegetables[id].VegetableName.c_str());
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// perform like an add.
|
||
|
OnButtonVegetableAdd();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableRemove()
|
||
|
{
|
||
|
sint id= VegetableList.GetCurSel();
|
||
|
if(id!=LB_ERR)
|
||
|
{
|
||
|
// UnSelect
|
||
|
setVegetableToEdit(NULL);
|
||
|
|
||
|
// erase the vegetable from the list.
|
||
|
_Vegetables[id].deleteVegetable();
|
||
|
_Vegetables.erase(_Vegetables.begin()+id);
|
||
|
|
||
|
// update view
|
||
|
VegetableList.DeleteString(id);
|
||
|
|
||
|
// select if posssible at the same id.
|
||
|
if(id>=(sint)_Vegetables.size())
|
||
|
id--;
|
||
|
if(id>=0)
|
||
|
{
|
||
|
// set the cur selection
|
||
|
VegetableList.SetCurSel(id);
|
||
|
// And set the new to edit
|
||
|
OnSelchangeListVegetable();
|
||
|
}
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::OnButtonVegetableLoadDesc()
|
||
|
{
|
||
|
CFileDialog fd(TRUE, ".vegetdesc", "*.vegetdesc", 0, NULL, this) ;
|
||
|
fd.m_ofn.lpstrTitle= "Open Vegetable Descriptor";
|
||
|
if (fd.DoModal() == IDOK)
|
||
|
{
|
||
|
NLMISC::CIFile f;
|
||
|
|
||
|
if( f.open((const char*)fd.GetPathName()) )
|
||
|
{
|
||
|
NL3D::CVegetable veget;
|
||
|
try
|
||
|
{
|
||
|
// read the vegetable
|
||
|
f.serial(veget);
|
||
|
// Add a new vegetable to the list.
|
||
|
_Vegetables.push_back(CVegetableDesc ());
|
||
|
uint id= (uint)_Vegetables.size()-1;
|
||
|
_Vegetables[id].initVegetable(veget);
|
||
|
|
||
|
// update view
|
||
|
VegetableList.AddString(_Vegetables[id].VegetableName.c_str());
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
catch(NLMISC::EStream &)
|
||
|
{
|
||
|
MessageBox("Failed to load file!");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MessageBox("Failed to open file!");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableSaveDesc()
|
||
|
{
|
||
|
sint id= VegetableList.GetCurSel();
|
||
|
if(id!=LB_ERR)
|
||
|
{
|
||
|
NL3D::CVegetable &veget= *_Vegetables[id].Vegetable;
|
||
|
|
||
|
std::string fileName= _Vegetables[id].VegetableName + ".vegetdesc";
|
||
|
|
||
|
CFileDialog fd(FALSE, "vegetdesc", fileName.c_str(), OFN_OVERWRITEPROMPT, "VegetDescFiles (*.vegetdesc)|*.vegetdesc|All Files (*.*)|*.*||", this) ;
|
||
|
fd.m_ofn.lpstrTitle= "Save Vegetable Descriptor";
|
||
|
if (fd.DoModal() == IDOK)
|
||
|
{
|
||
|
NLMISC::COFile f;
|
||
|
|
||
|
if( f.open((const char*)fd.GetPathName()) )
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
// save the vegetable
|
||
|
f.serial(veget);
|
||
|
}
|
||
|
catch(NLMISC::EStream &)
|
||
|
{
|
||
|
MessageBox("Failed to save file!");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MessageBox("Failed to open file for write!");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::OnButtonVegetableLoadSet()
|
||
|
{
|
||
|
NL3D::CTileVegetableDesc vegetSet;
|
||
|
// if succes to load the vegetSet
|
||
|
if(loadVegetableSet(vegetSet, "Load Vegetable Set"))
|
||
|
{
|
||
|
// Delete all vegetables.
|
||
|
clearVegetables();
|
||
|
|
||
|
// build them from list.
|
||
|
appendVegetableSet(vegetSet);
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableAppendSet()
|
||
|
{
|
||
|
NL3D::CTileVegetableDesc vegetSet;
|
||
|
// if succes to load the vegetSet
|
||
|
if(loadVegetableSet(vegetSet, "Append Vegetable Set"))
|
||
|
{
|
||
|
// Do not Delete any vegetables.
|
||
|
// build them from list.
|
||
|
appendVegetableSet(vegetSet);
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableSaveSet()
|
||
|
{
|
||
|
NL3D::CTileVegetableDesc vegetSet;
|
||
|
|
||
|
// first build the vegetSet.
|
||
|
buildVegetableSet(vegetSet);
|
||
|
|
||
|
// Then try to save it.
|
||
|
CFileDialog fd(FALSE, "vegetset", _LastVegetSetName.c_str(), OFN_OVERWRITEPROMPT, "VegetSetFiles (*.vegetset)|*.vegetset|All Files (*.*)|*.*||", this) ;
|
||
|
fd.m_ofn.lpstrTitle= "Save Vegetable Set";
|
||
|
if (fd.DoModal() == IDOK)
|
||
|
{
|
||
|
NLMISC::COFile f;
|
||
|
|
||
|
if( f.open((const char*)fd.GetPathName()) )
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
// save the vegetable set
|
||
|
f.serial(vegetSet);
|
||
|
}
|
||
|
catch(NLMISC::EStream &)
|
||
|
{
|
||
|
MessageBox("Failed to save file!");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MessageBox("Failed to open file for write!");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::OnButtonVegetableCopy()
|
||
|
{
|
||
|
sint dstid= VegetableList.GetCurSel();
|
||
|
if(dstid!=LB_ERR)
|
||
|
{
|
||
|
CVegetableCopyDlg dlg(this);
|
||
|
|
||
|
if(dlg.DoModal()==IDOK)
|
||
|
{
|
||
|
sint srcid= dlg.VegetableSelected;
|
||
|
if(srcid!=LB_ERR && srcid!=dstid)
|
||
|
{
|
||
|
// copy from src to dst
|
||
|
NL3D::CVegetable &vegetSrc= *_Vegetables[srcid].Vegetable;
|
||
|
NL3D::CVegetable &vegetDst= *_Vegetables[dstid].Vegetable;
|
||
|
|
||
|
// copy all?
|
||
|
if(!dlg.SubsetCopy)
|
||
|
{
|
||
|
// copy all the vegetable
|
||
|
vegetDst= vegetSrc;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// copy mesh part.
|
||
|
if(dlg.Mesh)
|
||
|
{
|
||
|
vegetDst.ShapeName= vegetSrc.ShapeName;
|
||
|
}
|
||
|
// Density/dist.
|
||
|
if(dlg.Distance)
|
||
|
vegetDst.DistType = vegetSrc.DistType;
|
||
|
if(dlg.Density)
|
||
|
vegetDst.Density = vegetSrc.Density;
|
||
|
if(dlg.MaxDensity)
|
||
|
vegetDst.MaxDensity = vegetSrc.MaxDensity;
|
||
|
if(dlg.AngleSetup)
|
||
|
{
|
||
|
switch(vegetSrc.getAngleType())
|
||
|
{
|
||
|
case NL3D::CVegetable::AngleGround:
|
||
|
vegetDst.setAngleGround(vegetSrc.getCosAngleMin());
|
||
|
break;
|
||
|
case NL3D::CVegetable::AngleCeiling:
|
||
|
vegetDst.setAngleCeiling(vegetSrc.getCosAngleMax());
|
||
|
break;
|
||
|
case NL3D::CVegetable::AngleWall:
|
||
|
vegetDst.setAngleWall(vegetSrc.getCosAngleMin(), vegetSrc.getCosAngleMax());
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// Appearance
|
||
|
if(dlg.BendPhase)
|
||
|
vegetDst.BendPhase = vegetSrc.BendPhase;
|
||
|
if(dlg.BendFactor)
|
||
|
vegetDst.BendFactor = vegetSrc.BendFactor;
|
||
|
if(dlg.ColorNoise)
|
||
|
vegetDst.Color.NoiseValue = vegetSrc.Color.NoiseValue;
|
||
|
if(dlg.ColorSetup)
|
||
|
vegetDst.Color.Gradients = vegetSrc.Color.Gradients;
|
||
|
// Scale/Rot
|
||
|
if(dlg.ScaleXY)
|
||
|
vegetDst.Sxy = vegetSrc.Sxy;
|
||
|
if(dlg.ScaleZ)
|
||
|
vegetDst.Sz = vegetSrc.Sz;
|
||
|
if(dlg.RotateX)
|
||
|
vegetDst.Rx = vegetSrc.Rx;
|
||
|
if(dlg.RotateY)
|
||
|
vegetDst.Ry = vegetSrc.Ry;
|
||
|
if(dlg.RotateZ)
|
||
|
vegetDst.Rz = vegetSrc.Rz;
|
||
|
}
|
||
|
|
||
|
// update dst vegetableName according to Vegetable copied
|
||
|
_Vegetables[dstid].updateVegetableName();
|
||
|
|
||
|
|
||
|
// deselect, then reselect, to refresh.
|
||
|
setVegetableToEdit(NULL);
|
||
|
// set the cur selection
|
||
|
VegetableList.SetCurSel(dstid);
|
||
|
// And set the new to edit
|
||
|
OnSelchangeListVegetable();
|
||
|
|
||
|
// must also update our name in view
|
||
|
updateCurSelVegetableName();
|
||
|
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnButtonVegetableRefresh()
|
||
|
{
|
||
|
// refresh view, independently of checkBox
|
||
|
doRefreshVegetableDisplay();
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnCheckVegetableAutomatic()
|
||
|
{
|
||
|
// Enabling the checkBox do a refresh (NB: disabling don't do a refresh).
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
|
||
|
void CVegetableDlg::OnCheckVegetableShow()
|
||
|
{
|
||
|
if(CheckShowLandscape.GetCheck()==1)
|
||
|
{
|
||
|
// Landscape not created ??
|
||
|
if(!_ObjView->isVegetableLandscapeCreated())
|
||
|
{
|
||
|
// if success to create / Load the landscape.
|
||
|
if(_ObjView->createVegetableLandscape())
|
||
|
{
|
||
|
// Enable the refresh button
|
||
|
ButtonRefreshLandscape.EnableWindow(true);
|
||
|
|
||
|
// refresh view, independently of checkBox
|
||
|
doRefreshVegetableDisplay();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Failed in load, never retry.
|
||
|
CheckShowLandscape.SetCheck(0);
|
||
|
CheckShowLandscape.EnableWindow(false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// show the landscape
|
||
|
_ObjView->showVegetableLandscape();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_ObjView->hideVegetableLandscape();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::OnCheckVegetableEnable()
|
||
|
{
|
||
|
// update view.
|
||
|
_ObjView->enableLandscapeVegetable(CheckEnableVegetable.GetCheck()==1);
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::OnButtonVegetableSetupWind()
|
||
|
{
|
||
|
// create the window if necessary
|
||
|
if(!_VegetableWindDlg)
|
||
|
{
|
||
|
_VegetableWindDlg= new CVegetableWindDlg(_ObjView, this);
|
||
|
_VegetableWindDlg->Create(CVegetableWindDlg::IDD, this);
|
||
|
}
|
||
|
|
||
|
// show the window.
|
||
|
_VegetableWindDlg->ShowWindow(true);
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::OnCheckVegetableSnaptoground()
|
||
|
{
|
||
|
// update view.
|
||
|
_ObjView->snapToGroundVegetableLandscape(CheckSnapToGround.GetCheck()==1);
|
||
|
}
|
||
|
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::swapShowHideVegetable (uint id)
|
||
|
{
|
||
|
if(id>=_Vegetables.size())
|
||
|
return;
|
||
|
|
||
|
_Vegetables[id].Visible ^= true;
|
||
|
|
||
|
// update 3D view
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CVegetableDlg::setShowHideVegetable (uint id, bool visible, bool refreshDisplay)
|
||
|
{
|
||
|
if(id>=_Vegetables.size())
|
||
|
return;
|
||
|
|
||
|
_Vegetables[id].Visible= visible;
|
||
|
|
||
|
// update 3D view
|
||
|
if(refreshDisplay)
|
||
|
refreshVegetableDisplay();
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
bool CVegetableDlg::isVegetableVisible (uint id)
|
||
|
{
|
||
|
if(id>=_Vegetables.size())
|
||
|
return true;
|
||
|
|
||
|
return _Vegetables[id].Visible;
|
||
|
}
|