Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

393 lines
10 KiB
C++

/***************************************************************************
* *
* 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 <DLLPlatform\DLLPlatform.hpp>
#include "MissionImp.h"
#include "ExportUtil.h"
//#ifdef _DEBUG
//#define new DEBUG_NEW
//#undef THIS_FILE
//static char THIS_FILE[] = __FILE__;
//#endif
#include <direct.h>
#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;x<pWorld->NumberOfChildren();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;x<pWorld->NumberOfChildren();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;
}