goat3d

annotate exporters/maxgoat/src/maxgoat.cc @ 61:fdece14403ff

max gui
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 31 Mar 2014 09:41:47 +0300
parents 0c3576325480
children 3751aabbc5b3
rev   line source
nuclear@5 1 #include <stdio.h>
nuclear@5 2 #include <string.h>
nuclear@27 3 #include <stdlib.h>
nuclear@5 4 #include <errno.h>
nuclear@27 5 #include <map>
nuclear@5 6 #include <windows.h>
nuclear@5 7 #include <shlobj.h>
nuclear@5 8 #include "max.h"
nuclear@5 9 #include "impexp.h" // SceneExport
nuclear@5 10 #include "iparamb2.h" // ClassDesc2
nuclear@5 11 #include "plugapi.h"
nuclear@5 12 #include "IGame.h"
nuclear@5 13 #include "IGameExport.h"
nuclear@5 14 #include "IConversionmanager.h"
nuclear@25 15 #include "goat3d.h"
nuclear@60 16 #include "minwin.h"
nuclear@10 17 #include "config.h"
nuclear@61 18 #include "logger.h"
nuclear@61 19 #include "resource.h"
nuclear@5 20
nuclear@5 21
nuclear@5 22 #pragma comment (lib, "core.lib")
nuclear@5 23 #pragma comment (lib, "geom.lib")
nuclear@5 24 #pragma comment (lib, "gfx.lib")
nuclear@5 25 #pragma comment (lib, "mesh.lib")
nuclear@5 26 #pragma comment (lib, "maxutil.lib")
nuclear@5 27 #pragma comment (lib, "maxscrpt.lib")
nuclear@5 28 #pragma comment (lib, "paramblk2.lib")
nuclear@5 29 #pragma comment (lib, "msxml2.lib")
nuclear@5 30 #pragma comment (lib, "igame.lib")
nuclear@5 31 #pragma comment (lib, "comctl32.lib")
nuclear@5 32
nuclear@5 33
nuclear@10 34 #define VERSION(major, minor) \
nuclear@10 35 ((major) * 100 + ((minor) < 10 ? (minor) * 10 : (minor)))
nuclear@10 36
nuclear@61 37 HINSTANCE hinst;
nuclear@5 38
nuclear@5 39 class GoatExporter : public SceneExport {
nuclear@27 40 private:
nuclear@28 41 std::map<IGameMaterial*, goat3d_material*> mtlmap;
nuclear@28 42 std::map<IGameNode*, goat3d_node*> nodemap;
nuclear@27 43
nuclear@5 44 public:
nuclear@5 45 IGameScene *igame;
nuclear@5 46
nuclear@5 47 int ExtCount();
nuclear@5 48 const TCHAR *Ext(int n);
nuclear@5 49 const TCHAR *LongDesc();
nuclear@5 50 const TCHAR *ShortDesc();
nuclear@5 51 const TCHAR *AuthorName();
nuclear@5 52 const TCHAR *CopyrightMessage();
nuclear@5 53 const TCHAR *OtherMessage1();
nuclear@5 54 const TCHAR *OtherMessage2();
nuclear@5 55 unsigned int Version();
nuclear@5 56 void ShowAbout(HWND win);
nuclear@5 57
nuclear@5 58 int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0);
nuclear@5 59
nuclear@27 60 void process_materials(goat3d *goat);
nuclear@27 61
nuclear@27 62 void process_node(goat3d *goat, goat3d_node *parent, IGameNode *maxnode);
nuclear@27 63
nuclear@27 64 void process_mesh(goat3d *goat, goat3d_mesh *mesh, IGameObject *maxobj);
nuclear@27 65 void process_light(goat3d *goat, goat3d_light *light, IGameObject *maxobj);
nuclear@27 66 void process_camera(goat3d *goat, goat3d_camera *cam, IGameObject *maxobj);
nuclear@5 67 };
nuclear@5 68
nuclear@5 69
nuclear@5 70 int GoatExporter::ExtCount()
nuclear@5 71 {
nuclear@5 72 return 1;
nuclear@5 73 }
nuclear@5 74
nuclear@5 75 const TCHAR *GoatExporter::Ext(int n)
nuclear@5 76 {
nuclear@27 77 return L"xml";
nuclear@5 78 }
nuclear@5 79
nuclear@5 80 const TCHAR *GoatExporter::LongDesc()
nuclear@5 81 {
nuclear@5 82 return L"Goat3D scene file";
nuclear@5 83 }
nuclear@5 84
nuclear@5 85 const TCHAR *GoatExporter::ShortDesc()
nuclear@5 86 {
nuclear@5 87 return L"Goat3D";
nuclear@5 88 }
nuclear@5 89
nuclear@5 90 const TCHAR *GoatExporter::AuthorName()
nuclear@5 91 {
nuclear@5 92 return L"John Tsiombikas";
nuclear@5 93 }
nuclear@5 94
nuclear@5 95 const TCHAR *GoatExporter::CopyrightMessage()
nuclear@5 96 {
nuclear@5 97 return L"Copyright 2013 (C) John Tsiombikas - GNU General Public License v3, see COPYING for details.";
nuclear@5 98 }
nuclear@5 99
nuclear@5 100 const TCHAR *GoatExporter::OtherMessage1()
nuclear@5 101 {
nuclear@5 102 return L"other1";
nuclear@5 103 }
nuclear@5 104
nuclear@5 105 const TCHAR *GoatExporter::OtherMessage2()
nuclear@5 106 {
nuclear@5 107 return L"other2";
nuclear@5 108 }
nuclear@5 109
nuclear@5 110 unsigned int GoatExporter::Version()
nuclear@5 111 {
nuclear@10 112 return VERSION(VER_MAJOR, VER_MINOR);
nuclear@5 113 }
nuclear@5 114
nuclear@5 115 void GoatExporter::ShowAbout(HWND win)
nuclear@5 116 {
nuclear@5 117 MessageBoxA(win, "Goat3D exporter plugin", "About this plugin", 0);
nuclear@5 118 }
nuclear@5 119
nuclear@61 120 static INT_PTR CALLBACK handle_dlg_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam)
nuclear@61 121 {
nuclear@61 122 switch(msg) {
nuclear@61 123 case WM_INITDIALOG:
nuclear@61 124 CheckDlgButton(win, IDC_GOAT_NODES, 1);
nuclear@61 125 CheckDlgButton(win, IDC_GOAT_MESHES, 1);
nuclear@61 126 CheckDlgButton(win, IDC_GOAT_LIGHTS, 1);
nuclear@61 127 CheckDlgButton(win, IDC_GOAT_CAMERAS, 1);
nuclear@61 128 break;
nuclear@61 129
nuclear@61 130 case WM_COMMAND:
nuclear@61 131 switch(LOWORD(wparam)) {
nuclear@61 132 case IDOK:
nuclear@61 133 EndDialog(win, 1);
nuclear@61 134 break;
nuclear@61 135
nuclear@61 136 case IDCANCEL:
nuclear@61 137 EndDialog(win, 0);
nuclear@61 138 break;
nuclear@61 139
nuclear@61 140 default:
nuclear@61 141 return 0;
nuclear@61 142 }
nuclear@61 143 break;
nuclear@61 144
nuclear@61 145 default:
nuclear@61 146 return 0;
nuclear@61 147 }
nuclear@61 148
nuclear@61 149 return 1;
nuclear@61 150 }
nuclear@61 151
nuclear@5 152 int GoatExporter::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface,
nuclear@5 153 BOOL non_interactive, DWORD opt)
nuclear@5 154 {
nuclear@61 155 if(!DialogBox(hinst, MAKEINTRESOURCE(IDD_GOAT_SCE), 0, handle_dlg_events)) {
nuclear@61 156 maxlog("canceled!\n");
nuclear@61 157 return IMPEXP_CANCEL;
nuclear@61 158 }
nuclear@60 159
nuclear@28 160 mtlmap.clear();
nuclear@28 161 nodemap.clear();
nuclear@27 162
nuclear@5 163 char fname[512];
nuclear@5 164 wcstombs(fname, name, sizeof fname - 1);
nuclear@5 165
nuclear@61 166 maxlog("Exporting Goat3D Scene (text) file: %s\n", fname);
nuclear@5 167 if(!(igame = GetIGameInterface())) {
nuclear@61 168 maxlog("failed to get the igame interface\n");
nuclear@5 169 return IMPEXP_FAIL;
nuclear@5 170 }
nuclear@5 171 IGameConversionManager *cm = GetConversionManager();
nuclear@5 172 cm->SetCoordSystem(IGameConversionManager::IGAME_OGL);
nuclear@5 173 igame->InitialiseIGame();
nuclear@5 174 igame->SetStaticFrame(0);
nuclear@5 175
nuclear@25 176 goat3d *goat = goat3d_create();
nuclear@5 177
nuclear@27 178 process_materials(goat);
nuclear@27 179
nuclear@27 180 // process all nodes
nuclear@27 181 for(int i=0; i<igame->GetTopLevelNodeCount(); i++) {
nuclear@27 182 IGameNode *node = igame->GetTopLevelNode(i);
nuclear@27 183 process_node(goat, 0, node);
nuclear@27 184 }
nuclear@5 185
nuclear@25 186 if(goat3d_save(goat, fname) == -1) {
nuclear@25 187 goat3d_free(goat);
nuclear@25 188 return IMPEXP_FAIL;
nuclear@25 189 }
nuclear@25 190
nuclear@25 191 goat3d_free(goat);
nuclear@5 192 return IMPEXP_SUCCESS;
nuclear@5 193 }
nuclear@5 194
nuclear@25 195 static const char *max_string(const MCHAR *wstr)
nuclear@25 196 {
nuclear@25 197 if(!wstr) return 0;
nuclear@25 198 static char str[512];
nuclear@25 199 wcstombs(str, wstr, sizeof str - 1);
nuclear@25 200 return str;
nuclear@25 201 }
nuclear@25 202
nuclear@27 203 void GoatExporter::process_materials(goat3d *goat)
nuclear@5 204 {
nuclear@5 205 IGameProperty *prop;
nuclear@5 206
nuclear@5 207 int num_mtl = igame->GetRootMaterialCount();
nuclear@25 208 for(int i=0; i<num_mtl; i++) {
nuclear@25 209 IGameMaterial *maxmtl = igame->GetRootMaterial(i);
nuclear@25 210 if(maxmtl) {
nuclear@25 211 goat3d_material *mtl = goat3d_create_mtl();
nuclear@5 212
nuclear@25 213 const char *name = max_string(maxmtl->GetMaterialName());
nuclear@25 214 if(name) {
nuclear@25 215 goat3d_set_mtl_name(mtl, name);
nuclear@5 216 }
nuclear@5 217
nuclear@25 218 // diffuse
nuclear@25 219 if((prop = maxmtl->GetDiffuseData())) {
nuclear@25 220 Point3 diffuse(1, 1, 1);
nuclear@5 221 prop->GetPropertyValue(diffuse);
nuclear@25 222 goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, diffuse[0],
nuclear@25 223 diffuse[1], diffuse[2]);
nuclear@5 224 }
nuclear@25 225 // specular
nuclear@25 226 if((prop = maxmtl->GetSpecularData())) {
nuclear@25 227 Point3 specular(0, 0, 0);
nuclear@5 228 prop->GetPropertyValue(specular);
nuclear@25 229
nuclear@25 230 float sstr = 1.0;
nuclear@25 231 if((prop = maxmtl->GetSpecularLevelData())) {
nuclear@25 232 prop->GetPropertyValue(sstr);
nuclear@25 233 }
nuclear@25 234 goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_SPECULAR, specular[0] * sstr,
nuclear@25 235 specular[1] * sstr, specular[2] * sstr);
nuclear@5 236 }
nuclear@25 237 // shininess
nuclear@25 238 if((prop = maxmtl->GetGlossinessData())) {
nuclear@25 239 float shin;
nuclear@5 240 prop->GetPropertyValue(shin);
nuclear@25 241 goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_SHININESS, shin * 100.0);
nuclear@5 242 }
nuclear@5 243
nuclear@25 244 // textures
nuclear@25 245 for(int j=0; j<maxmtl->GetNumberOfTextureMaps(); j++) {
nuclear@25 246 IGameTextureMap *tex = maxmtl->GetIGameTextureMap(j);
nuclear@5 247
nuclear@25 248 const char *fname = max_string(tex->GetBitmapFileName());
nuclear@25 249 if(!fname) {
nuclear@25 250 continue;
nuclear@25 251 }
nuclear@25 252
nuclear@25 253 int slot = tex->GetStdMapSlot();
nuclear@25 254 switch(slot) {
nuclear@25 255 case ID_DI: // diffuse
nuclear@25 256 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_DIFFUSE, fname);
nuclear@25 257 break;
nuclear@25 258
nuclear@25 259 case ID_SP:
nuclear@25 260 case ID_SS:
nuclear@25 261 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SPECULAR, fname);
nuclear@25 262 break;
nuclear@25 263
nuclear@25 264 case ID_SH:
nuclear@25 265 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SHININESS, fname);
nuclear@25 266 break;
nuclear@25 267
nuclear@25 268 case ID_BU:
nuclear@25 269 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_NORMAL, fname);
nuclear@25 270 break;
nuclear@25 271
nuclear@25 272 case ID_RL:
nuclear@25 273 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_REFLECTION, fname);
nuclear@25 274 break;
nuclear@25 275
nuclear@25 276 case ID_RR:
nuclear@25 277 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, fname);
nuclear@25 278 break;
nuclear@25 279
nuclear@25 280 default:
nuclear@25 281 break;
nuclear@5 282 }
nuclear@5 283 }
nuclear@25 284
nuclear@25 285 goat3d_add_mtl(goat, mtl);
nuclear@28 286 mtlmap[maxmtl] = mtl;
nuclear@5 287 }
nuclear@5 288 }
nuclear@25 289 }
nuclear@5 290
nuclear@27 291 void GoatExporter::process_node(goat3d *goat, goat3d_node *parent, IGameNode *maxnode)
nuclear@25 292 {
nuclear@27 293 goat3d_node *node = goat3d_create_node();
nuclear@27 294 goat3d_add_node(goat, node);
nuclear@25 295
nuclear@27 296 const char *name = max_string(maxnode->GetName());
nuclear@27 297 if(name) {
nuclear@27 298 goat3d_set_node_name(node, name);
nuclear@27 299 }
nuclear@27 300
nuclear@27 301 // no animation yet, just get the static PRS
nuclear@27 302 GMatrix maxmatrix = maxnode->GetObjectTM();
nuclear@27 303 Point3 trans = maxmatrix.Translation();
nuclear@27 304 Quat rot = maxmatrix.Rotation();
nuclear@27 305 Point3 scale = maxmatrix.Scaling();
nuclear@27 306
nuclear@27 307 goat3d_set_node_position(node, trans.x, trans.y, trans.z, 0);
nuclear@27 308 goat3d_set_node_rotation(node, rot.x, rot.y, rot.z, rot.w, 0);
nuclear@27 309 goat3d_set_node_scaling(node, scale.x, scale.y, scale.z, 0);
nuclear@27 310
nuclear@27 311 IGameObject *maxobj = maxnode->GetIGameObject();
nuclear@27 312 IGameObject::ObjectTypes type = maxobj->GetIGameType();
nuclear@27 313
nuclear@27 314 switch(type) {
nuclear@27 315 case IGameObject::IGAME_MESH:
nuclear@27 316 {
nuclear@27 317 goat3d_mesh *mesh = goat3d_create_mesh();
nuclear@27 318 if(name) goat3d_set_mesh_name(mesh, name);
nuclear@27 319 goat3d_set_node_object(node, GOAT3D_NODE_MESH, mesh);
nuclear@27 320
nuclear@27 321 // get the node material and assign it to the mesh
nuclear@27 322 IGameMaterial *maxmtl = maxnode->GetNodeMaterial();
nuclear@28 323 goat3d_material *mtl = mtlmap[maxmtl];
nuclear@27 324 if(mtl) {
nuclear@27 325 goat3d_set_mesh_mtl(mesh, mtl);
nuclear@27 326 }
nuclear@27 327
nuclear@27 328 process_mesh(goat, mesh, maxobj);
nuclear@30 329 goat3d_add_mesh(goat, mesh);
nuclear@27 330 }
nuclear@27 331 break;
nuclear@27 332
nuclear@27 333 case IGameObject::IGAME_LIGHT:
nuclear@27 334 {
nuclear@27 335 goat3d_light *light = goat3d_create_light();
nuclear@27 336 //if(name) goat3d_set_light_name(light, name);
nuclear@27 337 goat3d_set_node_object(node, GOAT3D_NODE_LIGHT, light);
nuclear@27 338
nuclear@27 339 process_light(goat, light, maxobj);
nuclear@30 340 goat3d_add_light(goat, light);
nuclear@27 341 }
nuclear@27 342 break;
nuclear@27 343
nuclear@27 344 case IGameObject::IGAME_CAMERA:
nuclear@27 345 {
nuclear@27 346 goat3d_camera *cam = goat3d_create_camera();
nuclear@27 347 //if(name) goat3d_set_camera_name(camera, name);
nuclear@27 348 goat3d_set_node_object(node, GOAT3D_NODE_CAMERA, cam);
nuclear@27 349
nuclear@27 350 process_camera(goat, cam, maxobj);
nuclear@30 351 goat3d_add_camera(goat, cam);
nuclear@27 352 }
nuclear@27 353 break;
nuclear@27 354
nuclear@27 355 default:
nuclear@27 356 // otherwise don't assign an object, essentially treating it as a null node
nuclear@27 357 break;
nuclear@27 358 }
nuclear@27 359
nuclear@27 360
nuclear@27 361 for(int i=0; i<maxnode->GetChildCount(); i++) {
nuclear@27 362 process_node(goat, node, maxnode->GetNodeChild(i));
nuclear@25 363 }
nuclear@5 364 }
nuclear@5 365
nuclear@27 366 void GoatExporter::process_mesh(goat3d *goat, goat3d_mesh *mesh, IGameObject *maxobj)
nuclear@27 367 {
nuclear@27 368 IGameMesh *maxmesh = (IGameMesh*)maxobj;
nuclear@27 369
nuclear@27 370 maxmesh->SetCreateOptimizedNormalList(); // not needed any more according to docs
nuclear@27 371 maxobj->InitializeData();
nuclear@27 372
nuclear@27 373 int num_verts = maxmesh->GetNumberOfVerts();
nuclear@30 374 int num_faces = maxmesh->GetNumberOfFaces();
nuclear@28 375 //assert(maxmesh->GetNumberOfTexVerts() == num_verts);
nuclear@27 376
nuclear@27 377 float *vertices = new float[num_verts * 3];
nuclear@27 378 float *normals = new float[num_verts * 3];
nuclear@28 379 //float *texcoords = new float[num_verts * 2];
nuclear@30 380 int *indices = new int[num_faces * 3];
nuclear@27 381
nuclear@27 382 for(int i=0; i<num_verts; i++) {
nuclear@27 383 Point3 v = maxmesh->GetVertex(i, true);
nuclear@27 384 vertices[i * 3] = v.x;
nuclear@27 385 vertices[i * 3 + 1] = v.y;
nuclear@27 386 vertices[i * 3 + 2] = v.z;
nuclear@27 387 }
nuclear@27 388
nuclear@27 389 for(int i=0; i<maxmesh->GetNumberOfNormals(); i++) {
nuclear@27 390 Point3 norm = maxmesh->GetNormal(i);
nuclear@27 391
nuclear@27 392 int vidx = maxmesh->GetNormalVertexIndex(i);
nuclear@27 393 normals[vidx * 3] = norm.x;
nuclear@27 394 normals[vidx * 3 + 1] = norm.y;
nuclear@27 395 normals[vidx * 3 + 2] = norm.z;
nuclear@27 396 }
nuclear@27 397
nuclear@28 398 /*for(int i=0; i<maxmesh->GetNumberOfTexVerts(); i++) {
nuclear@27 399 Point3 tex = maxmesh->GetTexVertex(i);
nuclear@27 400
nuclear@27 401 texcoords[i * 2] = tex.x;
nuclear@27 402 texcoords[i * 2 + 1] = tex.y;
nuclear@28 403 }*/
nuclear@27 404
nuclear@30 405 // get the faces
nuclear@30 406 for(int i=0; i<num_faces; i++) {
nuclear@30 407 FaceEx *face = maxmesh->GetFace(i);
nuclear@30 408 indices[i * 3] = face->vert[0];
nuclear@30 409 indices[i * 3 + 1] = face->vert[1];
nuclear@30 410 indices[i * 3 + 2] = face->vert[2];
nuclear@30 411 // TODO at some point I'll have to split based on normal/texcoord indices
nuclear@30 412 }
nuclear@30 413
nuclear@27 414 goat3d_set_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX, vertices, num_verts);
nuclear@27 415 goat3d_set_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL, normals, num_verts);
nuclear@28 416 //goat3d_set_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD, texcoords, num_verts);
nuclear@30 417 goat3d_set_mesh_faces(mesh, indices, num_faces);
nuclear@27 418
nuclear@27 419 delete [] vertices;
nuclear@27 420 delete [] normals;
nuclear@28 421 //delete [] texcoords;
nuclear@30 422 delete [] indices;
nuclear@27 423 }
nuclear@27 424
nuclear@27 425 void GoatExporter::process_light(goat3d *goat, goat3d_light *light, IGameObject *maxobj)
nuclear@27 426 {
nuclear@27 427 }
nuclear@27 428
nuclear@27 429 void GoatExporter::process_camera(goat3d *goat, goat3d_camera *cam, IGameObject *maxobj)
nuclear@27 430 {
nuclear@27 431 }
nuclear@27 432
nuclear@27 433
nuclear@5 434 // ------------------------------------------
nuclear@5 435
nuclear@5 436 class GoatClassDesc : public ClassDesc2 {
nuclear@5 437 public:
nuclear@5 438 int IsPublic() { return TRUE; }
nuclear@5 439 void *Create(BOOL loading = FALSE) { return new GoatExporter; }
nuclear@5 440 const TCHAR *ClassName() { return L"GoatExporter"; }
nuclear@5 441 SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
nuclear@5 442 Class_ID ClassID() { return Class_ID(0x77050f0d, 0x7d4c5ab5); }
nuclear@5 443 const TCHAR *Category() { return L"Mutant Stargoat"; }
nuclear@5 444
nuclear@5 445 const TCHAR *InternalName() { return L"GoatExporter"; }
nuclear@5 446 HINSTANCE HInstance() { return hinst; }
nuclear@5 447 };
nuclear@5 448
nuclear@58 449 // TODO: make 2 class descriptors, one for goat3d, one for goat3danim
nuclear@5 450 static GoatClassDesc class_desc;
nuclear@5 451
nuclear@5 452 BOOL WINAPI DllMain(HINSTANCE inst_handle, ULONG reason, void *reserved)
nuclear@5 453 {
nuclear@5 454 if(reason == DLL_PROCESS_ATTACH) {
nuclear@5 455 hinst = inst_handle;
nuclear@5 456 DisableThreadLibraryCalls(hinst);
nuclear@5 457 }
nuclear@5 458 return TRUE;
nuclear@5 459 }
nuclear@5 460
nuclear@5 461 extern "C" {
nuclear@5 462
nuclear@5 463 __declspec(dllexport) const TCHAR *LibDescription()
nuclear@5 464 {
nuclear@5 465 return L"test exporter";
nuclear@5 466 }
nuclear@5 467
nuclear@5 468 __declspec(dllexport) int LibNumberClasses()
nuclear@5 469 {
nuclear@5 470 return 1;
nuclear@5 471 }
nuclear@5 472
nuclear@5 473 __declspec(dllexport) ClassDesc *LibClassDesc(int i)
nuclear@5 474 {
nuclear@5 475 return i == 0 ? &class_desc : 0;
nuclear@5 476 }
nuclear@5 477
nuclear@5 478 __declspec(dllexport) ULONG LibVersion()
nuclear@5 479 {
nuclear@5 480 return Get3DSMAXVersion();
nuclear@5 481 }
nuclear@5 482
nuclear@5 483 __declspec(dllexport) int LibInitialize()
nuclear@5 484 {
nuclear@5 485 static char path[1024];
nuclear@5 486
nuclear@5 487 SHGetFolderPathA(0, CSIDL_PERSONAL, 0, 0, path);
nuclear@5 488 strcat(path, "/testexp.log");
nuclear@5 489
nuclear@61 490 maxlog_open(path);
nuclear@5 491 return TRUE;
nuclear@5 492 }
nuclear@5 493
nuclear@5 494 __declspec(dllexport) int LibShutdown()
nuclear@5 495 {
nuclear@61 496 maxlog_close();
nuclear@5 497 return TRUE;
nuclear@5 498 }
nuclear@5 499
nuclear@5 500 } // extern "C"