//===========================================================================// // File: HilAdjust.cpp // Project: MechWarrior 4 // Contents: Plugin to adjust height of max anmiations //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 04/28/99 JSE Initial coding, // 06/22/99 jkyle Maintenance and cleanup //---------------------------------------------------------------------------// // Copyright (C) 1998, Fasa Interactive, Inc. // All Rights reserved worldwide // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //===========================================================================// #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 "HillAdjust.hpp" #include ".\buildnum\curver.h" #pragma pack(push,8) const float NAN = (float)fmod(0.0,0.0); char g_szDir[][6] = {"Up","Down","Left","Right"}; HFONT g_hMyFont = NULL; int g_bHold = 0; CMapWordToOb g_mapCtlData; //#ifdef _DEBUG //#define new DEBUG_NEW //#undef THIS_FILE //static char THIS_FILE[] = __FILE__; //#endif HillAdjustPanel g_hillAdjustPanel; ////////////////// //Local Prototypes // Class that g_mapCtlData maps to class CCtlData : public CObject { float m_fDefault,m_fOldValue; ISpinnerControl *m_pSpinner; int m_idEdit,m_idSpinner,m_idCheck,m_bEnabled; public: CCtlData(HWND hWnd,HKEY hKey,int idCheck,int idSpinner,int idEdit,float min,float max,float inc,float fDefault); virtual ~CCtlData(); ISpinnerControl *GetSpinner() { return m_pSpinner;}; int GetIdEdit() {return m_idEdit;}; float SaveValue(float fval); float GetDefault() {return m_fDefault;}; int GetIdSpinner() {return m_idSpinner;}; int IsEnabled() {return m_bEnabled;}; void Enable(int i) {m_bEnabled = i;}; }; CCtlData::CCtlData(HWND hWnd,HKEY hKey,int idCheck,int idSpinner,int idEdit,float min,float max,float inc,float fDefault) { float fcurrent = fDefault; int m_bEnabled = 0; if (hKey) { DWORD wType = REG_SZ; char szValue[100]; BYTE *pData = (BYTE *)szValue; DWORD size = 100; char szInt[20]; if (ERROR_SUCCESS != RegQueryValueEx(hKey,itoa(idCheck,szInt,10),0,&wType,pData,&size)) { } else sscanf(szValue,"%i %f",&m_bEnabled,&fcurrent); } m_pSpinner = SetupFloatSpinner(hWnd,idSpinner,idEdit,min,max,fcurrent,inc); m_idEdit = idEdit; m_idSpinner = idSpinner; m_idCheck = idCheck; m_fDefault = fDefault; m_fOldValue = fDefault; g_mapCtlData.SetAt(idCheck,this); //if (!m_bEnabled) if (fabs(fDefault - fcurrent) > 0.0001f) { SetDlgFont(GetDlgItem(hWnd,idEdit),g_hMyFont); } else { SetDlgFont(GetDlgItem(hWnd,idEdit),GetFixedFont()); } InvalidateRect(GetDlgItem(hWnd,idEdit),NULL,false); // EnableWindow(GetDlgItem(hWnd,idEdit),bEnabled); } CCtlData::~CCtlData() { ReleaseISpinner(m_pSpinner); } float CCtlData::SaveValue(float fval) { float oldval = m_fOldValue; m_fOldValue = fval; return oldval; } char g_szDestPath[MAX_PATH]; static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { RECT rect; // //Center the browse dialog on the screen... // switch (uMsg) { case BFFM_INITIALIZED: { char szPath[MAX_PATH]; GetCurrentDirectory(MAX_PATH,szPath); SendMessage(hWnd,BFFM_SETSELECTION,TRUE,(LPARAM)szPath); if (GetWindowRect(hWnd, &rect)) { SetWindowPos(hWnd, HWND_TOP, (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) >> 1, (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) >> 1, 0, 0, SWP_NOSIZE); } } } return 0; } //////////////////////////////////////////////////////////////////////////////// // hillAdjustPanel Dialog Procedure to handle User and System Interactions static int CALLBACK HillAdjustPanelProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // ICustomControl *pControl = NULL; switch (msg) { case WM_QUICKFILE_BEGIN: { TCHAR szBuffer[MAX_PATH]; LPITEMIDLIST pidlBrowse,pidlRoot; BROWSEINFO bi; LPMALLOC lpMalloc; SHGetMalloc(&lpMalloc); ASSERT(lpMalloc); bi.hwndOwner = hWnd; // Get the ID for the "My Computer" root folder SHGetSpecialFolderLocation(hWnd,CSIDL_DRIVES,&pidlRoot); bi.pidlRoot = pidlRoot; bi.pszDisplayName = szBuffer; // Localize the descriptive text bi.lpszTitle = "Select Destination Folder"; // BIF_EDITBOX and BIF_VALIDATE are for versions 4.71 and later, they // might be ignored by older versions bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;//BIF_USENEWUI;//BIF_EDITBOX; //BIF_RETURNONLYFSDIRS | BIF_EDITBOX;// | BIF_VALIDATE; bi.lParam = 0; bi.iImage = NULL; bi.lpfn = BrowseCallbackProc; g_szDestPath[0] = '\0'; // //Call the Windows shell folder browsing routine... // pidlBrowse = SHBrowseForFolder(&bi); if (NULL != pidlBrowse) { if (SHGetPathFromIDList(pidlBrowse, g_szDestPath)) { if ('\\' == szBuffer[lstrlen(szBuffer)-1]) szBuffer[lstrlen(szBuffer)-1] = '\0'; } else g_szDestPath[0] = '\0'; // //Free up shell memory used... // lpMalloc->Free(pidlBrowse); } lpMalloc->Free(pidlRoot); lpMalloc->Release(); break; } case WM_QUICKFILE_END: { break; } case WM_QUICKFILE_APPLYFILE: { char *name = (char *)wParam; char *path = (char *)lParam; g_hillAdjustPanel.m_ip->LoadFromFile(path); theHold.SuperBegin(); g_hillAdjustPanel.AdjustToHill(); g_hillAdjustPanel.m_ip->RedrawViews(g_hillAdjustPanel.m_ip->GetTime(),REDRAW_BEGIN); g_hillAdjustPanel.m_ip->RedrawViews(g_hillAdjustPanel.m_ip->GetTime(),REDRAW_NORMAL); g_hillAdjustPanel.m_ip->RedrawViews(g_hillAdjustPanel.m_ip->GetTime(),REDRAW_END); theHold.SuperAccept("HillAdjust"); char szNewName[MAX_PATH]; sprintf(szNewName,"%s\\%s%c",g_szDestPath,name,g_szDir[g_hillAdjustPanel.m_angleEnum][0]); if (0xFFFFFFFF == GetFileAttributes(szNewName)) { // File already exists CFileDialog fd(FALSE,NULL,NULL,0,"Max Files (*.max)|*.max||",CWnd::FromHandle(g_hillAdjustPanel.m_hPanel)); char *filebuf = new char[MAX_PATH*200]; filebuf[0] = 0; fd.m_ofn.lpstrFile = filebuf; fd.m_ofn.nMaxFile = MAX_PATH*200; if (fd.DoModal()==IDOK) { g_hillAdjustPanel.m_ip->SaveToFile(fd.GetPathName()); } break; } else { g_hillAdjustPanel.m_ip->SaveToFile(szNewName); } break; } case WM_INITDIALOG: //Panel's extra initialization g_hillAdjustPanel.Init(hWnd); break; case WM_DESTROY: //Panel's extra destruction g_hillAdjustPanel.Destroy(hWnd); break; /* case WM_CTLCOLOREDIT: { HDC hDC = (HDC)wParam; HWND hWndEdit = (HWND)lParam; POSITION pos = g_mapCtlData.GetStartPosition(); CCtlData *pData; WORD key; BOOL bFound = false; /*while (pos) { CObject *pObj; g_mapCtlData.GetNextAssoc(pos,key,pObj); pData = (CCtlData *)pObj; //if (pSpinner == pData->GetSpinner()) int id = GetWindowLong(hWndEdit,GWL_ID); if (pData && (pData->GetIdEdit() == id)) { bFound = true; break; } } if (bFound) { } *//* char sz[MAX_PATH],sz1[MAX_PATH]; GetWindowText(hWndEdit,sz,MAX_PATH); GetWindowText(hWnd,sz1,MAX_PATH); static int x = 0; x++; static int y = 2; if (x==y) int z=1; return DefWindowProc(hWnd,msg,wParam,lParam); return (int)GetLTGrayBrush(); } */ case WM_COMMAND : { switch (LOWORD(wParam)) { //Handle Panel's controls case IDC_ABOUT: { CAbout dlg; dlg.DoModal(); break; } case IDC_LEAVE_TANG: { g_hillAdjustPanel.m_leaveOriginalTangents = !g_hillAdjustPanel.m_leaveOriginalTangents; break; } case IDC_LEAVE_CURVE: { g_hillAdjustPanel.m_leaveOriginalCurves = !g_hillAdjustPanel.m_leaveOriginalCurves; break; } case IDC_HILL_ADJUST: { if (g_bHold) g_hillAdjustPanel.m_ip->FileFetch(); theHold.SuperBegin(); g_hillAdjustPanel.AdjustToHill(); g_hillAdjustPanel.m_ip->RedrawViews(g_hillAdjustPanel.m_ip->GetTime(),REDRAW_BEGIN); g_hillAdjustPanel.m_ip->RedrawViews(g_hillAdjustPanel.m_ip->GetTime(),REDRAW_NORMAL); g_hillAdjustPanel.m_ip->RedrawViews(g_hillAdjustPanel.m_ip->GetTime(),REDRAW_END); theHold.SuperAccept("HillAdjust"); break; } case IDC_HILL_HOLD: { switch (HIWORD(wParam)) { case BN_CLICKED: { g_bHold = true; g_hillAdjustPanel.m_ip->FileHold(); /*g_bHold = 1-g_bHold; if (!g_bHold) { g_bHold = false; g_hillAdjustPanel.m_ip->FileFetch(); } else { g_bHold = true; g_hillAdjustPanel.m_ip->FileHold(); } SetDlgItemText(hWnd,IDC_HILL_HOLD,g_bHold?"Fetch Saved":"Hold Current State"); //SendMessage(hWnd,BM_SETSTATE,g_bHold?BST_PUSHED:0,0);*/ break; } case BN_PUSHED: { int x=1; break; } } break; } case IDC_HILL_FETCH: { switch (HIWORD(wParam)) { case BN_CLICKED: { g_bHold = false; g_hillAdjustPanel.m_ip->FileFetch(); break; } } break; } case IDC_COMBO_DIRECTION: { switch (HIWORD(wParam)) { case CBN_SELENDOK: { g_hillAdjustPanel.SaveValues(); int sel = SendDlgItemMessage(hWnd,IDC_COMBO_DIRECTION,CB_GETCURSEL,0,0); g_hillAdjustPanel.m_angleEnum = SendDlgItemMessage(hWnd,IDC_COMBO_DIRECTION,CB_GETITEMDATA,sel,0); ReleaseISpinner(g_hillAdjustPanel.m_angleSpinner); ReleaseISpinner(g_hillAdjustPanel.m_rootScalePosXControl); ReleaseISpinner(g_hillAdjustPanel.m_rootScalePosYControl); ReleaseISpinner(g_hillAdjustPanel.m_rootScalePosZControl); ReleaseISpinner(g_hillAdjustPanel.m_rootScaleRotXControl); ReleaseISpinner(g_hillAdjustPanel.m_rootScaleRotYControl); ReleaseISpinner(g_hillAdjustPanel.m_rootScaleRotZControl); ReleaseISpinner(g_hillAdjustPanel.m_rootMovePosXControl); ReleaseISpinner(g_hillAdjustPanel.m_rootMovePosYControl); ReleaseISpinner(g_hillAdjustPanel.m_rootMovePosZControl); ReleaseISpinner(g_hillAdjustPanel.m_rootMoveRotXControl); ReleaseISpinner(g_hillAdjustPanel.m_rootMoveRotYControl); ReleaseISpinner(g_hillAdjustPanel.m_rootMoveRotZControl); ReleaseISpinner(g_hillAdjustPanel.m_hipScaleControl); ReleaseISpinner(g_hillAdjustPanel.m_hipMoveControl); ReleaseISpinner(g_hillAdjustPanel.m_torsoScaleXControl); ReleaseISpinner(g_hillAdjustPanel.m_torsoScaleYControl); ReleaseISpinner(g_hillAdjustPanel.m_torsoScaleZControl); ReleaseISpinner(g_hillAdjustPanel.m_leftFootScaleCloseControl); ReleaseISpinner(g_hillAdjustPanel.m_rightFootScaleCloseControl); g_hillAdjustPanel.LoadValues(hWnd); } } break; } // Case COMBO DIRECTION default: { CObject *pObj; if (g_mapCtlData.Lookup(LOWORD(wParam),pObj)) { CCtlData *pData = (CCtlData *)pObj; HWND hWindow = GetDlgItem(hWnd,pData->GetIdEdit()); //if (fabs(pData->GetDefault() - pData->GetSpinner()->GetFVal()) < 0.0001f) if (pData->IsEnabled()) { //SetDlgFont(hWindow,g_hMyFont); pData->Enable(false); //EnableWindow(hWindow,FALSE); //float oldval = pData->SaveValue(pData->GetSpinner()->GetFVal()); //pData->GetSpinner()->SetValue(oldval,TRUE); SetDlgFont(hWindow,GetFixedFont()); //pData->GetSpinner()->SetValue(pData->SaveValue(pData->GetDefault()),TRUE); float oldval = pData->GetSpinner()->GetFVal(); pData->GetSpinner()->SetValue(pData->GetDefault(),TRUE); pData->SaveValue(oldval); InvalidateRect(hWindow,NULL,false); // store old value // Set value to identity value } else { pData->Enable(true); //EnableWindow(hWindow,TRUE); //SetDlgFont(hWindow,GetFixedFont()); //pData->GetSpinner()->SetValue(pData->SaveValue(pData->GetDefault()),TRUE); SetDlgFont(hWindow,g_hMyFont); //float oldval = pData->SaveValue(pData->GetDefault()); float oldval = pData->SaveValue(pData->GetSpinner()->GetFVal()); pData->GetSpinner()->SetValue(oldval,TRUE); InvalidateRect(hWindow,NULL,false); // restore old value // set old value to identity } } break; } } //END switch LOPARAM() break; } // END case WM_COMMAND: case CC_SPINNER_CHANGE: { int ctrlID = LOWORD(wParam); //if (HIWORD(wParam)) { ISpinnerControl *pSpinner = (ISpinnerControl *)lParam; POSITION pos = g_mapCtlData.GetStartPosition(); CCtlData *pData; WORD key; BOOL bFound = false; while (pos) { CObject *pObj; g_mapCtlData.GetNextAssoc(pos,key,pObj); pData = (CCtlData *)pObj; //if (pSpinner == pData->GetSpinner()) if (pData && (pData->GetIdSpinner() == ctrlID)) { bFound = true; break; } } if (bFound) { HWND hWindow = GetDlgItem(hWnd,pData->GetIdEdit()); // if it is < 0.0001f it is close enuf to zero if ( fabs(pData->GetDefault() - pSpinner->GetFVal()) > 0.0001f) { //pData->Enable(false); //EnableWindow(hWindow,FALSE); pData->Enable(true); SetDlgFont(hWindow,g_hMyFont); float oldval = pData->SaveValue(pData->GetSpinner()->GetFVal()); //pData->GetSpinner()->SetValue(pData->GetDefault(),TRUE); InvalidateRect(hWindow,NULL,false); // store old value // Set value to identity value } else { //pData->Enable(true); pData->Enable(false); SetDlgFont(hWindow,GetFixedFont()); //EnableWindow(hWindow,TRUE); pData->SaveValue(pData->GetDefault()); InvalidateRect(hWindow,NULL,false); // restore old value // set old value to identity } } } // if the new spinner value is equal to the default then shade the edit window break; } //////////////////////////////////////////////////////////////////////// //The following lines are not necessary for MAX2 Plugins case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MOUSEMOVE: g_hillAdjustPanel.m_ip->RollupMouseMessage(hWnd, msg, wParam, lParam); break; //////////////////////////////////////////////////////////////////////// default: return FALSE; } return TRUE; } //////////////////////////////////////////////////////////////////////////////// // Display the Plugin's Panel void HillAdjustPanel::BeginEditParams(Interface* ip, IUtil* iu) { m_ip = ip; //Get the Plugin's Interface m_iu = iu; //Get the Utility Plugin's Interface //Display the plugin's Rollup Dialog AFX_MANAGE_STATE(AfxGetStaticModuleState()); HINSTANCE loc_hInstance = AfxGetResourceHandle (); g_hMyFont = CreateFont(15,0,0,0,FW_BOLD,0,0,0,ANSI_CHARSET,0,0,0, DEFAULT_PITCH | FF_SWISS, _T("")); m_hPanel = m_ip->AddRollupPage(loc_hInstance, MAKEINTRESOURCE(IDD_HILLADJUST_PANEL), HillAdjustPanelProc, GetString(IDS_HILLADJUST_NAME),0); m_hQuickFile = EnableQuickFile(m_ip,m_hPanel); } //////////////////////////////////////////////////////////////////////////////// // Free the Plugins' Panel void HillAdjustPanel::EndEditParams(Interface *ip, IUtil *iu) { DeleteObject(g_hMyFont); DisableQuickFile(m_ip, m_hQuickFile); m_iu = NULL; m_ip = NULL; //Remove the Rollup Dialog ip->DeleteRollupPage(m_hPanel); m_hPanel = NULL; } //////////////////////////////////////////////////////////////////////////////// // Panel Initialization callback void HillAdjustPanel::Init(HWND hWnd) { g_bHold = 0; //Initialize the direction combo box for (int x=0;x<4;x++) { int index = SendDlgItemMessage(hWnd,IDC_COMBO_DIRECTION,CB_ADDSTRING,0,(LPARAM)g_szDir[x]); SendDlgItemMessage(hWnd,IDC_COMBO_DIRECTION,CB_SETITEMDATA,index,x); } m_angleEnum = -1; LoadValues(hWnd); } //////////////////////////////////////////////////////////////////////////////// // Panel Destruction callback void HillAdjustPanel::Destroy(HWND hWnd) { SaveValues(); ReleaseISpinner(m_angleSpinner); ReleaseISpinner(m_rootScalePosXControl); ReleaseISpinner(m_rootScalePosYControl); ReleaseISpinner(m_rootScalePosZControl); ReleaseISpinner(m_rootScaleRotXControl); ReleaseISpinner(m_rootScaleRotYControl); ReleaseISpinner(m_rootScaleRotZControl); ReleaseISpinner(m_rootMovePosXControl); ReleaseISpinner(m_rootMovePosYControl); ReleaseISpinner(m_rootMovePosZControl); ReleaseISpinner(m_rootMoveRotXControl); ReleaseISpinner(m_rootMoveRotYControl); ReleaseISpinner(m_rootMoveRotZControl); ReleaseISpinner(m_hipScaleControl); ReleaseISpinner(m_hipMoveControl); ReleaseISpinner(m_torsoScaleXControl); ReleaseISpinner(m_torsoScaleYControl); ReleaseISpinner(m_torsoScaleZControl); ReleaseISpinner(m_leftFootScaleCloseControl); ReleaseISpinner(m_rightFootScaleCloseControl); } //////////////////////////////////////////////////////////////////////////////// // Called when the Pick Button is pushed void HillAdjustPanel::AdjustToHill() { // need to check that the model has all of the necessary nodes char szCheckNames[] = "joint_VEL handle_lfoot site_lfoot handle_rfoot site_rfoot"; char *str = strtok(szCheckNames," "); while (str) { if (NULL == m_ip->GetINodeByName(str)) { CString s; s.Format("%s node required. Hill Adjust tool cannot adjust loaded model.",str); MessageBox(NULL,s,"Hill Adjust",MB_OK |MB_ICONSTOP); return; } str = strtok(NULL," "); } AFX_MANAGE_STATE(AfxGetStaticModuleState()); HINSTANCE loc_hInstance = AfxGetResourceHandle (); // get the angle.. m_angleSlope = m_angleSpinner->GetFVal() * Stuff::Radians_Per_Degree; m_rootPosScale.x = m_rootScalePosXControl->GetFVal() / 100.0f; m_rootPosScale.y = m_rootScalePosYControl->GetFVal() / 100.0f; m_rootPosScale.z = m_rootScalePosZControl->GetFVal() / 100.0f; m_rootRotScale.x = m_rootScaleRotXControl->GetFVal() / 100.0f; m_rootRotScale.y = m_rootScaleRotYControl->GetFVal() / 100.0f; m_rootRotScale.z = m_rootScaleRotZControl->GetFVal() / 100.0f; m_rootPosMove.x = m_rootMovePosXControl->GetFVal(); m_rootPosMove.y = m_rootMovePosYControl->GetFVal(); m_rootPosMove.z = m_rootMovePosZControl->GetFVal(); m_rootRotMove.x = m_rootMoveRotXControl->GetFVal() * Stuff::Radians_Per_Degree; m_rootRotMove.y = m_rootMoveRotYControl->GetFVal() * Stuff::Radians_Per_Degree; m_rootRotMove.z = m_rootMoveRotZControl->GetFVal() * Stuff::Radians_Per_Degree; m_hipScale.x = m_hipScaleControl->GetFVal() / 100.0f; m_hipScale.y = NAN; m_hipScale.z = NAN; m_hipMove.x = m_hipMoveControl->GetFVal() * Stuff::Radians_Per_Degree; m_hipMove.y = NAN; m_hipMove.z = NAN; m_torsoScale.x = m_torsoScaleXControl->GetFVal() / 100.0f; m_torsoScale.y = m_torsoScaleYControl->GetFVal() / 100.0f; m_torsoScale.z = m_torsoScaleZControl->GetFVal() / 100.0f; m_leftFootPosScale.x = m_leftFootScaleCloseControl->GetFVal() / 100.0f; m_leftFootPosScale.y = NAN; m_leftFootPosScale.z = NAN; m_rightFootPosScale.x = m_rightFootScaleCloseControl->GetFVal() / 100.0f; m_rightFootPosScale.y = NAN; m_rightFootPosScale.z = NAN; // we have our angle and our up/down/left/right // we need to check the foot handles turn them into bezeir splines // INode *lfoot_node = FindNode(m_ip->GetRootNode(), "handle_lfoot"); // Check_Pointer(lfoot_node); // ConvertTM(lfoot_node->GetTMController()); // INode *rfoot_node = FindNode(m_ip->GetRootNode(), "handle_rfoot"); // Check_Pointer(rfoot_node); // ConvertTM(rfoot_node->GetTMController()); // lets rumble... switch (m_angleEnum) { case UpAngleType: AdjustGeneral(); AdjustUpHill(); break; case DownAngleType: AdjustGeneral(); AdjustDownHill(); break; case LeftAngleType: AdjustGeneral(); AdjustLeftHill(); break; case RightAngleType: AdjustGeneral(); AdjustRightHill(); break; } } //===========================================================================// void HillAdjustPanel::ConvertTM(Control *c) { Check_Pointer(c); Control *rotation_controler = c->GetRotationController(); Check_Pointer(rotation_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_rot_controler); Convert(rotation_controler, x_rot_controler, 0); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_rot_controler); Convert(rotation_controler, y_rot_controler, 1); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_rot_controler); Convert(rotation_controler, z_rot_controler, 2); Control *position_controler = c->GetPositionController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Convert(position_controler, x_controler, 0); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Convert(position_controler, y_controler, 1); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Convert(position_controler, z_controler, 2); } //===========================================================================// void HillAdjustPanel::Convert(Control *parent_c, Control *c, int location) { Check_Pointer(c); if(c->ClassID().PartA() == HYBRIDINTERP_FLOAT_CLASS_ID) { return; } theHold.Begin(); // replace controler pointer with new controller // if the type is known but the sub type isn't // then convert that controller. // Example is RotationXYZ with a sub controler of SineWave or Noise Control *new_controler = NULL; new_controler = (Control *)m_ip->CreateInstance( CTRL_FLOAT_CLASS_ID, Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0)); SuspendAnimate(); AnimateOn(); { Interval iv; int ticks_per_frame = GetTicksPerFrame(); int num_of_frames = 1; TimeValue start = m_ip->GetAnimRange().Start(); TimeValue end = m_ip->GetAnimRange().End(); int delta = GetTicksPerFrame(); for (int time_of_key=start; time_of_key<=end; time_of_key+=delta) { float value; c->GetValue(time_of_key,&value,FOREVER,CTRL_ABSOLUTE); new_controler->SetValue(time_of_key,&value,TRUE,CTRL_ABSOLUTE); } } ResumeAnimate(); theHold.Accept(0); new_controler->SetORT(ORT_BEFORE, ORT_LOOP); new_controler->SetORT(ORT_AFTER, ORT_LOOP); parent_c->AssignController(new_controler, location); return; } //===========================================================================// void HillAdjustPanel::SampleController(Control *parent_c, Control *c, int location) { Check_Pointer(c); theHold.Begin(); // replace controler pointer with new controller // if the type is known but the sub type isn't // then convert that controller. // Example is RotationXYZ with a sub controler of SineWave or Noise Control *new_controler = NULL; new_controler = (Control *)m_ip->CreateInstance( CTRL_FLOAT_CLASS_ID, Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0)); SuspendAnimate(); AnimateOn(); { Interval iv; int ticks_per_frame = GetTicksPerFrame(); int num_of_frames = 1; TimeValue start = m_ip->GetAnimRange().Start(); TimeValue end = m_ip->GetAnimRange().End(); int delta = GetTicksPerFrame(); for (int time_of_key=start; time_of_key<=end; time_of_key+=delta) { float value; c->GetValue(time_of_key,&value,FOREVER,CTRL_ABSOLUTE); new_controler->SetValue(time_of_key,&value,TRUE,CTRL_ABSOLUTE); } } ResumeAnimate(); theHold.Accept(0); new_controler->SetORT(ORT_BEFORE, ORT_LOOP); new_controler->SetORT(ORT_AFTER, ORT_LOOP); parent_c->AssignController(new_controler, location); return; } //===========================================================================// void HillAdjustPanel::AdjustGeneral(void) { INode *root_node = FindNode(m_ip->GetRootNode(), "joint_root"); Check_Pointer(root_node); INode *torso_node = FindNode(m_ip->GetRootNode(), "joint_torso"); Check_Pointer(torso_node); INode *hip_node = FindNode(m_ip->GetRootNode(), "joint_hip"); Check_Pointer(hip_node); INode *lfoot_node = FindNode(m_ip->GetRootNode(), "handle_lfoot"); Check_Pointer(lfoot_node); INode *rfoot_node = FindNode(m_ip->GetRootNode(), "handle_rfoot"); Check_Pointer(rfoot_node); ScaleNodePosition(root_node, m_rootPosScale); ScaleNodeRotation(root_node, m_rootRotScale); MoveNodePosition(root_node, m_rootPosMove); MoveNodeRotation(root_node, m_rootRotMove); ScaleNodeRotation(hip_node, m_hipScale); MoveNodeRotation(hip_node, m_hipMove); ScaleNodeRotation(torso_node, m_torsoScale); ScaleNodePosition(lfoot_node, m_leftFootPosScale); ScaleNodePosition(rfoot_node, m_rightFootPosScale); } //===========================================================================// void HillAdjustPanel::ScaleNodeAll(Control *c, float scale) { if (_isnan(scale)) return; IKeyControl *keys = GetKeyControlInterface(c); if (keys == NULL) { //SPEW(("jerryeds", "FUCKED UP")); ScaleKey(c, keys, scale,0.0, -1); return; } float min = 0.0,max = 0.0; for (int i = 0; i < keys->GetNumKeys(); ++i) { int time = GetKeyTime(c, keys, i); float value; c->GetValue(time,&value,FOREVER,CTRL_ABSOLUTE); if (value < min) min = value; if (value > max) max = value; } if (keys->GetNumKeys() > 0) { for (i = 0; i < keys->GetNumKeys(); ++i) { ScaleKey(c, keys, scale, min+(max-min)/2,i); } } else { ScaleKey(c, keys, scale, min+(max-min)/2,-1); } } //===========================================================================// void HillAdjustPanel::MoveNodeAll(Control *c, float scale) { if (_isnan(scale)) return; IKeyControl *keys = GetKeyControlInterface(c); if (keys == NULL) { //SPEW(("jerryeds", "FUCKED UP")); MoveKey(c, keys, scale, -1); return; } if (keys->GetNumKeys() > 0) { for (int i = 0; i < keys->GetNumKeys(); ++i) { MoveKey(c, keys, scale, i); } } else { MoveKey(c, keys, scale, -1); } } //===========================================================================// void HillAdjustPanel::ScaleNodePosition(INode *node, Stuff::Point3D scale) { Control *tm_control = node->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); ScaleNodeAll(x_controler, scale.x); ScaleNodeAll(y_controler, scale.y); ScaleNodeAll(z_controler, scale.z); } //===========================================================================// void HillAdjustPanel::ScaleNodeRotation(INode *node, Stuff::Point3D scale) { Control *tm_control = node->GetTMController(); Check_Pointer(tm_control); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(rotation_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_rot_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_rot_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_rot_controler); ScaleNodeAll(x_rot_controler, scale.x); ScaleNodeAll(y_rot_controler, scale.y); ScaleNodeAll(z_rot_controler, scale.z); } //===========================================================================// void HillAdjustPanel::MoveNodePosition(INode *node, Stuff::Point3D scale) { Control *tm_control = node->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); MoveNodeAll(x_controler, scale.x); MoveNodeAll(y_controler, scale.y); MoveNodeAll(z_controler, scale.z); } //===========================================================================// void HillAdjustPanel::MoveNodeRotation(INode *node, Stuff::Point3D scale) { Control *tm_control = node->GetTMController(); Check_Pointer(tm_control); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(rotation_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_rot_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_rot_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_rot_controler); MoveNodeAll(x_rot_controler, scale.x); MoveNodeAll(y_rot_controler, scale.y); MoveNodeAll(z_rot_controler, scale.z); } //===========================================================================// void HillAdjustPanel::AdjustUpHill(void) { //SPEW(("jerryeds", "%f %f", m_angleSlope, 45.0f*Stuff::Radians_Per_Degree)); INode *root_node = FindNode(m_ip->GetRootNode(), "joint_VEL"); Check_Pointer(root_node); INode *left_foot_handle = FindNode(m_ip->GetRootNode(), "handle_lfoot"); Check_Pointer(left_foot_handle); { Control *tm_control = left_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); if (z_keys != NULL) { Stuff::Scalar *y_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(y_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { // Get the pos and rot from the frame. int time_of_key = GetKeyTime(z_controler, z_keys, i); AffineParts vel_world; decomp_affine(root_node->GetNodeTM(time_of_key), &vel_world); AffineParts foot_world; decomp_affine(left_foot_handle->GetNodeTM(time_of_key), &foot_world); y_position_table[i] = vel_world.t.y - foot_world.t.y; } Stuff::Scalar *height_table; height_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(height_table); for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = (Stuff::Scalar)tan(m_angleSlope) * y_position_table[i]; if (i > 0) { height_table[i] = height - height_table[i-1]; } else { height_table[0] = height; } //SPEW(("jerryeds", "height : %f", height_table[i])); MoveKey(z_controler, z_keys, height, i); } Unregister_Pointer(y_position_table); delete y_position_table; // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_lfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); //parentTM = left_foot_handle->GetNodeTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; //SPEW(("jerryeds", "foot_length %f", foot_length)); float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); left_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE); if (!m_leaveOriginalTangents) { for (int i = 1; i < z_keys->GetNumKeys()-1; ++i) { RotateTangents(z_controler, z_keys, height_table[i], i); } } Unregister_Pointer(height_table); delete height_table; } // turn the feet to match the ground IKeyControl *x_rot_keys = GetKeyControlInterface(x_rot_controler); if (x_rot_keys != NULL) { if (x_rot_keys->GetNumKeys() > 0) { for (int i = 0; i < x_rot_keys->GetNumKeys(); ++i) { MoveKey(x_rot_controler, x_rot_keys, -45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(x_rot_controler, x_rot_keys, -45.0f*Stuff::Radians_Per_Degree, -1); } } } INode *right_foot_handle = FindNode(m_ip->GetRootNode(), "handle_rfoot"); Check_Pointer(right_foot_handle); { Control *tm_control = right_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); if (!m_leaveOriginalCurves) { //sample the z_controller SampleController(position_controler, z_controler, 2); z_controler = position_controler->GetZController(); } // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); Stuff::Scalar *y_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(y_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { int time_of_key = GetKeyTime(z_controler, z_keys, i); AffineParts vel_world; decomp_affine(root_node->GetNodeTM(time_of_key), &vel_world); AffineParts foot_world; decomp_affine(right_foot_handle->GetNodeTM(time_of_key), &foot_world); y_position_table[i] = vel_world.t.y - foot_world.t.y; } Stuff::Scalar *height_table; height_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(height_table); for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = (Stuff::Scalar)tan(m_angleSlope) * y_position_table[i]; if (i > 0) { height_table[i] = height - height_table[i-1]; } else { height_table[0] = height; } //SPEW(("jerryeds", "height : %f", height_table[i])); MoveKey(z_controler, z_keys, height, i); } Unregister_Pointer(y_position_table); delete y_position_table; IKeyControl *x_rot_keys = GetKeyControlInterface(x_rot_controler); if (x_rot_keys->GetNumKeys() > 0) { for (i = 0; i < x_rot_keys->GetNumKeys(); ++i) { MoveKey(x_rot_controler, x_rot_keys, -45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(x_rot_controler, x_rot_keys, -45.0f*Stuff::Radians_Per_Degree, -1); } // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_rfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); right_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE); if (!m_leaveOriginalTangents) { for (i = 1; i < z_keys->GetNumKeys()-1; ++i) { RotateTangents(z_controler, z_keys, height_table[i], i); } } Unregister_Pointer(height_table); delete height_table; } } //===========================================================================// void HillAdjustPanel::AdjustDownHill(void) { INode *root_node = FindNode(m_ip->GetRootNode(), "joint_VEL"); Check_Pointer(root_node); INode *left_foot_handle = FindNode(m_ip->GetRootNode(), "handle_lfoot"); Check_Pointer(left_foot_handle); { Control *tm_control = left_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); if (z_keys != NULL) { Stuff::Scalar *y_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(y_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { // Get the pos and rot from the frame. int time_of_key = GetKeyTime(z_controler, z_keys, i); AffineParts vel_world; decomp_affine(root_node->GetNodeTM(time_of_key), &vel_world); AffineParts foot_world; decomp_affine(left_foot_handle->GetNodeTM(time_of_key), &foot_world); y_position_table[i] = vel_world.t.y - foot_world.t.y; } Stuff::Scalar *height_table; height_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(height_table); for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = -(Stuff::Scalar)tan(m_angleSlope) * y_position_table[i]; if (i > 0) { height_table[i] = height - height_table[i-1]; } else { height_table[0] = height; } //SPEW(("jerryeds", "height : %f", height_table[i])); MoveKey(z_controler, z_keys, height, i); } // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_lfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); //parentTM = left_foot_handle->GetNodeTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); left_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE); if (!m_leaveOriginalTangents) { for (i = 1; i < z_keys->GetNumKeys()-1; ++i) { RotateTangents(z_controler, z_keys, height_table[i], i); } } Unregister_Pointer(height_table); delete height_table; Unregister_Pointer(y_position_table); delete y_position_table; } IKeyControl *x_rot_keys = GetKeyControlInterface(x_rot_controler); if (x_rot_keys != NULL) { if (x_rot_keys->GetNumKeys() > 0) { for (int i = 0; i < x_rot_keys->GetNumKeys(); ++i) { MoveKey(x_rot_controler, x_rot_keys, 45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(x_rot_controler, x_rot_keys, 45.0f*Stuff::Radians_Per_Degree, -1); } } } INode *right_foot_handle = FindNode(m_ip->GetRootNode(), "handle_rfoot"); Check_Pointer(right_foot_handle); { Control *tm_control = right_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); if (!m_leaveOriginalCurves) { //sample the z_controller SampleController(position_controler, z_controler, 2); z_controler = position_controler->GetZController(); } // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); Stuff::Scalar *y_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(y_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { // Get the pos and rot from the frame. int time_of_key = GetKeyTime(z_controler, z_keys, i); AffineParts vel_world; decomp_affine(root_node->GetNodeTM(time_of_key), &vel_world); AffineParts foot_world; decomp_affine(right_foot_handle->GetNodeTM(time_of_key), &foot_world); y_position_table[i] = vel_world.t.y - foot_world.t.y; } Stuff::Scalar *height_table; height_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(height_table); for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = -(Stuff::Scalar)tan(m_angleSlope) * y_position_table[i]; if (i > 0) { height_table[i] = height - height_table[i-1]; } else { height_table[0] = height; } //SPEW(("jerryeds", "height : %f", height_table[i])); MoveKey(z_controler, z_keys, height, i); } Unregister_Pointer(y_position_table); delete y_position_table; IKeyControl *x_rot_keys = GetKeyControlInterface(x_rot_controler); if (x_rot_keys->GetNumKeys() > 0) { for (i = 0; i < x_rot_keys->GetNumKeys(); ++i) { MoveKey(x_rot_controler, x_rot_keys, 45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(x_rot_controler, x_rot_keys, 45.0f*Stuff::Radians_Per_Degree, -1); } // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_rfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); //parentTM = left_foot_handle->GetNodeTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); right_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE); if (!m_leaveOriginalTangents) { for (i = 1; i < z_keys->GetNumKeys()-1; ++i) { RotateTangents(z_controler, z_keys, height_table[i], i); } } Unregister_Pointer(height_table); delete height_table; } } //===========================================================================// void HillAdjustPanel::AdjustLeftHill(void) { INode *left_foot_handle = FindNode(m_ip->GetRootNode(), "handle_lfoot"); Check_Pointer(left_foot_handle); { //SPEW(("jerryeds", "LEFT")); Control *tm_control = left_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); Convert(position_controler, z_controler, 2); z_controler = position_controler->GetZController(); Convert(rotation_controler, y_rot_controler, 1); y_rot_controler = rotation_controler->GetYController(); // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); Stuff::Scalar *x_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(x_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { Quat rot; Point3 pos; // Get the pos and rot from the frame. int time_of_key = GetKeyTime(z_controler, z_keys, i); // Compute the relative TM Matrix3 parentTM, nodeTM, localTM; nodeTM = left_foot_handle->GetNodeTM(time_of_key); parentTM = left_foot_handle->GetParentTM(time_of_key); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); x_position_table[i] = ap.t.x; } for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = (Stuff::Scalar)tan(m_angleSlope) * x_position_table[i]; //SPEW(("jerryeds", "l:%f", height)); MoveKey(z_controler, z_keys, height, i); } Unregister_Pointer(x_position_table); delete x_position_table; IKeyControl *y_rot_keys = GetKeyControlInterface(y_rot_controler); if (y_rot_keys->GetNumKeys() > 0) { for (i = 0; i < y_rot_keys->GetNumKeys(); ++i) { MoveKey(y_rot_controler, y_rot_keys, -45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(y_rot_controler, y_rot_keys, -45.0f*Stuff::Radians_Per_Degree, -1); } // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_lfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); //parentTM = left_foot_handle->GetNodeTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; //SPEW(("jerryeds", "foot_length %f", foot_length)); float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); left_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE, TRUE); } INode *right_foot_handle = FindNode(m_ip->GetRootNode(), "handle_rfoot"); Check_Pointer(right_foot_handle); { //SPEW(("jerryeds", "RIGHT")); Control *tm_control = right_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); Convert(position_controler, z_controler, 2); z_controler = position_controler->GetZController(); Convert(rotation_controler, y_rot_controler, 1); y_rot_controler = rotation_controler->GetYController(); // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); Stuff::Scalar *x_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(x_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { Quat rot; Point3 pos; // Get the pos and rot from the frame. int time_of_key = GetKeyTime(z_controler, z_keys, i); // Compute the relative TM Matrix3 parentTM, nodeTM, localTM; nodeTM = right_foot_handle->GetNodeTM(time_of_key); parentTM = right_foot_handle->GetParentTM(time_of_key); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); x_position_table[i] = ap.t.x; } for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = (Stuff::Scalar)tan(m_angleSlope) * x_position_table[i]; //SPEW(("jerryeds", "r:%f", height)); MoveKey(z_controler, z_keys, height, i); } Unregister_Pointer(x_position_table); delete x_position_table; IKeyControl *y_rot_keys = GetKeyControlInterface(y_rot_controler); if (y_rot_keys->GetNumKeys() > 0) { for (i = 0; i < y_rot_keys->GetNumKeys(); ++i) { MoveKey(y_rot_controler, y_rot_keys, -45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(y_rot_controler, y_rot_keys, -45.0f*Stuff::Radians_Per_Degree, -1); } // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_rfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); //parentTM = left_foot_handle->GetNodeTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; //SPEW(("jerryeds", "foot_length %f", foot_length)); float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); right_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE, TRUE); } } //===========================================================================// void HillAdjustPanel::AdjustRightHill(void) { INode *left_foot_handle = FindNode(m_ip->GetRootNode(), "handle_lfoot"); Check_Pointer(left_foot_handle); { Control *tm_control = left_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); Convert(position_controler, z_controler, 2); z_controler = position_controler->GetZController(); Convert(rotation_controler, y_rot_controler, 1); y_rot_controler = rotation_controler->GetYController(); // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); Stuff::Scalar *x_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(x_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { Quat rot; Point3 pos; // Get the pos and rot from the frame. int time_of_key = GetKeyTime(z_controler, z_keys, i); // Compute the relative TM Matrix3 parentTM, nodeTM, localTM; nodeTM = left_foot_handle->GetNodeTM(time_of_key); parentTM = left_foot_handle->GetParentTM(time_of_key); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); x_position_table[i] = ap.t.x; } for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = (Stuff::Scalar)tan(m_angleSlope) * x_position_table[i]; //SPEW(("jerryeds", "l:%f", height)); MoveKey(z_controler, z_keys, -height, i); } Unregister_Pointer(x_position_table); delete x_position_table; IKeyControl *y_rot_keys = GetKeyControlInterface(y_rot_controler); if (y_rot_keys->GetNumKeys() > 0) { for (i = 0; i < y_rot_keys->GetNumKeys(); ++i) { MoveKey(y_rot_controler, y_rot_keys, 45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(y_rot_controler, y_rot_keys, 45.0f*Stuff::Radians_Per_Degree, -1); } // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_lfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); //parentTM = left_foot_handle->GetNodeTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; //SPEW(("jerryeds", "foot_length %f", foot_length)); float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); left_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE); } INode *right_foot_handle = FindNode(m_ip->GetRootNode(), "handle_rfoot"); Check_Pointer(right_foot_handle); { Control *tm_control = right_foot_handle->GetTMController(); Check_Pointer(tm_control); Control *position_controler = tm_control->GetPositionController(); Check_Pointer(position_controler); Control *rotation_controler = tm_control->GetRotationController(); Check_Pointer(position_controler); Control *x_controler = position_controler->GetXController(); Check_Pointer(x_controler); Control *y_controler = position_controler->GetYController(); Check_Pointer(y_controler); Control *z_controler = position_controler->GetZController(); Check_Pointer(z_controler); Control *x_rot_controler = rotation_controler->GetXController(); Check_Pointer(x_controler); Control *y_rot_controler = rotation_controler->GetYController(); Check_Pointer(y_controler); Control *z_rot_controler = rotation_controler->GetZController(); Check_Pointer(z_controler); Convert(position_controler, z_controler, 2); z_controler = position_controler->GetZController(); Convert(rotation_controler, y_rot_controler, 1); y_rot_controler = rotation_controler->GetYController(); // adjust keyframe to go up in z the correct amount of degrees... IKeyControl *z_keys = GetKeyControlInterface(z_controler); Stuff::Scalar *x_position_table = new Stuff::Scalar[z_keys->GetNumKeys()]; Register_Pointer(x_position_table); for (int i = 0; i < z_keys->GetNumKeys(); ++i) { Quat rot; Point3 pos; // Get the pos and rot from the frame. int time_of_key = GetKeyTime(z_controler, z_keys, i); // Compute the relative TM Matrix3 parentTM, nodeTM, localTM; nodeTM = right_foot_handle->GetNodeTM(time_of_key); parentTM = right_foot_handle->GetParentTM(time_of_key); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); x_position_table[i] = ap.t.x; } for (i = 0; i < z_keys->GetNumKeys(); ++i) { Stuff::Scalar height = (Stuff::Scalar)tan(m_angleSlope) * x_position_table[i]; //SPEW(("jerryeds", "r:%f", height)); MoveKey(z_controler, z_keys, -height, i); } Unregister_Pointer(x_position_table); delete x_position_table; IKeyControl *y_rot_keys = GetKeyControlInterface(y_rot_controler); if (y_rot_keys->GetNumKeys() > 0) { for (i = 0; i < y_rot_keys->GetNumKeys(); ++i) { MoveKey(y_rot_controler, y_rot_keys, 45.0f*Stuff::Radians_Per_Degree, i); } } else { MoveKey(y_rot_controler, y_rot_keys, 45.0f*Stuff::Radians_Per_Degree, -1); } // push out the handle just a little more to match the ground... INode *foot_site = FindNode(m_ip->GetRootNode(), "site_rfoot"); Check_Pointer(foot_site); // calculate the length of the foot.. Matrix3 parentTM, nodeTM, localTM; nodeTM = foot_site->GetNodeTM(m_ip->GetAnimRange().Start()); parentTM = foot_site->GetParentTM(m_ip->GetAnimRange().Start()); //parentTM = left_foot_handle->GetNodeTM(m_ip->GetAnimRange().Start()); localTM = nodeTM*Inverse(parentTM); AffineParts ap; decomp_affine(localTM, &ap); float foot_length = -ap.t.z; float ground_adjustment; { // // A // |\ // | \ // b| \c // | \ // C|____\B // a // // calculate the foot penetration float b,c,A,B; c = foot_length; B = m_angleSlope; A = (90.0f * Stuff::Radians_Per_Degree ) - B; b = Cos(A) * c; ground_adjustment = foot_length - b; } { float a,c,B; a = ground_adjustment; B = m_angleSlope; c = a / Cos(B); ground_adjustment = c; } // solve the second triangle... //SPEW(("jerryeds", "new_length %f", b)); SPEW(("jerryeds", "ground_adjustment %f", ground_adjustment)); // push the handle out from the normal of the ground... Matrix3 axis(MAT_IDENT); Point3 translate(0.0f, 0.0f, ground_adjustment); right_foot_handle->Move(0, axis, translate, FALSE, TRUE, PIV_NONE); } } //===========================================================================// void HillAdjustPanel::MoveKey(Control *c, IKeyControl *ikeys, Stuff::Scalar amount, int key_number) { if (key_number == -1) { SuspendAnimate(); AnimateOn(); float old_amount; c->GetValue(m_ip->GetAnimRange().Start(),&old_amount,FOREVER,CTRL_ABSOLUTE); amount += old_amount; c->SetValue(m_ip->GetAnimRange().Start(),&amount,TRUE,CTRL_ABSOLUTE); ResumeAnimate(); theHold.Accept(0); return; } { SuspendAnimate(); AnimateOn(); int time = GetKeyTime(c, ikeys, key_number); float old_amount; c->GetValue(time,&old_amount,FOREVER,CTRL_ABSOLUTE); amount += old_amount; c->SetValue(time,&amount,TRUE,CTRL_ABSOLUTE); ResumeAnimate(); theHold.Accept(0); return; } } //===========================================================================// void HillAdjustPanel::ScaleKey(Control *c, IKeyControl *ikeys, Stuff::Scalar amount, float median,int key_number) { if (key_number == -1) { SuspendAnimate(); AnimateOn(); float old_amount; c->GetValue(m_ip->GetAnimRange().Start(),&old_amount,FOREVER,CTRL_ABSOLUTE); // amount *= old_amount; amount = ((old_amount-median)*amount)+median; c->SetValue(m_ip->GetAnimRange().Start(),&amount,TRUE,CTRL_ABSOLUTE); ResumeAnimate(); theHold.Accept(0); return; } { SuspendAnimate(); AnimateOn(); int time = GetKeyTime(c, ikeys, key_number); float old_amount; c->GetValue(time,&old_amount,FOREVER,CTRL_ABSOLUTE); //amount *= old_amount; amount = ((old_amount-median)*amount)+median; c->SetValue(time,&amount,TRUE,CTRL_ABSOLUTE); ResumeAnimate(); theHold.Accept(0); return; } } //===========================================================================// #if 0 void HillAdjustPanel::RotateTangents(Control *c, IKeyControl *ikeys, Stuff::Scalar amount, int key_number) { //SPEW(("jerryeds", "adjust tangent by %f", amount)); if (key_number == -1) { return; } if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { return; } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { return; } else if(c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { IBezFloatKey key; ikeys->GetKey(key_number, &key); if (GetOutTanType(key.flags) == BEZKEY_USER && key_number < ikeys->GetNumKeys()-1) { int int_key_time_dif = GetKeyTime(c, ikeys, key_number) - GetKeyTime(c, ikeys, key_number + 1); int frame_diff = int_key_time_dif/3; Stuff::Scalar new_outtan = (key.outtan * frame_diff); Stuff::Scalar angle = 0.0f; Stuff::Scalar a = new_outtan; Stuff::Scalar b = TicksToSec(frame_diff)*GetFrameRate(); angle = Stuff::Arctan(a,b); // tan(A) = a/b a = Stuff::Tan(angle + amount) * b; key.outtan = a / frame_diff; //SPEW(("jerryeds", "intan old : new %f : %f", angle * Stuff::Degrees_Per_Radian, (angle+amount) * Stuff::Degrees_Per_Radian)); } if (GetInTanType(key.flags) == BEZKEY_USER && key_number > 0) { int int_key_time_dif = GetKeyTime(c, ikeys, key_number) - GetKeyTime(c, ikeys, key_number - 1); int frame_diff = int_key_time_dif/3; Stuff::Scalar new_intan = (key.intan * frame_diff); Stuff::Scalar angle = 0.0f; Stuff::Scalar a = new_intan; Stuff::Scalar b = TicksToSec(frame_diff)*GetFrameRate(); angle = Stuff::Arctan(a,b); a = Stuff::Tan(angle - amount) * b; key.intan = a / frame_diff; //SPEW(("jerryeds", "outtan old : new %f : %f", angle * Stuff::Degrees_Per_Radian, angle-amount * Stuff::Degrees_Per_Radian)); } ikeys->SetKey(key_number, &key); } } #endif void HillAdjustPanel::RotateTangents(Control *c, IKeyControl *ikeys, Stuff::Scalar height, int key_number) { //SPEW(("jerryeds", "adjust tangent by %f", amount)); if (key_number == -1) { return; } if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { return; } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { return; } else if(c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { if (key_number > 0) { IBezFloatKey last_key; IBezFloatKey now_key; ikeys->GetKey(key_number, &now_key); ikeys->GetKey(key_number-1, &last_key); float angle_of_adjustment; float time_diff = TicksToSec(now_key.time - last_key.time)*GetFrameRate(); angle_of_adjustment = Stuff::Arctan(height, time_diff); if (GetInTanType(now_key.flags) == BEZKEY_USER) { //SPEW(("jerryeds", "in angle %f", -angle_of_adjustment*Stuff::Degrees_Per_Radian)); int int_key_time_dif = now_key.time - last_key.time; int frame_diff = int_key_time_dif/3; Stuff::Scalar new_intan = (now_key.intan * frame_diff); Stuff::Scalar a = new_intan; Stuff::Scalar b = TicksToSec(frame_diff)*GetFrameRate(); Stuff::Scalar angle = Stuff::Arctan(a,b); // tan(A) = a/b a = Stuff::Tan(angle - angle_of_adjustment) * b; now_key.intan = a / frame_diff; ikeys->SetKey(key_number, &now_key); } if (GetOutTanType(last_key.flags) == BEZKEY_USER) { //SPEW(("jerryeds", "out angle %f", angle_of_adjustment*Stuff::Degrees_Per_Radian)); int int_key_time_dif = now_key.time - last_key.time; int frame_diff = int_key_time_dif/3; Stuff::Scalar new_outtan = (last_key.outtan * frame_diff); Stuff::Scalar a = new_outtan; Stuff::Scalar b = TicksToSec(frame_diff)*GetFrameRate(); Stuff::Scalar angle = Stuff::Arctan(a,b); // tan(A) = a/b a = Stuff::Tan(angle + angle_of_adjustment) * b; last_key.outtan = a / frame_diff; ikeys->SetKey(key_number-1, &last_key); } } } } //===========================================================================// Stuff::Scalar HillAdjustPanel::GetKeyValue(Control *c, IKeyControl *ikeys, int key_number) { Stuff::Scalar value = 0.0f; if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { ILinFloatKey key; ikeys->GetKey(key_number, &key); value = key.val; } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { ITCBFloatKey key; ikeys->GetKey(key_number, &key); value = key.val; } else if(c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { IBezFloatKey key; ikeys->GetKey(key_number, &key); value = key.val; } return value; } //===========================================================================// int HillAdjustPanel::GetKeyTime(Control *c, IKeyControl *ikeys, int key_number) { int value = 0; if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { ILinFloatKey key; ikeys->GetKey(key_number, &key); value = key.time; } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { ITCBFloatKey key; ikeys->GetKey(key_number, &key); value = key.time; } else if(c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { IBezFloatKey key; ikeys->GetKey(key_number, &key); value = key.time; } return value; } //===========================================================================// INode* HillAdjustPanel::FindNode(INode* node, const char *name_of_joint) { if (!_stricmp(node->GetName(), name_of_joint)) { return node; } for (int c = 0; c < node->NumberOfChildren(); c++) { INode *new_node = FindNode(node->GetChildNode(c), name_of_joint); if (new_node != NULL) { return new_node; } } return NULL; } void HillAdjustPanel::LoadValues(HWND hWnd) { DWORD wType = REG_SZ; char szValue[100]; BYTE *pData = (BYTE *)szValue; char keybase[100] = "SOFTWARE\\Autodesk\\3D Studio MAX"; HKEY hMax; if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,keybase,&hMax)) // 3dStudio is not installed?? return; char szKey[50] = "Plugins\\HillAdjust"; HKEY hKey; if (ERROR_SUCCESS != RegCreateKey(hMax,szKey,&hKey)) return; DWORD size = 10; char szLast[10]; int i=0; BOOL bReset = FALSE; if (-1 == m_angleEnum) { if (ERROR_SUCCESS != RegQueryValueEx(hKey,"Last",0,&wType,(BYTE *)szLast,&size)) { m_angleEnum = 0; strcpy(szLast,g_szDir[m_angleEnum]); } else for (i=0;(i<4)&&(strcmp(g_szDir[i],szLast));i++); if (-1 == m_angleEnum) { m_angleEnum = i; SendDlgItemMessage(hWnd,IDC_COMBO_DIRECTION,CB_SETCURSEL,i,0); } size = 20; char szVersion[20]; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"Version",0,&wType,(BYTE *)szVersion,&size)) { bReset = TRUE; } } else strcpy(szLast,g_szDir[m_angleEnum]); RegCloseKey(hKey); strcat(szKey,"\\"); strcat(szKey,szLast); if (ERROR_SUCCESS != RegCreateKey(hMax,szKey,&hKey)) return; /* char szKey[20]; sprintf(szKey,"Plugins\\HillAdjust\\%s",g_szDir[m_angleEnum]); HKEY hKey; if (ERROR_SUCCESS != RegCreateKey(hMax,szKey,&hKey)) // error creating key return; */ float fValue; size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"angle",0,&wType,pData,&size)) strcpy(szValue,"45.0f"); sscanf(szValue,"%f",&fValue); m_angleSpinner = SetupFloatSpinner(hWnd, IDC_SPIN_ANGLE, IDC_EDIT_ANGLE, 0.0f, 90.0f, fValue, 1.0f); // Load the control values //////////////////// m_rootScalePosXControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_ROOT_POS_X,IDC_SPIN_SCALE_ROOT_POS_X,IDC_EDIT_SCALE_ROOT_POS_X,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); m_rootScalePosYControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_ROOT_POS_Y,IDC_SPIN_SCALE_ROOT_POS_Y,IDC_EDIT_SCALE_ROOT_POS_Y,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); m_rootScalePosZControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_ROOT_POS_Z,IDC_SPIN_SCALE_ROOT_POS_Z,IDC_EDIT_SCALE_ROOT_POS_Z,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); //////////////////// m_rootScaleRotXControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_ROOT_ROT_X,IDC_SPIN_SCALE_ROOT_ROT_X,IDC_EDIT_SCALE_ROOT_ROT_X,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); m_rootScaleRotYControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_ROOT_ROT_Y,IDC_SPIN_SCALE_ROOT_ROT_Y,IDC_EDIT_SCALE_ROOT_ROT_Y,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); m_rootScaleRotZControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_ROOT_ROT_Z,IDC_SPIN_SCALE_ROOT_ROT_Z,IDC_EDIT_SCALE_ROOT_ROT_Z,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); //////////////////// m_rootMovePosXControl = (new CCtlData(hWnd,hKey,IDC_CHECK_MOVE_ROOT_POS_X,IDC_SPIN_MOVE_ROOT_POS_X,IDC_EDIT_MOVE_ROOT_POS_X,-50.0f,50.0f,0.1f,0.0f))->GetSpinner(); m_rootMovePosYControl = (new CCtlData(hWnd,hKey,IDC_CHECK_MOVE_ROOT_POS_Y,IDC_SPIN_MOVE_ROOT_POS_Y,IDC_EDIT_MOVE_ROOT_POS_Y,-50.0f,50.0f,0.1f,0.0f))->GetSpinner(); m_rootMovePosZControl = (new CCtlData(hWnd,hKey,IDC_CHECK_MOVE_ROOT_POS_Z,IDC_SPIN_MOVE_ROOT_POS_Z,IDC_EDIT_MOVE_ROOT_POS_Z,-50.0f,50.0f,0.1f,0.0f))->GetSpinner(); /*size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"RootMoveRot",0,&wType,pData,&size)) strcpy(szValue,"1,1,1,0.0,0.0,0.0"); sscanf(szValue,"%i,%i,%i,%f,%f,%f",&x,&y,&z,&fx,&fy,&fz);*/ m_rootMoveRotXControl = (new CCtlData(hWnd,hKey,IDC_CHECK_MOVE_ROOT_ROT_X,IDC_SPIN_MOVE_ROOT_ROT_X,IDC_EDIT_MOVE_ROOT_ROT_X,-50.0f,50.0f,0.1f,0.0f))->GetSpinner(); m_rootMoveRotYControl = (new CCtlData(hWnd,hKey,IDC_CHECK_MOVE_ROOT_ROT_Y,IDC_SPIN_MOVE_ROOT_ROT_Y,IDC_EDIT_MOVE_ROOT_ROT_Y,-50.0f,50.0f,0.1f,0.0f))->GetSpinner(); m_rootMoveRotZControl = (new CCtlData(hWnd,hKey,IDC_CHECK_MOVE_ROOT_ROT_Z,IDC_SPIN_MOVE_ROOT_ROT_Z,IDC_EDIT_MOVE_ROOT_ROT_Z,-50.0f,50.0f,0.1f,0.0f))->GetSpinner(); /*size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"HipScalePosX",0,&wType,pData,&size)) strcpy(szValue,"1,100.0f"); sscanf(szValue,"%i,%f",&x,&fValue);*/ m_hipScaleControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_HIP,IDC_SPIN_SCALE_HIP_POS_X,IDC_EDIT_SCALE_HIP_POS_X,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); /* size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"HipMoveX",0,&wType,pData,&size)) strcpy(szValue,"1,0.0f"); sscanf(szValue,"%i,%f",&x,&fValue);*/ m_hipMoveControl = (new CCtlData(hWnd,hKey,IDC_CHECK_MOVE_HIP,IDC_SPIN_MOVE_HIP_Y,IDC_EDIT_MOVE_HIP_Y,-179.0f,179.0f,0.1f,0.0f))->GetSpinner(); /* size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"TorsoScale",0,&wType,pData,&size)) strcpy(szValue,"1,1,1,100.0,100.0,100.0"); sscanf(szValue,"%i,%i,%i,%f,%f,%f",&x,&y,&z,&fx,&fy,&fz);*/ m_torsoScaleXControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_TORSO_X,IDC_SPIN_SCALE_TORSO_X,IDC_EDIT_SCALE_TORSO_X,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); m_torsoScaleYControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_TORSO_Y,IDC_SPIN_SCALE_TORSO_Y,IDC_EDIT_SCALE_TORSO_Y,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); m_torsoScaleZControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_TORSO_Z,IDC_SPIN_SCALE_TORSO_Z,IDC_EDIT_SCALE_TORSO_Z,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); /* size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"FeetCloseness",0,&wType,pData,&size)) strcpy(szValue,"1,1,100.0f 100.0f"); sscanf(szValue,"%i,%i,%f %f",&x,&y,&fx,&fy);*/ m_leftFootScaleCloseControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_FEET_L,IDC_SPIN_SCALE_FEET_CLOSENESS_LEFT,IDC_EDIT_SCALE_FEET_CLOSENESS_LEFT,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); m_rightFootScaleCloseControl = (new CCtlData(hWnd,hKey,IDC_CHECK_SCALE_FEET_R,IDC_SPIN_SCALE_FEET_CLOSENESS_RIGHT,IDC_EDIT_SCALE_FEET_CLOSENESS_RIGHT,-500.0f,500.0f,1.0f,100.0f))->GetSpinner(); size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"LeaveOriginalTangents",0,&wType,pData,&size)) strcpy(szValue,"0"); sscanf(szValue,"%i",&m_leaveOriginalTangents); SendDlgItemMessage(hWnd,IDC_LEAVE_TANG,BM_SETCHECK,m_leaveOriginalTangents?BST_CHECKED:BST_UNCHECKED,0); size = 100; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"LeaveOriginalCurves",0,&wType,pData,&size)) strcpy(szValue,"0"); sscanf(szValue,"%i",&m_leaveOriginalCurves); SendDlgItemMessage(hWnd,IDC_LEAVE_CURVE,BM_SETCHECK,m_leaveOriginalCurves?BST_CHECKED:BST_UNCHECKED,0); RegCloseKey(hKey); RegCloseKey(hMax); } void HillAdjustPanel::SaveValues() { char keybase[100] = "SOFTWARE\\Autodesk\\3D Studio MAX"; HKEY hMax; if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,keybase,&hMax)) // 3dStudio is not installed?? return; char szKey[50] = "Plugins\\HillAdjust"; HKEY hKey; if (ERROR_SUCCESS != RegCreateKey(hMax,szKey,&hKey)) return; DWORD size = 100; { bool bReset = FALSE; size = 20; DWORD wType = REG_SZ; char szVersion[20]; if (ERROR_SUCCESS != RegQueryValueEx(hKey,"Version",0,&wType,(BYTE *)szVersion,&size)) { bReset = TRUE; } // is the current version newer /* int iVersion = atoi(szVersion); if (0219 > iVersion) CURRENT_BUILD_COUNT { bReset = TRUE; } if (bReset) { for (int x=0;x<4;x++) RegDeleteKey(hKey,g_szDir[x]); }*/ } RegSetValueEx(hKey,"Version",0,REG_SZ,(BYTE *)CURRENT_BUILD_FULL_STRING,strlen(CURRENT_BUILD_FULL_STRING)); RegSetValueEx(hKey,"Last",0,REG_SZ,(BYTE *)g_szDir[m_angleEnum],strlen(g_szDir[m_angleEnum])); RegCloseKey(hKey); strcat(szKey,"\\"); strcat(szKey,g_szDir[m_angleEnum]); if (ERROR_SUCCESS != RegCreateKey(hMax,szKey,&hKey)) return; char szValue[100]; BYTE *pData = (BYTE *)szValue; // xyz used for enabled buttons // int x,y,z; size = 100; size = sprintf(szValue,"%f",m_angleSpinner->GetFVal()); int err; err = RegSetValueEx(hKey,"angle",0,REG_SZ,pData,size); Verify(ERROR_SUCCESS ==err); POSITION pos = g_mapCtlData.GetStartPosition(); WORD key; while (pos) { CObject *pObj; g_mapCtlData.GetNextAssoc(pos,key,pObj); CCtlData *pCtlData = (CCtlData *)pObj; int bEnabled = pCtlData->IsEnabled(); //IsWindowEnabled(GetDlgItem(this->m_hPanel,pCtlData->GetIdEdit())); size = sprintf(szValue,"%i %f",bEnabled,pCtlData->GetSpinner()->GetFVal()); char szKey[10]; sprintf(szKey,"%i",key); err = RegSetValueEx(hKey,szKey,0,REG_SZ,pData,size); Verify(ERROR_SUCCESS ==err); } /* x = rootScalePosXControl->IsEnabled(); y = rootScalePosYControl->IsEnabled(); z = rootScalePosZControl->IsEnabled(); size = sprintf(szValue,"%i,%i,%i,%f,%f,%f",x,y,z,rootScalePosXControl->GetFVal(),rootScalePosYControl->GetFVal(),rootScalePosZControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"RootScalePos",0,REG_SZ,pData,size)); x = rootScaleRotXControl->IsEnabled(); y = rootScaleRotYControl->IsEnabled(); z = rootScaleRotZControl->IsEnabled(); size = sprintf(szValue,"%i,%i,%i,%f,%f,%f",x,y,z,rootScaleRotXControl->GetFVal(),rootScaleRotYControl->GetFVal(),rootScaleRotZControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"RootScaleRot",0,REG_SZ,pData,size)); x = rootMovePosXControl->IsEnabled(); y = rootMovePosYControl->IsEnabled(); z = rootMovePosZControl->IsEnabled(); size = sprintf(szValue,"%i,%i,%i,%f,%f,%f",x,y,z,rootMovePosXControl->GetFVal(),rootMovePosYControl->GetFVal(),rootMovePosZControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"RootMovePos",0,REG_SZ,pData,size)); x = rootMoveRotXControl->IsEnabled(); y = rootMoveRotYControl->IsEnabled(); z = rootMoveRotZControl->IsEnabled(); size = sprintf(szValue,"%i,%i,%i,%f,%f,%f",x,y,z,rootMoveRotXControl->GetFVal(),rootMoveRotYControl->GetFVal(),rootMoveRotZControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"RootMoveRot",0,REG_SZ,pData,size)); x = hipScaleControl->IsEnabled(); size = sprintf(szValue,"%i,%f",x,hipScaleControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"HipScalePosX",0,REG_SZ,pData,size)); x = hipMoveControl->IsEnabled(); size = sprintf(szValue,"%i,%f",x,hipMoveControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"HipMoveX",0,REG_SZ,pData,size)); x = torsoScaleXControl->IsEnabled(); y = torsoScaleYControl->IsEnabled(); z = torsoScaleZControl->IsEnabled(); size = sprintf(szValue,"%i,%i,%i,%f,%f,%f",x,y,z,torsoScaleXControl->GetFVal(),torsoScaleYControl->GetFVal(),torsoScaleZControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"TorsoScale",0,REG_SZ,pData,size)); x = m_leftFootScaleCloseControl->IsEnabled(); y = rightFootScaleCloseControl->IsEnabled(); size = sprintf(szValue,"%i,%i,%f %f",x,y,m_leftFootScaleCloseControl->GetFVal(),rightFootScaleCloseControl->GetFVal()); Verify(ERROR_SUCCESS ==RegSetValueEx(hKey,"FeetCloseness",0,REG_SZ,pData,size)); */ size = sprintf(szValue,"%i",m_leaveOriginalTangents); err = RegSetValueEx(hKey,"LeaveOriginalTangents",0,REG_SZ,pData,size); Verify(ERROR_SUCCESS == err); size = sprintf(szValue,"%i",m_leaveOriginalCurves); err = RegSetValueEx(hKey,"LeaveOriginalCurves",0,REG_SZ,pData,size); Verify(ERROR_SUCCESS == err); RegCloseKey(hKey); RegCloseKey(hMax); } #pragma pack(pop)