Added aqua_speed for rite geo 50 tryker
[ryzomcore.git] / nel / tools / 3d / object_viewer / animation_set_dlg.cpp
blobf69a37b43b534c947c573ca2b7f1e464a5a54bf0
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "std_afx.h"
21 #include "object_viewer.h"
22 #include "animation_set_dlg.h"
24 #include "nel/misc/file.h"
25 #include "nel/3d/track_keyframer.h"
28 using namespace NLMISC;
29 using namespace NL3D;
31 /////////////////////////////////////////////////////////////////////////////
32 // CAnimationSetDlg dialog
35 CAnimationSetDlg::CAnimationSetDlg(CObjectViewer* objView, CWnd* pParent /*=NULL*/)
36 : CDialog(CAnimationSetDlg::IDD, pParent)
38 //{{AFX_DATA_INIT(CAnimationSetDlg)
39 UseMixer = 0;
40 //}}AFX_DATA_INIT
42 _ObjView=objView;
46 void CAnimationSetDlg::DoDataExchange(CDataExchange* pDX)
48 CDialog::DoDataExchange(pDX);
49 //{{AFX_DATA_MAP(CAnimationSetDlg)
50 DDX_Control(pDX, IDC_EDITED_OBJECT, EditedObject);
51 DDX_Control(pDX, IDC_PLAYLIST, PlayList);
52 DDX_Control(pDX, IDC_TREE2, SkelTree);
53 DDX_Control(pDX, IDC_TREE, Tree);
54 DDX_Radio(pDX, IDC_USE_LIST, UseMixer);
55 //}}AFX_DATA_MAP
59 BEGIN_MESSAGE_MAP(CAnimationSetDlg, CDialog)
60 //{{AFX_MSG_MAP(CAnimationSetDlg)
61 ON_BN_CLICKED(IDC_ADD_ANIMATION, OnAddAnimation)
62 ON_BN_CLICKED(IDC_RESET, OnReset)
63 ON_BN_CLICKED(IDC_ADD_SKEL_WT, OnAddSkelWt)
64 ON_WM_DESTROY()
65 ON_BN_CLICKED(IDC_LIST_INSERT, OnListInsert)
66 ON_BN_CLICKED(IDC_LIST_UP, OnListUp)
67 ON_BN_CLICKED(IDC_LIST_DOWN, OnListDown)
68 ON_BN_CLICKED(IDC_LIST_DELETE, OnListDelete)
69 ON_BN_CLICKED(IDC_SET_ANIM_LENGTH, OnSetAnimLength)
70 ON_BN_CLICKED(IDC_USE_LIST, OnUseList)
71 ON_BN_CLICKED(IDC_USE_MIXER, OnUseMixer)
72 ON_CBN_SELCHANGE(IDC_EDITED_OBJECT, OnSelchangeEditedObject)
73 //}}AFX_MSG_MAP
74 END_MESSAGE_MAP()
76 /////////////////////////////////////////////////////////////////////////////
77 // CAnimationSetDlg message handlers
79 // ***************************************************************************
81 void CAnimationSetDlg::OnAddAnimation ()
83 uint instance = _ObjView->getEditedObject ();
84 if (instance != 0xffffffff)
86 // Create a dialog
87 static TCHAR BASED_CODE szFilter[] =
88 _T("NeL Animation Files (*.anim)\0*.anim\0")
89 _T("All Files (*.*)\0*.*\0\0");
91 // Filename buffer
92 TCHAR buffer[65535];
93 buffer[0]=0;
95 OPENFILENAME openFile;
96 memset (&openFile, 0, sizeof (OPENFILENAME));
97 openFile.lStructSize = sizeof (OPENFILENAME);
98 openFile.hwndOwner = this->m_hWnd;
99 openFile.lpstrFilter = szFilter;
100 openFile.nFilterIndex = 0;
101 openFile.lpstrFile = buffer;
102 openFile.nMaxFile = 65535;
103 openFile.Flags = OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT|OFN_ENABLESIZING|OFN_EXPLORER;
104 openFile.lpstrDefExt = _T("*.anim");
107 if (GetOpenFileName(&openFile))
109 // Open the file
112 // Filename pointer
113 TCHAR *c=buffer;
115 // Read the path
116 CString path = buffer;
117 if (path.GetLength()>openFile.nFileOffset)
119 // Double zero at the end
120 c[path.GetLength()+1]=0;
122 // Path is empty
123 path.Empty();
125 else
127 // Adda slash
128 path += "\\";
130 // Look for the next string
131 while (*(c++)) {}
134 // For each file selected
135 while (*c)
137 // File name
138 TCHAR filename[256];
139 TCHAR *ptr=filename;
141 // Read a file name
142 while (*c)
144 *(ptr++)=*(c++);
146 *ptr=0;
147 c++;
149 // File name
150 CString name = path + filename;
152 // Load the animation
153 _ObjView->loadAnimation (tStrToUtf8(name), instance);
155 // Touch the channel mixer
156 _ObjView->reinitChannels ();
158 // Update
159 refresh (TRUE);
162 catch (const Exception& e)
164 MessageBox (nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
170 // ***************************************************************************
172 void CAnimationSetDlg::OnAddSkelWt()
174 // Instance number
175 int instance = _ObjView->getEditedObject ();
176 if (instance != CB_ERR)
178 // TODO: Add your control notification handler code here
179 static TCHAR BASED_CODE szFilter[] = _T("NeL Skeleton Weight Template Files (*.swt)|*.swt|All Files (*.*)|*.*||");
180 CFileDialog fileDlg( TRUE, _T(".swt"), _T("*.swt"), OFN_ALLOWMULTISELECT|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter);
181 if (fileDlg.DoModal()==IDOK)
183 // Open the file
186 // Get first file
187 POSITION pos=fileDlg.GetStartPosition( );
188 while (pos)
190 // Get the name
191 CString filename=fileDlg.GetNextPathName(pos);
193 // Load the animation
194 _ObjView->loadSWT (tStrToUtf8(filename), instance);
196 // Touch the channel mixer
197 _ObjView->reinitChannels ();
199 // Update
200 refresh (TRUE);
203 catch (const Exception& e)
205 MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
211 // ***************************************************************************
213 void CAnimationSetDlg::OnReset ()
215 // Instance
216 uint instance = _ObjView->getEditedObject ();
217 if (instance!=0xffffffff)
219 // Reset the channel mixer slots
220 _ObjView->resetSlots (instance);
224 // ***************************************************************************
226 void CAnimationSetDlg::refresh (BOOL update)
228 if (update)
230 CDialog::UpdateData (update);
232 // Clear the combo box
233 EditedObject.ResetContent ();
235 // Set edited object list
236 uint i;
237 for (i=0; i<_ObjView->getNumInstance (); i++)
239 std::string name = NLMISC::CFile::getFilenameWithoutExtension(_ObjView->getInstance(i)->Saved.ShapeFilename);
240 EditedObject.InsertString(-1, nlUtf8ToTStr(name));
243 // Get edited object
244 uint instance = _ObjView->getEditedObject ();
246 // Selection combo box
247 EditedObject.SetCurSel ((instance==0xffffffff)?-1:(int)instance);
249 // Clear the tree
250 Tree.DeleteAllItems ();
252 // Clear the tree
253 SkelTree.DeleteAllItems ();
255 // Clear the playlist
256 PlayList.ResetContent ();
258 if (instance != 0xffffffff)
260 // Get the instance
261 CInstanceInfo *object = _ObjView->getInstance (instance);
263 // For all tracks in the animation
264 uint i;
265 for (i=0; i<object->Saved.AnimationFileName.size(); i++)
267 // Get the animation name
268 std::string name = NLMISC::CFile::getFilenameWithoutExtension(object->Saved.AnimationFileName[i]);
270 // Get the animation pointer
271 CAnimation *anim = object->AnimationSet.getAnimation (object->AnimationSet.getAnimationIdByName (name));
273 // Insert an intem
274 HTREEITEM item = Tree.InsertItem(nlUtf8ToTStr(name));
275 Tree.SetItemData (item, i);
276 nlassert (item!=NULL);
278 // For all tracks in the animation
279 std::set<std::string> setString;
280 anim->getTrackNames (setString);
281 std::set<std::string>::iterator ite=setString.begin();
282 while (ite!=setString.end())
284 // Add this string
285 HTREEITEM newItem = Tree.InsertItem(nlUtf8ToTStr(*ite), item);
286 Tree.SetItemData (newItem, 0xffffffff);
288 // Get the track
289 ITrack *track=anim->getTrack (anim->getIdTrackByName (*ite));
291 // Keyframer ?
292 UTrackKeyframer *keyTrack=dynamic_cast<UTrackKeyframer *>(track);
294 if (keyTrack)
296 // Get number of keys
297 std::vector<TAnimationTime> keys;
298 keyTrack->getKeysInRange (track->getBeginTime ()-1, track->getEndTime ()+1, keys);
300 // Print track info
301 name = toString("%s (%f - %f) %u keys", typeid(*track).name(), track->getBeginTime(), track->getEndTime(), (uint32)keys.size());
303 else
305 // Print track info
306 name = toString("%s (%f - %f)", typeid(*track).name(), track->getBeginTime(), track->getEndTime());
309 HTREEITEM keyItem = Tree.InsertItem(nlUtf8ToTStr(name), newItem);
310 Tree.SetItemData(keyItem, 0xffffffff);
312 ite++;
316 // For all tracks in the animation
317 for (i=0; i<object->Saved.SWTFileName.size(); i++)
319 // Get the animation name
320 std::string name = NLMISC::CFile::getFilenameWithoutExtension(object->Saved.SWTFileName[i]);
322 // Get the animation pointer
323 CSkeletonWeight *swt = object->AnimationSet.getSkeletonWeight(object->AnimationSet.getSkeletonWeightIdByName(name));
325 // Insert an intem
326 HTREEITEM item = SkelTree.InsertItem(nlUtf8ToTStr(name));
327 nlassert (item!=NULL);
329 // Get number of node in this skeleton weight
330 uint numNode=swt->getNumNode ();
332 // Add the nodein the tree
333 for (uint n=0; n<numNode; n++)
335 std::string percent = toString("%s (%f%%)", swt->getNodeName(n).c_str(), swt->getNodeWeight(n)*100);
337 // Add this string
338 SkelTree.InsertItem(nlUtf8ToTStr(percent), item);
342 // For all tracks in the playlist
343 for (i=0; i<object->Saved.PlayList.size(); i++)
345 // Insert an intem
346 int item = PlayList.InsertString(-1, nlUtf8ToTStr(object->Saved.PlayList[i]));
347 nlassert (item!=LB_ERR);
351 CDialog::UpdateData (FALSE);
353 else
355 CDialog::UpdateData (TRUE);
357 // Get edited object
358 uint instance = _ObjView->getEditedObject ();
359 if (instance != 0xffffffff)
361 // Get the instance
362 CInstanceInfo *object = _ObjView->getInstance (instance);
364 // Clear the playlist
365 object->Saved.PlayList.resize (PlayList.GetCount ());
367 // For all tracks in the playlist
368 uint i;
369 for (i=0; i<object->Saved.PlayList.size(); i++)
371 // Insert an intem
372 TCHAR text[512];
373 PlayList.GetText( i, text);
374 object->Saved.PlayList[i] = tStrToUtf8(text);
377 CDialog::UpdateData (update);
381 _ObjView->refreshAnimationListeners();
384 // ***************************************************************************
386 void CAnimationSetDlg::OnDestroy()
388 setRegisterWindowState (this, REGKEY_OBJ_VIEW_ANIMATION_SET_DLG);
390 CDialog::OnDestroy();
393 // ***************************************************************************
395 void CAnimationSetDlg::OnListInsert()
397 // Get selected animation
398 HTREEITEM item = Tree.GetSelectedItem ();
399 if (item && (Tree.GetItemData (item)!=0xffffffff))
401 // Insert the string
402 int itemList = PlayList.InsertString (-1, Tree.GetItemText(item));
403 PlayList.SetItemData (itemList, Tree.GetItemData (item));
405 // Reselect the item
406 Tree.SelectItem (item);
409 // Update back
410 refresh (FALSE);
413 // ***************************************************************************
415 void CAnimationSetDlg::OnListUp()
417 // Get selected item
418 int sel = PlayList.GetCurSel ();
419 if ((sel != LB_ERR) && (sel>0))
421 // Backup the string
422 CString text;
423 PlayList.GetText (sel, text);
424 DWORD_PTR data = PlayList.GetItemData (sel);
426 // Remove the node
427 PlayList.DeleteString (sel);
429 // Insert the string
430 int pos = PlayList.InsertString (sel-1, text);
431 PlayList.SetItemData (pos, data);
432 PlayList.SetCurSel (pos);
435 // Update back
436 refresh (FALSE);
439 // ***************************************************************************
441 void CAnimationSetDlg::OnListDown()
443 // Get selected item
444 int sel = PlayList.GetCurSel ();
445 if ((sel != LB_ERR) && (sel<PlayList.GetCount()-1))
447 // Backup the string
448 CString text;
449 PlayList.GetText (sel, text);
450 DWORD_PTR data = PlayList.GetItemData (sel);
452 // Remove the node
453 PlayList.DeleteString (sel);
455 // Insert the string
456 int pos = PlayList.InsertString (sel+1, text);
457 PlayList.SetItemData (pos, data);
458 PlayList.SetCurSel (pos);
461 // Update back
462 refresh (FALSE);
465 // ***************************************************************************
467 void CAnimationSetDlg::OnListDelete()
469 // Get selected item
470 int sel = PlayList.GetCurSel ();
471 if (sel != LB_ERR)
473 // Remove the node
474 PlayList.DeleteString (sel);
476 if (sel>=PlayList.GetCount ())
477 sel--;
478 if (sel>=0)
479 PlayList.SetCurSel (sel);
482 // Update back
483 refresh (FALSE);
486 // ***************************************************************************
488 void CAnimationSetDlg::OnSetAnimLength()
490 // Longest animation
491 float longestLength = 0;
493 // For each instance
494 for (uint instance=0; instance<_ObjView->_ListInstance.size(); instance++)
496 // Ref on the instance
497 CInstanceInfo &inst = *_ObjView->_ListInstance[instance];
499 // There is some anim ?
500 if (inst.Saved.PlayList.size())
502 // Calculate the length
503 float length = 0;
505 // For each animation in the list
506 for (uint i=0; i<(uint)inst.Saved.PlayList.size(); i++)
508 // Get the animation
509 CAnimation *anim = inst.AnimationSet.getAnimation (inst.AnimationSet.getAnimationIdByName (inst.Saved.PlayList[i]));
511 // Add the length
512 length += anim->getEndTime () - anim->getBeginTime ();
515 if (length>longestLength)
516 longestLength=length;
520 // Adjuste length
521 if (longestLength>0)
522 _ObjView->setAnimTime (0, longestLength * _ObjView->getFrameRate ());
525 // ***************************************************************************
527 void CAnimationSetDlg::OnUseList()
529 // Disable channels
530 _ObjView->enableChannels ();
533 // ***************************************************************************
535 void CAnimationSetDlg::OnUseMixer()
537 // Enable channels
538 _ObjView->enableChannels ();
541 // ***************************************************************************
544 void CAnimationSetDlg::OnSelchangeEditedObject()
546 UpdateData ();
548 // Selection combo box
549 int selection = EditedObject.GetCurSel ();
550 _ObjView->setEditedObject ((selection==CB_ERR)?0xffffffff:selection);
552 refresh (TRUE);
553 _ObjView->getSlotDlg ()->refresh (TRUE);