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

📄 mdlviewer.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
//                 Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file:           mdlviewer.cpp
// last modified:  Jun 03 1999, Mete Ciragan
// copyright:      The programs and associated files contained in this
//                 distribution were developed by Mete Ciragan. The programs
//                 are not in the public domain, but they are freely
//                 distributable without licensing fees. These programs are
//                 provided without guarantee or warrantee expressed or
//                 implied.
//
// version:        1.2
//
// email:          mete@swissquake.ch
// web:            http://www.swissquake.ch/chumbalum-soft/
//
#include "cbase.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mx/mx.h>
#include <mx/mxTga.h>
#include <mx/mxEvent.h>
#include "mdlviewer.h"
#include "ViewerSettings.h"
#include "MatSysWin.h"
#include "ControlPanel.h"
#include "FlexPanel.h"
#include "StudioModel.h"
#include "cmdlib.h"
#include "mxExpressionTray.h"
#include "mxStatusWindow.h"
#include "ChoreoView.h"
#include "ifaceposersound.h"
#include "ifaceposerworkspace.h"
#include "expclass.h"
#include "PhonemeEditor.h"
#include "FileSystem.h"
#include "FileSystem_Tools.h"
#include "ExpressionTool.h"
#include "ControlPanel.h"
#include "choreowidgetdrawhelper.h"
#include "choreoviewcolors.h"
#include "tabwindow.h"
#include "faceposer_models.h"
#include "choiceproperties.h"
#include "choreoscene.h"
#include "choreoactor.h"
#include "vstdlib/strtools.h"
#include "InputProperties.h"
#include "GestureTool.h"
#include "SoundEmitterSystemBase.h"
#include "RampTool.h"
#include "SceneRampTool.h"
#include "vstdlib/icommandline.h"
#include "phonemeextractor.h"

#define WINDOW_TAB_OFFSET 24

MDLViewer *g_MDLViewer = 0;
char g_appTitle[] = "Half-Life Face Poser";
static char recentFiles[8][256] = { "", "", "", "", "", "", "", "" };

void
MDLViewer::initRecentFiles ()
{
	for (int i = 0; i < 8; i++)
	{
		if (strlen (recentFiles[i]))
		{
			mb->modify (IDC_FILE_RECENTMODELS1 + i, IDC_FILE_RECENTMODELS1 + i, recentFiles[i]);
		}
		else
		{
			mb->modify (IDC_FILE_RECENTMODELS1 + i, IDC_FILE_RECENTMODELS1 + i, "(empty)");
			mb->setEnabled (IDC_FILE_RECENTMODELS1 + i, false);
		}
	}
}



void
MDLViewer::loadRecentFiles ()
{
	char path[256];
	strcpy (path, mx::getApplicationPath ());
	strcat (path, "/hlmv.rf");
	FILE *file = fopen (path, "rb");
	if (file)
	{
		fread (recentFiles, sizeof recentFiles, 1, file);
		fclose (file);
	}
}



void
MDLViewer::saveRecentFiles ()
{
	char path[256];

	strcpy (path, mx::getApplicationPath ());
	strcat (path, "/hlmv.rf");

	FILE *file = fopen (path, "wb");
	if (file)
	{
		fwrite (recentFiles, sizeof recentFiles, 1, file);
		fclose (file);
	}
}

bool MDLViewer::Closing( void )
{
	Con_Printf( "Checking for sound script changes...\n" );

	// Save any changed sound script files
	int c = soundemitter->GetNumSoundScripts();
	for ( int i = 0; i < c; i++ )
	{
		if ( !soundemitter->IsSoundScriptDirty( i ) )
			continue;

		char const *scriptname = soundemitter->GetSoundScriptName( i );
		if ( !scriptname )
			continue;

		if ( !filesystem->FileExists( scriptname ) ||
			 !filesystem->IsFileWritable( scriptname ) )
		{
			continue;
		}

		soundemitter->SaveChangesToSoundScript( i );
	}

	SaveWindowPositions();

	models->SaveModelList();
	models->CloseAllModels();

	return true;
}

#define IDC_GRIDSETTINGS_FPS	1001
#define IDC_GRIDSETTINGS_SNAP	1002

class CFlatButton : public mxButton
{
public:
	CFlatButton( mxWindow *parent, int id )
		: mxButton( parent, 0, 0, 0, 0, "", id )
	{
		HWND wnd = (HWND)getHandle();
		DWORD exstyle = GetWindowLong( wnd, GWL_EXSTYLE );
		exstyle |= WS_EX_CLIENTEDGE;
		SetWindowLong( wnd, GWL_EXSTYLE, exstyle );

		DWORD style = GetWindowLong( wnd, GWL_STYLE );
		style &= ~WS_BORDER;
		SetWindowLong( wnd, GWL_STYLE, style );

	}
};

class CMDLViewerGridSettings : public mxWindow
{
public:
	typedef mxWindow BaseClass;

	CMDLViewerGridSettings( mxWindow *parent, int x, int y, int w, int h ) :
		mxWindow( parent, x, y, w, h )
	{
		FacePoser_AddWindowStyle( this, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
		m_btnFPS = new CFlatButton( this, IDC_GRIDSETTINGS_FPS );
		m_btnGridSnap = new CFlatButton( this, IDC_GRIDSETTINGS_SNAP );

	}

	void Init( void )
	{
		if ( g_pChoreoView )
		{
			CChoreoScene *scene = g_pChoreoView->GetScene();
			if ( scene )
			{
				char sz[ 256 ];
				Q_snprintf( sz, sizeof( sz ), "%i fps", scene->GetSceneFPS() );
				m_btnFPS->setLabel( sz );

				Q_snprintf( sz, sizeof( sz ), "snap: %s", scene->IsUsingFrameSnap() ? "on" : "off" );
				m_btnGridSnap->setLabel( sz );

				m_btnFPS->setVisible( true );
				m_btnGridSnap->setVisible( true );
				return;
			}
		}
		
		m_btnFPS->setVisible( false );
		m_btnGridSnap->setVisible( false );
	}

	virtual int handleEvent( mxEvent *event )
	{
		int iret = 0;
		switch ( event->event )
		{
		default:
			break;
		case mxEvent::Size:
			{
				int leftedge = w2() * 0.45f;
				m_btnFPS->setBounds( 0, 0, leftedge, h2() );
				m_btnGridSnap->setBounds( leftedge, 0, w2() - leftedge, h2() );
				iret = 1;
			}
			break;
		case mxEvent::Action:
			{
				iret = 1;
				switch ( event->action )
				{
				default:
					iret = 0;
					break;
				case IDC_GRIDSETTINGS_FPS:
					{
						if ( g_pChoreoView )
						{
							CChoreoScene *scene = g_pChoreoView->GetScene();
							if ( scene )
							{
								int currentFPS = scene->GetSceneFPS();
								
								CInputParams params;
								memset( &params, 0, sizeof( params ) );
								
								strcpy( params.m_szDialogTitle, "Change FPS" );
								
								Q_snprintf( params.m_szInputText, sizeof( params.m_szInputText ),
									"%i", currentFPS );
								
								strcpy( params.m_szPrompt, "Current FPS:" );
								
								if ( InputProperties( &params ) )
								{
									int newFPS = atoi( params.m_szInputText );
									
									if ( ( newFPS > 0 ) && ( newFPS != currentFPS ) )
									{
										g_pChoreoView->SetDirty( true );
										g_pChoreoView->PushUndo( "Change Scene FPS" );
										scene->SetSceneFPS( newFPS );
										g_pChoreoView->PushRedo( "Change Scene FPS" );
										Init();

										Con_Printf( "FPS changed to %i\n", newFPS );
									}
								}
								
							}
						}
					}
					break;
				case IDC_GRIDSETTINGS_SNAP:
					{
						if ( g_pChoreoView )
						{
							CChoreoScene *scene = g_pChoreoView->GetScene();
							if ( scene )
							{
								g_pChoreoView->SetDirty( true );
								g_pChoreoView->PushUndo( "Change Snap Frame" );
								
								scene->SetUsingFrameSnap( !scene->IsUsingFrameSnap() );
								
								g_pChoreoView->PushRedo( "Change Snap Frame" );
								
								Init();

								Con_Printf( "Time frame snapping: %s\n",
									scene->IsUsingFrameSnap() ? "on" : "off" );
							}
						}


					}
					break;
				}
			}
		}
		return iret;
	}

	bool PaintBackground( void )
	{
		CChoreoWidgetDrawHelper drawHelper( this );
		RECT rc;
		drawHelper.GetClientRect( rc );
		drawHelper.DrawFilledRect( GetSysColor( COLOR_BTNFACE ), rc );
		return false;
	}
	
private:

	CFlatButton	*m_btnFPS;
	CFlatButton	*m_btnGridSnap;
};

#define IDC_MODELTAB_LOAD			1000
#define IDC_MODELTAB_CLOSE			1001
#define IDC_MODELTAB_CLOSEALL		1002
#define IDC_MODELTAB_CENTERONFACE	1003
#define IDC_MODELTAB_ASSOCIATEACTOR 1004
#define IDC_MODELTAB_TOGGLE3DVIEW	1005
#define IDC_MODELTAB_SHOWALL		1006
#define IDC_MODELTAB_HIDEALL		1007
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
class CMDLViewerModelTab : public CTabWindow
{
public:
	typedef CTabWindow BaseClass;

	CMDLViewerModelTab( mxWindow *parent, int x, int y, int w, int h, int id = 0, int style = 0 ) :
		CTabWindow( parent, x, y, w, h, id, style )
	{
		SetInverted( true );
	}

	virtual void ShowRightClickMenu( int mx, int my )
	{
		mxPopupMenu *pop = new mxPopupMenu();
		Assert( pop );

		char const *current = "";
		char const *filename = "";
		int idx = getSelectedIndex();
		if ( idx >= 0 )
		{
			current = models->GetModelName( idx );
			filename = models->GetModelFileName( idx );
		}

		if ( models->Count() < MAX_FP_MODELS )
		{
			pop->add( "Load Model...", IDC_MODELTAB_LOAD );
		}
		if ( idx >= 0 )
		{
			pop->add( va( "Close '%s'", current ), IDC_MODELTAB_CLOSE );
		}
		if ( models->Count() > 0 )
		{
			pop->add( "Close All", IDC_MODELTAB_CLOSEALL );
		}
		if ( idx >= 0 )
		{
			pop->addSeparator();
			pop->add( va( "Center %s's face", current ), IDC_MODELTAB_CENTERONFACE );

			CChoreoScene *scene = g_pChoreoView->GetScene();
			if ( scene )
			{
				// See if there is already an actor with this model associated
				int c = scene->GetNumActors();
				bool hasassoc = false;
				for ( int i = 0; i < c; i++ )
				{
					CChoreoActor *a = scene->GetActor( i );
					Assert( a );
				
					if ( stricmp( a->GetFacePoserModelName(), filename ) )
						continue;
					hasassoc = true;
					break;
				}

				if ( hasassoc )
				{
					pop->add( va( "Change associated actor for %s", current ), IDC_MODELTAB_ASSOCIATEACTOR );
				}
				else
				{
					pop->add( va( "Associate actor to %s", current ), IDC_MODELTAB_ASSOCIATEACTOR );
				}
			}

			pop->addSeparator();

			bool visible = models->IsModelShownIn3DView( idx );
			if ( visible )
			{
				pop->add( va( "Remove %s from 3D View", current ), IDC_MODELTAB_TOGGLE3DVIEW );
			}
			else
			{
				pop->add( va( "Show %s in 3D View", current ), IDC_MODELTAB_TOGGLE3DVIEW );
			}
		}
		if ( models->Count() > 0 )
		{
			pop->addSeparator();
			pop->add( "Show All", IDC_MODELTAB_SHOWALL );
			pop->add( "Hide All", IDC_MODELTAB_HIDEALL );
		}

		// Convert click position
		POINT pt;
		pt.x = mx;
		pt.y = my;

		// Convert coordinate space
		pop->popup( this, pt.x, pt.y );
	}

	virtual int handleEvent( mxEvent *event )
	{
		int iret = 0;
		switch ( event->event )
		{
		default:
			break;
		case mxEvent::Action:
			{
				iret = 1;
				switch ( event->action )
				{
				default:
					iret = 0;
					break;
				case IDC_MODELTAB_SHOWALL:
				case IDC_MODELTAB_HIDEALL:
					{
						bool show = ( event->action == IDC_MODELTAB_SHOWALL ) ? true : false;
						int c = models->Count();
						for ( int i = 0; i < c ; i++ )
						{
							models->ShowModelIn3DView( i, show );
						}
					}
					break;
				case IDC_MODELTAB_LOAD:
					{
						const char *ptr = mxGetOpenFileName(
							this, 
							FacePoser_MakeWindowsSlashes( va( "%s/models/", GetGameDirectory() ) ), 
							"*.mdl" );

						if (ptr)
						{
							g_MDLViewer->LoadModelFile( ptr );
						}
					}
					break;
				case IDC_MODELTAB_CLOSE:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							models->FreeModel( idx );
						}
					}
					break;
				case IDC_MODELTAB_CLOSEALL:
					{
						models->CloseAllModels();
					}
					break;
				case IDC_MODELTAB_CENTERONFACE:
					{
						g_pControlPanel->CenterOnFace();
					}
					break;
				case IDC_MODELTAB_TOGGLE3DVIEW:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							bool visible = models->IsModelShownIn3DView( idx );
							models->ShowModelIn3DView( idx, !visible );
						}
					}
					break;
				case IDC_MODELTAB_ASSOCIATEACTOR:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							char const *modelname = models->GetModelFileName( idx );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -