815 lines
19 KiB
C++
815 lines
19 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU 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 General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "clipboard.h"
|
|
#include <istdplug.h>
|
|
#include "utilapi.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Node_Key
|
|
//----------------------------------------------------------------------------
|
|
|
|
class Node_Key
|
|
{
|
|
public:
|
|
|
|
Node_Key ( int nr_frames, const char * name, Node_Key * next );
|
|
~Node_Key ();
|
|
|
|
void set_position ( int frame, Point3 pos )
|
|
{
|
|
if ( frame >= 0 && frame < nr_frames_ )
|
|
position_ [frame] = pos;
|
|
}
|
|
|
|
void set_orientation ( int frame, Quat facing )
|
|
{
|
|
if ( frame >= 0 && frame < nr_frames_ )
|
|
orientation_ [frame] = facing;
|
|
}
|
|
|
|
const Point3 & position ( int frame )
|
|
{
|
|
if ( frame < 0 || frame >= nr_frames_ )
|
|
frame = 0;
|
|
|
|
return position_ [frame];
|
|
}
|
|
|
|
const Quat & orientation ( int frame )
|
|
{
|
|
if ( frame < 0 || frame >= nr_frames_ )
|
|
frame = 0;
|
|
|
|
return orientation_ [frame];
|
|
}
|
|
|
|
const char * name () { return name_; }
|
|
int nr_frames () { return nr_frames_; }
|
|
Node_Key * next () { return next_; }
|
|
|
|
private:
|
|
|
|
char * name_;
|
|
int nr_frames_;
|
|
Point3 * position_;
|
|
Quat * orientation_;
|
|
Node_Key * next_;
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Node_Key::Node_Key
|
|
//----------------------------------------------------------------------------
|
|
|
|
Node_Key::Node_Key
|
|
(
|
|
int nr_frames,
|
|
const char * name,
|
|
Node_Key * next
|
|
):
|
|
nr_frames_ (nr_frames),
|
|
next_ (next)
|
|
{
|
|
position_ = new Point3 [ nr_frames ];
|
|
orientation_ = new Quat [ nr_frames ];
|
|
name_ = new char [ strlen (name) + 1 ];
|
|
strcpy ( name_, name );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Node_Key::~Node_Key
|
|
//----------------------------------------------------------------------------
|
|
|
|
Node_Key::~Node_Key ()
|
|
{
|
|
delete [] position_;
|
|
delete [] orientation_;
|
|
delete [] name_;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Pose
|
|
//----------------------------------------------------------------------------
|
|
|
|
const MAX_NAME = 64;
|
|
|
|
class Pose
|
|
{
|
|
public:
|
|
|
|
Pose ( Interface * ip, const char * new_name, int first_frame, int last_frame );
|
|
|
|
~Pose ()
|
|
{
|
|
delete_keys ();
|
|
}
|
|
|
|
const char * name () const { return name_; }
|
|
|
|
void Add_Objects_To_List ( HWND hWnd );
|
|
|
|
void Paste_Keys ( Interface * ip );
|
|
|
|
Pose * next;
|
|
|
|
private:
|
|
|
|
void delete_keys ();
|
|
|
|
Node_Key * first_key;
|
|
|
|
char name_ [ MAX_NAME ];
|
|
|
|
int ticks_per_frame_;
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
class Clipboard_Class : public UtilityObj
|
|
{
|
|
public:
|
|
|
|
Clipboard_Class ();
|
|
~Clipboard_Class ();
|
|
|
|
void BeginEditParams(Interface *ip,IUtil *iu);
|
|
void EndEditParams(Interface *ip,IUtil *iu);
|
|
void SelectionSetChanged ( Interface * ip, IUtil * iu );
|
|
void DeleteThis() {}
|
|
|
|
void Init(HWND hWnd);
|
|
void Destroy(HWND hWnd);
|
|
void Close () { iu->CloseUtility (); }
|
|
|
|
void Create ( HWND );
|
|
void Paste ( HWND );
|
|
void Delete ( HWND );
|
|
|
|
BOOL Is_Empty () const { return first_pose == NULL; }
|
|
|
|
void Update_Object_List ( HWND hWnd );
|
|
|
|
private:
|
|
|
|
void Update_Pose_List ( HWND hWnd );
|
|
|
|
IUtil * iu;
|
|
Interface *ip;
|
|
HWND hPanel;
|
|
|
|
Pose * first_pose;
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// the_clipboard
|
|
//----------------------------------------------------------------------------
|
|
|
|
static Clipboard_Class the_clipboard;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Static data used for communicating to/from the name dialog.
|
|
//----------------------------------------------------------------------------
|
|
|
|
static char pose_name [ MAX_NAME ];
|
|
static int first_frame;
|
|
static int last_frame;
|
|
static int current_frame;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Desc_Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
class Clipboard_Desc_Class:public ClassDesc
|
|
{
|
|
public:
|
|
int IsPublic() {return 1;}
|
|
void * Create(BOOL) {return &the_clipboard;}
|
|
const TCHAR * ClassName() {return _T("Key Clipboard");}
|
|
SClass_ID SuperClassID() {return UTILITY_CLASS_ID;}
|
|
Class_ID ClassID() {return Class_ID(0x5eb13907, 0x1d931bb4);}
|
|
const TCHAR* Category() {return _T("Westwood Tools");}
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// clipboard_desc
|
|
//----------------------------------------------------------------------------
|
|
|
|
static Clipboard_Desc_Class clipboard_desc;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ClipboardDesc
|
|
//----------------------------------------------------------------------------
|
|
|
|
ClassDesc* ClipboardDesc() {return &clipboard_desc;}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ClipboardDlgProc
|
|
//----------------------------------------------------------------------------
|
|
|
|
static BOOL CALLBACK ClipboardDlgProc
|
|
(
|
|
HWND hWnd,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
the_clipboard.Init(hWnd);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
the_clipboard.Destroy(hWnd);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case ID_CLOSE:
|
|
the_clipboard.Close ();
|
|
break;
|
|
|
|
case ID_CREATE:
|
|
the_clipboard.Create ( hWnd );
|
|
break;
|
|
|
|
case ID_PASTE:
|
|
the_clipboard.Paste ( hWnd );
|
|
break;
|
|
|
|
case ID_DELETE:
|
|
the_clipboard.Delete ( hWnd );
|
|
break;
|
|
|
|
case IDC_POSE_LIST:
|
|
if ( HIWORD(wParam) == CBN_SELCHANGE )
|
|
the_clipboard.Update_Object_List ( hWnd );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Pose_Name_Message_Handler
|
|
//----------------------------------------------------------------------------
|
|
|
|
static BOOL CALLBACK Pose_Name_Message_Handler
|
|
(
|
|
HWND hWnd,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
static ISpinnerControl * first_frame_spin;
|
|
static ISpinnerControl * last_frame_spin;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CenterWindow ( hWnd, GetParent (hWnd) );
|
|
SetFocus ( GetDlgItem (hWnd, IDC_NAME) );
|
|
|
|
first_frame_spin = SetupIntSpinner
|
|
(
|
|
hWnd,
|
|
IDC_FIRST_FRAME_SPIN,
|
|
IDC_FIRST_FRAME_EDIT,
|
|
first_frame,
|
|
last_frame,
|
|
current_frame
|
|
);
|
|
|
|
first_frame_spin->SetResetValue ( current_frame );
|
|
|
|
last_frame_spin = SetupIntSpinner
|
|
(
|
|
hWnd,
|
|
IDC_LAST_FRAME_SPIN,
|
|
IDC_LAST_FRAME_EDIT,
|
|
first_frame,
|
|
last_frame,
|
|
current_frame
|
|
);
|
|
|
|
last_frame_spin->SetResetValue ( current_frame );
|
|
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
if ( SendDlgItemMessage ( hWnd, IDC_NAME, WM_GETTEXTLENGTH, 0, 0 ) == 0 )
|
|
EndDialog ( hWnd, 0 );
|
|
|
|
SendDlgItemMessage ( hWnd, IDC_NAME, WM_GETTEXT, MAX_NAME,
|
|
(LPARAM) pose_name );
|
|
|
|
first_frame = first_frame_spin->GetIVal ();
|
|
last_frame = last_frame_spin->GetIVal ();
|
|
EndDialog ( hWnd, 1 );
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog ( hWnd, 0 );
|
|
break;
|
|
}
|
|
return TRUE;
|
|
|
|
case CC_SPINNER_CHANGE:
|
|
|
|
// Do checking on the range spinners to make sure the low value never
|
|
// exceeds the high value.
|
|
|
|
switch ( LOWORD(wParam) )
|
|
{
|
|
case IDC_FIRST_FRAME_SPIN:
|
|
if ( first_frame_spin->GetIVal () > last_frame_spin->GetIVal () )
|
|
{
|
|
last_frame_spin->SetValue ( first_frame_spin->GetIVal (),
|
|
FALSE );
|
|
}
|
|
break;
|
|
|
|
case IDC_LAST_FRAME_SPIN:
|
|
if ( last_frame_spin->GetIVal () < first_frame_spin->GetIVal () )
|
|
{
|
|
first_frame_spin->SetValue ( last_frame_spin->GetIVal (),
|
|
FALSE );
|
|
}
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Clipboard_Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
Clipboard_Class::Clipboard_Class()
|
|
{
|
|
iu = NULL;
|
|
ip = NULL;
|
|
hPanel = NULL;
|
|
first_pose = NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::~Clipboard_Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
Clipboard_Class::~Clipboard_Class ()
|
|
{
|
|
while ( first_pose != NULL )
|
|
{
|
|
Pose * delete_p = first_pose;
|
|
first_pose = first_pose->next;
|
|
delete delete_p;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::BeginEditParams
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::BeginEditParams(Interface *ip,IUtil *iu)
|
|
{
|
|
this->iu = iu;
|
|
this->ip = ip;
|
|
hPanel = ip->AddRollupPage
|
|
(
|
|
hInstance,
|
|
MAKEINTRESOURCE(IDD_CLIPBOARD_PANEL),
|
|
ClipboardDlgProc,
|
|
_T("Key Clipboard"),
|
|
0
|
|
);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::EndEditParams
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::EndEditParams ( Interface *ip, IUtil *iu )
|
|
{
|
|
this->iu = NULL;
|
|
this->ip = NULL;
|
|
ip->DeleteRollupPage(hPanel);
|
|
hPanel = NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::SelectionSetChanged
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::SelectionSetChanged ( Interface * ip, IUtil * iu )
|
|
{
|
|
if ( ip->GetSelNodeCount () == 0 )
|
|
{
|
|
EnableWindow ( GetDlgItem ( hPanel, ID_CREATE ), FALSE );
|
|
}
|
|
else
|
|
{
|
|
EnableWindow ( GetDlgItem ( hPanel, ID_CREATE ), TRUE );
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Init
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::Init ( HWND hWnd )
|
|
{
|
|
Update_Pose_List ( hWnd );
|
|
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_SETCURSEL, 0, 0 );
|
|
Update_Object_List ( hWnd );
|
|
|
|
if ( ip->GetSelNodeCount () == 0 )
|
|
{
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_CREATE ), FALSE );
|
|
}
|
|
else
|
|
{
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_CREATE ), TRUE );
|
|
}
|
|
|
|
if ( Is_Empty () )
|
|
{
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), FALSE );
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), FALSE );
|
|
}
|
|
else
|
|
{
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), TRUE );
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), TRUE );
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Destroy
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::Destroy(HWND hWnd) {}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Create
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::Create ( HWND hWnd )
|
|
{
|
|
// Set up the data that will appear in the name dialog.
|
|
|
|
const int ticks_per_frame = GetTicksPerFrame ();
|
|
|
|
first_frame = ip->GetAnimRange ().Start () / ticks_per_frame;
|
|
last_frame = ip->GetAnimRange ().End () / ticks_per_frame;
|
|
current_frame = ip->GetTime () / ticks_per_frame;
|
|
|
|
// Put up the name dialog.
|
|
|
|
int rv = DialogBoxParam
|
|
(
|
|
hInstance,
|
|
MAKEINTRESOURCE ( IDD_POSE_NAME ),
|
|
hWnd,
|
|
Pose_Name_Message_Handler,
|
|
0
|
|
);
|
|
|
|
if ( rv == 0 )
|
|
return;
|
|
|
|
Pose * new_pose = new Pose ( ip, pose_name, first_frame, last_frame );
|
|
|
|
new_pose->next = first_pose;
|
|
first_pose = new_pose;
|
|
|
|
Update_Pose_List ( hWnd );
|
|
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_SETCURSEL, 0, 0 );
|
|
Update_Object_List ( hWnd );
|
|
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), TRUE );
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), TRUE );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Paste
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::Paste ( HWND hWnd )
|
|
{
|
|
SetCursor ( LoadCursor (NULL, IDC_WAIT) );
|
|
|
|
int sel = SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_GETCURSEL, 0, 0 );
|
|
|
|
if ( sel == CB_ERR )
|
|
return;
|
|
|
|
// Find the selected pose.
|
|
|
|
Pose * p = first_pose;
|
|
|
|
while ( sel > 0 && p != NULL )
|
|
{
|
|
p = p->next;
|
|
-- sel;
|
|
}
|
|
|
|
if ( p == NULL )
|
|
return;
|
|
|
|
p->Paste_Keys ( ip );
|
|
|
|
SetCursor ( LoadCursor (NULL, IDC_ARROW) );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Delete
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::Delete ( HWND hWnd )
|
|
{
|
|
int sel = SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_GETCURSEL, 0, 0 );
|
|
|
|
if ( sel != CB_ERR )
|
|
{
|
|
// Delete the pose's name from the list box.
|
|
|
|
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_DELETESTRING, sel, 0 );
|
|
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_SETCURSEL, 0, 0 );
|
|
|
|
// Find the selected pose and delete it.
|
|
|
|
Pose ** pointer_to_p = & first_pose;
|
|
Pose * p = first_pose;
|
|
|
|
while ( sel > 0 && p != NULL )
|
|
{
|
|
pointer_to_p = & p->next;
|
|
p = p->next;
|
|
-- sel;
|
|
}
|
|
|
|
if ( p != NULL )
|
|
{
|
|
*pointer_to_p = p->next;
|
|
|
|
delete p;
|
|
}
|
|
|
|
Update_Object_List ( hWnd );
|
|
}
|
|
|
|
if ( Is_Empty () )
|
|
{
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), FALSE );
|
|
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), FALSE );
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Update_Pose_List
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::Update_Pose_List ( HWND hWnd )
|
|
{
|
|
// Delete any strings in the combo box.
|
|
|
|
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_RESETCONTENT, 0, 0 );
|
|
|
|
// Rebuild the combo box.
|
|
|
|
for ( Pose * p = first_pose; p != NULL; p = p->next )
|
|
{
|
|
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_ADDSTRING, 0,
|
|
(LPARAM) (LPCTSTR) p->name () );
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard_Class::Update_Object_List
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Clipboard_Class::Update_Object_List ( HWND hWnd )
|
|
{
|
|
// Delete any strings in the combo box.
|
|
|
|
SendDlgItemMessage ( hWnd, IDC_OBJECT_LIST, LB_RESETCONTENT, 0, 0 );
|
|
|
|
// Add strings from the objects in the currently selected pose.
|
|
|
|
int sel = SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_GETCURSEL, 0, 0 );
|
|
|
|
if ( sel != CB_ERR )
|
|
{
|
|
Pose * p = first_pose;
|
|
|
|
while ( sel > 0 && p != NULL )
|
|
{
|
|
p = p->next;
|
|
-- sel;
|
|
}
|
|
|
|
if ( p != NULL )
|
|
{
|
|
p->Add_Objects_To_List ( hWnd );
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Pose::Pose
|
|
//----------------------------------------------------------------------------
|
|
|
|
Pose::Pose ( Interface * ip, const char * name, int first_frame, int last_frame ):
|
|
first_key (NULL),
|
|
next (NULL),
|
|
ticks_per_frame_ (GetTicksPerFrame ())
|
|
{
|
|
int number_of_nodes = ip->GetSelNodeCount ();
|
|
int nr_frames = (last_frame - first_frame) + 1;
|
|
TimeValue start_time = first_frame * ticks_per_frame_;
|
|
|
|
char frame_count [ 16 ];
|
|
sprintf ( frame_count, " (%d)", nr_frames );
|
|
|
|
strncpy ( name_, name, MAX_NAME - 6 );
|
|
strncat ( name_, frame_count, 5 );
|
|
name_ [MAX_NAME - 1] = '\0';
|
|
|
|
for ( int i = 0; i < number_of_nodes; ++ i )
|
|
{
|
|
// Get the inode.
|
|
|
|
INode * inode = ip->GetSelNode ( i );
|
|
|
|
Control * tm_controller = inode->GetTMController ();
|
|
if ( tm_controller == NULL )
|
|
continue;
|
|
|
|
Node_Key * new_key = new Node_Key
|
|
(
|
|
nr_frames,
|
|
inode->GetName (),
|
|
first_key
|
|
);
|
|
|
|
first_key = new_key;
|
|
|
|
// Store the position and rotation keys.
|
|
|
|
Point3 node_position ( 0.0, 0.0, 0.0 );
|
|
Quat node_orientation ( 0.0, 0.0, 0.0, 1.0 );
|
|
|
|
for ( int frame = 0; frame < nr_frames; ++ frame )
|
|
{
|
|
TimeValue key_time = frame * ticks_per_frame_ + start_time;
|
|
Control * c;
|
|
|
|
// Copy rotation keys.
|
|
|
|
c = tm_controller->GetRotationController ();
|
|
|
|
if ( c != NULL )
|
|
c->GetValue ( key_time, & node_orientation, FOREVER );
|
|
else
|
|
node_orientation = Quat (0.0, 0.0, 0.0, 1.0);
|
|
|
|
// Copy position keys.
|
|
|
|
c = tm_controller->GetPositionController ();
|
|
|
|
if ( c != NULL )
|
|
c->GetValue ( key_time, & node_position, FOREVER );
|
|
else
|
|
node_position = Point3 (0.0, 0.0, 0.0);
|
|
|
|
new_key->set_position ( frame, node_position );
|
|
new_key->set_orientation ( frame, node_orientation );
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Pose::Paste_Keys
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Pose::Paste_Keys ( Interface * ip )
|
|
{
|
|
TimeValue current_time = ip->GetTime ();
|
|
|
|
theHold.Begin ();
|
|
|
|
SuspendAnimate ();
|
|
AnimateOn ();
|
|
|
|
Node_Key * p = first_key;
|
|
|
|
while ( p != NULL )
|
|
{
|
|
INode * inode = ip->GetINodeByName ( p->name () );
|
|
|
|
if ( inode != NULL )
|
|
{
|
|
Control * tm_controller = inode->GetTMController ();
|
|
if ( tm_controller != NULL )
|
|
{
|
|
for ( int frame = 0; frame < p->nr_frames (); ++ frame )
|
|
{
|
|
TimeValue key_time = current_time + frame * ticks_per_frame_;
|
|
Control * c;
|
|
|
|
// Paste rotation keys.
|
|
|
|
c = tm_controller->GetRotationController ();
|
|
|
|
if ( c != NULL )
|
|
{
|
|
c->EnableORTs (FALSE);
|
|
Quat orientation = p->orientation (frame);
|
|
c->SetValue ( key_time, & orientation );
|
|
c->EnableORTs (TRUE);
|
|
}
|
|
|
|
// Paste position keys.
|
|
|
|
c = tm_controller->GetPositionController ();
|
|
|
|
if ( c != NULL )
|
|
{
|
|
c->EnableORTs (FALSE);
|
|
Point3 position = p->position (frame);
|
|
c->SetValue ( key_time, & position );
|
|
c->EnableORTs (TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
p = p->next ();
|
|
}
|
|
|
|
ResumeAnimate ();
|
|
|
|
TSTR undostr;
|
|
undostr.printf ( "Paste Keys" );
|
|
theHold.Accept ( undostr );
|
|
|
|
ip->RedrawViews ( current_time );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Pose::delete_keys
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Pose::delete_keys ()
|
|
{
|
|
while ( first_key != NULL )
|
|
{
|
|
Node_Key * delete_p = first_key;
|
|
first_key = first_key->next ();
|
|
delete delete_p;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Pose::Add_Objects_To_List
|
|
//----------------------------------------------------------------------------
|
|
|
|
void Pose::Add_Objects_To_List ( HWND hWnd )
|
|
{
|
|
for ( Node_Key * k = first_key; k != NULL; k = k->next () )
|
|
{
|
|
SendDlgItemMessage ( hWnd, IDC_OBJECT_LIST, LB_ADDSTRING, 0,
|
|
(LPARAM) (LPCTSTR) k->name () );
|
|
}
|
|
}
|