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

📄 modelsdlg.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	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 + -