Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

705 lines
21 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // QC_EyesDlg.cpp : implementation file
  3. //
  4. #include "stdafx.h"
  5. #include <math.h>
  6. #include "QC_Eyes.h"
  7. #include "QC_EyesDlg.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CQC_EyesDlg dialog
  15. CQC_EyesDlg::CQC_EyesDlg(CWnd* pParent /*=NULL*/)
  16. : CDialog(CQC_EyesDlg::IDD, pParent)
  17. {
  18. //{{AFX_DATA_INIT(CQC_EyesDlg)
  19. // NOTE: the ClassWizard will add member initialization here
  20. //}}AFX_DATA_INIT
  21. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  22. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  23. m_pBitmapHead = NULL;
  24. }
  25. void CQC_EyesDlg::DoDataExchange(CDataExchange* pDX)
  26. {
  27. CDialog::DoDataExchange(pDX);
  28. //{{AFX_DATA_MAP(CQC_EyesDlg)
  29. DDX_Control(pDX, IDC_LEFT_LID_CONTROL, m_IndependentLeftLidControl);
  30. DDX_Control(pDX, IDC_PICTURES, m_PictureControl);
  31. //}}AFX_DATA_MAP
  32. }
  33. BEGIN_MESSAGE_MAP(CQC_EyesDlg, CDialog)
  34. //{{AFX_MSG_MAP(CQC_EyesDlg)
  35. ON_WM_PAINT()
  36. ON_WM_QUERYDRAGICON()
  37. ON_BN_CLICKED(IDC_CREATE_QC_TEXT, OnCreateQcText)
  38. ON_BN_CLICKED(IDC_IRIS_COLOR_BROWN, OnIrisColorBrown)
  39. ON_BN_CLICKED(IDC_IRIS_COLOR_GREEN, OnIrisColorGreen)
  40. ON_BN_CLICKED(IDC_IRIS_COLOR_BLUE, OnIrisColorBlue)
  41. ON_BN_CLICKED(IDC_EYE_COLOR_DARK, OnEyeColorDark)
  42. ON_BN_CLICKED(IDC_EYE_COLOR_LIGHT, OnEyeColorLight)
  43. ON_EN_SETFOCUS(IDC_RIGHT_EYE_X, OnSetfocusRightEyeX)
  44. ON_EN_SETFOCUS(IDC_RIGHT_EYE_Y, OnSetfocusRightEyeY)
  45. ON_EN_SETFOCUS(IDC_RIGHT_EYE_Z, OnSetfocusRightEyeZ)
  46. ON_EN_SETFOCUS(IDC_LEFT_EYE_X, OnSetfocusLeftEyeX)
  47. ON_EN_SETFOCUS(IDC_LEFT_EYE_Y, OnSetfocusLeftEyeY)
  48. ON_EN_SETFOCUS(IDC_LEFT_EYE_Z, OnSetfocusLeftEyeZ)
  49. ON_EN_SETFOCUS(IDC_UPPER_LID_LOWERED, OnSetfocusUpperLidLowered)
  50. ON_EN_SETFOCUS(IDC_UPPER_LID_NEUTRAL, OnSetfocusUpperLidNeutral)
  51. ON_EN_SETFOCUS(IDC_UPPER_LID_RAISED, OnSetfocusUpperLidRaised)
  52. ON_EN_SETFOCUS(IDC_LOWER_LID_LOWERED, OnSetfocusLowerLidLowered)
  53. ON_EN_SETFOCUS(IDC_LOWER_LID_NEUTRAL, OnSetfocusLowerLidNeutral)
  54. ON_EN_SETFOCUS(IDC_LOWER_LID_RAISED, OnSetfocusLowerLidRaised)
  55. ON_BN_CLICKED(IDC_COPY_TEXT_TO_CLIPBOARD, OnCopyTextToClipboard)
  56. ON_BN_CLICKED(IDC_DEFAULT_CONTROLS, OnDefaultControls)
  57. ON_BN_CLICKED(IDC_ADVANCED_CONTROLS, OnAdvancedControls)
  58. ON_BN_CLICKED(IDC_LEFT_LID_CONTROL, OnLeftLidControl)
  59. //}}AFX_MSG_MAP
  60. END_MESSAGE_MAP()
  61. void CQC_EyesDlg::AddText( const char *pFormat, ... )
  62. {
  63. char tempMsg[4096];
  64. va_list marker;
  65. va_start( marker, pFormat );
  66. _vsnprintf( tempMsg, sizeof( tempMsg ), pFormat, marker );
  67. tempMsg[ ARRAYSIZE(tempMsg) - 1 ] = 0;
  68. va_end( marker );
  69. size_t nCharsInBuf = strlen( m_Buf );
  70. size_t nCharsInMsg = strlen( tempMsg );
  71. if ( nCharsInBuf + nCharsInMsg + 1 > m_BufSize )
  72. {
  73. m_BufSize = nCharsInBuf + nCharsInMsg + 4096;
  74. char *newbuf = new char[m_BufSize];
  75. memcpy( newbuf, m_Buf, nCharsInBuf + 1 );
  76. delete [] m_Buf;
  77. m_Buf = newbuf;
  78. }
  79. strcat( m_Buf, tempMsg );
  80. }
  81. void SendToEditControl( HWND hEditControl, const char *pText )
  82. {
  83. LRESULT nLen = SendMessage( hEditControl, EM_GETLIMITTEXT, 0, 0 );
  84. SendMessage( hEditControl, EM_SETSEL, nLen, nLen );
  85. SendMessage( hEditControl, EM_REPLACESEL, FALSE, (LPARAM)pText );
  86. }
  87. void FormatAndSendToEditControl( void *hWnd, const char *pText )
  88. {
  89. HWND hEditControl = (HWND)hWnd;
  90. // Translate \n to \r\n.
  91. char outMsg[1024];
  92. const char *pIn = pText;
  93. char *pOut = outMsg;
  94. while ( *pIn )
  95. {
  96. if ( *pIn == '\n' )
  97. {
  98. *pOut = '\r';
  99. pOut++;
  100. }
  101. *pOut = *pIn;
  102. ++pIn;
  103. ++pOut;
  104. if ( pOut - outMsg >= 1020 )
  105. {
  106. *pOut = 0;
  107. SendToEditControl( hEditControl, outMsg );
  108. pOut = outMsg;
  109. }
  110. }
  111. *pOut = 0;
  112. SendToEditControl( hEditControl, outMsg );
  113. }
  114. HBITMAP CQC_EyesDlg::GetCachedBitmap( UINT id )
  115. {
  116. for ( CBitmapRef *pCur=m_pBitmapHead; pCur; pCur=pCur->m_pNext )
  117. {
  118. if ( pCur->m_iResource == id )
  119. return pCur->m_hBitmap;
  120. }
  121. CBitmapRef *pNew = new CBitmapRef;
  122. pNew->m_iResource = id;
  123. pNew->m_hBitmap = ::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(id) );
  124. pNew->m_pNext = m_pBitmapHead;
  125. m_pBitmapHead = pNew;
  126. return pNew->m_hBitmap;
  127. }
  128. /////////////////////////////////////////////////////////////////////////////
  129. // CQC_EyesDlg message handlers
  130. BOOL CQC_EyesDlg::OnInitDialog()
  131. {
  132. CDialog::OnInitDialog();
  133. // Set the icon for this dialog. The framework does this automatically
  134. // when the application's main window is not a dialog
  135. SetIcon(m_hIcon, TRUE); // Set big icon
  136. SetIcon(m_hIcon, FALSE); // Set small icon
  137. // TODO: Add extra initialization here
  138. GetDlgItem( IDC_REFERENCE_FILENAME )->SetWindowText( "filename_reference" );
  139. GetDlgItem( IDC_EXPRESSIONS_FILENAME )->SetWindowText( "filename_expressions" );
  140. GetDlgItem( IDC_MODEL_FILENAME )->SetWindowText( "filename_model" );
  141. GetDlgItem( IDC_IRIS_SIZE )->SetWindowText( "0.63" );
  142. GetDlgItem( IDC_EYEBALL_SIZE )->SetWindowText( "1.0" );
  143. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_Y_AXIS_UP ), BM_SETCHECK, BST_CHECKED, 0 );
  144. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_DEFAULT_CONTROLS ), BM_SETCHECK, BST_CHECKED, 0 );
  145. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_BROWN ), BM_SETCHECK, BST_CHECKED, 0 );
  146. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_EYE_COLOR_LIGHT ), BM_SETCHECK, BST_CHECKED, 0 );
  147. m_hOutputText = ::GetDlgItem( m_hWnd, IDC_OUTPUT_TEXT );
  148. m_PictureControl.SetBitmap( GetCachedBitmap( IDB_EYE_DEFAULT ) );
  149. OnDefaultControls(); // Hide the advanced controls.
  150. return TRUE; // return TRUE unless you set the focus to a control
  151. }
  152. // If you add a minimize button to your dialog, you will need the code below
  153. // to draw the icon. For MFC applications using the document/view model,
  154. // this is automatically done for you by the framework.
  155. void CQC_EyesDlg::OnPaint()
  156. {
  157. if (IsIconic())
  158. {
  159. CPaintDC dc(this); // device context for painting
  160. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  161. // Center icon in client rectangle
  162. int cxIcon = GetSystemMetrics(SM_CXICON);
  163. int cyIcon = GetSystemMetrics(SM_CYICON);
  164. CRect rect;
  165. GetClientRect(&rect);
  166. int x = (rect.Width() - cxIcon + 1) / 2;
  167. int y = (rect.Height() - cyIcon + 1) / 2;
  168. // Draw the icon
  169. dc.DrawIcon(x, y, m_hIcon);
  170. }
  171. else
  172. {
  173. CDialog::OnPaint();
  174. }
  175. }
  176. // The system calls this to obtain the cursor to display while the user drags
  177. // the minimized window.
  178. HCURSOR CQC_EyesDlg::OnQueryDragIcon()
  179. {
  180. return (HCURSOR) m_hIcon;
  181. }
  182. void HandleYAxisUp( float &yVal, float &zVal )
  183. {
  184. float flTemp = yVal;
  185. yVal = -zVal;
  186. zVal = flTemp;
  187. }
  188. float CQC_EyesDlg::GetDlgItemFloat( UINT id )
  189. {
  190. char text[4096];
  191. GetDlgItemText( id, text, sizeof( text ) );
  192. return (float)atof( text );
  193. }
  194. bool CQC_EyesDlg::IsOptionChecked( UINT option )
  195. {
  196. return (::SendMessage( ::GetDlgItem( m_hWnd, option ), BM_GETCHECK, 0, 0 ) == BST_CHECKED);
  197. }
  198. void CQC_EyesDlg::GetDialogParams( CDialogParams &p )
  199. {
  200. p.m_flLeftEye[0] = GetDlgItemFloat( IDC_LEFT_EYE_X );
  201. p.m_flLeftEye[1] = GetDlgItemFloat( IDC_LEFT_EYE_Y );
  202. p.m_flLeftEye[2] = GetDlgItemFloat( IDC_LEFT_EYE_Z );
  203. p.m_flRightEye[0] = GetDlgItemFloat( IDC_RIGHT_EYE_X );
  204. p.m_flRightEye[1] = GetDlgItemFloat( IDC_RIGHT_EYE_Y );
  205. p.m_flRightEye[2] = GetDlgItemFloat( IDC_RIGHT_EYE_Z );
  206. bool bYAxisUp = IsOptionChecked( IDC_Y_AXIS_UP );
  207. if ( bYAxisUp )
  208. {
  209. HandleYAxisUp( p.m_flLeftEye[1], p.m_flLeftEye[2] );
  210. HandleYAxisUp( p.m_flRightEye[1], p.m_flRightEye[2] );
  211. }
  212. GetDlgItemText( IDC_REFERENCE_FILENAME, p.m_ReferenceFilename, sizeof( p.m_ReferenceFilename ) );
  213. GetDlgItemText( IDC_EXPRESSIONS_FILENAME, p.m_ExpressionsFilename, sizeof( p.m_ExpressionsFilename ) );
  214. GetDlgItemText( IDC_MODEL_FILENAME, p.m_ModelFilename, sizeof( p.m_ModelFilename ) );
  215. p.m_flIrisSize = GetDlgItemFloat( IDC_IRIS_SIZE );
  216. p.m_flEyeballSize = GetDlgItemFloat( IDC_EYEBALL_SIZE );
  217. p.m_flRightUpperLidRaised = GetDlgItemFloat( IDC_UPPER_LID_RAISED );
  218. p.m_flRightUpperLidNeutral = GetDlgItemFloat( IDC_UPPER_LID_NEUTRAL );
  219. p.m_flRightUpperLidLowered = GetDlgItemFloat( IDC_UPPER_LID_LOWERED );
  220. p.m_flRightLowerLidRaised = GetDlgItemFloat( IDC_LOWER_LID_RAISED );
  221. p.m_flRightLowerLidNeutral = GetDlgItemFloat( IDC_LOWER_LID_NEUTRAL );
  222. p.m_flRightLowerLidLowered = GetDlgItemFloat( IDC_LOWER_LID_LOWERED );
  223. if ( IsIndependentLeftLidControlEnabled() )
  224. {
  225. p.m_flLeftUpperLidRaised = GetDlgItemFloat( IDC_UPPER_LEFT_LID_RAISED );
  226. p.m_flLeftUpperLidNeutral = GetDlgItemFloat( IDC_UPPER_LEFT_LID_NEUTRAL );
  227. p.m_flLeftUpperLidLowered = GetDlgItemFloat( IDC_UPPER_LEFT_LID_LOWERED );
  228. p.m_flLeftLowerLidRaised = GetDlgItemFloat( IDC_LOWER_LEFT_LID_RAISED );
  229. p.m_flLeftLowerLidNeutral = GetDlgItemFloat( IDC_LOWER_LEFT_LID_NEUTRAL );
  230. p.m_flLeftLowerLidLowered = GetDlgItemFloat( IDC_LOWER_LEFT_LID_LOWERED );
  231. }
  232. else
  233. {
  234. // Left lids follow the right lids.
  235. p.m_flLeftUpperLidRaised = p.m_flRightUpperLidRaised;
  236. p.m_flLeftUpperLidNeutral = p.m_flRightUpperLidNeutral;
  237. p.m_flLeftUpperLidLowered = p.m_flRightUpperLidLowered;
  238. p.m_flLeftLowerLidRaised = p.m_flRightLowerLidRaised;
  239. p.m_flLeftLowerLidNeutral = p.m_flRightLowerLidNeutral;
  240. p.m_flLeftLowerLidLowered = p.m_flRightLowerLidLowered;
  241. }
  242. // Figure out the eyeball prefix.
  243. if ( IsOptionChecked( IDC_EYE_COLOR_LIGHT ) )
  244. strcpy( p.m_EyeballPrefix, "eyeball" );
  245. else
  246. strcpy( p.m_EyeballPrefix, "dark_eyeball" );
  247. // Figure out the pupil prefix.
  248. if ( IsOptionChecked( IDC_IRIS_COLOR_BROWN ) )
  249. strcpy( p.m_PupilPrefix, "pupil" );
  250. else if ( IsOptionChecked( IDC_IRIS_COLOR_GREEN ) )
  251. strcpy( p.m_PupilPrefix, "grn_pupil" );
  252. else
  253. strcpy( p.m_PupilPrefix, "bl_pupil" );
  254. }
  255. void CQC_EyesDlg::GenerateQCText()
  256. {
  257. CDialogParams p;
  258. GetDialogParams( p );
  259. m_BufSize = 16 * 1024;
  260. m_Buf = new char[m_BufSize];
  261. m_Buf[0] = 0;
  262. AddText( "//start eye/face data\n" );
  263. AddText( "$eyeposition 0 0 70\n\n" );
  264. AddText( "//head controllers\n" );
  265. AddText( "$attachment \"eyes\" \"ValveBiped.Bip01_Head1\" %.2f %.2f %.2f absolute\n",
  266. p.m_flLeftEye[0] - ((fabs( p.m_flRightEye[0] ) + p.m_flLeftEye[0]) * 0.5),
  267. (p.m_flLeftEye[1] + p.m_flRightEye[1]) * 0.5,
  268. (p.m_flLeftEye[2] + p.m_flRightEye[2]) * 0.5 );
  269. AddText( "$attachment \"mouth\" \"ValveBiped.Bip01_Head1\" 0.80 -5.80 -0.15 rotate 0 -80 -90\n\n" );
  270. AddText( "$model %s \"%s.smd\" {\n",
  271. p.m_ModelFilename, p.m_ReferenceFilename );
  272. AddText( "\teyeball righteye \"ValveBiped.Bip01_Head1\" %.2f %.2f %.2f \"%s_r\" %.2f 4 \"%s_r\" %.2f\n",
  273. p.m_flRightEye[0],
  274. p.m_flRightEye[1],
  275. p.m_flRightEye[2],
  276. p.m_EyeballPrefix,
  277. p.m_flEyeballSize,
  278. p.m_PupilPrefix,
  279. p.m_flIrisSize );
  280. AddText( "\teyeball lefteye \"ValveBiped.Bip01_Head1\" %.2f %.2f %.2f \"%s_l\" %.2f -4 \"%s_l\" %.2f\n\n",
  281. p.m_flLeftEye[0],
  282. p.m_flLeftEye[1],
  283. p.m_flLeftEye[2],
  284. p.m_EyeballPrefix,
  285. p.m_flEyeballSize,
  286. p.m_PupilPrefix,
  287. p.m_flIrisSize );
  288. AddText( "\teyelid upper_right \"%s\" lowerer 1 %.2f neutral 0 %.2f raiser 2 %.2f split 0.1 eyeball righteye\n",
  289. p.m_ExpressionsFilename,
  290. p.m_flRightUpperLidLowered - p.m_flRightEye[2],
  291. p.m_flRightUpperLidNeutral - p.m_flRightEye[2],
  292. p.m_flRightUpperLidRaised - p.m_flRightEye[2] );
  293. AddText( "\teyelid lower_right \"%s\" lowerer 3 %.2f neutral 0 %.2f raiser 4 %.2f split 0.1 eyeball righteye\n",
  294. p.m_ExpressionsFilename,
  295. p.m_flRightLowerLidLowered - p.m_flRightEye[2],
  296. p.m_flRightLowerLidNeutral - p.m_flRightEye[2],
  297. p.m_flRightLowerLidRaised - p.m_flRightEye[2] );
  298. AddText( "\teyelid upper_left \"%s\" lowerer 1 %.2f neutral 0 %.2f raiser 2 %.2f split -0.1 eyeball lefteye\n",
  299. p.m_ExpressionsFilename,
  300. p.m_flLeftUpperLidLowered - p.m_flLeftEye[2],
  301. p.m_flLeftUpperLidNeutral - p.m_flLeftEye[2],
  302. p.m_flLeftUpperLidRaised - p.m_flLeftEye[2] );
  303. AddText( "\teyelid lower_left \"%s\" lowerer 3 %.2f neutral 0 %.2f raiser 4 %.2f split -0.1 eyeball lefteye\n\n",
  304. p.m_ExpressionsFilename,
  305. p.m_flLeftLowerLidLowered - p.m_flLeftEye[2],
  306. p.m_flLeftLowerLidNeutral - p.m_flLeftEye[2],
  307. p.m_flLeftLowerLidRaised - p.m_flLeftEye[2] );
  308. AddText( "\tmouth 0 \"mouth\" \"ValveBiped.Bip01_Head1\" 0 1 0 // mouth illumination\n" );
  309. AddText( "\tflexfile \"%s\" {\n", p.m_ExpressionsFilename );
  310. AddText( "\t\t$include \"../standardflex_xsi.qci\"\n" );
  311. AddText( "\t}\n" );
  312. AddText( "\t$include \"../facerules_xsi.qci\"\n" );
  313. AddText( "\t$include \"../bodyrules_xsi.qci\"\n" );
  314. AddText( "}\n" );
  315. AddText( "//end eye/face data\n" );
  316. }
  317. bool CQC_EyesDlg::CheckNumericInputs()
  318. {
  319. struct
  320. {
  321. const char *pControlName;
  322. UINT controlID;
  323. }
  324. controls[] =
  325. {
  326. {"Right Eye X", IDC_RIGHT_EYE_X},
  327. {"Right Eye Y", IDC_RIGHT_EYE_Y},
  328. {"Right Eye Z", IDC_RIGHT_EYE_Z},
  329. {"Left Eye X", IDC_LEFT_EYE_X},
  330. {"Left Eye Y", IDC_LEFT_EYE_Y},
  331. {"Left Eye Z", IDC_LEFT_EYE_Z},
  332. {"Upper Lid Raised", IDC_UPPER_LID_RAISED},
  333. {"Upper Lid Neutral", IDC_UPPER_LID_NEUTRAL},
  334. {"Upper Lid Lowered", IDC_UPPER_LID_LOWERED},
  335. {"Lower Lid Raised", IDC_LOWER_LID_RAISED},
  336. {"Lower Lid Neutral", IDC_LOWER_LID_NEUTRAL},
  337. {"Lower Lid Lowered", IDC_LOWER_LID_LOWERED},
  338. {"Upper Left Lid Raised", IDC_UPPER_LEFT_LID_RAISED},
  339. {"Upper Left Lid Neutral", IDC_UPPER_LEFT_LID_NEUTRAL},
  340. {"Upper Left Lid Lowered", IDC_UPPER_LEFT_LID_LOWERED},
  341. {"Lower Left Lid Raised", IDC_LOWER_LEFT_LID_RAISED},
  342. {"Lower Left Lid Neutral", IDC_LOWER_LEFT_LID_NEUTRAL},
  343. {"Lower Left Lid Lowered", IDC_LOWER_LEFT_LID_LOWERED},
  344. {"Iris Size", IDC_IRIS_SIZE},
  345. {"Eyeball Size", IDC_EYEBALL_SIZE}
  346. };
  347. for ( int i=0; i < sizeof( controls ) / sizeof( controls[0] ); i++ )
  348. {
  349. char text[512];
  350. GetDlgItem( controls[i].controlID )->GetWindowText( text, sizeof( text ) );
  351. for ( int z=0; z < (int)strlen( text ); z++ )
  352. {
  353. if ( text[z] < '0' || text[z] > '9' )
  354. {
  355. if ( text[z] != '.' && text[z] != '-' )
  356. {
  357. char errMsg[512];
  358. _snprintf( errMsg, sizeof( errMsg ), "The '%s' control must have a numeric value.", controls[i].pControlName );
  359. AfxMessageBox( errMsg, MB_OK );
  360. return false;
  361. }
  362. }
  363. }
  364. }
  365. return true;
  366. }
  367. void CQC_EyesDlg::OnCreateQcText()
  368. {
  369. if ( !CheckNumericInputs() )
  370. return;
  371. GenerateQCText();
  372. // Clear the edit control.
  373. LRESULT nLen = ::SendMessage( m_hOutputText, EM_GETLIMITTEXT, 0, 0 );
  374. ::SendMessage( m_hOutputText, EM_SETSEL, 0, nLen );
  375. ::SendMessage( m_hOutputText, EM_REPLACESEL, FALSE, (LPARAM)"" );
  376. FormatAndSendToEditControl( m_hOutputText, m_Buf );
  377. delete [] m_Buf;
  378. }
  379. void CQC_EyesDlg::OnIrisColorBrown()
  380. {
  381. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_BROWN ), BM_SETCHECK, BST_CHECKED, 0 );
  382. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_GREEN ), BM_SETCHECK, BST_UNCHECKED, 0 );
  383. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_BLUE ), BM_SETCHECK, BST_UNCHECKED, 0 );
  384. SetupBitmapLabel( IDB_EYE_DEFAULT, "" );
  385. }
  386. void CQC_EyesDlg::OnIrisColorGreen()
  387. {
  388. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_BROWN ), BM_SETCHECK, BST_UNCHECKED, 0 );
  389. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_GREEN ), BM_SETCHECK, BST_CHECKED, 0 );
  390. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_BLUE ), BM_SETCHECK, BST_UNCHECKED, 0 );
  391. SetupBitmapLabel( IDB_EYE_DEFAULT, "" );
  392. }
  393. void CQC_EyesDlg::OnIrisColorBlue()
  394. {
  395. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_BROWN ), BM_SETCHECK, BST_UNCHECKED, 0 );
  396. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_GREEN ), BM_SETCHECK, BST_UNCHECKED, 0 );
  397. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_IRIS_COLOR_BLUE ), BM_SETCHECK, BST_CHECKED, 0 );
  398. SetupBitmapLabel( IDB_EYE_DEFAULT, "" );
  399. }
  400. void CQC_EyesDlg::OnEyeColorDark()
  401. {
  402. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_EYE_COLOR_LIGHT ), BM_SETCHECK, BST_UNCHECKED, 0 );
  403. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_EYE_COLOR_DARK ), BM_SETCHECK, BST_CHECKED, 0 );
  404. SetupBitmapLabel( IDB_EYE_DEFAULT, "" );
  405. }
  406. void CQC_EyesDlg::OnEyeColorLight()
  407. {
  408. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_EYE_COLOR_LIGHT ), BM_SETCHECK, BST_CHECKED, 0 );
  409. ::SendMessage( ::GetDlgItem( m_hWnd, IDC_EYE_COLOR_DARK ), BM_SETCHECK, BST_UNCHECKED, 0 );
  410. SetupBitmapLabel( IDB_EYE_DEFAULT, "" );
  411. }
  412. void CQC_EyesDlg::SetupBitmapLabel( UINT iBitmapResourceID, const char *pString, ... )
  413. {
  414. char msg[4096];
  415. va_list marker;
  416. va_start( marker, pString );
  417. _vsnprintf( msg, sizeof( msg ), pString, marker );
  418. msg[ ARRAYSIZE(msg) - 1 ] = 0;
  419. va_end( marker );
  420. m_PictureControl.SetBitmap( GetCachedBitmap( iBitmapResourceID ) );
  421. GetDlgItem( IDC_PICTURE_LABEL )->SetWindowText( msg );
  422. }
  423. void CQC_EyesDlg::OnSetfocusRightEyeX()
  424. {
  425. SetupBitmapLabel( IDB_EYE_XY_R, "Enter the X position of the center vertex of the right eye" );
  426. }
  427. void CQC_EyesDlg::OnSetfocusRightEyeY()
  428. {
  429. SetupBitmapLabel( IsOptionChecked( IDC_Y_AXIS_UP ) ? IDB_EYE_XY_R : IDB_EYE_Z_R, "Enter the Y position of the center vertex of the right eye" );
  430. }
  431. void CQC_EyesDlg::OnSetfocusRightEyeZ()
  432. {
  433. SetupBitmapLabel( IsOptionChecked( IDC_Y_AXIS_UP ) ? IDB_EYE_Z_R : IDB_EYE_XY_R, "Enter the Z position of the center vertex of the right eye" );
  434. }
  435. void CQC_EyesDlg::OnSetfocusLeftEyeX()
  436. {
  437. SetupBitmapLabel( IDB_EYE_XY_L, "Enter the X position of the center vertex of the right eye" );
  438. }
  439. void CQC_EyesDlg::OnSetfocusLeftEyeY()
  440. {
  441. SetupBitmapLabel( IsOptionChecked( IDC_Y_AXIS_UP ) ? IDB_EYE_XY_L : IDB_EYE_Z_L, "Enter the Y position of the center vertex of the right eye" );
  442. }
  443. void CQC_EyesDlg::OnSetfocusLeftEyeZ()
  444. {
  445. SetupBitmapLabel( IsOptionChecked( IDC_Y_AXIS_UP ) ? IDB_EYE_Z_L : IDB_EYE_XY_L, "Enter the Z position of the center vertex of the right eye" );
  446. }
  447. void CQC_EyesDlg::OnSetfocusUpperLidLowered()
  448. {
  449. const char *pCoord = IsOptionChecked( IDC_Y_AXIS_UP ) ? "Y" : "Z";
  450. SetupBitmapLabel( IDB_EYE_UPPER_LO, "At Frame 1, enter the %s position of the center vertex of the right upper eye lid", pCoord );
  451. }
  452. void CQC_EyesDlg::OnSetfocusUpperLidNeutral()
  453. {
  454. const char *pCoord = IsOptionChecked( IDC_Y_AXIS_UP ) ? "Y" : "Z";
  455. SetupBitmapLabel( IDB_EYE_UPPER_MID, "At Frame 0, enter the %s position of the center vertex of the right upper eye lid", pCoord );
  456. }
  457. void CQC_EyesDlg::OnSetfocusUpperLidRaised()
  458. {
  459. const char *pCoord = IsOptionChecked( IDC_Y_AXIS_UP ) ? "Y" : "Z";
  460. SetupBitmapLabel( IDB_EYE_UPPER_HI, "At Frame 2, enter the %s position of the center vertex of the right upper eye lid", pCoord );
  461. }
  462. void CQC_EyesDlg::OnSetfocusLowerLidLowered()
  463. {
  464. const char *pCoord = IsOptionChecked( IDC_Y_AXIS_UP ) ? "Y" : "Z";
  465. SetupBitmapLabel( IDB_EYE_LOWER_LO, "At Frame 3, enter the %s position of the center vertex of the right lower eye lid", pCoord );
  466. }
  467. void CQC_EyesDlg::OnSetfocusLowerLidNeutral()
  468. {
  469. const char *pCoord = IsOptionChecked( IDC_Y_AXIS_UP ) ? "Y" : "Z";
  470. SetupBitmapLabel( IDB_EYE_LOWER_MID, "At Frame 0, enter the %s position of the center vertex of the right lower eye lid", pCoord );
  471. }
  472. void CQC_EyesDlg::OnSetfocusLowerLidRaised()
  473. {
  474. const char *pCoord = IsOptionChecked( IDC_Y_AXIS_UP ) ? "Y" : "Z";
  475. SetupBitmapLabel( IDB_EYE_LOWER_HI, "At Frame 4, enter the %s position of the center vertex of the right lower eye lid", pCoord );
  476. }
  477. void CQC_EyesDlg::OnCopyTextToClipboard()
  478. {
  479. if ( !CheckNumericInputs() )
  480. return;
  481. GenerateQCText();
  482. if ( !OpenClipboard() )
  483. return;
  484. size_t textLen = strlen( m_Buf );
  485. HANDLE hmem = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, textLen + 1 );
  486. if ( hmem )
  487. {
  488. void *ptr = GlobalLock( hmem );
  489. if ( ptr )
  490. {
  491. memcpy( ptr, m_Buf, textLen+1 );
  492. GlobalUnlock( hmem );
  493. SetClipboardData( CF_TEXT, hmem );
  494. }
  495. }
  496. CloseClipboard();
  497. delete [] m_Buf;
  498. }
  499. int g_AdvancedControls[] =
  500. {
  501. IDC_EYE_DETAIL_CONTROL_FRAME,
  502. IDC_IRIS_SIZE,
  503. IDC_IRIS_SIZE_LABEL,
  504. IDC_EYEBALL_SIZE,
  505. IDC_EYEBALL_SIZE_LABEL,
  506. IDC_LEFT_LID_CONTROL
  507. };
  508. #define NUM_ADVANCED_CONTROLS ( sizeof( g_AdvancedControls ) / sizeof( g_AdvancedControls[0] ) )
  509. int g_LeftLidPositionControls[] =
  510. {
  511. IDC_UPPER_LEFT_LID_PANEL,
  512. IDC_UPPER_LEFT_LID_RAISED,
  513. IDC_UPPER_LEFT_LID_RAISED_LABEL,
  514. IDC_UPPER_LEFT_LID_NEUTRAL,
  515. IDC_UPPER_LEFT_LID_NEUTRAL_LABEL,
  516. IDC_UPPER_LEFT_LID_LOWERED,
  517. IDC_UPPER_LEFT_LID_LOWERED_LABEL,
  518. IDC_LOWER_LEFT_LID_PANEL,
  519. IDC_LOWER_LEFT_LID_RAISED,
  520. IDC_LOWER_LEFT_LID_RAISED_LABEL,
  521. IDC_LOWER_LEFT_LID_NEUTRAL,
  522. IDC_LOWER_LEFT_LID_NEUTRAL_LABEL,
  523. IDC_LOWER_LEFT_LID_LOWERED,
  524. IDC_LOWER_LEFT_LID_LOWERED_LABEL
  525. };
  526. #define NUM_LEFT_LID_POSITION_CONTROLS ( sizeof( g_LeftLidPositionControls ) / sizeof( g_LeftLidPositionControls[0] ) )
  527. void CQC_EyesDlg::OnDefaultControls()
  528. {
  529. GetDlgItem( IDC_PICTURES )->ShowWindow( SW_SHOW );
  530. // Hide all the advanced controls.
  531. for ( int i=0; i < NUM_ADVANCED_CONTROLS; i++ )
  532. {
  533. GetDlgItem( g_AdvancedControls[i] )->ShowWindow( SW_HIDE );
  534. }
  535. for ( int i=0; i < NUM_LEFT_LID_POSITION_CONTROLS; i++ )
  536. {
  537. GetDlgItem( g_LeftLidPositionControls[i] )->ShowWindow( SW_HIDE );
  538. }
  539. }
  540. void CQC_EyesDlg::OnAdvancedControls()
  541. {
  542. GetDlgItem( IDC_PICTURES )->ShowWindow( SW_HIDE );
  543. // Show the advanced controls.
  544. for ( int i=0; i < NUM_ADVANCED_CONTROLS; i++ )
  545. {
  546. GetDlgItem( g_AdvancedControls[i] )->ShowWindow( SW_SHOW );
  547. GetDlgItem( g_AdvancedControls[i] )->InvalidateRect( NULL );
  548. }
  549. if ( IsIndependentLeftLidControlEnabled() )
  550. {
  551. OnLeftLidControl();
  552. }
  553. }
  554. bool CQC_EyesDlg::IsIndependentLeftLidControlEnabled()
  555. {
  556. return m_IndependentLeftLidControl.GetCheck() == 1;
  557. }
  558. void CQC_EyesDlg::OnLeftLidControl()
  559. {
  560. if ( IsIndependentLeftLidControlEnabled() )
  561. {
  562. for ( int i=0; i < NUM_LEFT_LID_POSITION_CONTROLS; i++ )
  563. {
  564. GetDlgItem( g_LeftLidPositionControls[i] )->ShowWindow( SW_SHOW );
  565. GetDlgItem( g_LeftLidPositionControls[i] )->InvalidateRect( NULL );
  566. }
  567. }
  568. else
  569. {
  570. for ( int i=0; i < NUM_LEFT_LID_POSITION_CONTROLS; i++ )
  571. {
  572. GetDlgItem( g_LeftLidPositionControls[i] )->ShowWindow( SW_HIDE );
  573. GetDlgItem( g_LeftLidPositionControls[i] )->InvalidateRect( NULL );
  574. }
  575. }
  576. }