⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 max2nmo.cpp

📁 3dmax导出3d模型二次开发插件
💻 CPP
📖 第 1 页 / 共 3 页
字号:

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 + -