Added aqua_speed for rite geo 50 tryker
[ryzomcore.git] / nel / tools / 3d / object_viewer / vegetable_dlg.cpp
blobe1d420b1d7354d8117d7557bb97a7a77d3cf851d
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "std_afx.h"
22 #include "object_viewer.h"
23 #include "vegetable_dlg.h"
24 #include "vegetable_density_page.h"
25 #include "vegetable_apperance_page.h"
26 #include "vegetable_scale_page.h"
27 #include "vegetable_rotate_page.h"
28 #include "vegetable_copy_dlg.h"
29 #include "vegetable_edit_tools.h"
30 #include "vegetable_wind_dlg.h"
31 #include "nel/3d/vegetable.h"
32 #include "nel/3d/tile_vegetable_desc.h"
36 /////////////////////////////////////////////////////////////////////////////
37 // CVegetableDlg dialog
40 CVegetableDlg::CVegetableDlg(CObjectViewer *viewer, CWnd* pParent /*=NULL*/)
41 : CDialog(CVegetableDlg::IDD, pParent), _ObjView(viewer),
42 _PropertySheet(NULL), _VegetableDensityPage(NULL), _VegetableApperancePage(NULL),
43 _VegetableScalePage(NULL), _VegetableRotatePage(NULL),
44 _VegetableWindDlg(NULL)
46 nlassert(viewer);
48 _LastVegetSetName= "*.vegetset";
50 // init VegetableList
51 VegetableList.VegetableDlg= this;
53 //{{AFX_DATA_INIT(CVegetableDlg)
54 //}}AFX_DATA_INIT
58 void CVegetableDlg::DoDataExchange(CDataExchange* pDX)
60 CDialog::DoDataExchange(pDX);
61 //{{AFX_DATA_MAP(CVegetableDlg)
62 DDX_Control(pDX, IDC_LIST_VEGETABLE, VegetableList);
63 DDX_Control(pDX, IDC_STATIC_VEGETABLE_PERF, StaticPolyCount);
64 DDX_Control(pDX, IDC_CHECK_VEGETABLE_SNAPTOGROUND, CheckSnapToGround);
65 DDX_Control(pDX, IDC_CHECK_VEGETABLE_ENABLE, CheckEnableVegetable);
66 DDX_Control(pDX, IDC_CHECK_VEGETABLE_AUTOMATIC, CheckAutomaticRefresh);
67 DDX_Control(pDX, IDC_BUTTON_VEGETABLE_REFRESH, ButtonRefreshLandscape);
68 DDX_Control(pDX, IDC_CHECK_VEGETABLE_SHOW, CheckShowLandscape);
69 DDX_Control(pDX, IDC_STATIC_SELECT_VEGETABLE, SelectVegetableStaticText);
70 //}}AFX_DATA_MAP
74 BEGIN_MESSAGE_MAP(CVegetableDlg, CDialog)
75 //{{AFX_MSG_MAP(CVegetableDlg)
76 ON_WM_DESTROY()
77 ON_LBN_SELCHANGE(IDC_LIST_VEGETABLE, OnSelchangeListVegetable)
78 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_ADD, OnButtonVegetableAdd)
79 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_CLEAR, OnButtonVegetableClear)
80 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_INSERT, OnButtonVegetableInsert)
81 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_LOAD_DESC, OnButtonVegetableLoadDesc)
82 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_LOAD_SET, OnButtonVegetableLoadSet)
83 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_REMOVE, OnButtonVegetableRemove)
84 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_SAVE_DESC, OnButtonVegetableSaveDesc)
85 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_SAVE_SET, OnButtonVegetableSaveSet)
86 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_APPEND_SET, OnButtonVegetableAppendSet)
87 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_COPY, OnButtonVegetableCopy)
88 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_REFRESH, OnButtonVegetableRefresh)
89 ON_BN_CLICKED(IDC_CHECK_VEGETABLE_SHOW, OnCheckVegetableShow)
90 ON_BN_CLICKED(IDC_BUTTON_VEGETABLE_SETUP_WIND, OnButtonVegetableSetupWind)
91 ON_BN_CLICKED(IDC_CHECK_VEGETABLE_AUTOMATIC, OnCheckVegetableAutomatic)
92 ON_BN_CLICKED(IDC_CHECK_VEGETABLE_ENABLE, OnCheckVegetableEnable)
93 ON_BN_CLICKED(IDC_CHECK_VEGETABLE_SNAPTOGROUND, OnCheckVegetableSnaptoground)
94 //}}AFX_MSG_MAP
95 END_MESSAGE_MAP()
97 /////////////////////////////////////////////////////////////////////////////
98 // CVegetableDlg message handlers
100 void CVegetableDlg::OnDestroy()
102 setRegisterWindowState (this, REGKEY_OBJ_VIEW_VEGETABLE_DLG);
104 CDialog::OnDestroy();
106 // TODO: Add your message handler code here
111 CVegetableDlg::~CVegetableDlg()
113 #define REMOVE_WND(wnd) if (wnd) { wnd->DestroyWindow(); delete wnd; }
114 REMOVE_WND(_VegetableDensityPage);
115 REMOVE_WND(_VegetableApperancePage);
116 REMOVE_WND(_VegetableScalePage);
117 REMOVE_WND(_VegetableRotatePage);
118 REMOVE_WND(_PropertySheet);
119 // destroy and remove wind dialog
120 REMOVE_WND(_VegetableWindDlg);
126 // ***************************************************************************
127 // ***************************************************************************
128 // ***************************************************************************
129 // ***************************************************************************
132 // ***************************************************************************
133 void CVegetableDlg::doRefreshVegetableDisplay()
135 NL3D::CTileVegetableDesc vegetSet;
137 // first build the vegetSet, but don't keep <default> shapeName. and skip Hiden vegetables too
138 buildVegetableSet(vegetSet, false, false);
140 // then refresh window.
141 _ObjView->refreshVegetableLandscape(vegetSet);
145 // ***************************************************************************
146 void CVegetableDlg::refreshVegetableDisplay()
148 // if automatic refresh is checked.
149 if(CheckAutomaticRefresh.GetCheck()==1)
150 // then do it
151 doRefreshVegetableDisplay();
155 // ***************************************************************************
156 void CVegetableDlg::setVegetableToEdit(NL3D::CVegetable *vegetable)
158 if(vegetable == NULL)
160 // Show the SelectVegetableStaticText
161 SelectVegetableStaticText.ShowWindow(true);
163 // Hide the property sheet.
164 _PropertySheet->ShowWindow(false);
166 else
168 // Hide the SelectVegetableStaticText
169 SelectVegetableStaticText.ShowWindow(false);
171 // Setup 3 property pages.
172 _VegetableDensityPage->setVegetableToEdit(vegetable);
173 _VegetableApperancePage->setVegetableToEdit(vegetable);
174 _VegetableScalePage->setVegetableToEdit(vegetable);
175 _VegetableRotatePage->setVegetableToEdit(vegetable);
177 // Show the property sheet.
178 _PropertySheet->ShowWindow(true);
182 // ***************************************************************************
183 uint CVegetableDlg::getNumVegetables() const
185 return (uint)_Vegetables.size();
187 // ***************************************************************************
188 std::string CVegetableDlg::getVegetableName(uint id) const
190 nlassert(id<_Vegetables.size());
191 return _Vegetables[id].VegetableName;
193 // ***************************************************************************
194 void CVegetableDlg::updateCurSelVegetableName()
196 sint id= VegetableList.GetCurSel();
197 if(id!=LB_ERR)
199 _Vegetables[id].updateVegetableName();
200 // replace name in the listBox: must delete, and re-insert
201 VegetableList.DeleteString(id);
202 VegetableList.InsertString(id, nlUtf8ToTStr(_Vegetables[id].VegetableName));
203 VegetableList.SetCurSel(id);
207 // ***************************************************************************
208 NL3D::CVegetable *CVegetableDlg::getVegetable(uint id) const
210 nlassert(id<_Vegetables.size());
211 return _Vegetables[id].Vegetable;
215 static const char *NL_DefaultVegetName= "<default>";
217 // ***************************************************************************
218 CVegetableDlg::CVegetableDesc::CVegetableDesc()
220 Vegetable= NULL;
221 VegetableName= NL_DefaultVegetName;
222 Visible= true;
225 // ***************************************************************************
226 void CVegetableDlg::CVegetableDesc::initDefaultVegetable()
228 Vegetable= new NL3D::CVegetable;
229 // update vegetableName according to Vegetable
230 updateVegetableName();
232 // init Vegetable with some good default values.
234 // General/Density.
235 // Density.
236 Vegetable->Density.Abs= NL_VEGETABLE_DENSITY_ABS_DEFAULT;
237 Vegetable->Density.Rand= NL_VEGETABLE_DENSITY_RAND_DEFAULT;
238 Vegetable->Density.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
239 // disable MaxDensity
240 Vegetable->MaxDensity= -1;
241 // Leave ShapeName to ""
242 // Default DistType is always 0.
243 Vegetable->DistType= 0;
246 // Apperance
247 // BendPhase
248 Vegetable->BendPhase.Abs= NL_VEGETABLE_BENDPHASE_ABS_DEFAULT;
249 Vegetable->BendPhase.Rand= NL_VEGETABLE_BENDPHASE_RAND_DEFAULT;
250 Vegetable->BendPhase.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
251 // BendFactor
252 Vegetable->BendFactor.Abs= NL_VEGETABLE_BENDFACTOR_ABS_DEFAULT;
253 Vegetable->BendFactor.Rand= NL_VEGETABLE_BENDFACTOR_RAND_DEFAULT;
254 Vegetable->BendFactor.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
255 // Color
256 Vegetable->Color.NoiseValue.Abs= NL_VEGETABLE_COLOR_ABS_DEFAULT;
257 Vegetable->Color.NoiseValue.Rand= NL_VEGETABLE_COLOR_RAND_DEFAULT;
258 Vegetable->Color.NoiseValue.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
260 // Scale
261 // ScaleXY
262 Vegetable->Sxy.Abs= NL_VEGETABLE_SCALE_ABS_DEFAULT;
263 Vegetable->Sxy.Rand= NL_VEGETABLE_SCALE_RAND_DEFAULT;
264 Vegetable->Sxy.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
265 // ScaleZ.
266 Vegetable->Sz.Abs= NL_VEGETABLE_SCALE_ABS_DEFAULT;
267 Vegetable->Sz.Rand= NL_VEGETABLE_SCALE_RAND_DEFAULT;
268 Vegetable->Sz.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
270 // Rotate
271 // RotateX
272 Vegetable->Rx.Abs= NL_VEGETABLE_ROTATEX_ABS_DEFAULT;
273 Vegetable->Rx.Rand= NL_VEGETABLE_ROTATEX_RAND_DEFAULT;
274 Vegetable->Rx.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
275 // RotateY
276 Vegetable->Ry.Abs= NL_VEGETABLE_ROTATEY_ABS_DEFAULT;
277 Vegetable->Ry.Rand= NL_VEGETABLE_ROTATEY_RAND_DEFAULT;
278 Vegetable->Ry.Frequency= NL_VEGETABLE_FREQ_DEFAULT;
279 // RotateZ
280 Vegetable->Rz.Abs= NL_VEGETABLE_ROTATEZ_ABS_DEFAULT;
281 Vegetable->Rz.Rand= NL_VEGETABLE_ROTATEZ_RAND_DEFAULT;
282 Vegetable->Rz.Frequency= NL_VEGETABLE_ROTATEZ_FREQ_DEFAULT;
286 // ***************************************************************************
287 void CVegetableDlg::CVegetableDesc::initVegetable(const NL3D::CVegetable &vegetable)
289 Vegetable= new NL3D::CVegetable(vegetable);
290 // update vegetableName according to Vegetable
291 updateVegetableName();
295 // ***************************************************************************
296 void CVegetableDlg::CVegetableDesc::updateVegetableName()
298 // Build the vegetable Name according to the ShapeName
299 if(Vegetable->ShapeName.empty())
301 VegetableName= NL_DefaultVegetName;
303 else
305 std::string::size_type pos= Vegetable->ShapeName.find(".veget");
306 VegetableName= Vegetable->ShapeName.substr(0, pos);
307 // And (to be clearer) append distance of creation.
308 char str[256];
309 sprintf(str, " - %dm", (Vegetable->DistType+1)*10);
310 VegetableName+= str;
311 // NB: if you add info with other parameters, you must use updateCurSelVegetableName() if they change
316 // ***************************************************************************
317 void CVegetableDlg::CVegetableDesc::deleteVegetable()
319 delete Vegetable;
320 Vegetable= NULL;
321 VegetableName= NL_DefaultVegetName;
325 // ***************************************************************************
326 void CVegetableDlg::clearVegetables()
328 // delete all vegetables.
329 for(uint i=0; i<_Vegetables.size(); i++)
331 _Vegetables[i].deleteVegetable();
333 _Vegetables.clear();
335 // update view
336 VegetableList.ResetContent();
337 setVegetableToEdit(NULL);
341 // ***************************************************************************
342 bool CVegetableDlg::loadVegetableSet(NL3D::CTileVegetableDesc &vegetSet, const TCHAR *title)
344 vegetSet.clear();
345 bool ok= false;
347 CFileDialog fd(TRUE, _T(".vegetset"), _T("*.vegetset"), 0, NULL, this) ;
348 fd.m_ofn.lpstrTitle = title;
349 if (fd.DoModal() == IDOK)
351 NLMISC::CIFile f;
353 ok= true;
355 if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
359 // read the vegetable
360 f.serial(vegetSet);
361 // bkup fileName.
362 _LastVegetSetName = NLMISC::tStrToUtf8(fd.GetFileName());
364 catch(const NLMISC::EStream &)
366 ok= false;
367 MessageBox(_T("Failed to load file!"));
370 else
372 ok= false;
373 MessageBox(_T("Failed to open file!"));
377 return ok;
380 // ***************************************************************************
381 void CVegetableDlg::buildVegetableSet(NL3D::CTileVegetableDesc &vegetSet, bool keepDefaultShapeName, bool keepHiden )
383 vegetSet.clear();
384 float degToRad= (float)(NLMISC::Pi / 180.f);
386 // build the list.
387 std::vector<NL3D::CVegetable> vegetables;
388 for(uint i=0;i<_Vegetables.size();i++)
390 // if don't want to keep <default> ShapeNames, skip them.
391 if(!keepDefaultShapeName && _Vegetables[i].Vegetable->ShapeName.empty())
392 continue;
393 // if don't want to keep hiden vegetables, skip them.
394 if(!keepHiden && !_Vegetables[i].Visible)
395 continue;
397 vegetables.push_back(*_Vegetables[i].Vegetable);
398 // get dst index.
399 uint dstId= (uint)vegetables.size()-1;
400 // transform degrees in radians.
401 vegetables[dstId].Rx.Abs*= degToRad;
402 vegetables[dstId].Rx.Rand*= degToRad;
403 vegetables[dstId].Ry.Abs*= degToRad;
404 vegetables[dstId].Ry.Rand*= degToRad;
405 vegetables[dstId].Rz.Abs*= degToRad;
406 vegetables[dstId].Rz.Rand*= degToRad;
409 // build the set.
410 vegetSet.build(vegetables);
414 // ***************************************************************************
415 void CVegetableDlg::appendVegetableSet(NL3D::CTileVegetableDesc &vegetSet)
417 float radToDeg= (float)(180.f / NLMISC::Pi);
419 // for all distances Types.
420 for(uint distType=0; distType<NL3D_VEGETABLE_BLOCK_NUMDIST; distType++)
422 // retrieve list of vegetable
423 const std::vector<NL3D::CVegetable> &vegetList= vegetSet.getVegetableList(distType);
425 // for all of them
426 for(uint i=0;i<vegetList.size();i++)
428 // append the vegetable to the list.
429 NL3D::CVegetable veget= vegetList[i];
431 // transform radians into degrees.
432 veget.Rx.Abs*= radToDeg;
433 veget.Rx.Rand*= radToDeg;
434 veget.Ry.Abs*= radToDeg;
435 veget.Ry.Rand*= radToDeg;
436 veget.Rz.Abs*= radToDeg;
437 veget.Rz.Rand*= radToDeg;
439 // Add a new vegetable to the list.
440 _Vegetables.push_back( CVegetableDesc ());
441 uint id= (uint)_Vegetables.size()-1;
442 _Vegetables[id].initVegetable(veget);
444 // update view
445 VegetableList.AddString(nlUtf8ToTStr(_Vegetables[id].VegetableName));
451 // ***************************************************************************
452 // ***************************************************************************
453 // CVegetableDlg message handlers
454 // ***************************************************************************
455 // ***************************************************************************
458 // ***************************************************************************
459 BOOL CVegetableDlg::OnInitDialog()
461 CDialog::OnInitDialog();
464 _PropertySheet= new CPropertySheet();
466 // Create the 4 pages.
467 // density
468 _VegetableDensityPage= new CVegetableDensityPage();
469 _VegetableDensityPage->initVegetableDlg(this);
470 _PropertySheet->AddPage(_VegetableDensityPage);
471 // appearance
472 _VegetableApperancePage= new CVegetableApperancePage();
473 _VegetableApperancePage->initVegetableDlg(this);
474 _PropertySheet->AddPage(_VegetableApperancePage);
475 // scale
476 _VegetableScalePage= new CVegetableScalePage();
477 _VegetableScalePage->initVegetableDlg(this);
478 _PropertySheet->AddPage(_VegetableScalePage);
479 // rot
480 _VegetableRotatePage= new CVegetableRotatePage();
481 _VegetableRotatePage->initVegetableDlg(this);
482 _PropertySheet->AddPage(_VegetableRotatePage);
484 // Create the _PropertySheet in the DialogBox.
485 _PropertySheet->Create(this, WS_CHILD | DS_CONTROL | WS_VISIBLE, 0);
486 // Enlarge at max size of the PropertySheet
487 _PropertySheet->MoveWindow(160, 0, 1000, 570);
490 // Force creation of the 4 pages, by selecting them.
491 _PropertySheet->SetActivePage(0);
492 _PropertySheet->SetActivePage(1);
493 _PropertySheet->SetActivePage(2);
494 _PropertySheet->SetActivePage(3);
495 // Start with Density page selected.
496 _PropertySheet->SetActivePage(0);
499 // Init the Dlg with no vegetable to edit.
500 setVegetableToEdit(NULL);
502 // Enable the Automatic update by default.
503 CheckAutomaticRefresh.SetCheck(1);
504 CheckEnableVegetable.SetCheck(1);
505 CheckSnapToGround.SetCheck(1);
507 // Disable the refresh button, because landscape not displayed by default
508 ButtonRefreshLandscape.EnableWindow(false);
511 return TRUE; // return TRUE unless you set the focus to a control
512 // EXCEPTION: OCX Property Pages should return FALSE
516 // ***************************************************************************
517 void CVegetableDlg::OnSelchangeListVegetable()
519 // set the new vegetable to edit.
520 sint id= VegetableList.GetCurSel();
521 if(id==LB_ERR)
522 setVegetableToEdit( NULL );
523 else
524 setVegetableToEdit( _Vegetables[id].Vegetable );
527 void CVegetableDlg::OnButtonVegetableAdd()
529 // Add a new vegetable to the list.
530 _Vegetables.push_back(CVegetableDesc ());
531 uint id= (uint)_Vegetables.size()-1;
532 _Vegetables[id].initDefaultVegetable();
534 // update view
535 VegetableList.AddString(nlUtf8ToTStr(_Vegetables[id].VegetableName));
537 // update 3D view
538 refreshVegetableDisplay();
541 void CVegetableDlg::OnButtonVegetableClear()
543 if(_Vegetables.size()==0)
544 return;
546 if( MessageBox(_T("Clear all the list?"), _T("Clear List"), MB_OKCANCEL | MB_ICONWARNING | MB_APPLMODAL)==IDOK )
548 clearVegetables();
550 // update 3D view
551 refreshVegetableDisplay();
555 void CVegetableDlg::OnButtonVegetableInsert()
557 sint id= VegetableList.GetCurSel();
558 if(id!=LB_ERR)
560 // Add a new vegetable to the list.
561 _Vegetables.insert(_Vegetables.begin()+id, CVegetableDesc());
562 _Vegetables[id].initDefaultVegetable();
564 // update view
565 VegetableList.InsertString(id, nlUtf8ToTStr(_Vegetables[id].VegetableName));
567 // update 3D view
568 refreshVegetableDisplay();
570 else
572 // perform like an add.
573 OnButtonVegetableAdd();
577 void CVegetableDlg::OnButtonVegetableRemove()
579 sint id= VegetableList.GetCurSel();
580 if(id!=LB_ERR)
582 // UnSelect
583 setVegetableToEdit(NULL);
585 // erase the vegetable from the list.
586 _Vegetables[id].deleteVegetable();
587 _Vegetables.erase(_Vegetables.begin()+id);
589 // update view
590 VegetableList.DeleteString(id);
592 // select if posssible at the same id.
593 if(id>=(sint)_Vegetables.size())
594 id--;
595 if(id>=0)
597 // set the cur selection
598 VegetableList.SetCurSel(id);
599 // And set the new to edit
600 OnSelchangeListVegetable();
603 // update 3D view
604 refreshVegetableDisplay();
608 // ***************************************************************************
609 void CVegetableDlg::OnButtonVegetableLoadDesc()
611 CFileDialog fd(TRUE, _T(".vegetdesc"), _T("*.vegetdesc"), 0, NULL, this) ;
612 fd.m_ofn.lpstrTitle = _T("Open Vegetable Descriptor");
613 if (fd.DoModal() == IDOK)
615 NLMISC::CIFile f;
617 if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
619 NL3D::CVegetable veget;
622 // read the vegetable
623 f.serial(veget);
624 // Add a new vegetable to the list.
625 _Vegetables.push_back(CVegetableDesc ());
626 uint id= (uint)_Vegetables.size()-1;
627 _Vegetables[id].initVegetable(veget);
629 // update view
630 VegetableList.AddString(nlUtf8ToTStr(_Vegetables[id].VegetableName));
632 // update 3D view
633 refreshVegetableDisplay();
635 catch(const NLMISC::EStream &)
637 MessageBox(_T("Failed to load file!"));
640 else
642 MessageBox(_T("Failed to open file!"));
648 void CVegetableDlg::OnButtonVegetableSaveDesc()
650 sint id= VegetableList.GetCurSel();
651 if(id!=LB_ERR)
653 NL3D::CVegetable &veget= *_Vegetables[id].Vegetable;
655 std::string fileName= _Vegetables[id].VegetableName + ".vegetdesc";
657 CFileDialog fd(FALSE, _T("vegetdesc"), nlUtf8ToTStr(fileName), OFN_OVERWRITEPROMPT, _T("VegetDescFiles (*.vegetdesc)|*.vegetdesc|All Files (*.*)|*.*||"), this);
658 fd.m_ofn.lpstrTitle = _T("Save Vegetable Descriptor");
659 if (fd.DoModal() == IDOK)
661 NLMISC::COFile f;
663 if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
667 // save the vegetable
668 f.serial(veget);
670 catch(const NLMISC::EStream &)
672 MessageBox(_T("Failed to save file!"));
675 else
677 MessageBox(_T("Failed to open file for write!"));
685 // ***************************************************************************
686 void CVegetableDlg::OnButtonVegetableLoadSet()
688 NL3D::CTileVegetableDesc vegetSet;
689 // if succes to load the vegetSet
690 if(loadVegetableSet(vegetSet, _T("Load Vegetable Set")))
692 // Delete all vegetables.
693 clearVegetables();
695 // build them from list.
696 appendVegetableSet(vegetSet);
698 // update 3D view
699 refreshVegetableDisplay();
704 void CVegetableDlg::OnButtonVegetableAppendSet()
706 NL3D::CTileVegetableDesc vegetSet;
707 // if succes to load the vegetSet
708 if(loadVegetableSet(vegetSet, _T("Append Vegetable Set")))
710 // Do not Delete any vegetables.
711 // build them from list.
712 appendVegetableSet(vegetSet);
714 // update 3D view
715 refreshVegetableDisplay();
720 void CVegetableDlg::OnButtonVegetableSaveSet()
722 NL3D::CTileVegetableDesc vegetSet;
724 // first build the vegetSet.
725 buildVegetableSet(vegetSet);
727 // Then try to save it.
728 CFileDialog fd(FALSE, _T("vegetset"), nlUtf8ToTStr(_LastVegetSetName), OFN_OVERWRITEPROMPT, _T("VegetSetFiles (*.vegetset)|*.vegetset|All Files (*.*)|*.*||"), this);
729 fd.m_ofn.lpstrTitle = _T("Save Vegetable Set");
730 if (fd.DoModal() == IDOK)
732 NLMISC::COFile f;
734 if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
738 // save the vegetable set
739 f.serial(vegetSet);
741 catch(const NLMISC::EStream &)
743 MessageBox(_T("Failed to save file!"));
746 else
748 MessageBox(_T("Failed to open file for write!"));
755 // ***************************************************************************
756 void CVegetableDlg::OnButtonVegetableCopy()
758 sint dstid= VegetableList.GetCurSel();
759 if(dstid!=LB_ERR)
761 CVegetableCopyDlg dlg(this);
763 if(dlg.DoModal()==IDOK)
765 sint srcid= dlg.VegetableSelected;
766 if(srcid!=LB_ERR && srcid!=dstid)
768 // copy from src to dst
769 NL3D::CVegetable &vegetSrc= *_Vegetables[srcid].Vegetable;
770 NL3D::CVegetable &vegetDst= *_Vegetables[dstid].Vegetable;
772 // copy all?
773 if(!dlg.SubsetCopy)
775 // copy all the vegetable
776 vegetDst= vegetSrc;
778 else
780 // copy mesh part.
781 if(dlg.Mesh)
783 vegetDst.ShapeName= vegetSrc.ShapeName;
785 // Density/dist.
786 if(dlg.Distance)
787 vegetDst.DistType = vegetSrc.DistType;
788 if(dlg.Density)
789 vegetDst.Density = vegetSrc.Density;
790 if(dlg.MaxDensity)
791 vegetDst.MaxDensity = vegetSrc.MaxDensity;
792 if(dlg.AngleSetup)
794 switch(vegetSrc.getAngleType())
796 case NL3D::CVegetable::AngleGround:
797 vegetDst.setAngleGround(vegetSrc.getCosAngleMin());
798 break;
799 case NL3D::CVegetable::AngleCeiling:
800 vegetDst.setAngleCeiling(vegetSrc.getCosAngleMax());
801 break;
802 case NL3D::CVegetable::AngleWall:
803 vegetDst.setAngleWall(vegetSrc.getCosAngleMin(), vegetSrc.getCosAngleMax());
804 break;
807 // Appearance
808 if(dlg.BendPhase)
809 vegetDst.BendPhase = vegetSrc.BendPhase;
810 if(dlg.BendFactor)
811 vegetDst.BendFactor = vegetSrc.BendFactor;
812 if(dlg.ColorNoise)
813 vegetDst.Color.NoiseValue = vegetSrc.Color.NoiseValue;
814 if(dlg.ColorSetup)
815 vegetDst.Color.Gradients = vegetSrc.Color.Gradients;
816 // Scale/Rot
817 if(dlg.ScaleXY)
818 vegetDst.Sxy = vegetSrc.Sxy;
819 if(dlg.ScaleZ)
820 vegetDst.Sz = vegetSrc.Sz;
821 if(dlg.RotateX)
822 vegetDst.Rx = vegetSrc.Rx;
823 if(dlg.RotateY)
824 vegetDst.Ry = vegetSrc.Ry;
825 if(dlg.RotateZ)
826 vegetDst.Rz = vegetSrc.Rz;
829 // update dst vegetableName according to Vegetable copied
830 _Vegetables[dstid].updateVegetableName();
833 // deselect, then reselect, to refresh.
834 setVegetableToEdit(NULL);
835 // set the cur selection
836 VegetableList.SetCurSel(dstid);
837 // And set the new to edit
838 OnSelchangeListVegetable();
840 // must also update our name in view
841 updateCurSelVegetableName();
844 // update 3D view
845 refreshVegetableDisplay();
851 void CVegetableDlg::OnButtonVegetableRefresh()
853 // refresh view, independently of checkBox
854 doRefreshVegetableDisplay();
857 void CVegetableDlg::OnCheckVegetableAutomatic()
859 // Enabling the checkBox do a refresh (NB: disabling don't do a refresh).
860 refreshVegetableDisplay();
863 void CVegetableDlg::OnCheckVegetableShow()
865 if(CheckShowLandscape.GetCheck()==1)
867 // Landscape not created ??
868 if(!_ObjView->isVegetableLandscapeCreated())
870 // if success to create / Load the landscape.
871 if(_ObjView->createVegetableLandscape())
873 // Enable the refresh button
874 ButtonRefreshLandscape.EnableWindow(true);
876 // refresh view, independently of checkBox
877 doRefreshVegetableDisplay();
879 else
881 // Failed in load, never retry.
882 CheckShowLandscape.SetCheck(0);
883 CheckShowLandscape.EnableWindow(false);
887 // show the landscape
888 _ObjView->showVegetableLandscape();
890 else
892 _ObjView->hideVegetableLandscape();
897 // ***************************************************************************
898 void CVegetableDlg::OnCheckVegetableEnable()
900 // update view.
901 _ObjView->enableLandscapeVegetable(CheckEnableVegetable.GetCheck()==1);
905 // ***************************************************************************
906 void CVegetableDlg::OnButtonVegetableSetupWind()
908 // create the window if necessary
909 if(!_VegetableWindDlg)
911 _VegetableWindDlg= new CVegetableWindDlg(_ObjView, this);
912 _VegetableWindDlg->Create(CVegetableWindDlg::IDD, this);
915 // show the window.
916 _VegetableWindDlg->ShowWindow(true);
920 // ***************************************************************************
921 void CVegetableDlg::OnCheckVegetableSnaptoground()
923 // update view.
924 _ObjView->snapToGroundVegetableLandscape(CheckSnapToGround.GetCheck()==1);
928 // ***************************************************************************
929 void CVegetableDlg::swapShowHideVegetable (uint id)
931 if(id>=_Vegetables.size())
932 return;
934 _Vegetables[id].Visible ^= true;
936 // update 3D view
937 refreshVegetableDisplay();
940 // ***************************************************************************
941 void CVegetableDlg::setShowHideVegetable (uint id, bool visible, bool refreshDisplay)
943 if(id>=_Vegetables.size())
944 return;
946 _Vegetables[id].Visible= visible;
948 // update 3D view
949 if(refreshDisplay)
950 refreshVegetableDisplay();
953 // ***************************************************************************
954 bool CVegetableDlg::isVegetableVisible (uint id)
956 if(id>=_Vegetables.size())
957 return true;
959 return _Vegetables[id].Visible;