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.

349 lines
8.4 KiB

  1. //========= Copyright 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. CAttachmentsWindow::CAttachmentsWindow( ControlPanel* pParent ) : mxWindow( pParent, 0, 0, 0, 0 )
  17. {
  18. m_pControlPanel = pParent;
  19. g_viewerSettings.m_iEditAttachment = -1;
  20. }
  21. void CAttachmentsWindow::Init( )
  22. {
  23. int left, top;
  24. left = 5;
  25. top = 0;
  26. // Attachment selection list
  27. new mxLabel( this, left + 3, top + 4, 60, 18, "Attachment" );
  28. m_cAttachmentList = new mxListBox( this, left, top + 20, 260, 100, IDC_ATTACHMENT_LIST );
  29. m_cAttachmentList->add ("None");
  30. m_cAttachmentList->select (0);
  31. mxToolTip::add (m_cAttachmentList, "Select an attachment to modify");
  32. left = 280;
  33. new mxLabel( this, left + 3, top + 4, 60, 18, "Attach To Bone" );
  34. m_cBoneList = new mxListBox( this, left, top + 20, 260, 100, IDC_ATTACHMENT_LIST_BONES );
  35. m_cBoneList->add ("None");
  36. m_cBoneList->select( 0 );
  37. mxToolTip::add( m_cBoneList, "Select a bone to attach to" );
  38. left = 5;
  39. top = 120;
  40. new mxLabel( this, left + 3, top + 4, 60, 18, "Translation" );
  41. m_cTranslation = new mxLineEdit2( this, left + 70, top, 90, 25, "10 20 30", IDC_ATTACHMENT_TRANSLATION );
  42. left = 170;
  43. top = 120;
  44. new mxLabel( this, left + 3, top + 4, 60, 18, "Rotation" );
  45. m_cRotation = new mxLineEdit2( this, left + 70, top, 90, 25, "0 90 180", IDC_ATTACHMENT_ROTATION );
  46. top = 145;
  47. left = 5;
  48. new mxLabel( this, left, top, 60, 18, "QC String" );
  49. 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 );
  50. }
  51. void CAttachmentsWindow::OnLoadModel()
  52. {
  53. int iPrevEdit = g_viewerSettings.m_iEditAttachment;
  54. PopulateBoneList();
  55. PopulateAttachmentsList();
  56. if ( iPrevEdit >= 0 && iPrevEdit < m_cAttachmentList->getItemCount())
  57. {
  58. m_cAttachmentList->select( iPrevEdit + 1 );
  59. }
  60. g_viewerSettings.m_iEditAttachment = iPrevEdit;
  61. UpdateStrings();
  62. }
  63. void CAttachmentsWindow::OnTabSelected()
  64. {
  65. // for now, keep selection
  66. // g_viewerSettings.m_iEditAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  67. }
  68. void CAttachmentsWindow::OnTabUnselected()
  69. {
  70. // for now, keep selection
  71. // g_viewerSettings.m_iEditAttachment = -1;
  72. }
  73. void CAttachmentsWindow::PopulateAttachmentsList()
  74. {
  75. m_cAttachmentList->removeAll();
  76. m_cAttachmentList->add( "(none)" );
  77. if ( g_pStudioModel )
  78. {
  79. CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
  80. if (pHdr->GetNumAttachments())
  81. {
  82. for ( int i = 0; i < pHdr->GetNumAttachments(); i++ )
  83. {
  84. m_cAttachmentList->add ( pHdr->pAttachment(i).pszName() );
  85. }
  86. m_cAttachmentList->select (0);
  87. OnSelChangeAttachmentList();
  88. return;
  89. }
  90. }
  91. m_cAttachmentList->select (0);
  92. }
  93. void CAttachmentsWindow::PopulateBoneList()
  94. {
  95. m_cBoneList->removeAll();
  96. if ( g_pStudioModel )
  97. {
  98. CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
  99. if (pHdr->numbones())
  100. {
  101. for ( int i = 0; i < pHdr->numbones(); i++ )
  102. {
  103. m_cBoneList->add ( pHdr->pBone(i)->pszName() );
  104. }
  105. m_cBoneList->select (0);
  106. return;
  107. }
  108. }
  109. m_cBoneList->add( "None" );
  110. m_cBoneList->select (0);
  111. }
  112. int CAttachmentsWindow::handleEvent (mxEvent *event)
  113. {
  114. MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
  115. if ( !g_pStudioModel )
  116. return 0;
  117. CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
  118. switch( event->action )
  119. {
  120. case IDC_ATTACHMENT_LIST:
  121. {
  122. OnSelChangeAttachmentList();
  123. }
  124. break;
  125. case IDC_ATTACHMENT_LIST_BONES:
  126. {
  127. int iAttachment = g_viewerSettings.m_iEditAttachment;
  128. int iBone = m_cBoneList->getSelectedIndex();
  129. if ( iAttachment >= 0 &&
  130. iAttachment < pHdr->GetNumAttachments() &&
  131. iBone >= 0 &&
  132. iBone < pHdr->numbones() )
  133. {
  134. pHdr->SetAttachmentBone( iAttachment, iBone );
  135. UpdateStrings();
  136. }
  137. }
  138. break;
  139. case IDC_ATTACHMENT_TRANSLATION:
  140. {
  141. int iAttachment = g_viewerSettings.m_iEditAttachment;
  142. if ( iAttachment >= 0 &&
  143. iAttachment < pHdr->GetNumAttachments() )
  144. {
  145. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
  146. Vector vTrans( 0, 0, 0 );
  147. char curText[512];
  148. m_cTranslation->getText( curText, sizeof( curText ) );
  149. sscanf( curText, "%f %f %f", &vTrans.x, &vTrans.y, &vTrans.z );
  150. pAttachment.local[0][3] = vTrans.x;
  151. pAttachment.local[1][3] = vTrans.y;
  152. pAttachment.local[2][3] = vTrans.z;
  153. UpdateStrings( true, false, false );
  154. }
  155. }
  156. break;
  157. case IDC_ATTACHMENT_ROTATION:
  158. {
  159. int iAttachment = g_viewerSettings.m_iEditAttachment;
  160. if ( iAttachment >= 0 &&
  161. iAttachment < pHdr->GetNumAttachments() )
  162. {
  163. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
  164. QAngle vRotation( 0, 0, 0 );
  165. char curText[512];
  166. m_cRotation->getText( curText, sizeof( curText ) );
  167. sscanf( curText, "%f %f %f", &vRotation.x, &vRotation.y, &vRotation.z );
  168. Vector vTrans = GetCurrentTranslation();
  169. AngleMatrix( vRotation, vTrans, pAttachment.local );
  170. UpdateStrings( true, false, false );
  171. }
  172. }
  173. break;
  174. default:
  175. return 0;
  176. }
  177. return 1;
  178. }
  179. void CAttachmentsWindow::OnSelChangeAttachmentList()
  180. {
  181. CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
  182. if ( !pStudioHdr )
  183. return;
  184. int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  185. if ( iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
  186. {
  187. g_viewerSettings.m_iEditAttachment = iAttachment;
  188. // Init the bone list index.
  189. int iBone = g_pStudioModel->GetStudioHdr()->GetAttachmentBone( iAttachment );
  190. m_cBoneList->select( iBone );
  191. }
  192. else
  193. {
  194. g_viewerSettings.m_iEditAttachment = -1;
  195. }
  196. UpdateStrings();
  197. }
  198. Vector CAttachmentsWindow::GetCurrentTranslation()
  199. {
  200. CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
  201. int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  202. if ( pStudioHdr && iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
  203. {
  204. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pStudioHdr->pAttachment( iAttachment );
  205. return Vector( pAttachment.local[0][3],
  206. pAttachment.local[1][3],
  207. pAttachment.local[2][3] );
  208. }
  209. else
  210. {
  211. return vec3_origin;
  212. }
  213. }
  214. Vector CAttachmentsWindow::GetCurrentRotation()
  215. {
  216. CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
  217. int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  218. if ( pStudioHdr && iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
  219. {
  220. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pStudioHdr->pAttachment( iAttachment );
  221. float angles[3];
  222. MatrixAngles( pAttachment.local, angles );
  223. return Vector( angles[0], angles[1], angles[2] );
  224. }
  225. else
  226. {
  227. return vec3_origin;
  228. }
  229. }
  230. void CAttachmentsWindow::UpdateStrings( bool bUpdateQC, bool bUpdateTranslation, bool bUpdateRotation )
  231. {
  232. char str[1024];
  233. int iAttachment = -1;
  234. CStudioHdr* pHdr = NULL;
  235. if ( g_pStudioModel )
  236. {
  237. pHdr = g_pStudioModel->GetStudioHdr();
  238. iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
  239. if ( iAttachment < 0 || iAttachment >= pHdr->GetNumAttachments() )
  240. iAttachment = -1;
  241. }
  242. if ( iAttachment == -1 )
  243. {
  244. m_cTranslation->setText( "(none)" );
  245. m_cRotation->setText( "(none)" );
  246. m_cQCString->setText( "(none)" );
  247. }
  248. else
  249. {
  250. mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
  251. int iBone= pHdr->GetAttachmentBone( iAttachment );
  252. Vector vTranslation = GetCurrentTranslation();
  253. Vector vRotation = GetCurrentRotation();
  254. if ( bUpdateQC )
  255. {
  256. sprintf( str, "$attachment \"%s\" \"%s\" %.2f %.2f %.2f rotate %.0f %.0f %.0f",
  257. pAttachment.pszName(),
  258. pHdr->pBone( iBone )->pszName(),
  259. VectorExpand( vTranslation ),
  260. VectorExpand( vRotation ) );
  261. m_cQCString->setText( str );
  262. }
  263. if ( bUpdateTranslation )
  264. {
  265. sprintf( str, "%.2f %.2f %.2f", VectorExpand( vTranslation ) );
  266. m_cTranslation->setText( str );
  267. }
  268. if ( bUpdateRotation )
  269. {
  270. sprintf( str, "%.0f %.0f %.0f", VectorExpand( vRotation ) );
  271. m_cRotation->setText( str );
  272. }
  273. }
  274. }