mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-12-27 11:20:54 +00:00
817 lines
26 KiB
C++
817 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 "main_frame.h"
|
||
|
#include "snapshot_tool_dlg.h"
|
||
|
#include "choose_name.h"
|
||
|
#include "object_viewer.h"
|
||
|
//
|
||
|
#include "nel/misc/path.h"
|
||
|
#include "nel/misc/algo.h"
|
||
|
#include "nel/misc/file.h"
|
||
|
//
|
||
|
#include "nel/3d/u_scene.h"
|
||
|
#include "nel/3d/u_driver.h"
|
||
|
//
|
||
|
#include "nel/3d/driver.h"
|
||
|
#include "nel/3d/driver_user.h"
|
||
|
#include "nel/3d/shape_bank.h"
|
||
|
#include "nel/3d/camera.h"
|
||
|
#include "nel/3d/texture_multi_file.h"
|
||
|
#include "nel/3d/mesh_base.h"
|
||
|
#include "nel/3d/particle_system.h"
|
||
|
#include "nel/3d/particle_system_shape.h"
|
||
|
#include "nel/3d/particle_system_model.h"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#define NEL_OV_SNAPSHOT_TOOL_REGKEY "Software\\Nevrax\\nel\\object_viewer\\snapshot_dlg"
|
||
|
|
||
|
|
||
|
using namespace NLMISC;
|
||
|
using namespace NL3D;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CSnapshotToolDlg dialog
|
||
|
|
||
|
//****************************************************************************************
|
||
|
CSnapshotToolDlg::CSnapshotToolDlg(CObjectViewer *ov, CWnd* pParent /*=NULL*/)
|
||
|
: CDialog(CSnapshotToolDlg::IDD, pParent)
|
||
|
{
|
||
|
nlassert(ov);
|
||
|
_ObjectViewer = ov;
|
||
|
//{{AFX_DATA_INIT(CSnapshotToolDlg)
|
||
|
m_OutputPath = _T("");
|
||
|
m_InputPath = _T("");
|
||
|
m_RecurseSubFolder = FALSE;
|
||
|
m_OutputHeight = 100;
|
||
|
m_OutputWidth = 160;
|
||
|
m_Format = -1;
|
||
|
m_OutputPathOption = -1;
|
||
|
m_DumpTextureSets = FALSE;
|
||
|
m_ViewBack = FALSE;
|
||
|
m_ViewBottom = FALSE;
|
||
|
m_ViewFront = FALSE;
|
||
|
m_ViewLeft = FALSE;
|
||
|
m_ViewRight = FALSE;
|
||
|
m_ViewTop = FALSE;
|
||
|
m_PostFixViewName = FALSE;
|
||
|
//}}AFX_DATA_INIT
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
CSnapshotToolDlg::~CSnapshotToolDlg()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::DoDataExchange(CDataExchange* pDX)
|
||
|
{
|
||
|
CDialog::DoDataExchange(pDX);
|
||
|
//{{AFX_DATA_MAP(CSnapshotToolDlg)
|
||
|
DDX_Control(pDX, IDC_LOG, m_Log);
|
||
|
DDX_Control(pDX, IDC_FILTERS, m_Filters);
|
||
|
DDX_Text(pDX, IDC_OUTPUT_PATH, m_OutputPath);
|
||
|
DDX_Text(pDX, IDC_INPUT_PATH, m_InputPath);
|
||
|
DDX_Check(pDX, IDC_RECURSE_SUBFOLDER, m_RecurseSubFolder);
|
||
|
DDX_Text(pDX, IDC_HEIGHT, m_OutputHeight);
|
||
|
DDV_MinMaxUInt(pDX, m_OutputHeight, 1, 1024);
|
||
|
DDX_Text(pDX, IDC_WIDTH, m_OutputWidth);
|
||
|
DDV_MinMaxUInt(pDX, m_OutputWidth, 1, 1024);
|
||
|
DDX_CBIndex(pDX, IDC_FORMAT, m_Format);
|
||
|
DDX_CBIndex(pDX, IDC_OUTPUTPATH_OPTION, m_OutputPathOption);
|
||
|
DDX_Check(pDX, IDC_DUMP_TEXTURE_SETS, m_DumpTextureSets);
|
||
|
DDX_Check(pDX, IDC_VIEW_BACK, m_ViewBack);
|
||
|
DDX_Check(pDX, IDC_VIEW_BOTTOM, m_ViewBottom);
|
||
|
DDX_Check(pDX, IDC_VIEW_FRONT, m_ViewFront);
|
||
|
DDX_Check(pDX, IDC_VIEW_LEFT, m_ViewLeft);
|
||
|
DDX_Check(pDX, IDC_VIEW_RIGHT, m_ViewRight);
|
||
|
DDX_Check(pDX, IDC_VIEW_TOP, m_ViewTop);
|
||
|
DDX_Check(pDX, IDC_POSTFIX_VIEWNAME, m_PostFixViewName);
|
||
|
//}}AFX_DATA_MAP
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::stringFromRegistry(HKEY hKey, const char *name, CString &dest, const CString &defaultStr)
|
||
|
{
|
||
|
DWORD type;
|
||
|
DWORD size;
|
||
|
LONG result = RegQueryValueEx(hKey, name, NULL, &type, NULL, &size);
|
||
|
if (type != REG_SZ || result != ERROR_SUCCESS || size == 0)
|
||
|
{
|
||
|
dest = defaultStr;
|
||
|
return;
|
||
|
}
|
||
|
std::string tmpDest;
|
||
|
tmpDest.resize(size);
|
||
|
result = RegQueryValueEx(hKey, name, NULL, &type, (unsigned char *) &tmpDest[0], &size);
|
||
|
if (result != ERROR_SUCCESS)
|
||
|
{
|
||
|
dest = defaultStr;
|
||
|
return;
|
||
|
}
|
||
|
dest = tmpDest.c_str();
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
template <class T, class U> void integralTypeFromRegistry(HKEY hKey, const char *name, T &dest, const U &defaultValue)
|
||
|
{
|
||
|
if (hKey == 0)
|
||
|
{
|
||
|
dest = defaultValue;
|
||
|
return;
|
||
|
}
|
||
|
DWORD type;
|
||
|
DWORD size;
|
||
|
LONG result = RegQueryValueEx(hKey, name, NULL, &type, NULL, &size);
|
||
|
if (type != REG_DWORD || result != ERROR_SUCCESS || size == 0)
|
||
|
{
|
||
|
dest = (T) defaultValue;
|
||
|
return;
|
||
|
}
|
||
|
DWORD value;
|
||
|
result = RegQueryValueEx(hKey, name, NULL, &type, LPBYTE(&value), &size);
|
||
|
if (result != ERROR_SUCCESS)
|
||
|
{
|
||
|
dest = defaultValue;
|
||
|
return;
|
||
|
}
|
||
|
dest = (T) value;
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::fromRegistry()
|
||
|
{
|
||
|
HKEY hKey = 0;
|
||
|
RegOpenKeyEx(HKEY_CURRENT_USER, NEL_OV_SNAPSHOT_TOOL_REGKEY, 0, KEY_READ, &hKey);
|
||
|
stringFromRegistry(hKey, "InputPath", m_InputPath, "");
|
||
|
stringFromRegistry(hKey, "OutputPath", m_OutputPath, "");
|
||
|
CString filters;
|
||
|
stringFromRegistry(hKey, "Filters", filters, "*.shape");
|
||
|
std::string stdFilters((LPCTSTR) filters);
|
||
|
std::vector<std::string> filterList;
|
||
|
NLMISC::splitString(stdFilters, ",", filterList);
|
||
|
m_Filters.ResetContent();
|
||
|
for (uint k = 0; k < filterList.size(); ++k)
|
||
|
{
|
||
|
m_Filters.AddString(filterList[k].c_str());
|
||
|
}
|
||
|
|
||
|
integralTypeFromRegistry(hKey, "RecurseSubFolder", (int &) m_RecurseSubFolder, FALSE);
|
||
|
integralTypeFromRegistry(hKey, "DumpTextureSets", (int &) m_DumpTextureSets, TRUE);
|
||
|
integralTypeFromRegistry(hKey, "PostFixViewName", (int &) m_PostFixViewName, TRUE);
|
||
|
integralTypeFromRegistry(hKey, "ViewBack", (int &) m_ViewBack, FALSE);
|
||
|
integralTypeFromRegistry(hKey, "ViewBottom", (int &) m_ViewBottom, FALSE);
|
||
|
integralTypeFromRegistry(hKey, "ViewFront", (int &) m_ViewFront, TRUE);
|
||
|
integralTypeFromRegistry(hKey, "ViewLeft", (int &) m_ViewLeft, FALSE);
|
||
|
integralTypeFromRegistry(hKey, "ViewRight", (int &) m_ViewRight, FALSE);
|
||
|
integralTypeFromRegistry(hKey, "ViewTop", (int &) m_ViewTop, FALSE);
|
||
|
integralTypeFromRegistry(hKey, "OutputWidth", m_OutputWidth, 128);
|
||
|
integralTypeFromRegistry(hKey, "OutputHeight", m_OutputHeight, 128);
|
||
|
integralTypeFromRegistry(hKey, "Format", m_Format, 0);
|
||
|
integralTypeFromRegistry(hKey, "OutputPathOption", m_OutputPathOption, 1);
|
||
|
UpdateData(FALSE);
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::toRegistry()
|
||
|
{
|
||
|
UpdateData();
|
||
|
HKEY hKey;
|
||
|
if (RegCreateKey(HKEY_CURRENT_USER, NEL_OV_SNAPSHOT_TOOL_REGKEY, &hKey)==ERROR_SUCCESS)
|
||
|
{
|
||
|
RegSetValueEx(hKey, "InputPath", 0, REG_SZ, (unsigned char *) (LPCTSTR) m_InputPath, m_InputPath.GetLength() + 1);
|
||
|
RegSetValueEx(hKey, "OutputPath", 0, REG_SZ, (unsigned char *) (LPCTSTR) m_OutputPath, m_OutputPath.GetLength() + 1);
|
||
|
CString filters;
|
||
|
for (uint k = 0; k < (uint) m_Filters.GetCount(); ++k)
|
||
|
{
|
||
|
if (k!=0) filters += ",";
|
||
|
CString filter;
|
||
|
m_Filters.GetText(k, filter);
|
||
|
filters += filter;
|
||
|
}
|
||
|
RegSetValueEx(hKey, "Filters", 0, REG_SZ, (unsigned char *) (LPCTSTR) filters, filters.GetLength() + 1);
|
||
|
DWORD recurseSubFolder = m_RecurseSubFolder;
|
||
|
DWORD dumpTextureSets = m_DumpTextureSets;
|
||
|
DWORD views [] =
|
||
|
{
|
||
|
m_ViewBack,
|
||
|
m_ViewBottom,
|
||
|
m_ViewFront,
|
||
|
m_ViewLeft,
|
||
|
m_ViewRight,
|
||
|
m_ViewTop
|
||
|
};
|
||
|
DWORD width = (DWORD) m_OutputWidth;
|
||
|
DWORD height = (DWORD) m_OutputHeight;
|
||
|
DWORD format = m_Format;
|
||
|
DWORD outputPathOption = m_OutputPathOption;
|
||
|
DWORD postFixViewName = m_PostFixViewName;
|
||
|
integralTypeFromRegistry(hKey, "PostFixViewName", (int &) m_PostFixViewName, TRUE);
|
||
|
RegSetValueEx(hKey, "ViewBack", 0, REG_DWORD, (const BYTE *) &m_ViewBack, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "ViewBottom", 0, REG_DWORD, (const BYTE *) &m_ViewBottom, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "ViewFront", 0, REG_DWORD, (const BYTE *) &m_ViewFront, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "ViewLeft", 0, REG_DWORD, (const BYTE *) &m_ViewLeft, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "ViewRight", 0, REG_DWORD, (const BYTE *) &m_ViewRight, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "ViewTop", 0, REG_DWORD, (const BYTE *) &m_ViewTop, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "RecurseSubFolder", 0, REG_DWORD, (const BYTE *) &recurseSubFolder, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "DumpTextureSets", 0, REG_DWORD, (const BYTE *) &dumpTextureSets, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "OutputWidth", 0, REG_DWORD, (const BYTE *) &width, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "OutputHeight", 0, REG_DWORD, (const BYTE *) &height, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "Format", 0, REG_DWORD, (const BYTE *) &format, sizeof(DWORD));
|
||
|
RegSetValueEx(hKey, "OutputPathOption", 0, REG_DWORD, (const BYTE *) &outputPathOption, sizeof(DWORD));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CSnapshotToolDlg, CDialog)
|
||
|
//{{AFX_MSG_MAP(CSnapshotToolDlg)
|
||
|
ON_BN_CLICKED(IDC_BROWSE_INPUT_PATH, OnBrowseInputPath)
|
||
|
ON_BN_CLICKED(IDC_BROWSE_OUTPUT_PATH, OnBrowseOutputPath)
|
||
|
ON_BN_CLICKED(IDC_GO, OnGo)
|
||
|
ON_BN_CLICKED(IDC_ADD_FILTER, OnAddFilter)
|
||
|
ON_BN_CLICKED(IDC_REMOVE_FILTER, OnRemoveFilter)
|
||
|
ON_BN_CLICKED(IDC_EDIT_FILTER, OnEditFilter)
|
||
|
ON_WM_CLOSE()
|
||
|
ON_EN_CHANGE(IDC_WIDTH, OnChangeWidth)
|
||
|
ON_EN_KILLFOCUS(IDC_HEIGHT, OnKillfocusHeight)
|
||
|
ON_EN_KILLFOCUS(IDC_WIDTH, OnKillfocusWidth)
|
||
|
ON_CBN_SELCHANGE(IDC_OUTPUTPATH_OPTION, OnSelchangeOutputpathOption)
|
||
|
ON_CBN_SELCHANGE(IDC_FORMAT, OnSelchangeFormat)
|
||
|
ON_BN_CLICKED(IDC_CLOSE, OnCloseButton)
|
||
|
ON_WM_TIMER()
|
||
|
ON_BN_CLICKED(IDC_STOP, OnStopSnapshots)
|
||
|
ON_BN_CLICKED(IDC_VIEW_FRONT, OnViewFront)
|
||
|
ON_BN_CLICKED(IDC_VIEW_LEFT, OnViewLeft)
|
||
|
ON_BN_CLICKED(IDC_VIEW_RIGHT, OnViewRight)
|
||
|
ON_BN_CLICKED(IDC_VIEW_TOP, OnViewTop)
|
||
|
ON_BN_CLICKED(IDC_VIEW_ALL, OnViewAll)
|
||
|
ON_BN_CLICKED(IDC_VIEW_NONE, OnViewNone)
|
||
|
ON_BN_CLICKED(IDC_POSTFIX_VIEWNAME, OnPostFixViewName)
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CSnapshotToolDlg message handlers
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
BOOL CSnapshotToolDlg::OnInitDialog()
|
||
|
{
|
||
|
CDialog::OnInitDialog();
|
||
|
fromRegistry();
|
||
|
SetTimer(1, 10, NULL);
|
||
|
return TRUE; // return TRUE unless you set the focus to a control
|
||
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnClose()
|
||
|
{
|
||
|
toRegistry();
|
||
|
CDialog::OnClose();
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnBrowseInputPath()
|
||
|
{
|
||
|
browseFolder(getStrRsc(IDS_CHOOSE_SNAPSHOT_INPUT_PATH), m_InputPath, this->m_hWnd);
|
||
|
UpdateData(FALSE);
|
||
|
toRegistry();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnBrowseOutputPath()
|
||
|
{
|
||
|
browseFolder(getStrRsc(IDS_CHOOSE_SNAPSHOT_OUTPUT_PATH), m_OutputPath, this->m_hWnd);
|
||
|
UpdateData(FALSE);
|
||
|
toRegistry();
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnAddFilter()
|
||
|
{
|
||
|
CChooseName cn("*.shape", this);
|
||
|
if (cn.DoModal() == IDOK && !cn.m_Name.IsEmpty())
|
||
|
{
|
||
|
m_Filters.AddString(cn.m_Name);
|
||
|
}
|
||
|
toRegistry();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnRemoveFilter()
|
||
|
{
|
||
|
if (m_Filters.GetCurSel() != LB_ERR)
|
||
|
{
|
||
|
m_Filters.DeleteString(m_Filters.GetCurSel());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnEditFilter()
|
||
|
{
|
||
|
if (m_Filters.GetCurSel() != LB_ERR)
|
||
|
{
|
||
|
CString current;
|
||
|
m_Filters.GetText(m_Filters.GetCurSel(), current);
|
||
|
CChooseName cn((LPCTSTR) current, this);
|
||
|
if (cn.DoModal() == IDOK && !cn.m_Name.IsEmpty())
|
||
|
{
|
||
|
int curSel = m_Filters.GetCurSel();
|
||
|
m_Filters.DeleteString(m_Filters.GetCurSel());
|
||
|
m_Filters.InsertString(curSel, cn.m_Name);
|
||
|
m_Filters.SetCurSel(curSel);
|
||
|
}
|
||
|
}
|
||
|
toRegistry();
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
uint CSnapshotToolDlg::getSelectedViewCount()
|
||
|
{
|
||
|
UpdateData();
|
||
|
return (m_ViewBack ? 1 : 0) +
|
||
|
(m_ViewBottom ? 1 : 0) +
|
||
|
(m_ViewFront ? 1 : 0) +
|
||
|
(m_ViewLeft ? 1 : 0) +
|
||
|
(m_ViewRight ? 1 : 0) +
|
||
|
(m_ViewTop ? 1 : 0);
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::updateUIEnabledState()
|
||
|
{
|
||
|
BOOL enabled = _FilteredFiles.empty() ? TRUE : FALSE;
|
||
|
m_Filters.EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_INPUT_PATH)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_BROWSE_INPUT_PATH)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_OUTPUT_PATH)->EnableWindow(enabled && m_OutputPathOption == OutputPath_Custom);
|
||
|
GetDlgItem(IDC_BROWSE_OUTPUT_PATH)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_RECURSE_SUBFOLDER)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_OUTPUTPATH_OPTION)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_FILTERS)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_ADD_FILTER)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_REMOVE_FILTER)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_EDIT_FILTER)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_WIDTH)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_HEIGHT)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_FORMAT)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_GO)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_DUMP_TEXTURE_SETS)->EnableWindow(enabled);
|
||
|
GetDlgItem(IDC_STOP)->EnableWindow(!enabled);
|
||
|
GetDlgItem(IDC_POSTFIX_VIEWNAME)->EnableWindow((enabled && getSelectedViewCount() == 1) ? TRUE : FALSE);
|
||
|
//GetDlgItem(IDC_CLOSE)->EnaleWindow(enabled);
|
||
|
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnGo()
|
||
|
{
|
||
|
UpdateData();
|
||
|
if (getSelectedViewCount() == 0)
|
||
|
{
|
||
|
MessageBox(getStrRsc(IDS_SNAPSHOT_NO_VIEW_SELECTED), getStrRsc(IDS_OBJECT_VIEWER), MB_ICONEXCLAMATION);
|
||
|
return;
|
||
|
}
|
||
|
if (m_InputPath.IsEmpty())
|
||
|
{
|
||
|
MessageBox(getStrRsc(IDS_SNAPSHOT_EMPTY_INPUT_PATH), getStrRsc(IDS_OBJECT_VIEWER), MB_ICONEXCLAMATION);
|
||
|
return;
|
||
|
}
|
||
|
if (!NLMISC::CFile::isDirectory(LPCTSTR(m_InputPath)))
|
||
|
{
|
||
|
MessageBox(getStrRsc(IDS_SNAPSHOT_EMPTY_INPUT_PATH_NOT_FOUND), getStrRsc(IDS_OBJECT_VIEWER), MB_ICONEXCLAMATION);
|
||
|
return;
|
||
|
}
|
||
|
if (m_OutputPathOption == OutputPath_Custom && m_OutputPath.IsEmpty())
|
||
|
{
|
||
|
MessageBox(getStrRsc(IDS_SNAPSHOT_EMPTY_OUTPUT_PATH), getStrRsc(IDS_OBJECT_VIEWER), MB_ICONEXCLAMATION);
|
||
|
return;
|
||
|
}
|
||
|
if (m_OutputPathOption == OutputPath_Custom && !NLMISC::CFile::isDirectory(LPCTSTR(m_OutputPath)))
|
||
|
{
|
||
|
if (MessageBox(getStrRsc(IDS_SNAPSHOT_CREATE_OUTPUT_DIRECTORY), getStrRsc(IDS_OBJECT_VIEWER), MB_OKCANCEL) != IDOK)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if(!NLMISC::CFile::createDirectoryTree(LPCTSTR(m_OutputPath)))
|
||
|
{
|
||
|
MessageBox(getStrRsc(IDS_SNAPSHOT_OUTPUT_PATH_CREATION_FAILED), getStrRsc(IDS_OBJECT_VIEWER), MB_ICONEXCLAMATION);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// make sure that the screen can contains the window client area
|
||
|
RECT desktopSize;
|
||
|
::GetClientRect(::GetDesktopWindow(), &desktopSize);
|
||
|
if (desktopSize.right < LONG(m_OutputWidth) ||
|
||
|
desktopSize.bottom < LONG(m_OutputHeight))
|
||
|
{
|
||
|
MessageBox(getStrRsc(IDS_DESKTOP_TOO_SMALL_FOR_SNAPSHOT), getStrRsc(IDS_OBJECT_VIEWER), MB_ICONEXCLAMATION);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_Log.ResetContent();
|
||
|
m_Log.AddString(getStrRsc(IDS_GETTING_PATH_CONTENT));
|
||
|
std::vector<std::string> files;
|
||
|
CPath::getPathContent((LPCTSTR) m_InputPath, m_RecurseSubFolder == TRUE, false, true, files);
|
||
|
if (files.empty())
|
||
|
{
|
||
|
m_Log.AddString(getStrRsc(IDS_SNAPSHOT_NO_FILES_FOUND));
|
||
|
return;
|
||
|
}
|
||
|
_FilteredFiles.clear();
|
||
|
for (uint k = 0; k < files.size(); ++k)
|
||
|
{
|
||
|
for (uint l = 0; l < uint(m_Filters.GetCount()); ++l)
|
||
|
{
|
||
|
CString wildCard;
|
||
|
m_Filters.GetText(l, wildCard);
|
||
|
wildCard.MakeLower();
|
||
|
if (testWildCard(toLower(NLMISC::CFile::getFilename(files[k])).c_str(), (LPCTSTR) wildCard))
|
||
|
{
|
||
|
_FilteredFiles.push_back(files[k]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (_FilteredFiles.empty())
|
||
|
{
|
||
|
m_Log.AddString(getStrRsc(IDS_SNAPSHOT_NO_FILTER_MATCH_FOUND));
|
||
|
return;
|
||
|
}
|
||
|
m_Log.AddString(toString("%d", (int) _FilteredFiles.size()).c_str() + getStrRsc(IDS_SNAPSHOT_FILES_TO_PROCESS));
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnChangeWidth()
|
||
|
{
|
||
|
// TODO: If this is a RICHEDIT control, the control will not
|
||
|
// send this notification unless you override the CDialog::OnInitDialog()
|
||
|
// function and call CRichEditCtrl().SetEventMask()
|
||
|
// with the ENM_CHANGE flag ORed into the mask.
|
||
|
|
||
|
// TODO: Add your control notification handler code here
|
||
|
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnKillfocusHeight()
|
||
|
{
|
||
|
toRegistry();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnKillfocusWidth()
|
||
|
{
|
||
|
toRegistry();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnSelchangeOutputpathOption()
|
||
|
{
|
||
|
toRegistry();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnSelchangeFormat()
|
||
|
{
|
||
|
toRegistry();
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnCloseButton()
|
||
|
{
|
||
|
toRegistry();
|
||
|
SendMessage(WM_CLOSE);
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::setCamFromView(uint view, CCamera *cam, const CAABBox &bbox)
|
||
|
{
|
||
|
static const CVector camBackDir[] =
|
||
|
{
|
||
|
-CVector::J,
|
||
|
CVector::I,
|
||
|
-CVector::I,
|
||
|
CVector::K,
|
||
|
-CVector::K,
|
||
|
CVector::J
|
||
|
};
|
||
|
const float viewDistScale = 3.f;
|
||
|
CVector halfSize = bbox.getHalfSize();
|
||
|
if (view == SnapshotAngle_Top) // top
|
||
|
{
|
||
|
CMatrix camMat;
|
||
|
camMat.setRot(CVector::I, -CVector::K, CVector::J);
|
||
|
camMat.setPos(bbox.getCenter() + viewDistScale * CVector::K);
|
||
|
cam->setMatrix(camMat);
|
||
|
}
|
||
|
else if (view == SnapshotAngle_Bottom)
|
||
|
{
|
||
|
CMatrix camMat;
|
||
|
camMat.setRot(CVector::I, CVector::K, -CVector::J);
|
||
|
camMat.setPos(bbox.getCenter() - viewDistScale * CVector::K);
|
||
|
cam->setMatrix(camMat);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// standard lookat for other directions
|
||
|
cam->lookAt(bbox.getCenter() + viewDistScale * maxof(halfSize.x, halfSize.y, halfSize.z) * camBackDir[view], bbox.getCenter());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
std::string CSnapshotToolDlg::viewToString(uint view)
|
||
|
{
|
||
|
switch(view)
|
||
|
{
|
||
|
case SnapshotAngle_Front: return "front";
|
||
|
case SnapshotAngle_Right: return "right";
|
||
|
case SnapshotAngle_Left: return "left";
|
||
|
case SnapshotAngle_Top: return "top";
|
||
|
case SnapshotAngle_Bottom: return "bottom";
|
||
|
case SnapshotAngle_Back: return "back";
|
||
|
}
|
||
|
nlassert(0);
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnTimer(UINT_PTR nIDEvent)
|
||
|
{
|
||
|
if (_FilteredFiles.empty()) return;
|
||
|
if (nIDEvent == 1)
|
||
|
{
|
||
|
// resize the window if needed
|
||
|
HWND wnd = (HWND) NL3D::CNELU::Driver->getDisplay();
|
||
|
CScene scene(true /* small scene */);
|
||
|
|
||
|
scene.initDefaultRoots();
|
||
|
scene.setDriver(CNELU::Driver);
|
||
|
scene.initQuadGridClipManager();
|
||
|
NL3D::CViewport vp;
|
||
|
vp.init(0.f, 0.f, 1.f, 1.f);
|
||
|
scene.setViewport(vp);
|
||
|
scene.enableLightingSystem(true);
|
||
|
scene.setAmbientGlobal(CRGBA::White);
|
||
|
|
||
|
CShapeBank sb;
|
||
|
scene.setShapeBank(&sb);
|
||
|
CCamera *cam= safe_cast<CCamera *>(scene.createModel(CameraId));
|
||
|
scene.setCam(cam);
|
||
|
cam->setFrustum(0.1f, 0.1f, 0.1f, 5000.f);
|
||
|
|
||
|
|
||
|
try
|
||
|
{
|
||
|
CShapeStream ss;
|
||
|
m_Log.AddString(_FilteredFiles[0].c_str());
|
||
|
CIFile stream(_FilteredFiles[0]);
|
||
|
ss.serial(stream);
|
||
|
nlassert(ss.getShapePointer());
|
||
|
CAABBox bbox;
|
||
|
ss.getShapePointer()->getAABBox(bbox);
|
||
|
sb.add("shape", ss.getShapePointer());
|
||
|
CTransformShape *model = scene.createInstance("shape");
|
||
|
CMatrix initTM = model->getMatrix();
|
||
|
model->setTransformMode(CTransform::DirectMatrix);
|
||
|
initTM.setPos(CVector::Null);
|
||
|
model->setMatrix(initTM);
|
||
|
CVector newBBoxCenter = initTM * bbox.getCenter();
|
||
|
CVector newBBoxHalfSize = initTM.mulVector(bbox.getHalfSize());
|
||
|
bbox.setCenter(newBBoxCenter);
|
||
|
bbox.setHalfSize(newBBoxHalfSize);
|
||
|
if (model)
|
||
|
{
|
||
|
CMeshBaseInstance *mbi = dynamic_cast<CMeshBaseInstance *>(model);
|
||
|
uint textureSetCount = 1;
|
||
|
CMeshBase *mb = dynamic_cast<CMeshBase *>((IShape *) model->Shape);
|
||
|
CMesh *mesh = dynamic_cast<CMesh *>((IShape *) model->Shape);
|
||
|
if (m_DumpTextureSets && mbi)
|
||
|
{
|
||
|
if (mb)
|
||
|
{
|
||
|
const uint numMat = mb->getNbMaterial();
|
||
|
// see which material are selectable
|
||
|
for(uint k = 0; k < numMat; ++k)
|
||
|
{
|
||
|
CMaterial &mat = mb->getMaterial(k);
|
||
|
for(uint l = 0; l < IDRV_MAT_MAXTEXTURES; ++l)
|
||
|
{
|
||
|
CTextureMultiFile *tmf = dynamic_cast<CTextureMultiFile *>(mat.getTexture(l));
|
||
|
if (tmf)
|
||
|
{
|
||
|
textureSetCount = std::max(textureSetCount, (uint) tmf->getNumFileName());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// for particle systems : simulate until half duration, then capture bbox
|
||
|
CParticleSystemModel *psm = dynamic_cast<CParticleSystemModel *>(model);
|
||
|
if (psm)
|
||
|
{
|
||
|
psm->forceInstanciate();
|
||
|
CParticleSystem *ps = psm->getPS();
|
||
|
if (ps)
|
||
|
{
|
||
|
float duration = ps->evalDuration();
|
||
|
float deltaT = .5f * ps->getTimeTheshold();
|
||
|
for (float date = 0.f; date < duration * 0.5f; date += deltaT)
|
||
|
{
|
||
|
ps->setSysMat(&CMatrix::Identity);
|
||
|
ps->step(CParticleSystem::Anim, deltaT, *safe_cast<CParticleSystemShape *>((IShape *) psm->Shape), *psm);
|
||
|
}
|
||
|
ps->computeBBox(bbox);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cam->setTransformMode(ITransformable::DirectMatrix);
|
||
|
BOOL views[] =
|
||
|
{
|
||
|
m_ViewFront,
|
||
|
m_ViewRight,
|
||
|
m_ViewLeft,
|
||
|
m_ViewTop,
|
||
|
m_ViewBottom,
|
||
|
m_ViewBack
|
||
|
};
|
||
|
for (uint viewIndex = 0; viewIndex < 6; ++viewIndex)
|
||
|
{
|
||
|
if (!views[viewIndex]) continue;
|
||
|
setCamFromView(viewIndex, cam, bbox);
|
||
|
for (uint textureSet = 0; textureSet < textureSetCount; ++textureSet)
|
||
|
{
|
||
|
if (mbi)
|
||
|
{
|
||
|
mbi->selectTextureSet(textureSet);
|
||
|
}
|
||
|
|
||
|
CNELU::Driver->clear2D(_ObjectViewer->getBackGroundColor());
|
||
|
CNELU::Driver->clearZBuffer();
|
||
|
scene.render();
|
||
|
NLMISC::CBitmap snapshot;
|
||
|
CNELU::Driver->getBuffer(snapshot);
|
||
|
if (snapshot.getWidth() == 0 || snapshot.getHeight() == 0)
|
||
|
{
|
||
|
m_Log.AddString(getStrRsc(IDS_SNAPSHOT_NO_CONTENT_RETRIEVED));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
snapshot.resample(m_OutputWidth, m_OutputHeight);
|
||
|
size_t lastPoint = _FilteredFiles[0].find_last_of('.');
|
||
|
std::string outputFilename = _FilteredFiles[0].substr(0, lastPoint);
|
||
|
if (textureSetCount > 1)
|
||
|
{
|
||
|
outputFilename += toString("_%u", (unsigned int) textureSet);
|
||
|
}
|
||
|
if (getSelectedViewCount() != 1 || m_PostFixViewName)
|
||
|
{
|
||
|
outputFilename += "_" + viewToString(viewIndex);
|
||
|
}
|
||
|
outputFilename += (m_Format == OutputFormat_Tga ? ".tga" : ".jpg");
|
||
|
switch(m_OutputPathOption)
|
||
|
{
|
||
|
case OutputPath_Custom: // custom output path
|
||
|
outputFilename = LPCTSTR(m_OutputPath) + std::string("\\") + NLMISC::CFile::getFilename(outputFilename);
|
||
|
break;
|
||
|
case OutputPath_SameAsInput: // Input path
|
||
|
outputFilename = LPCTSTR(m_InputPath) + std::string("\\") + NLMISC::CFile::getFilename(outputFilename);
|
||
|
break;
|
||
|
case OutputPath_CurrShapeDirectory: // current path
|
||
|
// no op
|
||
|
break;
|
||
|
}
|
||
|
COFile output(outputFilename);
|
||
|
if (m_Format == OutputFormat_Tga)
|
||
|
{
|
||
|
snapshot.writeTGA(output);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
snapshot.writeJPG(output);
|
||
|
}
|
||
|
}
|
||
|
CNELU::Driver->swapBuffers();
|
||
|
}
|
||
|
}
|
||
|
scene.deleteInstance(model);
|
||
|
}
|
||
|
sb.reset();
|
||
|
}
|
||
|
catch(std::exception &e)
|
||
|
{
|
||
|
nlwarning(e.what());
|
||
|
|
||
|
}
|
||
|
_FilteredFiles.pop_front();
|
||
|
if (_FilteredFiles.empty())
|
||
|
{
|
||
|
m_Log.AddString(getStrRsc(IDS_SNAPSHOT_FINISHED));
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
}
|
||
|
CDialog::OnTimer(nIDEvent);
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnStopSnapshots()
|
||
|
{
|
||
|
_FilteredFiles.clear();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnViewFront()
|
||
|
{
|
||
|
toRegistry();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnViewLeft()
|
||
|
{
|
||
|
toRegistry();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnViewRight()
|
||
|
{
|
||
|
toRegistry();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnViewTop()
|
||
|
{
|
||
|
toRegistry();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnViewAll()
|
||
|
{
|
||
|
m_ViewBack = TRUE;
|
||
|
m_ViewBottom = TRUE;
|
||
|
m_ViewFront = TRUE;
|
||
|
m_ViewLeft = TRUE;
|
||
|
m_ViewRight = TRUE;
|
||
|
m_ViewTop = TRUE;
|
||
|
UpdateData(FALSE);
|
||
|
toRegistry();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnViewNone()
|
||
|
{
|
||
|
m_ViewBack = FALSE;
|
||
|
m_ViewBottom = FALSE;
|
||
|
m_ViewFront = FALSE;
|
||
|
m_ViewLeft = FALSE;
|
||
|
m_ViewRight = FALSE;
|
||
|
m_ViewTop = FALSE;
|
||
|
UpdateData(FALSE);
|
||
|
toRegistry();
|
||
|
updateUIEnabledState();
|
||
|
}
|
||
|
|
||
|
//****************************************************************************************
|
||
|
void CSnapshotToolDlg::OnPostFixViewName()
|
||
|
{
|
||
|
toRegistry();
|
||
|
}
|