diff --git a/3rd_party/HavokLib b/3rd_party/HavokLib index 29a7821..e1872fc 160000 --- a/3rd_party/HavokLib +++ b/3rd_party/HavokLib @@ -1 +1 @@ -Subproject commit 29a782185500938431d41261a34853d85332c4fc +Subproject commit e1872fc9763e5df5314cd8d032312c7edc1fcc2b diff --git a/CHANGELOG b/CHANGELOG index cca77dd..b48ca54 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v1.13 +- Added blend hint override. +- Added support for 2022 version. v1.12 - Fixed specific crash when importing incomplete skeletons. (#18 ) - Fixed wrong root motion rotation directions. diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d04c34..cd42420 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required(VERSION 3.3) -project(HavokMax VERSION 1.12) +project(HavokMax VERSION 1.13) set (HavokLibLibraryPath ../HavokLib) - +set(CMAKE_CXX_STANDARD 14) add_subdirectory(3rd_party/HavokLib ${HavokLibLibraryPath}) include(${PRECORE_SOURCE_DIR}/cmake/3dsmax.cmake) @@ -18,7 +18,7 @@ build_target( src/HavokMax.rc ${MAX_EX_DIR}/win/About.rc LINKS - gdiplus bmm core HavokLib flt mesh maxutil maxscrpt paramblk2 geom MaxSDKTarget + gdiplus bmm core havok-objects flt mesh maxutil maxscrpt paramblk2 geom MaxSDKTarget AUTHOR "Lukas Cone" DESCR "Havok 3DS Max Unofficial Plugin" START_YEAR 2016 diff --git a/src/HavokExport.cpp b/src/HavokExport.cpp index 9811d04..bfdb682 100644 --- a/src/HavokExport.cpp +++ b/src/HavokExport.cpp @@ -65,6 +65,7 @@ class : public ClassDesc2 { const TCHAR *Category() { return NULL; } const TCHAR *InternalName() { return _className; } HINSTANCE HInstance() { return hInstance; } + const TCHAR *NonLocalizedClassName() { return _className; } } HavokExportDesc; ClassDesc2 *GetHavokExportDesc() { return &HavokExportDesc; } diff --git a/src/HavokImport.cpp b/src/HavokImport.cpp index a473305..51c1689 100644 --- a/src/HavokImport.cpp +++ b/src/HavokImport.cpp @@ -53,14 +53,15 @@ class HavokImport : public SceneImport, HavokMaxV2 { class : public ClassDesc2 { public: - virtual int IsPublic() { return TRUE; } - virtual void *Create(BOOL) { return new HavokImport(); } - virtual const TCHAR *ClassName() { return _className; } - virtual SClass_ID SuperClassID() { return SCENE_IMPORT_CLASS_ID; } - virtual Class_ID ClassID() { return HavokImport_CLASS_ID; } - virtual const TCHAR *Category() { return NULL; } - virtual const TCHAR *InternalName() { return _className; } - virtual HINSTANCE HInstance() { return hInstance; } + int IsPublic() { return TRUE; } + void *Create(BOOL) { return new HavokImport(); } + const TCHAR *ClassName() { return _className; } + SClass_ID SuperClassID() { return SCENE_IMPORT_CLASS_ID; } + Class_ID ClassID() { return HavokImport_CLASS_ID; } + const TCHAR *Category() { return NULL; } + const TCHAR *InternalName() { return _className; } + HINSTANCE HInstance() { return hInstance; } + const TCHAR *NonLocalizedClassName() { return _className; } } HavokImportDesc; ClassDesc2 *GetHavokImportDesc() { return &HavokImportDesc; } @@ -274,7 +275,11 @@ void HavokImport::LoadAnimation(const hkaAnimation *ani, } const auto numBones = ani->GetNumOfTransformTracks(); - const BlendHint blendType = bind ? bind->GetBlendHint() : BlendHint::NORMAL; + BlendHint blendType = bind ? bind->GetBlendHint() : BlendHint::NORMAL; + + if (additiveOverride) { + blendType = static_cast(additiveOverride); + } std::vector addTMs(numBones, true); diff --git a/src/HavokMax.cpp b/src/HavokMax.cpp index 4b09b23..4d2a2e5 100644 --- a/src/HavokMax.cpp +++ b/src/HavokMax.cpp @@ -43,7 +43,8 @@ const TCHAR _homePage[] = #include "MAXex/win/AboutDlg.h" REFLECTOR_CREATE(HavokMax, 1, VARNAMES, checked, visible, motionIndex, toolset, - animationStart, animationEnd, captureFrame, currentPresetName); + animationStart, animationEnd, captureFrame, currentPresetName, + additiveOverride); struct PresetData : ReflectorInterface { float scale; @@ -66,7 +67,7 @@ void SavePresets(pugi::xml_node node) { if (!f.second.external) { auto presetNode = rootNode.append_child("preset"); presetNode.append_attribute("name").set_value(f.first.data()); - ReflectorWrapConst rWrap(f.second); + ReflectorWrap rWrap(f.second); ReflectorXMLUtil::Save(rWrap, presetNode); auto corMatNode = presetNode.append_child("matrix"); auto corMatData = GetCorrectionMatrix(f.second.corMat); @@ -270,7 +271,7 @@ void DestroyHavokResources() { HavokMax::HavokMax() : hWnd(), comboHandle(), currentPresetName("Default"), objectScale(1.0f), instanceDialogType(DLGTYPE_unknown), toolset(HK500), captureFrame(), - motionIndex() { + motionIndex(), additiveOverride() { corMat.IdentityMatrix(); Interval aniRange = GetCOREInterface()->GetAnimRange(); @@ -334,9 +335,9 @@ static void LoadLegacyConfig() { genName += ToTSTRING(std::to_string(p)); TSTRING prName_; prName_.resize(0x102); - auto numReadChars = - GetPrivateProfileString(legacyGroup, genName.data(), _T(""), &prName_[0], - (DWORD)prName_.size(), cfgpath.data()); + auto numReadChars = GetPrivateProfileString( + legacyGroup, genName.data(), _T(""), &prName_[0], (DWORD)prName_.size(), + cfgpath.data()); prName_.resize(numReadChars); @@ -378,7 +379,7 @@ void HavokMax::LoadCFG() { void HavokMax::SaveCFG() { pugi::xml_document doc; - ReflectorWrapConst rWrap(this); + ReflectorWrap rWrap(this); ReflectorXMLUtil::Save(rWrap, doc); SavePresets(doc); auto conf = GetConfig(); @@ -967,6 +968,9 @@ INT_PTR HavokMaxV2::DlgCommandCallBack(WPARAM wParam, LPARAM lParam) { UpdateData(); return TRUE; } + case IDC_CB_ADDITIVE_OVERRIDE: + additiveOverride = SendMessage(comboAddOvr, CB_GETCURSEL, 0, 0); + return TRUE; } return (INT_PTR)FALSE; } @@ -989,6 +993,7 @@ void HavokMaxV2::Setup(HWND hwnd) { HavokMax::Setup(hwnd); comboBack = GetDlgItem(hWnd, IDC_CB_BACK); comboRight = GetDlgItem(hWnd, IDC_CB_RIGHT); + comboAddOvr = GetDlgItem(hWnd, IDC_CB_ADDITIVE_OVERRIDE); static const TCHAR *_items[] = {_T("Right"), _T("Back"), _T("Top")}; @@ -996,6 +1001,10 @@ void HavokMaxV2::Setup(HWND hwnd) { SendMessage(comboBack, CB_ADDSTRING, 0, (LPARAM)_items[c]); SendMessage(comboRight, CB_ADDSTRING, 0, (LPARAM)_items[c]); } + + SendMessage(comboAddOvr, CB_ADDSTRING, 0, (LPARAM) _T("AUTO")); + SendMessage(comboAddOvr, CB_ADDSTRING, 0, (LPARAM) _T("OLD")); + SendMessage(comboAddOvr, CB_ADDSTRING, 0, (LPARAM) _T("NEW")); } static const int toEnableItemsV2[] = { @@ -1013,6 +1022,7 @@ void HavokMaxV2::UpdatePresetUI(PresetData &data) { SetupFloatSpinner(hWnd, IDC_SPIN_SCALE, IDC_EDIT_SCALE, 0, 5000, objectScale); SetupIntSpinner(hWnd, IDC_SPIN_MOTIONID, IDC_EDIT_MOTIONID, 0, numAnimations - 1, motionIndex); + SendMessage(comboAddOvr, CB_SETCURSEL, additiveOverride, 0); int curIndex = 0; diff --git a/src/HavokMax.h b/src/HavokMax.h index 0efcc31..edf3c84 100644 --- a/src/HavokMax.h +++ b/src/HavokMax.h @@ -56,7 +56,7 @@ class HavokMax : public ReflectorInterface { // config es::Flags checked; es::Flags visible; - int32 motionIndex; + int32 motionIndex, additiveOverride; hkToolset toolset; TimeValue animationStart, animationEnd, captureFrame; std::string currentPresetName; @@ -106,6 +106,7 @@ class HavokMaxV2 : public HavokMax { public: HWND comboRight; HWND comboBack; + HWND comboAddOvr; void CollisionHandler(); void UpdatePresetUI(PresetData &presetData); diff --git a/src/HavokMax.rc b/src/HavokMax.rc index bd4b76f..a51e094 100644 --- a/src/HavokMax.rc +++ b/src/HavokMax.rc @@ -193,37 +193,39 @@ BEGIN LTEXT "Toolset:",IDC_STATIC,7,9,26,8 END -IDD_IMPORT_NEW DIALOGEX 0, 0, 123, 175 +IDD_IMPORT_NEW DIALOGEX 0, 0, 123, 192 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOOLWINDOW FONT 8, "MS Sans Serif", 400, 0, 0xEE BEGIN - PUSHBUTTON "&Import",IDC_BT_DONE,6,155,45,14 - PUSHBUTTON "&Cancel",IDC_BT_CANCEL,72,155,45,14 - PUSHBUTTON "?",IDC_BT_ABOUT,54,155,15,14 - CONTROL "&s",IDC_EDIT_SCALE,"CustEdit",WS_TABSTOP,45,6,35,10 - CONTROL "&m",IDC_EDIT_MOTIONID,"CustEdit",WS_TABSTOP,45,20,35,10 - CONTROL "Invert &Top",IDC_CH_INVERT_TOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,63,44,10 - CONTROL "- &B",IDC_CH_INVERT_BACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,57,79,15,8 - COMBOBOX IDC_CB_BACK,72,76,36,50,CBS_DROPDOWNLIST | WS_TABSTOP - CONTROL "- &R",IDC_CH_INVERT_RIGHT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,57,98,15,8 - COMBOBOX IDC_CB_RIGHT,72,94,36,50,CBS_DROPDOWNLIST | WS_TABSTOP - COMBOBOX IDC_CB_PRESET,6,131,111,150,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "+",IDC_BT_ADDPRESET,9,113,18,14 - PUSHBUTTON "-",IDC_BT_DELETEPRESET,30,113,18,14 - CONTROL "",IDC_SPIN_SCALE,"SpinnerControl",0x0,81,6,7,10 + PUSHBUTTON "&Import",IDC_BT_DONE,7,171,45,14 + PUSHBUTTON "&Cancel",IDC_BT_CANCEL,73,171,45,14 + PUSHBUTTON "?",IDC_BT_ABOUT,55,171,15,14 + CONTROL "&s",IDC_EDIT_SCALE,"CustEdit",WS_TABSTOP,69,6,35,10 + CONTROL "&m",IDC_EDIT_MOTIONID,"CustEdit",WS_TABSTOP,69,20,35,10 + COMBOBOX IDC_CB_ADDITIVE_OVERRIDE,69,34,44,30,CBS_DROPDOWNLIST | WS_TABSTOP + LTEXT "Additive override",IDC_STATIC,9,36,54,8 + CONTROL "Invert &Top",IDC_CH_INVERT_TOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,79,44,10 + CONTROL "- &B",IDC_CH_INVERT_BACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,58,95,15,8 + COMBOBOX IDC_CB_BACK,74,92,36,50,CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "- &R",IDC_CH_INVERT_RIGHT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,58,114,15,8 + COMBOBOX IDC_CB_RIGHT,74,110,36,50,CBS_DROPDOWNLIST | WS_TABSTOP + COMBOBOX IDC_CB_PRESET,8,147,111,150,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "+",IDC_BT_ADDPRESET,10,129,18,14 + PUSHBUTTON "-",IDC_BT_DELETEPRESET,31,129,18,14 + CONTROL "",IDC_SPIN_SCALE,"SpinnerControl",0x0,105,6,7,10 LTEXT "Scale:",IDC_STATIC,9,6,21,8 - PUSHBUTTON "Save",IDC_BT_SAVEPRESET,51,113,39,14,NOT WS_VISIBLE | NOT WS_TABSTOP - CONTROL IDB_BITMAP2,IDC_STATIC,"Static",SS_BITMAP,9,73,24,31 - GROUPBOX "Coords setup",IDC_STATIC,3,52,114,60 - CONTROL IDB_BITMAP3,IDC_PC_INVERT_ERROR,"Static",SS_BITMAP | NOT WS_VISIBLE,56,62,3,10 - CONTROL IDB_BITMAP3,IDC_PC_REMAP_ERROR2,"Static",SS_BITMAP | NOT WS_VISIBLE,110,78,3,10 - CONTROL IDB_BITMAP3,IDC_PC_REMAP_ERROR1,"Static",SS_BITMAP | NOT WS_VISIBLE,110,97,3,10 - LTEXT "Back:",IDC_STATIC,36,79,20,8 - LTEXT "Right:",IDC_STATIC,36,97,20,8 - CONTROL "",IDC_SPIN_MOTIONID,"SpinnerControl",0x0,81,20,7,10 + PUSHBUTTON "Save",IDC_BT_SAVEPRESET,52,129,39,14,NOT WS_VISIBLE | NOT WS_TABSTOP + CONTROL IDB_BITMAP2,IDC_STATIC,"Static",SS_BITMAP,10,89,24,31 + GROUPBOX "Coords setup",IDC_STATIC,4,68,114,60 + CONTROL IDB_BITMAP3,IDC_PC_INVERT_ERROR,"Static",SS_BITMAP | NOT WS_VISIBLE,57,78,3,10 + CONTROL IDB_BITMAP3,IDC_PC_REMAP_ERROR2,"Static",SS_BITMAP | NOT WS_VISIBLE,112,93,3,10 + CONTROL IDB_BITMAP3,IDC_PC_REMAP_ERROR1,"Static",SS_BITMAP | NOT WS_VISIBLE,112,112,3,10 + LTEXT "Back:",IDC_STATIC,37,95,20,8 + LTEXT "Right:",IDC_STATIC,37,113,20,8 + CONTROL "",IDC_SPIN_MOTIONID,"SpinnerControl",0x0,105,20,7,10 LTEXT "Motion ID:",IDC_STATIC,9,20,34,8 - CONTROL "&Disable scale",IDC_CH_DISABLE_SCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,36,58,10 + CONTROL "&Disable scale",IDC_CH_DISABLE_SCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,52,58,10 END IDD_EXPORT_NEW DIALOGEX 0, 0, 229, 159 @@ -301,7 +303,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 116 TOPMARGIN, 7 - BOTTOMMARGIN, 168 + BOTTOMMARGIN, 185 END IDD_EXPORT_NEW, DIALOG diff --git a/src/resource.h b/src/resource.h index 74a17bc..a3c6964 100644 --- a/src/resource.h +++ b/src/resource.h @@ -57,6 +57,7 @@ #define IDC_CH_INVERT_RIGHT2 1041 #define IDC_CH_DISABLE_SCALE 1041 #define IDC_CHECK2 1042 +#define IDC_CB_ADDITIVE_OVERRIDE 1043 #define IDC_COLOR 1456 #define IDC_EDIT 1490 #define IDC_EDIT_SCALE 1490 @@ -75,9 +76,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 112 +#define _APS_NEXT_RESOURCE_VALUE 113 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1043 +#define _APS_NEXT_CONTROL_VALUE 1044 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif