2017-03-15 19:43:10 +00:00
|
|
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// 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 Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#include "std_afx.h"
|
|
|
|
#include "object_viewer.h"
|
|
|
|
#include "animation_dlg.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include <nel/misc/time_nl.h>
|
|
|
|
|
|
|
|
using namespace NLMISC;
|
|
|
|
using namespace NL3D;
|
|
|
|
|
|
|
|
#define SPEED_FOREWARD 3
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CAnimationDlg dialog
|
|
|
|
|
|
|
|
|
|
|
|
CAnimationDlg::CAnimationDlg(class CObjectViewer* main, CWnd* pParent /*=NULL*/)
|
|
|
|
: CDialog(CAnimationDlg::IDD, pParent)
|
|
|
|
{
|
|
|
|
//{{AFX_DATA_INIT(CAnimationDlg)
|
|
|
|
End = 0.0f;
|
|
|
|
Speed = 30.0f;
|
|
|
|
Start = 0.0f;
|
|
|
|
Loop = TRUE;
|
|
|
|
UICurrentFrame = 0;
|
|
|
|
CurrentFrame = 0.0f;
|
|
|
|
Inplace = FALSE;
|
|
|
|
IncPos = TRUE;
|
|
|
|
//}}AFX_DATA_INIT
|
|
|
|
LastFrame = 0;
|
|
|
|
Playing=false;
|
|
|
|
Main=main;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::DoDataExchange(CDataExchange* pDX)
|
|
|
|
{
|
|
|
|
CDialog::DoDataExchange(pDX);
|
|
|
|
//{{AFX_DATA_MAP(CAnimationDlg)
|
|
|
|
DDX_Control(pDX, IDC_FRW, FRWCtrl);
|
|
|
|
DDX_Control(pDX, IDC_FFW, FFWCtrl);
|
|
|
|
DDX_Control(pDX, IDC_TIME_LINE, TimeLineCtrl);
|
|
|
|
DDX_Control(pDX, IDC_PLAY, PlayCtrl);
|
|
|
|
DDX_Control(pDX, IDC_STOP, StopCtrl);
|
|
|
|
DDX_Text(pDX, IDC_END_EDIT, End);
|
|
|
|
DDX_Text(pDX, IDC_SPEED, Speed);
|
|
|
|
DDX_Text(pDX, IDC_START_EDIT, Start);
|
|
|
|
DDX_Check(pDX, IDC_LOOP, Loop);
|
|
|
|
DDX_Text(pDX, IDC_CURRENT_FRAME, UICurrentFrame);
|
|
|
|
DDX_Check(pDX, IDC_INPLACE, Inplace);
|
|
|
|
DDX_Check(pDX, IDC_INC_POS, IncPos);
|
|
|
|
//}}AFX_DATA_MAP
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CAnimationDlg, CDialog)
|
|
|
|
//{{AFX_MSG_MAP(CAnimationDlg)
|
|
|
|
ON_BN_CLICKED(IDC_END, OnEnd)
|
|
|
|
ON_BN_CLICKED(IDC_PLAY, OnPlay)
|
|
|
|
ON_BN_CLICKED(IDC_STOP, OnStop)
|
|
|
|
ON_EN_CHANGE(IDC_CURRENT_FRAME, OnChangeCurrentFrame)
|
|
|
|
ON_EN_CHANGE(IDC_END_EDIT, OnChangeEndEdit)
|
|
|
|
ON_EN_CHANGE(IDC_SPEED, OnChangeSpeed)
|
|
|
|
ON_BN_CLICKED(IDC_START, OnStart)
|
|
|
|
ON_EN_CHANGE(IDC_START_EDIT, OnChangeStartEdit)
|
|
|
|
ON_WM_HSCROLL()
|
|
|
|
ON_WM_DESTROY()
|
|
|
|
//}}AFX_MSG_MAP
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CAnimationDlg message handlers
|
|
|
|
|
|
|
|
void CAnimationDlg::OnEnd()
|
|
|
|
{
|
|
|
|
UpdateData ();
|
|
|
|
CurrentFrame=End;
|
|
|
|
LastFrame=End;
|
|
|
|
UICurrentFrame=(int)CurrentFrame;
|
|
|
|
UpdateData (FALSE);
|
|
|
|
updateBar ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnPlay()
|
|
|
|
{
|
|
|
|
// play
|
|
|
|
UpdateData ();
|
|
|
|
StopCtrl.SetCheck (0);
|
|
|
|
PlayCtrl.SetCheck (1);
|
|
|
|
PlayCtrl.EnableWindow (FALSE);
|
|
|
|
StopCtrl.EnableWindow (TRUE);
|
|
|
|
|
|
|
|
if (!Playing)
|
|
|
|
{
|
|
|
|
Playing=true;
|
|
|
|
}
|
|
|
|
Main->enableFXs(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnStop()
|
|
|
|
{
|
|
|
|
// Is checked ?
|
|
|
|
UpdateData ();
|
|
|
|
Playing=false;
|
|
|
|
StopCtrl.SetCheck (1);
|
|
|
|
PlayCtrl.SetCheck (0);
|
|
|
|
PlayCtrl.EnableWindow (TRUE);
|
|
|
|
StopCtrl.EnableWindow (FALSE);
|
|
|
|
UpdateData (FALSE);
|
|
|
|
Main->enableFXs(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnChangeCurrentFrame()
|
|
|
|
{
|
|
|
|
// TODO: If this is a RICHEDIT control, the control will not
|
|
|
|
// send this notification unless you override the CDialog::OnInitDialog()
|
|
|
|
// function and call CRichEditCtrl().SetEventMask()
|
|
|
|
// with the ENM_CHANGE flag ORed into the mask.
|
|
|
|
|
|
|
|
// Update values
|
|
|
|
UpdateData ();
|
|
|
|
|
|
|
|
// Clamp current frame
|
|
|
|
clamp (UICurrentFrame, (int)Start, (int)End);
|
|
|
|
CurrentFrame=(float)UICurrentFrame;
|
|
|
|
LastFrame=CurrentFrame;
|
|
|
|
|
|
|
|
// Update
|
|
|
|
updateBar ();
|
|
|
|
UpdateData (FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnChangeEndEdit()
|
|
|
|
{
|
|
|
|
// TODO: If this is a RICHEDIT control, the control will not
|
|
|
|
// send this notification unless you override the CDialog::OnInitDialog()
|
|
|
|
// function and call CRichEditCtrl().SetEventMask()
|
|
|
|
// with the ENM_CHANGE flag ORed into the mask.
|
|
|
|
|
|
|
|
// TODO: Add your control notification handler code here
|
|
|
|
|
|
|
|
// Update values
|
|
|
|
UpdateData ();
|
|
|
|
|
|
|
|
// Clamp current frame
|
|
|
|
if (End<Start)
|
|
|
|
Start=End;
|
|
|
|
if (End<CurrentFrame)
|
|
|
|
{
|
|
|
|
CurrentFrame=End;
|
|
|
|
LastFrame=End;
|
|
|
|
}
|
|
|
|
UICurrentFrame=(int)CurrentFrame;
|
|
|
|
|
|
|
|
// Update
|
|
|
|
UpdateData (FALSE);
|
|
|
|
Main->setAnimTime (Start, End);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnChangeSpeed()
|
|
|
|
{
|
|
|
|
// TODO: If this is a RICHEDIT control, the control will not
|
|
|
|
// send this notification unless you override the CDialog::OnInitDialog()
|
|
|
|
// function and call CRichEditCtrl().SetEventMask()
|
|
|
|
// with the ENM_CHANGE flag ORed into the mask.
|
|
|
|
|
|
|
|
UpdateData();
|
|
|
|
if (Speed<=0.001f)
|
|
|
|
Speed=0.001f;
|
|
|
|
Start=Speed*Start;
|
|
|
|
End=Speed*End;
|
|
|
|
UpdateData(FALSE);
|
|
|
|
Main->setAnimTime (Start, End);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnStart()
|
|
|
|
{
|
|
|
|
UpdateData ();
|
|
|
|
CurrentFrame=Start;
|
|
|
|
LastFrame=Start;
|
|
|
|
UICurrentFrame=(int)CurrentFrame;
|
|
|
|
UpdateData (FALSE);
|
|
|
|
updateBar ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnChangeStartEdit()
|
|
|
|
{
|
|
|
|
// TODO: If this is a RICHEDIT control, the control will not
|
|
|
|
// send this notification unless you override the CDialog::OnInitDialog()
|
|
|
|
// function and call CRichEditCtrl().SetEventMask()
|
|
|
|
// with the ENM_CHANGE flag ORed into the mask.
|
|
|
|
|
|
|
|
// Update values
|
|
|
|
UpdateData ();
|
|
|
|
|
|
|
|
// Clamp current frame
|
|
|
|
if (End<Start)
|
|
|
|
End=Start;
|
|
|
|
if (CurrentFrame<Start)
|
|
|
|
{
|
|
|
|
CurrentFrame=Start;
|
|
|
|
LastFrame=Start;
|
|
|
|
}
|
|
|
|
UICurrentFrame=(int)CurrentFrame;
|
|
|
|
|
|
|
|
// Update
|
|
|
|
UpdateData (FALSE);
|
|
|
|
Main->setAnimTime (Start, End);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
|
|
{
|
|
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
|
|
|
|
// Drag the time line ?
|
|
|
|
if (pScrollBar==GetDlgItem (IDC_TIME_LINE))
|
|
|
|
{
|
|
|
|
// Update values
|
|
|
|
UpdateData ();
|
|
|
|
|
|
|
|
// Setup current pos
|
|
|
|
CurrentFrame=(float)TimeLineCtrl.GetPos()*(End-Start)/65535.f+Start;
|
|
|
|
CurrentFrame=(float)floor(CurrentFrame+0.5f);
|
|
|
|
LastFrame=CurrentFrame;
|
|
|
|
UICurrentFrame=(int)CurrentFrame;
|
|
|
|
|
|
|
|
// Update values
|
|
|
|
UpdateData (FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::handle ()
|
|
|
|
{
|
|
|
|
// New time
|
|
|
|
uint64 newTime=NLMISC::CTime::getLocalTime ();
|
|
|
|
|
|
|
|
// Forward or rewind ?
|
|
|
|
bool forward=(((CButton*)GetDlgItem (IDC_FFW))->GetState()&BST_PUSHED)!=0;
|
|
|
|
bool rewind=(((CButton*)GetDlgItem (IDC_FRW))->GetState()&BST_PUSHED)!=0;
|
|
|
|
|
|
|
|
// If play, back last frame
|
|
|
|
if (Playing)
|
|
|
|
LastFrame=CurrentFrame;
|
|
|
|
|
|
|
|
if (forward||rewind||Playing)
|
|
|
|
{
|
|
|
|
UpdateData ();
|
|
|
|
|
|
|
|
// Delta time
|
|
|
|
uint deltaTime=(uint)(newTime-LastTime);
|
|
|
|
|
|
|
|
if (forward)
|
|
|
|
{
|
|
|
|
// Fast forward
|
|
|
|
CurrentFrame+=(float)((float)deltaTime*SPEED_FOREWARD*Speed/1000.0);
|
|
|
|
}
|
|
|
|
else if (rewind)
|
|
|
|
{
|
|
|
|
// Fast rewind
|
|
|
|
CurrentFrame-=(float)((float)deltaTime*SPEED_FOREWARD*Speed/1000.0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Compute new time
|
|
|
|
if (Playing)
|
|
|
|
{
|
|
|
|
CurrentFrame+=(float)((float)deltaTime*Speed/1000.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Loop
|
|
|
|
if (Loop&&(!forward)&&(!rewind)&&Playing)
|
|
|
|
{
|
|
|
|
float backup = CurrentFrame;
|
|
|
|
CurrentFrame=(float)fmod ((CurrentFrame-Start), End-Start)+Start;
|
|
|
|
if (backup!=CurrentFrame)
|
|
|
|
{
|
|
|
|
LastFrame = CurrentFrame;
|
|
|
|
Main->enableFXs(false);
|
|
|
|
Main->enableFXs(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clamp time
|
|
|
|
if (CurrentFrame>End)
|
|
|
|
{
|
|
|
|
CurrentFrame=End;
|
|
|
|
LastFrame=CurrentFrame;
|
|
|
|
UpdateData (FALSE);
|
|
|
|
|
|
|
|
// Stop animation
|
|
|
|
OnStop ();
|
|
|
|
|
|
|
|
}
|
|
|
|
if (CurrentFrame<Start)
|
|
|
|
{
|
|
|
|
CurrentFrame=Start;
|
|
|
|
LastFrame=CurrentFrame;
|
|
|
|
UpdateData (FALSE);
|
|
|
|
|
|
|
|
// Stop animation
|
|
|
|
OnStop ();
|
|
|
|
}
|
|
|
|
|
|
|
|
UICurrentFrame=(int)CurrentFrame;
|
|
|
|
UpdateData (FALSE);
|
|
|
|
updateBar ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If not play, copy current frame
|
|
|
|
if (!Playing)
|
|
|
|
LastFrame=CurrentFrame;
|
|
|
|
|
|
|
|
// Setup new time
|
|
|
|
LastTime=newTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CAnimationDlg::OnInitDialog()
|
|
|
|
{
|
|
|
|
CDialog::OnInitDialog();
|
|
|
|
|
|
|
|
// Stop
|
|
|
|
LastTime=NLMISC::CTime::getLocalTime ();
|
|
|
|
StopCtrl.SetCheck (1);
|
|
|
|
|
|
|
|
// Set time line range
|
|
|
|
TimeLineCtrl.SetRangeMin (0);
|
|
|
|
TimeLineCtrl.SetRangeMax (65535);
|
|
|
|
|
|
|
|
// Update the time line
|
|
|
|
updateBar ();
|
|
|
|
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::setAnimTime (float animStart, float animEnd)
|
|
|
|
{
|
|
|
|
UpdateData();
|
|
|
|
Start=animStart;
|
|
|
|
End=animEnd;
|
|
|
|
UpdateData(FALSE);
|
|
|
|
updateBar ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::updateBar ()
|
|
|
|
{
|
|
|
|
// Update value
|
|
|
|
UpdateData();
|
|
|
|
|
|
|
|
// Set cursor position
|
|
|
|
int position;
|
|
|
|
if (fabs (End-Start)<0.00001f)
|
|
|
|
position=0;
|
|
|
|
else
|
|
|
|
position=(int)((CurrentFrame-Start)*65535.f/(End-Start));
|
|
|
|
clamp (position, 0, 65535);
|
|
|
|
TimeLineCtrl.SetPos(position);
|
|
|
|
|
|
|
|
// Update value
|
|
|
|
UpdateData (FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
NL3D::TAnimationTime CAnimationDlg::getTime ()
|
|
|
|
{
|
|
|
|
// Return current time in second
|
|
|
|
return CurrentFrame/Speed;
|
|
|
|
}
|
|
|
|
|
|
|
|
NL3D::TAnimationTime CAnimationDlg::getLastTime ()
|
|
|
|
{
|
|
|
|
// Return current time in second
|
|
|
|
return LastFrame/Speed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::OnDestroy()
|
|
|
|
{
|
|
|
|
setRegisterWindowState (this, REGKEY_OBJ_VIEW_ANIMATION_DLG);
|
|
|
|
|
|
|
|
CDialog::OnDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAnimationDlg::setCurrentFrame (float currentFrame)
|
|
|
|
{
|
|
|
|
// Update values
|
|
|
|
UpdateData ();
|
|
|
|
|
|
|
|
// Setup current pos
|
|
|
|
CurrentFrame=currentFrame;
|
|
|
|
LastFrame=CurrentFrame;
|
|
|
|
UICurrentFrame=(int)CurrentFrame;
|
|
|
|
|
|
|
|
// Update values
|
|
|
|
UpdateData (FALSE);
|
|
|
|
updateBar ();
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CAnimationDlg::EnableWindow(BOOL enable /*=TRUE*/)
|
|
|
|
{
|
|
|
|
PlayCtrl.EnableWindow(Playing && enable);
|
|
|
|
StopCtrl.EnableWindow(FALSE);
|
|
|
|
FRWCtrl.EnableWindow(enable);
|
|
|
|
FFWCtrl.EnableWindow(enable);
|
|
|
|
TimeLineCtrl.EnableWindow(enable);
|
|
|
|
PlayCtrl.EnableWindow(enable);
|
|
|
|
StopCtrl.EnableWindow(enable);
|
|
|
|
GetDlgItem(IDC_END)->EnableWindow(enable);
|
|
|
|
GetDlgItem(IDC_START)->EnableWindow(enable);
|
|
|
|
GetDlgItem(IDC_LOOP)->EnableWindow(enable);
|
|
|
|
GetDlgItem(IDC_START_EDIT)->EnableWindow(enable);
|
|
|
|
GetDlgItem(IDC_CURRENT_FRAME)->EnableWindow(enable);
|
|
|
|
GetDlgItem(IDC_SPEED)->EnableWindow(enable);
|
|
|
|
GetDlgItem(IDC_END_EDIT)->EnableWindow(enable);
|
|
|
|
return TRUE;
|
|
|
|
}
|