📄 max2nmo.cpp
字号:
void Max2Nmo::ShowAbout(HWND hWnd)
{
DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutBoxDlgProc, 0);
}
static BOOL CALLBACK ReportDlgProc(HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
Max2Nmo *exp = (Max2Nmo*)GetWindowLong(hWnd,GWL_USERDATA);
switch (msg) {
case WM_INITDIALOG: {
exp = (Max2Nmo*)lParam;
SetWindowLong(hWnd,GWL_USERDATA,lParam);
CenterWindow(hWnd, GetParent(hWnd));
SetDlgItemText(hWnd,IDC_EDITREPORT,(const char*)exp->ReportBuffer.Begin());
break;
}
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK: {
EndDialog(hWnd, 1);
break;
} break;
}
default: return FALSE;
}
return TRUE;
}
// Dialog proc
static BOOL CALLBACK ExportDlgProc(HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
Interval animRange;
ISpinnerControl *spin;
Max2Nmo *exp = (Max2Nmo*)GetWindowLong(hWnd,GWL_USERDATA);
switch (msg) {
case WM_INITDIALOG: {
exp = (Max2Nmo*)lParam;
SetWindowLong(hWnd,GWL_USERDATA,lParam);
CenterWindow(hWnd, GetParent(hWnd));
// check Export Type
int RadioToEnable = IDC_RADIOEXPORTASOBJECTS;
if (exp->GetExportAsObjects()) RadioToEnable=IDC_RADIOEXPORTASOBJECTS;
else
if (exp->GetExportAsCharacter()) RadioToEnable=IDC_RADIOEXPORTASCHARACTER;
else
if (exp->GetExportAsAnimationOnly()) RadioToEnable=IDC_RADIOEXPORTASANIMATION;
CheckRadioButton(hWnd, IDC_RADIOEXPORTASOBJECTS, IDC_RADIOEXPORTASANIMATION, RadioToEnable);
CheckDlgButton(hWnd, IDC_CHECKSTOREFILENAMES, exp->GetStoreOnlyFilenames());
CheckDlgButton(hWnd, IDC_CHECKRESCALESCENE, exp->GetRescaleScene());
CheckDlgButton(hWnd, IDC_CHECKGROUPASPLACE, exp->GetGroupAsPlace());
CheckDlgButton(hWnd, IDC_CHECKBIPEDMESH, exp->GetSaveBipedGeom());
CheckDlgButton(hWnd, IDC_CHECKALIGNANIMATIONS, exp->GetAlignAnimOnZ());
CheckRadioButton(hWnd, IDC_RADIOSKIN, IDC_RADIOMORPH,
exp->GetConvertPhysiqueToSkin() ? IDC_RADIOSKIN : IDC_RADIOMORPH);
// Setup the spinner controls for the controller key sample rate
spin = GetISpinner(GetDlgItem(hWnd, IDC_CONT_STEP_SPIN));
spin->LinkToEdit(GetDlgItem(hWnd,IDC_CONT_STEP), EDITTYPE_INT );
spin->SetLimits(1, 100, TRUE);
spin->SetScale(1.0f);
spin->SetValue(exp->GetKeyFrameStep() ,FALSE);
ReleaseISpinner(spin);
// Setup the spinner controls for the report level
spin = GetISpinner(GetDlgItem(hWnd, IDC_CONT_REPORTSPIN));
spin->LinkToEdit(GetDlgItem(hWnd,IDC_CONT_REPORT), EDITTYPE_INT );
spin->SetLimits(REPORT_NONE, REPORT_LLEVEL, TRUE);
spin->SetScale(1.0f);
spin->SetValue(exp->GetReportLevel() ,FALSE);
ReleaseISpinner(spin);
// Setup the spinner controls for the compression level
spin = GetISpinner(GetDlgItem(hWnd, IDC_CONT_COMPRESSIONSPIN));
spin->LinkToEdit(GetDlgItem(hWnd,IDC_CONT_COMPRESSION), EDITTYPE_INT );
spin->SetLimits(0, 9, TRUE);
spin->SetScale(1.0f);
spin->SetValue(exp->GetCompressionLevel() ,FALSE);
ReleaseISpinner(spin);
// Setup the spinner controls for the mesh definition sample rate
spin = GetISpinner(GetDlgItem(hWnd, IDC_MESH_STEP_SPIN));
spin->LinkToEdit(GetDlgItem(hWnd,IDC_MESH_STEP), EDITTYPE_INT );
spin->SetLimits(1, 100, TRUE);
spin->SetScale(1.0f);
spin->SetValue(exp->GetMeshFrameStep() ,FALSE);
ReleaseISpinner(spin);
SetWindowText(GetDlgItem(hWnd, IDC_EDITCHARACTERNAME),exp->GetCharacterName());
SetWindowText(GetDlgItem(hWnd, IDC_EDITANIMATIONNAME),exp->GetAnimationName());
// Enable / disable character name edit box
EnableWindow(GetDlgItem(hWnd, IDC_EDITCHARACTERNAME), exp->GetExportAsCharacter());
break;
}
case CC_SPINNER_CHANGE:
spin = (ISpinnerControl*)lParam;
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_RADIOEXPORTASOBJECTS:
case IDC_RADIOEXPORTASANIMATION:
case IDC_RADIOEXPORTASCHARACTER:
// Enable / disable character name edit box options
EnableWindow(GetDlgItem(hWnd, IDC_EDITCHARACTERNAME), IsDlgButtonChecked(hWnd,IDC_RADIOEXPORTASCHARACTER));
break;
case IDOK: {
exp->SetExportAsAnimationOnly(IsDlgButtonChecked(hWnd, IDC_RADIOEXPORTASANIMATION));
exp->SetExportAsCharacter(IsDlgButtonChecked(hWnd, IDC_RADIOEXPORTASCHARACTER));
exp->SetExportAsObjects(IsDlgButtonChecked(hWnd, IDC_RADIOEXPORTASOBJECTS));
exp->SetConvertPhysiqueToSkin(IsDlgButtonChecked(hWnd, IDC_RADIOSKIN));
exp->SetRescaleScene(IsDlgButtonChecked(hWnd, IDC_CHECKRESCALESCENE));
exp->SetGroupAsPlace(IsDlgButtonChecked(hWnd, IDC_CHECKGROUPASPLACE));
exp->SetSaveBipedGeom(IsDlgButtonChecked(hWnd, IDC_CHECKBIPEDMESH));
exp->SetbAlignAnimOnZ(IsDlgButtonChecked(hWnd, IDC_CHECKALIGNANIMATIONS));
exp->SetStoreOnlyFilenames(IsDlgButtonChecked(hWnd, IDC_CHECKSTOREFILENAMES));
char TempString[512];
GetDlgItemText(hWnd,IDC_EDITANIMATIONNAME,TempString,512);
exp->SetAnimationName(TempString);
GetDlgItemText(hWnd,IDC_EDITCHARACTERNAME,TempString,512);
exp->SetCharacterName(TempString);
spin = GetISpinner(GetDlgItem(hWnd, IDC_CONT_STEP_SPIN));
exp->SetKeyFrameStep(spin->GetIVal());
ReleaseISpinner(spin);
spin = GetISpinner(GetDlgItem(hWnd, IDC_CONT_REPORTSPIN));
exp->SetReportLevel(spin->GetIVal());
ReleaseISpinner(spin);
spin = GetISpinner(GetDlgItem(hWnd, IDC_CONT_COMPRESSIONSPIN));
exp->SetCompressionLevel(spin->GetIVal());
ReleaseISpinner(spin);
spin = GetISpinner(GetDlgItem(hWnd, IDC_MESH_STEP_SPIN));
exp->SetMeshFrameStep(spin->GetIVal());
ReleaseISpinner(spin);
EndDialog(hWnd, 1);
break;
}
case IDCANCEL:
EndDialog(hWnd, 0);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
// Dummy function for progress bar
DWORD WINAPI fn(LPVOID arg)
{
return(0);
}
// Start the exporter!
// This is the real entrypoint to the exporter. After the user has selected
// the filename (and he's prompted for overwrite etc.) this method is called.
int Max2Nmo::DoExport(const TCHAR *name,ExpInterface *ei,Interface *inf, BOOL suppressPrompts, DWORD options)
{
// Grab the interface pointer.
ip = inf;
#ifdef _USESCRIPTS_
if( name ){
theVirtoolsTool.m_ExportFileName = name;
for( int a=0 ; a<theVirtoolsTool.m_ExportFileName.Length() ; ++a ){
if( theVirtoolsTool.m_ExportFileName[a] == '\\' ){
theVirtoolsTool.m_ExportFileName[a] = '/';
}
}
} else {
theVirtoolsTool.m_ExportFileName = "";
}
theVirtoolsTool.BeginEditParams( inf, NULL );
return 1;
#else
// Get the options the user selected the last time
ReadConfig();
// Prompt the user with our dialogbox, and get all the options.
if (!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MAX2NMOEXPORT_DLG),
ip->GetMAXHWnd(), ExportDlgProc, (LPARAM)this)) {
return 1;
}
SetShowProgressionBar( TRUE );
int res = ReallyDoExport( name, ip, (options&SCENE_EXPORT_SELECTED)? TRUE:FALSE );
return res;
#endif
}
// This methode do the export job, and suppose all the parameters
// has correctly been set (by the export UI, or with MAXScript)
int Max2Nmo::ReallyDoExport( const TCHAR *name, Interface *inf, BOOL sel )
{
ip = inf;
exportSelected = sel;
// Virtools Engine initialization
if (!VirtoolsPluginsParsed) {
#ifndef MAX42
//------ Check the version of Physique installed...
g_CharacterStudio312 = FALSE;
// Parse every plugin dir to find Physique Version !
DWORD Version1,Version2,Version3,Version4;
for (int k=0;k<ip->GetPlugInEntryCount();k++) {
XString Path = ip->GetPlugInDir(k);
Path << "Physique.dlm";
if (GetVersionInfo(Path.Str(),Version1,Version2,Version3,Version4)) {
#ifdef MAX4
// For Max 4 incompatibility starts at version 3.0.2
if ((Version1 >= 3) && ( Version2 >= 1) && ( Version3 >= 2)) {
g_CharacterStudio312 = TRUE;
}
#else
// For Max 3 incompatibility starts at version 3.0.2
if ((Version1 >= 3) && ( Version2 >= 0) && ( Version3 >= 2)) {
g_CharacterStudio312 = TRUE;
}
#endif
break;
}
}
#endif
//-------------------------------------------------------
#ifdef CK_LIB
// Register static plugins that we use...
CKPluginManager* pm = CKGetPluginManager();
// NULL Rasterizer
RegisterRenderEngine(pm);
// Image Plugins
RegisterImageReader(pm);
RegisterAVIReader(pm);
RegisterPNGReader(pm);
RegisterJPGReader(pm);
RegisterTIFFReader(pm);
//--- That's All
#else
for (int j=0;j<ip->GetPlugInEntryCount();j++)
CKGetPluginManager()->ParsePlugins(ip->GetPlugInDir(j));
#endif
VirtoolsPluginsParsed = TRUE;
}
if( !g_VirtoolsContext ){
if (CKCreateContext(&VirtoolsContext,ip->GetMAXHWnd(),0) != CK_OK)
{
MessageBox(NULL, "CK Initialisation Problems", "Max2Nmo", MB_OK);
return 1;
}
VirtoolsContext->GetVariableManager()->SetStringValue("Globals/StartingFlags","Disable Sound,Disable Input");
//-- Add Max Bitmap path to Virtools PathManager
int BitmapPathCount = TheManager->GetMapDirCount();
for(int i=0;i<BitmapPathCount;i++) {
VirtoolsContext->GetPathManager()->AddPath(BITMAP_PATH_IDX,XString(TheManager->GetMapDir(i)));
}
RegisterAllSpecialParameters();
g_VirtoolsContext = VirtoolsContext;
} else {
VirtoolsContext = g_VirtoolsContext;
}
// Virtools Exporter context creation
VirtoolsExporter = new Export2Virtools(VirtoolsContext);
// Rescale Scene to 1 unit = 1 meter if asked
if (GetRescaleScene()) {
RescaleScene();
Report(REPORT_HLEVEL,"Scene rescaled to 1 unit = 1 meter\r\n");
}
// First we write out a file header with global information.
Interval range = ip->GetAnimRange();
m_StartFrame = (float)range.Start();
m_EndFrame = (float)range.End();
m_InvFrameRate = 1.0f/(float)GetTicksPerFrame();
// Startup the progress bar.
if( GetShowProgressionBar() ){
ip->ProgressStart(GetString(IDS_PROGRESS_MSG), TRUE, fn, NULL);
}
// Get a total node count by traversing the scene
// We don't really need to do this, but it doesn't take long, and
// it is nice to have an accurate progress bar.
nTotalNodeCount = 0;
nCurNode = 0;
PreProcess(ip->GetRootNode(), nTotalNodeCount);
//-- Export list of material definitions
Report(REPORT_HLEVEL,"---------Exporting materials----------\r\n");
ExportMaterialList();
Report(REPORT_HLEVEL,"\r\n");
Report(REPORT_HLEVEL,"-----------Exporting objects-----------\r\n");
// Call our node enumerator.
// The nodeEnum function will recurse into itself and
// export each object found in the scene.
int numChildren = ip->GetRootNode()->NumberOfChildren();
for (int idx=0; idx<numChildren; idx++) {
if (ip->GetCancel())
break;
nodeEnum(ip->GetRootNode()->GetChildNode(idx));
}
Report(REPORT_HLEVEL,"\r\n");
Report(REPORT_HLEVEL,"------ Exporting animated meshes ------\r\n");
//-- Check if there are animated meshes (morph, skin, physique)
PostProcess(ip->GetRootNode());
// We're done. Finish the progress bar.
if( GetShowProgressionBar() ){
ip->ProgressEnd();
}
// Write the current options to be used next time around.
WriteConfig();
// Finish creating appropriate objects
CKKeyedAnimation* GlobalAnim = VirtoolsExporter->CreateGlobalAnimation(GetAnimationName());
GlobalAnim->SetLength(FrameTime(m_EndFrame));
if (GetExportAsCharacter()) {
Report(REPORT_HLEVEL,"\r\n");
Report(REPORT_HLEVEL,"Creating character : %s\r\n",GetCharacterName());
VirtoolsExporter->CreateCharacter(GetCharacterName());
}
if (GetStoreOnlyFilenames())
VirtoolsContext->SetGlobalImagesSaveOptions(CKTEXTURE_EXTERNAL);
// Generate the final list containing all the CKObjects
CKFile* VirtoolsFile = VirtoolsContext->CreateCKFile();
m_VirtoolsObjects = CreateCKObjectArray();
VirtoolsExporter->GenerateObjects(m_VirtoolsObjects,GetExportAsAnimationOnly());
// Create Groups for Named Selection Sets
if( GetSelectionAsGroup() ){
Report(REPORT_HLEVEL,"\r\n");
Report(REPORT_HLEVEL,"----------- Exporting Named Selections -----------\r\n");
int namedSelCount = ip->GetNumNamedSelSets();
for( int a=0 ; a<namedSelCount ; ++a ){
CKGroup *grp = (CKGroup *)VirtoolsContext->CreateObject( CKCID_GROUP, ip->GetNamedSelSetName(a) );
if( !grp ) continue;
int selObjCount = ip->GetNamedSelSetItemCount(a);
for( int b=0 ; b<selObjCount ; ++b ){
INode *selNode = ip->GetNamedSelSetItem( a, b);
CK3dEntity *selEnt = VirtoolsExporter->GetEntityByKey( selNode );
if( !selEnt ){
selEnt = VirtoolsExporter->GetLightByKey( selNode );
if( !selEnt ){
selEnt = VirtoolsExporter->GetCameraByKey( selNode );
}
}
if( selEnt ){
grp->AddObject( selEnt );
}
}
if( grp->GetObjectCount() ){
m_VirtoolsObjects->InsertFront( grp );
}
}
}
#ifdef _USESCRIPTS_
Report(REPORT_HLEVEL,"\r\n");
Report(REPORT_HLEVEL,"----------- Evaluating User Defined Properties -----------\r\n");
// Call our node user defined properties evaluator.
// The nodeEnum function will recurse into itself and
// evaluate each user defined properties
for( idx=0; idx<numChildren; idx++) {
if (ip->GetCancel())
break;
evaluateNodeUserDefinedProperties( ip->GetRootNode()->GetChildNode(idx) );
}
// If some scripts has been added
// we must create a Level
int behCount = VirtoolsContext->GetObjectsCountByClassID( CKCID_BEHAVIOR );
if( behCount ){
// create a level
CKLevel *level = (CKLevel *)VirtoolsContext->CreateObject( CKCID_LEVEL );
CKScene* LevelScene = level->GetLevelScene();
VirtoolsContext->SetCurrentLevel(level);
// add all objects to this level
for( m_VirtoolsObjects->Reset() ; !m_VirtoolsObjects->EndOfList() ; ){
CKObject *tmpObj = m_VirtoolsObjects->GetData( VirtoolsContext );
// if their was already a scene or a level remove it
if (CKIsChildClassOf(tmpObj,CKCID_SCENE) || CKIsChildClassOf(tmpObj,CKCID_LEVEL)) {
m_VirtoolsObjects->RemoveAt();
// if it isn't a level (or scene)
} else {
DWORD SceneFlags = 0;
CKSceneObject* ScnObj = NULL;
// if the object is attached to a scene
if (CKIsChildClassOf(tmpObj,CKCID_SCENEOBJECT)) {
ScnObj = (CKSceneObject*)tmpObj;
CKScene *Scene = ScnObj->GetSceneIn(0);
if (Scene && Scene!=LevelScene) {
// get the scripts activation states
SceneFlags = Scene->GetObjectFlags(ScnObj);
}
}
// add object to the created level
level->AddObject( tmpObj );
if (SceneFlags) {
// put scripts activation states
LevelScene->SetObjectFlags( ScnObj, (CK_SCENEOBJECT_FLAGS)SceneFlags);
}
m_VirtoolsObjects->Next();
}
}
// add the created level to the list of objects to be saved
// only for the web player (because it has no level and it need one)
// but don't save the level if it's supposed to be loaded by some
// application (like Dev) that already has a level (because it won't be loaded).
//
// if we save without level, the scripts activation states will be saved
// into a special chunk
XString fileName = name;
CKPathSplitter splitter( fileName.Str() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -