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.

290 lines
6.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "stdafx.h"
  7. #include "hammer.h"
  8. #include "hammer_mathlib.h"
  9. #include "ArchDlg.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include <tier0/memdbgon.h>
  12. static LPCTSTR pszSection = "Arch";
  13. extern void MakeArc(float x1, float y1, float x2, float y2, int npoints,
  14. float start_ang, float fArc, float points[][2]);
  15. CArchDlg::CArchDlg(Vector& boxmins, Vector& boxmaxs, CWnd* pParent /*=NULL*/)
  16. : CDialog(CArchDlg::IDD, pParent)
  17. {
  18. bmins = boxmins;
  19. bmaxs = boxmaxs;
  20. //{{AFX_DATA_INIT(CArchDlg)
  21. m_iSides = 0;
  22. m_iWallWidth = 0;
  23. m_iAddHeight = 0;
  24. m_fArc = 0.0f;
  25. m_fAngle = 0.0f;
  26. //}}AFX_DATA_INIT
  27. // load up old defaults
  28. CString str;
  29. m_iWallWidth = AfxGetApp()->GetProfileInt(pszSection, "Wall Width", 32);
  30. str = AfxGetApp()->GetProfileString(pszSection, "Arc_", "180");
  31. m_fArc = atof(str);
  32. m_iSides = AfxGetApp()->GetProfileInt(pszSection, "Sides", 8);
  33. str = AfxGetApp()->GetProfileString(pszSection, "Start Angle_", "0");
  34. m_fAngle = atof(str);
  35. m_iAddHeight = AfxGetApp()->GetProfileInt(pszSection, "Add Height", 0);
  36. }
  37. void CArchDlg::SaveValues()
  38. {
  39. CString str;
  40. AfxGetApp()->WriteProfileInt(pszSection, "Wall Width", m_iWallWidth);
  41. str.Format("%f", m_fArc);
  42. AfxGetApp()->WriteProfileString(pszSection, "Arc_", str);
  43. AfxGetApp()->WriteProfileInt(pszSection, "Sides", m_iSides);
  44. str.Format("%f", m_fAngle);
  45. AfxGetApp()->WriteProfileString(pszSection, "Start Angle_", str);
  46. AfxGetApp()->WriteProfileInt(pszSection, "Add Height", m_iAddHeight);
  47. }
  48. void CArchDlg::DoDataExchange(CDataExchange* pDX)
  49. {
  50. CDialog::DoDataExchange(pDX);
  51. //{{AFX_DATA_MAP(CArchDlg)
  52. DDX_Control(pDX, IDC_ANGLESPIN, m_cStartAngleSpin);
  53. DDX_Control(pDX, IDC_WALLWIDTHSPIN, m_cWallWidthSpin);
  54. DDX_Control(pDX, IDC_WALLWIDTH, m_cWallWidth);
  55. DDX_Control(pDX, IDC_SIDESSPIN, m_cSidesSpin);
  56. DDX_Control(pDX, IDC_SIDES, m_cSides);
  57. DDX_Control(pDX, IDC_ARCSPIN, m_cArcSpin);
  58. DDX_Control(pDX, IDC_ARC, m_cArc);
  59. DDX_Control(pDX, IDC_PREVIEW, m_cPreview);
  60. DDX_Text(pDX, IDC_WALLWIDTH, m_iWallWidth);
  61. DDX_Text(pDX, IDC_SIDES, m_iSides);
  62. DDV_MinMaxInt(pDX, m_iSides, 3, 2048);
  63. DDX_Text(pDX, IDC_ADDHEIGHT, m_iAddHeight);
  64. DDX_Text(pDX, IDC_ARC, m_fArc);
  65. DDV_MinMaxFloat(pDX, m_fArc, 8.f, 360.f);
  66. DDX_Text(pDX, IDC_ANGLE, m_fAngle);
  67. DDV_MinMaxFloat(pDX, m_fAngle, 0.f, 360.f);
  68. //}}AFX_DATA_MAP
  69. }
  70. BEGIN_MESSAGE_MAP(CArchDlg, CDialog)
  71. //{{AFX_MSG_MAP(CArchDlg)
  72. ON_EN_CHANGE(IDC_ARC, OnChangeArc)
  73. ON_BN_CLICKED(IDC_CIRCLE, OnCircle)
  74. ON_EN_UPDATE(IDC_SIDES, OnUpdateSides)
  75. ON_EN_UPDATE(IDC_WALLWIDTH, OnUpdateWallwidth)
  76. ON_WM_PAINT()
  77. ON_BN_CLICKED(IDC_ARCH_PREVIEW, OnArchPreview)
  78. //}}AFX_MSG_MAP
  79. END_MESSAGE_MAP()
  80. void CArchDlg::OnChangeArc()
  81. {
  82. }
  83. void CArchDlg::OnCircle()
  84. {
  85. m_cArcSpin.SetPos(360);
  86. }
  87. void CArchDlg::OnUpdateSides()
  88. {
  89. }
  90. void CArchDlg::OnUpdateWallwidth()
  91. {
  92. }
  93. BOOL CArchDlg::OnInitDialog()
  94. {
  95. CDialog::OnInitDialog();
  96. m_cArcSpin.SetRange(8, 360);
  97. m_cSidesSpin.SetRange(3, 100);
  98. m_cWallWidthSpin.SetRange(2, m_iMaxWallWidth);
  99. m_cStartAngleSpin.SetRange(0, 360);
  100. m_cPreview.ShowWindow(SW_HIDE);
  101. return TRUE;
  102. }
  103. void CArchDlg::OnPaint()
  104. {
  105. CPaintDC dc(this); // device context for painting
  106. // Do not call CDialog::OnPaint() for painting messages
  107. CBrush black(RGB(0,0,0));
  108. CBrush grey(RGB(128,128,128));
  109. CRect rcPreview;
  110. m_cPreview.GetWindowRect(&rcPreview);
  111. ScreenToClient(&rcPreview);
  112. dc.FillRect(rcPreview, &black);
  113. DrawArch(&dc);
  114. rcPreview.InflateRect(1,1);
  115. dc.FrameRect(rcPreview, &grey);
  116. ValidateRect(rcPreview);
  117. }
  118. void CArchDlg::OnArchPreview()
  119. {
  120. //
  121. // Build preview.
  122. //
  123. UpdateData(TRUE);
  124. InvalidateRect(NULL);
  125. UpdateWindow();
  126. }
  127. CArchDlg::~CArchDlg()
  128. {
  129. }
  130. void CArchDlg::DrawArch(CDC* pDC)
  131. {
  132. float fOuterPoints[ARC_MAX_POINTS][2];
  133. float fInnerPoints[ARC_MAX_POINTS][2];
  134. float fScaleX;
  135. float fScaleY;
  136. CPen m_hPen, *pOldPen;
  137. m_hPen.CreatePen(PS_SOLID, 1, RGB(255,255,255));
  138. pOldPen = pDC->SelectObject(&m_hPen);
  139. CRect rcItem;
  140. m_cPreview.GetWindowRect(&rcItem);
  141. ScreenToClient(&rcItem);
  142. CPoint pt;
  143. pt.x = rcItem.left + rcItem.Width() / 2;
  144. pt.y = rcItem.top + rcItem.Height() / 2;
  145. if (bmaxs[0] - bmins[0])
  146. fScaleX = rcItem.Width()/(bmaxs[0] - bmins[0]);
  147. else
  148. fScaleX = 1.0f;
  149. if (bmaxs[1] - bmins[1])
  150. fScaleY = rcItem.Height()/(bmaxs[1] - bmins[1]);
  151. else
  152. fScaleY = 1.0f;
  153. int iSides, iWallWidth;
  154. float fArc, fStartAngle;
  155. fArc = m_fArc;
  156. fStartAngle = m_fAngle;
  157. iSides = m_iSides;
  158. iWallWidth = m_iWallWidth;
  159. MakeArc(bmins[0], bmins[1],
  160. bmaxs[0], bmaxs[1], iSides,
  161. fStartAngle, fArc, fOuterPoints);
  162. MakeArc(bmins[0] + iWallWidth,
  163. bmins[1] + iWallWidth,
  164. bmaxs[0] - iWallWidth,
  165. bmaxs[1] - iWallWidth, iSides,
  166. fStartAngle, fArc, fInnerPoints);
  167. // check wall width - if it's half or more of the total,
  168. // set the inner poinst to the center point of the box
  169. // and turn off the CreateSouthFace flag
  170. BOOL bCreateSouthFace = TRUE;
  171. float fCenter[3];
  172. for (int i = 0; i < 3; i++)
  173. fCenter[i] = (bmins[i] + bmaxs[i])/2.0;
  174. if((iWallWidth*2+8) >= (bmaxs[0] - bmins[0]) ||
  175. (iWallWidth*2+8) >= (bmaxs[1] - bmins[1]))
  176. {
  177. for(int i = 0; i < ARC_MAX_POINTS; i++)
  178. {
  179. fInnerPoints[i][0] = fCenter[0];
  180. fInnerPoints[i][1] = fCenter[1];
  181. }
  182. bCreateSouthFace = FALSE;
  183. }
  184. for (int i = 0; i < iSides; i++)
  185. {
  186. int iNextPoint = i+1;
  187. if (iNextPoint >= iSides + 1)
  188. iNextPoint = 0;
  189. Vector points[4];
  190. points[0][0] = fOuterPoints[i][0];
  191. points[0][1] = fOuterPoints[i][1];
  192. points[1][0] = fOuterPoints[iNextPoint][0];
  193. points[1][1] = fOuterPoints[iNextPoint][1];
  194. points[2][0] = fInnerPoints[iNextPoint][0];
  195. points[2][1] = fInnerPoints[iNextPoint][1];
  196. points[3][0] = fInnerPoints[i][0];
  197. points[3][1] = fInnerPoints[i][1];
  198. for (int j = 0; j < 4; j++)
  199. {
  200. points[j][0] = fScaleX * (points[j][0] - fCenter[0]);
  201. points[j][1] = fScaleY * (points[j][1] - fCenter[1]);
  202. }
  203. pDC->MoveTo(pt.x + (int)points[0][0], pt.y - (int)points[0][1]);
  204. pDC->LineTo(pt.x + (int)points[1][0], pt.y - (int)points[1][1]);
  205. pDC->LineTo(pt.x + (int)points[2][0], pt.y - (int)points[2][1]);
  206. pDC->LineTo(pt.x + (int)points[3][0], pt.y - (int)points[3][1]);
  207. }
  208. // Draw the bbox
  209. /*CPen hPen2;
  210. hPen2.CreatePen(PS_SOLID, 1, RGB(255,255,0));
  211. pDC->SelectObject(&hPen2);
  212. pDC->MoveTo(pt.x + (int)((bmins[0] - fCenter[0])*fScaleX), pt.y - (int)((bmins[1] - fCenter[1])*fScaleY));
  213. pDC->LineTo(pt.x + (int)((bmins[0] - fCenter[0])*fScaleX), pt.y - (int)((bmaxs[1] - fCenter[1])*fScaleY));
  214. pDC->LineTo(pt.x + (int)((bmaxs[0] - fCenter[0])*fScaleX), pt.y - (int)((bmaxs[1] - fCenter[1])*fScaleY));
  215. pDC->LineTo(pt.x + (int)((bmaxs[0] - fCenter[0])*fScaleX), pt.y - (int)((bmins[1] - fCenter[1])*fScaleY));
  216. */
  217. pDC->SelectObject(pOldPen);
  218. }