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

3246 lines
84 KiB
C++

//===========================================================================//
// 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)