Add static mesh export feature

master
stujones11 2018-10-04 17:53:07 +01:00
parent 52f3a9390a
commit 2969478764
7 changed files with 110 additions and 18 deletions

View File

@ -13,6 +13,7 @@ Features
* Mesh debug view. (wire-frame, skeleton and normals)
* Animation playback amd frame controls.
* Simple lighting.
* Static mesh export.
Supported Mesh Formats
----------------------

View File

@ -13,23 +13,36 @@
#else
#define D_ABOUT_LINK_URL "https://github.com/stujones11/SAM-Viewer"
#define D_ABOUT_LINK_TEXT "github.com/stujones11/SAM-Viewer"
#define D_VERSION "0.0"
#define D_VERSION "dirty"
#endif
namespace dialog
{
const char *fileOpenDialog(IGUIEnvironment *env, const char *caption,
static inline void setWorkingDir(io::IFileSystem *fs, const char *fn)
{
if (!fn || stringc(fn).empty())
return;
io::path cwd = fs->getFileDir(fn);
fs->changeWorkingDirectoryTo(cwd);
}
const char *fileOpenDialog(io::IFileSystem *fs, const char *caption,
const char **filters, const int filter_count)
{
io::IFileSystem *fs = env->getFileSystem();
io::path path = fs->getWorkingDirectory() + "/";
const char *fn = tinyfd_openFileDialog(caption, path.c_str(),
filter_count, filters, 0);
if (fn)
{
io::path cwd = fs->getFileDir(fn);
fs->changeWorkingDirectoryTo(cwd);
}
setWorkingDir(fs, fn);
return fn;
}
const char *fileSaveDialog(io::IFileSystem *fs, const char *caption,
const char **filters, const int filter_count)
{
io::path path = fs->getWorkingDirectory() + "/";
const char *fn = tinyfd_saveFileDialog(caption, path.c_str(),
filter_count, filters);
setWorkingDir(fs, fn);
return fn;
}
}
@ -400,9 +413,9 @@ bool TexturesDialog::OnEvent(const SEvent &event)
}
if (edit)
{
const char *fn = dialog::fileOpenDialog(Environment,
"Open Image File", dialog::texture_filters,
dialog::texture_filter_count);
const char *fn = dialog::fileOpenDialog(
Environment->getFileSystem(), "Open Image File",
dialog::texture_filters, dialog::texture_filter_count);
if (fn)
{
edit->setText(stringw(fn).c_str());

View File

@ -69,7 +69,10 @@ namespace dialog
"*.psd", "*.pcx", "*.ppm", "*.wal"
};
const char *fileOpenDialog(IGUIEnvironment *env, const char *caption,
const char *fileOpenDialog(io::IFileSystem *fs, const char *caption,
const char **filters, const int filter_count);
const char *fileSaveDialog(io::IFileSystem *fs, const char *caption,
const char **filters, const int filter_count);
}

View File

@ -169,11 +169,24 @@ void GUI::initMenu()
submenu = menu->getSubMenu(0);
submenu->addItem(L"Load Model Mesh", E_GUI_ID_LOAD_MODEL_MESH);
submenu->addItem(L"Load Wield Mesh", E_GUI_ID_LOAD_WIELD_MESH);
submenu->addSeparator();
submenu->addItem(L"Save Configuration", E_GUI_ID_SAVE_CONFIG);
submenu->addSeparator();
submenu->addItem(L"Export Static Mesh", -1, true, true);
submenu->addSeparator();
submenu->addItem(L"Quit", E_GUI_ID_QUIT);
submenu = menu->getSubMenu(0)->getSubMenu(4);
submenu->addItem(L"Irrlcht (.irrmesh)",
E_GUI_ID_EXPORT_MESH_IRR);
submenu->addItem(L"Collada (.dae, .xml)",
E_GUI_ID_EXPORT_MESH_COL);
submenu->addItem(L"STL (.stl)",
E_GUI_ID_EXPORT_MESH_STL);
submenu->addItem(L"Wavefront (.obj)",
E_GUI_ID_EXPORT_MESH_OBJ);
submenu->addItem(L"Polygon file format (.ply)",
E_GUI_ID_EXPORT_MESH_PLY);
submenu = menu->getSubMenu(1);
submenu->addItem(L"Textures", E_DIALOG_ID_TEXTURES);
submenu->addItem(L"Lights", E_DIALOG_ID_LIGHTS);

View File

@ -13,6 +13,11 @@ enum
E_GUI_ID_TOOLBAR,
E_GUI_ID_LOAD_MODEL_MESH,
E_GUI_ID_LOAD_WIELD_MESH,
E_GUI_ID_EXPORT_MESH_IRR,
E_GUI_ID_EXPORT_MESH_COL,
E_GUI_ID_EXPORT_MESH_STL,
E_GUI_ID_EXPORT_MESH_OBJ,
E_GUI_ID_EXPORT_MESH_PLY,
E_GUI_ID_SAVE_CONFIG,
E_GUI_ID_QUIT,
E_GUI_ID_TOOLBOX_MODEL,

View File

@ -132,6 +132,26 @@ void Viewer::setCaptionFileName(const io::path &filename)
device->setWindowCaption(caption.c_str());
}
void Viewer::exportStaticMesh(const char *caption, const char **filters,
const int filter_count, EMESH_WRITER_TYPE id)
{
io::IFileSystem *fs = device->getFileSystem();
const char *fn = dialog::fileSaveDialog(fs, caption, filters,
filter_count);
if (!fn || stringc(fn).empty())
return;
IAnimatedMeshSceneNode *model =
(IAnimatedMeshSceneNode*)scene->getNode(E_SCENE_ID_MODEL);
IAnimatedMesh *mesh = model->getMesh();
io::IWriteFile *file = fs->createAndWriteFile(fn);
ISceneManager *smgr = device->getSceneManager();
IMeshWriter *writer = smgr->createMeshWriter(id);
writer->writeMesh(file, mesh);
writer->drop();
file->drop();
}
static inline std::string boolToString(bool b)
{
return (b) ? "true" : "false";
@ -154,16 +174,16 @@ bool Viewer::OnEvent(const SEvent &event)
IGUIContextMenu *menu = (IGUIContextMenu*)event.GUIEvent.Caller;
s32 item = menu->getSelectedItem();
s32 id = menu->getItemCommandId(item);
IGUIEnvironment *env = device->getGUIEnvironment();
io::IFileSystem *fs = device->getFileSystem();
switch (id)
{
case E_GUI_ID_LOAD_MODEL_MESH:
{
const char *fn = dialog::fileOpenDialog(env,
const char *fn = dialog::fileOpenDialog(fs,
"Open main model file", dialog::model_filters,
dialog::model_filter_count);
if (fn && scene->loadModelMesh(fn))
if (fn && !stringc(fn).empty() && scene->loadModelMesh(fn))
{
ISceneNode *model = scene->getNode(E_SCENE_ID_MODEL);
if (model)
@ -178,16 +198,51 @@ bool Viewer::OnEvent(const SEvent &event)
}
case E_GUI_ID_LOAD_WIELD_MESH:
{
const char *fn = dialog::fileOpenDialog(env,
const char *fn = dialog::fileOpenDialog(fs,
"Open wield model file", dialog::model_filters,
dialog::model_filter_count);
if (fn && scene->loadWieldMesh(fn))
if (fn && !stringc(fn).empty() && scene->loadWieldMesh(fn))
{
gui->reloadToolBox(E_GUI_ID_TOOLBOX_WIELD);
conf->set("wield_mesh", fn);
}
break;
}
case E_GUI_ID_EXPORT_MESH_IRR:
{
const char *filters[] = {"*.irrmesh"};
exportStaticMesh("Export Irrlicht Mesh",
filters, 1, EMWT_IRR_MESH);
break;
}
case E_GUI_ID_EXPORT_MESH_COL:
{
const char *filters[] = {"*.dae", "*.xml"};
exportStaticMesh("Export Collada Mesh",
filters, 2, EMWT_COLLADA);
break;
}
case E_GUI_ID_EXPORT_MESH_STL:
{
const char *filters[] = {"*.stl"};
exportStaticMesh("Export STL Mesh",
filters, 1, EMWT_STL);
break;
}
case E_GUI_ID_EXPORT_MESH_OBJ:
{
const char *filters[] = {"*.obj"};
exportStaticMesh("Export Wavefront Mesh",
filters, 1, EMWT_OBJ);
break;
}
case E_GUI_ID_EXPORT_MESH_PLY:
{
const char *filters[] = {"*.ply"};
exportStaticMesh("Export Polygon File",
filters, 1, EMWT_PLY);
break;
}
case E_GUI_ID_ENABLE_WIELD:
{
ISceneNode *wield = scene->getNode(E_SCENE_ID_WIELD);

View File

@ -57,6 +57,8 @@ private:
void setProjection();
void setBackgroundColor(const u32 &color);
void setCaptionFileName(const io::path &filename);
void exportStaticMesh(const char *caption, const char **filters,
const int filter_count, EMESH_WRITER_TYPE id);
Config *conf;
IrrlichtDevice *device;