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