1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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/>.
22 #include "object_viewer.h"
23 #include "main_frame.h"
24 #include "snapshot_tool_dlg.h"
25 #include "choose_name.h"
26 #include "object_viewer.h"
28 #include "nel/misc/path.h"
29 #include "nel/misc/algo.h"
30 #include "nel/misc/file.h"
32 #include "nel/3d/u_scene.h"
33 #include "nel/3d/u_driver.h"
35 #include "nel/3d/driver.h"
36 #include "nel/3d/driver_user.h"
37 #include "nel/3d/shape_bank.h"
38 #include "nel/3d/camera.h"
39 #include "nel/3d/texture_multi_file.h"
40 #include "nel/3d/mesh_base.h"
41 #include "nel/3d/particle_system.h"
42 #include "nel/3d/particle_system_shape.h"
43 #include "nel/3d/particle_system_model.h"
48 #define NEL_OV_SNAPSHOT_TOOL_REGKEY _T("Software\\Nevrax\\nel\\object_viewer\\snapshot_dlg")
51 using namespace NLMISC
;
54 /////////////////////////////////////////////////////////////////////////////
55 // CSnapshotToolDlg dialog
57 //****************************************************************************************
58 CSnapshotToolDlg::CSnapshotToolDlg(CObjectViewer
*ov
, CWnd
* pParent
/*=NULL*/)
59 : CDialog(CSnapshotToolDlg::IDD
, pParent
)
63 //{{AFX_DATA_INIT(CSnapshotToolDlg)
64 m_OutputPath
= _T("");
66 m_RecurseSubFolder
= FALSE
;
70 m_OutputPathOption
= -1;
71 m_DumpTextureSets
= FALSE
;
78 m_PostFixViewName
= FALSE
;
82 //****************************************************************************************
83 CSnapshotToolDlg::~CSnapshotToolDlg()
87 //****************************************************************************************
88 void CSnapshotToolDlg::DoDataExchange(CDataExchange
* pDX
)
90 CDialog::DoDataExchange(pDX
);
91 //{{AFX_DATA_MAP(CSnapshotToolDlg)
92 DDX_Control(pDX
, IDC_LOG
, m_Log
);
93 DDX_Control(pDX
, IDC_FILTERS
, m_Filters
);
94 DDX_Text(pDX
, IDC_OUTPUT_PATH
, m_OutputPath
);
95 DDX_Text(pDX
, IDC_INPUT_PATH
, m_InputPath
);
96 DDX_Check(pDX
, IDC_RECURSE_SUBFOLDER
, m_RecurseSubFolder
);
97 DDX_Text(pDX
, IDC_HEIGHT
, m_OutputHeight
);
98 DDV_MinMaxUInt(pDX
, m_OutputHeight
, 1, 1024);
99 DDX_Text(pDX
, IDC_WIDTH
, m_OutputWidth
);
100 DDV_MinMaxUInt(pDX
, m_OutputWidth
, 1, 1024);
101 DDX_CBIndex(pDX
, IDC_FORMAT
, m_Format
);
102 DDX_CBIndex(pDX
, IDC_OUTPUTPATH_OPTION
, m_OutputPathOption
);
103 DDX_Check(pDX
, IDC_DUMP_TEXTURE_SETS
, m_DumpTextureSets
);
104 DDX_Check(pDX
, IDC_VIEW_BACK
, m_ViewBack
);
105 DDX_Check(pDX
, IDC_VIEW_BOTTOM
, m_ViewBottom
);
106 DDX_Check(pDX
, IDC_VIEW_FRONT
, m_ViewFront
);
107 DDX_Check(pDX
, IDC_VIEW_LEFT
, m_ViewLeft
);
108 DDX_Check(pDX
, IDC_VIEW_RIGHT
, m_ViewRight
);
109 DDX_Check(pDX
, IDC_VIEW_TOP
, m_ViewTop
);
110 DDX_Check(pDX
, IDC_POSTFIX_VIEWNAME
, m_PostFixViewName
);
114 //****************************************************************************************
115 void CSnapshotToolDlg::stringFromRegistry(HKEY hKey
, const TCHAR
*name
, CString
&dest
, const CString
&defaultStr
)
119 LONG result
= RegQueryValueEx(hKey
, name
, NULL
, &type
, NULL
, &size
);
121 if (type
!= REG_SZ
|| result
!= ERROR_SUCCESS
|| size
== 0)
127 std::vector
<TCHAR
> tmpDest(size
);
128 result
= RegQueryValueEx(hKey
, name
, NULL
, &type
, (BYTE
*)&tmpDest
[0], &size
);
130 if (result
!= ERROR_SUCCESS
)
140 //****************************************************************************************
141 template <class T
, class U
> void integralTypeFromRegistry(HKEY hKey
, const TCHAR
*name
, T
&dest
, const U
&defaultValue
)
150 LONG result
= RegQueryValueEx(hKey
, name
, NULL
, &type
, NULL
, &size
);
152 if (type
!= REG_DWORD
|| result
!= ERROR_SUCCESS
|| size
== 0)
154 dest
= (T
) defaultValue
;
159 result
= RegQueryValueEx(hKey
, name
, NULL
, &type
, LPBYTE(&value
), &size
);
161 if (result
!= ERROR_SUCCESS
)
171 //****************************************************************************************
172 void CSnapshotToolDlg::fromRegistry()
175 RegOpenKeyEx(HKEY_CURRENT_USER
, NEL_OV_SNAPSHOT_TOOL_REGKEY
, 0, KEY_READ
, &hKey
);
176 stringFromRegistry(hKey
, _T("InputPath"), m_InputPath
, "");
177 stringFromRegistry(hKey
, _T("OutputPath"), m_OutputPath
, "");
180 stringFromRegistry(hKey
, _T("Filters"), filters
, "*.shape");
182 std::vector
<std::string
> filterList
;
183 NLMISC::splitString(tStrToUtf8(filters
), ",", filterList
);
185 m_Filters
.ResetContent();
187 for (uint k
= 0; k
< filterList
.size(); ++k
)
189 m_Filters
.AddString(nlUtf8ToTStr(filterList
[k
]));
192 integralTypeFromRegistry(hKey
, _T("RecurseSubFolder"), (int &) m_RecurseSubFolder
, FALSE
);
193 integralTypeFromRegistry(hKey
, _T("DumpTextureSets"), (int &) m_DumpTextureSets
, TRUE
);
194 integralTypeFromRegistry(hKey
, _T("PostFixViewName"), (int &) m_PostFixViewName
, TRUE
);
195 integralTypeFromRegistry(hKey
, _T("ViewBack"), (int &) m_ViewBack
, FALSE
);
196 integralTypeFromRegistry(hKey
, _T("ViewBottom"), (int &) m_ViewBottom
, FALSE
);
197 integralTypeFromRegistry(hKey
, _T("ViewFront"), (int &) m_ViewFront
, TRUE
);
198 integralTypeFromRegistry(hKey
, _T("ViewLeft"), (int &) m_ViewLeft
, FALSE
);
199 integralTypeFromRegistry(hKey
, _T("ViewRight"), (int &) m_ViewRight
, FALSE
);
200 integralTypeFromRegistry(hKey
, _T("ViewTop"), (int &) m_ViewTop
, FALSE
);
201 integralTypeFromRegistry(hKey
, _T("OutputWidth"), m_OutputWidth
, 128);
202 integralTypeFromRegistry(hKey
, _T("OutputHeight"), m_OutputHeight
, 128);
203 integralTypeFromRegistry(hKey
, _T("Format"), m_Format
, 0);
204 integralTypeFromRegistry(hKey
, _T("OutputPathOption"), m_OutputPathOption
, 1);
206 updateUIEnabledState();
209 //****************************************************************************************
210 void CSnapshotToolDlg::toRegistry()
214 if (RegCreateKey(HKEY_CURRENT_USER
, NEL_OV_SNAPSHOT_TOOL_REGKEY
, &hKey
)==ERROR_SUCCESS
)
216 RegSetValueEx(hKey
, _T("InputPath"), 0, REG_SZ
, (BYTE
*) (LPCTSTR
) m_InputPath
, (m_InputPath
.GetLength() + 1) * sizeof(TCHAR
));
217 RegSetValueEx(hKey
, _T("OutputPath"), 0, REG_SZ
, (BYTE
*) (LPCTSTR
) m_OutputPath
, (m_OutputPath
.GetLength() + 1) * sizeof(TCHAR
));
219 for (uint k
= 0; k
< (uint
) m_Filters
.GetCount(); ++k
)
221 if (k
!=0) filters
+= ",";
223 m_Filters
.GetText(k
, filter
);
227 RegSetValueEx(hKey
, _T("Filters"), 0, REG_SZ
, (BYTE
*) (LPCTSTR
) filters
, (filters
.GetLength() + 1) * sizeof(TCHAR
));
228 DWORD recurseSubFolder
= m_RecurseSubFolder
;
229 DWORD dumpTextureSets
= m_DumpTextureSets
;
230 DWORD width
= (DWORD
) m_OutputWidth
;
231 DWORD height
= (DWORD
) m_OutputHeight
;
232 DWORD format
= m_Format
;
233 DWORD outputPathOption
= m_OutputPathOption
;
234 DWORD postFixViewName
= m_PostFixViewName
;
235 integralTypeFromRegistry(hKey
, _T("PostFixViewName"), (int &) m_PostFixViewName
, TRUE
);
236 RegSetValueEx(hKey
, _T("ViewBack"), 0, REG_DWORD
, (const BYTE
*) &m_ViewBack
, sizeof(DWORD
));
237 RegSetValueEx(hKey
, _T("ViewBottom"), 0, REG_DWORD
, (const BYTE
*) &m_ViewBottom
, sizeof(DWORD
));
238 RegSetValueEx(hKey
, _T("ViewFront"), 0, REG_DWORD
, (const BYTE
*) &m_ViewFront
, sizeof(DWORD
));
239 RegSetValueEx(hKey
, _T("ViewLeft"), 0, REG_DWORD
, (const BYTE
*) &m_ViewLeft
, sizeof(DWORD
));
240 RegSetValueEx(hKey
, _T("ViewRight"), 0, REG_DWORD
, (const BYTE
*) &m_ViewRight
, sizeof(DWORD
));
241 RegSetValueEx(hKey
, _T("ViewTop"), 0, REG_DWORD
, (const BYTE
*) &m_ViewTop
, sizeof(DWORD
));
242 RegSetValueEx(hKey
, _T("RecurseSubFolder"), 0, REG_DWORD
, (const BYTE
*) &recurseSubFolder
, sizeof(DWORD
));
243 RegSetValueEx(hKey
, _T("DumpTextureSets"), 0, REG_DWORD
, (const BYTE
*) &dumpTextureSets
, sizeof(DWORD
));
244 RegSetValueEx(hKey
, _T("OutputWidth"), 0, REG_DWORD
, (const BYTE
*) &width
, sizeof(DWORD
));
245 RegSetValueEx(hKey
, _T("OutputHeight"), 0, REG_DWORD
, (const BYTE
*) &height
, sizeof(DWORD
));
246 RegSetValueEx(hKey
, _T("Format"), 0, REG_DWORD
, (const BYTE
*) &format
, sizeof(DWORD
));
247 RegSetValueEx(hKey
, _T("OutputPathOption"), 0, REG_DWORD
, (const BYTE
*) &outputPathOption
, sizeof(DWORD
));
252 BEGIN_MESSAGE_MAP(CSnapshotToolDlg
, CDialog
)
253 //{{AFX_MSG_MAP(CSnapshotToolDlg)
254 ON_BN_CLICKED(IDC_BROWSE_INPUT_PATH
, OnBrowseInputPath
)
255 ON_BN_CLICKED(IDC_BROWSE_OUTPUT_PATH
, OnBrowseOutputPath
)
256 ON_BN_CLICKED(IDC_GO
, OnGo
)
257 ON_BN_CLICKED(IDC_ADD_FILTER
, OnAddFilter
)
258 ON_BN_CLICKED(IDC_REMOVE_FILTER
, OnRemoveFilter
)
259 ON_BN_CLICKED(IDC_EDIT_FILTER
, OnEditFilter
)
261 ON_EN_CHANGE(IDC_WIDTH
, OnChangeWidth
)
262 ON_EN_KILLFOCUS(IDC_HEIGHT
, OnKillfocusHeight
)
263 ON_EN_KILLFOCUS(IDC_WIDTH
, OnKillfocusWidth
)
264 ON_CBN_SELCHANGE(IDC_OUTPUTPATH_OPTION
, OnSelchangeOutputpathOption
)
265 ON_CBN_SELCHANGE(IDC_FORMAT
, OnSelchangeFormat
)
266 ON_BN_CLICKED(IDC_CLOSE
, OnCloseButton
)
268 ON_BN_CLICKED(IDC_STOP
, OnStopSnapshots
)
269 ON_BN_CLICKED(IDC_VIEW_FRONT
, OnViewFront
)
270 ON_BN_CLICKED(IDC_VIEW_LEFT
, OnViewLeft
)
271 ON_BN_CLICKED(IDC_VIEW_RIGHT
, OnViewRight
)
272 ON_BN_CLICKED(IDC_VIEW_TOP
, OnViewTop
)
273 ON_BN_CLICKED(IDC_VIEW_ALL
, OnViewAll
)
274 ON_BN_CLICKED(IDC_VIEW_NONE
, OnViewNone
)
275 ON_BN_CLICKED(IDC_POSTFIX_VIEWNAME
, OnPostFixViewName
)
279 /////////////////////////////////////////////////////////////////////////////
280 // CSnapshotToolDlg message handlers
283 //****************************************************************************************
284 BOOL
CSnapshotToolDlg::OnInitDialog()
286 CDialog::OnInitDialog();
288 SetTimer(1, 10, NULL
);
289 return TRUE
; // return TRUE unless you set the focus to a control
290 // EXCEPTION: OCX Property Pages should return FALSE
293 //****************************************************************************************
294 void CSnapshotToolDlg::OnClose()
301 //****************************************************************************************
302 void CSnapshotToolDlg::OnBrowseInputPath()
304 browseFolder(getStrRsc(IDS_CHOOSE_SNAPSHOT_INPUT_PATH
), m_InputPath
, this->m_hWnd
);
309 //****************************************************************************************
310 void CSnapshotToolDlg::OnBrowseOutputPath()
312 browseFolder(getStrRsc(IDS_CHOOSE_SNAPSHOT_OUTPUT_PATH
), m_OutputPath
, this->m_hWnd
);
318 //****************************************************************************************
319 void CSnapshotToolDlg::OnAddFilter()
321 CChooseName
cn("*.shape", this);
322 if (cn
.DoModal() == IDOK
&& !cn
.m_Name
.IsEmpty())
324 m_Filters
.AddString(cn
.m_Name
);
329 //****************************************************************************************
330 void CSnapshotToolDlg::OnRemoveFilter()
332 if (m_Filters
.GetCurSel() != LB_ERR
)
334 m_Filters
.DeleteString(m_Filters
.GetCurSel());
339 //****************************************************************************************
340 void CSnapshotToolDlg::OnEditFilter()
342 if (m_Filters
.GetCurSel() != LB_ERR
)
345 m_Filters
.GetText(m_Filters
.GetCurSel(), current
);
346 CChooseName
cn((LPCTSTR
) current
, this);
347 if (cn
.DoModal() == IDOK
&& !cn
.m_Name
.IsEmpty())
349 int curSel
= m_Filters
.GetCurSel();
350 m_Filters
.DeleteString(m_Filters
.GetCurSel());
351 m_Filters
.InsertString(curSel
, cn
.m_Name
);
352 m_Filters
.SetCurSel(curSel
);
359 //****************************************************************************************
360 uint
CSnapshotToolDlg::getSelectedViewCount()
363 return (m_ViewBack
? 1 : 0) +
364 (m_ViewBottom
? 1 : 0) +
365 (m_ViewFront
? 1 : 0) +
366 (m_ViewLeft
? 1 : 0) +
367 (m_ViewRight
? 1 : 0) +
371 //****************************************************************************************
372 void CSnapshotToolDlg::updateUIEnabledState()
374 BOOL enabled
= _FilteredFiles
.empty() ? TRUE
: FALSE
;
375 m_Filters
.EnableWindow(enabled
);
376 GetDlgItem(IDC_INPUT_PATH
)->EnableWindow(enabled
);
377 GetDlgItem(IDC_BROWSE_INPUT_PATH
)->EnableWindow(enabled
);
378 GetDlgItem(IDC_OUTPUT_PATH
)->EnableWindow(enabled
&& m_OutputPathOption
== OutputPath_Custom
);
379 GetDlgItem(IDC_BROWSE_OUTPUT_PATH
)->EnableWindow(enabled
);
380 GetDlgItem(IDC_RECURSE_SUBFOLDER
)->EnableWindow(enabled
);
381 GetDlgItem(IDC_OUTPUTPATH_OPTION
)->EnableWindow(enabled
);
382 GetDlgItem(IDC_FILTERS
)->EnableWindow(enabled
);
383 GetDlgItem(IDC_ADD_FILTER
)->EnableWindow(enabled
);
384 GetDlgItem(IDC_REMOVE_FILTER
)->EnableWindow(enabled
);
385 GetDlgItem(IDC_EDIT_FILTER
)->EnableWindow(enabled
);
386 GetDlgItem(IDC_WIDTH
)->EnableWindow(enabled
);
387 GetDlgItem(IDC_HEIGHT
)->EnableWindow(enabled
);
388 GetDlgItem(IDC_FORMAT
)->EnableWindow(enabled
);
389 GetDlgItem(IDC_GO
)->EnableWindow(enabled
);
390 GetDlgItem(IDC_DUMP_TEXTURE_SETS
)->EnableWindow(enabled
);
391 GetDlgItem(IDC_STOP
)->EnableWindow(!enabled
);
392 GetDlgItem(IDC_POSTFIX_VIEWNAME
)->EnableWindow((enabled
&& getSelectedViewCount() == 1) ? TRUE
: FALSE
);
393 //GetDlgItem(IDC_CLOSE)->EnaleWindow(enabled);
397 //****************************************************************************************
398 void CSnapshotToolDlg::OnGo()
401 if (getSelectedViewCount() == 0)
403 MessageBox(getStrRsc(IDS_SNAPSHOT_NO_VIEW_SELECTED
), getStrRsc(IDS_OBJECT_VIEWER
), MB_ICONEXCLAMATION
);
406 if (m_InputPath
.IsEmpty())
408 MessageBox(getStrRsc(IDS_SNAPSHOT_EMPTY_INPUT_PATH
), getStrRsc(IDS_OBJECT_VIEWER
), MB_ICONEXCLAMATION
);
411 if (!NLMISC::CFile::isDirectory(tStrToUtf8(m_InputPath
)))
413 MessageBox(getStrRsc(IDS_SNAPSHOT_EMPTY_INPUT_PATH_NOT_FOUND
), getStrRsc(IDS_OBJECT_VIEWER
), MB_ICONEXCLAMATION
);
416 if (m_OutputPathOption
== OutputPath_Custom
&& m_OutputPath
.IsEmpty())
418 MessageBox(getStrRsc(IDS_SNAPSHOT_EMPTY_OUTPUT_PATH
), getStrRsc(IDS_OBJECT_VIEWER
), MB_ICONEXCLAMATION
);
421 if (m_OutputPathOption
== OutputPath_Custom
&& !NLMISC::CFile::isDirectory(tStrToUtf8(m_OutputPath
)))
423 if (MessageBox(getStrRsc(IDS_SNAPSHOT_CREATE_OUTPUT_DIRECTORY
), getStrRsc(IDS_OBJECT_VIEWER
), MB_OKCANCEL
) != IDOK
)
427 if(!NLMISC::CFile::createDirectoryTree(tStrToUtf8(m_OutputPath
)))
429 MessageBox(getStrRsc(IDS_SNAPSHOT_OUTPUT_PATH_CREATION_FAILED
), getStrRsc(IDS_OBJECT_VIEWER
), MB_ICONEXCLAMATION
);
434 // make sure that the screen can contains the window client area
436 ::GetClientRect(::GetDesktopWindow(), &desktopSize
);
437 if (desktopSize
.right
< LONG(m_OutputWidth
) ||
438 desktopSize
.bottom
< LONG(m_OutputHeight
))
440 MessageBox(getStrRsc(IDS_DESKTOP_TOO_SMALL_FOR_SNAPSHOT
), getStrRsc(IDS_OBJECT_VIEWER
), MB_ICONEXCLAMATION
);
444 m_Log
.ResetContent();
445 m_Log
.AddString(getStrRsc(IDS_GETTING_PATH_CONTENT
));
446 std::vector
<std::string
> files
;
447 CPath::getPathContent(tStrToUtf8(m_InputPath
), m_RecurseSubFolder
== TRUE
, false, true, files
);
450 m_Log
.AddString(getStrRsc(IDS_SNAPSHOT_NO_FILES_FOUND
));
453 _FilteredFiles
.clear();
454 for (uint k
= 0; k
< files
.size(); ++k
)
456 for (uint l
= 0; l
< uint(m_Filters
.GetCount()); ++l
)
459 m_Filters
.GetText(l
, wildCard
);
460 wildCard
.MakeLower();
461 if (testWildCard(toLowerAscii(NLMISC::CFile::getFilename(files
[k
])).c_str(), tStrToUtf8(wildCard
).c_str()))
463 _FilteredFiles
.push_back(files
[k
]);
468 if (_FilteredFiles
.empty())
470 m_Log
.AddString(getStrRsc(IDS_SNAPSHOT_NO_FILTER_MATCH_FOUND
));
473 m_Log
.AddString(toString("%d", (int) _FilteredFiles
.size()).c_str() + getStrRsc(IDS_SNAPSHOT_FILES_TO_PROCESS
));
474 updateUIEnabledState();
477 //****************************************************************************************
478 void CSnapshotToolDlg::OnChangeWidth()
480 // TODO: If this is a RICHEDIT control, the control will not
481 // send this notification unless you override the CDialog::OnInitDialog()
482 // function and call CRichEditCtrl().SetEventMask()
483 // with the ENM_CHANGE flag ORed into the mask.
485 // TODO: Add your control notification handler code here
489 //****************************************************************************************
490 void CSnapshotToolDlg::OnKillfocusHeight()
495 //****************************************************************************************
496 void CSnapshotToolDlg::OnKillfocusWidth()
501 //****************************************************************************************
502 void CSnapshotToolDlg::OnSelchangeOutputpathOption()
505 updateUIEnabledState();
509 //****************************************************************************************
510 void CSnapshotToolDlg::OnSelchangeFormat()
516 //****************************************************************************************
517 void CSnapshotToolDlg::OnCloseButton()
520 SendMessage(WM_CLOSE
);
523 //****************************************************************************************
524 void CSnapshotToolDlg::setCamFromView(uint view
, CCamera
*cam
, const CAABBox
&bbox
)
526 static const CVector camBackDir
[] =
535 const float viewDistScale
= 3.f
;
536 CVector halfSize
= bbox
.getHalfSize();
537 if (view
== SnapshotAngle_Top
) // top
540 camMat
.setRot(CVector::I
, -CVector::K
, CVector::J
);
541 camMat
.setPos(bbox
.getCenter() + viewDistScale
* CVector::K
);
542 cam
->setMatrix(camMat
);
544 else if (view
== SnapshotAngle_Bottom
)
547 camMat
.setRot(CVector::I
, CVector::K
, -CVector::J
);
548 camMat
.setPos(bbox
.getCenter() - viewDistScale
* CVector::K
);
549 cam
->setMatrix(camMat
);
553 // standard lookat for other directions
554 cam
->lookAt(bbox
.getCenter() + viewDistScale
* maxof(halfSize
.x
, halfSize
.y
, halfSize
.z
) * camBackDir
[view
], bbox
.getCenter());
558 //****************************************************************************************
559 std::string
CSnapshotToolDlg::viewToString(uint view
)
563 case SnapshotAngle_Front
: return "front";
564 case SnapshotAngle_Right
: return "right";
565 case SnapshotAngle_Left
: return "left";
566 case SnapshotAngle_Top
: return "top";
567 case SnapshotAngle_Bottom
: return "bottom";
568 case SnapshotAngle_Back
: return "back";
574 //****************************************************************************************
575 void CSnapshotToolDlg::OnTimer(UINT_PTR nIDEvent
)
577 if (_FilteredFiles
.empty()) return;
580 // resize the window if needed
581 HWND wnd
= (HWND
) NL3D::CNELU::Driver
->getDisplay();
582 CScene
scene(true /* small scene */);
584 scene
.initDefaultRoots();
585 scene
.setDriver(CNELU::Driver
);
586 scene
.initQuadGridClipManager();
588 vp
.init(0.f
, 0.f
, 1.f
, 1.f
);
589 scene
.setViewport(vp
);
590 scene
.enableLightingSystem(true);
591 scene
.setAmbientGlobal(CRGBA::White
);
594 scene
.setShapeBank(&sb
);
595 CCamera
*cam
= safe_cast
<CCamera
*>(scene
.createModel(CameraId
));
597 cam
->setFrustum(0.1f
, 0.1f
, 0.1f
, 5000.f
);
603 m_Log
.AddString(nlUtf8ToTStr(_FilteredFiles
[0]));
604 CIFile
stream(_FilteredFiles
[0]);
606 nlassert(ss
.getShapePointer());
608 ss
.getShapePointer()->getAABBox(bbox
);
609 sb
.add("shape", ss
.getShapePointer());
610 CTransformShape
*model
= scene
.createInstance("shape");
611 CMatrix initTM
= model
->getMatrix();
612 model
->setTransformMode(CTransform::DirectMatrix
);
613 initTM
.setPos(CVector::Null
);
614 model
->setMatrix(initTM
);
615 CVector newBBoxCenter
= initTM
* bbox
.getCenter();
616 CVector newBBoxHalfSize
= initTM
.mulVector(bbox
.getHalfSize());
617 bbox
.setCenter(newBBoxCenter
);
618 bbox
.setHalfSize(newBBoxHalfSize
);
621 CMeshBaseInstance
*mbi
= dynamic_cast<CMeshBaseInstance
*>(model
);
622 uint textureSetCount
= 1;
623 CMeshBase
*mb
= dynamic_cast<CMeshBase
*>((IShape
*) model
->Shape
);
624 CMesh
*mesh
= dynamic_cast<CMesh
*>((IShape
*) model
->Shape
);
625 if (m_DumpTextureSets
&& mbi
)
629 const uint numMat
= mb
->getNbMaterial();
630 // see which material are selectable
631 for(uint k
= 0; k
< numMat
; ++k
)
633 CMaterial
&mat
= mb
->getMaterial(k
);
634 for(uint l
= 0; l
< IDRV_MAT_MAXTEXTURES
; ++l
)
636 CTextureMultiFile
*tmf
= dynamic_cast<CTextureMultiFile
*>(mat
.getTexture(l
));
639 textureSetCount
= std::max(textureSetCount
, (uint
) tmf
->getNumFileName());
645 // for particle systems : simulate until half duration, then capture bbox
646 CParticleSystemModel
*psm
= dynamic_cast<CParticleSystemModel
*>(model
);
649 psm
->forceInstanciate();
650 CParticleSystem
*ps
= psm
->getPS();
653 float duration
= ps
->evalDuration();
654 float deltaT
= .5f
* ps
->getTimeTheshold();
655 for (float date
= 0.f
; date
< duration
* 0.5f
; date
+= deltaT
)
657 ps
->setSysMat(&CMatrix::Identity
);
658 ps
->step(CParticleSystem::Anim
, deltaT
, *safe_cast
<CParticleSystemShape
*>((IShape
*) psm
->Shape
), *psm
);
660 ps
->computeBBox(bbox
);
664 cam
->setTransformMode(ITransformable::DirectMatrix
);
674 for (uint viewIndex
= 0; viewIndex
< 6; ++viewIndex
)
676 if (!views
[viewIndex
]) continue;
677 setCamFromView(viewIndex
, cam
, bbox
);
678 for (uint textureSet
= 0; textureSet
< textureSetCount
; ++textureSet
)
682 mbi
->selectTextureSet(textureSet
);
685 CNELU::Driver
->clear2D(_ObjectViewer
->getBackGroundColor());
686 CNELU::Driver
->clearZBuffer();
688 NLMISC::CBitmap snapshot
;
689 CNELU::Driver
->getBuffer(snapshot
);
690 if (snapshot
.getWidth() == 0 || snapshot
.getHeight() == 0)
692 m_Log
.AddString(getStrRsc(IDS_SNAPSHOT_NO_CONTENT_RETRIEVED
));
696 snapshot
.resample(m_OutputWidth
, m_OutputHeight
);
697 size_t lastPoint
= _FilteredFiles
[0].find_last_of('.');
698 std::string outputFilename
= _FilteredFiles
[0].substr(0, lastPoint
);
699 if (textureSetCount
> 1)
701 outputFilename
+= toString("_%u", (unsigned int) textureSet
);
703 if (getSelectedViewCount() != 1 || m_PostFixViewName
)
705 outputFilename
+= "_" + viewToString(viewIndex
);
711 case OutputFormat_Tga
:
714 case OutputFormat_Png
:
717 case OutputFormat_Jpg
:
721 nlerror("Unsupported format %d", m_Format
);
724 outputFilename
+= "." + ext
;
726 switch(m_OutputPathOption
)
728 case OutputPath_Custom
: // custom output path
729 outputFilename
= tStrToUtf8(m_OutputPath
) + "\\" + NLMISC::CFile::getFilename(outputFilename
);
731 case OutputPath_SameAsInput
: // Input path
732 outputFilename
= tStrToUtf8(m_InputPath
) + "\\" + NLMISC::CFile::getFilename(outputFilename
);
734 case OutputPath_CurrShapeDirectory
: // current path
738 COFile
output(outputFilename
);
740 if (m_Format
== OutputFormat_Tga
)
742 snapshot
.writeTGA(output
);
744 else if (m_Format
== OutputFormat_Png
)
746 snapshot
.writePNG(output
);
750 snapshot
.writeJPG(output
);
753 CNELU::Driver
->swapBuffers();
756 scene
.deleteInstance(model
);
760 catch(const std::exception
&e
)
765 _FilteredFiles
.pop_front();
766 if (_FilteredFiles
.empty())
768 m_Log
.AddString(getStrRsc(IDS_SNAPSHOT_FINISHED
));
769 updateUIEnabledState();
772 CDialog::OnTimer(nIDEvent
);
775 //****************************************************************************************
776 void CSnapshotToolDlg::OnStopSnapshots()
778 _FilteredFiles
.clear();
779 updateUIEnabledState();
783 //****************************************************************************************
784 void CSnapshotToolDlg::OnViewFront()
787 updateUIEnabledState();
790 //****************************************************************************************
791 void CSnapshotToolDlg::OnViewLeft()
794 updateUIEnabledState();
797 //****************************************************************************************
798 void CSnapshotToolDlg::OnViewRight()
801 updateUIEnabledState();
804 //****************************************************************************************
805 void CSnapshotToolDlg::OnViewTop()
808 updateUIEnabledState();
811 //****************************************************************************************
812 void CSnapshotToolDlg::OnViewAll()
822 updateUIEnabledState();
825 //****************************************************************************************
826 void CSnapshotToolDlg::OnViewNone()
829 m_ViewBottom
= FALSE
;
836 updateUIEnabledState();
839 //****************************************************************************************
840 void CSnapshotToolDlg::OnPostFixViewName()