5#include "imgui_stdlib.h"
22 s.push_back(static_cast<char>(c & 0x7F));
26std::wstring stringToWstring(
const std::string& s)
31 ws.push_back(static_cast<wchar_t>(static_cast<unsigned char>(c)));
59 auto pos = f.find(
"*.");
60 if (pos != std::string::npos)
62 auto end = f.find_first_of(
";|)", pos);
63 ext = f.substr(pos + 1,
64 (end == std::string::npos) ? std::string::npos :
end - pos - 1);
74 std::vector<int> animsToExport;
75 for (
size_t i = 0; i < ctx.
exportAnimChecked->size() && i < model->anims.size(); ++i)
78 animsToExport.push_back(model->
anims[i].Index);
83 std::wstring wpath = stringToWstring(pathStr);
84 LOG_INFO <<
"Exporting model to: " << pathStr;
89 LOG_INFO <<
"Export complete: " << pathStr;
94 LOG_ERROR <<
"Export failed: " << pathStr;
105 assert(ctx.
exporters &&
"DrawContext::exporters must not be null");
106 assert(ctx.
selectedExporter &&
"DrawContext::selectedExporter must not be null");
107 assert(ctx.
exportPath &&
"DrawContext::exportPath must not be null");
108 assert(ctx.
exportStatus &&
"DrawContext::exportStatus must not be null");
114 ImGui::SeparatorText(
"Format");
117 for (
int i = 0; i < static_cast<int>(ctx.
exporters->size()); ++i)
119 std::string label = wstringToString((*ctx.
exporters)[i]->menuLabel());
121 if (i <
static_cast<int>(ctx.
exporters->size()) - 1)
127 ImGui::SeparatorText(
"Output");
128 ImGui::Text(
"File Path:");
129 ImGui::SetNextItemWidth(-1);
130 ImGui::InputText(
"##exportPath", ctx.
exportPath);
139 ImGui::SeparatorText(
"Animations");
144 if (ImGui::Button(
"Select All"))
148 if (ImGui::Button(
"Select None"))
152 int checkedCount = 0;
154 ImGui::Text(
"%d / %d selected", checkedCount,
157 ImGui::BeginChild(
"##AnimExportList", ImVec2(0, 200), ImGuiChildFlags_Borders);
158 ImGuiListClipper clipper;
159 clipper.Begin(
static_cast<int>(ctx.
animEntries->size()));
160 while (clipper.Step())
162 for (
int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i)
166 if (ImGui::Checkbox((*ctx.
animEntries)[i].label.c_str(), &checked))
175 ImGui::SeparatorText(
"Animations");
176 ImGui::TextDisabled(
"No animations on current model.");
181 if (ImGui::Button(
"Export", ImVec2(-1, 0)))
186 if (ImGui::Button(
"Export Current Anim Only", ImVec2(-1, 0)))
200 bool isError = ctx.
exportStatus->find(
"failed") != std::string::npos ||
204 ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f),
"%s", ctx.
exportStatus->c_str());
206 ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f),
"%s", ctx.
exportStatus->c_str());
211 ImGui::TextDisabled(
"No model loaded.");
Abstract base class for model export plugins (OBJ, FBX, etc.).
virtual bool exportModel(Model *, std::wstring file)=0
void setAnimationsToExport(std::vector< int > values)
virtual std::wstring fileSaveFilter() const =0
bool canExportAnimation() const
Core WoW .m2 model: geometry, animation, textures, and character data.
std::vector< ModelAnimation > anims
void end(GLFWwindow *window, const char *statusText)
ImGui panel for exporting models to OBJ / FBX formats.
void draw(DrawContext &ctx)
std::string wstringToString(const std::wstring &ws)
Convert a wide string to narrow ASCII (lossy, for display only).
bool endsWithIgnoreCase(const std::string &s, const std::string &suffix)
Per-frame context for the export panel.
std::vector< std::unique_ptr< ExporterPlugin > > * exporters
std::vector< AnimEntry > * animEntries
std::vector< char > * exportAnimChecked
std::function< WoWModel *()> getLoadedModel
std::string * exportStatus