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.
1523 lines
36 KiB
C++
1523 lines
36 KiB
C++
// JointEditDialog.cpp : implementation file
|
|
//
|
|
|
|
#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 "JointEditDialog.h"
|
|
|
|
//#ifdef _DEBUG
|
|
//#define new DEBUG_NEW
|
|
//#undef THIS_FILE
|
|
//static char THIS_FILE[] = __FILE__;
|
|
//#endif
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// JointEditDialog dialog
|
|
|
|
|
|
JointEditDialog::JointEditDialog(INode *root_node, Interface *ip, CWnd* pParent /*=NULL*/)
|
|
: CDialog(JointEditDialog::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(JointEditDialog)
|
|
m_rotOptCheck = FALSE;
|
|
m_tranOptCheck = FALSE;
|
|
m_rotRangeCheck = FALSE;
|
|
m_tranRangeCheck = FALSE;
|
|
m_encodeVelocityCheck = FALSE;
|
|
m_rotThresholdEdit = 0.0f;
|
|
m_tranThresholdEdit = 0.0f;
|
|
m_rotMaxRange = 0;
|
|
m_rotMinRange = 0;
|
|
m_tranMaxRange = 0;
|
|
m_tranMinRange = 0;
|
|
m_rotConvertCheck = FALSE;
|
|
m_tranConvertCheck = FALSE;
|
|
//}}AFX_DATA_INIT
|
|
m_max_interface = ip;
|
|
m_rootNode = root_node;
|
|
|
|
m_forceExclude = false;
|
|
m_forceConvertRotation = false;
|
|
m_forceConvertTranslation = false;
|
|
}
|
|
|
|
|
|
void JointEditDialog::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
|
|
if (m_firstDataSave)
|
|
{
|
|
//{{AFX_DATA_MAP(JointEditDialog)
|
|
DDX_Control(pDX, IDC_COMBO_TRAN_CONVERT, m_tranConvertCombo);
|
|
DDX_Control(pDX, IDC_COMBO_ROT_CONVERT, m_rotConvertCombo);
|
|
DDX_Control(pDX, IDC_COMBO_INCLUDE, m_includeCombo);
|
|
DDX_Check(pDX, IDC_CHECK_ROT_OPT, m_rotOptCheck);
|
|
DDX_Check(pDX, IDC_CHECK_TRAN_OPT, m_tranOptCheck);
|
|
DDX_Check(pDX, IDC_CHECK_ROT_RANGE, m_rotRangeCheck);
|
|
DDX_Check(pDX, IDC_CHECK_TRAN_RANGE, m_tranRangeCheck);
|
|
DDX_Check(pDX, IDC_CHECK_ENCODE_VELOCITY, m_encodeVelocityCheck);
|
|
DDX_Text(pDX, IDC_EDIT_ROT_THRESH, m_rotThresholdEdit);
|
|
DDX_Text(pDX, IDC_EDIT_TRAN_THRESH, m_tranThresholdEdit);
|
|
DDX_Text(pDX, IDC_ROT_MAX_RANGE, m_rotMaxRange);
|
|
DDX_Text(pDX, IDC_ROT_MIN_RANGE, m_rotMinRange);
|
|
DDX_Text(pDX, IDC_TRAN_MAX_RANGE, m_tranMaxRange);
|
|
DDX_Text(pDX, IDC_TRAN_MIN_RANGE, m_tranMinRange);
|
|
DDX_Check(pDX, IDC_CONVERT_ROT_CHECK, m_rotConvertCheck);
|
|
DDX_Check(pDX, IDC_CONVERT_TRAN_CHECK, m_tranConvertCheck);
|
|
//}}AFX_DATA_MAP
|
|
|
|
m_firstDataSave = false;
|
|
}
|
|
|
|
GetDlgItem(IDC_COMBO_INCLUDE)->EnableWindow(true);
|
|
GetDlgItem(IDC_CONVERT_ROT_CHECK)->EnableWindow(true);
|
|
GetDlgItem(IDC_CONVERT_TRAN_CHECK)->EnableWindow(true);
|
|
|
|
|
|
{
|
|
|
|
|
|
DDX_Control(pDX, IDC_COMBO_INCLUDE, m_includeCombo);
|
|
|
|
if (m_forceExclude)
|
|
{
|
|
GetDlgItem(IDC_COMBO_INCLUDE)->EnableWindow(false);
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_COMBO_INCLUDE)->EnableWindow(true);
|
|
}
|
|
|
|
|
|
DDX_Check(pDX, IDC_CHECK_ENCODE_VELOCITY, m_encodeVelocityCheck);
|
|
|
|
//-----------------------------------------------------------
|
|
// Do the rotation
|
|
|
|
DDX_Check(pDX, IDC_CONVERT_ROT_CHECK, m_rotConvertCheck);
|
|
if (m_rotConvertCheck)
|
|
{
|
|
DDX_Control(pDX, IDC_COMBO_ROT_CONVERT, m_rotConvertCombo);
|
|
GetDlgItem(IDC_COMBO_ROT_CONVERT)->EnableWindow(true);
|
|
|
|
if (m_forceConvertRotation)
|
|
{
|
|
GetDlgItem(IDC_CONVERT_ROT_CHECK)->EnableWindow(false);
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_CONVERT_ROT_CHECK)->EnableWindow(true);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// if we are loading then disable the controls
|
|
if (!pDX->m_bSaveAndValidate)
|
|
{
|
|
GetDlgItem(IDC_COMBO_ROT_CONVERT)->EnableWindow(false);
|
|
CComboBox *box = (CComboBox *)GetDlgItem(IDC_COMBO_ROT_CONVERT);
|
|
box->SetCurSel( -1 );
|
|
}
|
|
}
|
|
|
|
|
|
DDX_Check(pDX, IDC_CHECK_ROT_OPT, m_rotOptCheck);
|
|
if (m_rotOptCheck)
|
|
{
|
|
DDX_Text(pDX, IDC_EDIT_ROT_THRESH, m_rotThresholdEdit);
|
|
DDX_Check(pDX, IDC_CHECK_ROT_RANGE, m_rotRangeCheck);
|
|
|
|
GetDlgItem(IDC_EDIT_ROT_THRESH)->EnableWindow(true);
|
|
GetDlgItem(IDC_CHECK_ROT_RANGE)->EnableWindow(true);
|
|
|
|
|
|
if (m_rotRangeCheck)
|
|
{
|
|
DDX_Text(pDX, IDC_ROT_MAX_RANGE, m_rotMaxRange);
|
|
DDX_Text(pDX, IDC_ROT_MIN_RANGE, m_rotMinRange);
|
|
GetDlgItem(IDC_ROT_MIN_RANGE)->EnableWindow(true);
|
|
GetDlgItem(IDC_ROT_MAX_RANGE)->EnableWindow(true);
|
|
}
|
|
else
|
|
{
|
|
// if we are loading then disable the controls
|
|
if (!pDX->m_bSaveAndValidate)
|
|
{
|
|
GetDlgItem(IDC_ROT_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_ROT_MAX_RANGE)->EnableWindow(false);
|
|
CEdit *edit;
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if we are loading then disable the controls
|
|
if (!pDX->m_bSaveAndValidate)
|
|
{
|
|
GetDlgItem(IDC_EDIT_ROT_THRESH)->EnableWindow(false);
|
|
GetDlgItem(IDC_CHECK_ROT_RANGE)->EnableWindow(false);
|
|
|
|
CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT_ROT_THRESH);
|
|
edit->SetWindowText("");
|
|
|
|
GetDlgItem(IDC_ROT_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_ROT_MAX_RANGE)->EnableWindow(false);
|
|
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
// Do the translation
|
|
|
|
DDX_Check(pDX, IDC_CONVERT_TRAN_CHECK, m_tranConvertCheck);
|
|
if (m_tranConvertCheck)
|
|
{
|
|
DDX_Control(pDX, IDC_COMBO_TRAN_CONVERT, m_tranConvertCombo);
|
|
GetDlgItem(IDC_COMBO_TRAN_CONVERT)->EnableWindow(true);
|
|
|
|
if (m_forceConvertTranslation)
|
|
{
|
|
GetDlgItem(IDC_CONVERT_TRAN_CHECK)->EnableWindow(false);
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_CONVERT_TRAN_CHECK)->EnableWindow(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if we are loading then disable the controls
|
|
if (!pDX->m_bSaveAndValidate)
|
|
{
|
|
GetDlgItem(IDC_COMBO_TRAN_CONVERT)->EnableWindow(false);
|
|
CComboBox *box = (CComboBox *)GetDlgItem(IDC_COMBO_TRAN_CONVERT);
|
|
box->SetCurSel( -1 );
|
|
}
|
|
}
|
|
|
|
DDX_Check(pDX, IDC_CHECK_TRAN_OPT, m_tranOptCheck);
|
|
if (m_tranOptCheck)
|
|
{
|
|
DDX_Text(pDX, IDC_EDIT_TRAN_THRESH, m_tranThresholdEdit);
|
|
DDX_Check(pDX, IDC_CHECK_TRAN_RANGE, m_tranRangeCheck);
|
|
GetDlgItem(IDC_EDIT_TRAN_THRESH)->EnableWindow(true);
|
|
GetDlgItem(IDC_CHECK_TRAN_RANGE)->EnableWindow(true);
|
|
|
|
if (m_tranRangeCheck)
|
|
{
|
|
DDX_Text(pDX, IDC_TRAN_MAX_RANGE, m_tranMaxRange);
|
|
DDX_Text(pDX, IDC_TRAN_MIN_RANGE, m_tranMinRange);
|
|
GetDlgItem(IDC_TRAN_MIN_RANGE)->EnableWindow(true);
|
|
GetDlgItem(IDC_TRAN_MAX_RANGE)->EnableWindow(true);
|
|
}
|
|
else
|
|
{
|
|
// if we are loading then disable the controls
|
|
if (!pDX->m_bSaveAndValidate)
|
|
{
|
|
GetDlgItem(IDC_TRAN_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_TRAN_MAX_RANGE)->EnableWindow(false);
|
|
CEdit *edit;
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if we are loading then disable the controls
|
|
if (!pDX->m_bSaveAndValidate)
|
|
{
|
|
GetDlgItem(IDC_EDIT_TRAN_THRESH)->EnableWindow(false);
|
|
GetDlgItem(IDC_CHECK_TRAN_RANGE)->EnableWindow(false);
|
|
|
|
|
|
CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT_TRAN_THRESH);
|
|
edit->SetWindowText("");
|
|
|
|
GetDlgItem(IDC_TRAN_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_TRAN_MAX_RANGE)->EnableWindow(false);
|
|
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(JointEditDialog, CDialog)
|
|
//{{AFX_MSG_MAP(JointEditDialog)
|
|
ON_BN_CLICKED(ID_REVERT_JOINT, OnRevertJoint)
|
|
ON_NOTIFY(TVN_SELCHANGED, IDC_NODE_TREE, OnSelchangedNodeTree)
|
|
ON_BN_CLICKED(IDC_CHECK_ROT_OPT, OnCheckRotOpt)
|
|
ON_BN_CLICKED(IDC_CONVERT_ROT_CHECK, OnConvertRotCheck)
|
|
ON_BN_CLICKED(IDC_CHECK_ROT_RANGE, OnCheckRotRange)
|
|
ON_BN_CLICKED(IDC_CONVERT_TRAN_CHECK, OnConvertTranCheck)
|
|
ON_BN_CLICKED(IDC_CHECK_TRAN_OPT, OnCheckTranOpt)
|
|
ON_BN_CLICKED(IDC_CHECK_TRAN_RANGE, OnCheckTranRange)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// JointEditDialog message handlers
|
|
|
|
BOOL JointEditDialog::OnInitDialog()
|
|
{
|
|
|
|
// prime the pump...
|
|
AddJointPreference(m_rootNode);
|
|
|
|
|
|
m_firstDataSave = true;
|
|
CDialog::OnInitDialog();
|
|
|
|
|
|
// set up the combos...
|
|
m_tranConvertCombo.InsertString(-1, "Linear");
|
|
m_tranConvertCombo.InsertString(-1, "EulerXYZ");
|
|
m_tranConvertCombo.InsertString(-1, "PositionXYZ");
|
|
|
|
m_rotConvertCombo.InsertString(-1, "Linear");
|
|
m_rotConvertCombo.InsertString(-1, "EulerXYZ");
|
|
m_rotConvertCombo.InsertString(-1, "PositionXYZ");
|
|
|
|
m_includeCombo.InsertString(-1, "Exclude");
|
|
m_includeCombo.InsertString(-1, "Include");
|
|
m_includeCombo.InsertString(-1, "Auto");
|
|
|
|
// init the tree...
|
|
|
|
CTreeCtrl *tree = (CTreeCtrl *)GetDlgItem(IDC_NODE_TREE);
|
|
|
|
HTREEITEM top_item = AddToTree(tree, m_rootNode, TVI_ROOT);
|
|
|
|
tree->EnsureVisible(top_item);
|
|
tree->SelectItem(top_item);
|
|
|
|
|
|
|
|
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
HTREEITEM JointEditDialog::AddToTree(CTreeCtrl *tree, INode *node, HTREEITEM parent)
|
|
{
|
|
|
|
HTREEITEM new_entry = tree->InsertItem( node->GetName(), parent, TVI_LAST );
|
|
tree->SetItemData(new_entry, (DWORD)node);
|
|
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
AddToTree(tree, node->GetChildNode(c), new_entry);
|
|
}
|
|
|
|
tree->Expand(new_entry, TVE_EXPAND );
|
|
|
|
return new_entry;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void JointEditDialog::OnOK()
|
|
{
|
|
|
|
// save the current node...
|
|
CTreeCtrl *tree = (CTreeCtrl *)GetDlgItem(IDC_NODE_TREE);
|
|
|
|
INode *node = (INode*)tree->GetItemData(tree->GetSelectedItem());
|
|
|
|
if (!node->IsRootNode())
|
|
{
|
|
|
|
|
|
AppDataChunk *ad =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID
|
|
);
|
|
|
|
JointPreference *j_pref = (JointPreference *)ad->data;
|
|
SaveControls(j_pref);
|
|
}
|
|
|
|
|
|
|
|
AcceptTempData(m_max_interface->GetRootNode());
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void JointEditDialog::OnCancel()
|
|
{
|
|
|
|
|
|
CancelTempData(m_max_interface->GetRootNode());
|
|
|
|
CDialog::OnCancel();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
JointPreference * JointEditDialog::GetJointPrefrence(INode* node)
|
|
{
|
|
AppDataChunk *ad =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID
|
|
);
|
|
|
|
if (ad != NULL)
|
|
{
|
|
return (JointPreference *)ad->data;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void JointEditDialog::CopyJointPrefrence(INode* source_node, INode* target_node)
|
|
{
|
|
AppDataChunk *ad =
|
|
source_node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID
|
|
);
|
|
|
|
if (ad != NULL)
|
|
{
|
|
size_t size = ad->length;
|
|
BYTE *data = new BYTE[size];
|
|
|
|
Mem_Copy(data, ad->data, ad->length, size);
|
|
|
|
target_node->AddAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID,
|
|
size, data);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void JointEditDialog::AcceptTempData(INode *node)
|
|
{
|
|
AppDataChunk *ad =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID
|
|
);
|
|
if (ad)
|
|
{
|
|
node->RemoveAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID);
|
|
|
|
|
|
size_t size = ad->length;
|
|
BYTE *data = new BYTE[size];
|
|
|
|
Mem_Copy(data, ad->data, ad->length, size);
|
|
|
|
node->AddAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID,
|
|
size, data);
|
|
|
|
// now kill the temp data
|
|
node->RemoveAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID);
|
|
|
|
SetSaveRequired(TRUE);
|
|
}
|
|
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
AcceptTempData(node->GetChildNode(c));
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void JointEditDialog::CancelTempData(INode *node)
|
|
{
|
|
|
|
node->RemoveAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID);
|
|
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
CancelTempData(node->GetChildNode(c));
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void JointEditDialog::DeleteAllJointPrefrence(INode* node)
|
|
{
|
|
|
|
|
|
if (!node->IsRootNode())
|
|
{
|
|
node->RemoveAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID);
|
|
|
|
node->RemoveAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID);
|
|
|
|
}
|
|
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
DeleteAllJointPrefrence(node->GetChildNode(c));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void JointEditDialog::OnRevertJoint()
|
|
{
|
|
|
|
// reinitialize this joints temporary data with it's perminate data.
|
|
|
|
// remove temp data
|
|
// copy perm data into temp data
|
|
|
|
CTreeCtrl *tree = (CTreeCtrl *)GetDlgItem(IDC_NODE_TREE);
|
|
|
|
INode *node = (INode*)tree->GetItemData(tree->GetSelectedItem());
|
|
|
|
|
|
AppDataChunk *ad_perm =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID
|
|
);
|
|
|
|
Verify(ad_perm != NULL);
|
|
|
|
size_t size = ad_perm->length;
|
|
BYTE *data = new BYTE[size];
|
|
|
|
Mem_Copy(data, ad_perm->data, ad_perm->length, size);
|
|
|
|
// remove it if it exists...
|
|
node->RemoveAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID);
|
|
|
|
node->AddAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID,
|
|
size, data);
|
|
|
|
AppDataChunk *ad =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID
|
|
);
|
|
|
|
Verify(ad != NULL);
|
|
// we just added it!
|
|
|
|
ClearControls();
|
|
|
|
JointPreference *j_pref = (JointPreference *)ad->data;
|
|
InitControls(j_pref);
|
|
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void JointEditDialog::OnSelchangedNodeTree(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
|
CTreeCtrl *tree = (CTreeCtrl *)GetDlgItem(IDC_NODE_TREE);
|
|
|
|
// Save old node data...
|
|
if (pNMTreeView->itemOld.hItem != NULL)
|
|
{
|
|
// copy the interface into the tempdata
|
|
// get pointer to data
|
|
|
|
INode *node = (INode*)tree->GetItemData(pNMTreeView->itemOld.hItem);
|
|
|
|
if (!node->IsRootNode())
|
|
{
|
|
|
|
|
|
AppDataChunk *ad =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID
|
|
);
|
|
|
|
JointPreference *j_pref = (JointPreference *)ad->data;
|
|
SaveControls(j_pref);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Load this data segment
|
|
|
|
INode *node = (INode*)tree->GetItemData(pNMTreeView->itemNew.hItem);
|
|
|
|
if (node->IsRootNode())
|
|
{
|
|
ClearControls();
|
|
return;
|
|
}
|
|
|
|
AppDataChunk *ad =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID
|
|
);
|
|
|
|
if (!ad)
|
|
{
|
|
// Not found!
|
|
// copy from the other perm data segment...
|
|
|
|
AppDataChunk *ad_perm =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID
|
|
);
|
|
|
|
Verify(ad_perm != NULL);
|
|
|
|
size_t size = ad_perm->length;
|
|
BYTE *data = new BYTE[size];
|
|
|
|
Mem_Copy(data, ad_perm->data, ad_perm->length, size);
|
|
|
|
node->AddAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID,
|
|
size, data);
|
|
|
|
|
|
ad = node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
TEMP_DATA_ID
|
|
);
|
|
|
|
}
|
|
|
|
|
|
// copy ad into the interface
|
|
ClearControls();
|
|
|
|
JointPreference *j_pref = (JointPreference *)ad->data;
|
|
InitControls(j_pref);
|
|
|
|
*pResult = 0;
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void JointEditDialog::ClearControls()
|
|
{
|
|
|
|
|
|
|
|
// Clear the combos
|
|
m_tranConvertCombo.SetCurSel( -1 );
|
|
m_rotConvertCombo.SetCurSel( -1 );
|
|
m_includeCombo.SetCurSel( -1 );
|
|
|
|
|
|
m_rotOptCheck = false;
|
|
m_tranOptCheck = false;
|
|
m_rotRangeCheck = false;
|
|
m_tranRangeCheck = false;
|
|
m_rotConvertCheck = false;
|
|
m_tranConvertCheck = false;
|
|
m_encodeVelocityCheck = false;
|
|
m_rotThresholdEdit = 0.0f;
|
|
m_tranThresholdEdit = 0.0f;
|
|
m_rotMaxRange = 0;
|
|
m_rotMinRange = 0;
|
|
m_tranMaxRange = 0;
|
|
m_tranMinRange = 0;
|
|
|
|
UpdateData(false);
|
|
|
|
// clear out the edits
|
|
CEdit *edit;
|
|
|
|
edit = (CEdit *)GetDlgItem(IDC_EDIT_ROT_THRESH);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_EDIT_TRAN_THRESH);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
|
|
GetDlgItem(IDC_COMBO_TRAN_CONVERT)->EnableWindow(false);
|
|
GetDlgItem(IDC_TRAN_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_TRAN_MAX_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_EDIT_TRAN_THRESH)->EnableWindow(false);
|
|
GetDlgItem(IDC_CHECK_TRAN_RANGE)->EnableWindow(false);
|
|
|
|
GetDlgItem(IDC_COMBO_ROT_CONVERT)->EnableWindow(false);
|
|
GetDlgItem(IDC_ROT_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_ROT_MAX_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_EDIT_ROT_THRESH)->EnableWindow(false);
|
|
GetDlgItem(IDC_CHECK_ROT_RANGE)->EnableWindow(false);
|
|
|
|
CButton *button;
|
|
|
|
button = (CButton *)GetDlgItem(IDC_CHECK_TRAN_RANGE);
|
|
button->SetCheck(0);
|
|
|
|
button = (CButton *)GetDlgItem(IDC_CHECK_ROT_RANGE);
|
|
button->SetCheck(0);
|
|
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void JointEditDialog::SaveControls(JointPreference *j_pref)
|
|
{
|
|
UpdateData(true);
|
|
|
|
j_pref->m_forceExclude = m_forceExclude;
|
|
j_pref->m_forceConvertRotation = m_forceConvertRotation;
|
|
j_pref->m_forceConvertTranslation = m_forceConvertTranslation;
|
|
|
|
|
|
j_pref->m_excludeJoint = m_includeCombo.GetCurSel();
|
|
j_pref->m_decodeWithVelocity = (m_encodeVelocityCheck)?true:false;
|
|
Verify(j_pref->m_decodeWithVelocity == true || j_pref->m_decodeWithVelocity == false);
|
|
|
|
//SPEW((0, "SAVE : %d : %d", j_pref->m_decodeWithVelocity, encodeVelocityCheck ));
|
|
|
|
|
|
j_pref->m_convertRotationJoint = (m_rotConvertCheck)?true:false;;
|
|
if (m_rotConvertCheck)
|
|
{
|
|
j_pref->m_rotationConvertType = m_rotConvertCombo.GetCurSel();
|
|
}
|
|
|
|
j_pref->m_convertTranslationJoint = (m_tranConvertCheck)?true:false;;
|
|
if (m_tranConvertCheck)
|
|
{
|
|
j_pref->m_translationConvertType = m_tranConvertCombo.GetCurSel();
|
|
}
|
|
|
|
j_pref->m_optimizeRotation = (m_rotOptCheck)?true:false;;
|
|
if (m_rotOptCheck)
|
|
{
|
|
j_pref->m_rotationThreshold = m_rotThresholdEdit;
|
|
j_pref->m_rotationRange = (m_rotRangeCheck)?true:false;;
|
|
if (m_rotRangeCheck)
|
|
{
|
|
j_pref->m_rotationSampleStartFrame = m_rotMinRange;
|
|
j_pref->m_rotationSampleEndFrame = m_rotMaxRange;
|
|
}
|
|
}
|
|
|
|
j_pref->m_optimizeTranslation = (m_tranOptCheck)?true:false;;
|
|
if (m_tranOptCheck)
|
|
{
|
|
j_pref->m_translationThreshold = m_tranThresholdEdit;
|
|
j_pref->m_translationRange = (m_tranRangeCheck)?true:false;;
|
|
if (m_tranRangeCheck)
|
|
{
|
|
j_pref->m_translationSampleStartFrame = m_tranMinRange;
|
|
j_pref->m_translationSampleEndFrame = m_tranMaxRange;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void JointEditDialog::InitControls(JointPreference *j_pref)
|
|
{
|
|
|
|
m_forceExclude = j_pref->m_forceExclude;
|
|
m_forceConvertRotation = j_pref->m_forceConvertRotation;
|
|
m_forceConvertTranslation = j_pref->m_forceConvertTranslation;
|
|
|
|
m_includeCombo.SetCurSel(j_pref->m_excludeJoint);
|
|
m_encodeVelocityCheck = j_pref->m_decodeWithVelocity;
|
|
Verify(j_pref->m_decodeWithVelocity == true || j_pref->m_decodeWithVelocity == false);
|
|
|
|
//SPEW((0, "INIT : %d : %d", j_pref->m_decodeWithVelocity, encodeVelocityCheck ));
|
|
|
|
m_rotConvertCheck = j_pref->m_convertRotationJoint;
|
|
if (m_rotConvertCheck)
|
|
{
|
|
m_rotConvertCombo.SetCurSel(j_pref->m_rotationConvertType);
|
|
}
|
|
|
|
m_tranConvertCheck = j_pref->m_convertTranslationJoint;
|
|
if (m_tranConvertCheck)
|
|
{
|
|
m_tranConvertCombo.SetCurSel(j_pref->m_translationConvertType);
|
|
}
|
|
|
|
m_rotOptCheck = j_pref->m_optimizeRotation;
|
|
if (m_rotOptCheck)
|
|
{
|
|
m_rotThresholdEdit = j_pref->m_rotationThreshold;
|
|
m_rotRangeCheck = j_pref->m_rotationRange;
|
|
if (m_rotRangeCheck)
|
|
{
|
|
m_rotMinRange = j_pref->m_rotationSampleStartFrame;
|
|
m_rotMaxRange = j_pref->m_rotationSampleEndFrame;
|
|
}
|
|
}
|
|
|
|
m_tranOptCheck = j_pref->m_optimizeTranslation;
|
|
if (m_tranOptCheck)
|
|
{
|
|
m_tranThresholdEdit = j_pref->m_translationThreshold;
|
|
m_tranRangeCheck = j_pref->m_translationRange;
|
|
if (m_tranRangeCheck)
|
|
{
|
|
m_tranMinRange = j_pref->m_translationSampleStartFrame;
|
|
m_tranMaxRange = j_pref->m_translationSampleEndFrame;
|
|
}
|
|
}
|
|
|
|
UpdateData(false);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
#define APPDATA_TEST_CLASS_ID 0xf6277abd
|
|
|
|
void JointEditDialog::AddJointPreference(INode* node)
|
|
{
|
|
|
|
AppDataChunk *ad =
|
|
node->GetAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID
|
|
);
|
|
|
|
if (!ad)
|
|
{
|
|
// Not found!
|
|
// Create and load...
|
|
|
|
|
|
if (!node->IsRootNode())
|
|
{
|
|
|
|
JointPreference *joint_preference = (JointPreference *)malloc(sizeof(JointPreference));
|
|
|
|
LoadPrefs(node, joint_preference);
|
|
|
|
node->AddAppDataChunk(
|
|
JOINTPREFS_SAVE_CLASS_ID,
|
|
JOINT_SAVE_SUPER_CLASS_ID,
|
|
PERM_DATA_ID,
|
|
(DWORD)sizeof(JointPreference), (void *)joint_preference);
|
|
}
|
|
}
|
|
|
|
|
|
// For each child of this node, we recurse into ourselves
|
|
// and increment the counter until no more children are found.
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
AddJointPreference(node->GetChildNode(c));
|
|
}
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void JointEditDialog::CountNodes(INode* node, int& node_count)
|
|
{
|
|
|
|
node_count++;
|
|
|
|
// For each child of this node, we recurse into ourselves
|
|
// and increment the counter until no more children are found.
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
CountNodes(node->GetChildNode(c), node_count);
|
|
}
|
|
}
|
|
|
|
|
|
//===========================================================================//
|
|
|
|
void JointEditDialog::LoadPrefs(INode* node, JointPreference *prefs)
|
|
{
|
|
// Right now we are just going to fake it...
|
|
// these routines will be used by the prefrence plugin
|
|
|
|
// only allow for geom, helpers, bones, etc...NO CAMERAS, LIGHTS, etc...
|
|
if (!KnownNode(node))
|
|
{
|
|
prefs->m_forceExclude = true;
|
|
prefs->m_excludeJoint = JointPreference::ExcludeJoint;
|
|
prefs->m_decodeWithVelocity = false;
|
|
}
|
|
else if (!NodeAnimated(node))
|
|
{
|
|
prefs->m_forceExclude = false;
|
|
prefs->m_excludeJoint = JointPreference::AutoJoint;
|
|
prefs->m_decodeWithVelocity = false;
|
|
|
|
}
|
|
else
|
|
{
|
|
prefs->m_forceExclude = false;
|
|
prefs->m_excludeJoint = JointPreference::AutoJoint;
|
|
|
|
|
|
const char *node_name = node->GetName();
|
|
|
|
if (!_strnicmp(node_name, "joint_vel", 9))
|
|
{
|
|
prefs->m_decodeWithVelocity = true;
|
|
}
|
|
else
|
|
{
|
|
prefs->m_decodeWithVelocity = false;
|
|
}
|
|
|
|
|
|
// if one is diffrent
|
|
// then we can't be sure that it doesn't mess
|
|
// with the other so we just throw out unless we
|
|
// know both controllers!
|
|
|
|
if (HasKnownControler(node))
|
|
{
|
|
// this should check each one
|
|
prefs->m_convertRotationJoint = false;
|
|
prefs->m_convertTranslationJoint = false;
|
|
prefs->m_optimizeRotation = false;
|
|
prefs->m_optimizeTranslation = false;
|
|
|
|
prefs->m_forceConvertRotation = false;
|
|
prefs->m_forceConvertTranslation = false;
|
|
|
|
prefs->m_rotationRange = false;
|
|
prefs->m_translationRange = false;
|
|
}
|
|
else
|
|
{
|
|
prefs->m_forceConvertRotation = true;
|
|
prefs->m_forceConvertTranslation = true;
|
|
|
|
Interval total_time = m_max_interface->GetAnimRange();
|
|
int start_frame;
|
|
int end_frame;
|
|
|
|
TIME_TO_FRAME(total_time.Start(), start_frame);
|
|
TIME_TO_FRAME(total_time.End(), end_frame);
|
|
|
|
|
|
prefs->m_convertRotationJoint = true;
|
|
prefs->m_convertTranslationJoint = true;
|
|
prefs->m_rotationConvertType = JointPreference::LinearKeyframeType;
|
|
prefs->m_translationConvertType = JointPreference::LinearKeyframeType;
|
|
|
|
prefs->m_optimizeRotation = true;
|
|
prefs->m_rotationThreshold = 0.3f;
|
|
prefs->m_rotationSampleStartFrame = start_frame;
|
|
prefs->m_rotationSampleEndFrame = end_frame;
|
|
|
|
|
|
prefs->m_optimizeTranslation = true;
|
|
prefs->m_translationThreshold = 0.05f;
|
|
prefs->m_translationSampleStartFrame = start_frame;
|
|
prefs->m_translationSampleEndFrame = end_frame;
|
|
|
|
prefs->m_rotationRange = false;
|
|
prefs->m_translationRange = false;
|
|
}
|
|
|
|
|
|
// Detect if translation is there
|
|
|
|
// Detect if rotation is there
|
|
|
|
|
|
}
|
|
|
|
Verify(prefs->m_decodeWithVelocity == true || prefs->m_decodeWithVelocity == false);
|
|
|
|
}
|
|
|
|
//===========================================================================//
|
|
|
|
|
|
bool JointEditDialog::NodeIsRoot(INode* node)
|
|
{
|
|
// root node defined as being a child to theworld
|
|
if (m_max_interface->GetRootNode() == node->GetParentNode())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
//===========================================================================//
|
|
|
|
bool JointEditDialog::KnownNode(INode* node)
|
|
{
|
|
ObjectState os;
|
|
SClass_ID SCID;
|
|
Class_ID CID;
|
|
|
|
os = node->EvalWorldState(m_max_interface->GetTime());
|
|
|
|
if (os.obj)
|
|
{
|
|
SCID = os.obj->SuperClassID();
|
|
CID = os.obj->ClassID();
|
|
switch (SCID)
|
|
{
|
|
case GEOMOBJECT_CLASS_ID:
|
|
return true;
|
|
|
|
case HELPER_CLASS_ID:
|
|
if (CID == Class_ID(DUMMY_CLASS_ID,0) || CID == Class_ID(BONE_CLASS_ID, 0)
|
|
||CID == SITEOBJECT_CLASS_ID)
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
//===========================================================================//
|
|
|
|
|
|
bool
|
|
JointEditDialog::HasKnownControler(INode *node)
|
|
{
|
|
Control *c;
|
|
c = node->GetTMController();
|
|
|
|
// If known consists of .. is the top a leaf node? if so is it a PRS_CONTROL_CLASS_ID ?
|
|
// If it is a prs, are both the p & r known to me?
|
|
// we ignore scale.
|
|
|
|
|
|
// This works but...MAN...do we need Euelers now!
|
|
|
|
|
|
// Check leaf, if it is not a leaf ( leaf is the last node on a branch, imagine )
|
|
// then it must be procedural and wierd. That would mean that it has one controller
|
|
// for position, rotation and scale
|
|
if (c->IsLeaf())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Make sure it is a Position Rotation Scale control class, since we don't support hybreeds.
|
|
if (c->ClassID().PartA() != PRS_CONTROL_CLASS_ID)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
IsKnownControlerType(c->GetRotationController()) &&
|
|
IsKnownControlerType(c->GetPositionController())
|
|
)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
// We didn't know it so
|
|
// it is hasta la vista ( ?sp? )
|
|
|
|
return false;
|
|
}
|
|
|
|
//===========================================================================//
|
|
|
|
bool
|
|
JointEditDialog::IsKnownControlerType(Control *c)
|
|
{
|
|
if ( c == NULL )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
switch(c->ClassID().PartA())
|
|
{
|
|
case LININTERP_POSITION_CLASS_ID:
|
|
case LININTERP_ROTATION_CLASS_ID:
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
//===========================================================================//
|
|
|
|
bool JointEditDialog::NodeAnimated(INode* node)
|
|
{
|
|
// this does not correctly get bones....
|
|
// only way to tell is to spin through them...
|
|
|
|
|
|
#if 0
|
|
ObjectState os;
|
|
SClass_ID SCID;
|
|
Class_ID CID;
|
|
|
|
os = node->EvalWorldState(0);
|
|
|
|
if (os.obj)
|
|
{
|
|
SCID = os.obj->SuperClassID();
|
|
CID = os.obj->ClassID();
|
|
|
|
|
|
if ((SCID == HELPER_CLASS_ID) && (CID == Class_ID(BONE_CLASS_ID, 0)))
|
|
{
|
|
|
|
if (node->IsAnimated())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
Interval iv = m_max_interface->GetAnimRange();
|
|
|
|
TimeValue start = iv.Start();
|
|
TimeValue end = iv.End();
|
|
int delta = GetTicksPerFrame();
|
|
|
|
Matrix3 lastTM = node->GetNodeTM(start);
|
|
|
|
for (int time_of_key=start; time_of_key<=end; time_of_key+=delta)
|
|
{
|
|
Matrix3 nodeTM;
|
|
nodeTM = node->GetNodeTM(time_of_key);
|
|
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
Point3 m1 = nodeTM.GetRow(i);
|
|
Point3 m2 = lastTM.GetRow(i);
|
|
|
|
if (m1 != m2)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
lastTM = nodeTM;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return (node->IsAnimated())?true:false;
|
|
|
|
#endif
|
|
|
|
//just evaluate the name
|
|
|
|
//cull out sites unless they are animated...
|
|
//cull out anything not joint_
|
|
|
|
const char *node_name = node->GetName();
|
|
|
|
if (!_stricmp(node_name, "joint_world"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
if (!_stricmp(node_name, "joint_lgunabove"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!_stricmp(node_name, "joint_luarmabove"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!_stricmp(node_name, "joint_rgunabove"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!_stricmp(node_name, "joint_ruarmabove"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!_stricmp(node_name, "joint_torsoabove"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!_stricmp(node_name, "joint_torsobelow"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!_stricmp(node_name, "joint_hipabove"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!_stricmp(node_name, "joint_hipbelow"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
if (!_strnicmp(node_name, "joint_", 6))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (!_strnicmp(node_name, "site_", 5))
|
|
{
|
|
if (node_name)
|
|
{
|
|
|
|
ObjectState os;
|
|
os = node->EvalWorldState(0);
|
|
SClass_ID SCID;
|
|
Class_ID CID;
|
|
|
|
if (os.obj)
|
|
{
|
|
SCID = os.obj->SuperClassID();
|
|
CID = os.obj->ClassID();
|
|
if (SCID == HELPER_CLASS_ID && CID == SITEOBJECT_CLASS_ID)
|
|
{
|
|
IParamBlock *pb = (IParamBlock*)os.obj->GetParamBlock();
|
|
|
|
return (pb->IsAnimated())?true:false;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
//deal with life then move on.
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
void JointEditDialog::OnConvertRotCheck()
|
|
{
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CONVERT_ROT_CHECK);
|
|
|
|
if (button->GetCheck())
|
|
{
|
|
GetDlgItem(IDC_COMBO_ROT_CONVERT)->EnableWindow(true);
|
|
CComboBox *box = (CComboBox *)GetDlgItem(IDC_COMBO_ROT_CONVERT);
|
|
box->SetCurSel( 2 );
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_COMBO_ROT_CONVERT)->EnableWindow(false);
|
|
CComboBox *box = (CComboBox *)GetDlgItem(IDC_COMBO_ROT_CONVERT);
|
|
box->SetCurSel( -1 );
|
|
}
|
|
|
|
}
|
|
|
|
void JointEditDialog::OnCheckRotOpt()
|
|
{
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CHECK_ROT_OPT);
|
|
if (button->GetCheck())
|
|
{
|
|
GetDlgItem(IDC_EDIT_ROT_THRESH)->EnableWindow(true);
|
|
GetDlgItem(IDC_CHECK_ROT_RANGE)->EnableWindow(true);
|
|
|
|
CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT_ROT_THRESH);
|
|
edit->SetWindowText("0.3");
|
|
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_EDIT_ROT_THRESH)->EnableWindow(false);
|
|
GetDlgItem(IDC_CHECK_ROT_RANGE)->EnableWindow(false);
|
|
|
|
CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT_ROT_THRESH);
|
|
edit->SetWindowText("");
|
|
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CHECK_ROT_RANGE);
|
|
|
|
if (button->GetCheck())
|
|
{
|
|
button->SetCheck(0);
|
|
GetDlgItem(IDC_ROT_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_ROT_MAX_RANGE)->EnableWindow(false);
|
|
CEdit *edit;
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void JointEditDialog::OnCheckRotRange()
|
|
{
|
|
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CHECK_ROT_RANGE);
|
|
|
|
if (button->GetCheck())
|
|
{
|
|
GetDlgItem(IDC_ROT_MIN_RANGE)->EnableWindow(true);
|
|
GetDlgItem(IDC_ROT_MAX_RANGE)->EnableWindow(true);
|
|
|
|
Interval total_time = m_max_interface->GetAnimRange();
|
|
int start_frame;
|
|
int end_frame;
|
|
|
|
TIME_TO_FRAME(total_time.Start(), start_frame);
|
|
TIME_TO_FRAME(total_time.End(), end_frame);
|
|
|
|
char buffer[20];
|
|
CEdit *edit;
|
|
|
|
sprintf(buffer, "%d", start_frame);
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MIN_RANGE);
|
|
edit->SetWindowText(buffer);
|
|
|
|
sprintf(buffer, "%d", end_frame);
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MAX_RANGE);
|
|
edit->SetWindowText(buffer);
|
|
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_ROT_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_ROT_MAX_RANGE)->EnableWindow(false);
|
|
CEdit *edit;
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_ROT_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
|
|
}
|
|
}
|
|
|
|
void JointEditDialog::OnConvertTranCheck()
|
|
{
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CONVERT_TRAN_CHECK);
|
|
|
|
if (button->GetCheck())
|
|
{
|
|
GetDlgItem(IDC_COMBO_TRAN_CONVERT)->EnableWindow(true);
|
|
CComboBox *box = (CComboBox *)GetDlgItem(IDC_COMBO_TRAN_CONVERT);
|
|
box->SetCurSel( 2 );
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_COMBO_TRAN_CONVERT)->EnableWindow(false);
|
|
CComboBox *box = (CComboBox *)GetDlgItem(IDC_COMBO_TRAN_CONVERT);
|
|
box->SetCurSel( -1 );
|
|
}
|
|
|
|
}
|
|
|
|
void JointEditDialog::OnCheckTranOpt()
|
|
{
|
|
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CHECK_TRAN_OPT);
|
|
if (button->GetCheck())
|
|
{
|
|
GetDlgItem(IDC_EDIT_TRAN_THRESH)->EnableWindow(true);
|
|
GetDlgItem(IDC_CHECK_TRAN_RANGE)->EnableWindow(true);
|
|
|
|
CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT_TRAN_THRESH);
|
|
edit->SetWindowText("0.05");
|
|
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_EDIT_TRAN_THRESH)->EnableWindow(false);
|
|
GetDlgItem(IDC_CHECK_TRAN_RANGE)->EnableWindow(false);
|
|
|
|
|
|
CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT_TRAN_THRESH);
|
|
edit->SetWindowText("");
|
|
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CHECK_TRAN_RANGE);
|
|
|
|
if (button->GetCheck())
|
|
{
|
|
button->SetCheck(0);
|
|
GetDlgItem(IDC_TRAN_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_TRAN_MAX_RANGE)->EnableWindow(false);
|
|
CEdit *edit;
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void JointEditDialog::OnCheckTranRange()
|
|
{
|
|
|
|
CButton *button = (CButton *)GetDlgItem(IDC_CHECK_TRAN_RANGE);
|
|
|
|
if (button->GetCheck())
|
|
{
|
|
GetDlgItem(IDC_TRAN_MIN_RANGE)->EnableWindow(true);
|
|
GetDlgItem(IDC_TRAN_MAX_RANGE)->EnableWindow(true);
|
|
|
|
Interval total_time = m_max_interface->GetAnimRange();
|
|
int start_frame;
|
|
int end_frame;
|
|
|
|
TIME_TO_FRAME(total_time.Start(), start_frame);
|
|
TIME_TO_FRAME(total_time.End(), end_frame);
|
|
|
|
char buffer[20];
|
|
CEdit *edit;
|
|
|
|
sprintf(buffer, "%d", start_frame);
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MIN_RANGE);
|
|
edit->SetWindowText(buffer);
|
|
|
|
sprintf(buffer, "%d", end_frame);
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MAX_RANGE);
|
|
edit->SetWindowText(buffer);
|
|
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_TRAN_MIN_RANGE)->EnableWindow(false);
|
|
GetDlgItem(IDC_TRAN_MAX_RANGE)->EnableWindow(false);
|
|
CEdit *edit;
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MIN_RANGE);
|
|
edit->SetWindowText("");
|
|
edit = (CEdit *)GetDlgItem(IDC_TRAN_MAX_RANGE);
|
|
edit->SetWindowText("");
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
int
|
|
JointEditDialog::CountChildren(
|
|
INode *node
|
|
)
|
|
{
|
|
|
|
|
|
// Me
|
|
int total_count = 1;
|
|
|
|
// and all my children
|
|
for (int i = 0; i < node->NumberOfChildren(); i++)
|
|
{
|
|
INode *child_node = node->GetChildNode(i);
|
|
assert(child_node != NULL);
|
|
total_count += CountChildren(child_node);
|
|
}
|
|
|
|
return total_count;
|
|
}
|
|
|