Counter Strike : Global Offensive Source Code
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.

471 lines
14 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "attachments_window.h"
  7. #include "ControlPanel.h"
  8. #include "ViewerSettings.h"
  9. #include "StudioModel.h"
  10. #include "MatSysWin.h"
  11. #define IDC_ATTACHMENT_LIST (IDC_ATTACHMENT_WINDOW_FIRST+0)
  12. #define IDC_ATTACHMENT_LIST_BONES (IDC_ATTACHMENT_WINDOW_FIRST+1)
  13. #define IDC_ATTACHMENT_TRANSLATION (IDC_ATTACHMENT_WINDOW_FIRST+2)
  14. #define IDC_ATTACHMENT_ROTATION (IDC_ATTACHMENT_WINDOW_FIRST+3)
  15. #define IDC_ATTACHMENT_QC_STRING (IDC_ATTACHMENT_WINDOW_FIRST+4)
  16. #define IDC_ATTACHMENT_NUDGE (IDC_ATTACHMENT_WINDOW_FIRST+5)
  17. CAttachmentsWindow::CAttachmentsWindow( ControlPanel* pParent ) : mxWindow( pParent, 0, 0, 0, 0 )
  18. {
  19. m_pControlPanel = pParent;
  20. g_viewerSettings.m_iEditAttachment = -1;
  21. }
  22. void CAttachmentsWindow::Init( )
  23. {
  24. int left, top;
  25. left = 5;
  26. top = 0;
  27. // Attachment selection list
  28. new mxLabel( this, left + 3, top + 4, 60, 18, "Attachment" );
  29. m_cAttachmentList = new mxListBox( this, left, top + 20, 260, 100, IDC_ATTACHMENT_LIST );
  30. m_cAttachmentList->add ("None");
  31. m_cAttachmentList->select (0);
  32. mxToolTip::add (m_cAttachmentList, "Select an attachment to modify");
  33. left = 280;
  34. new mxLabel( this, left + 3, top + 4, 60, 18, "Attach To Bone" );
  35. m_cBoneList = new mxListBox( this, left, top + 20, 260, 100, IDC_ATTACHMENT_LIST_BONES );
  36. m_cBoneList->add ("None");
  37. m_cBoneList->select( 0 );
  38. mxToolTip::add( m_cBoneList, "Select a bone to attach to" );
  39. left = 5;
  40. top = 120;
  41. new mxLabel( this, left + 3, top + 4, 60, 18, "Translation" );
  42. m_cTranslation = new mxLineEdit2( this, left + 70, top, 90, 25, "10 20 30", IDC_ATTACHMENT_TRANSLATION );
  43. left = 170;
  44. top = 120;
  45. new mxLabel( this, left + 3, top + 4, 60, 18, "Rotation" );
  46. m_cRotation = new mxLineEdit2( this, left + 70, top, 90, 25, "0 90 180", IDC_ATTACHMENT_ROTATION );
  47. top = 145;
  48. left = 5;
  49. new mxLabel( this, left, top, 60, 18, "QC String" );
  50. m_cQCString = new mxLineEdit2( this, left + 70, top, 400, 25, "$attachment \"controlpanel0_ur\" \"Vgui\" -22 -15 4 rotate 0 0 0", IDC_ATTACHMENT_QC_STRING );
  51. top = 5;
  52. left = 550;
  53. m_bTranslateXLargeMinus = new mxButton( this, left, top, 30, 20, "-X", IDC_ATTACHMENT_NUDGE );
  54. m_bTranslateXSmallMinus = new mxButton( this, left+30, top, 30, 20, "-x", IDC_ATTACHMENT_NUDGE );
  55. m_bTranslateXSmallPlus = new mxButton( this, left+70, top, 30, 20, "+x", IDC_ATTACHMENT_NUDGE );
  56. m_bTranslateXLargePlus = new mxButton( this, left+100, top, 30, 20, "+X", IDC_ATTACHMENT_NUDGE );
  57. top += 20;
  58. m_bTranslateYLargeMinus = new mxButton( this, left, top, 30, 20, "-Y", IDC_ATTACHMENT_NUDGE );
  59. m_bTranslateYSmallMinus = new mxButton( this, left+30, top, 30, 20, "-y", IDC_ATTACHMENT_NUDGE );
  60. m_bTranslateYSmallPlus = new mxButton( this, left+70, top, 30, 20, "+y", IDC_ATTACHMENT_NUDGE );
  61. m_bTranslateYLargePlus = new mxButton( this, left+100, top, 30, 20, "+Y", IDC_ATTACHMENT_NUDGE );
  62. top += 20;
  63. m_bTranslateZLargeMinus = new mxButton( this, left, top, 30, 20, "-Z", IDC_ATTACHMENT_NUDGE );
  64. m_bTranslateZSmallMinus = new mxButton( this, left+30, top, 30, 20, "-z", IDC_ATTACHMENT_NUDGE );
  65. m_bTranslateZSmallPlus = new mxButton( this, left+70, top, 30, 20, "+z", IDC_ATTACHMENT_NUDGE );
  66. m_bTranslateZLargePlus = new mxButton( this, left+100, top, 30, 20, "+Z", IDC_ATTACHMENT_NUDGE );
  67. top += 30;
  68. m_bRotateXLargeMinus = new mxButton( this, left, top, 30, 20, "-XR", IDC_ATTACHMENT_NUDGE );
  69. m_bRotateXSmallMinus = new mxButton( this, left+30, top, 30, 20, "-xr", IDC_ATTACHMENT_NUDGE );
  70. m_bRotateXSmallPlus = new mxButton( this, left+70, top, 30, 20, "+xr", IDC_ATTACHMENT_NUDGE );
  71. m_bRotateXLargePlus = new mxButton( this, left+100, top, 30, 20, "+XR", IDC_ATTACHMENT_NUDGE );
  72. top += 20;
  73. m_bRotateYLargeMinus = new mxButton( this, left, top, 30, 20, "-YR", IDC_ATTACHMENT_NUDGE );
  74. m_bRotateYSmallMinus = new mxButton( this, left+30, top, 30, 20, "-yr", IDC_ATTACHMENT_NUDGE );
  75. m_bRotateYSmallPlus = new mxButton( this, left+70, top, 30, 20, "+yr", IDC_ATTACHMENT_NUDGE );
  76. m_bRotateYLargePlus = new mxButton( this, left+100, top, 30, 20, "+YR", IDC_ATTACHMENT_NUDGE );
  77. top += 20;
  78. m_bRotateZLargeMinus = new mxButton( this, left, top, 30, 20, "-ZR", IDC_ATTACHMENT_NUDGE );
  79. m_bRotateZSmallMinus = new mxButton( this, left+30, top, 30, 20, "-zr", IDC_ATTACHMENT_NUDGE );
  80. m_bRotateZSmallPlus = new mxButton( this, left+70, top, 30, 20, "+zr", IDC_ATTACHMENT_NUDGE );
  81. m_bRotateZLargePlus = new mxButton( this, left+100, top, 30, 20, "+ZR", IDC_ATTACHMENT_NUDGE );
  82. }
  83. void CAttachmentsWindow::OnLoadModel()
  84. {
  85. int iPrevEdit = g_viewerSettings.m_iEditAttachment;
  86. PopulateBoneList();
  87. PopulateAttachmentsList();
  88. if ( iPrevEdit >= 0 && iPrevEdit < m_cAttachmentList->getItemCount())
  89. {
  90. m_cAttachmentList->select( iPrevEdit + 1 );
  91. }
  92. g_viewerSettings.m_iEditAttachment = iPrevEdit;
  93. UpdateStrings();
  94. }
  95. void CAttachmentsWindow::OnTabSelected()
  96. {
  97. // for now, keep selection
  98. // g_viewerSettings.m_iEditAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  99. }
  100. void CAttachmentsWindow::OnTabUnselected()
  101. {
  102. // for now, keep selection
  103. // g_viewerSettings.m_iEditAttachment = -1;
  104. }
  105. void CAttachmentsWindow::PopulateAttachmentsList()
  106. {
  107. m_cAttachmentList->removeAll();
  108. m_cAttachmentList->add( "(none)" );
  109. if ( g_pStudioModel )
  110. {
  111. CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
  112. if (pHdr->GetNumAttachments())
  113. {
  114. for ( int i = 0; i < pHdr->GetNumAttachments(); i++ )
  115. {
  116. m_cAttachmentList->add ( pHdr->pAttachment(i).pszName() );
  117. }
  118. m_cAttachmentList->select (0);
  119. OnSelChangeAttachmentList();
  120. return;
  121. }
  122. }
  123. m_cAttachmentList->select (0);
  124. }
  125. void CAttachmentsWindow::PopulateBoneList()
  126. {
  127. m_cBoneList->removeAll();
  128. if ( g_pStudioModel )
  129. {
  130. CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
  131. if (pHdr->numbones())
  132. {
  133. for ( int i = 0; i < pHdr->numbones(); i++ )
  134. {
  135. m_cBoneList->add ( pHdr->pBone(i)->pszName() );
  136. }
  137. m_cBoneList->select (0);
  138. return;
  139. }
  140. }
  141. m_cBoneList->add( "None" );
  142. m_cBoneList->select (0);
  143. }
  144. int CAttachmentsWindow::handleEvent (mxEvent *event)
  145. {
  146. MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
  147. if ( !g_pStudioModel )
  148. return 0;
  149. CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
  150. switch( event->action )
  151. {
  152. case IDC_ATTACHMENT_LIST:
  153. {
  154. OnSelChangeAttachmentList();
  155. }
  156. break;
  157. case IDC_ATTACHMENT_LIST_BONES:
  158. {
  159. int iAttachment = g_viewerSettings.m_iEditAttachment;
  160. int iBone = m_cBoneList->getSelectedIndex();
  161. if ( iAttachment >= 0 &&
  162. iAttachment < pHdr->GetNumAttachments() &&
  163. iBone >= 0 &&
  164. iBone < pHdr->numbones() )
  165. {
  166. pHdr->SetAttachmentBone( iAttachment, iBone );
  167. UpdateStrings();
  168. }
  169. }
  170. break;
  171. case IDC_ATTACHMENT_TRANSLATION:
  172. {
  173. int iAttachment = g_viewerSettings.m_iEditAttachment;
  174. if ( iAttachment >= 0 &&
  175. iAttachment < pHdr->GetNumAttachments() )
  176. {
  177. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
  178. Vector vTrans( 0, 0, 0 );
  179. char curText[512];
  180. m_cTranslation->getText( curText, sizeof( curText ) );
  181. sscanf( curText, "%f %f %f", &vTrans.x, &vTrans.y, &vTrans.z );
  182. pAttachment.local[0][3] = vTrans.x;
  183. pAttachment.local[1][3] = vTrans.y;
  184. pAttachment.local[2][3] = vTrans.z;
  185. UpdateStrings( true, false, false );
  186. }
  187. }
  188. break;
  189. case IDC_ATTACHMENT_ROTATION:
  190. {
  191. int iAttachment = g_viewerSettings.m_iEditAttachment;
  192. if ( iAttachment >= 0 &&
  193. iAttachment < pHdr->GetNumAttachments() )
  194. {
  195. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
  196. QAngle vRotation( 0, 0, 0 );
  197. char curText[512];
  198. m_cRotation->getText( curText, sizeof( curText ) );
  199. sscanf( curText, "%f %f %f", &vRotation.x, &vRotation.y, &vRotation.z );
  200. Vector vTrans = GetCurrentTranslation();
  201. AngleMatrix( vRotation, vTrans, pAttachment.local );
  202. UpdateStrings( true, false, false );
  203. }
  204. }
  205. break;
  206. case IDC_ATTACHMENT_NUDGE:
  207. {
  208. int iAttachment = g_viewerSettings.m_iEditAttachment;
  209. if ( iAttachment >= 0 && iAttachment < pHdr->GetNumAttachments() )
  210. {
  211. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
  212. QAngle vRotation( 0, 0, 0 );
  213. char curText[512];
  214. m_cRotation->getText( curText, sizeof( curText ) );
  215. sscanf( curText, "%f %f %f", &vRotation.x, &vRotation.y, &vRotation.z );
  216. Vector vTrans( 0, 0, 0 );
  217. m_cTranslation->getText( curText, sizeof( curText ) );
  218. sscanf( curText, "%f %f %f", &vTrans.x, &vTrans.y, &vTrans.z );
  219. if ( Q_strcmp( event->widget->getLabel(), "+x" ) == 0 )
  220. vTrans.x += 0.1f;
  221. if ( Q_strcmp( event->widget->getLabel(), "-x" ) == 0 )
  222. vTrans.x -= 0.1f;
  223. if ( Q_strcmp( event->widget->getLabel(), "+X" ) == 0 )
  224. vTrans.x += 1;
  225. if ( Q_strcmp( event->widget->getLabel(), "-X" ) == 0 )
  226. vTrans.x -= 1;
  227. if ( Q_strcmp( event->widget->getLabel(), "+y" ) == 0 )
  228. vTrans.y += 0.1f;
  229. if ( Q_strcmp( event->widget->getLabel(), "-y" ) == 0 )
  230. vTrans.y -= 0.1f;
  231. if ( Q_strcmp( event->widget->getLabel(), "+Y" ) == 0 )
  232. vTrans.y += 1;
  233. if ( Q_strcmp( event->widget->getLabel(), "-Y" ) == 0 )
  234. vTrans.y -= 1;
  235. if ( Q_strcmp( event->widget->getLabel(), "+z" ) == 0 )
  236. vTrans.z += 0.1f;
  237. if ( Q_strcmp( event->widget->getLabel(), "-z" ) == 0 )
  238. vTrans.z -= 0.1f;
  239. if ( Q_strcmp( event->widget->getLabel(), "+Z" ) == 0 )
  240. vTrans.z += 1;
  241. if ( Q_strcmp( event->widget->getLabel(), "-Z" ) == 0 )
  242. vTrans.z -= 1;
  243. if ( Q_strcmp( event->widget->getLabel(), "+xr" ) == 0 )
  244. vRotation.x += 0.1f;
  245. if ( Q_strcmp( event->widget->getLabel(), "-xr" ) == 0 )
  246. vRotation.x -= 0.1f;
  247. if ( Q_strcmp( event->widget->getLabel(), "+XR" ) == 0 )
  248. vRotation.x += 1;
  249. if ( Q_strcmp( event->widget->getLabel(), "-XR" ) == 0 )
  250. vRotation.x -= 1;
  251. if ( Q_strcmp( event->widget->getLabel(), "+yr" ) == 0 )
  252. vRotation.y += 0.1f;
  253. if ( Q_strcmp( event->widget->getLabel(), "-yr" ) == 0 )
  254. vRotation.y -= 0.1f;
  255. if ( Q_strcmp( event->widget->getLabel(), "+YR" ) == 0 )
  256. vRotation.y += 1;
  257. if ( Q_strcmp( event->widget->getLabel(), "-YR" ) == 0 )
  258. vRotation.y -= 1;
  259. if ( Q_strcmp( event->widget->getLabel(), "+zr" ) == 0 )
  260. vRotation.z += 0.1f;
  261. if ( Q_strcmp( event->widget->getLabel(), "-zr" ) == 0 )
  262. vRotation.z -= 0.1f;
  263. if ( Q_strcmp( event->widget->getLabel(), "+ZR" ) == 0 )
  264. vRotation.z += 1;
  265. if ( Q_strcmp( event->widget->getLabel(), "-ZR" ) == 0 )
  266. vRotation.z -= 1;
  267. AngleMatrix( vRotation, vTrans, pAttachment.local );
  268. UpdateStrings( true, true, true );
  269. }
  270. }
  271. break;
  272. default:
  273. return 0;
  274. }
  275. return 1;
  276. }
  277. void CAttachmentsWindow::OnSelChangeAttachmentList()
  278. {
  279. CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
  280. if ( !pStudioHdr )
  281. return;
  282. int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  283. if ( iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
  284. {
  285. g_viewerSettings.m_iEditAttachment = iAttachment;
  286. // Init the bone list index.
  287. int iBone = g_pStudioModel->GetStudioHdr()->GetAttachmentBone( iAttachment );
  288. m_cBoneList->select( iBone );
  289. }
  290. else
  291. {
  292. g_viewerSettings.m_iEditAttachment = -1;
  293. }
  294. UpdateStrings();
  295. }
  296. Vector CAttachmentsWindow::GetCurrentTranslation()
  297. {
  298. CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
  299. int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  300. if ( pStudioHdr && iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
  301. {
  302. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pStudioHdr->pAttachment( iAttachment );
  303. return Vector( pAttachment.local[0][3],
  304. pAttachment.local[1][3],
  305. pAttachment.local[2][3] );
  306. }
  307. else
  308. {
  309. return vec3_origin;
  310. }
  311. }
  312. Vector CAttachmentsWindow::GetCurrentRotation()
  313. {
  314. CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
  315. int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  316. if ( pStudioHdr && iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
  317. {
  318. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pStudioHdr->pAttachment( iAttachment );
  319. float angles[3];
  320. MatrixAngles( pAttachment.local, angles );
  321. return Vector( angles[0], angles[1], angles[2] );
  322. }
  323. else
  324. {
  325. return vec3_origin;
  326. }
  327. }
  328. void CAttachmentsWindow::UpdateStrings( bool bUpdateQC, bool bUpdateTranslation, bool bUpdateRotation )
  329. {
  330. char str[1024];
  331. int iAttachment = -1;
  332. CStudioHdr* pHdr = NULL;
  333. if ( g_pStudioModel )
  334. {
  335. pHdr = g_pStudioModel->GetStudioHdr();
  336. iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  337. if ( iAttachment < 0 || iAttachment >= pHdr->GetNumAttachments() )
  338. iAttachment = -1;
  339. }
  340. if ( iAttachment == -1 )
  341. {
  342. m_cTranslation->setText( "(none)" );
  343. m_cRotation->setText( "(none)" );
  344. m_cQCString->setText( "(none)" );
  345. }
  346. else
  347. {
  348. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
  349. int iBone= pHdr->GetAttachmentBone( iAttachment );
  350. Vector vTranslation = GetCurrentTranslation();
  351. Vector vRotation = GetCurrentRotation();
  352. if ( bUpdateQC )
  353. {
  354. sprintf( str, "$attachment \"%s\" \"%s\" %.2f %.2f %.2f rotate %.0f %.0f %.0f",
  355. pAttachment.pszName(),
  356. pHdr->pBone( iBone )->pszName(),
  357. VectorExpand( vTranslation ),
  358. VectorExpand( vRotation ) );
  359. m_cQCString->setText( str );
  360. }
  361. if ( bUpdateTranslation )
  362. {
  363. sprintf( str, "%.2f %.2f %.2f", VectorExpand( vTranslation ) );
  364. m_cTranslation->setText( str );
  365. }
  366. if ( bUpdateRotation )
  367. {
  368. sprintf( str, "%.0f %.0f %.0f", VectorExpand( vRotation ) );
  369. m_cRotation->setText( str );
  370. }
  371. }
  372. }