📄 modelsdlg.cpp
字号:
// and transform to new position
Model_TransformFromTo (pModel, &XfmFrom, &XfmTo, Level_GetBrushes (pDoc->pLevel));
// set model's new current keyframe
Model_SetCurrentKeyTime (pModel, Time);
// 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);
m_EditKey.EnableWindow (TRUE);
m_DeleteKey.EnableWindow (TRUE);
m_EditEvent.EnableWindow (FALSE);
m_DeleteEvent.EnableWindow (FALSE);
break;
}
default :
assert (0); // bad key type returned
}
}
void CModelsDlg::OnLocked()
{
int Locked;
Model *pModel;
Locked = m_cbLocked.GetCheck ();
pModel = GetCurrentModel ();
if (pModel != NULL)
{
Model_SetLock (pModel, (Locked == 1));
}
}
void CModelsDlg::OnClonemodel()
{
CString ModelName;
Model *pModel;
char const *pName;
int CopyNum;
CString tag;
BrushList *BList = Level_GetBrushes (pDoc->pLevel);
pModel = GetCurrentModel ();
assert (pModel != NULL);
// Create default unique name.
pName = Model_GetName (pModel);
if (pName == NULL)
{
pName = "Model";
}
CopyNum = 0;
do
{
++CopyNum;
ModelName.Format ("%s_Copy%d", pName, CopyNum);
} while (ModelList_FindByName (pModelInfo->Models, ModelName) != NULL);
// Prompt user for name. If user cancels, then exit.
if (GetUniqueModelName ("Enter name for new model", ModelName) != IDOK)
{
return;
}
{
// Make list of cloned brushes.
BrushList *pNewBrushes;
Brush *pBrush;
BrushIterator bi;
Model *pNewModel;
int ModelId;
pNewBrushes = BrushList_Create ();
if (pNewBrushes == NULL)
{
MessageBox ("Out of memory.", "Clone model.", MB_OK | MB_ICONEXCLAMATION);
return;
}
// clone model brushes
ModelId = Model_GetId (pModel);
pBrush = BrushList_GetFirst (BList, &bi);
while (pBrush != NULL)
{
if (Brush_GetModelId (pBrush) == ModelId)
{
Brush *pNewBrush;
pNewBrush = Brush_Clone (pBrush);
BrushList_Append (pNewBrushes, pNewBrush);
}
pBrush = BrushList_GetNext (&bi);
}
pNewModel = ModelList_AddFromBrushList (pModelInfo->Models, ModelName, pNewBrushes);
if (pNewModel != NULL)
{
int Index;
int NewModelId;
// add brushes to doc's brush list (remove from temporary list)
pBrush = BrushList_GetFirst (pNewBrushes, &bi);
while (pBrush != NULL)
{
// remove from temporary list
BrushList_Remove (pNewBrushes, pBrush);
// add to doc's list
BrushList_Append (BList, pBrush);
pBrush = BrushList_GetNext (&bi);
}
// Copy model keys and other stuff
Model_CopyStuff (pNewModel, pModel);
// Add new model to combo box
NewModelId = Model_GetId (pNewModel);
Index = m_ModelCombo.AddString (ModelName);
m_ModelCombo.SetItemData (Index, NewModelId);
m_ModelCombo.SetCurSel (Index);
pModelInfo->CurrentModel = NewModelId;
// Select new model
OnSelectBrushes ();
// now move it just a bit to offset from the one we cloned
{
geXForm3d XfmMove;
// offset in X and Z only per artist request
geXForm3d_SetTranslation (&XfmMove, 100.0f, 0.0f, 100.0f);
Model_UpdateOrigin (pNewModel, BRUSH_MOVE, &(XfmMove.Translation));
Model_Transform (pNewModel, &XfmMove, BList);
}
// 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);
}
else
{
MessageBox ("Error cloning model.", "Clone model.", MB_OK | MB_ICONEXCLAMATION);
}
if (pNewBrushes != NULL)
{
BrushList_Destroy (&pNewBrushes);
}
}
}
void CModelsDlg::OnSetmodelorigin()
{
Model *pModel;
pModel = GetCurrentModel ();
if (SettingOrigin)
{
assert (pModel != NULL);
// Update model's reference transform to take new origin into account.
StopSettingOrigin (pModel);
// update UI to reflect new state
m_SetModelOrigin.SetWindowText ("Set &Origin");
SettingOrigin = GE_FALSE;
Animating = GE_FALSE;
Model_SetAnimating (pModel, GE_FALSE);
EnableControls (GE_TRUE, pModel);
}
else
{
if (pModel != NULL)
{
if (StartSettingOrigin (pModel))
{
Model_SetAnimating (pModel, GE_TRUE);
Animating = GE_TRUE;
SettingOrigin = GE_TRUE;
EnableControls (GE_FALSE, pModel);
m_SetModelOrigin.SetWindowText ("D&one");
m_SetModelOrigin.EnableWindow (TRUE);
}
}
}
}
geBoolean CModelsDlg::StartSettingOrigin
(
Model *pModel
)
/*
Here I insert a special ModelOrigin entity and select it.
Then allow user to move it as desired. When done, press the Done button.
*/
// Create ModelOrigin entity and place it at the model's current origin
{
geBoolean rslt;
CEntity Ent;
assert (pModel != NULL);
assert (EntityIndex == -1);
rslt = GE_FALSE;
if (pDoc->CreateEntityFromName ("ModelOrigin", Ent))
{
geVec3d org;
CEntityArray *Entities;
Model_GetCurrentPos (pModel, &org);
Ent.SetOrigin (org.X, org.Y, org.Z, Level_GetEntityDefs (pDoc->pLevel));
EntityIndex = Level_AddEntity (pDoc->pLevel, Ent);
pDoc->DoGeneralSelect (); // calls ConfigureCurrentTool()
// which calls UpdateAllViews()
pDoc->ResetAllSelections ();
Entities = Level_GetEntities (pDoc->pLevel);
pDoc->SelectEntity (&(*Entities)[EntityIndex]);
pDoc->mCurrentTool=ID_TOOLS_BRUSH_MOVEROTATEBRUSH;
// g3dc tuning comment
// ConfigureCurrentTool() already calls UpdateAllViews()
pDoc->ConfigureCurrentTool();
// Be very careful when speccing flags for UpdateAllViews()
// The wrong flags at the wrong time will totally screw things up
// g3dc tuning comment
// ConfigureCurrentTool() already calls UpdateAllViews()
// pDoc->UpdateAllViews (UAV_ALL3DVIEWS, NULL);
rslt = GE_TRUE;
}
return rslt;
}
void CModelsDlg::StopSettingOrigin
(
Model *pModel
)
{
geVec3d org, CurPos, VecDelta;
CEntity *pEnt;
CEntityArray *Entities = Level_GetEntities (pDoc->pLevel);
assert (pModel != NULL);
assert (EntityIndex != -1);
// reset the deltas...
geXForm3d_SetIdentity (&XfmDelta);
// get entity's position
pEnt = &(*Entities)[EntityIndex];
org = pEnt->mOrigin;
// get model's current position
Model_GetCurrentPos (pModel, &CurPos);
// compute deltas...
geVec3d_Subtract (&org, &CurPos, &VecDelta);
// and move the model's origin (but not the brushes!)
Model_UpdateOrigin (pModel, BRUSH_MOVE, &VecDelta);
// remove entity
pDoc->DeleteEntity (EntityIndex);
EntityIndex = -1;
// select the model
pDoc->ResetAllSelections ();
// select the model
OnSelectBrushes ();
}
void CModelsDlg::OnLockorigin()
{
int Locked;
Model *pModel;
Locked = m_cbLockOrigin.GetCheck ();
pModel = GetCurrentModel ();
if (pModel != NULL)
{
Model_SetRotationLock (pModel, (Locked == 1));
}
}
void CModelsDlg::OnAddevent()
{
EventEditType EventInfo;
CEventKeyEdit *pDlg;
Model *pModel;
pModel = GetCurrentModel ();
if (pModel == NULL)
{
return;
}
EventInfo.AddOrEdit = 'A';
pDlg = new CEventKeyEdit (this, &EventInfo);
if (pDlg != NULL)
{
if (pDlg->DoModal () == IDOK)
{
Model_AddEvent (pModel, EventInfo.Time, EventInfo.EventString);
UpdateKeysList (pModel);
}
}
}
void CModelsDlg::OnDeleteevent()
{
Model *pModel;
pModel = GetCurrentModel ();
if (pModel != NULL)
{
int CurSel;
geFloat Time, KeyTime;
int KeyType;
CurSel = GetCurrentLbKey (&Time, &KeyType);
if ((CurSel != LB_ERR) && (KeyType == KEY_TYPE_EVENT))
{
geXForm3d XfmFrom, XfmTo;
geXForm3d_SetIdentity (&XfmFrom);
geXForm3d_SetIdentity (&XfmTo);
Model_DeleteEvent (pModel, Time);
// get current transform
KeyTime = Model_GetCurrentKeyTime (pModel);
Model_GetKeyframe (pModel, KeyTime, &XfmFrom);
ReverseDeltas (pModel);
// position to key 0
Model_GetKeyframe (pModel, 0.0f, &XfmTo);
Model_TransformFromTo (pModel, &XfmFrom, &XfmTo, Level_GetBrushes (pDoc->pLevel));
Model_SetCurrentKeyTime (pModel, 0.0f);
// and finally update the views
// 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);
if (Model_GetNumKeys (pModel) == 1)
{
Model_SetRotationLock (pModel, FALSE);
m_cbLockOrigin.SetCheck (0);
m_cbLockOrigin.EnableWindow (FALSE);
}
UpdateKeysList (pModel);
}
}
}
void CModelsDlg::OnEditevent()
{
// TODO: Add your control notification handler code here
}
void CModelsDlg::OnEditkey()
{
int CurSel;
int KeyType;
geFloat OldTime, NewTime;
CurSel = GetCurrentLbKey (&OldTime, &KeyType);
if ((CurSel <= 0) || (KeyType != KEY_TYPE_KEYFRAME))
{
return;
}
static const CString Prompt = "Enter new key time";
CString Value;
Value.Format ("%f", OldTime);
Model *pModel = GetCurrentModel ();
geBoolean GotKeyTime = GE_FALSE;
CFloatKeyEditDlg Dlg (this, Prompt, &Value);
do
{
int rslt = Dlg.DoModal ();
if (rslt == IDOK)
{
geXForm3d XfmTemp;
// get the new time.
sscanf (Value, "%f", &NewTime);
if (NewTime <= 0.0f)
{
MessageBox ("Can't replace the first key.", "Edit key", MB_ICONEXCLAMATION | MB_OK);
GotKeyTime = GE_FALSE;
}
else if (Model_GetKeyframe (pModel, NewTime, &XfmTemp))
// if a key already exists at this time, then we need to prompt user.
{
CString msg;
msg.Format ("A key with time %s already exists.\rDo you want to replace it?", Value);
rslt = MessageBox (msg, "Edit key", MB_ICONQUESTION | MB_YESNOCANCEL);
switch (rslt)
{
case IDCANCEL :
{
ReverseDeltas (pModel);
// 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);
return;
}
case IDNO :
break;
case IDYES :
GotKeyTime = GE_TRUE;
Model_DeleteKeyframe (pModel, NewTime);
break;
}
}
else
{
GotKeyTime = GE_TRUE;
}
}
else
{
return;
}
} while (!GotKeyTime);
// get key information
geXForm3d XfmFrom;
Model_GetKeyframe (pModel, OldTime, &XfmFrom);
// delete the old key
OnDeletekey ();
// and then add this new key.
AddTheKey (pModel, NewTime, &XfmFrom);
}
void CModelsDlg::OnEditmodel()
{
// TODO: Add your control notification handler code here
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -