📄 modelsdlg.cpp
字号:
/****************************************************************************************/
/* ModelsDlg.cpp */
/* */
/* Author: Tom Morris */
/* Description: Model Control */
/* */
/* The contents of this file are subject to the Genesis3D Public License */
/* Version 1.01 (the "License"); you may not use this file except in */
/* compliance with the License. You may obtain a copy of the License at */
/* http://www.genesis3d.com */
/* */
/* Software distributed under the License is distributed on an "AS IS" */
/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
/* the License for the specific language governing rights and limitations */
/* under the License. */
/* */
/* The Original Code is Genesis3D, released March 25, 1999. */
/* Genesis3D Version 1.1 released November 15, 1999 */
/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */
/* */
/* Prepared for GenEdit-Classic ver. 0.5, Dec. 15, 2000 */
/****************************************************************************************/
#include "stdafx.h"
#include "genedit.h"
#include "ModelsDlg.h"
#include "Globals.h"
#include "KeyEditDlg.h"
#include <assert.h>
#include "ram.h"
#include "util.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
enum
{
KEY_TYPE_INVALID,
KEY_TYPE_EVENT,
KEY_TYPE_KEYFRAME
};
struct EventEditType
{
geFloat Time;
char EventString[_MAX_PATH];
char AddOrEdit;
};
/////////////////////////////////////////////////////////////////////////////
// CEventKeyEdit dialog
class CEventKeyEdit : public CDialog
{
// Construction
public:
CEventKeyEdit(CWnd* pParent, EventEditType *pInfo); // standard constructor
// Dialog Data
//{{AFX_DATA(CEventKeyEdit)
enum { IDD = IDD_EVENTEDIT };
CEdit m_EventTime;
CEdit m_EventString;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEventKeyEdit)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
EventEditType *pEditInfo;
// Generated message map functions
//{{AFX_MSG(CEventKeyEdit)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CEventKeyEdit dialog
CEventKeyEdit::CEventKeyEdit(CWnd* pParent, EventEditType *pInfo)
: CDialog(CEventKeyEdit::IDD, pParent), pEditInfo(pInfo)
{
//{{AFX_DATA_INIT(CEventKeyEdit)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CEventKeyEdit::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEventKeyEdit)
DDX_Control(pDX, IDC_EVENTTIME, m_EventTime);
DDX_Control(pDX, IDC_EVENTSTRING, m_EventString);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CEventKeyEdit, CDialog)
//{{AFX_MSG_MAP(CEventKeyEdit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEventKeyEdit message handlers
BOOL CEventKeyEdit::OnInitDialog()
{
assert (pEditInfo != NULL);
CDialog::OnInitDialog();
switch (pEditInfo->AddOrEdit)
{
case 'A' :
SetWindowText ("Add event");
m_EventTime.SetWindowText ("");
m_EventString.SetWindowText ("");
break;
case 'E' :
char StringTime[20];
SetWindowText ("Edit event");
sprintf (StringTime, "%.2f", pEditInfo->Time);
m_EventTime.SetWindowText (StringTime);
m_EventString.SetWindowText (pEditInfo->EventString);
break;
default :
assert (0); // better not happen...
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CEventKeyEdit::OnOK()
{
CString EditTime;
CString EditText;
float Time;
m_EventTime.GetWindowText (EditTime);
if (Util_IsValidFloat (EditTime, &Time))
{
m_EventString.GetWindowText (EditText);
if ((EditText.GetLength () == 0) ||
(EditText.GetLength () >= sizeof (pEditInfo->EventString)))
{
m_EventString.SetFocus ();
m_EventString.SetSel (0, -1, FALSE);
}
else
{
pEditInfo->Time = Time;
strcpy (pEditInfo->EventString, EditText);
CDialog::OnOK();
}
}
else
{
m_EventTime.SetFocus ();
m_EventTime.SetSel (0, -1, FALSE);
}
}
/////////////////////////////////////////////////////////////////////////////
// CModelsDlg dialog
CModelsDlg::CModelsDlg(CWnd* pParent /*=NULL*/)
: CDialog(CModelsDlg::IDD, pParent),
pDoc(NULL), pModelInfo(NULL), Animating(GE_FALSE),
SettingOrigin(GE_FALSE), EntityIndex (-1)
{
//{{AFX_DATA_INIT(CModelsDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
geXForm3d_SetIdentity (&XfmDelta);
}
void CModelsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CModelsDlg)
DDX_Control(pDX, IDC_SETMODELORIGIN, m_SetModelOrigin);
DDX_Control(pDX, IDC_CLONEMODEL, m_CloneModel);
DDX_Control(pDX, IDC_LOCKORIGIN, m_cbLockOrigin);
DDX_Control(pDX, IDI_STOP, m_Stop);
DDX_Control(pDX, IDI_RRSTART, m_rrStart);
DDX_Control(pDX, IDI_RRFRAME, m_rrFrame);
DDX_Control(pDX, IDI_PLAY, m_Play);
DDX_Control(pDX, IDI_FFFRAME, m_ffFrame);
DDX_Control(pDX, IDI_FFEND, m_ffEnd);
DDX_Control(pDX, IDC_SELECT, m_Select);
DDX_Control(pDX, IDC_REMOVEBRUSHES, m_RemoveBrushes);
DDX_Control(pDX, IDC_EDITMODEL, m_EditModel);
DDX_Control(pDX, IDC_EDITKEY, m_EditKey);
DDX_Control(pDX, IDC_EDITEVENT, m_EditEvent);
DDX_Control(pDX, IDC_DESELECT, m_Deselect);
DDX_Control(pDX, IDC_DELETEMODEL, m_DeleteModel);
DDX_Control(pDX, IDC_DELETEKEY, m_DeleteKey);
DDX_Control(pDX, IDC_DELETEEVENT, m_DeleteEvent);
DDX_Control(pDX, IDC_ADDMODEL, m_AddModel);
DDX_Control(pDX, IDC_ADDEVENT, m_AddEvent);
DDX_Control(pDX, IDC_ADDBRUSHES, m_AddBrushes);
DDX_Control(pDX, IDC_LOCKED, m_cbLocked);
DDX_Control(pDX, IDC_ANIMATE, m_AnimateButton);
DDX_Control(pDX, IDC_KEYSLIST, m_KeysList);
DDX_Control(pDX, IDC_MODELCOMBO, m_ModelCombo);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CModelsDlg, CDialog)
//{{AFX_MSG_MAP(CModelsDlg)
ON_BN_CLICKED(IDC_ADDMODEL, OnAddmodel)
ON_BN_CLICKED(IDC_DELETEMODEL, OnDeletemodel)
ON_BN_CLICKED(IDC_ADDBRUSHES, OnAddbrushes)
ON_BN_CLICKED(IDC_REMOVEBRUSHES, OnRemovebrushes)
ON_BN_CLICKED(IDC_SELECT, OnSelectBrushes)
ON_BN_CLICKED(IDC_DESELECT, OnDeselectBrushes)
ON_CBN_SELENDOK(IDC_MODELCOMBO, OnSelendokModelcombo)
ON_BN_CLICKED(IDC_ANIMATE, OnAnimate)
ON_BN_CLICKED(IDC_DELETEKEY, OnDeletekey)
ON_LBN_SELCHANGE(IDC_KEYSLIST, OnSelchangeKeyslist)
ON_BN_CLICKED(IDC_LOCKED, OnLocked)
ON_BN_CLICKED(IDC_CLONEMODEL, OnClonemodel)
ON_BN_CLICKED(IDC_SETMODELORIGIN, OnSetmodelorigin)
ON_BN_CLICKED(IDC_LOCKORIGIN, OnLockorigin)
ON_BN_CLICKED(IDC_ADDEVENT, OnAddevent)
ON_BN_CLICKED(IDC_DELETEEVENT, OnDeleteevent)
ON_BN_CLICKED(IDC_EDITEVENT, OnEditevent)
ON_BN_CLICKED(IDC_EDITKEY, OnEditkey)
ON_BN_CLICKED(IDC_EDITMODEL, OnEditmodel)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CModelsDlg message handlers
BOOL CModelsDlg::OnInitDialog()
{
CGlobals::PositionDialogUnderTabs(this);
CDialog::OnInitDialog();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
static const char ModelPrompt[] =
"One or more of the selected brushes is already owned by a model.\r"
"If you continue, those brushes will be removed from their current models\r"
"and placed in this model.\r\r"
"Do you want to continue?";
int CModelsDlg::GetUniqueModelName
(
CString const &Caption,
CString &ModelName
)
{
int rslt;
BOOL NameExists;
CKeyEditDlg Dlg (this, Caption, &ModelName);
do
{
// Get the model name.
// It has to be unique.
rslt = Dlg.DoModal ();
NameExists = TRUE;
if (rslt == IDOK)
{
if (ModelName == "")
{
rslt = AfxMessageBox( IDS_NOBLANKMODEL, MB_OKCANCEL ) ;
}
else if (ModelList_FindByName (pModelInfo->Models, ModelName) != NULL)
{
CString s;
s.Format( IDS_MODELEXISTS, ModelName);
rslt = MessageBox (s, NULL, MB_OKCANCEL);
}
else
{
NameExists = FALSE;
}
}
} while ((rslt == IDOK) && (NameExists));
return rslt;
}
void CModelsDlg::OnAddmodel()
{
CString ModelName;
int rslt;
if (SelBrushList_GetSize (pDoc->pSelBrushes) == 0)
{
MessageBox ("No brushes selected.", "Add Model", MB_ICONEXCLAMATION | MB_OK);
return;
}
// See if any of the selected brushes already belong to a model
if (SelectedBrushesInOtherModels (0))
{
if (MessageBox (ModelPrompt, "Add Model", MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2) != IDYES)
{
return;
}
}
ModelName = "";
rslt = GetUniqueModelName ("Enter model name", ModelName);
if (rslt == IDOK)
{
// add the new model to the list.
// This will set the model id fields in the model's brushes
if (ModelList_Add (pModelInfo->Models, ModelName, pDoc->pSelBrushes))
{
Model *m;
// get current model and update its object-to-world transform
m = ModelList_FindByName (pModelInfo->Models, ModelName);
assert (m != NULL);
pModelInfo->CurrentModel = Model_GetId (m);
UpdateModelsList ();
geXForm3d_SetIdentity (&XfmDelta);
// we add the first key (identity)
// (and don't allow it to be edited/deleted)
AddTheKey (m, 0.0f, &XfmDelta);
// rebuild trees when brushes added to model.
pDoc->RebuildTrees ();
}
PrivateUpdate ();
}
}
void CModelsDlg::OnDeletemodel()
// delete the current model.
// This sets the model brushes' model id to 0.
{
if (pModelInfo->CurrentModel != 0)
{
ModelList_Remove (pModelInfo->Models, pModelInfo->CurrentModel, Level_GetBrushes (pDoc->pLevel));
PrivateUpdate ();
pDoc->RebuildTrees ();
}
}
geBoolean CModelsDlg::SelectedBrushesInOtherModels
(
int ModelId
)
{
int iBrush;
int NumSelBrushes;
// First check to see if any of the selected brushes belong to some other model.
// If they do, then prompt the user.
NumSelBrushes = SelBrushList_GetSize (pDoc->pSelBrushes);
for (iBrush = 0; iBrush < NumSelBrushes; iBrush++)
{
Brush *pBrush;
int BrushModelId;
pBrush = SelBrushList_GetBrush (pDoc->pSelBrushes, iBrush);
BrushModelId = Brush_GetModelId (pBrush);
if ((BrushModelId != 0) && (BrushModelId != ModelId))
{
return GE_TRUE;
}
}
return GE_FALSE;
}
void CModelsDlg::OnAddbrushes()
// Add selected brushes to this model
{
Model *pModel;
int ModelId;
BOOL AddBrushes;
pModel = GetCurrentModel ();
if (pModel == NULL)
{
MessageBox ("No brushes selected.", "Add model brushes", MB_OK);
return;
}
AddBrushes = TRUE;
ModelId = Model_GetId (pModel);
if (SelectedBrushesInOtherModels (ModelId))
{
// prompt user
int rslt;
rslt = MessageBox (ModelPrompt, "Add model brushes", MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
if (rslt != IDYES)
{
AddBrushes = FALSE;
}
}
if (AddBrushes)
{
Model_AddBrushes (pModel, pDoc->pSelBrushes);
// make sure that all model brushes are selected if this is a locked model...
Brush *pBrush = SelBrushList_GetBrush (pDoc->pSelBrushes, 0);
pDoc->DoBrushSelection (pBrush, brushSelAlways);
// Have to rebuild the trees when brushes are added to a model.
pDoc->RebuildTrees ();
// Be very careful when speccing flags for UpdateAllViews()
// The wrong flags at the wrong time will totally screw things up
pDoc->UpdateAllViews (UAV_ALL3DVIEWS, NULL);
}
}
void CModelsDlg::OnRemovebrushes()
// remove selected brushes from this model
{
Model *pModel;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -