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
290 lines
6.7 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "stdafx.h"
|
|
#include "hammer.h"
|
|
#include "hammer_mathlib.h"
|
|
#include "ArchDlg.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include <tier0/memdbgon.h>
|
|
|
|
|
|
static LPCTSTR pszSection = "Arch";
|
|
|
|
extern void MakeArc(float x1, float y1, float x2, float y2, int npoints,
|
|
float start_ang, float fArc, float points[][2]);
|
|
|
|
|
|
CArchDlg::CArchDlg(Vector& boxmins, Vector& boxmaxs, CWnd* pParent /*=NULL*/)
|
|
: CDialog(CArchDlg::IDD, pParent)
|
|
{
|
|
bmins = boxmins;
|
|
bmaxs = boxmaxs;
|
|
|
|
//{{AFX_DATA_INIT(CArchDlg)
|
|
m_iSides = 0;
|
|
m_iWallWidth = 0;
|
|
m_iAddHeight = 0;
|
|
m_fArc = 0.0f;
|
|
m_fAngle = 0.0f;
|
|
//}}AFX_DATA_INIT
|
|
|
|
// load up old defaults
|
|
CString str;
|
|
m_iWallWidth = AfxGetApp()->GetProfileInt(pszSection, "Wall Width", 32);
|
|
str = AfxGetApp()->GetProfileString(pszSection, "Arc_", "180");
|
|
m_fArc = atof(str);
|
|
m_iSides = AfxGetApp()->GetProfileInt(pszSection, "Sides", 8);
|
|
str = AfxGetApp()->GetProfileString(pszSection, "Start Angle_", "0");
|
|
m_fAngle = atof(str);
|
|
m_iAddHeight = AfxGetApp()->GetProfileInt(pszSection, "Add Height", 0);
|
|
}
|
|
|
|
|
|
void CArchDlg::SaveValues()
|
|
{
|
|
CString str;
|
|
AfxGetApp()->WriteProfileInt(pszSection, "Wall Width", m_iWallWidth);
|
|
str.Format("%f", m_fArc);
|
|
AfxGetApp()->WriteProfileString(pszSection, "Arc_", str);
|
|
AfxGetApp()->WriteProfileInt(pszSection, "Sides", m_iSides);
|
|
str.Format("%f", m_fAngle);
|
|
AfxGetApp()->WriteProfileString(pszSection, "Start Angle_", str);
|
|
AfxGetApp()->WriteProfileInt(pszSection, "Add Height", m_iAddHeight);
|
|
}
|
|
|
|
|
|
void CArchDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
|
|
//{{AFX_DATA_MAP(CArchDlg)
|
|
DDX_Control(pDX, IDC_ANGLESPIN, m_cStartAngleSpin);
|
|
DDX_Control(pDX, IDC_WALLWIDTHSPIN, m_cWallWidthSpin);
|
|
DDX_Control(pDX, IDC_WALLWIDTH, m_cWallWidth);
|
|
DDX_Control(pDX, IDC_SIDESSPIN, m_cSidesSpin);
|
|
DDX_Control(pDX, IDC_SIDES, m_cSides);
|
|
DDX_Control(pDX, IDC_ARCSPIN, m_cArcSpin);
|
|
DDX_Control(pDX, IDC_ARC, m_cArc);
|
|
DDX_Control(pDX, IDC_PREVIEW, m_cPreview);
|
|
|
|
DDX_Text(pDX, IDC_WALLWIDTH, m_iWallWidth);
|
|
DDX_Text(pDX, IDC_SIDES, m_iSides);
|
|
DDV_MinMaxInt(pDX, m_iSides, 3, 2048);
|
|
|
|
DDX_Text(pDX, IDC_ADDHEIGHT, m_iAddHeight);
|
|
DDX_Text(pDX, IDC_ARC, m_fArc);
|
|
DDV_MinMaxFloat(pDX, m_fArc, 8.f, 360.f);
|
|
DDX_Text(pDX, IDC_ANGLE, m_fAngle);
|
|
DDV_MinMaxFloat(pDX, m_fAngle, 0.f, 360.f);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CArchDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CArchDlg)
|
|
ON_EN_CHANGE(IDC_ARC, OnChangeArc)
|
|
ON_BN_CLICKED(IDC_CIRCLE, OnCircle)
|
|
ON_EN_UPDATE(IDC_SIDES, OnUpdateSides)
|
|
ON_EN_UPDATE(IDC_WALLWIDTH, OnUpdateWallwidth)
|
|
ON_WM_PAINT()
|
|
ON_BN_CLICKED(IDC_ARCH_PREVIEW, OnArchPreview)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
void CArchDlg::OnChangeArc()
|
|
{
|
|
}
|
|
|
|
|
|
void CArchDlg::OnCircle()
|
|
{
|
|
m_cArcSpin.SetPos(360);
|
|
}
|
|
|
|
|
|
void CArchDlg::OnUpdateSides()
|
|
{
|
|
}
|
|
|
|
|
|
void CArchDlg::OnUpdateWallwidth()
|
|
{
|
|
}
|
|
|
|
|
|
BOOL CArchDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
m_cArcSpin.SetRange(8, 360);
|
|
m_cSidesSpin.SetRange(3, 100);
|
|
m_cWallWidthSpin.SetRange(2, m_iMaxWallWidth);
|
|
m_cStartAngleSpin.SetRange(0, 360);
|
|
|
|
m_cPreview.ShowWindow(SW_HIDE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void CArchDlg::OnPaint()
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
// Do not call CDialog::OnPaint() for painting messages
|
|
CBrush black(RGB(0,0,0));
|
|
CBrush grey(RGB(128,128,128));
|
|
|
|
CRect rcPreview;
|
|
m_cPreview.GetWindowRect(&rcPreview);
|
|
ScreenToClient(&rcPreview);
|
|
dc.FillRect(rcPreview, &black);
|
|
|
|
DrawArch(&dc);
|
|
rcPreview.InflateRect(1,1);
|
|
dc.FrameRect(rcPreview, &grey);
|
|
|
|
ValidateRect(rcPreview);
|
|
}
|
|
|
|
|
|
void CArchDlg::OnArchPreview()
|
|
{
|
|
//
|
|
// Build preview.
|
|
//
|
|
UpdateData(TRUE);
|
|
InvalidateRect(NULL);
|
|
UpdateWindow();
|
|
}
|
|
|
|
|
|
CArchDlg::~CArchDlg()
|
|
{
|
|
}
|
|
|
|
|
|
void CArchDlg::DrawArch(CDC* pDC)
|
|
{
|
|
float fOuterPoints[ARC_MAX_POINTS][2];
|
|
float fInnerPoints[ARC_MAX_POINTS][2];
|
|
|
|
float fScaleX;
|
|
float fScaleY;
|
|
|
|
CPen m_hPen, *pOldPen;
|
|
|
|
m_hPen.CreatePen(PS_SOLID, 1, RGB(255,255,255));
|
|
|
|
pOldPen = pDC->SelectObject(&m_hPen);
|
|
|
|
CRect rcItem;
|
|
m_cPreview.GetWindowRect(&rcItem);
|
|
ScreenToClient(&rcItem);
|
|
|
|
CPoint pt;
|
|
pt.x = rcItem.left + rcItem.Width() / 2;
|
|
pt.y = rcItem.top + rcItem.Height() / 2;
|
|
|
|
if (bmaxs[0] - bmins[0])
|
|
fScaleX = rcItem.Width()/(bmaxs[0] - bmins[0]);
|
|
else
|
|
fScaleX = 1.0f;
|
|
|
|
if (bmaxs[1] - bmins[1])
|
|
fScaleY = rcItem.Height()/(bmaxs[1] - bmins[1]);
|
|
else
|
|
fScaleY = 1.0f;
|
|
|
|
int iSides, iWallWidth;
|
|
float fArc, fStartAngle;
|
|
|
|
fArc = m_fArc;
|
|
fStartAngle = m_fAngle;
|
|
iSides = m_iSides;
|
|
iWallWidth = m_iWallWidth;
|
|
|
|
|
|
MakeArc(bmins[0], bmins[1],
|
|
bmaxs[0], bmaxs[1], iSides,
|
|
fStartAngle, fArc, fOuterPoints);
|
|
|
|
MakeArc(bmins[0] + iWallWidth,
|
|
bmins[1] + iWallWidth,
|
|
bmaxs[0] - iWallWidth,
|
|
bmaxs[1] - iWallWidth, iSides,
|
|
fStartAngle, fArc, fInnerPoints);
|
|
|
|
|
|
// check wall width - if it's half or more of the total,
|
|
// set the inner poinst to the center point of the box
|
|
// and turn off the CreateSouthFace flag
|
|
|
|
BOOL bCreateSouthFace = TRUE;
|
|
float fCenter[3];
|
|
for (int i = 0; i < 3; i++)
|
|
fCenter[i] = (bmins[i] + bmaxs[i])/2.0;
|
|
|
|
if((iWallWidth*2+8) >= (bmaxs[0] - bmins[0]) ||
|
|
(iWallWidth*2+8) >= (bmaxs[1] - bmins[1]))
|
|
{
|
|
for(int i = 0; i < ARC_MAX_POINTS; i++)
|
|
{
|
|
fInnerPoints[i][0] = fCenter[0];
|
|
fInnerPoints[i][1] = fCenter[1];
|
|
}
|
|
bCreateSouthFace = FALSE;
|
|
}
|
|
|
|
for (int i = 0; i < iSides; i++)
|
|
{
|
|
int iNextPoint = i+1;
|
|
if (iNextPoint >= iSides + 1)
|
|
iNextPoint = 0;
|
|
|
|
Vector points[4];
|
|
|
|
points[0][0] = fOuterPoints[i][0];
|
|
points[0][1] = fOuterPoints[i][1];
|
|
|
|
points[1][0] = fOuterPoints[iNextPoint][0];
|
|
points[1][1] = fOuterPoints[iNextPoint][1];
|
|
|
|
points[2][0] = fInnerPoints[iNextPoint][0];
|
|
points[2][1] = fInnerPoints[iNextPoint][1];
|
|
|
|
points[3][0] = fInnerPoints[i][0];
|
|
points[3][1] = fInnerPoints[i][1];
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
points[j][0] = fScaleX * (points[j][0] - fCenter[0]);
|
|
points[j][1] = fScaleY * (points[j][1] - fCenter[1]);
|
|
}
|
|
|
|
pDC->MoveTo(pt.x + (int)points[0][0], pt.y - (int)points[0][1]);
|
|
pDC->LineTo(pt.x + (int)points[1][0], pt.y - (int)points[1][1]);
|
|
pDC->LineTo(pt.x + (int)points[2][0], pt.y - (int)points[2][1]);
|
|
pDC->LineTo(pt.x + (int)points[3][0], pt.y - (int)points[3][1]);
|
|
}
|
|
|
|
// Draw the bbox
|
|
/*CPen hPen2;
|
|
hPen2.CreatePen(PS_SOLID, 1, RGB(255,255,0));
|
|
|
|
pDC->SelectObject(&hPen2);
|
|
|
|
pDC->MoveTo(pt.x + (int)((bmins[0] - fCenter[0])*fScaleX), pt.y - (int)((bmins[1] - fCenter[1])*fScaleY));
|
|
pDC->LineTo(pt.x + (int)((bmins[0] - fCenter[0])*fScaleX), pt.y - (int)((bmaxs[1] - fCenter[1])*fScaleY));
|
|
pDC->LineTo(pt.x + (int)((bmaxs[0] - fCenter[0])*fScaleX), pt.y - (int)((bmaxs[1] - fCenter[1])*fScaleY));
|
|
pDC->LineTo(pt.x + (int)((bmaxs[0] - fCenter[0])*fScaleX), pt.y - (int)((bmins[1] - fCenter[1])*fScaleY));
|
|
*/
|
|
pDC->SelectObject(pOldPen);
|
|
|
|
}
|