goat3d

view exporters/maxgoat/src/maxgoat.cc @ 25:d0260d80ae09

adding the nodes interface, and continuing the max plugin
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 28 Sep 2013 19:12:50 +0300
parents 1f94a2107c64
children 4deb0b12fe14
line source
1 #include <stdio.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <windows.h>
5 #include <shlobj.h>
6 #include "max.h"
7 #include "impexp.h" // SceneExport
8 #include "iparamb2.h" // ClassDesc2
9 #include "plugapi.h"
10 #include "IGame.h"
11 #include "IGameExport.h"
12 #include "IConversionmanager.h"
13 #include "goat3d.h"
14 #include "config.h"
17 #pragma comment (lib, "core.lib")
18 #pragma comment (lib, "geom.lib")
19 #pragma comment (lib, "gfx.lib")
20 #pragma comment (lib, "mesh.lib")
21 #pragma comment (lib, "maxutil.lib")
22 #pragma comment (lib, "maxscrpt.lib")
23 #pragma comment (lib, "paramblk2.lib")
24 #pragma comment (lib, "msxml2.lib")
25 #pragma comment (lib, "igame.lib")
26 #pragma comment (lib, "comctl32.lib")
29 #define VERSION(major, minor) \
30 ((major) * 100 + ((minor) < 10 ? (minor) * 10 : (minor)))
32 static FILE *logfile;
33 static HINSTANCE hinst;
35 class GoatExporter : public SceneExport {
36 public:
37 IGameScene *igame;
39 int ExtCount();
40 const TCHAR *Ext(int n);
41 const TCHAR *LongDesc();
42 const TCHAR *ShortDesc();
43 const TCHAR *AuthorName();
44 const TCHAR *CopyrightMessage();
45 const TCHAR *OtherMessage1();
46 const TCHAR *OtherMessage2();
47 unsigned int Version();
48 void ShowAbout(HWND win);
50 int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0);
52 void export_materials(goat3d *goat);
53 void export_meshes(goat3d *goat);
54 void process_node(goat3d *goat, IGameNode *maxnode);
55 };
58 int GoatExporter::ExtCount()
59 {
60 return 1;
61 }
63 const TCHAR *GoatExporter::Ext(int n)
64 {
65 return L"txt";
66 }
68 const TCHAR *GoatExporter::LongDesc()
69 {
70 return L"Goat3D scene file";
71 }
73 const TCHAR *GoatExporter::ShortDesc()
74 {
75 return L"Goat3D";
76 }
78 const TCHAR *GoatExporter::AuthorName()
79 {
80 return L"John Tsiombikas";
81 }
83 const TCHAR *GoatExporter::CopyrightMessage()
84 {
85 return L"Copyright 2013 (C) John Tsiombikas - GNU General Public License v3, see COPYING for details.";
86 }
88 const TCHAR *GoatExporter::OtherMessage1()
89 {
90 return L"other1";
91 }
93 const TCHAR *GoatExporter::OtherMessage2()
94 {
95 return L"other2";
96 }
98 unsigned int GoatExporter::Version()
99 {
100 return VERSION(VER_MAJOR, VER_MINOR);
101 }
103 void GoatExporter::ShowAbout(HWND win)
104 {
105 MessageBoxA(win, "Goat3D exporter plugin", "About this plugin", 0);
106 }
108 int GoatExporter::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface,
109 BOOL non_interactive, DWORD opt)
110 {
111 char fname[512];
112 wcstombs(fname, name, sizeof fname - 1);
114 if(!(igame = GetIGameInterface())) {
115 fprintf(logfile, "failed to get the igame interface\n");
116 return IMPEXP_FAIL;
117 }
118 IGameConversionManager *cm = GetConversionManager();
119 cm->SetCoordSystem(IGameConversionManager::IGAME_OGL);
120 igame->InitialiseIGame();
121 igame->SetStaticFrame(0);
123 goat3d *goat = goat3d_create();
125 export_materials(goat);
126 export_meshes(goat);
128 if(goat3d_save(goat, fname) == -1) {
129 goat3d_free(goat);
130 return IMPEXP_FAIL;
131 }
133 // process all nodes
134 for(int i=0; i<igame->GetTopLevelNodeCount(); i++) {
135 IGameNode *node = igame->GetTopLevelNode(i);
136 process_node(goat, node);
137 }
139 goat3d_free(goat);
140 return IMPEXP_SUCCESS;
141 }
143 static const char *max_string(const MCHAR *wstr)
144 {
145 if(!wstr) return 0;
146 static char str[512];
147 wcstombs(str, wstr, sizeof str - 1);
148 return str;
149 }
151 void GoatExporter::export_materials(goat3d *goat)
152 {
153 IGameProperty *prop;
155 int num_mtl = igame->GetRootMaterialCount();
156 for(int i=0; i<num_mtl; i++) {
157 IGameMaterial *maxmtl = igame->GetRootMaterial(i);
158 if(maxmtl) {
159 goat3d_material *mtl = goat3d_create_mtl();
161 const char *name = max_string(maxmtl->GetMaterialName());
162 if(name) {
163 goat3d_set_mtl_name(mtl, name);
164 }
166 // diffuse
167 if((prop = maxmtl->GetDiffuseData())) {
168 Point3 diffuse(1, 1, 1);
169 prop->GetPropertyValue(diffuse);
170 goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, diffuse[0],
171 diffuse[1], diffuse[2]);
172 }
173 // specular
174 if((prop = maxmtl->GetSpecularData())) {
175 Point3 specular(0, 0, 0);
176 prop->GetPropertyValue(specular);
178 float sstr = 1.0;
179 if((prop = maxmtl->GetSpecularLevelData())) {
180 prop->GetPropertyValue(sstr);
181 }
182 goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_SPECULAR, specular[0] * sstr,
183 specular[1] * sstr, specular[2] * sstr);
184 }
185 // shininess
186 if((prop = maxmtl->GetGlossinessData())) {
187 float shin;
188 prop->GetPropertyValue(shin);
189 goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_SHININESS, shin * 100.0);
190 }
192 // textures
193 for(int j=0; j<maxmtl->GetNumberOfTextureMaps(); j++) {
194 IGameTextureMap *tex = maxmtl->GetIGameTextureMap(j);
196 const char *fname = max_string(tex->GetBitmapFileName());
197 if(!fname) {
198 continue;
199 }
201 int slot = tex->GetStdMapSlot();
202 switch(slot) {
203 case ID_DI: // diffuse
204 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_DIFFUSE, fname);
205 break;
207 case ID_SP:
208 case ID_SS:
209 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SPECULAR, fname);
210 break;
212 case ID_SH:
213 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SHININESS, fname);
214 break;
216 case ID_BU:
217 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_NORMAL, fname);
218 break;
220 case ID_RL:
221 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_REFLECTION, fname);
222 break;
224 case ID_RR:
225 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, fname);
226 break;
228 default:
229 break;
230 }
231 }
233 goat3d_add_mtl(goat, mtl);
234 }
235 }
236 }
238 void GoatExporter::export_meshes(goat3d *goat)
239 {
240 Tab<IGameNode*> meshes = igame->GetIGameNodeByType(IGameObject::IGAME_MESH);
242 for(int i=0; i<meshes.Count(); i++) {
243 const char *name = max_string(meshes[i]->GetName());
244 }
245 }
247 // ------------------------------------------
249 class GoatClassDesc : public ClassDesc2 {
250 public:
251 int IsPublic() { return TRUE; }
252 void *Create(BOOL loading = FALSE) { return new GoatExporter; }
253 const TCHAR *ClassName() { return L"GoatExporter"; }
254 SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
255 Class_ID ClassID() { return Class_ID(0x77050f0d, 0x7d4c5ab5); }
256 const TCHAR *Category() { return L"Mutant Stargoat"; }
258 const TCHAR *InternalName() { return L"GoatExporter"; }
259 HINSTANCE HInstance() { return hinst; }
260 };
262 static GoatClassDesc class_desc;
264 BOOL WINAPI DllMain(HINSTANCE inst_handle, ULONG reason, void *reserved)
265 {
266 if(reason == DLL_PROCESS_ATTACH) {
267 hinst = inst_handle;
268 DisableThreadLibraryCalls(hinst);
269 }
270 return TRUE;
271 }
273 extern "C" {
275 __declspec(dllexport) const TCHAR *LibDescription()
276 {
277 return L"test exporter";
278 }
280 __declspec(dllexport) int LibNumberClasses()
281 {
282 return 1;
283 }
285 __declspec(dllexport) ClassDesc *LibClassDesc(int i)
286 {
287 return i == 0 ? &class_desc : 0;
288 }
290 __declspec(dllexport) ULONG LibVersion()
291 {
292 return Get3DSMAXVersion();
293 }
295 __declspec(dllexport) int LibInitialize()
296 {
297 static char path[1024];
299 SHGetFolderPathA(0, CSIDL_PERSONAL, 0, 0, path);
300 strcat(path, "/testexp.log");
302 if((logfile = fopen(path, "w"))) {
303 setvbuf(logfile, 0, _IONBF, 0);
304 }
305 return TRUE;
306 }
308 __declspec(dllexport) int LibShutdown()
309 {
310 if(logfile) {
311 fclose(logfile);
312 logfile = 0;
313 }
314 return TRUE;
315 }
317 } // extern "C"