Serious-Engine/Sources/Modeler/DlgPgCollision.cpp
2016-03-11 18:20:51 -06:00

422 lines
12 KiB
C++

/* Copyright (c) 2002-2012 Croteam Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as published by
the Free Software Foundation
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
// DlgPgCollision.cpp : implementation file
//
#include "stdafx.h"
#ifdef _DEBUG
#undef new
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgPgCollision property page
IMPLEMENT_DYNCREATE(CDlgPgCollision, CPropertyPage)
CDlgPgCollision::CDlgPgCollision() : CPropertyPage(CDlgPgCollision::IDD)
{
//{{AFX_DATA_INIT(CDlgPgCollision)
m_fWidth = 0.0f;
m_fHeight = 0.0f;
m_fLenght = 0.0f;
m_fXCenter = 0.0f;
m_fYDown = 0.0f;
m_fZCenter = 0.0f;
m_EqualityRadio = -1;
m_strCollisionBoxName = _T("");
m_strCollisionBoxIndex = _T("");
m_bCollideAsBox = FALSE;
//}}AFX_DATA_INIT
theApp.m_pPgInfoCollision = this;
}
CDlgPgCollision::~CDlgPgCollision()
{
}
void CDlgPgCollision::DoDataExchange(CDataExchange* pDX)
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
// if transfering data from document to dialog
if( !pDX->m_bSaveAndValidate)
{
// get collision min vector
FLOAT3D vMinCollisionBox = pDoc->m_emEditModel.GetCollisionBoxMin();
// get collision max vector
FLOAT3D vMaxCollisionBox = pDoc->m_emEditModel.GetCollisionBoxMax();
FLOATaabbox3D bboxCollision = FLOATaabbox3D( vMinCollisionBox, vMaxCollisionBox);
m_fWidth = bboxCollision.Size()(1);
m_fHeight = bboxCollision.Size()(2);
m_fLenght = bboxCollision.Size()(3);
m_fXCenter = bboxCollision.Center()(1);
m_fYDown = vMinCollisionBox(2);
m_fZCenter = bboxCollision.Center()(3);
// set equality radio initial value
INDEX iEqualityType = pDoc->m_emEditModel.GetCollisionBoxDimensionEquality();
// get index of curently selected collision box
char achrString[ 256];
sprintf( achrString, "%d.", pDoc->m_emEditModel.GetActiveCollisionBoxIndex());
m_strCollisionBoxIndex = achrString;
// get name of curently selected collision box
sprintf( achrString, "%s", pDoc->m_emEditModel.GetCollisionBoxName());
m_strCollisionBoxName = achrString;
// enable all controls
GetDlgItem( IDC_STATIC_WIDTH)->EnableWindow( TRUE);
GetDlgItem( IDC_EDIT_WIDTH)->EnableWindow( TRUE);
GetDlgItem( IDC_STATIC_HEIGHT)->EnableWindow( TRUE);
GetDlgItem( IDC_EDIT_HEIGHT)->EnableWindow( TRUE);
GetDlgItem( IDC_STATIC_LENGHT)->EnableWindow( TRUE);
GetDlgItem( IDC_EDIT_LENGHT)->EnableWindow( TRUE);
m_bCollideAsBox = pDoc->m_emEditModel.edm_md.md_bCollideAsCube;
// if we are colliding using sphere approximation
switch( iEqualityType)
{
case HEIGHT_EQ_WIDTH:
{
m_EqualityRadio = 0;
if( !m_bCollideAsBox)
{
GetDlgItem( IDC_STATIC_HEIGHT)->EnableWindow( FALSE);
GetDlgItem( IDC_EDIT_HEIGHT)->EnableWindow( FALSE);
m_fHeight = m_fWidth;
}
break;
}
case LENGTH_EQ_WIDTH:
{
m_EqualityRadio = 1;
if( !m_bCollideAsBox)
{
GetDlgItem( IDC_STATIC_LENGHT)->EnableWindow( FALSE);
GetDlgItem( IDC_EDIT_LENGHT)->EnableWindow( FALSE);
m_fLenght = m_fWidth;
}
break;
}
case LENGTH_EQ_HEIGHT:
{
m_EqualityRadio = 2;
if( !m_bCollideAsBox)
{
GetDlgItem( IDC_STATIC_LENGHT)->EnableWindow( FALSE);
GetDlgItem( IDC_EDIT_LENGHT)->EnableWindow( FALSE);
m_fLenght = m_fHeight;
}
break;
}
default:
{
ASSERTALWAYS( "None of collision dimensions are the same and that can't be.");
}
}
// mark that the values have been updated to reflect the state of the view
m_udAllValues.MarkUpdated();
}
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgPgCollision)
DDX_SkyFloat(pDX, IDC_EDIT_WIDTH, m_fWidth);
DDX_SkyFloat(pDX, IDC_EDIT_HEIGHT, m_fHeight);
DDX_SkyFloat(pDX, IDC_EDIT_LENGHT, m_fLenght);
DDX_SkyFloat(pDX, IDC_EDIT_XCENTER, m_fXCenter);
DDX_SkyFloat(pDX, IDC_EDIT_YDOWN, m_fYDown);
DDX_SkyFloat(pDX, IDC_EDIT_ZCENTER, m_fZCenter);
DDX_Radio(pDX, IDC_H_EQ_W, m_EqualityRadio);
DDX_Text(pDX, IDC_COLLISION_BOX_NAME, m_strCollisionBoxName);
DDX_Text(pDX, IDC_COLLISION_BOX_INDEX, m_strCollisionBoxIndex);
DDX_Check(pDX, IDC_COLLIDE_AS_BOX, m_bCollideAsBox);
//}}AFX_DATA_MAP
// if transfering data from dialog to document
if( pDX->m_bSaveAndValidate)
{
// if we are colliding using sphere approximation
if( !pDoc->m_emEditModel.edm_md.md_bCollideAsCube)
{
INDEX iEqualityType;
switch( m_EqualityRadio)
{
case 0:
{
iEqualityType = HEIGHT_EQ_WIDTH;
CString strWidth;
GetDlgItem( IDC_EDIT_WIDTH)->GetWindowText(strWidth);
GetDlgItem( IDC_EDIT_HEIGHT)->SetWindowText(strWidth);
break;
}
case 1:
{
iEqualityType = LENGTH_EQ_WIDTH;
CString strWidth;
GetDlgItem( IDC_EDIT_WIDTH)->GetWindowText(strWidth);
GetDlgItem( IDC_EDIT_LENGHT)->SetWindowText( strWidth );
break;
}
case 2:
{
iEqualityType = LENGTH_EQ_HEIGHT;
CString strHeight;
GetDlgItem( IDC_EDIT_HEIGHT)->GetWindowText(strHeight);
GetDlgItem( IDC_EDIT_LENGHT)->SetWindowText( strHeight);
break;
}
default:
{
ASSERTALWAYS( "Illegal value found in collision dimensions equality radio.");
}
}
// set collision equality value
if( pDoc->m_emEditModel.GetCollisionBoxDimensionEquality() != iEqualityType)
{
pDoc->m_emEditModel.SetCollisionBoxDimensionEquality( iEqualityType);
}
}
// set name of curently selected collision box
pDoc->m_emEditModel.SetCollisionBoxName( CTString( CStringA(m_strCollisionBoxName)) );
// get collision min and max vectors
FLOAT3D vMinCollisionBox;
FLOAT3D vMaxCollisionBox;
// get sizing values
vMinCollisionBox(1) = m_fXCenter-m_fWidth/2.0f;
vMinCollisionBox(2) = m_fYDown;
vMinCollisionBox(3) = m_fZCenter-m_fLenght/2.0f;
// get origin coordinates
vMaxCollisionBox(1) = m_fXCenter+m_fWidth/2.0f;
vMaxCollisionBox(2) = m_fYDown+m_fHeight;
vMaxCollisionBox(3) = m_fZCenter+m_fLenght/2.0f;
// transfer data from dialog to document
pDoc->m_emEditModel.SetCollisionBox( vMinCollisionBox, vMaxCollisionBox);
pDoc->SetModifiedFlag();
// update all views
pDoc->UpdateAllViews( NULL);
}
}
BEGIN_MESSAGE_MAP(CDlgPgCollision, CPropertyPage)
//{{AFX_MSG_MAP(CDlgPgCollision)
ON_EN_CHANGE(IDC_EDIT_WIDTH, OnChangeEditWidth)
ON_EN_CHANGE(IDC_EDIT_HEIGHT, OnChangeEditHeight)
ON_EN_CHANGE(IDC_EDIT_LENGHT, OnChangeEditLenght)
ON_EN_CHANGE(IDC_EDIT_XCENTER, OnChangeEditXCenter)
ON_EN_CHANGE(IDC_EDIT_YDOWN, OnChangeEditYDown)
ON_EN_CHANGE(IDC_EDIT_ZCENTER, OnChangeEditZCenter)
ON_BN_CLICKED(IDC_H_EQ_W, OnHEqW)
ON_BN_CLICKED(IDC_L_EQ_W, OnLEqW)
ON_BN_CLICKED(IDC_L_EQ_H, OnLEqH)
ON_BN_CLICKED(IDC_ADD_COLLISION_BOX, OnAddCollisionBox)
ON_EN_CHANGE(IDC_COLLISION_BOX_NAME, OnChangeCollisionBoxName)
ON_BN_CLICKED(IDC_NEXT_COLLISION_BOX, OnNextCollisionBox)
ON_BN_CLICKED(IDC_PREVIOUS_COLLISION_BOX, OnPreviousCollisionBox)
ON_BN_CLICKED(IDC_REMOVE_COLLISION_BOX, OnRemoveCollisionBox)
ON_BN_CLICKED(IDC_COLLIDE_AS_BOX, OnCollideAsBox)
ON_BN_CLICKED(IDC_ALLIGN_TO_SIZE, OnAllignToSize)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgPgCollision message handlers
BOOL CDlgPgCollision::OnIdle(LONG lCount)
{
CModelerView *pModelerView = CModelerView::GetActiveView();
ASSERT(pModelerView != NULL);
// update data
if (!theApp.m_chGlobal.IsUpToDate(m_udAllValues) )
{
UpdateData(FALSE);
}
return TRUE;
}
BOOL _bAvoidingLooping = FALSE;
void CDlgPgCollision::OnChangeEditWidth()
{
if( !_bAvoidingLooping)
{
_bAvoidingLooping = TRUE;
UpdateData(TRUE);
//UpdateData(FALSE);
_bAvoidingLooping = FALSE;
}
}
void CDlgPgCollision::OnChangeEditHeight()
{
if( !_bAvoidingLooping)
{
_bAvoidingLooping = TRUE;
UpdateData(TRUE);
//UpdateData(FALSE);
_bAvoidingLooping = FALSE;
}
}
void CDlgPgCollision::OnChangeEditLenght()
{
if( !_bAvoidingLooping)
{
_bAvoidingLooping = TRUE;
UpdateData(TRUE);
//UpdateData(FALSE);
_bAvoidingLooping = FALSE;
}
}
void CDlgPgCollision::OnChangeEditXCenter()
{
UpdateData(TRUE);
//UpdateData(FALSE);
}
void CDlgPgCollision::OnChangeEditYDown()
{
UpdateData(TRUE);
//UpdateData(FALSE);
}
void CDlgPgCollision::OnChangeEditZCenter()
{
UpdateData(TRUE);
//UpdateData(FALSE);
}
void CDlgPgCollision::OnHEqW()
{
m_EqualityRadio = 0;
UpdateData(TRUE);
UpdateData(FALSE);
}
void CDlgPgCollision::OnLEqW()
{
m_EqualityRadio = 1;
UpdateData(TRUE);
UpdateData(FALSE);
}
void CDlgPgCollision::OnLEqH()
{
m_EqualityRadio = 2;
UpdateData(TRUE);
UpdateData(FALSE);
}
void CDlgPgCollision::OnChangeCollisionBoxName()
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
// document has been changed
pDoc->SetModifiedFlag();
UpdateData( TRUE);
}
void CDlgPgCollision::OnNextCollisionBox()
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
pDoc->m_emEditModel.ActivateNextCollisionBox();
UpdateData(FALSE);
// update all views
pDoc->UpdateAllViews( NULL);
}
void CDlgPgCollision::OnPreviousCollisionBox()
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
pDoc->m_emEditModel.ActivatePreviousCollisionBox();
UpdateData(FALSE);
// update all views
pDoc->UpdateAllViews( NULL);
}
void CDlgPgCollision::OnAddCollisionBox()
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
pDoc->m_emEditModel.AddCollisionBox();
UpdateData(FALSE);
// document has been changed
pDoc->SetModifiedFlag();
// update all views
pDoc->UpdateAllViews( NULL);
}
void CDlgPgCollision::OnRemoveCollisionBox()
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
pDoc->m_emEditModel.DeleteCurrentCollisionBox();
UpdateData(FALSE);
// document has been changed
pDoc->SetModifiedFlag();
// update all views
pDoc->UpdateAllViews( NULL);
}
void CDlgPgCollision::OnCollideAsBox()
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
pDoc->m_emEditModel.edm_md.md_bCollideAsCube = !pDoc->m_emEditModel.edm_md.md_bCollideAsCube;
UpdateData(TRUE);
UpdateData(FALSE);
pDoc->SetModifiedFlag();
pDoc->UpdateAllViews( NULL);
}
void CDlgPgCollision::OnAllignToSize()
{
CModelerView *pModelerView = CModelerView::GetActiveView();
if(pModelerView == NULL) return;
CModelerDoc* pDoc = pModelerView->GetDocument();
FLOATaabbox3D MaxBB;
pDoc->m_emEditModel.edm_md.GetAllFramesBBox( MaxBB);
pDoc->m_emEditModel.SetCollisionBox( MaxBB.Min(), MaxBB.Max());
UpdateData(FALSE);
pDoc->SetModifiedFlag();
pDoc->UpdateAllViews( NULL);
}