📄 modelsdlg.cpp
字号:
pModel = GetCurrentModel ();
if (pModel != NULL)
{
Model_RemoveBrushes (pModel, pDoc->pSelBrushes);
pDoc->RebuildTrees ();
}
}
void CModelsDlg::OnSelectBrushes()
// Select all of the brushes that are in the current model
// This will deselect any other current selection??
{
Model *pModel;
pModel = GetCurrentModel ();
if (pModel != NULL)
{
int ModelId;
ModelId = Model_GetId (pModel);
// calls ConfigureCurrentTool, which calls UpdateAllViews()
pDoc->DoGeneralSelect ();
pDoc->ResetAllSelections ();
pDoc->SelectModelBrushes (TRUE, ModelId);
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);
}
}
void CModelsDlg::OnDeselectBrushes()
// Deselect all brushes that belong to the current model.
{
Model *pModel;
pModel = GetCurrentModel ();
if (pModel != NULL)
{
int CurrentModelId;
CurrentModelId = Model_GetId (pModel);
pDoc->SelectModelBrushes (FALSE, CurrentModelId);
pDoc->UpdateAllViews( UAV_ALL3DVIEWS, NULL );
}
}
void CModelsDlg::PostNcDestroy()
{
CDialog::PostNcDestroy();
/*
Modeless dialog boxes delete themselves.
(quiver, spasm, twitch)
*/
// delete this;
}
bool CModelsDlg::UpdateModels( CGenEditDoc *aDoc, ModelInfo_Type *aModelInfo)
{
// if (pDoc != aDoc)
{
pDoc = aDoc;
pModelInfo = aModelInfo;
PrivateUpdate ();
}
// Restore focus to active view
CMDIChildWnd *pMDIChild =(CMDIChildWnd *)pDoc->mpMainFrame->MDIGetActive();
if(pMDIChild)
{
CView *cv =(CView *)pMDIChild->GetActiveView();
if( cv)
cv->SetFocus();
}
return true;
}
void CModelsDlg::PrivateUpdate(void)
{
if (pDoc == NULL)
{
EnableControls (FALSE, NULL);
}
else
{
Model *pModel;
pModel = GetCurrentModel ();
UpdateModelsList ();
UpdateKeysList (pModel);
}
}
void CModelsDlg::UpdateModelsList
(
void
)
// updates the list of models in the combo box
// Puts the model's name in the text field, and the model id
// in SetItemData.
{
ModelIterator mi;
int Index;
Model *pModel;
m_ModelCombo.ResetContent ();
// add no-selection item.
// This one can't be deleted and should always be first!
Index = m_ModelCombo.AddString ("<none>");
if (Index != CB_ERR)
{
m_ModelCombo.SetItemData (Index, 0);
m_ModelCombo.SetCurSel (Index);
}
pModel = ModelList_GetFirst (pModelInfo->Models, &mi);
while (pModel != NULL)
{
int ModelId;
char const * ModelName;
ModelName = Model_GetName (pModel);
ModelId = Model_GetId (pModel);
Index = m_ModelCombo.AddString (ModelName);
m_ModelCombo.SetItemData (Index, ModelId);
if (ModelId == pModelInfo->CurrentModel)
{
m_ModelCombo.SetCurSel (Index);
}
pModel = ModelList_GetNext (pModelInfo->Models, &mi);
}
}
void CModelsDlg::SetListboxKeySelection
(
geFloat KeyTime
)
// Set listbox current position to first key that's >= passed key time.
{
int KeyNo;
for (KeyNo = 0; (KeyNo < m_KeysList.GetCount ()); ++KeyNo)
{
CString lbText;
m_KeysList.GetText (KeyNo, lbText);
// only interested in keys right now...
if (lbText[0] == 'K')
{
geFloat Time;
LONG lbData;
lbData = m_KeysList.GetItemData (KeyNo);
Time = *((geFloat *)&lbData);
if (Time >= KeyTime)
{
break;
}
}
}
if (KeyNo >= m_KeysList.GetCount ())
{
KeyNo = m_KeysList.GetCount () - 1;
}
m_KeysList.SetCurSel (KeyNo);
}
struct KeyEventEntry
{
geFloat Time;
char *pString;
};
static int __cdecl KeyEventCompare
(
void const *pvKey1,
void const *pvKey2
)
{
KeyEventEntry const *pKey1 = (KeyEventEntry const *)pvKey1;
KeyEventEntry const *pKey2 = (KeyEventEntry const *)pvKey2;
if (pKey1->Time < pKey2->Time) return -1;
if (pKey1->Time > pKey2->Time) return 1;
return 0;
}
void CModelsDlg::UpdateKeysList
(
Model *pModel
)
// Displays the current model's key frames and events in the list box.
{
gePath *pPath;
geMotion *pMotion;
KeyEventEntry *pKeyEventsList;
int KeyEventCount;
m_KeysList.ResetContent ();
if (pModel == NULL)
{
EnableControls (FALSE, NULL);
m_AddModel.EnableWindow (TRUE);
m_ModelCombo.EnableWindow (TRUE);
return;
}
if (!Animating)
{
EnableControls (TRUE, pModel);
}
// set state of Locked check...
m_cbLocked.SetCheck (Model_IsLocked (pModel) ? 1 : 0);
m_cbLockOrigin.SetCheck (Model_IsRotationLocked (pModel) ? 1 : 0);
m_cbLockOrigin.EnableWindow (Model_GetNumKeys (pModel) > 1);
#pragma message ("Clean this up and move path/motion twiddling to Model.c")
pPath = Model_GetPath (pModel);
pMotion = Model_GetMotion (pModel);
assert (pPath != NULL); // can't happen
assert (pMotion != NULL); // really!
pKeyEventsList = NULL;
// count number of keyframes and events and allocate
// array of KeyEventEntry structures...
{
int EventCount;
geFloat StartTime, EndTime;
geFloat EventTime;
char const *EventString;
int KeyframeCount;
KeyframeCount = gePath_GetKeyframeCount (pPath, GE_PATH_ROTATION_CHANNEL);
EventCount = 0;
/*
geMotion_GetEventExtents will crash if there are no events.
Which means that it's a useless function.
So we'll set the event extents to -10000..10000. This limits our
events range to +/- 10,000 seconds, or about 2 hours and 45 minutes.
*/
StartTime = -10000.0f;
EndTime = 10000.0f;
// if (geMotion_GetEventExtents (pMotion, &StartTime, &EndTime) != GE_FALSE)
{
EndTime += 1.0f;
geMotion_SetupEventIterator (pMotion, StartTime, EndTime);
while (geMotion_GetNextEvent (pMotion, &EventTime, &EventString) != GE_FALSE)
{
++EventCount;
}
}
KeyEventCount = EventCount + KeyframeCount;
// allocate the events buffer
if (KeyEventCount > 0)
{
pKeyEventsList = (KeyEventEntry *)geRam_Allocate(sizeof (KeyEventEntry) * KeyEventCount);
}
// fill the buffer
if (pKeyEventsList != NULL)
{
int ListItemNo;
KeyEventEntry *pEntry;
int i;
ListItemNo = 0;
// first the keyframes
for (i = 0; i < KeyframeCount; ++i)
{
geFloat Time;
geXForm3d Xfm;
char Text[100];
// Xfm isn't used here, just time for display
gePath_GetKeyframe (pPath, i, GE_PATH_ROTATION_CHANNEL, &Time, &Xfm);
sprintf (Text, "K %.2f", (float)Time);
pEntry = &pKeyEventsList[ListItemNo];
pEntry->Time = Time;
pEntry->pString = Util_Strdup (Text);
++ListItemNo;
}
// and then the events
if (EventCount > 0)
{
geMotion_SetupEventIterator (pMotion, StartTime, EndTime);
while (geMotion_GetNextEvent (pMotion, &EventTime, &EventString) != GE_FALSE)
{
int len;
char Text[20];
sprintf (Text, "E %.2f ()", (float)EventTime);
if (EventString == NULL)
{
EventString = "";
}
len = strlen (Text) + strlen (EventString) + 1;
pEntry = &pKeyEventsList[ListItemNo];
pEntry->Time = EventTime;
pEntry->pString = (char *)geRam_Allocate(len);
if (pEntry->pString != NULL)
{
sprintf (pEntry->pString, "E %.2f (%s)", (float)EventTime, EventString);
}
++ListItemNo;
}
}
assert (ListItemNo == KeyEventCount);
// sort the list by time...
qsort (pKeyEventsList, KeyEventCount, sizeof (KeyEventEntry), KeyEventCompare);
// fill up the listbox
for (i = 0; i < KeyEventCount; ++i)
{
int Index;
pEntry = &pKeyEventsList[i];
Index = m_KeysList.AddString (pEntry->pString);
if (Index != LB_ERR)
{
// Yes, that's an ugly cast. I want to pass the value as though it
// is a LONG, but I don't want to do any conversion...
m_KeysList.SetItemData (Index, *((LONG*)&(pEntry->Time)));
}
}
// and, finally, destroy the list
for (i = 0; i < KeyEventCount; ++i)
{
pEntry = &pKeyEventsList[i];
if (pEntry->pString != NULL)
{
geRam_Free (pEntry->pString);
pEntry->pString = NULL;
}
}
geRam_Free (pKeyEventsList);
}
}
SetListboxKeySelection (Model_GetCurrentKeyTime (pModel));
}
void CModelsDlg::OnSelendokModelcombo()
{
if (pDoc != NULL)
{
int Index;
Index = m_ModelCombo.GetCurSel ();
if (Index == CB_ERR)
{
pModelInfo->CurrentModel = 0;
}
else
{
pModelInfo->CurrentModel = m_ModelCombo.GetItemData (Index);
}
}
UpdateKeysList (GetCurrentModel ());
}
void CModelsDlg::OnOK()
{
// it's a modeless dialog. Don't allow OK.
}
void CModelsDlg::OnCancel()
{
if (Animating)
{
// can't close if we're animating...
::MessageBeep (MB_ICONEXCLAMATION);
return;
}
else
return;
}
Model *CModelsDlg::GetCurrentModel
(
void
)
{
int CurSel;
int CurrentModelId;
CurSel = m_ModelCombo.GetCurSel ();
if (CurSel == CB_ERR)
{
// no valid model selected
return NULL;
}
CurrentModelId = m_ModelCombo.GetItemData (CurSel);
if (CurrentModelId == 0)
{
// 0 is not a valid model number
return NULL;
}
// make sure model number is valid...
assert (CurrentModelId > 0);
return ModelList_FindById (pModelInfo->Models, CurrentModelId);
}
void CModelsDlg::AddTheKey
(
Model *pModel,
geFloat Time,
geXForm3d const *pXfm
)
// input pXfm must be model-relative!
{
Model_AddKeyframe (pModel, Time, pXfm);
UpdateKeysList (pModel);
}
void CModelsDlg::AddKey()
{
/*
User requested to add a key.
o Prompt the user for the motion time.
o Compute the transformation matrix using the model's reference transform.
o Add the key to the model's motion.
o Update list box and focus new item.
*/
float Time;
Model *pModel;
CString const Prompt = "Enter key time";
CString Value;
CFloatKeyEditDlg *pDlg;
int SaveNumKeys;
geBoolean GotKeyTime;
geXForm3d XfmCurrent;
pModel = GetCurrentModel ();
// shouldn't be able to get here w/o a selected model!
assert (pModel != NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -