From 2b1a79cc9cdeb956deb011162c86f0b6e83c72df Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Sat, 16 Feb 2008 15:58:06 +0000 Subject: [PATCH] multiple interpolation-types! \o/ --- editor/editor.vcproj | 8 ++++-- editor/synceditdata.h | 2 +- editor/synctracker2.cpp | 55 +++++++---------------------------------- editor/trackview.cpp | 42 +++++++++++++++++++++++++++++++ editor/trackview.h | 1 + sync/device_client.cpp | 7 +++++- sync/track.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++------ sync/track.h | 21 +++++++++++++--- sync_player.vcproj | 1 + 9 files changed, 142 insertions(+), 61 deletions(-) diff --git a/editor/editor.vcproj b/editor/editor.vcproj index 6774f2d..6280c2f 100644 --- a/editor/editor.vcproj +++ b/editor/editor.vcproj @@ -2,9 +2,9 @@ @@ -229,6 +229,10 @@ RelativePath="..\sync\track.h" > + + #include "resource.h" - #define WIN32_LEAN_AND_MEAN #include #include @@ -26,10 +25,6 @@ static LRESULT CALLBACK setRowsDialogProc(HWND hDlg, UINT message, WPARAM wParam { switch (message) { -/* case WM_CHAR: - printf("char: %d %d\n", wParam, lParam); - break; */ - case WM_INITDIALOG: { int *rows = (int*)lParam; @@ -169,7 +164,6 @@ static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA break; case WM_SETROWS: - printf("rows: %d\n", int(lParam)); trackView->setRows(int(lParam)); break; @@ -183,7 +177,7 @@ static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA case ID_FILE_SAVE: case ID_FILE_SAVE_AS: case ID_FILE_OPEN: - MessageBox(trackViewWin, "Not implemented", NULL, MB_OK | MB_ICONERROR); + MessageBox(trackViewWin, _T("Not implemented"), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); break; case ID_FILE_EXIT: PostQuitMessage(0); break; @@ -198,7 +192,7 @@ static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA HINSTANCE hInstance = GetModuleHandle(NULL); int rows = trackView->getRows(); INT_PTR result = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_SETROWS), hwnd, (DLGPROC)setRowsDialogProc, (LPARAM)&rows); - if (FAILED(result)) MessageBox(NULL, _T("unable to create dialog box"), NULL, MB_OK); + if (FAILED(result)) MessageBox(NULL, _T("unable to create dialog box"), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); } break; @@ -207,7 +201,7 @@ static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA HINSTANCE hInstance = GetModuleHandle(NULL); int initialBias = 0; INT_PTR result = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_BIASSELECTION), hwnd, (DLGPROC)biasSelectionDialogProc, (LPARAM)&initialBias); - if (FAILED(result)) MessageBox(NULL, _T("unable to create dialog box"), NULL, MB_OK); + if (FAILED(result)) MessageBox(NULL, _T("unable to create dialog box"), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); } break; } @@ -270,8 +264,9 @@ int _tmain(int argc, _TCHAR* argv[]) puts("binding..."); if (SOCKET_ERROR == bind( serverSocket, (struct sockaddr *)&sin, sizeof(sin))) { + MessageBox(NULL, "Could not start server", NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); fputs("Coult not start server", stderr); - exit(1); + return -1; } puts("listening..."); @@ -287,45 +282,13 @@ int _tmain(int argc, _TCHAR* argv[]) SyncEditData syncData; syncData.clientSocket = INVALID_SOCKET; -#if 0 - - SyncTrack &camXTrack = syncData.getTrack(_T("cam.x")); - SyncTrack &camXTrack2 = syncData.getTrack(_T("cam.x")); - camXTrack.setKeyFrame(1, 2.0f); - camXTrack.setKeyFrame(4, 3.0f); - printf("%p %p\n", &camXTrack, &camXTrack2); - - SyncTrack &camYTrack = syncData.getTrack(_T("cam.y")); - SyncTrack &camZTrack = syncData.getTrack(_T("cam.z")); - -/* for (int i = 0; i < 16; ++i) - { - TCHAR temp[256]; - _sntprintf_s(temp, 256, _T("gen %02d"), i); - SyncTrack &temp2 = syncData.getTrack(temp); - } */ - - camXTrack.setKeyFrame(1, 2.0f); - camXTrack.setKeyFrame(4, 3.0f); - - camYTrack.setKeyFrame(0, 100.0f); - camYTrack.setKeyFrame(8, 999.0f); - - camYTrack.setKeyFrame(16, SyncTrack::KeyFrame(float(1E-5))); - - for (int i = 0; i < 5 * 2; ++i) - { - float time = float(i) / 2; - printf("%f %d - %f\n", time, camXTrack.isKeyFrame(i), camXTrack.getValue(time)); - } -#endif ATOM mainClass = registerMainWindowClass(hInstance); ATOM trackViewClass = registerTrackViewWindowClass(hInstance); if (!mainClass || !trackViewClass) { - MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK); - return 0; + MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"), MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + return -1; } trackView = new TrackView(); @@ -344,8 +307,8 @@ int _tmain(int argc, _TCHAR* argv[]) if (NULL == hwnd) { - MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK); - return 0; + MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"), MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND); + return -1; } HACCEL accel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); diff --git a/editor/trackview.cpp b/editor/trackview.cpp index 24f76c7..b7e0c0e 100644 --- a/editor/trackview.cpp +++ b/editor/trackview.cpp @@ -664,6 +664,44 @@ void TrackView::editEnterValue() else MessageBeep(0); } +void TrackView::editToggleInterpolationType() +{ + if (editTrack < int(syncData->getTrackCount())) + { + sync::Track &t = syncData->getTrack(editTrack); + + // find key to modify + sync::Track::KeyFrameContainer::const_iterator upper = t.keyFrames.upper_bound(editRow); + // bounds check + if (upper == t.keyFrames.end()) + { + MessageBeep(0); + return; + } + + sync::Track::KeyFrameContainer::const_iterator lower = lower; + lower--; + // bounds check again + if (lower == t.keyFrames.end()) + { + MessageBeep(0); + return; + } + + sync::Track::KeyFrame newKey = lower->second; + // modify interpolation type + newKey.interpolationType = sync::Track::KeyFrame::InterpolationType( + (int(newKey.interpolationType) + 1) % sync::Track::KeyFrame::IT_COUNT + ); + + SyncEditData::Command *cmd = syncData->getSetKeyFrameCommand(editTrack, int(lower->first), newKey); + syncData->exec(cmd); + + invalidateRange(editTrack, editTrack, lower->first, upper->first); + } + else MessageBeep(0); +} + void TrackView::editDelete() { int selectLeft = min(selectStartTrack, selectStopTrack); @@ -863,6 +901,10 @@ LRESULT TrackView::onChar(UINT keyCode, UINT flags) } else MessageBeep(0); break; + + case 'i': + editToggleInterpolationType(); + break; } return FALSE; } diff --git a/editor/trackview.h b/editor/trackview.h index e43fbaf..c98eafc 100644 --- a/editor/trackview.h +++ b/editor/trackview.h @@ -47,6 +47,7 @@ private: void editCopy(); void editCut(); void editPaste(); + void editToggleInterpolationType(); void paintTracks(HDC hdc, RECT rcTracks); void paintTopMargin(HDC hdc, RECT rcTracks); diff --git a/sync/device_client.cpp b/sync/device_client.cpp index d0dbab0..0c3f2e8 100644 --- a/sync/device_client.cpp +++ b/sync/device_client.cpp @@ -79,12 +79,17 @@ bool ClientDevice::update(float row) { int track, row; float value; + Track::KeyFrame::InterpolationType interp; + recv(serverSocket, (char*)&track, sizeof(int), 0); recv(serverSocket, (char*)&row, sizeof(int), 0); recv(serverSocket, (char*)&value, sizeof(float), 0); + recv(serverSocket, (char*)&interp, 1, 0); + + assert(interp < Track::KeyFrame::IT_COUNT); sync::Track &t = syncData.getTrack(track); - t.setKeyFrame(row, Track::KeyFrame(value)); + t.setKeyFrame(row, Track::KeyFrame(value, interp)); } break; diff --git a/sync/track.cpp b/sync/track.cpp index 10f2b23..e304de3 100644 --- a/sync/track.cpp +++ b/sync/track.cpp @@ -1,17 +1,62 @@ +#define _USE_MATH_DEFINES +#include + #include "track.h" #include "data.h" using namespace sync; -#include #include +/*#ifndef M_PI +#define M_PI +#endif */ + +static inline float step(Track::KeyFrameContainer::const_iterator lower, Track::KeyFrameContainer::const_iterator upper, float time) +{ + return lower->second.value; +} + +static inline float lerp(Track::KeyFrameContainer::const_iterator lower, Track::KeyFrameContainer::const_iterator upper, float time) +{ + // find local time + float t = (time - lower->first) / (upper->first - lower->first); + + // lerp, bitch + float delta = upper->second.value - lower->second.value; + return lower->second.value + delta * t; +} + +static inline float cosine(Track::KeyFrameContainer::const_iterator lower, Track::KeyFrameContainer::const_iterator upper, float time) +{ + // find local time + float t = (time - lower->first) / (upper->first - lower->first); + t = float((1.0 - cos(t * M_PI)) * 0.5); + + // lerp, bitch + float delta = upper->second.value - lower->second.value; + return lower->second.value + delta * t; +} + +static inline float ramp(Track::KeyFrameContainer::const_iterator lower, Track::KeyFrameContainer::const_iterator upper, float time) +{ + // find local time + float t = (time - lower->first) / (upper->first - lower->first); + t = powf(t, 2.0f); + + // lerp, bitch + float delta = upper->second.value - lower->second.value; + return lower->second.value + delta * t; +} + +/*float cosine(float time) const; +float ramp(float time) const; */ + float Track::getValue(float time) const { if (keyFrames.size() == 0) return 0.0f; - int currRow = int(floor(time)); - // find bounding keyframes + int currRow = int(floor(time)); KeyFrameContainer::const_iterator upper = keyFrames.upper_bound(currRow); KeyFrameContainer::const_iterator lower = upper; lower--; @@ -20,11 +65,16 @@ float Track::getValue(float time) const if (lower == keyFrames.end()) return upper->second.value; if (upper == keyFrames.end()) return lower->second.value; - float delta = upper->second.value - lower->second.value; - - // lerp, bitch - float d = (time - lower->first) / (upper->first - lower->first); - return lower->second.value + delta * d; + switch (lower->second.interpolationType) + { + case Track::KeyFrame::IT_STEP: return step( lower, upper, time); + case Track::KeyFrame::IT_LERP: return lerp( lower, upper, time); + case Track::KeyFrame::IT_COSINE: return cosine(lower, upper, time); + case Track::KeyFrame::IT_RAMP: return ramp( lower, upper, time); + default: + assert(false); + return step(lower, upper, time); + } } bool Track::isKeyFrame(size_t row) const diff --git a/sync/track.h b/sync/track.h index 0bd748e..6c892cc 100644 --- a/sync/track.h +++ b/sync/track.h @@ -10,13 +10,28 @@ namespace sync public: struct KeyFrame { - KeyFrame() : lerp(false) {} - KeyFrame(float value) : value(value), lerp(false) {} + enum InterpolationType + { + IT_STEP, + IT_LERP, + IT_COSINE, + IT_RAMP, + IT_COUNT // max value + }; + + KeyFrame() : value(0.0f), interpolationType(IT_STEP) {} + explicit KeyFrame(float value, InterpolationType interpolationType) : + value(value), + interpolationType(interpolationType) + { + } + float value; - bool lerp; + InterpolationType interpolationType; }; float getValue(float time) const; + bool isKeyFrame(size_t row) const; const KeyFrame *getKeyFrame(size_t row) const; size_t getFrameCount() const; diff --git a/sync_player.vcproj b/sync_player.vcproj index a574665..aab5559 100644 --- a/sync_player.vcproj +++ b/sync_player.vcproj @@ -182,6 +182,7 @@ />