⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modelsdlg.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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 + -