/*************************************************************************** * * * 3DS Max Test Plugin * * * *************************************************************************** * * * Version : 1.0ß, March 11th, 1998 * * * * Written By Loic Baumann from Fatal Design, specially for Gamasutra * * * *************************************************************************** * * * This Plugin demonstrates how to write a simple 3DS MAX Plugin, using MFCs * * * ***************************************************************************/ #include "stdafx.h" #ifdef STRICT // Already defined by stdafx, #undef STRICT // so we avoid warning linking msg #endif #ifdef _MBCS // The same as above #undef _MBCS #endif #include #include "MissionImp.h" #include "ExportUtil.h" //#ifdef _DEBUG //#define new DEBUG_NEW //#undef THIS_FILE //static char THIS_FILE[] = __FILE__; //#endif #include #include "ExportUtil.h" //#include "mapsizedlg.h" //===========================================================================// int MissionImp::DoImport(const TCHAR *name, ImpInterface *ii,Interface *i, BOOL suppressPrompts) { int return_value; __try { m_ip = i; m_suppress = suppressPrompts?true:false; return_value = ImportMission(name); //return_value = true; GetSystemSetting(SYSSET_CLEAR_UNDO); Verify(!theHold.Holding()); } __except(ProcessException(GetExceptionInformation())) { } return return_value; } // in maxpolygonmesh.cpp Quat ConvertMWToMax(UnitQuaternion &quat); Point3 ConvertMWToMax(Stuff::Point3D &pnt); /******************************************************************************* /* function name: ImportVideo /* description: Import .video files /*******************************************************************************/ int MissionImp::ImportVideo(const char *name,Quat maxrot,Point3 maxtrans) { CString filename = GetGamePath(m_ip) + "content\\"+name; NotationFile videofile(filename); Page *page = videofile.FindPage("LOD"); if (page) { const char *entry; if (page->GetEntry("Geometry",&entry)) { char path[MAX_PATH]; _splitpath(name,NULL,path,NULL,NULL); CString path1(path); // trim "armaturevideo from the tail of the path path1.MakeLower(); int index = path1.Find("armaturevideo"); if (index>0) { path1 = path1.Left(index); } CString erfpath = GetGamePath(m_ip) + "content\\"; erfpath+=path1; erfpath+=entry; if (m_ip->ImportFromFile(erfpath,false)) { // Move any node with name not starting with "_" to the rotation/translation coordinates Matrix3 axis(MAT_IDENT); INode *pWorld = m_ip->GetRootNode(); for (int x=0;xNumberOfChildren();x++) { INode *pChild = pWorld->GetChildNode(x); CString name = pChild->GetName(); if (strnicmp(name,"_",1)) { name = CString("_")+name;//name; pChild->SetName((char *)(LPCTSTR)name); pChild->Rotate(0,axis,maxrot); pChild->Move(0,axis,maxtrans); Quat fixrot(0.0,0.0,PI/2.0,0.0); // Now move and rotate to the terrain's coordinate system // pChild->Move(0,axis,fixtrans); pChild->Rotate(0,axis,fixrot); } } return 1; } } } return 0; } /******************************************************************************* /* function name: ImportModel /* description: Import .data files /*******************************************************************************/ int MissionImp::ImportModel(const char *name,Quat maxrot,Point3 maxtrans) { CString filename = GetGamePath(m_ip) + "content\\"+name; NotationFile modelfile(filename); Page *page = modelfile.FindPage("Renderers"); if (page) { const char *entry; if (page->GetEntry("VideoRenderer",&entry)) { char path[MAX_PATH]; _splitpath(name,NULL,path,NULL,NULL); CString filename(path); // trim "armaturedata from the tail of the path filename.MakeLower(); int index = filename.Find("armaturedata"); if (index>0) { filename = filename.Left(index); } filename+=entry; return ImportVideo(filename,maxrot,maxtrans); } } return 0; } struct ARMNODE { ARMNODE *parent; CString name; const char *model; Quat rot; Point3 trans; }; /******************************************************************************* /* function name: ImportArmature /* description: Import .armature files /*******************************************************************************/ int MissionImp::ImportArmature(const char *name,Quat maxrot,Point3 maxtrans) { CString filename = GetGamePath(m_ip) + "content\\"+name; NotationFile armfile(filename); NotationFile::PageIterator *pages = armfile.MakePageIterator(); CMapStringToPtr mapNode; ARMNODE *pRoot = NULL; Page *page; while (page = pages->ReadAndNext()) { ARMNODE *pNode = new ARMNODE; if (NULL == pRoot) pRoot = pNode; pNode->name = page->GetName(); pNode->name.MakeLower(); mapNode[pNode->name] = pNode; pNode->parent = NULL; pNode->rot.Identity(); pNode->trans = Point3(0,0,0); pNode->model = NULL; } delete pages; pages = armfile.MakePageIterator(); while (page = pages->ReadAndNext()) { CString name = page->GetName(); name.MakeLower(); ARMNODE *pNode = (ARMNODE *)mapNode[name]; Page::NoteIterator *notes = page->MakeNoteIterator(); Note *note; while (note = notes->ReadAndNext()) { if (0==stricmp(note->GetName(),"rotation")) { YawPitchRoll ypr; note->GetEntry(&ypr); { UnitQuaternion rotation; rotation = ypr; pNode->rot = ConvertMWToMax(rotation); } } if (0==stricmp(note->GetName(),"translation")) { Point3D translation; note->GetEntry(&translation); { pNode->trans = ConvertMWToMax(translation); } } if (0==stricmp(note->GetName(),"child")) { const char *child; note->GetEntry(&child); { CString str(child); str.MakeLower(); ARMNODE *pChild = (ARMNODE *)mapNode[str]; Check_Pointer(pChild); pChild->parent = pNode; if (pChild == pRoot) pRoot= pNode; } } if (0==stricmp(note->GetName(),"model")) { const char *model; note->GetEntry(&model); { pNode->model = model; } } } delete notes; } delete pages; int count = 0; POSITION pos = mapNode.GetStartPosition(); while (pos) { CString key; LPVOID value; mapNode.GetNextAssoc(pos,key,value); ARMNODE *pNode = (ARMNODE *)value; if (pNode->model) { Quat q = pNode->rot; Point3 p = pNode->trans; ARMNODE *pParent = pNode->parent; while (pParent) { q+=pParent->rot; p+=pParent->trans; pParent = pParent->parent; } q+=maxrot; p+=maxtrans; char path[MAX_PATH]; _splitpath(name,NULL,path,NULL,NULL); CString filename(path); filename+=pNode->model; count += ImportModel(filename,q,p); } } pos = mapNode.GetStartPosition(); while (pos) { CString key; LPVOID value; mapNode.GetNextAssoc(pos,key,value); ARMNODE *pNode = (ARMNODE *)value; delete pNode; } mapNode.RemoveAll(); return count; } /******************************************************************************* /* function name: ImportPage /* description: Import an object from a mission contents file /*******************************************************************************/ int MissionImp::ImportPage(Page *page) { Quat maxrot; Point3 maxtrans; maxrot.Identity(); maxtrans = Point3(0,0,0); YawPitchRoll ypl; if (page->GetEntry("rotation",&ypl)) { UnitQuaternion rotation; rotation = ypl; maxrot = ConvertMWToMax(rotation); } Point3D translation; if (page->GetEntry("translation",&translation)) { maxtrans = ConvertMWToMax(translation); } // Now import the buildings only const char *entry; if (page->GetEntry("armature",&entry)) { if (0==strnicmp(entry,"buildings",9)) return ImportArmature(entry,maxrot,maxtrans); } if (page->GetEntry("model",&entry)) { if (0==strnicmp(entry,"buildings",9)) return ImportModel(entry,maxrot,maxtrans); } return 0; } /******************************************************************************* /* function name: ImportMission /* description: Import a mission .contents file /*******************************************************************************/ int MissionImp::ImportMission(const CString& fileName) { Point3 fixtrans; fixtrans.x = 0; fixtrans.y = 0; Quat fixrot(0.0,0.0,PI/2.0,0.0); INode *pWorld = m_ip->GetRootNode(); for (int x=0;xNumberOfChildren();x++) { INode *pChild = pWorld->GetChildNode(x); CString name = pChild->GetName(); if (strnicmp(name,"_",1)) { name = CString("_")+name;//name; pChild->SetName((char *)(LPCTSTR)name); } } // Change directory to game path CString gamepath = GetGamePath(m_ip); char tpath[MAX_PATH]; getcwd(tpath,MAX_PATH); chdir(gamepath); NotationFile notefile(fileName); m_ip->ProgressStart((char *)(LPCTSTR)(CString("Importing ")+fileName),false,fn,NULL); Page *page; NotationFile::PageIterator *pages = notefile.MakePageIterator(); Check_Object(pages); int count = 0; int progress = 0; int maxcount = pages->GetSize(); while (page = pages->ReadAndNext()) { progress++; m_ip->ProgressUpdate((int)(((float)progress/(float)maxcount)*100.0f),false,(char *)page->GetName()); count += ImportPage(page); } m_ip->ProgressEnd(); delete pages; chdir(tpath); return true; }