nuclear@5: #include nuclear@5: #include nuclear@5: #include nuclear@5: #include nuclear@5: #include nuclear@5: #include "max.h" nuclear@5: #include "impexp.h" // SceneExport nuclear@5: #include "iparamb2.h" // ClassDesc2 nuclear@5: #include "plugapi.h" nuclear@5: #include "IGame.h" nuclear@5: #include "IGameExport.h" nuclear@5: #include "IConversionmanager.h" nuclear@25: #include "goat3d.h" nuclear@10: #include "config.h" nuclear@5: nuclear@5: nuclear@5: #pragma comment (lib, "core.lib") nuclear@5: #pragma comment (lib, "geom.lib") nuclear@5: #pragma comment (lib, "gfx.lib") nuclear@5: #pragma comment (lib, "mesh.lib") nuclear@5: #pragma comment (lib, "maxutil.lib") nuclear@5: #pragma comment (lib, "maxscrpt.lib") nuclear@5: #pragma comment (lib, "paramblk2.lib") nuclear@5: #pragma comment (lib, "msxml2.lib") nuclear@5: #pragma comment (lib, "igame.lib") nuclear@5: #pragma comment (lib, "comctl32.lib") nuclear@5: nuclear@5: nuclear@10: #define VERSION(major, minor) \ nuclear@10: ((major) * 100 + ((minor) < 10 ? (minor) * 10 : (minor))) nuclear@10: nuclear@5: static FILE *logfile; nuclear@5: static HINSTANCE hinst; nuclear@5: nuclear@5: class GoatExporter : public SceneExport { nuclear@5: public: nuclear@5: IGameScene *igame; nuclear@5: nuclear@5: int ExtCount(); nuclear@5: const TCHAR *Ext(int n); nuclear@5: const TCHAR *LongDesc(); nuclear@5: const TCHAR *ShortDesc(); nuclear@5: const TCHAR *AuthorName(); nuclear@5: const TCHAR *CopyrightMessage(); nuclear@5: const TCHAR *OtherMessage1(); nuclear@5: const TCHAR *OtherMessage2(); nuclear@5: unsigned int Version(); nuclear@5: void ShowAbout(HWND win); nuclear@5: nuclear@5: int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0); nuclear@5: nuclear@25: void export_materials(goat3d *goat); nuclear@25: void export_meshes(goat3d *goat); nuclear@25: void process_node(goat3d *goat, IGameNode *maxnode); nuclear@5: }; nuclear@5: nuclear@5: nuclear@5: int GoatExporter::ExtCount() nuclear@5: { nuclear@5: return 1; nuclear@5: } nuclear@5: nuclear@5: const TCHAR *GoatExporter::Ext(int n) nuclear@5: { nuclear@5: return L"txt"; nuclear@5: } nuclear@5: nuclear@5: const TCHAR *GoatExporter::LongDesc() nuclear@5: { nuclear@5: return L"Goat3D scene file"; nuclear@5: } nuclear@5: nuclear@5: const TCHAR *GoatExporter::ShortDesc() nuclear@5: { nuclear@5: return L"Goat3D"; nuclear@5: } nuclear@5: nuclear@5: const TCHAR *GoatExporter::AuthorName() nuclear@5: { nuclear@5: return L"John Tsiombikas"; nuclear@5: } nuclear@5: nuclear@5: const TCHAR *GoatExporter::CopyrightMessage() nuclear@5: { nuclear@5: return L"Copyright 2013 (C) John Tsiombikas - GNU General Public License v3, see COPYING for details."; nuclear@5: } nuclear@5: nuclear@5: const TCHAR *GoatExporter::OtherMessage1() nuclear@5: { nuclear@5: return L"other1"; nuclear@5: } nuclear@5: nuclear@5: const TCHAR *GoatExporter::OtherMessage2() nuclear@5: { nuclear@5: return L"other2"; nuclear@5: } nuclear@5: nuclear@5: unsigned int GoatExporter::Version() nuclear@5: { nuclear@10: return VERSION(VER_MAJOR, VER_MINOR); nuclear@5: } nuclear@5: nuclear@5: void GoatExporter::ShowAbout(HWND win) nuclear@5: { nuclear@5: MessageBoxA(win, "Goat3D exporter plugin", "About this plugin", 0); nuclear@5: } nuclear@5: nuclear@5: int GoatExporter::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, nuclear@5: BOOL non_interactive, DWORD opt) nuclear@5: { nuclear@5: char fname[512]; nuclear@5: wcstombs(fname, name, sizeof fname - 1); nuclear@5: nuclear@5: if(!(igame = GetIGameInterface())) { nuclear@5: fprintf(logfile, "failed to get the igame interface\n"); nuclear@5: return IMPEXP_FAIL; nuclear@5: } nuclear@5: IGameConversionManager *cm = GetConversionManager(); nuclear@5: cm->SetCoordSystem(IGameConversionManager::IGAME_OGL); nuclear@5: igame->InitialiseIGame(); nuclear@5: igame->SetStaticFrame(0); nuclear@5: nuclear@25: goat3d *goat = goat3d_create(); nuclear@5: nuclear@25: export_materials(goat); nuclear@25: export_meshes(goat); nuclear@5: nuclear@25: if(goat3d_save(goat, fname) == -1) { nuclear@25: goat3d_free(goat); nuclear@25: return IMPEXP_FAIL; nuclear@25: } nuclear@25: nuclear@25: // process all nodes nuclear@25: for(int i=0; iGetTopLevelNodeCount(); i++) { nuclear@25: IGameNode *node = igame->GetTopLevelNode(i); nuclear@25: process_node(goat, node); nuclear@25: } nuclear@25: nuclear@25: goat3d_free(goat); nuclear@5: return IMPEXP_SUCCESS; nuclear@5: } nuclear@5: nuclear@25: static const char *max_string(const MCHAR *wstr) nuclear@25: { nuclear@25: if(!wstr) return 0; nuclear@25: static char str[512]; nuclear@25: wcstombs(str, wstr, sizeof str - 1); nuclear@25: return str; nuclear@25: } nuclear@25: nuclear@25: void GoatExporter::export_materials(goat3d *goat) nuclear@5: { nuclear@5: IGameProperty *prop; nuclear@5: nuclear@5: int num_mtl = igame->GetRootMaterialCount(); nuclear@25: for(int i=0; iGetRootMaterial(i); nuclear@25: if(maxmtl) { nuclear@25: goat3d_material *mtl = goat3d_create_mtl(); nuclear@5: nuclear@25: const char *name = max_string(maxmtl->GetMaterialName()); nuclear@25: if(name) { nuclear@25: goat3d_set_mtl_name(mtl, name); nuclear@5: } nuclear@5: nuclear@25: // diffuse nuclear@25: if((prop = maxmtl->GetDiffuseData())) { nuclear@25: Point3 diffuse(1, 1, 1); nuclear@5: prop->GetPropertyValue(diffuse); nuclear@25: goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, diffuse[0], nuclear@25: diffuse[1], diffuse[2]); nuclear@5: } nuclear@25: // specular nuclear@25: if((prop = maxmtl->GetSpecularData())) { nuclear@25: Point3 specular(0, 0, 0); nuclear@5: prop->GetPropertyValue(specular); nuclear@25: nuclear@25: float sstr = 1.0; nuclear@25: if((prop = maxmtl->GetSpecularLevelData())) { nuclear@25: prop->GetPropertyValue(sstr); nuclear@25: } nuclear@25: goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_SPECULAR, specular[0] * sstr, nuclear@25: specular[1] * sstr, specular[2] * sstr); nuclear@5: } nuclear@25: // shininess nuclear@25: if((prop = maxmtl->GetGlossinessData())) { nuclear@25: float shin; nuclear@5: prop->GetPropertyValue(shin); nuclear@25: goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_SHININESS, shin * 100.0); nuclear@5: } nuclear@5: nuclear@25: // textures nuclear@25: for(int j=0; jGetNumberOfTextureMaps(); j++) { nuclear@25: IGameTextureMap *tex = maxmtl->GetIGameTextureMap(j); nuclear@5: nuclear@25: const char *fname = max_string(tex->GetBitmapFileName()); nuclear@25: if(!fname) { nuclear@25: continue; nuclear@25: } nuclear@25: nuclear@25: int slot = tex->GetStdMapSlot(); nuclear@25: switch(slot) { nuclear@25: case ID_DI: // diffuse nuclear@25: goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_DIFFUSE, fname); nuclear@25: break; nuclear@25: nuclear@25: case ID_SP: nuclear@25: case ID_SS: nuclear@25: goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SPECULAR, fname); nuclear@25: break; nuclear@25: nuclear@25: case ID_SH: nuclear@25: goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SHININESS, fname); nuclear@25: break; nuclear@25: nuclear@25: case ID_BU: nuclear@25: goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_NORMAL, fname); nuclear@25: break; nuclear@25: nuclear@25: case ID_RL: nuclear@25: goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_REFLECTION, fname); nuclear@25: break; nuclear@25: nuclear@25: case ID_RR: nuclear@25: goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, fname); nuclear@25: break; nuclear@25: nuclear@25: default: nuclear@25: break; nuclear@5: } nuclear@5: } nuclear@25: nuclear@25: goat3d_add_mtl(goat, mtl); nuclear@5: } nuclear@5: } nuclear@25: } nuclear@5: nuclear@25: void GoatExporter::export_meshes(goat3d *goat) nuclear@25: { nuclear@25: Tab meshes = igame->GetIGameNodeByType(IGameObject::IGAME_MESH); nuclear@25: nuclear@25: for(int i=0; iGetName()); nuclear@25: } nuclear@5: } nuclear@5: nuclear@5: // ------------------------------------------ nuclear@5: nuclear@5: class GoatClassDesc : public ClassDesc2 { nuclear@5: public: nuclear@5: int IsPublic() { return TRUE; } nuclear@5: void *Create(BOOL loading = FALSE) { return new GoatExporter; } nuclear@5: const TCHAR *ClassName() { return L"GoatExporter"; } nuclear@5: SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } nuclear@5: Class_ID ClassID() { return Class_ID(0x77050f0d, 0x7d4c5ab5); } nuclear@5: const TCHAR *Category() { return L"Mutant Stargoat"; } nuclear@5: nuclear@5: const TCHAR *InternalName() { return L"GoatExporter"; } nuclear@5: HINSTANCE HInstance() { return hinst; } nuclear@5: }; nuclear@5: nuclear@5: static GoatClassDesc class_desc; nuclear@5: nuclear@5: BOOL WINAPI DllMain(HINSTANCE inst_handle, ULONG reason, void *reserved) nuclear@5: { nuclear@5: if(reason == DLL_PROCESS_ATTACH) { nuclear@5: hinst = inst_handle; nuclear@5: DisableThreadLibraryCalls(hinst); nuclear@5: } nuclear@5: return TRUE; nuclear@5: } nuclear@5: nuclear@5: extern "C" { nuclear@5: nuclear@5: __declspec(dllexport) const TCHAR *LibDescription() nuclear@5: { nuclear@5: return L"test exporter"; nuclear@5: } nuclear@5: nuclear@5: __declspec(dllexport) int LibNumberClasses() nuclear@5: { nuclear@5: return 1; nuclear@5: } nuclear@5: nuclear@5: __declspec(dllexport) ClassDesc *LibClassDesc(int i) nuclear@5: { nuclear@5: return i == 0 ? &class_desc : 0; nuclear@5: } nuclear@5: nuclear@5: __declspec(dllexport) ULONG LibVersion() nuclear@5: { nuclear@5: return Get3DSMAXVersion(); nuclear@5: } nuclear@5: nuclear@5: __declspec(dllexport) int LibInitialize() nuclear@5: { nuclear@5: static char path[1024]; nuclear@5: nuclear@5: SHGetFolderPathA(0, CSIDL_PERSONAL, 0, 0, path); nuclear@5: strcat(path, "/testexp.log"); nuclear@5: nuclear@5: if((logfile = fopen(path, "w"))) { nuclear@5: setvbuf(logfile, 0, _IONBF, 0); nuclear@5: } nuclear@5: return TRUE; nuclear@5: } nuclear@5: nuclear@5: __declspec(dllexport) int LibShutdown() nuclear@5: { nuclear@5: if(logfile) { nuclear@5: fclose(logfile); nuclear@5: logfile = 0; nuclear@5: } nuclear@5: return TRUE; nuclear@5: } nuclear@5: nuclear@5: } // extern "C"