Files
firestorm/Gameleap/code/mw4/Tools/3DSPlugins/AnimationSuite/OptimizeKeyframe.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

276 lines
7.2 KiB
C++

#include "stdafx.h"
#ifdef STRICT // Already defined by stdafx,
#undef STRICT // so we avoid warning linking msg
#endif
#ifdef _MBCS // The same as above
#undef _MBCS
#endif
#include "OptimizeKeyframe.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
OptimizeKeyframePanel g_optimizeKeyframePanel;
CCriticalSection g_threadLock;
ThreadData g_threadInfo;
////////////////////////////////////////////////////////////////////////////////
// PlugPanel Dialog Procedure to handle User and System Interactions
static BOOL CALLBACK OptimizeKeyframePanelProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
switch (msg) {
case WM_INITDIALOG: //Panel's extra initialization
g_optimizeKeyframePanel.Init(hWnd);
break;
case WM_DESTROY: //Panel's extra destruction
g_optimizeKeyframePanel.Destroy(hWnd);
break;
case WM_COMMAND :
switch (LOWORD(wParam)) { //Handle Panel's controls
case IDC_ABOUT: {
CAbout dlg;
dlg.DoModal();
break;
}
case IDC_OPTIMIZE: {
g_optimizeKeyframePanel.Optimize();
break;
}
}
break;
////////////////////////////////////////////////////////////////////////
//The following lines are not necessary for MAX2 Plugins
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
g_optimizeKeyframePanel.m_ip->RollupMouseMessage(hWnd, msg, wParam, lParam);
break;
////////////////////////////////////////////////////////////////////////
default:
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
// Display the Plugin's Panel
void OptimizeKeyframePanel::BeginEditParams(Interface* ip, IUtil* iu)
{
m_ip = ip; //Get the Plugin's Interface
m_iu = iu; //Get the Utility Plugin's Interface
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HINSTANCE loc_hInstance = AfxGetResourceHandle ();
//Display the plugin's Rollup Dialog
m_hPanel = m_ip->AddRollupPage(loc_hInstance, MAKEINTRESOURCE(IDD_OPT_PANEL),
OptimizeKeyframePanelProc, GetString(IDS_OPTIMIZEKEY_NAME),0);
}
////////////////////////////////////////////////////////////////////////////////
// Free the Plugins' Panel
void OptimizeKeyframePanel::EndEditParams(Interface *ip, IUtil *iu)
{
m_iu = NULL;
m_ip = NULL;
//Remove the Rollup Dialog
ip->DeleteRollupPage(m_hPanel);
m_hPanel = NULL;
}
////////////////////////////////////////////////////////////////////////////////
// Panel Initialization callback
void OptimizeKeyframePanel::Init(HWND hWnd)
{
}
////////////////////////////////////////////////////////////////////////////////
// Panel Destruction callback
void OptimizeKeyframePanel::Destroy(HWND hWnd)
{
}
////////////////////////////////////////////////////////////////////////////////
// Called when the Optimize Button is pushed
void OptimizeKeyframePanel::Optimize()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
JointEditDialog dialog(m_ip->GetRootNode(), m_ip);
if (dialog.DoModal() == IDOK)
{
// now optimize...
int total_nodes = JointEditDialog::CountChildren(m_ip->GetRootNode());
int current_node = 0;
theHold.SuperBegin();
LPVOID arg = NULL;
m_ip->ProgressStart(_T("Optimizing Joints"), TRUE, fn, arg);
OptimizeAnimation(m_ip->GetRootNode(), current_node, total_nodes, &dialog);
m_ip->ProgressEnd();
// Close out the undo
theHold.SuperAccept("Replicate");
}
}
////////////////////////////////////////////////////////////////////////////////
void
OptimizeKeyframePanel::OptimizeAnimation(INode *copy_node, int &current_node, int total_nodes, JointEditDialog *dialog)
{
Control *position_control = NULL;
Control *rotation_control = NULL;
Control *tm_controller = copy_node->GetTMController();
if (tm_controller != NULL)
{
position_control = tm_controller->GetPositionController();
rotation_control = tm_controller->GetRotationController();
JointPreference *pref = dialog->GetJointPrefrence(copy_node);
Verify(pref != NULL);
int include_joint = true;
if (pref->m_excludeJoint == JointPreference::ExcludeJoint)
{
include_joint = false;
}
if (pref->m_excludeJoint == JointPreference::AutoJoint)
{
if(dialog->NodeAnimated(copy_node))
{
include_joint = false;
}
}
if (include_joint)
{
if (pref->m_optimizeRotation)
{
if (rotation_control != NULL)
{
int num_keys = rotation_control->NumKeys();
if (num_keys > 0)
{
TimeValue start = rotation_control->GetKeyTime(0);
TimeValue end = rotation_control->GetKeyTime(num_keys-1);
if (pref->m_rotationRange)
{
start = (TimeValue)pref->m_rotationSampleStartFrame * GetTicksPerFrame();
end = (TimeValue)pref->m_rotationSampleEndFrame * GetTicksPerFrame();
}
Interval range;
start = (rotation_control->GetKeyTime(0) > start) ? rotation_control->GetKeyTime(0):start;
end = (rotation_control->GetKeyTime(num_keys-1) < end) ? rotation_control->GetKeyTime(num_keys-1):end;
// adjust the optimization to not include the last frame... tehehehehehe
if ((end - GetTicksPerFrame()) > start)
{
end -= GetTicksPerFrame();
}
range.Set(start , end);
OptKeyReduceStatus rot_progress;
ApplyKeyReduction_MW4(
rotation_control,
range,
pref->m_rotationThreshold * Stuff::Radians_Per_Degree,
GetTicksPerFrame(),
&rot_progress
);
}
}
}
if (pref->m_optimizeTranslation)
{
if (position_control != NULL)
{
int num_keys = position_control->NumKeys();
if (num_keys > 0)
{
TimeValue start = position_control->GetKeyTime(0);
TimeValue end = position_control->GetKeyTime(num_keys-1);
if (pref->m_translationRange)
{
start = (TimeValue)pref->m_translationSampleStartFrame * GetTicksPerFrame();
end = (TimeValue)pref->m_translationSampleEndFrame * GetTicksPerFrame();
}
Interval range;
start = (position_control->GetKeyTime(0) > start) ? position_control->GetKeyTime(0):start;
end = (position_control->GetKeyTime(num_keys-1) < end) ? position_control->GetKeyTime(num_keys-1):end;
// adjust the optimization to not include the last frame... tehehehehehe
if ((end - GetTicksPerFrame()) > start)
{
end -= GetTicksPerFrame();
}
range.Set(start , end);
OptKeyReduceStatus tran_progress;
ApplyKeyReduction_MW4(
position_control,
range,
pref->m_translationThreshold,
GetTicksPerFrame(),
&tran_progress
);
}
}
}
}
}
++current_node;
int total_done = (int)(((float)current_node/(float)total_nodes)*100.0f);
m_ip->ProgressUpdate(total_done);
for (int i = 0; i < copy_node->NumberOfChildren(); i++)
{
INode *child_node = copy_node->GetChildNode(i);
assert(child_node != NULL);
OptimizeAnimation(child_node, current_node, total_nodes, dialog);
}
return;
}