123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- // DlgLightAnimationEditor.cpp : implementation file
- //
- #include "stdafx.h"
- #include "WorldEditor.h"
- #include "DlgLightAnimationEditor.h"
- #include <Engine/Templates/Stock_CAnimData.h>
- #ifdef _DEBUG
- #undef new
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CDlgLightAnimationEditor dialog
- #define DEFAULT_ANIMATION_FILE "Temp\\DefaultAnimation.ani"
- INDEX CDlgLightAnimationEditor::GetSelectedLightAnimation(void)
- {
- // get curently selected light animation combo member
- INDEX iLightAnimation = m_LightAnimationCombo.GetCurSel();
- if( iLightAnimation == CB_ERR)
- {
- return 0;
- }
- return iLightAnimation;
- }
- CDlgLightAnimationEditor::CDlgLightAnimationEditor(CWnd* pParent /*=NULL*/)
- : CDialog(CDlgLightAnimationEditor::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CDlgLightAnimationEditor)
- m_fLightAnimationSpeed = 0.0f;
- m_iAnimationFrames = 0;
- m_strLightAnimationName = _T("");
- //}}AFX_DATA_INIT
- m_bCustomWindowsCreated = FALSE;
- m_fnSaveName = CTString("");
- // save default animation into temporary directory
- CAnimData adDefault;
- adDefault.DefaultAnimation();
- CTFileName fnDefaultAnimation = CTString( DEFAULT_ANIMATION_FILE);
- try {
- adDefault.Save_t( fnDefaultAnimation);
- } catch( char *pError) {
- FatalError( "Unable to save default animation: \"%s\", %s", (CTString&)fnDefaultAnimation, pError);
- }
- // try to load animation that was last edited
- try
- {
- CTFileName fnLastEditted = CTString( CStringA(theApp.GetProfileString(L"World editor", L"Last edited light animation", CString(DEFAULT_ANIMATION_FILE))));
- m_padAnimData = _pAnimStock->Obtain_t( fnLastEditted);
- m_fnSaveName = fnLastEditted;
- }
- catch( char *pError)
- {
- (void) pError;
- // try to load default animation
- try
- {
- m_padAnimData = _pAnimStock->Obtain_t( fnDefaultAnimation);
- }
- catch( char *pError2)
- {
- FatalError( "Unable to save and obtain default animation: \"%s\", %s", (CTString&)fnDefaultAnimation, pError2);
- }
- }
- // set animation data
- m_wndTestAnimation.m_aoAnimObject.SetData( m_padAnimData);
- m_bChanged = FALSE;
- }
- CDlgLightAnimationEditor::~CDlgLightAnimationEditor()
- {
- theApp.WriteProfileString(L"World editor", L"Last edited light animation", CString(m_padAnimData->GetName()));
- m_wndTestAnimation.m_aoAnimObject.SetData( NULL);
- _pAnimStock->Release( m_padAnimData);
- }
- void CDlgLightAnimationEditor::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- // if dialog is receiving data
- if( pDX->m_bSaveAndValidate == FALSE)
- {
- InitializeData();
- }
- //{{AFX_DATA_MAP(CDlgLightAnimationEditor)
- DDX_Control(pDX, IDC_LIGHT_ANIMATION_NAME_COMBO, m_LightAnimationCombo);
- DDX_Text(pDX, IDC_CURRENT_FRAME, m_strCurrentFrame);
- DDX_SkyFloat(pDX, IDC_LIGHT_ANIMATION_SPEED, m_fLightAnimationSpeed);
- DDX_Text(pDX, IDC_LIGHT_ANIMATION_FRAMES, m_iAnimationFrames);
- DDV_MinMaxInt(pDX, m_iAnimationFrames, 1, 999);
- DDX_Text(pDX, IDC_LIGHT_ANIMATION_NAME, m_strLightAnimationName);
- DDV_MaxChars(pDX, m_strLightAnimationName, 30);
- //}}AFX_DATA_MAP
- // if dialog is giving data
- if( pDX->m_bSaveAndValidate != FALSE )
- {
- StoreData();
- }
- }
- BEGIN_MESSAGE_MAP(CDlgLightAnimationEditor, CDialog)
- //{{AFX_MSG_MAP(CDlgLightAnimationEditor)
- ON_WM_PAINT()
- ON_BN_CLICKED(IDC_DELETE_MARKER, OnDeleteMarker)
- ON_EN_CHANGE(IDC_LIGHT_ANIMATION_FRAMES, OnChangeLightAnimationFrames)
- ON_CBN_SELCHANGE(IDC_LIGHT_ANIMATION_NAME_COMBO, OnSelchangeLightAnimationNameCombo)
- ON_EN_CHANGE(IDC_LIGHT_ANIMATION_SPEED, OnChangeLightAnimationSpeed)
- ON_BN_CLICKED(IDC_SCROLL_LEFT, OnScrollLeft)
- ON_BN_CLICKED(IDC_SCROLL_RIGHT, OnScrollRight)
- ON_BN_CLICKED(IDC_SCROLL_PG_LEFT, OnScrollPgLeft)
- ON_BN_CLICKED(IDC_SCROLL_PG_RIGHT, OnScrollPgRight)
- ON_BN_CLICKED(ID_DELETE_ANIMATION, OnDeleteAnimation)
- ON_BN_CLICKED(ID_ADD_ANIMATION, OnAddAnimation)
- ON_EN_CHANGE(IDC_LIGHT_ANIMATION_NAME, OnChangeLightAnimationName)
- ON_BN_CLICKED(ID_LOAD_ANIMATION, OnLoadAnimation)
- ON_BN_CLICKED(ID_SAVE_ANIMATION, OnSaveAnimation)
- ON_BN_CLICKED(ID_SAVE_AS_ANIMATION, OnSaveAsAnimation)
- ON_BN_CLICKED(ID_CLOSE, OnButtonClose)
- ON_BN_CLICKED(IDCANCEL, OnCancel)
- ON_WM_CLOSE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CDlgLightAnimationEditor message handlers
- void CDlgLightAnimationEditor::InitializeData(void)
- {
- if( !IsWindow( m_LightAnimationCombo.m_hWnd)) return;
- // set dialog window title
- CTString strTitle = m_padAnimData->GetName();
- if( (strTitle == "") || (strTitle ==DEFAULT_ANIMATION_FILE) )
- {
- strTitle = "<unnamed>";
- }
- SetWindowText( CString(CTString("Editing animation: ") + strTitle));
- // get currently selected light animation combo member
- INDEX iLightAnimation = m_LightAnimationCombo.GetCurSel();
- if( iLightAnimation != CB_ERR)
- {
- m_wndTestAnimation.m_aoAnimObject.StartAnim( iLightAnimation);
- // obtain information about animation
- CAnimInfo aiInfo;
- m_padAnimData->GetAnimInfo(iLightAnimation, aiInfo);
- // set info into controls
- m_fLightAnimationSpeed = aiInfo.ai_SecsPerFrame;
- m_iAnimationFrames = aiInfo.ai_NumberOfFrames;
- m_strLightAnimationName = aiInfo.ai_AnimName;
- // set current frame text
- char achrFrame[ 64];
- sprintf( achrFrame, "Frame: %d", m_wndAnimationFrames.m_iSelectedFrame);
- m_strCurrentFrame = achrFrame;
- // redraw frames
- if( IsWindow(m_wndAnimationFrames.m_hWnd))
- {
- // enable/disable delete key-frame button
- GetDlgItem(IDC_DELETE_MARKER)->EnableWindow(
- m_wndAnimationFrames.IsSelectedFrameKeyFrame() );
- m_wndAnimationFrames.Invalidate( FALSE);
- }
- }
- }
- void CDlgLightAnimationEditor::StoreData(void)
- {
- // get curently selected light animation combo member
- INDEX iLightAnimation = m_LightAnimationCombo.GetCurSel();
- if( iLightAnimation == CB_ERR)
- {
- return;
- }
- // and set new name to anim data
- m_padAnimData->SetName( iLightAnimation, CTString(CStringA(m_strLightAnimationName)));
- //------------ Prepare new array of frames for current animation (key frames changing is
- // not applied here but in control LMB down handler)
- CAnimData *pAD = m_padAnimData;
- // obtain information about animation
- CAnimInfo aiInfo;
- pAD->GetAnimInfo(iLightAnimation, aiInfo);
- // get count of old frames
- INDEX ctOldFrames = aiInfo.ai_NumberOfFrames;
- // create array for new frames
- INDEX *piNewFrames = new INDEX[ m_iAnimationFrames];
- // now copy old array over new one but if new one is longer than old one, added
- // frames will be filled with last value (RGBA format)
- for( INDEX iFrame=0; iFrame<m_iAnimationFrames; iFrame++)
- {
- // if we are copying old frames
- if( iFrame<ctOldFrames)
- {
- piNewFrames[iFrame]=pAD->GetFrame(iLightAnimation, iFrame);
- // if we are adding last frame, delete its key-frame marker
- if( (m_iAnimationFrames>ctOldFrames) && (iFrame==(ctOldFrames-1)) && (iFrame != 0) )
- {
- piNewFrames[iFrame] &= 0xFFFFFF00;
- }
- }
- // if we are adding new frames
- else
- {
- // obtain last frame in old animation
- INDEX iLastFrame = pAD->GetFrame(iLightAnimation, ctOldFrames-1);
- // clear alpha chanell (we don't want added frames to be key frames)
- iLastFrame &= 0xFFFFFF00;
- // clone last frame from ole animation as added frames in new animation
- piNewFrames[iFrame]=iLastFrame;
- }
- }
- // set alpha to 0xFF to mark key frame for last frame (first and last frames must be keys)
- piNewFrames[m_iAnimationFrames-1] |= 0x000000FF;
- // set new speed
- pAD->SetSpeed( iLightAnimation, m_fLightAnimationSpeed);
- // set new frames
- pAD->SetFrames( iLightAnimation, m_iAnimationFrames, piNewFrames);
- // spread frames
- SpreadFrames();
- // delete allocated array
- delete piNewFrames;
- m_bChanged = TRUE;
- }
- void CDlgLightAnimationEditor::SpreadFrames(void)
- {
- // get curently selected light animation combo member
- INDEX iLightAnimation = m_LightAnimationCombo.GetCurSel();
- if( iLightAnimation == CB_ERR)
- {
- return;
- }
- // obtain information about animation
- CAnimInfo aiInfo;
- CAnimData *pAD = m_padAnimData;
- pAD->GetAnimInfo(iLightAnimation, aiInfo);
- // get count of frames
- INDEX ctFrames = aiInfo.ai_NumberOfFrames;
- // create array to be copy of current frames array
- INDEX *piFrames = new INDEX[ ctFrames];
- // now copy old array over new one
- for( INDEX iFrame=0; iFrame<m_iAnimationFrames; iFrame++)
- {
- piFrames[iFrame]=pAD->GetFrame(iLightAnimation, iFrame);
- }
- // we will start spreading from first frame
- INDEX iStart=0;
- // now spread frames beetween key-frames
- do
- {
- // find first next key frame
- INDEX iKeySearcher=iStart+1;
- for( ; iKeySearcher<ctFrames; iKeySearcher++)
- {
- // is this gradient key frame?
- if( (piFrames[iKeySearcher] & 0x000000FF) != 0)
- {
- // yes it is, stop searching
- break;
- }
- }
- // get starting R, G, B values
- FLOAT fStartR = (FLOAT) ((piFrames[iStart]>>24) & 0x000000FF);
- FLOAT fStartG = (FLOAT) ((piFrames[iStart]>>16) & 0x000000FF);
- FLOAT fStartB = (FLOAT) ((piFrames[iStart]>>8 ) & 0x000000FF);
- // calculate R, G and B deltas
- FLOAT fdR = ( (FLOAT)((piFrames[iKeySearcher]>>24) & 0x000000FF)-
- ((piFrames[iStart]>>24) & 0x000000FF) )/(iKeySearcher-iStart);
- FLOAT fdG = ( (FLOAT)((piFrames[iKeySearcher]>>16) & 0x000000FF)-
- ((piFrames[iStart]>>16) & 0x000000FF) )/(iKeySearcher-iStart);
- FLOAT fdB = ( (FLOAT)((piFrames[iKeySearcher]>>8) & 0x000000FF)-
- ((piFrames[iStart]>>8) & 0x000000FF) )/(iKeySearcher-iStart);
- INDEX iDeltaTimes=1;
- // create gradients beetween iStart and iKeySearcher
- for( INDEX iGradient=iStart+1; iGradient<iKeySearcher; iGradient++)
- {
- FLOAT fCurrentR = fStartR+fdR*iDeltaTimes;
- FLOAT fCurrentG = fStartG+fdG*iDeltaTimes;
- FLOAT fCurrentB = fStartB+fdB*iDeltaTimes;
- COLOR colNR = (COLOR) fCurrentR;
- COLOR colNG = (COLOR) fCurrentG;
- COLOR colNB = (COLOR) fCurrentB;
- piFrames[iGradient]= (colNR<<24) | (colNG<<16) | (colNB<<8);
- // next delta
- iDeltaTimes ++;
- }
- // next gradient will start at last key frame
- iStart = iKeySearcher;
- }
- while( iStart < ctFrames);
- // set new frames
- pAD->SetFrames( iLightAnimation, ctFrames, piFrames);
- // delete allocated array
- delete piFrames;
- // redraw frames
- if( IsWindow(m_wndAnimationFrames.m_hWnd))
- {
- m_wndAnimationFrames.Invalidate( FALSE);
- }
- }
- void CDlgLightAnimationEditor::OnPaint()
- {
- {
- CPaintDC dc(this); // device context for painting
- }
- if( !m_bCustomWindowsCreated)
- {
- // ---------------- Create custom window that will hold graphical representation of frames
- // obtain frames area window
- CWnd *pWndFramesArea = GetDlgItem(IDC_FRAMES_AREA);
- ASSERT(pWndFramesArea != NULL);
- // obtain frames area frame control's rectangle
- CRect rectFramesArea;
- pWndFramesArea->GetWindowRect(&rectFramesArea);
- ScreenToClient(&rectFramesArea);
- // create window for area to contain frames
- m_wndAnimationFrames.Create( NULL, NULL, WS_BORDER|WS_VISIBLE, rectFramesArea,
- this, IDW_ANIMATION_FRAMES);
- m_wndAnimationFrames.SetParentDlg( this);
- // ---------------- Create custom window that show how light animation looks like
- CWnd *pWndTestArea = GetDlgItem(IDC_TEST_AREA);
- ASSERT(pWndTestArea != NULL);
- CRect rectTestArea;
- pWndTestArea->GetWindowRect(&rectTestArea);
- ScreenToClient(&rectTestArea);
- // create window for for animation testing
- m_wndTestAnimation.Create( NULL, NULL, WS_BORDER|WS_VISIBLE, rectTestArea,
- this, IDW_ANIMATION_FRAMES);
- m_wndTestAnimation.SetParentDlg( this);
- // mark that custom windows are created
- m_bCustomWindowsCreated = TRUE;
- }
- }
- BOOL CDlgLightAnimationEditor::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // initialize light animation combo
- InitLightAnimationCombo();
- m_LightAnimationCombo.SetCurSel(0);
- // initialize
- UpdateData( FALSE);
- return TRUE;
- }
- void CDlgLightAnimationEditor::OnDeleteMarker()
- {
- // delete selected frame
- m_wndAnimationFrames.DeleteSelectedFrame();
- }
- void CDlgLightAnimationEditor::OnChangeLightAnimationFrames()
- {
- // store data state from dialog into animation data
- if( IsWindow(m_LightAnimationCombo.m_hWnd))
- {
- // reset starting and selected frames
- m_wndAnimationFrames.m_iStartingFrame = 0;
- m_wndAnimationFrames.m_iSelectedFrame = 0;
- UpdateData( TRUE);
- }
- }
- void CDlgLightAnimationEditor::InitLightAnimationCombo(void)
- {
- // clear combo box
- m_LightAnimationCombo.ResetContent();
- // limit animation lenght
- m_LightAnimationCombo.LimitText(NAME_SIZE);
- // initialize light animations combo box
- for(INDEX iAnimation=0;iAnimation<m_padAnimData->GetAnimsCt(); iAnimation++)
- {
- // obtain information about animation
- CAnimInfo aiInfo;
- m_padAnimData->GetAnimInfo(iAnimation, aiInfo);
- // add animation name
- m_LightAnimationCombo.AddString( CString(aiInfo.ai_AnimName));
- }
- }
- void CDlgLightAnimationEditor::OnScrollLeft()
- {
- m_wndAnimationFrames.ScrollLeft();
- }
- void CDlgLightAnimationEditor::OnScrollRight()
- {
- m_wndAnimationFrames.ScrollRight();
- }
- void CDlgLightAnimationEditor::OnScrollPgLeft()
- {
- m_wndAnimationFrames.ScrollPgLeft();
- }
- void CDlgLightAnimationEditor::OnScrollPgRight()
- {
- m_wndAnimationFrames.ScrollPgRight();
- }
- void CDlgLightAnimationEditor::OnSelchangeLightAnimationNameCombo()
- {
- // reset starting and selected frames
- m_wndAnimationFrames.m_iStartingFrame = 0;
- m_wndAnimationFrames.m_iSelectedFrame = 0;
- UpdateData( FALSE);
- }
- void CDlgLightAnimationEditor::OnChangeLightAnimationSpeed()
- {
- // store data state from dialog into animation data
- if( IsWindow(m_LightAnimationCombo.m_hWnd))
- {
- UpdateData( TRUE);
- }
- }
- void CDlgLightAnimationEditor::OnDeleteAnimation()
- {
- // get newly selected animation
- INDEX iAnimation = m_LightAnimationCombo.GetCurSel();
- m_padAnimData->DeleteAnimation( iAnimation);
- InitLightAnimationCombo();
- m_LightAnimationCombo.SetCurSel( 0);
- UpdateData( FALSE);
- }
- void CDlgLightAnimationEditor::OnAddAnimation()
- {
- m_padAnimData->AddAnimation();
- // select newly added animation
- InitLightAnimationCombo();
- m_LightAnimationCombo.SetCurSel(m_padAnimData->GetAnimsCt()-1);
- // reset starting and selected frames
- m_wndAnimationFrames.m_iStartingFrame = 0;
- m_wndAnimationFrames.m_iSelectedFrame = 0;
- UpdateData( FALSE);
- }
- void CDlgLightAnimationEditor::OnChangeLightAnimationName()
- {
- UpdateData( TRUE);
- INDEX iAnimation = m_LightAnimationCombo.GetCurSel();
- InitLightAnimationCombo();
- m_LightAnimationCombo.SetCurSel( iAnimation);
- }
- void CDlgLightAnimationEditor::OnLoadAnimation()
- {
- CTFileName fnAnimation = _EngineGUI.FileRequester(
- "Load animation file",
- "Animation file (*.ani)\0*.ani\0" FILTER_ALL FILTER_END,
- "Animation directory", "");
- if( fnAnimation == "") return;
- try
- {
- _pAnimStock->Release( m_padAnimData);
- m_padAnimData = _pAnimStock->Obtain_t( fnAnimation);
- m_fnSaveName = fnAnimation;
- }
- catch( char *strError)
- {
- WarningMessage( strError);
- try
- {
- CTFileName fnDefaultAnimation = CTString( DEFAULT_ANIMATION_FILE);
- m_padAnimData = _pAnimStock->Obtain_t( fnDefaultAnimation);
- }
- catch( char *strError2)
- {
- FatalError( strError2);
- }
- }
- // initialize light animation combo
- InitLightAnimationCombo();
- // set animation data
- m_wndTestAnimation.m_aoAnimObject.SetData( m_padAnimData);
- m_LightAnimationCombo.SetCurSel(0);
- UpdateData( FALSE);
- }
- void CDlgLightAnimationEditor::OnSaveAnimation()
- {
- if( m_fnSaveName == "")
- {
- OnSaveAsAnimation();
- }
- else
- {
- try
- {
- CTFileStream strmFile;
- strmFile.Create_t( m_fnSaveName);
- // write animation from file
- m_padAnimData->Write_t( &strmFile);
- strmFile.Close();
- // refresh animation
- CAnimData *pad = _pAnimStock->Obtain_t(m_fnSaveName);
- pad->Reload();
- _pAnimStock->Release(pad);
- }
- catch( char *strError)
- {
- WarningMessage( strError);
- }
- }
- }
- void CDlgLightAnimationEditor::OnSaveAsAnimation()
- {
- CTFileName fnAnimation = _EngineGUI.FileRequester(
- "Save animation file",
- "Animation file (*.ani)\0*.ani\0" FILTER_ALL FILTER_END,
- "Animation directory", "", "", NULL, FALSE);
- if( fnAnimation == "") return;
- try
- {
- CTFileStream strmFile;
- strmFile.Create_t( fnAnimation);
- // write animation into file
- m_padAnimData->Write_t( &strmFile);
- m_fnSaveName = fnAnimation;
- strmFile.Close();
- // refresh animation
- CAnimData *pad = _pAnimStock->Obtain_t(m_fnSaveName);
- pad->Reload();
- _pAnimStock->Release(pad);
- }
- catch( char *strError)
- {
- WarningMessage( strError);
- }
- }
- void CDlgLightAnimationEditor::OnButtonClose()
- {
- if( m_bChanged) OnSaveAnimation();
- EndDialog( 0);
- }
- void CDlgLightAnimationEditor::OnCancel()
- {
- if( m_bChanged) OnSaveAnimation();
- EndDialog( 0);
- }
- void CDlgLightAnimationEditor::OnClose()
- {
- if( m_bChanged) OnSaveAnimation();
- CDialog::OnClose();
- }
- void CDlgLightAnimationEditor::OnOK()
- {
- }
|