📄 modelsdlg.cpp
字号:
SaveNumKeys = Model_GetNumKeys (pModel); // need to know this...
assert (SaveNumKeys > 0); // I think this is required...
// get the current key.
// We have to do this here because the key might be deleted before we're
// ready to muck with the current transform.
Model_GetKeyframe (pModel, Model_GetCurrentKeyTime (pModel), &XfmCurrent);
GotKeyTime = GE_FALSE;
do
{
int rslt;
geXForm3d XfmTemp;
// prompt user for time
pDlg = new CFloatKeyEditDlg (this, Prompt, &Value);
rslt = pDlg->DoModal ();
delete pDlg;
if (rslt != IDOK)
{
// user cancelled
ReverseDeltas (pModel);
// and 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 );
return;
}
sscanf (Value, "%f", &Time);
if (Time <= 0.0f)
{
rslt = MessageBox ("Key time must be greater than 0.", "Add key", MB_ICONINFORMATION | MB_OKCANCEL);
if (rslt == 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;
}
}
else if (Model_GetKeyframe (pModel, Time, &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, "Add 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, Time);
break;
}
}
else
{
GotKeyTime = GE_TRUE;
}
} while (!GotKeyTime);
{
// apply deltas (world-relative in XfmDelta)
// to current object-relative transform.
geVec3d VecXlate;
// back out the translations
VecXlate = XfmCurrent.Translation;
geXForm3d_Translate (&XfmCurrent, -VecXlate.X, -VecXlate.Y, -VecXlate.Z);
// do the rotation
geXForm3d_Multiply (&XfmDelta, &XfmCurrent, &XfmCurrent);
// and re-apply the translations
geXForm3d_Translate (&XfmCurrent, VecXlate.X, VecXlate.Y, VecXlate.Z);
AddTheKey (pModel, Time, &XfmCurrent);
// deltas are again 0...
geXForm3d_SetIdentity (&XfmDelta);
}
if ((SaveNumKeys == 1) && (Model_GetNumKeys (pModel) > 1))
{
// there was only one key, and now there are multiple keys.
// Which means that the RotationLock was disabled and the
// checkbox was disabled. Enable them.
Model_SetRotationLock (pModel, GE_TRUE);
m_cbLockOrigin.SetCheck (1);
m_cbLockOrigin.EnableWindow (TRUE);
}
SetListboxKeySelection (Time);
Model_SetCurrentKeyTime (pModel, Time);
}
void CModelsDlg::GetTranslation (geVec3d *pVec)
{
*pVec = XfmDelta.Translation;
}
void CModelsDlg::UpdateSelectedModel
(
int MoveRotate,
geVec3d const *pVecDelta
)
{
Model *pModel;
pModel = GetCurrentModel ();
if (Animating && (pModel != NULL))
{
geXForm3d *pXfm;
// apply translation/rotation to model's delta position
pXfm = &XfmDelta;
switch (MoveRotate)
{
case BRUSH_MOVE :
{
// simple translation
geXForm3d_Translate (pXfm, pVecDelta->X, pVecDelta->Y, pVecDelta->Z);
break;
}
case BRUSH_ROTATE :
{
geXForm3d XfmRotate;
// build rotation transform from angles
geXForm3d_SetEulerAngles (&XfmRotate, pVecDelta);
// and apply it
{
/*
The problem here is that this new rotation has to be
applied AFTER the existing rotations. So I need to
back out the current translations, apply this rotation,
and then re-apply the translations.
*/
geVec3d VecXlate;
VecXlate = pXfm->Translation;
geVec3d_Clear (&(pXfm->Translation));
geXForm3d_Multiply (&XfmRotate, pXfm, pXfm);
pXfm->Translation = VecXlate;
}
break;
}
default:
// what did you want to do?
assert (0);
break;
}
}
}
void CModelsDlg::EnableControls
(
BOOL Enable,
Model const *pModel
)
// This function called to enable/disable dialog controls
{
#pragma message ("VCR control buttons disabled")
// Permamently disable the VCR control buttons...
m_Stop.EnableWindow (FALSE);
m_rrStart.EnableWindow (FALSE);
m_rrFrame.EnableWindow (FALSE);
m_Play.EnableWindow (FALSE);
m_ffFrame.EnableWindow (FALSE);
m_ffEnd.EnableWindow (FALSE);
m_Select.EnableWindow (Enable);
m_RemoveBrushes.EnableWindow (Enable);
m_AddModel.EnableWindow (Enable);
#pragma message ("Edit Model button disabled")
m_EditModel.EnableWindow (FALSE);
m_DeleteModel.EnableWindow (Enable);
m_EditKey.EnableWindow (Enable);
m_DeleteKey.EnableWindow (Enable);
m_AddEvent.EnableWindow (Enable);
#pragma message ("Edit Event button disabled")
m_EditEvent.EnableWindow (FALSE);
m_DeleteEvent.EnableWindow (Enable);
m_Deselect.EnableWindow (Enable);
m_AddBrushes.EnableWindow (Enable);
m_cbLocked.EnableWindow (Enable);
m_KeysList.EnableWindow (Enable);
m_ModelCombo.EnableWindow (Enable);
m_CloneModel.EnableWindow (Enable);
m_SetModelOrigin.EnableWindow (Enable);
m_AnimateButton.EnableWindow (Enable);
if ((pModel == NULL) || !Enable)
{
m_cbLockOrigin.EnableWindow (FALSE);
}
else
{
m_cbLockOrigin.EnableWindow ((Model_GetNumKeys (pModel) > 1));
}
if ((pModel != NULL) && Enable)
{
int CurSel;
int KeyType;
geFloat Time;
CurSel = GetCurrentLbKey (&Time, &KeyType);
m_EditKey.EnableWindow ((KeyType == KEY_TYPE_KEYFRAME));
#pragma message ("Editing events disabled")
// m_EditEvent.EnableWindow ((KeyType == KEY_TYPE_EVENT));
m_DeleteKey.EnableWindow ((KeyType == KEY_TYPE_KEYFRAME));
m_DeleteEvent.EnableWindow ((KeyType == KEY_TYPE_EVENT));
}
}
void CModelsDlg::OnAnimate()
{
Model *pModel;
pModel = GetCurrentModel ();
if (Animating)
{
assert (pModel != NULL); // can't happen (right?)
// Stop animating and add key at this position
Model_SetAnimating (pModel, GE_FALSE);
Animating = GE_FALSE;
EnableControls (TRUE, pModel);
m_AnimateButton.SetWindowText ("&Animate");
m_AnimateButton.EnableWindow (TRUE);
AddKey ();
}
else
{
if (pModel != NULL)
{
// start animating
Animating = GE_TRUE;
Model_SetAnimating (pModel, GE_TRUE);
EnableControls (FALSE, pModel);
geXForm3d_SetIdentity (&XfmDelta);
m_AnimateButton.SetWindowText ("Stop &Animating");
m_AnimateButton.EnableWindow (TRUE);
OnSelectBrushes (); // selects the model and all of its brushes
}
}
}
int CModelsDlg::GetCurrentLbKey
(
geFloat *pTime,
int *pKeyType
)
// Returns the key number of the current listbox selection
// Returns 0 if no keys.
{
int CurSel;
int KeyNo;
int EventNo;
int retval;
CString lbText;
LONG lbData;
int KeyType;
assert (pTime != NULL);
assert (pKeyType != NULL);
CurSel = m_KeysList.GetCurSel ();
if (CurSel == LB_ERR)
{
return 0;
}
m_KeysList.GetText (CurSel, lbText);
lbData = m_KeysList.GetItemData (CurSel);
// ugly cast.
// The item returned is a float that's stored in a long.
*pTime = *((geFloat *)&lbData);
// now iterate the listbox items counting the keys until we get here...
KeyNo = 0;
EventNo = 0;
retval = 0;
KeyType = KEY_TYPE_INVALID;
for (int i = 0; i < m_KeysList.GetCount (); ++i)
{
m_KeysList.GetText (i, lbText);
switch (lbText[0])
{
case 'E' :
retval = EventNo;
KeyType = KEY_TYPE_EVENT;
++EventNo;
break;
case 'K' :
KeyType = KEY_TYPE_KEYFRAME;
retval = KeyNo;
++KeyNo;
break;
default :
assert (0); // something bad in listbox
}
if (i == CurSel)
{
*pKeyType = KeyType;
return retval;
}
}
assert (0); // current selection bigger than key count?
return -1;
}
void CModelsDlg::ReverseDeltas
(
Model *pModel
)
{
// This code figures out where we are, then calls Model_TransformFromTo
// to put us back to the current key.
geVec3d VecXlate;
geXForm3d XfmCurrent;
geXForm3d XfmWork;
assert (pModel != NULL);
// get the current key
Model_GetKeyframe (pModel, Model_GetCurrentKeyTime (pModel), &XfmCurrent);
// XfmWork is used to calculate current position.
XfmWork = XfmCurrent;
// back out the translations
VecXlate = XfmWork.Translation;
geXForm3d_Translate (&XfmWork, -VecXlate.X, -VecXlate.Y, -VecXlate.Z);
// do the rotation
geXForm3d_Multiply (&XfmDelta, &XfmWork, &XfmWork);
// and re-apply the translations
geXForm3d_Translate (&XfmWork, VecXlate.X, VecXlate.Y, VecXlate.Z);
Model_TransformFromTo (pModel, &XfmWork, &XfmCurrent, Level_GetBrushes (pDoc->pLevel));
// deltas are cleared!
geXForm3d_SetIdentity (&XfmDelta);
}
void CModelsDlg::OnDeletekey()
// delete the selected key
{
Model *pModel;
pModel = GetCurrentModel ();
if (pModel != NULL)
{
int CurSel;
geFloat Time;
int KeyType;
CurSel = GetCurrentLbKey (&Time, &KeyType);
if ((CurSel != LB_ERR) && (KeyType == KEY_TYPE_KEYFRAME) && (Time != 0.0f)) // can't delete first key!!
{
geXForm3d XfmFrom, XfmTo;
geXForm3d_SetIdentity (&XfmFrom);
geXForm3d_SetIdentity (&XfmTo);
Time = Model_GetCurrentKeyTime (pModel);
// get current transform
Model_GetKeyframe (pModel, Time, &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);
// remove this keyframe from the model
Model_DeleteKeyframe (pModel, Time);
// and from the listbox
// m_KeysList.DeleteString (CurSel);
// 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::OnSelchangeKeyslist()
{
// selection has changed.
// Move to the new selection
Model *pModel;
int CurSel;
geFloat Time;
int KeyType;
pModel = GetCurrentModel ();
assert (pModel != NULL); // MUST exist if we get here
CurSel = GetCurrentLbKey (&Time, &KeyType);
switch (KeyType)
{
case KEY_TYPE_EVENT :
m_EditKey.EnableWindow (FALSE);
#pragma message ("Editing events disabled")
m_EditEvent.EnableWindow (FALSE);
// m_EditEvent.EnableWindow (TRUE);
m_DeleteKey.EnableWindow (FALSE);
m_DeleteEvent.EnableWindow (TRUE);
break;
case KEY_TYPE_KEYFRAME :
{
geXForm3d XfmFrom;
geXForm3d XfmTo;
ReverseDeltas (pModel);
// current position
Model_GetKeyframe (pModel, Model_GetCurrentKeyTime (pModel), &XfmFrom);
// get transform to new position
Model_GetKeyframe (pModel, Time, &XfmTo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -