// 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); SetSaveRequiredFlag(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; }