New exporter on trunk
This commit is contained in:
parent
0a0bf8e38f
commit
c035bc7665
|
|
@ -11,7 +11,6 @@
|
|||
*> Copyright (c) 2000, All Rights Reserved.
|
||||
**********************************************************************/
|
||||
|
||||
#include "MaxEgg.h"
|
||||
|
||||
extern ClassDesc* GetMaxEggPluginDesc();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,16 +8,6 @@
|
|||
exporter for 3D Studio Max.
|
||||
*/
|
||||
|
||||
//Includes & Defines
|
||||
#include "maxEgg.h"
|
||||
//Types and structures from windows system-level calls
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
//Controls used in fopen
|
||||
#include <fcntl.h>
|
||||
//C Debugging
|
||||
#include <crtdbg.h>
|
||||
|
||||
// Discreet-Generated ID for this app.
|
||||
#define MNEG Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2
|
||||
#define MNEG_GEOMETRY_GENERATION Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3
|
||||
|
|
@ -60,7 +50,7 @@ IObjParam *MaxEggPlugin::iObjParams;
|
|||
BOOL CALLBACK MaxEggPluginOptionsDlgProc( HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
MaxEggExpOptions *tempEgg;
|
||||
MaxOptionsDialog *tempEgg;
|
||||
int sel, res;
|
||||
|
||||
//We pass in our plugin through the lParam variable. Let's convert it back.
|
||||
|
|
@ -104,12 +94,11 @@ BOOL CALLBACK MaxEggPluginOptionsDlgProc( HWND hWnd, UINT message,
|
|||
(IsDlgButtonChecked(hWnd, IDC_LOGGING) == BST_CHECKED);
|
||||
return TRUE; break;
|
||||
case IDC_ADD_EGG:
|
||||
tempEgg = new MaxEggExpOptions();
|
||||
tempEgg->maxInterface = imp->iObjParams;
|
||||
tempEgg = new MaxOptionsDialog();
|
||||
tempEgg->SetMaxInterface(imp->iObjParams);
|
||||
tempEgg->SetAnimRange();
|
||||
res = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EGG_DETAILS),
|
||||
hWnd, MaxEggExpOptionsProc, (LPARAM)tempEgg);
|
||||
tempEgg->maxInterface = NULL;
|
||||
hWnd, MaxOptionsDialogProc, (LPARAM)tempEgg);
|
||||
if (res == TRUE) {
|
||||
imp->SaveCheckState();
|
||||
imp->AddEgg(tempEgg);
|
||||
|
|
@ -120,14 +109,12 @@ BOOL CALLBACK MaxEggPluginOptionsDlgProc( HWND hWnd, UINT message,
|
|||
case IDC_EDIT_EGG:
|
||||
sel = ListView_GetSelectionMark(GetDlgItem(hWnd, IDC_LIST_EGGS));
|
||||
if (sel != -1) {
|
||||
MaxEggExpOptions *tempEgg = imp->GetEgg(sel);
|
||||
MaxOptionsDialog *tempEgg = imp->GetEgg(sel);
|
||||
if (tempEgg) {
|
||||
tempEgg->maxInterface = imp->iObjParams;
|
||||
tempEgg->SetAnimRange();
|
||||
tempEgg->CullBadNodes();
|
||||
DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EGG_DETAILS),
|
||||
hWnd, MaxEggExpOptionsProc, (LPARAM)tempEgg);
|
||||
tempEgg->maxInterface = NULL;
|
||||
tempEgg->SetAnimRange();
|
||||
tempEgg->CullBadNodes();
|
||||
DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EGG_DETAILS),
|
||||
hWnd, MaxOptionsDialogProc, (LPARAM)tempEgg);
|
||||
}
|
||||
imp->SaveCheckState();
|
||||
imp->UpdateUI();
|
||||
|
|
@ -149,219 +136,205 @@ BOOL CALLBACK MaxEggPluginOptionsDlgProc( HWND hWnd, UINT message,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* MaxEggPlugin() - Uninteresting constructor.
|
||||
*/
|
||||
MaxEggPlugin::MaxEggPlugin() :
|
||||
autoOverwrite(false), pview(true), logOutput(false), numEggs(0), maxEggs(5)
|
||||
{
|
||||
eggList = new MaxEggExpOptions*[maxEggs];
|
||||
BuildMesh();
|
||||
eggList = new MaxOptionsDialog*[maxEggs];
|
||||
BuildMesh();
|
||||
}
|
||||
|
||||
MaxEggPlugin::~MaxEggPlugin() {
|
||||
for (int i = 0; i < numEggs; i++) delete eggList[i];
|
||||
delete [] eggList;
|
||||
for (int i = 0; i < numEggs; i++) delete eggList[i];
|
||||
delete [] eggList;
|
||||
}
|
||||
|
||||
void MaxEggPlugin::AddEgg(MaxEggExpOptions *newEgg) {
|
||||
if (numEggs >= maxEggs) {
|
||||
MaxEggExpOptions **newList;
|
||||
maxEggs *= 2;
|
||||
newList = new MaxEggExpOptions*[maxEggs];
|
||||
for (int i = 0; i < numEggs; i++) newList[i] = eggList[i];
|
||||
delete [] eggList;
|
||||
eggList = newList;
|
||||
}
|
||||
|
||||
eggList[numEggs++] = newEgg;
|
||||
void MaxEggPlugin::AddEgg(MaxOptionsDialog *newEgg) {
|
||||
if (numEggs >= maxEggs) {
|
||||
MaxOptionsDialog **newList;
|
||||
maxEggs *= 2;
|
||||
newList = new MaxOptionsDialog*[maxEggs];
|
||||
for (int i = 0; i < numEggs; i++) newList[i] = eggList[i];
|
||||
delete [] eggList;
|
||||
eggList = newList;
|
||||
}
|
||||
|
||||
eggList[numEggs++] = newEgg;
|
||||
}
|
||||
|
||||
void MaxEggPlugin::RemoveEgg(int i) {
|
||||
if (i >= 0 && i < numEggs) {
|
||||
delete eggList[i];
|
||||
for (int j = i+1; j < numEggs;) eggList[i++] = eggList[j++];
|
||||
--numEggs;
|
||||
}
|
||||
if (i >= 0 && i < numEggs) {
|
||||
delete eggList[i];
|
||||
for (int j = i+1; j < numEggs;) eggList[i++] = eggList[j++];
|
||||
--numEggs;
|
||||
}
|
||||
}
|
||||
|
||||
void MaxEggPlugin::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
|
||||
{
|
||||
iObjParams = ip;
|
||||
if ( !hMaxEggParams ) {
|
||||
hMaxEggParams = ip->AddRollupPage(hInstance,
|
||||
MAKEINTRESOURCE(IDD_PANEL),
|
||||
MaxEggPluginOptionsDlgProc,
|
||||
GetString(IDS_PARAMS),
|
||||
(LPARAM)this );
|
||||
ip->RegisterDlgWnd(hMaxEggParams);
|
||||
} else {
|
||||
SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, (LPARAM)this );
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
iObjParams = ip;
|
||||
for (int i=0; i<numEggs; i++) {
|
||||
eggList[i]->SetMaxInterface(ip);
|
||||
}
|
||||
|
||||
if ( !hMaxEggParams ) {
|
||||
hMaxEggParams = ip->AddRollupPage(hInstance,
|
||||
MAKEINTRESOURCE(IDD_PANEL),
|
||||
MaxEggPluginOptionsDlgProc,
|
||||
GetString(IDS_PARAMS),
|
||||
(LPARAM)this );
|
||||
ip->RegisterDlgWnd(hMaxEggParams);
|
||||
} else {
|
||||
SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, (LPARAM)this );
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
void MaxEggPlugin::EndEditParams( IObjParam *ip, ULONG flags,Animatable *prev)
|
||||
{
|
||||
SaveCheckState();
|
||||
if ( flags&END_EDIT_REMOVEUI ) {
|
||||
ip->UnRegisterDlgWnd(hMaxEggParams);
|
||||
ip->DeleteRollupPage(hMaxEggParams);
|
||||
hMaxEggParams = NULL;
|
||||
} else {
|
||||
SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, NULL );
|
||||
}
|
||||
iObjParams = NULL;
|
||||
SaveCheckState();
|
||||
if ( flags&END_EDIT_REMOVEUI ) {
|
||||
ip->UnRegisterDlgWnd(hMaxEggParams);
|
||||
ip->DeleteRollupPage(hMaxEggParams);
|
||||
hMaxEggParams = NULL;
|
||||
} else {
|
||||
SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
void MaxEggPlugin::SaveCheckState() {
|
||||
if (!hMaxEggParams) return;
|
||||
HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS);
|
||||
for (int i = 0; i < numEggs; i++)
|
||||
eggList[i]->checked = ListView_GetCheckState(lv, i);
|
||||
if (!hMaxEggParams) return;
|
||||
HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS);
|
||||
for (int i = 0; i < numEggs; i++)
|
||||
eggList[i]->_checked = ListView_GetCheckState(lv, i);
|
||||
}
|
||||
|
||||
void MaxEggPlugin::UpdateUI() {
|
||||
HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS);
|
||||
LV_COLUMN pCol;
|
||||
|
||||
if (ListView_GetColumnWidth(lv, 1) <= 0 || ListView_GetColumnWidth(lv, 1) > 10000) {
|
||||
//Columns have not been setup, so initialize the control
|
||||
ListView_SetExtendedListViewStyleEx(lv, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT,
|
||||
HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS);
|
||||
LV_COLUMN pCol;
|
||||
|
||||
if (ListView_GetColumnWidth(lv, 1) <= 0 || ListView_GetColumnWidth(lv, 1) > 10000) {
|
||||
//Columns have not been setup, so initialize the control
|
||||
ListView_SetExtendedListViewStyleEx(lv, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT,
|
||||
LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
|
||||
|
||||
pCol.fmt = LVCFMT_LEFT;
|
||||
pCol.cx = 96;
|
||||
pCol.pszText = "Filename";
|
||||
pCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||||
pCol.iSubItem = 0;
|
||||
ListView_InsertColumn(lv, 0, &pCol);
|
||||
|
||||
pCol.cx = 44;
|
||||
pCol.pszText = "Type";
|
||||
ListView_InsertColumn(lv, 1, &pCol);
|
||||
}
|
||||
|
||||
//Add the eggs to the list
|
||||
ListView_DeleteAllItems(lv);
|
||||
LV_ITEM Item;
|
||||
Item.mask = LVIF_TEXT;
|
||||
|
||||
for (int i = 0; i < numEggs; i++) {
|
||||
Item.iItem = i;
|
||||
Item.iSubItem = 0;
|
||||
Item.pszText = eggList[i]->shortName;
|
||||
ListView_InsertItem(lv, &Item);
|
||||
Item.iSubItem = 1;
|
||||
switch(eggList[i]->anim_type) {
|
||||
case MaxEggExpOptions::Anim_Type::AT_chan: Item.pszText = "Animation"; break;
|
||||
case MaxEggExpOptions::Anim_Type::AT_both: Item.pszText = "Both"; break;
|
||||
case MaxEggExpOptions::Anim_Type::AT_pose: Item.pszText = "Pose"; break;
|
||||
case MaxEggExpOptions::Anim_Type::AT_model:
|
||||
default: Item.pszText = "Model"; break;
|
||||
|
||||
pCol.fmt = LVCFMT_LEFT;
|
||||
pCol.cx = 96;
|
||||
pCol.pszText = "Filename";
|
||||
pCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||||
pCol.iSubItem = 0;
|
||||
ListView_InsertColumn(lv, 0, &pCol);
|
||||
|
||||
pCol.cx = 44;
|
||||
pCol.pszText = "Type";
|
||||
ListView_InsertColumn(lv, 1, &pCol);
|
||||
}
|
||||
ListView_SetItem(lv, &Item);
|
||||
ListView_SetCheckState(lv, i, eggList[i]->checked);
|
||||
}
|
||||
|
||||
// Set the "Overwrite Existing Files" and "Pview" checkboxes
|
||||
CheckDlgButton(hMaxEggParams, IDC_OVERWRITE_CHECK,
|
||||
autoOverwrite ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hMaxEggParams, IDC_PVIEW_CHECK,
|
||||
pview ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hMaxEggParams, IDC_LOGGING,
|
||||
logOutput ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
//Add the eggs to the list
|
||||
ListView_DeleteAllItems(lv);
|
||||
LV_ITEM Item;
|
||||
Item.mask = LVIF_TEXT;
|
||||
|
||||
for (int i = 0; i < numEggs; i++) {
|
||||
Item.iItem = i;
|
||||
Item.iSubItem = 0;
|
||||
Item.pszText = eggList[i]->_short_name;
|
||||
ListView_InsertItem(lv, &Item);
|
||||
Item.iSubItem = 1;
|
||||
switch(eggList[i]->_anim_type) {
|
||||
case MaxEggOptions::AT_chan: Item.pszText = "Animation"; break;
|
||||
case MaxEggOptions::AT_both: Item.pszText = "Both"; break;
|
||||
case MaxEggOptions::AT_pose: Item.pszText = "Pose"; break;
|
||||
case MaxEggOptions::AT_model: Item.pszText = "Model"; break;
|
||||
default: Item.pszText = "Model"; break;
|
||||
}
|
||||
ListView_SetItem(lv, &Item);
|
||||
ListView_SetCheckState(lv, i, eggList[i]->_checked);
|
||||
}
|
||||
|
||||
// Set the "Overwrite Existing Files" and "Pview" checkboxes
|
||||
CheckDlgButton(hMaxEggParams, IDC_OVERWRITE_CHECK,
|
||||
autoOverwrite ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hMaxEggParams, IDC_PVIEW_CHECK,
|
||||
pview ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hMaxEggParams, IDC_LOGGING,
|
||||
logOutput ? BST_CHECKED : BST_UNCHECKED);
|
||||
}
|
||||
|
||||
void MaxEggPlugin::DoExport() {
|
||||
int good = 0, bad = 0;
|
||||
char msg[2048];
|
||||
strcpy(msg, "The following exports failed:\n");
|
||||
|
||||
SaveCheckState();
|
||||
|
||||
for (int i = 0; i < numEggs; i++) {
|
||||
if (eggList[i]->checked) {
|
||||
if (!eggList[i]->DoExport(iObjParams, autoOverwrite, logOutput)) {
|
||||
++bad;
|
||||
strcat(msg, eggList[i]->shortName);
|
||||
strcat(msg, ".egg\n");
|
||||
}
|
||||
else ++good;
|
||||
}
|
||||
}
|
||||
|
||||
if (bad == 0)
|
||||
strcpy(msg, "All eggs exported successfully");
|
||||
else
|
||||
strcat(msg, "\nAll other eggs exported successfully");
|
||||
|
||||
UINT mask = MB_OK;
|
||||
if (bad > 0) mask |= MB_ICONEXCLAMATION;
|
||||
else mask |= MB_ICONINFORMATION;
|
||||
|
||||
MessageBox(hMaxEggParams, msg, "Panda3D Export results", mask);
|
||||
|
||||
if (pview && good > 0) {
|
||||
char pviewMsg[2048];
|
||||
int pviewSkipped = 0;
|
||||
strcpy(pviewMsg, "The following eggs were skipped since animations cannot be pviewed:\n");
|
||||
for (i = 0; i < numEggs; i++)
|
||||
if (eggList[i]->checked && eggList[i]->successful)
|
||||
if (eggList[i]->anim_type != MaxEggExpOptions::AT_chan) {
|
||||
char buf[1024];
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
|
||||
memset(&si,0,sizeof(si));
|
||||
si.cb= sizeof(si);
|
||||
|
||||
sprintf(buf, "Pview %s.egg?", eggList[i]->shortName);
|
||||
if (MessageBox(hMaxEggParams, buf, "Panda3D exporter", MB_YESNO | MB_ICONQUESTION) == IDYES) {
|
||||
char cmdLine[2048];
|
||||
sprintf(cmdLine, "pview \"%s\"", eggList[i]->filename);
|
||||
CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE,
|
||||
NULL, NULL, &si, &pi);
|
||||
}
|
||||
}
|
||||
else {
|
||||
pviewSkipped++;
|
||||
strcat(pviewMsg, eggList[i]->shortName);
|
||||
strcat(pviewMsg, ".egg\n");
|
||||
}
|
||||
int good = 0, bad = 0;
|
||||
|
||||
if (pviewSkipped > 0) {
|
||||
strcat(pviewMsg, "\nExport animations using the \"both\" option to pview them.");
|
||||
MessageBox(hMaxEggParams, pviewMsg, "Panda3D exporter", MB_OK | MB_ICONINFORMATION);
|
||||
std::stringstream status;
|
||||
|
||||
SaveCheckState();
|
||||
|
||||
for (int i = 0; i < numEggs; i++) {
|
||||
if (eggList[i]->_checked) {
|
||||
MaxToEggConverter converter;
|
||||
if (converter.convert((MaxEggOptions*)eggList[i])) {
|
||||
good += 1;
|
||||
status << "Successfully created " << eggList[i]->_short_name << ".egg\n";
|
||||
} else {
|
||||
bad += 1;
|
||||
status << "Could not export " << eggList[i]->_short_name << ".egg\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT mask = MB_OK;
|
||||
if (bad > 0) mask |= MB_ICONEXCLAMATION;
|
||||
else mask |= MB_ICONINFORMATION;
|
||||
|
||||
MessageBox(hMaxEggParams, status.str().c_str(), "Panda3D Export results", mask);
|
||||
|
||||
int pviewed = 0;
|
||||
if (pview && good > 0) {
|
||||
for (i = 0; i < numEggs; i++) {
|
||||
if (eggList[i]->_checked && eggList[i]->_successful) {
|
||||
if (eggList[i]->_anim_type != MaxEggOptions::AT_chan) {
|
||||
char buf[1024];
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
|
||||
memset(&si,0,sizeof(si));
|
||||
si.cb= sizeof(si);
|
||||
|
||||
sprintf(buf, "pview %s.egg?", eggList[i]->_short_name);
|
||||
char cmdLine[2048];
|
||||
sprintf(cmdLine, "pview \"%s\"", eggList[i]->_file_name);
|
||||
CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE,
|
||||
NULL, NULL, &si, &pi);
|
||||
pviewed += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MaxEggPlugin::BuildMesh()
|
||||
{
|
||||
int i;
|
||||
if(meshBuilt) return;
|
||||
|
||||
mesh.setNumVerts(252);
|
||||
mesh.setNumFaces(84);
|
||||
mesh.setSmoothFlags(0);
|
||||
mesh.setNumTVerts (0);
|
||||
mesh.setNumTVFaces (0);
|
||||
|
||||
for (i=0; i<252; i++)
|
||||
mesh.setVert(i, meshVerts[i][0]*10, meshVerts[i][1]*10, meshVerts[i][2]*10);
|
||||
for (i=0; i<84; i++) {
|
||||
mesh.faces[i].setEdgeVisFlags(1, 1, 0);
|
||||
mesh.faces[i].setSmGroup(0);
|
||||
mesh.faces[i].setVerts(i*3, i*3+1, i*3+2);
|
||||
}
|
||||
|
||||
mesh.InvalidateGeomCache();
|
||||
mesh.BuildStripsAndEdges();
|
||||
|
||||
meshBuilt = TRUE;
|
||||
int i;
|
||||
if(meshBuilt) return;
|
||||
|
||||
mesh.setNumVerts(252);
|
||||
mesh.setNumFaces(84);
|
||||
mesh.setSmoothFlags(0);
|
||||
mesh.setNumTVerts (0);
|
||||
mesh.setNumTVFaces (0);
|
||||
|
||||
for (i=0; i<252; i++)
|
||||
mesh.setVert(i, meshVerts[i][0]*10, meshVerts[i][1]*10, meshVerts[i][2]*10);
|
||||
for (i=0; i<84; i++) {
|
||||
mesh.faces[i].setEdgeVisFlags(1, 1, 0);
|
||||
mesh.faces[i].setSmGroup(0);
|
||||
mesh.faces[i].setVerts(i*3, i*3+1, i*3+2);
|
||||
}
|
||||
|
||||
mesh.InvalidateGeomCache();
|
||||
mesh.BuildStripsAndEdges();
|
||||
|
||||
meshBuilt = TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -371,25 +344,25 @@ void MaxEggPlugin::BuildMesh()
|
|||
class MaxEggPluginCreateMouseCallBack: public CreateMouseCallBack
|
||||
{
|
||||
public:
|
||||
int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat );
|
||||
int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat );
|
||||
};
|
||||
|
||||
int MaxEggPluginCreateMouseCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat )
|
||||
{
|
||||
if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
|
||||
switch(point) {
|
||||
case 0:
|
||||
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
|
||||
break;
|
||||
case 1:
|
||||
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
|
||||
if (msg==MOUSE_POINT) return CREATE_STOP;
|
||||
break;
|
||||
if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
|
||||
switch(point) {
|
||||
case 0:
|
||||
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
|
||||
break;
|
||||
case 1:
|
||||
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
|
||||
if (msg==MOUSE_POINT) return CREATE_STOP;
|
||||
break;
|
||||
}
|
||||
} else if (msg == MOUSE_ABORT) {
|
||||
return CREATE_ABORT;
|
||||
}
|
||||
} else if (msg == MOUSE_ABORT) {
|
||||
return CREATE_ABORT;
|
||||
}
|
||||
return CREATE_CONTINUE;
|
||||
return CREATE_CONTINUE;
|
||||
}
|
||||
|
||||
static MaxEggPluginCreateMouseCallBack MaxEggCreateMouseCB;
|
||||
|
|
@ -403,94 +376,94 @@ CreateMouseCallBack* MaxEggPlugin::GetCreateMouseCallBack()
|
|||
|
||||
void MaxEggPlugin::GetMat(TimeValue t, INode* inode, ViewExp* vpt, Matrix3& tm)
|
||||
{
|
||||
tm = inode->GetObjectTM(t);
|
||||
tm.NoScale();
|
||||
float scaleFactor = vpt->NonScalingObjectSize()*vpt->GetVPWorldWidth(tm.GetTrans())/(float)360.0;
|
||||
tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor));
|
||||
tm = inode->GetObjectTM(t);
|
||||
tm.NoScale();
|
||||
float scaleFactor = vpt->NonScalingObjectSize()*vpt->GetVPWorldWidth(tm.GetTrans())/(float)360.0;
|
||||
tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor));
|
||||
}
|
||||
|
||||
void MaxEggPlugin::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel )
|
||||
{
|
||||
box = mesh.getBoundingBox(tm);
|
||||
box = mesh.getBoundingBox(tm);
|
||||
}
|
||||
|
||||
void MaxEggPlugin::GetLocalBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
|
||||
{
|
||||
Matrix3 m = inode->GetObjectTM(t);
|
||||
Point3 pt;
|
||||
Point3 q[4];
|
||||
float scaleFactor = vpt->GetVPWorldWidth(m.GetTrans())/360.0f;
|
||||
box = mesh.getBoundingBox();
|
||||
box.Scale(scaleFactor);
|
||||
Matrix3 m = inode->GetObjectTM(t);
|
||||
Point3 pt;
|
||||
Point3 q[4];
|
||||
float scaleFactor = vpt->GetVPWorldWidth(m.GetTrans())/360.0f;
|
||||
box = mesh.getBoundingBox();
|
||||
box.Scale(scaleFactor);
|
||||
}
|
||||
|
||||
void MaxEggPlugin::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
|
||||
{
|
||||
int i, nv; Matrix3 tm; Point3 pt;
|
||||
GetMat(t,inode,vpt,tm);
|
||||
nv = mesh.getNumVerts();
|
||||
box.Init();
|
||||
for (i=0; i<nv; i++)
|
||||
box += tm*mesh.getVert(i);
|
||||
int i, nv; Matrix3 tm; Point3 pt;
|
||||
GetMat(t,inode,vpt,tm);
|
||||
nv = mesh.getNumVerts();
|
||||
box.Init();
|
||||
for (i=0; i<nv; i++)
|
||||
box += tm*mesh.getVert(i);
|
||||
}
|
||||
|
||||
int MaxEggPlugin::HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt)
|
||||
{
|
||||
HitRegion hitRegion;
|
||||
DWORD savedLimits;
|
||||
Matrix3 m;
|
||||
GraphicsWindow *gw = vpt->getGW();
|
||||
Material *mtl = gw->getMaterial();
|
||||
MakeHitRegion(hitRegion,type,crossing,4,p);
|
||||
gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
|
||||
GetMat(t,inode,vpt,m);
|
||||
gw->setTransform(m);
|
||||
gw->clearHitCode();
|
||||
if (mesh.select( gw, mtl, &hitRegion, flags & HIT_ABORTONHIT ))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
HitRegion hitRegion;
|
||||
DWORD savedLimits;
|
||||
Matrix3 m;
|
||||
GraphicsWindow *gw = vpt->getGW();
|
||||
Material *mtl = gw->getMaterial();
|
||||
MakeHitRegion(hitRegion,type,crossing,4,p);
|
||||
gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
|
||||
GetMat(t,inode,vpt,m);
|
||||
gw->setTransform(m);
|
||||
gw->clearHitCode();
|
||||
if (mesh.select( gw, mtl, &hitRegion, flags & HIT_ABORTONHIT ))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int MaxEggPlugin::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags)
|
||||
{
|
||||
Matrix3 m;
|
||||
GraphicsWindow *gw = vpt->getGW();
|
||||
Material *mtl = gw->getMaterial();
|
||||
|
||||
GetMat(t,inode,vpt,m);
|
||||
gw->setTransform(m);
|
||||
DWORD rlim = gw->getRndLimits();
|
||||
gw->setRndLimits(GW_WIREFRAME|GW_BACKCULL);
|
||||
if (inode->Selected())
|
||||
gw->setColor( LINE_COLOR, GetSelColor());
|
||||
else if(!inode->IsFrozen())
|
||||
gw->setColor( LINE_COLOR, GetUIColor(COLOR_TAPE_OBJ));
|
||||
mesh.render( gw, mtl, NULL, COMP_ALL);
|
||||
return 0;
|
||||
Matrix3 m;
|
||||
GraphicsWindow *gw = vpt->getGW();
|
||||
Material *mtl = gw->getMaterial();
|
||||
|
||||
GetMat(t,inode,vpt,m);
|
||||
gw->setTransform(m);
|
||||
DWORD rlim = gw->getRndLimits();
|
||||
gw->setRndLimits(GW_WIREFRAME|GW_BACKCULL);
|
||||
if (inode->Selected())
|
||||
gw->setColor( LINE_COLOR, GetSelColor());
|
||||
else if(!inode->IsFrozen())
|
||||
gw->setColor( LINE_COLOR, GetUIColor(COLOR_TAPE_OBJ));
|
||||
mesh.render( gw, mtl, NULL, COMP_ALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefResult MaxEggPlugin::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message )
|
||||
{
|
||||
UpdateUI();
|
||||
return REF_SUCCEED;
|
||||
UpdateUI();
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
ObjectState MaxEggPlugin::Eval(TimeValue time)
|
||||
{
|
||||
return ObjectState(this);
|
||||
return ObjectState(this);
|
||||
}
|
||||
|
||||
Interval MaxEggPlugin::ObjectValidity(TimeValue t)
|
||||
{
|
||||
Interval ivalid;
|
||||
ivalid.SetInfinite();
|
||||
return ivalid;
|
||||
Interval ivalid;
|
||||
ivalid.SetInfinite();
|
||||
return ivalid;
|
||||
}
|
||||
|
||||
RefTargetHandle MaxEggPlugin::Clone(RemapDir& remap)
|
||||
{
|
||||
MaxEggPlugin* newob = new MaxEggPlugin();
|
||||
return(newob);
|
||||
MaxEggPlugin* newob = new MaxEggPlugin();
|
||||
return(newob);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
|
@ -498,34 +471,35 @@ RefTargetHandle MaxEggPlugin::Clone(RemapDir& remap)
|
|||
///////////////////////////////////////////////////////////
|
||||
|
||||
IOResult MaxEggPlugin::Save(ISave *isave) {
|
||||
SaveCheckState();
|
||||
for (int i = 0; i < numEggs; i++)
|
||||
eggList[i]->Save(isave);
|
||||
ChunkSave(isave, CHUNK_OVERWRITE_FLAG, autoOverwrite);
|
||||
ChunkSave(isave, CHUNK_PVIEW_FLAG, pview);
|
||||
ChunkSave(isave, CHUNK_LOG_OUTPUT, logOutput);
|
||||
|
||||
return IO_OK;
|
||||
SaveCheckState();
|
||||
for (int i = 0; i < numEggs; i++)
|
||||
eggList[i]->Save(isave);
|
||||
ChunkSave(isave, CHUNK_OVERWRITE_FLAG, autoOverwrite);
|
||||
ChunkSave(isave, CHUNK_PVIEW_FLAG, pview);
|
||||
ChunkSave(isave, CHUNK_LOG_OUTPUT, logOutput);
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult MaxEggPlugin::Load(ILoad *iload) {
|
||||
IOResult res = iload->OpenChunk();
|
||||
MaxEggExpOptions *temp;
|
||||
|
||||
while (res == IO_OK) {
|
||||
switch(iload->CurChunkID()) {
|
||||
case CHUNK_OVERWRITE_FLAG: autoOverwrite = ChunkLoadBool(iload); break;
|
||||
case CHUNK_PVIEW_FLAG: pview = ChunkLoadBool(iload); break;
|
||||
case CHUNK_LOG_OUTPUT: logOutput = ChunkLoadBool(iload); break;
|
||||
case CHUNK_EGG_EXP_OPTIONS:
|
||||
temp = new MaxEggExpOptions();
|
||||
temp->Load(iload);
|
||||
AddEgg(temp);
|
||||
break;
|
||||
IOResult res = iload->OpenChunk();
|
||||
MaxOptionsDialog *temp;
|
||||
|
||||
while (res == IO_OK) {
|
||||
switch(iload->CurChunkID()) {
|
||||
case CHUNK_OVERWRITE_FLAG: autoOverwrite = ChunkLoadBool(iload); break;
|
||||
case CHUNK_PVIEW_FLAG: pview = ChunkLoadBool(iload); break;
|
||||
case CHUNK_LOG_OUTPUT: logOutput = ChunkLoadBool(iload); break;
|
||||
case CHUNK_EGG_EXP_OPTIONS:
|
||||
temp = new MaxOptionsDialog();
|
||||
temp->SetMaxInterface(iObjParams);
|
||||
temp->Load(iload);
|
||||
AddEgg(temp);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
res = iload->OpenChunk();
|
||||
}
|
||||
iload->CloseChunk();
|
||||
res = iload->OpenChunk();
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,16 +15,10 @@
|
|||
|
||||
#pragma conform(forScope, off)
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
//Includes & Definitions
|
||||
#include "maxToEgg.h"
|
||||
#include "maxEggExpOptions.h"
|
||||
#include "windef.h"
|
||||
|
||||
/* Error-Reporting Includes
|
||||
*/
|
||||
#include "maxLogger.h"
|
||||
#define ME Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM6
|
||||
#define MaxEggPlugin_CLASS_ID Class_ID(0x7ac0d6b7, 0x55731ef6)
|
||||
|
||||
|
|
@ -51,7 +45,7 @@ extern TCHAR *GetString(int id);
|
|||
|
||||
class MaxEggPlugin : public HelperObject
|
||||
{
|
||||
MaxEggExpOptions **eggList;
|
||||
MaxOptionsDialog **eggList;
|
||||
int numEggs;
|
||||
int maxEggs;
|
||||
|
||||
|
|
@ -76,9 +70,9 @@ class MaxEggPlugin : public HelperObject
|
|||
void SaveCheckState();
|
||||
void BuildMesh();
|
||||
|
||||
void AddEgg(MaxEggExpOptions *newEgg);
|
||||
void AddEgg(MaxOptionsDialog *newEgg);
|
||||
void RemoveEgg(int i);
|
||||
MaxEggExpOptions *GetEgg(int i) { return (i >= 0 && i < numEggs) ? eggList[i] : NULL; }
|
||||
MaxOptionsDialog *GetEgg(int i) { return (i >= 0 && i < numEggs) ? eggList[i] : NULL; }
|
||||
|
||||
// Required implimented virtual methods:
|
||||
// inherited virtual methods for Reference-management
|
||||
|
|
@ -118,7 +112,6 @@ class MaxEggPlugin : public HelperObject
|
|||
// IO
|
||||
IOResult Save(ISave *isave);
|
||||
IOResult Load(ILoad *iload);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
what to export from 3D Studio max
|
||||
*/
|
||||
|
||||
#include "maxEggExpOptions.h"
|
||||
|
||||
//Disable the forcing int to true or false performance warning
|
||||
#pragma warning(disable: 4800)
|
||||
|
|
@ -154,10 +153,10 @@ void enableAnimRadios(HWND hWnd, int mask) {
|
|||
class AddNodeCB : public HitByNameDlgCallback
|
||||
{
|
||||
public:
|
||||
MaxEggExpOptions *ph; //Pointer to the parent class
|
||||
MaxOptionsDialog *ph; //Pointer to the parent class
|
||||
HWND hWnd; //Handle to the parent dialog
|
||||
|
||||
AddNodeCB (MaxEggExpOptions *instance, HWND wnd) :
|
||||
AddNodeCB (MaxOptionsDialog *instance, HWND wnd) :
|
||||
ph(instance), hWnd(wnd) {}
|
||||
|
||||
virtual TCHAR *dialogTitle() {return _T("Objects to Export");}
|
||||
|
|
@ -206,307 +205,324 @@ void AddNodeCB::proc(INodeTab &nodeTab) {
|
|||
class RemoveNodeCB : public HitByNameDlgCallback
|
||||
{
|
||||
public:
|
||||
MaxEggExpOptions *ph; //Pointer to the parent class
|
||||
HWND hWnd; //Handle to the parent dialog
|
||||
|
||||
RemoveNodeCB (MaxEggExpOptions *instance, HWND wnd) :
|
||||
ph(instance), hWnd(wnd) {}
|
||||
|
||||
virtual TCHAR *dialogTitle() {return _T("Objects to Remove");}
|
||||
virtual TCHAR *buttonText() {return _T("Remove");}
|
||||
virtual int filter(INode *node) {return (node && ph->FindNode(node->GetHandle()));}
|
||||
virtual void proc(INodeTab &nodeTab);
|
||||
MaxOptionsDialog *ph; //Pointer to the parent class
|
||||
HWND hWnd; //Handle to the parent dialog
|
||||
|
||||
RemoveNodeCB (MaxOptionsDialog *instance, HWND wnd) :
|
||||
ph(instance), hWnd(wnd) {}
|
||||
|
||||
virtual TCHAR *dialogTitle() {return _T("Objects to Remove");}
|
||||
virtual TCHAR *buttonText() {return _T("Remove");}
|
||||
virtual int filter(INode *node) {return (node && ph->FindNode(node->GetHandle()));}
|
||||
virtual void proc(INodeTab &nodeTab);
|
||||
};
|
||||
|
||||
|
||||
//Adds all of the selected items to the list
|
||||
void RemoveNodeCB::proc(INodeTab &nodeTab) {
|
||||
for (int i = 0; i < nodeTab.Count(); i++)
|
||||
ph->RemoveNodeByHandle(nodeTab[i]->GetHandle());
|
||||
ph->RefreshNodeList(hWnd);
|
||||
for (int i = 0; i < nodeTab.Count(); i++)
|
||||
ph->RemoveNodeByHandle(nodeTab[i]->GetHandle());
|
||||
ph->RefreshNodeList(hWnd);
|
||||
}
|
||||
|
||||
MaxEggExpOptions::MaxEggExpOptions () :
|
||||
checked(true), anim_type(AT_model), sf(INT_MIN), ef(INT_MIN),
|
||||
expWholeScene(true), dblSided(false), numNodes(0), maxNodes(5),
|
||||
choosingNodes(false), prev_type(AT_model) {
|
||||
*filename = NULL;
|
||||
nodeList = new ULONG[maxNodes];
|
||||
MaxEggOptions::MaxEggOptions() {
|
||||
_max_interface = NULL;
|
||||
_anim_type = MaxEggOptions::AT_model;
|
||||
_start_frame = INT_MIN;
|
||||
_end_frame = INT_MIN;
|
||||
_double_sided = false;
|
||||
_file_name[0]=0;
|
||||
_short_name[0]=0;
|
||||
_path_replace = new PathReplace;
|
||||
_export_whole_scene = true;
|
||||
}
|
||||
|
||||
BOOL CALLBACK MaxEggExpOptionsProc( HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam )
|
||||
BOOL CALLBACK MaxOptionsDialogProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
char tempFilename[2048];
|
||||
//We pass in our plugin through the lParam variable. Let's convert it back.
|
||||
MaxEggExpOptions *imp = (MaxEggExpOptions*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
|
||||
if ( !imp && message != WM_INITDIALOG ) return FALSE;
|
||||
char tempFilename[2048];
|
||||
//We pass in our plugin through the lParam variable. Let's convert it back.
|
||||
MaxOptionsDialog *imp = (MaxOptionsDialog*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
|
||||
if ( !imp && message != WM_INITDIALOG ) return FALSE;
|
||||
|
||||
switch(message) {
|
||||
|
||||
switch(message)
|
||||
{
|
||||
// When we start, center the window.
|
||||
case WM_INITDIALOG:
|
||||
// this line is very necessary to pass the plugin as the lParam
|
||||
SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);
|
||||
((MaxEggExpOptions*)lParam)->UpdateUI(hWnd);
|
||||
return TRUE; break;
|
||||
|
||||
// this line is very necessary to pass the plugin as the lParam
|
||||
SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);
|
||||
((MaxOptionsDialog*)lParam)->UpdateUI(hWnd);
|
||||
return TRUE; break;
|
||||
|
||||
case WM_CLOSE:
|
||||
EndDialog(hWnd, FALSE);
|
||||
return TRUE; break;
|
||||
|
||||
// A control was modified
|
||||
EndDialog(hWnd, FALSE);
|
||||
return TRUE; break;
|
||||
|
||||
case WM_COMMAND:
|
||||
//The modified control is found in the lower word of the wParam long.
|
||||
switch( LOWORD(wParam) ) {
|
||||
//The modified control is found in the lower word of the wParam long.
|
||||
switch( LOWORD(wParam) ) {
|
||||
case IDC_MODEL:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Meshes:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_NONE);
|
||||
showAnimControls(hWnd, TRUE);
|
||||
enableAnimControls(hWnd, FALSE);
|
||||
if (imp->prev_type == MaxEggExpOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->prev_type = MaxEggExpOptions::AT_model;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Meshes:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_NONE);
|
||||
showAnimControls(hWnd, TRUE);
|
||||
enableAnimControls(hWnd, FALSE);
|
||||
if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->_prev_type = MaxEggOptions::AT_model;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_ANIMATION:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Bones:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_ALL);
|
||||
showAnimControls(hWnd, TRUE);
|
||||
enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
|
||||
if (imp->prev_type != MaxEggExpOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->prev_type = MaxEggExpOptions::AT_chan;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Bones:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_ALL);
|
||||
showAnimControls(hWnd, TRUE);
|
||||
enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
|
||||
if (imp->_prev_type != MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->_prev_type = MaxEggOptions::AT_chan;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case IDC_BOTH:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Models:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_ALL);
|
||||
showAnimControls(hWnd, TRUE);
|
||||
enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
|
||||
if (imp->prev_type == MaxEggExpOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->prev_type = MaxEggExpOptions::AT_both;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Models:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_ALL);
|
||||
showAnimControls(hWnd, TRUE);
|
||||
enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
|
||||
if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->_prev_type = MaxEggOptions::AT_both;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case IDC_POSE:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Meshes:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_EXPSEL);
|
||||
showAnimControls(hWnd, FALSE);
|
||||
enableAnimControls(hWnd, TRUE);
|
||||
CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_SEL_FRAMES);
|
||||
if (imp->prev_type == MaxEggExpOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->prev_type = MaxEggExpOptions::AT_pose;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
|
||||
"Export Meshes:");
|
||||
enableAnimRadios(hWnd, ANIM_RAD_EXPSEL);
|
||||
showAnimControls(hWnd, FALSE);
|
||||
enableAnimControls(hWnd, TRUE);
|
||||
CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_SEL_FRAMES);
|
||||
if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
|
||||
imp->_prev_type = MaxEggOptions::AT_pose;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case IDC_EXP_ALL_FRAMES:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableAnimControls(hWnd, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableAnimControls(hWnd, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_EXP_SEL_FRAMES:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableAnimControls(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableAnimControls(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_EXPORT_ALL:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableChooserControls(hWnd, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableChooserControls(hWnd, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_EXPORT_SELECTED:
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableChooserControls(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
enableChooserControls(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_ADD_EXPORT:
|
||||
{
|
||||
if (!imp->choosingNodes) {
|
||||
AddNodeCB PickCB(imp, hWnd);
|
||||
imp->choosingNodes = true;
|
||||
imp->maxInterface->DoHitByNameDialog(&PickCB);
|
||||
imp->choosingNodes = false;
|
||||
}
|
||||
}
|
||||
return TRUE; break;
|
||||
{
|
||||
if (!imp->_choosing_nodes) {
|
||||
AddNodeCB PickCB(imp, hWnd);
|
||||
imp->_choosing_nodes = true;
|
||||
imp->_max_interface->DoHitByNameDialog(&PickCB);
|
||||
imp->_choosing_nodes = false;
|
||||
}
|
||||
}
|
||||
return TRUE; break;
|
||||
|
||||
case IDC_REMOVE_EXPORT:
|
||||
{
|
||||
if (!imp->choosingNodes) {
|
||||
imp->choosingNodes = true;
|
||||
RemoveNodeCB PickCB(imp, hWnd);
|
||||
imp->maxInterface->DoHitByNameDialog(&PickCB);
|
||||
imp->choosingNodes = false;
|
||||
}
|
||||
}
|
||||
return TRUE; break;
|
||||
{
|
||||
if (!imp->_choosing_nodes) {
|
||||
imp->_choosing_nodes = true;
|
||||
RemoveNodeCB PickCB(imp, hWnd);
|
||||
imp->_max_interface->DoHitByNameDialog(&PickCB);
|
||||
imp->_choosing_nodes = false;
|
||||
}
|
||||
}
|
||||
return TRUE; break;
|
||||
|
||||
case IDC_OK:
|
||||
if (imp->UpdateFromUI(hWnd)) EndDialog(hWnd, TRUE);
|
||||
return TRUE; break;
|
||||
if (imp->UpdateFromUI(hWnd)) EndDialog(hWnd, TRUE);
|
||||
return TRUE; break;
|
||||
case IDC_CANCEL:
|
||||
EndDialog(hWnd, FALSE);
|
||||
return TRUE; break;
|
||||
EndDialog(hWnd, FALSE);
|
||||
return TRUE; break;
|
||||
case IDC_BROWSE:
|
||||
OPENFILENAME ofn;
|
||||
strcpy(tempFilename, GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME)));
|
||||
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.nMaxFile = 2047;
|
||||
ofn.lpstrFile = tempFilename;
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hWnd;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;
|
||||
ofn.lpstrDefExt = "egg";
|
||||
ofn.lpstrFilter = "Panda3D Egg Files (*.egg)\0*.egg\0All Files (*.*)\0*.*\0";
|
||||
|
||||
SetFocus(GetDlgItem(hWnd, IDC_FILENAME));
|
||||
if (GetSaveFileName(&ofn))
|
||||
SetICustEdit(hWnd, IDC_FILENAME, ofn.lpstrFile);
|
||||
//else {
|
||||
// char buf[255];
|
||||
// sprintf(buf, "%d", CommDlgExtendedError());
|
||||
// MessageBox(hWnd, buf, "Error on GetSaveFileName", MB_OK);
|
||||
//}
|
||||
return TRUE; break;
|
||||
OPENFILENAME ofn;
|
||||
strcpy(tempFilename, GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME)));
|
||||
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.nMaxFile = 2047;
|
||||
ofn.lpstrFile = tempFilename;
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hWnd;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;
|
||||
ofn.lpstrDefExt = "egg";
|
||||
ofn.lpstrFilter = "Panda3D Egg Files (*.egg)\0*.egg\0All Files (*.*)\0*.*\0";
|
||||
|
||||
SetFocus(GetDlgItem(hWnd, IDC_FILENAME));
|
||||
if (GetSaveFileName(&ofn))
|
||||
SetICustEdit(hWnd, IDC_FILENAME, ofn.lpstrFile);
|
||||
//else {
|
||||
// char buf[255];
|
||||
// sprintf(buf, "%d", CommDlgExtendedError());
|
||||
// MessageBox(hWnd, buf, "Error on GetSaveFileName", MB_OK);
|
||||
//}
|
||||
return TRUE; break;
|
||||
case IDC_CHECK1:
|
||||
if (IsDlgButtonChecked(hWnd, IDC_CHECK1))
|
||||
if (MessageBox(hWnd, "Warning: Exporting double-sided polygons can severely hurt "
|
||||
"performance in Panda3D.\n\nAre you sure you want to export them?",
|
||||
"Panda3D Exporter", MB_YESNO | MB_ICONQUESTION) != IDYES)
|
||||
CheckDlgButton(hWnd, IDC_CHECK1, BST_UNCHECKED);
|
||||
return TRUE; break;
|
||||
if (IsDlgButtonChecked(hWnd, IDC_CHECK1))
|
||||
if (MessageBox(hWnd, "Warning: Exporting double-sided polygons can severely hurt "
|
||||
"performance in Panda3D.\n\nAre you sure you want to export them?",
|
||||
"Panda3D Exporter", MB_YESNO | MB_ICONQUESTION) != IDYES)
|
||||
CheckDlgButton(hWnd, IDC_CHECK1, BST_UNCHECKED);
|
||||
return TRUE; break;
|
||||
default:
|
||||
//char buf[255];
|
||||
//sprintf(buf, "%d", LOWORD(wParam));
|
||||
//MessageBox(hWnd, buf, "Unknown WParam", MB_OK);
|
||||
break;
|
||||
}
|
||||
//char buf[255];
|
||||
//sprintf(buf, "%d", LOWORD(wParam));
|
||||
//MessageBox(hWnd, buf, "Unknown WParam", MB_OK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::SetAnimRange() {
|
||||
// Get the start and end frames and the animation frame rate from Max
|
||||
Interval anim_range = maxInterface->GetAnimRange();
|
||||
minFrame = anim_range.Start()/GetTicksPerFrame();
|
||||
maxFrame = anim_range.End()/GetTicksPerFrame();
|
||||
void MaxOptionsDialog::SetAnimRange() {
|
||||
// Get the start and end frames and the animation frame rate from Max
|
||||
Interval anim_range = _max_interface->GetAnimRange();
|
||||
_min_frame = anim_range.Start()/GetTicksPerFrame();
|
||||
_max_frame = anim_range.End()/GetTicksPerFrame();
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::UpdateUI(HWND hWnd) {
|
||||
int typeButton = IDC_MODEL;
|
||||
int anim_exp = sf == INT_MIN ? IDC_EXP_ALL_FRAMES : IDC_EXP_SEL_FRAMES;
|
||||
int model_exp = expWholeScene ? IDC_EXPORT_ALL : IDC_EXPORT_SELECTED;
|
||||
|
||||
switch (anim_type) {
|
||||
case AT_chan: typeButton = IDC_ANIMATION; break;
|
||||
case AT_both: typeButton = IDC_BOTH; break;
|
||||
case AT_pose: typeButton = IDC_POSE; break;
|
||||
}
|
||||
|
||||
prev_type = anim_type;
|
||||
|
||||
CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, typeButton);
|
||||
SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(typeButton, BN_CLICKED), 0);
|
||||
CheckRadioButton(hWnd, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, model_exp);
|
||||
SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(model_exp, BN_CLICKED), 0);
|
||||
CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, anim_exp);
|
||||
SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(anim_exp, BN_CLICKED), 0);
|
||||
|
||||
CheckDlgButton(hWnd, IDC_CHECK1,
|
||||
dblSided ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
SetICustEdit(hWnd, IDC_FILENAME, filename);
|
||||
if (sf != INT_MIN) {
|
||||
SetICustEdit(hWnd, IDC_SF, sf);
|
||||
SetICustEdit(hWnd, IDC_EF, ef);
|
||||
}
|
||||
else {
|
||||
SetICustEdit(hWnd, IDC_SF, minFrame);
|
||||
SetICustEdit(hWnd, IDC_EF, maxFrame);
|
||||
}
|
||||
|
||||
RefreshNodeList(hWnd);
|
||||
MaxOptionsDialog::MaxOptionsDialog() :
|
||||
MaxEggOptions(),
|
||||
_min_frame(0),
|
||||
_max_frame(0),
|
||||
_checked(true),
|
||||
_choosing_nodes(false),
|
||||
_successful(false),
|
||||
_prev_type(AT_model)
|
||||
{
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::ClearNodeList(HWND hWnd) {
|
||||
numNodes = 0;
|
||||
RefreshNodeList(hWnd);
|
||||
MaxOptionsDialog::~MaxOptionsDialog ()
|
||||
{
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::RefreshNodeList(HWND hWnd) {
|
||||
|
||||
void MaxOptionsDialog::UpdateUI(HWND hWnd) {
|
||||
int typeButton = IDC_MODEL;
|
||||
int anim_exp = _start_frame == INT_MIN ? IDC_EXP_ALL_FRAMES : IDC_EXP_SEL_FRAMES;
|
||||
int model_exp = _export_whole_scene ? IDC_EXPORT_ALL : IDC_EXPORT_SELECTED;
|
||||
|
||||
switch (_anim_type) {
|
||||
case MaxEggOptions::AT_chan: typeButton = IDC_ANIMATION; break;
|
||||
case MaxEggOptions::AT_both: typeButton = IDC_BOTH; break;
|
||||
case MaxEggOptions::AT_pose: typeButton = IDC_POSE; break;
|
||||
case MaxEggOptions::AT_model: typeButton = IDC_MODEL; break;
|
||||
}
|
||||
|
||||
_prev_type = _anim_type;
|
||||
|
||||
CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, typeButton);
|
||||
SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(typeButton, BN_CLICKED), 0);
|
||||
CheckRadioButton(hWnd, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, model_exp);
|
||||
SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(model_exp, BN_CLICKED), 0);
|
||||
CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, anim_exp);
|
||||
SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(anim_exp, BN_CLICKED), 0);
|
||||
|
||||
CheckDlgButton(hWnd, IDC_CHECK1,
|
||||
_double_sided ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
SetICustEdit(hWnd, IDC_FILENAME, _file_name);
|
||||
if (_start_frame != INT_MIN) {
|
||||
SetICustEdit(hWnd, IDC_SF, _start_frame);
|
||||
SetICustEdit(hWnd, IDC_EF, _end_frame);
|
||||
} else {
|
||||
SetICustEdit(hWnd, IDC_SF, _min_frame);
|
||||
SetICustEdit(hWnd, IDC_EF, _max_frame);
|
||||
}
|
||||
|
||||
RefreshNodeList(hWnd);
|
||||
}
|
||||
|
||||
void MaxOptionsDialog::ClearNodeList(HWND hWnd) {
|
||||
_node_list.clear();
|
||||
RefreshNodeList(hWnd);
|
||||
}
|
||||
|
||||
void MaxOptionsDialog::RefreshNodeList(HWND hWnd) {
|
||||
//Clear and repopulate the node box
|
||||
HWND nodeLB = GetDlgItem(hWnd, IDC_LIST_EXPORT);
|
||||
SendMessage(nodeLB, LB_RESETCONTENT, 0, 0);
|
||||
for (int i = 0; i < numNodes; i++) {
|
||||
INode *temp = maxInterface->GetINodeByHandle(GetNode(i));
|
||||
TCHAR *name = _T("Unknown Node");
|
||||
if (temp) name = temp->GetName();
|
||||
SendMessage(nodeLB, LB_ADDSTRING, 0, (LPARAM)name);
|
||||
for (int i = 0; i < _node_list.size(); i++) {
|
||||
INode *temp = _max_interface->GetINodeByHandle(_node_list[i]);
|
||||
TCHAR *name = _T("Unknown Node");
|
||||
if (temp) name = temp->GetName();
|
||||
SendMessage(nodeLB, LB_ADDSTRING, 0, (LPARAM)name);
|
||||
}
|
||||
}
|
||||
|
||||
bool MaxEggExpOptions::UpdateFromUI(HWND hWnd) {
|
||||
bool MaxOptionsDialog::UpdateFromUI(HWND hWnd) {
|
||||
BOOL valid;
|
||||
Anim_Type newAnimType;
|
||||
int newSF = INT_MIN, newEF = INT_MIN;
|
||||
char msg[1024];
|
||||
|
||||
if (IsDlgButtonChecked(hWnd, IDC_MODEL)) newAnimType = AT_model;
|
||||
else if (IsDlgButtonChecked(hWnd, IDC_ANIMATION)) newAnimType = AT_chan;
|
||||
else if (IsDlgButtonChecked(hWnd, IDC_BOTH)) newAnimType = AT_both;
|
||||
else newAnimType = AT_pose;
|
||||
if (IsDlgButtonChecked(hWnd, IDC_MODEL)) newAnimType = MaxEggOptions::AT_model;
|
||||
else if (IsDlgButtonChecked(hWnd, IDC_ANIMATION)) newAnimType = MaxEggOptions::AT_chan;
|
||||
else if (IsDlgButtonChecked(hWnd, IDC_BOTH)) newAnimType = MaxEggOptions::AT_both;
|
||||
else newAnimType = MaxEggOptions::AT_pose;
|
||||
|
||||
if (newAnimType != AT_model && IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)) {
|
||||
newSF = GetICustEditI(GetDlgItem(hWnd, IDC_SF), &valid);
|
||||
if (!valid) {
|
||||
MessageBox(hWnd, "Start Frame must be an integer", "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newSF < minFrame) {
|
||||
sprintf(msg, "Start Frame must be at least %d", minFrame);
|
||||
MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newSF > maxFrame) {
|
||||
sprintf(msg, "Start Frame must be at most %d", maxFrame);
|
||||
MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newAnimType != AT_pose) {
|
||||
newEF = GetICustEditI(GetDlgItem(hWnd, IDC_EF), &valid);
|
||||
if (newAnimType != MaxEggOptions::AT_model && IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)) {
|
||||
newSF = GetICustEditI(GetDlgItem(hWnd, IDC_SF), &valid);
|
||||
if (!valid) {
|
||||
MessageBox(hWnd, "End Frame must be an integer", "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
MessageBox(hWnd, "Start Frame must be an integer", "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newEF > maxFrame) {
|
||||
sprintf(msg, "End Frame must be at most %d", maxFrame);
|
||||
MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
if (newSF < _min_frame) {
|
||||
sprintf(msg, "Start Frame must be at least %d", _min_frame);
|
||||
MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newEF < newSF) {
|
||||
MessageBox(hWnd, "End Frame must be greater than the start frame", "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
if (newSF > _max_frame) {
|
||||
sprintf(msg, "Start Frame must be at most %d", _max_frame);
|
||||
MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newAnimType != MaxEggOptions::AT_pose) {
|
||||
newEF = GetICustEditI(GetDlgItem(hWnd, IDC_EF), &valid);
|
||||
if (!valid) {
|
||||
MessageBox(hWnd, "End Frame must be an integer", "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newEF > _max_frame) {
|
||||
sprintf(msg, "End Frame must be at most %d", _max_frame);
|
||||
MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
if (newEF < newSF) {
|
||||
MessageBox(hWnd, "End Frame must be greater than the start frame", "Invalid Value", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *temp = GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME));
|
||||
|
|
@ -516,245 +532,113 @@ bool MaxEggExpOptions::UpdateFromUI(HWND hWnd) {
|
|||
}
|
||||
|
||||
if (strlen(temp) < 4 || strncmp(".egg", temp+(strlen(temp) - 4), 4))
|
||||
sprintf(filename, "%s.egg", temp);
|
||||
else strcpy(filename, temp);
|
||||
sprintf(_file_name, "%s.egg", temp);
|
||||
else strcpy(_file_name, temp);
|
||||
|
||||
temp = strrchr(filename, '\\');
|
||||
if (!temp) temp = filename;
|
||||
temp = strrchr(_file_name, '\\');
|
||||
if (!temp) temp = _file_name;
|
||||
else temp++;
|
||||
|
||||
if (strlen(temp) > sizeof(shortName))
|
||||
sprintf(shortName, "%.*s...", sizeof(shortName)-4, temp);
|
||||
if (strlen(temp) > sizeof(_short_name))
|
||||
sprintf(_short_name, "%.*s...", sizeof(_short_name)-4, temp);
|
||||
else {
|
||||
strcpy(shortName, temp);
|
||||
shortName[strlen(shortName) - 4] = NULL; //Cut off the .egg
|
||||
strcpy(_short_name, temp);
|
||||
_short_name[strlen(_short_name) - 4] = NULL; //Cut off the .egg
|
||||
}
|
||||
|
||||
dblSided = IsDlgButtonChecked(hWnd, IDC_CHECK1);
|
||||
expWholeScene = IsDlgButtonChecked(hWnd, IDC_EXPORT_ALL);
|
||||
sf = newSF; ef = newEF; anim_type = newAnimType;
|
||||
_start_frame = newSF;
|
||||
_end_frame = newEF;
|
||||
_anim_type = newAnimType;
|
||||
_double_sided = IsDlgButtonChecked(hWnd, IDC_CHECK1);
|
||||
_export_whole_scene = IsDlgButtonChecked(hWnd, IDC_EXPORT_ALL);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MaxEggExpOptions::FindNode(ULONG INodeHandle) {
|
||||
for (int i = 0; i < numNodes; i++)
|
||||
if (nodeList[i] == INodeHandle) return true;
|
||||
return false;
|
||||
bool MaxOptionsDialog::FindNode(ULONG INodeHandle) {
|
||||
for (int i = 0; i < _node_list.size(); i++)
|
||||
if (_node_list[i] == INodeHandle) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::AddNode(ULONG INodeHandle) {
|
||||
void MaxOptionsDialog::AddNode(ULONG INodeHandle) {
|
||||
if (FindNode(INodeHandle)) return;
|
||||
if (numNodes >= maxNodes) {
|
||||
ULONG *newList;
|
||||
maxNodes *= 2;
|
||||
newList = new ULONG[maxNodes];
|
||||
for (int i = 0; i < numNodes; i++) newList[i] = nodeList[i];
|
||||
delete [] nodeList;
|
||||
nodeList = newList;
|
||||
}
|
||||
|
||||
nodeList[numNodes++] = INodeHandle;
|
||||
_node_list.push_back(INodeHandle);
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::CullBadNodes() {
|
||||
if (!maxInterface) return;
|
||||
int i = 0, j = 0;
|
||||
while (j < numNodes) {
|
||||
if (!maxInterface->GetINodeByHandle(nodeList[i])) j++;
|
||||
else nodeList[i++] = nodeList[j++];
|
||||
void MaxOptionsDialog::CullBadNodes() {
|
||||
if (!_max_interface) return;
|
||||
std::vector<ULONG> good;
|
||||
for (int i=0; i<_node_list.size(); i++) {
|
||||
ULONG handle = _node_list[i];
|
||||
if (_max_interface->GetINodeByHandle(handle)) {
|
||||
good.push_back(handle);
|
||||
}
|
||||
}
|
||||
numNodes = i;
|
||||
_node_list = good;
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::RemoveNode(int i) {
|
||||
if (i >= 0 && i < numNodes) {
|
||||
for (int j = i+1; j < numNodes;) nodeList[i++] = nodeList[j++];
|
||||
--numNodes;
|
||||
}
|
||||
}
|
||||
|
||||
void MaxEggExpOptions::RemoveNodeByHandle(ULONG INodeHandle) {
|
||||
for (int i = 0; i < numNodes; i++)
|
||||
if (nodeList[i] == INodeHandle) {
|
||||
RemoveNode(i);
|
||||
return;
|
||||
void MaxOptionsDialog::RemoveNode(int i) {
|
||||
if (i >= 0 && i < _node_list.size()) {
|
||||
for (int j = i+1; j < _node_list.size(); j++)
|
||||
_node_list[i++] = _node_list[j++];
|
||||
_node_list.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
IOResult MaxEggExpOptions::Save(ISave *isave) {
|
||||
isave->BeginChunk(CHUNK_EGG_EXP_OPTIONS);
|
||||
ChunkSave(isave, CHUNK_ANIM_TYPE, anim_type);
|
||||
ChunkSave(isave, CHUNK_FILENAME, filename);
|
||||
ChunkSave(isave, CHUNK_SHORTNAME, shortName);
|
||||
ChunkSave(isave, CHUNK_SF, sf);
|
||||
ChunkSave(isave, CHUNK_EF, ef);
|
||||
ChunkSave(isave, CHUNK_DBL_SIDED, dblSided);
|
||||
ChunkSave(isave, CHUNK_EGG_CHECKED, checked);
|
||||
ChunkSave(isave, CHUNK_EXPORT_FULL, expWholeScene);
|
||||
isave->BeginChunk(CHUNK_NODE_LIST);
|
||||
for (int i = 0; i < numNodes; i++)
|
||||
ChunkSave(isave, CHUNK_NODE_HANDLE, nodeList[i]);
|
||||
isave->EndChunk();
|
||||
isave->EndChunk();
|
||||
void MaxOptionsDialog::RemoveNodeByHandle(ULONG INodeHandle) {
|
||||
for (int i = 0; i < _node_list.size(); i++) {
|
||||
if (_node_list[i] == INodeHandle) {
|
||||
RemoveNode(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
IOResult MaxOptionsDialog::Save(ISave *isave) {
|
||||
isave->BeginChunk(CHUNK_EGG_EXP_OPTIONS);
|
||||
ChunkSave(isave, CHUNK_ANIM_TYPE, _anim_type);
|
||||
ChunkSave(isave, CHUNK_FILENAME, _file_name);
|
||||
ChunkSave(isave, CHUNK_SHORTNAME, _short_name);
|
||||
ChunkSave(isave, CHUNK_SF, _start_frame);
|
||||
ChunkSave(isave, CHUNK_EF, _end_frame);
|
||||
ChunkSave(isave, CHUNK_DBL_SIDED, _double_sided);
|
||||
ChunkSave(isave, CHUNK_EGG_CHECKED, _checked);
|
||||
ChunkSave(isave, CHUNK_EXPORT_FULL, _export_whole_scene);
|
||||
isave->BeginChunk(CHUNK_NODE_LIST);
|
||||
for (int i = 0; i < _node_list.size(); i++)
|
||||
ChunkSave(isave, CHUNK_NODE_HANDLE, _node_list[i]);
|
||||
isave->EndChunk();
|
||||
isave->EndChunk();
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult MaxEggExpOptions::Load(ILoad *iload) {
|
||||
IOResult res = iload->OpenChunk();
|
||||
|
||||
while (res == IO_OK) {
|
||||
switch(iload->CurChunkID()) {
|
||||
case CHUNK_ANIM_TYPE: anim_type = (Anim_Type)ChunkLoadInt(iload); break;
|
||||
case CHUNK_FILENAME: ChunkLoadString(iload, filename, sizeof(filename)); break;
|
||||
case CHUNK_SHORTNAME: ChunkLoadString(iload, shortName, sizeof(shortName)); break;
|
||||
case CHUNK_SF: sf = ChunkLoadInt(iload); break;
|
||||
case CHUNK_EF: ef = ChunkLoadInt(iload); break;
|
||||
case CHUNK_DBL_SIDED: dblSided = ChunkLoadBool(iload); break;
|
||||
case CHUNK_EGG_CHECKED: checked = ChunkLoadBool(iload); break;
|
||||
case CHUNK_EXPORT_FULL: expWholeScene = ChunkLoadBool(iload); break;
|
||||
case CHUNK_NODE_LIST:
|
||||
res = iload->OpenChunk();
|
||||
while (res == IO_OK) {
|
||||
if (iload->CurChunkID() == CHUNK_NODE_HANDLE) AddNode(ChunkLoadULONG(iload));
|
||||
IOResult MaxOptionsDialog::Load(ILoad *iload) {
|
||||
IOResult res = iload->OpenChunk();
|
||||
|
||||
while (res == IO_OK) {
|
||||
switch(iload->CurChunkID()) {
|
||||
case CHUNK_ANIM_TYPE: _anim_type = (Anim_Type)ChunkLoadInt(iload); break;
|
||||
case CHUNK_FILENAME: ChunkLoadString(iload, _file_name, sizeof(_file_name)); break;
|
||||
case CHUNK_SHORTNAME: ChunkLoadString(iload, _short_name, sizeof(_short_name)); break;
|
||||
case CHUNK_SF: _start_frame = ChunkLoadInt(iload); break;
|
||||
case CHUNK_EF: _end_frame = ChunkLoadInt(iload); break;
|
||||
case CHUNK_DBL_SIDED: _double_sided = ChunkLoadBool(iload); break;
|
||||
case CHUNK_EGG_CHECKED: _checked = ChunkLoadBool(iload); break;
|
||||
case CHUNK_EXPORT_FULL: _export_whole_scene = ChunkLoadBool(iload); break;
|
||||
case CHUNK_NODE_LIST:
|
||||
res = iload->OpenChunk();
|
||||
while (res == IO_OK) {
|
||||
if (iload->CurChunkID() == CHUNK_NODE_HANDLE) AddNode(ChunkLoadULONG(iload));
|
||||
iload->CloseChunk();
|
||||
res = iload->OpenChunk();
|
||||
}
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
res = iload->OpenChunk();
|
||||
}
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
res = iload->OpenChunk();
|
||||
}
|
||||
|
||||
if (res == IO_END) return IO_OK;
|
||||
return IO_ERROR;
|
||||
|
||||
if (res == IO_END) return IO_OK;
|
||||
return IO_ERROR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This method creates and triggers the exporter. Basically it takes the
|
||||
* user's options and builds a command-line parameter list from it.
|
||||
* It then invokes the converter pretending it was invoked as a standalone
|
||||
* program. BIG WARNING: The converter stuff often does exit() if the
|
||||
* command line arguments are displeasing.
|
||||
*/
|
||||
bool MaxEggExpOptions::DoExport(IObjParam *ip, bool autoOverwrite, bool saveLog)
|
||||
{
|
||||
MaxToEgg *pmteConverter = new MaxToEgg();
|
||||
char *apcParameters[64];
|
||||
char pszSF[10], pszEF[10];
|
||||
char acOutputFilename[MAX_PATH];
|
||||
int iParameterCount=0;
|
||||
|
||||
//Initialize our global error logger
|
||||
if (saveLog)
|
||||
Logger::globalLoggingInstance = new Logger( Logger::PIPE_TO_FILE, "MaxEggLog.txt" );
|
||||
else Logger::globalLoggingInstance = new Logger( Logger::PIPE_TO_DEV_NULL, "" );
|
||||
|
||||
//Set the various logging levels for the subsystems.
|
||||
Logger::SetOneErrorMask( ME, Logger::SAT_ALL );
|
||||
Logger::SetOneErrorMask( MTE, Logger::SAT_NULL_ERROR |
|
||||
Logger::SAT_CRITICAL_ERROR |
|
||||
Logger::SAT_PARAMETER_INVALID_ERROR |
|
||||
Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL );
|
||||
Logger::SetOneErrorMask( MTEC, Logger::SAT_NULL_ERROR |
|
||||
Logger::SAT_CRITICAL_ERROR |
|
||||
Logger::SAT_PARAMETER_INVALID_ERROR |
|
||||
Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL |
|
||||
Logger::SAT_MEDIUM_LEVEL | Logger::SAT_LOW_LEVEL |
|
||||
Logger::SAT_DEBUG_SPAM_LEVEL );
|
||||
Logger::SetOneErrorMask( MNEG, Logger::SAT_NULL_ERROR |
|
||||
Logger::SAT_CRITICAL_ERROR |
|
||||
Logger::SAT_PARAMETER_INVALID_ERROR |
|
||||
Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL |
|
||||
Logger::SAT_MEDIUM_LEVEL | Logger::SAT_LOW_LEVEL );
|
||||
Logger::SetOneErrorMask( MNEG_GEOMETRY_GENERATION, Logger::SAT_NULL_ERROR |
|
||||
Logger::SAT_CRITICAL_ERROR |
|
||||
Logger::SAT_PARAMETER_INVALID_ERROR |
|
||||
Logger::SAT_OTHER_ERROR | Logger::SAT_HIGH_LEVEL |
|
||||
Logger::SAT_MEDIUM_LEVEL | Logger::SAT_LOW_LEVEL );
|
||||
Logger::SetOneErrorMask( LLOGGING, Logger::SAT_ALL );
|
||||
|
||||
Logger::FunctionEntry( "MaxEggPlugin::DoExport" );
|
||||
|
||||
// Copy the output filename so that it can be modified if necessary
|
||||
strncpy(acOutputFilename, filename, MAX_PATH-1);
|
||||
acOutputFilename[MAX_PATH-1]=0;
|
||||
|
||||
// Panda reaaaaaaaaly wants the extension to be in lower case.
|
||||
// So if we see a .egg at the end, lower case it.
|
||||
if ((strlen(acOutputFilename)>4) &&
|
||||
(stricmp(acOutputFilename+strlen(acOutputFilename)-4,".egg")==0)) {
|
||||
strlwr(acOutputFilename+strlen(acOutputFilename)-4);
|
||||
}
|
||||
pmteConverter->SetMaxInterface((Interface*)ip);
|
||||
|
||||
// Set the command-line arguments
|
||||
// ARGV[0] = program name
|
||||
apcParameters[iParameterCount++]="MaxEggPlugin";
|
||||
|
||||
// ARGV[1] = Input file
|
||||
// Use a bogus input filename that exists
|
||||
apcParameters[iParameterCount++]="nul.max";
|
||||
|
||||
// ARGV[2,3] = Animation options
|
||||
// Check if there is an animation to be saved and what type of animation it
|
||||
// will be saved as. Then set the animation option.
|
||||
apcParameters[iParameterCount++]="-a";
|
||||
switch (anim_type) {
|
||||
case AT_chan: apcParameters[iParameterCount++]="chan"; break;
|
||||
case AT_pose: apcParameters[iParameterCount++]="pose"; break;
|
||||
case AT_both: apcParameters[iParameterCount++]="both"; break;
|
||||
case AT_model:
|
||||
default: apcParameters[iParameterCount++]="model"; break;
|
||||
}
|
||||
|
||||
//Start Frame
|
||||
//If the export options need a start frame and we have one
|
||||
//then use it
|
||||
if (sf != INT_MIN && anim_type != AT_model) {
|
||||
sprintf(pszSF, "%d", sf);
|
||||
apcParameters[iParameterCount++] = "-sf";
|
||||
apcParameters[iParameterCount++] = pszSF;
|
||||
}
|
||||
|
||||
//Start Frame
|
||||
//If the export options need an end frame and we have one
|
||||
//then use it
|
||||
if (sf != INT_MIN && (anim_type == AT_chan || anim_type == AT_both)) {
|
||||
sprintf(pszEF, "%d", ef);
|
||||
apcParameters[iParameterCount++] = "-ef";
|
||||
apcParameters[iParameterCount++] = pszEF;
|
||||
}
|
||||
|
||||
// Doublesided: This option may be diabled in the converter
|
||||
// but this is here for when it is enabled
|
||||
if (dblSided) apcParameters[iParameterCount++] = "-bface";
|
||||
|
||||
// Final ARGV = Output file
|
||||
// Pass in the output filename
|
||||
// Output file has to be passed in with the -o parameter in order to be able
|
||||
// to overwrite an existing file
|
||||
if (autoOverwrite) apcParameters[iParameterCount++]="-o";
|
||||
apcParameters[iParameterCount++]=acOutputFilename;
|
||||
|
||||
apcParameters[iParameterCount]=0;
|
||||
|
||||
// Parse the command line and run the converter
|
||||
pmteConverter->parse_command_line(iParameterCount, apcParameters);
|
||||
if (expWholeScene) pmteConverter->Run(NULL, 0);
|
||||
else pmteConverter->Run(nodeList, numNodes);
|
||||
|
||||
successful = pmteConverter->IsSuccessful();
|
||||
|
||||
// This was put in try block because originally deleting pmteConverter
|
||||
// would throw an exception. That no longer happens, but this is still
|
||||
// here for good measure
|
||||
delete pmteConverter;
|
||||
|
||||
Logger::FunctionExit();
|
||||
//Free the error logger
|
||||
if ( Logger::globalLoggingInstance )
|
||||
delete Logger::globalLoggingInstance;
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,7 @@
|
|||
#pragma conform(forScope, off)
|
||||
|
||||
//Includes & Definitions
|
||||
#include "maxToEgg.h"
|
||||
#include "windef.h"
|
||||
|
||||
/* Error-Reporting Includes */
|
||||
#include "maxLogger.h"
|
||||
#define ME Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM6
|
||||
#define MNEG Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2
|
||||
#define MNEG_GEOMETRY_GENERATION Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3
|
||||
|
|
@ -49,66 +45,65 @@ char *ChunkLoadString(ILoad *iload, char *buffer, int maxBytes);
|
|||
int ChunkLoadInt(ILoad *iload);
|
||||
bool ChunkLoadBool(ILoad *iload);
|
||||
void SetICustEdit(HWND wnd, int nIDDlgItem, char *text);
|
||||
BOOL CALLBACK MaxEggExpOptionsProc( HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam );
|
||||
BOOL CALLBACK MaxOptionsDialogProc( HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam );
|
||||
|
||||
class MaxEggExpOptions
|
||||
struct MaxEggOptions
|
||||
{
|
||||
friend class MaxEggPlugin;
|
||||
public:
|
||||
MaxEggOptions();
|
||||
|
||||
enum Anim_Type {
|
||||
AT_none,
|
||||
AT_model,
|
||||
AT_chan,
|
||||
AT_pose,
|
||||
AT_strobe,
|
||||
AT_both
|
||||
};
|
||||
AT_none,
|
||||
AT_model,
|
||||
AT_chan,
|
||||
AT_pose,
|
||||
AT_strobe,
|
||||
AT_both
|
||||
};
|
||||
|
||||
protected:
|
||||
Anim_Type anim_type;
|
||||
int sf, ef;
|
||||
int minFrame, maxFrame;
|
||||
bool dblSided, expWholeScene;
|
||||
char shortName[256];
|
||||
IObjParam *_max_interface;
|
||||
Anim_Type _anim_type;
|
||||
int _start_frame;
|
||||
int _end_frame;
|
||||
bool _double_sided;
|
||||
bool _export_whole_scene;
|
||||
char _file_name[2048];
|
||||
char _short_name[256];
|
||||
PT(PathReplace) _path_replace;
|
||||
std::vector<ULONG> _node_list;
|
||||
};
|
||||
|
||||
bool successful;
|
||||
class MaxOptionsDialog : public MaxEggOptions
|
||||
{
|
||||
friend class MaxEggPlugin;
|
||||
|
||||
public:
|
||||
int _min_frame, _max_frame;
|
||||
bool _checked;
|
||||
bool _choosing_nodes;
|
||||
bool _successful;
|
||||
MaxEggOptions::Anim_Type _prev_type;
|
||||
|
||||
ULONG *nodeList;
|
||||
int numNodes;
|
||||
int maxNodes;
|
||||
|
||||
public:
|
||||
bool checked;
|
||||
char filename[2048];
|
||||
IObjParam *maxInterface;
|
||||
bool choosingNodes;
|
||||
Anim_Type prev_type;
|
||||
|
||||
MaxEggExpOptions();
|
||||
virtual ~MaxEggExpOptions() { delete [] nodeList;}
|
||||
|
||||
bool DoExport(IObjParam *ip, bool autoOverwrite, bool saveLog);
|
||||
|
||||
void UpdateUI(HWND hWnd);
|
||||
bool UpdateFromUI(HWND hWnd);
|
||||
void RefreshNodeList(HWND hWnd);
|
||||
void SetAnimRange();
|
||||
|
||||
bool FindNode(ULONG INodeHandle); //returns true if the node is already in the list
|
||||
void AddNode(ULONG INodeHandle);
|
||||
void RemoveNode(int i);
|
||||
void RemoveNodeByHandle(ULONG INodeHandle);
|
||||
void ClearNodeList(HWND hWnd);
|
||||
void CullBadNodes();
|
||||
|
||||
ULONG GetNode(int i) { return (i >= 0 && i < maxNodes) ? nodeList[i] : ULONG_MAX; }
|
||||
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
|
||||
//int DoExport(const TCHAR *name,ExpInterface *ei,
|
||||
// Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0);
|
||||
MaxOptionsDialog();
|
||||
~MaxOptionsDialog();
|
||||
|
||||
void SetMaxInterface(IObjParam *iface) { _max_interface = iface; }
|
||||
void UpdateUI(HWND hWnd);
|
||||
bool UpdateFromUI(HWND hWnd);
|
||||
void RefreshNodeList(HWND hWnd);
|
||||
void SetAnimRange();
|
||||
|
||||
bool FindNode(ULONG INodeHandle); //returns true if the node is already in the list
|
||||
void AddNode(ULONG INodeHandle);
|
||||
void RemoveNode(int i);
|
||||
void RemoveNodeByHandle(ULONG INodeHandle);
|
||||
void ClearNodeList(HWND hWnd);
|
||||
void CullBadNodes();
|
||||
|
||||
ULONG GetNode(int i) { return (i >= 0 && i < _node_list.size()) ? _node_list[i] : ULONG_MAX; }
|
||||
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
};
|
||||
|
||||
#endif // __MaxEggExpOptions__H
|
||||
|
|
|
|||
|
|
@ -1,369 +1 @@
|
|||
#include "maxLogger.h"
|
||||
|
||||
/* Globals & Static Members
|
||||
*/
|
||||
|
||||
Logger *Logger::globalLoggingInstance = 0;
|
||||
|
||||
/* Error Logger Member Functions
|
||||
*/
|
||||
|
||||
Logger::Logger()
|
||||
{
|
||||
VoidEverything();
|
||||
LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, "A new, void Logging instance has been created." );
|
||||
}
|
||||
|
||||
Logger::Logger( LoggingPipeType toWhere, char *additionalStringInfo )
|
||||
{
|
||||
VoidEverything();
|
||||
SetPipeInstance( toWhere, additionalStringInfo );
|
||||
|
||||
sprintf( GetLogString(), "A new, piped logging instance has been created with data '%s'.", additionalStringInfo );
|
||||
LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, GetLogString() );
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
//Send message telling everyone we're going away.
|
||||
LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, "Error logger shutting down!" );
|
||||
//If we've got an open file, close that muthafugga!
|
||||
if ( ( myLogDestination == PIPE_TO_FILE ) && myFileOutputLog.is_open() )
|
||||
myFileOutputLog.close();
|
||||
VoidEverything();
|
||||
}
|
||||
|
||||
/* Public, Static Member Functions
|
||||
*/
|
||||
|
||||
void Logger::FunctionEntry( char *newFunctionName )
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
globalLoggingInstance->FunctionEntryInstance( newFunctionName );
|
||||
}
|
||||
|
||||
void Logger::FunctionExit()
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
globalLoggingInstance->FunctionExitInstance();
|
||||
}
|
||||
|
||||
int Logger::GetHierarchyLevel()
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
return globalLoggingInstance->GetHierarchyLevelInstance();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
char * Logger::GetLogString()
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
return globalLoggingInstance->GetLogStringInstance();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void Logger::Log( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription )
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
globalLoggingInstance->LogInstance( whichSystem, whichErrorKind, errorDescription );
|
||||
}
|
||||
|
||||
void Logger::SetCurrentFunctionName( char *newFunctionName )
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
globalLoggingInstance->SetCurrentFunctionNameInstance( newFunctionName );
|
||||
}
|
||||
|
||||
void Logger::SetHierarchyLevel( unsigned int newIndentLevel )
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
globalLoggingInstance->SetHierarchyLevelInstance( newIndentLevel );
|
||||
}
|
||||
|
||||
void Logger::SetOneErrorMask( SystemType whichType, long int whichErrors )
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
globalLoggingInstance->SetOneErrorMaskInstance( whichType, whichErrors );
|
||||
}
|
||||
|
||||
void Logger::SetPipe( LoggingPipeType toWhere, char *additionalStringInfo )
|
||||
{
|
||||
if ( !globalLoggingInstance )
|
||||
globalLoggingInstance = new Logger();
|
||||
if ( globalLoggingInstance )
|
||||
globalLoggingInstance->SetPipeInstance( toWhere, additionalStringInfo );
|
||||
}
|
||||
|
||||
/* Private Member Functions
|
||||
*/
|
||||
|
||||
void Logger::FunctionEntryInstance( char *newFunctionName )
|
||||
{
|
||||
SetCurrentFunctionNameInstance( newFunctionName );
|
||||
SetHierarchyLevelInstance( GetHierarchyLevelInstance() + 1 );
|
||||
}
|
||||
|
||||
void Logger::FunctionExitInstance()
|
||||
{
|
||||
char endMsg[64];
|
||||
|
||||
SetHierarchyLevelInstance( GetHierarchyLevelInstance() - 1 );
|
||||
if ( myFunctionNames.back() )
|
||||
{
|
||||
if ( myWrittenHierarchyLevel >= myHierarchyLevel )
|
||||
{
|
||||
sprintf( endMsg, "#END {%s}", myFunctionNames.back() );
|
||||
WriteToPipe( endMsg );
|
||||
//LogInstance( LLOGGING, this->SAT_HIGH_LEVEL, GetLogStringInstance());
|
||||
--myWrittenHierarchyLevel;
|
||||
}
|
||||
free( (void *)myFunctionNames.back() );
|
||||
myFunctionNames.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
int Logger::GetHierarchyLevelInstance()
|
||||
{
|
||||
return myHierarchyLevel;
|
||||
}
|
||||
|
||||
char * Logger::GetLogStringInstance()
|
||||
{
|
||||
return myLogString;
|
||||
}
|
||||
|
||||
void Logger::LogInstance( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription )
|
||||
{
|
||||
unsigned int i;
|
||||
char *typeBuf;
|
||||
char beginMsg[64];
|
||||
|
||||
if ( !errorDescription )
|
||||
return;
|
||||
if ( !( (int)whichErrorKind & myErrorMasks[(int)whichSystem] ) )
|
||||
return;
|
||||
typeBuf = (char *)malloc( strlen( errorDescription ) + 64 );
|
||||
if ( !typeBuf )
|
||||
return;
|
||||
typeBuf = strcpy( typeBuf, errorDescription );
|
||||
switch( whichErrorKind )
|
||||
{
|
||||
case SAT_NONE:
|
||||
break;
|
||||
case SAT_NULL_ERROR:
|
||||
strcat( typeBuf, " - (***!!!NULL ERROR!!!***, " );
|
||||
break;
|
||||
case SAT_CRITICAL_ERROR:
|
||||
strcat( typeBuf, " - (***!!!CRITICAL ERROR!!!***, " );
|
||||
break;
|
||||
case SAT_PARAMETER_INVALID_ERROR:
|
||||
strcat( typeBuf, " - (***PARAMETER ERROR***, " );
|
||||
break;
|
||||
case SAT_OTHER_ERROR:
|
||||
strcat( typeBuf, " - (***OTHER ERROR***, " );
|
||||
break;
|
||||
case SAT_HIGH_LEVEL:
|
||||
strcat( typeBuf, " - (---HIGH LEVEL---, " );
|
||||
break;
|
||||
case SAT_MEDIUM_LEVEL:
|
||||
strcat( typeBuf, " - (MEDIUM LEVEL, " );
|
||||
break;
|
||||
case SAT_LOW_LEVEL:
|
||||
strcat( typeBuf, " - (LOW LEVEL, " );
|
||||
break;
|
||||
case SAT_DEBUG_SPAM_LEVEL:
|
||||
strcat( typeBuf, " - (SPAM LEVEL, " );
|
||||
break;
|
||||
case SAT_ALL:
|
||||
strcat( typeBuf, " - (ALL INCLUSIVE, " );
|
||||
break;
|
||||
}
|
||||
switch( whichSystem )
|
||||
{
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM1:
|
||||
strcat( typeBuf, "SYS_ONE)" );
|
||||
break;
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2:
|
||||
strcat( typeBuf, "SYS_TWO)" );
|
||||
break;
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3:
|
||||
strcat( typeBuf, "SYS_THREE)" );
|
||||
break;
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4:
|
||||
strcat( typeBuf, "SYS_FOUR)" );
|
||||
break;
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM5:
|
||||
strcat( typeBuf, "SYS_FIVE)" );
|
||||
break;
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM6:
|
||||
strcat( typeBuf, "SYS_SIX)" );
|
||||
break;
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM7:
|
||||
strcat( typeBuf, "SYS_SEVEN)" );
|
||||
break;
|
||||
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM8:
|
||||
strcat( typeBuf, "SYS_EIGHT)" );
|
||||
break;
|
||||
}
|
||||
|
||||
//Now that we've created the correct logging line to print, we need to worry
|
||||
//about function entries and exits. Only do this if we're not writing to a dialog box.
|
||||
if ( myLogDestination != PIPE_TO_DIALOG_BOX )
|
||||
{
|
||||
unsigned int tempHierarchyLevel = myHierarchyLevel;
|
||||
|
||||
i = 0;
|
||||
for( CharStarVectorIterator hierarchyDepthIterator = myFunctionNames.begin();
|
||||
hierarchyDepthIterator != myFunctionNames.end();
|
||||
++hierarchyDepthIterator )
|
||||
{
|
||||
++i;
|
||||
//Since we're writing some output, we need to print all function headings
|
||||
//leading up to this output, bumping up our written hierarchy level to match
|
||||
//the "actual" level.
|
||||
//If we've reached a function level that's deeper than what we've written out already...
|
||||
if ( i > myWrittenHierarchyLevel )
|
||||
{
|
||||
myHierarchyLevel = myWrittenHierarchyLevel;
|
||||
sprintf( beginMsg, "#BEGIN {%s}", *hierarchyDepthIterator );
|
||||
WriteToPipe( beginMsg );
|
||||
myHierarchyLevel = tempHierarchyLevel;
|
||||
++myWrittenHierarchyLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
WriteToPipe( typeBuf );
|
||||
free(typeBuf);
|
||||
}
|
||||
|
||||
void Logger::SetCurrentFunctionNameInstance( char *newFunctionName )
|
||||
{
|
||||
char *newBuf;
|
||||
|
||||
//No FunctionEntry Instance allowed...that function uses this!
|
||||
if ( !newFunctionName )
|
||||
{
|
||||
LogInstance( LLOGGING, SAT_NULL_ERROR, "newFunctionName is null!" );
|
||||
return;
|
||||
}
|
||||
newBuf = strdup( newFunctionName );
|
||||
myFunctionNames.push_back( newBuf );
|
||||
}
|
||||
|
||||
void Logger::SetHierarchyLevelInstance( unsigned int newIndentLevel )
|
||||
{
|
||||
myHierarchyLevel = newIndentLevel;
|
||||
}
|
||||
|
||||
void Logger::SetOneErrorMaskInstance( SystemType whichType, long int whichErrors )
|
||||
{
|
||||
if ( ( (int)whichType < 0 ) || ( (int)whichType >= MY_MAX_NUM_SYSTEMS ) )
|
||||
{
|
||||
LogInstance( LLOGGING, SAT_PARAMETER_INVALID_ERROR, "whichType is out of bounds!" );
|
||||
return;
|
||||
}
|
||||
//Now that the sanity check is out of the way, let us change the error mask!
|
||||
myErrorMasks[(int)whichType] = whichErrors;
|
||||
sprintf( GetLogStringInstance(), "Set error mask for system with ID %x to %x.", (int)whichType, whichErrors );
|
||||
LogInstance( LLOGGING, SAT_LOW_LEVEL, GetLogStringInstance() );
|
||||
}
|
||||
|
||||
void Logger::SetPipeInstance( LoggingPipeType toWhere, char *additionalStringInfo )
|
||||
{
|
||||
myLogDestination = toWhere;
|
||||
switch( myLogDestination )
|
||||
{
|
||||
case PIPE_TO_FILE:
|
||||
if ( myFileOutputLog.is_open() )
|
||||
myFileOutputLog.close();
|
||||
if ( additionalStringInfo )
|
||||
myFileOutputLog.open( additionalStringInfo, ofstream::out | ofstream::trunc );
|
||||
else
|
||||
myFileOutputLog.open( "Kens_Logger_Log_File.txt", ofstream::out | ofstream::trunc );
|
||||
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to file." );
|
||||
break;
|
||||
case PIPE_TO_COUT:
|
||||
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to cout." );
|
||||
break;
|
||||
case PIPE_TO_CERR:
|
||||
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to cerr." );
|
||||
break;
|
||||
case PIPE_TO_DIALOG_BOX:
|
||||
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to dialog box." );
|
||||
break;
|
||||
case PIPE_TO_DEV_NULL:
|
||||
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to dev null." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::VoidEverything()
|
||||
{
|
||||
myLogDestination = PIPE_TO_DEV_NULL;
|
||||
myHierarchyLevel = 0;
|
||||
myWrittenHierarchyLevel = 0;
|
||||
//(Get rid of the stack of called functions.)
|
||||
for (CharStarVectorIterator it = myFunctionNames.begin(); it < myFunctionNames.end(); it++) {
|
||||
if (*it)
|
||||
free ((void *)(*it));
|
||||
}
|
||||
myFunctionNames.erase( myFunctionNames.begin(), myFunctionNames.end() );
|
||||
//Make it so that our logger blindly accepts all logs...
|
||||
for( int i = 0; i < MY_MAX_NUM_SYSTEMS; ++i )
|
||||
SetOneErrorMaskInstance( (SystemType)i, (long int)SAT_ALL );
|
||||
//...but pipes them all to /dev/null. Mwahaha! The irony!
|
||||
strncpy( myLogString, "No Error", LOGGER_STRING_BUFFER_SIZE - 1 );
|
||||
}
|
||||
|
||||
void Logger::WriteToPipe( char *textToPipe )
|
||||
{
|
||||
switch( myLogDestination )
|
||||
{
|
||||
case PIPE_TO_FILE:
|
||||
if ( myFileOutputLog.is_open() )
|
||||
{
|
||||
for (unsigned int i = 0; i < myHierarchyLevel; ++i )
|
||||
myFileOutputLog << " ";
|
||||
myFileOutputLog << textToPipe << endl;
|
||||
myFileOutputLog.flush();
|
||||
}
|
||||
break;
|
||||
case PIPE_TO_COUT:
|
||||
cout << "(" << textToPipe << ")" << endl;
|
||||
break;
|
||||
case PIPE_TO_CERR:
|
||||
cerr << "(" << textToPipe << ")" << endl;
|
||||
break;
|
||||
case PIPE_TO_DIALOG_BOX:
|
||||
MessageBox( NULL, textToPipe, "Logger", MB_OK );
|
||||
break;
|
||||
case PIPE_TO_DEV_NULL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
char Logger::dummy[65536];
|
||||
|
|
|
|||
|
|
@ -1,31 +1,6 @@
|
|||
#ifndef __maxLogger__H
|
||||
#define __maxLogger__H
|
||||
|
||||
/* Standard C++ Includes for file and stream output
|
||||
*/
|
||||
|
||||
//For file IO and cmd line output
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
//For MessageBox
|
||||
#include "windows.h"
|
||||
|
||||
#define MY_MAX_NUM_SYSTEMS 8
|
||||
#define LOGGER_STRING_BUFFER_SIZE 128
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
/* Vector definitions
|
||||
*/
|
||||
|
||||
typedef vector<char *> CharStarVector;
|
||||
typedef CharStarVector::iterator CharStarVectorIterator;
|
||||
|
||||
/* Class Defintions
|
||||
*/
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
|
|
@ -60,62 +35,22 @@ public:
|
|||
PIPE_TO_FILE, PIPE_TO_COUT, PIPE_TO_CERR, PIPE_TO_DIALOG_BOX, PIPE_TO_DEV_NULL
|
||||
};
|
||||
|
||||
private:
|
||||
//Which errors to display
|
||||
long int myErrorMasks[MY_MAX_NUM_SYSTEMS];
|
||||
//For use when the the logger is set to pipe to a file.
|
||||
ofstream myFileOutputLog;
|
||||
//The stack of called functions.
|
||||
CharStarVector myFunctionNames;
|
||||
//For formatting purposes, in the file, cerr, or cout versions, add n whitespace to the front, where n is this.
|
||||
unsigned int myHierarchyLevel;
|
||||
//A memory of which state we're in, as far as output is concerned
|
||||
LoggingPipeType myLogDestination;
|
||||
//A pre-allocated string to use with sprintf, or when error logging just needs a little scratch space.
|
||||
char myLogString[LOGGER_STRING_BUFFER_SIZE];
|
||||
//An integer that keeps track of how far down into the indent hierarchy we've actually written.
|
||||
unsigned int myWrittenHierarchyLevel;
|
||||
|
||||
public:
|
||||
//A static pointer to an active errorLogger that any class can get to.
|
||||
static Logger *globalLoggingInstance;
|
||||
Logger() {}
|
||||
Logger( LoggingPipeType toWhere, char *additionalStringInfo ) { }
|
||||
~Logger() { }
|
||||
static void FunctionEntry( char *newFunctionName ) { }
|
||||
static void FunctionExit() { }
|
||||
static int GetHierarchyLevel() { }
|
||||
static char * GetLogString() { return dummy; }
|
||||
static void Log( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription ) { }
|
||||
static void SetCurrentFunctionName( char *newFunctionName ) { }
|
||||
static void SetHierarchyLevel( unsigned int newIndentLevel ) { }
|
||||
static void SetOneErrorMask( SystemType whichType, long int whichErrors ) { }
|
||||
static void SetPipe( LoggingPipeType toWhere, char *additionalStringInfo ) { }
|
||||
|
||||
//Constructors & Destructor
|
||||
Logger();
|
||||
Logger( LoggingPipeType toWhere, char *additionalStringInfo );
|
||||
~Logger();
|
||||
//Static functions that constitute the main interface to this class.
|
||||
static void FunctionEntry( char *newFunctionName );
|
||||
static void FunctionExit();
|
||||
static int GetHierarchyLevel();
|
||||
static char * GetLogString();
|
||||
static void Log( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription );
|
||||
static void SetCurrentFunctionName( char *newFunctionName );
|
||||
static void SetHierarchyLevel( unsigned int newIndentLevel );
|
||||
static void SetOneErrorMask( SystemType whichType, long int whichErrors );
|
||||
static void SetPipe( LoggingPipeType toWhere, char *additionalStringInfo );
|
||||
static char dummy[65536];
|
||||
|
||||
private:
|
||||
//Private functions called by the static versions if a globalLogging instance exists.
|
||||
void FunctionEntryInstance( char *newFunctionName );
|
||||
void FunctionExitInstance();
|
||||
int GetHierarchyLevelInstance();
|
||||
char * GetLogStringInstance();
|
||||
void LogInstance( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription );
|
||||
void SetCurrentFunctionNameInstance( char *newFunctionName );
|
||||
void SetHierarchyLevelInstance( unsigned int newIndentLevel );
|
||||
void SetOneErrorMaskInstance( SystemType whichType, long int whichErrors );
|
||||
void SetPipeInstance( LoggingPipeType toWhere, char *additionalStringInfo );
|
||||
void VoidEverything();
|
||||
void WriteToPipe( char *textToPipe );
|
||||
};
|
||||
|
||||
/* Subsystem defs for logger.
|
||||
*/
|
||||
|
||||
#define LLOGGING Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM1
|
||||
|
||||
/* Externed Globals
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "maxNodeDesc.h"
|
||||
#include "maxLogger.h"
|
||||
#define MTEC Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4
|
||||
|
||||
TypeHandle MaxNodeDesc::_type_handle;
|
||||
|
|
|
|||
|
|
@ -16,31 +16,6 @@
|
|||
#ifndef MAXNODEDESC_H
|
||||
#define MAXNODEDESC_H
|
||||
|
||||
#pragma conform(forScope, off)
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "namable.h"
|
||||
|
||||
#ifdef MAX5
|
||||
//Disable the "Too many actual parameters in istdplug.h" warning in Max5
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4002)
|
||||
#include "max_pre_include.h"
|
||||
#endif
|
||||
#include <Max.h>
|
||||
#include "bipexp.h"
|
||||
#ifdef MAX5
|
||||
#include "max_post_include.h"
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
class EggGroup;
|
||||
class EggTable;
|
||||
class EggXfmSAnim;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MaxNodeDesc
|
||||
// Description : Describes a single instance of a node in the Max
|
||||
|
|
@ -82,7 +57,7 @@ class MaxNodeDesc : public ReferenceCount, public Namable {
|
|||
JT_none, // Not a joint.
|
||||
JT_node_joint, // Node that represents a joint in the geometry
|
||||
// but not the actual joint itself
|
||||
JT_joint, // An actual joint in Max.
|
||||
JT_joint, // An actual joint in Max.
|
||||
JT_pseudo_joint, // Not a joint in Max, but treated just like a
|
||||
// joint for the purposes of the converter.
|
||||
JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
|
||||
|
|
|
|||
|
|
@ -13,24 +13,6 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "maxNodeTree.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
#include "eggData.h"
|
||||
|
||||
#ifdef MAX5
|
||||
//Disable the "Too many actual parameters in istdplug.h" warning in Max5
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4002)
|
||||
#include "max_pre_include.h"
|
||||
#endif
|
||||
#include "Max.h"
|
||||
#ifdef MAX5
|
||||
#include "max_post_include.h"
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include "maxToEggConverter.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -133,74 +115,6 @@ build_complete_hierarchy(INode *root, ULONG *selection_list, int len) {
|
|||
return all_ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::build_selected_hierarchy
|
||||
// Access: Public
|
||||
// Description: Walks through the selected subset of the Max
|
||||
// hierarchy (or the complete hierarchy, if nothing is
|
||||
// selected) and builds up the corresponding tree.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MaxNodeTree::
|
||||
build_selected_hierarchy(INode *root) {
|
||||
// *** Write this later when it's time to do selection
|
||||
/*
|
||||
MStatus status;
|
||||
|
||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||
if (!status) {
|
||||
status.perror("MItDag constructor");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get only the selected geometry.
|
||||
MSelectionList selection;
|
||||
status = MGlobal::getActiveSelectionList(selection);
|
||||
if (!status) {
|
||||
status.perror("MGlobal::getActiveSelectionList");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the selected geometry only if the selection is nonempty;
|
||||
// otherwise, get the whole scene anyway.
|
||||
if (selection.isEmpty()) {
|
||||
mayaegg_cat.info()
|
||||
<< "Selection list is empty.\n";
|
||||
return build_complete_hierarchy();
|
||||
}
|
||||
*/
|
||||
bool all_ok = true;
|
||||
/*
|
||||
unsigned int length = selection.length();
|
||||
for (unsigned int i = 0; i < length; i++) {
|
||||
MDagPath root_path;
|
||||
status = selection.getDagPath(i, root_path);
|
||||
if (!status) {
|
||||
status.perror("MSelectionList::getDagPath");
|
||||
} else {
|
||||
// Now traverse through the selected dag path and all nested
|
||||
// dag paths.
|
||||
dag_iterator.reset(root_path);
|
||||
while (!dag_iterator.isDone()) {
|
||||
MDagPath dag_path;
|
||||
status = dag_iterator.getPath(dag_path);
|
||||
if (!status) {
|
||||
status.perror("MItDag::getPath");
|
||||
} else {
|
||||
build_node(dag_path);
|
||||
}
|
||||
|
||||
dag_iterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (all_ok) {
|
||||
_root->check_pseudo_joints(false);
|
||||
}
|
||||
*/
|
||||
return all_ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::get_num_nodes
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
#ifndef MAXNODETREE_H
|
||||
#define MAXNODETREE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "maxNodeDesc.h"
|
||||
|
||||
class EggData;
|
||||
class EggGroupNode;
|
||||
|
||||
|
|
@ -34,7 +30,6 @@ public:
|
|||
MaxNodeDesc *build_node(INode *max_node);
|
||||
MaxNodeDesc *build_joint(INode *max_node, MaxNodeDesc *node_joint);
|
||||
bool build_complete_hierarchy(INode *root, ULONG *selection_list, int len);
|
||||
bool build_selected_hierarchy(INode *root);
|
||||
MaxNodeDesc *find_node(INode *max_node);
|
||||
MaxNodeDesc *find_joint(INode *max_node);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
maxToEgg.cxx
|
||||
Created by Ken Strickland 02/24/03
|
||||
Modified and maintained by Corey Revilla, (05/22/03)-(Present)
|
||||
Carnegie Mellon University, Entetainment Technology Center
|
||||
*/
|
||||
|
||||
//Our headers, which in turn includes some Max headers.
|
||||
#include "maxToEgg.h"
|
||||
#include "errno.h"
|
||||
|
||||
//Member Function Definitions
|
||||
/* ~MaxToEgg() - Uninteresting destructor.
|
||||
*/
|
||||
MaxToEgg::~MaxToEgg()
|
||||
{
|
||||
}
|
||||
|
||||
/* MaxToEgg() - Constructs a MaxToEgg "application." It sets the types of
|
||||
options this converter can take and sets up a description of the program.
|
||||
*/
|
||||
MaxToEgg::MaxToEgg() : SomethingToEgg("3D Studio Max",".max")
|
||||
{
|
||||
add_path_replace_options();
|
||||
add_path_store_options();
|
||||
add_animation_options();
|
||||
add_units_options();
|
||||
add_normals_options();
|
||||
add_transform_options();
|
||||
|
||||
set_program_description("This program converts 3D Studio Max model files to egg.");
|
||||
/*add_option("p", "", 0,
|
||||
"Generate polygon output only. Convert scene to triangle mesh "
|
||||
"before converting.", &MaxToEgg::dispatch_none, &alertOnBegin);*/
|
||||
add_option("bface", "", 0,
|
||||
"Export all polygons as double-sided ",
|
||||
&MaxToEgg::dispatch_none, &doubleSided);
|
||||
//Fill in the member variables.
|
||||
pMaxInterface = null;
|
||||
successfulOutput = false;
|
||||
confirmExport = true;
|
||||
doubleSided = false;
|
||||
}
|
||||
|
||||
/* IsSuccessful() - Indicates if conversion was successful.
|
||||
*/
|
||||
bool MaxToEgg::IsSuccessful()
|
||||
{
|
||||
return successfulOutput;
|
||||
}
|
||||
|
||||
char *MaxToEgg::MyClassName()
|
||||
{
|
||||
return "MaxToEgg";
|
||||
}
|
||||
|
||||
/* Run() - Runs the conversion. Creates a MaxToEggConverter, populates it
|
||||
with the scene graph, and then writes out the egg file.
|
||||
*/
|
||||
void MaxToEgg::Run(ULONG *selection_list, int len)
|
||||
{
|
||||
MaxToEggConverter converter;
|
||||
|
||||
Logger::FunctionEntry( "MaxToEgg::Run" );
|
||||
// Now, we fill out the necessary fields of the converter, which does all
|
||||
// the necessary work.
|
||||
Logger::Log( MTE, Logger::SAT_DEBUG_SPAM_LEVEL, "Setting Max Interface." );
|
||||
converter.setMaxInterface( pMaxInterface );
|
||||
Logger::Log( MTE, Logger::SAT_DEBUG_SPAM_LEVEL,
|
||||
"Setting converter's egg data." );
|
||||
converter.set_egg_data( _data );
|
||||
// applies the parameters from the command line options
|
||||
apply_parameters(converter);
|
||||
converter.set_double_sided(doubleSided);
|
||||
converter.set_selection_list(selection_list, len);
|
||||
|
||||
//Now, do the actual file conversion.
|
||||
if (confirmExport && converter.convert_file(_input_filename)) {
|
||||
successfulOutput=true;
|
||||
write_egg_file();
|
||||
Logger::Log( MTE, Logger::SAT_DEBUG_SPAM_LEVEL, "Egg file written!" );
|
||||
}
|
||||
|
||||
Logger::FunctionExit();
|
||||
}
|
||||
|
||||
|
||||
/* SetMaxInterface(Interface *) - This is how we know how to traverse the Max
|
||||
scene graph. For this to be a standalone application, we'd want to be able
|
||||
to build one of these interfaces for the input file.
|
||||
*/
|
||||
void MaxToEgg::SetMaxInterface(Interface *pInterface)
|
||||
{
|
||||
pMaxInterface = pInterface;
|
||||
}
|
||||
|
||||
bool MaxToEgg::handle_args(Args &args) {
|
||||
char msg[3072];
|
||||
|
||||
//If "auto overwrite" was not checked, ask if the user wishes to overwrite the file
|
||||
if (_allow_last_param && !_got_output_filename && args.size() > 1) {
|
||||
_got_output_filename = true;
|
||||
_output_filename = Filename::from_os_specific(args.back());
|
||||
args.pop_back();
|
||||
|
||||
if (!verify_output_file_safe()) {
|
||||
sprintf(msg, "Overwrite file \"%s\"?", _output_filename.to_os_specific().c_str());
|
||||
confirmExport =
|
||||
( MessageBox(pMaxInterface->GetMAXHWnd(), msg, "Panda3D Exporter", MB_YESNO | MB_ICONQUESTION)
|
||||
== IDYES );
|
||||
}
|
||||
}
|
||||
|
||||
//Attempt to catch if the output file is read-only
|
||||
if (confirmExport) {
|
||||
_output_filename.make_dir();
|
||||
if (access(Filename(_output_filename.get_dirname()).to_os_specific().c_str(), 2) ||
|
||||
(access(_output_filename.to_os_specific().c_str(), 2) && errno != ENOENT)) {
|
||||
sprintf(msg, "Error attempting to open \"%s\"\n\nDestination file is in use or read-only", _output_filename.to_os_specific().c_str());
|
||||
MessageBox(pMaxInterface->GetMAXHWnd(), msg, "Panda3D Exporter", MB_OK | MB_ICONERROR);
|
||||
confirmExport = false;
|
||||
}
|
||||
}
|
||||
|
||||
return SomethingToEgg::handle_args(args);
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
maxToEgg.h
|
||||
Created by Ken Strickland, 02/24/03
|
||||
Modified + Maintained by Corey Revilla, (05/22/03-Present)
|
||||
CMU's Entertainment Technology Center
|
||||
|
||||
This file defines the MaxToEgg class, a class derived from SomethingToEgg,
|
||||
which means it was designed to be a standalone application that would get
|
||||
called by Ppremake during compilation to convert models of the appropriate
|
||||
type. As there doesn't seem to be a way get at the 3dsMax API without going
|
||||
the plug-in route, however, this class is actually run by another wrapper
|
||||
class, MaxEggPlugin. This class, in turn, is a wrapper about the
|
||||
MaxToEggConverter class, which actually twiddles the bits, as they say.
|
||||
*/
|
||||
#ifndef __maxToEgg__H
|
||||
#define __maxToEgg__H
|
||||
|
||||
#pragma conform(forScope, off)
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "maxToEggConverter.h"
|
||||
|
||||
/* Error-Reporting Includes
|
||||
*/
|
||||
#include "maxLogger.h"
|
||||
#define MTE Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM5
|
||||
|
||||
/**
|
||||
* This class defines a "converter" between Max files and eggs. All it
|
||||
* does is define the output file, call MaxToEggConverter to actually
|
||||
* convert the geometry, and then write out the output file.
|
||||
*/
|
||||
class MaxToEgg : public SomethingToEgg
|
||||
{
|
||||
protected:
|
||||
// If true, various windows pop-up alerts will announce when certain tasks
|
||||
// begin.
|
||||
bool confirmExport;
|
||||
// The local pointer to the 3ds max interface we keep around to get the
|
||||
// scene graph. If we ever get this to run standalone, we'll need an
|
||||
// alternate way to set this other than through MaxEggPlugin.
|
||||
Interface *pMaxInterface;
|
||||
// False initially, but premanently switches to true when a file is
|
||||
// sucessfully converted.
|
||||
bool successfulOutput;
|
||||
bool doubleSided;
|
||||
virtual bool handle_args(Args &args);
|
||||
|
||||
public:
|
||||
MaxToEgg();
|
||||
~MaxToEgg();
|
||||
bool IsSuccessful();
|
||||
//Returns a pointer to the class name.
|
||||
char *MyClassName();
|
||||
void Run(ULONG *selection_list, int len);
|
||||
void SetMaxInterface(Interface *pInterface);
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -18,54 +18,8 @@
|
|||
|
||||
#pragma conform(forScope, off)
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
/* 3ds Max Includes, with bonus(!) memory protection
|
||||
*/
|
||||
|
||||
#ifdef MAX5
|
||||
//Disable the "Too many actual parameters in istdplug.h" warning in Max5
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4002)
|
||||
#include "max_pre_include.h"
|
||||
#endif
|
||||
#include "Max.h"
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "istdplug.h"
|
||||
#include "iskin.h"
|
||||
#include "maxResource.h"
|
||||
#include "stdmat.h"
|
||||
#include "phyexp.h"
|
||||
#include "surf_api.h"
|
||||
#ifdef MAX5
|
||||
#include "max_post_include.h"
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
/* Panda Includes
|
||||
*/
|
||||
#include "eggCoordinateSystem.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "eggTexture.h"
|
||||
#include "eggVertex.h"
|
||||
#include "eggVertexPool.h"
|
||||
#include "eggNurbsCurve.h"
|
||||
#include "pandatoolbase.h"
|
||||
#include "somethingToEgg.h"
|
||||
#include "somethingToEggConverter.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
|
||||
/* Local Includes
|
||||
*/
|
||||
#include "maxNodeTree.h"
|
||||
|
||||
/* Error-Reporting Includes
|
||||
*/
|
||||
#include "maxLogger.h"
|
||||
#define MTEC Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4
|
||||
|
||||
/* Helpful Defintions and Casts
|
||||
|
|
@ -83,115 +37,69 @@
|
|||
// Description : This class supervises the construction of an EggData
|
||||
// structure from a Max model
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class MaxToEggConverter : public SomethingToEggConverter {
|
||||
class MaxToEggConverter {
|
||||
public:
|
||||
MaxToEggConverter(const string &program_name = "");
|
||||
MaxToEggConverter(const MaxToEggConverter ©);
|
||||
virtual ~MaxToEggConverter();
|
||||
|
||||
virtual SomethingToEggConverter *make_copy();
|
||||
|
||||
virtual string get_name() const;
|
||||
virtual string get_extension() const;
|
||||
|
||||
virtual bool convert_file(const Filename &filename);
|
||||
bool convert_max(bool from_selection);
|
||||
|
||||
//Sets the interface to 3dsMax.
|
||||
void setMaxInterface(Interface *pInterface);
|
||||
|
||||
void set_selection_list(ULONG *list, int len) {
|
||||
_selection_list = list; _selection_len = len; }
|
||||
void set_double_sided(bool flag) {double_sided = flag;}
|
||||
MaxToEggConverter();
|
||||
~MaxToEggConverter();
|
||||
|
||||
bool convert(MaxEggOptions *options);
|
||||
|
||||
private:
|
||||
double _current_frame;
|
||||
ULONG *_selection_list; int _selection_len;
|
||||
MaxEggOptions *_options;
|
||||
int _current_frame;
|
||||
PT(EggData) _egg_data;
|
||||
string _program_name;
|
||||
MaxNodeTree _tree;
|
||||
int _cur_tref;
|
||||
|
||||
void reset();
|
||||
|
||||
bool convert_flip(double start_frame, double end_frame,
|
||||
double frame_inc, double output_frame_rate);
|
||||
bool convert_char_model();
|
||||
bool convert_char_chan(double start_frame, double end_frame,
|
||||
double frame_inc, double output_frame_rate);
|
||||
bool convert_hierarchy(EggGroupNode *egg_root);
|
||||
bool process_model_node(MaxNodeDesc *node_desc);
|
||||
|
||||
void get_transform(INode *max_node, EggGroup *egg_group);
|
||||
LMatrix4d get_object_transform(INode *max_node);
|
||||
void get_joint_transform(INode *max_node, EggGroup *egg_group);
|
||||
void get_joint_transform(INode *max_node, INode *parent_node,
|
||||
EggGroup *egg_group);
|
||||
|
||||
bool make_nurbs_curve(NURBSCVCurve *curve, const string &name,
|
||||
TimeValue time, EggGroup *egg_group);
|
||||
void make_polyset(INode *max_node,
|
||||
Mesh *mesh,
|
||||
EggGroup *egg_group,
|
||||
Shader *default_shader = NULL);
|
||||
|
||||
bool convert_char_model();
|
||||
bool convert_char_chan(double start_frame, double end_frame,
|
||||
double frame_inc, double output_frame_rate);
|
||||
bool convert_hierarchy(EggGroupNode *egg_root);
|
||||
bool process_model_node(MaxNodeDesc *node_desc);
|
||||
|
||||
void get_transform(INode *max_node, EggGroup *egg_group);
|
||||
LMatrix4d get_object_transform(INode *max_node);
|
||||
void get_joint_transform(INode *max_node, EggGroup *egg_group);
|
||||
void get_joint_transform(INode *max_node, INode *parent_node,
|
||||
EggGroup *egg_group);
|
||||
|
||||
// *** Leaving out these functions til there use/support in Max is determined
|
||||
/*
|
||||
void make_nurbs_surface(const MDagPath &dag_path,
|
||||
MFnNurbsSurface &surface,
|
||||
EggGroup *group);
|
||||
EggNurbsCurve *make_trim_curve(const MFnNurbsCurve &curve,
|
||||
const string &nurbs_name,
|
||||
EggGroupNode *egg_group,
|
||||
int trim_curve_index);
|
||||
*/
|
||||
bool make_nurbs_curve(NURBSCVCurve *curve, const string &name,
|
||||
TimeValue time, EggGroup *egg_group);
|
||||
void make_polyset(INode *max_node,
|
||||
Mesh *mesh,
|
||||
EggGroup *egg_group,
|
||||
Shader *default_shader = NULL);
|
||||
/*
|
||||
void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
||||
EggGroup *egg_group);
|
||||
*/
|
||||
|
||||
//Gets the vertex normal for a given face and vertex. Go figure.
|
||||
Point3 get_max_vertex_normal(Mesh *mesh, int faceNo, int vertNo);
|
||||
|
||||
void get_vertex_weights(INode *max_node, EggVertexPool *vpool);
|
||||
/*
|
||||
void set_shader_attributes(EggPrimitive &primitive,
|
||||
const MayaShader &shader);
|
||||
*/
|
||||
void set_material_attributes(EggPrimitive &primitive, INode *max_node);
|
||||
|
||||
void set_material_attributes(EggPrimitive &primitive, Mtl *maxMaterial, Face *face);
|
||||
|
||||
void apply_texture_properties(EggTexture &tex,
|
||||
StdMat *maxMaterial);
|
||||
/*
|
||||
bool compare_texture_properties(EggTexture &tex,
|
||||
const MayaShaderColorDef &color_def);
|
||||
*/
|
||||
|
||||
bool reparent_decals(EggGroupNode *egg_parent);
|
||||
|
||||
string _program_name;
|
||||
bool _from_selection;
|
||||
|
||||
MaxNodeTree _tree;
|
||||
|
||||
int _cur_tref;
|
||||
bool double_sided;
|
||||
//Gets the vertex normal for a given face and vertex. Go figure.
|
||||
Point3 get_max_vertex_normal(Mesh *mesh, int faceNo, int vertNo);
|
||||
|
||||
void get_vertex_weights(INode *max_node, EggVertexPool *vpool);
|
||||
|
||||
void set_material_attributes(EggPrimitive &primitive, INode *max_node);
|
||||
|
||||
void set_material_attributes(EggPrimitive &primitive, Mtl *maxMaterial, Face *face);
|
||||
|
||||
void apply_texture_properties(EggTexture &tex,
|
||||
StdMat *maxMaterial);
|
||||
bool reparent_decals(EggGroupNode *egg_parent);
|
||||
|
||||
public:
|
||||
//MayaShaders _shaders;
|
||||
EggTextureCollection _textures;
|
||||
Interface *maxInterface;
|
||||
|
||||
bool _polygon_output;
|
||||
double _polygon_tolerance;
|
||||
|
||||
EggTextureCollection _textures;
|
||||
|
||||
enum TransformType {
|
||||
TT_invalid,
|
||||
TT_all,
|
||||
TT_model,
|
||||
TT_dcs,
|
||||
TT_none,
|
||||
TT_invalid,
|
||||
TT_all,
|
||||
TT_model,
|
||||
TT_dcs,
|
||||
TT_none,
|
||||
};
|
||||
TransformType _transform_type;
|
||||
|
||||
|
||||
static TransformType string_transform_type(const string &arg);
|
||||
|
||||
|
||||
Modifier* FindSkinModifier (INode* node, const Class_ID &type);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
// Filename: post_maya_include.h
|
||||
// Created by: drose (11Apr02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This header file works in conjunction with pre_maya_include.h; it
|
||||
// cleans up some of the definitions that it left open.
|
||||
|
||||
// Remove the symbols defined from pre_maya_include.h.
|
||||
#undef ostream
|
||||
#undef istream
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
// Filename: pre_maya_include.h
|
||||
// Created by: drose (11Apr02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This header file defines a few things that are necessary to define
|
||||
// before including any Maya headers, just to work around some of
|
||||
// Max's assumptions about the compiler. It must not try to protect
|
||||
// itself from multiple inclusion with #ifdef .. #endif, since it must
|
||||
// be used each time it is included.
|
||||
|
||||
// Max will try to typedef bool unless this symbol is defined.
|
||||
#ifndef _BOOL
|
||||
#define _BOOL 1
|
||||
#endif
|
||||
|
||||
// Max tries to make a forward declaration for class ostream, but
|
||||
// this is not necessarily a class! Curses. We can't use any of the
|
||||
// built-in Max stream operators, and we have to protect ourselves
|
||||
// from them.
|
||||
#define ostream max_ostream
|
||||
#define istream max_istream
|
||||
|
|
@ -1,3 +1,58 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <crtdbg.h>
|
||||
#include "errno.h"
|
||||
#include "Max.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
#include "eggData.h"
|
||||
#include "pandatoolbase.h"
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "namable.h"
|
||||
#include "modstack.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "windef.h"
|
||||
#include "windows.h"
|
||||
|
||||
#include "Max.h"
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "istdplug.h"
|
||||
#include "iskin.h"
|
||||
#include "maxResource.h"
|
||||
#include "stdmat.h"
|
||||
#include "phyexp.h"
|
||||
#include "surf_api.h"
|
||||
#include "bipexp.h"
|
||||
|
||||
#include "eggCoordinateSystem.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "eggTexture.h"
|
||||
#include "eggVertex.h"
|
||||
#include "eggVertexPool.h"
|
||||
#include "eggNurbsCurve.h"
|
||||
#include "pandatoolbase.h"
|
||||
#include "somethingToEgg.h"
|
||||
#include "somethingToEggConverter.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
|
||||
#include "maxNodeDesc.h"
|
||||
#include "maxNodeTree.h"
|
||||
#include "maxLogger.h"
|
||||
#include "maxToEgg.h"
|
||||
#include "maxEggExpOptions.h"
|
||||
#include "maxToEggConverter.h"
|
||||
#include "maxEgg.h"
|
||||
|
||||
#include "maxDllEntry.cxx"
|
||||
#include "maxLogger.cxx"
|
||||
#include "maxEgg.cxx"
|
||||
|
|
|
|||
Loading…
Reference in New Issue