use mvvm
Switch the Testbed GUI architecture pattern to MVVM (Model-View-ModelView).
This commit is contained in:
parent
b9b23de3a0
commit
4570c971c0
@ -24,15 +24,19 @@
|
|||||||
// error
|
// error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <glfw/glfw3.h>
|
||||||
|
|
||||||
#include <testbed/framework/model.h>
|
#include <testbed/framework/model.h>
|
||||||
#include <testbed/framework/view.h>
|
#include <testbed/framework/view.h>
|
||||||
|
#include <testbed/framework/view_model.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
GLFWwindow* g_window;
|
static GLFWwindow* g_window;
|
||||||
|
|
||||||
//
|
//
|
||||||
Model* g_model;
|
static Model* g_model;
|
||||||
View* g_view;
|
static View* g_view;
|
||||||
|
static ViewModel* g_viewModel;
|
||||||
|
|
||||||
static void WindowSize(GLFWwindow* ww, int w, int h)
|
static void WindowSize(GLFWwindow* ww, int w, int h)
|
||||||
{
|
{
|
||||||
@ -103,9 +107,9 @@ static void Run()
|
|||||||
|
|
||||||
g_profiler->PushEvent("Frame");
|
g_profiler->PushEvent("Frame");
|
||||||
|
|
||||||
g_view->Command_PreDraw();
|
g_view->BeginInterface();
|
||||||
|
|
||||||
if (g_settings->pause)
|
if (g_model->IsPaused())
|
||||||
{
|
{
|
||||||
g_draw->DrawString(b3Color_white, "*PAUSED*");
|
g_draw->DrawString(b3Color_white, "*PAUSED*");
|
||||||
}
|
}
|
||||||
@ -124,11 +128,11 @@ static void Run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_view->Command_Draw();
|
g_view->Interface();
|
||||||
|
|
||||||
g_model->Command_Step();
|
g_model->Update();
|
||||||
|
|
||||||
g_view->Command_PostDraw();
|
g_view->EndInterface();
|
||||||
|
|
||||||
g_profiler->PopEvent();
|
g_profiler->PopEvent();
|
||||||
|
|
||||||
@ -183,12 +187,16 @@ int main(int argc, char** args)
|
|||||||
|
|
||||||
//
|
//
|
||||||
g_model = new Model();
|
g_model = new Model();
|
||||||
g_view = new View(g_window, g_model);
|
g_view = new View(g_window);
|
||||||
|
g_viewModel = new ViewModel(g_model, g_view);
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
Run();
|
Run();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
delete g_viewModel;
|
||||||
|
g_viewModel = nullptr;
|
||||||
|
|
||||||
delete g_view;
|
delete g_view;
|
||||||
g_view = nullptr;
|
g_view = nullptr;
|
||||||
|
|
||||||
|
@ -17,13 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <testbed/framework/model.h>
|
#include <testbed/framework/model.h>
|
||||||
|
#include <testbed/framework/view_model.h>
|
||||||
Settings* g_settings = nullptr;
|
#include <testbed/framework/test.h>
|
||||||
|
|
||||||
Model::Model()
|
Model::Model()
|
||||||
{
|
{
|
||||||
g_settings = &m_settings;
|
m_viewModel = nullptr;
|
||||||
g_testSettings = &m_testSettings;
|
|
||||||
g_draw = &m_draw;
|
g_draw = &m_draw;
|
||||||
g_camera = &m_camera;
|
g_camera = &m_camera;
|
||||||
g_profiler = &m_profiler;
|
g_profiler = &m_profiler;
|
||||||
@ -42,43 +41,80 @@ Model::Model()
|
|||||||
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
|
||||||
glClearDepth(1.0f);
|
glClearDepth(1.0f);
|
||||||
|
|
||||||
Action_DefaultCamera();
|
Action_ResetCamera();
|
||||||
|
|
||||||
|
m_setTest = true;
|
||||||
|
m_pause = true;
|
||||||
|
m_singlePlay = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Model::~Model()
|
Model::~Model()
|
||||||
{
|
{
|
||||||
g_testSettings = nullptr;
|
|
||||||
g_draw = nullptr;
|
g_draw = nullptr;
|
||||||
g_camera = nullptr;
|
g_camera = nullptr;
|
||||||
g_profiler = nullptr;
|
g_profiler = nullptr;
|
||||||
g_profilerRecorder = nullptr;
|
g_profilerRecorder = nullptr;
|
||||||
g_profilerListener = nullptr;
|
g_profilerListener = nullptr;
|
||||||
g_testSettings = nullptr;
|
|
||||||
|
|
||||||
delete m_test;
|
delete m_test;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::Command_Step()
|
void Model::Action_SaveTest()
|
||||||
|
{
|
||||||
|
m_test->Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::Command_Press_Key(int button)
|
||||||
|
{
|
||||||
|
m_test->KeyDown(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::Command_Release_Key(int button)
|
||||||
|
{
|
||||||
|
m_test->KeyUp(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::Command_Press_Mouse_Left(const b3Vec2& ps)
|
||||||
|
{
|
||||||
|
Ray3 pw = m_camera.ConvertScreenToWorld(ps);
|
||||||
|
|
||||||
|
m_test->MouseLeftDown(pw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::Command_Release_Mouse_Left(const b3Vec2& ps)
|
||||||
|
{
|
||||||
|
Ray3 pw = m_camera.ConvertScreenToWorld(ps);
|
||||||
|
|
||||||
|
m_test->MouseLeftUp(pw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::Command_Move_Cursor(const b3Vec2& ps)
|
||||||
|
{
|
||||||
|
Ray3 pw = m_camera.ConvertScreenToWorld(ps);
|
||||||
|
|
||||||
|
m_test->MouseMove(pw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::Update()
|
||||||
{
|
{
|
||||||
g_drawFlags = 0;
|
g_drawFlags = 0;
|
||||||
g_drawFlags += m_settings.drawPoints * DrawFlags::e_pointsFlag;
|
g_drawFlags += g_settings->drawPoints * DrawFlags::e_pointsFlag;
|
||||||
g_drawFlags += m_settings.drawLines * DrawFlags::e_linesFlag;
|
g_drawFlags += g_settings->drawLines * DrawFlags::e_linesFlag;
|
||||||
g_drawFlags += m_settings.drawTriangles * DrawFlags::e_trianglesFlag;
|
g_drawFlags += g_settings->drawTriangles * DrawFlags::e_trianglesFlag;
|
||||||
|
|
||||||
glViewport(0, 0, GLsizei(m_camera.m_width), GLsizei(m_camera.m_height));
|
glViewport(0, 0, GLsizei(m_camera.m_width), GLsizei(m_camera.m_height));
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
if (m_settings.testID != m_settings.lastTestID)
|
if (m_setTest)
|
||||||
{
|
{
|
||||||
delete m_test;
|
delete m_test;
|
||||||
m_settings.lastTestID = m_settings.testID;
|
m_test = g_tests[g_settings->testID].create();
|
||||||
m_test = g_tests[m_settings.testID].create();
|
m_setTest = false;
|
||||||
|
m_pause = true;
|
||||||
m_settings.pause = true;
|
Action_ResetCamera();
|
||||||
Action_DefaultCamera();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_settings.drawGrid)
|
if (g_settings->drawGrid)
|
||||||
{
|
{
|
||||||
b3Color color(0.2f, 0.2f, 0.2f, 1.0f);
|
b3Color color(0.2f, 0.2f, 0.2f, 1.0f);
|
||||||
|
|
||||||
@ -114,19 +150,25 @@ void Model::Command_Step()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
m_testSettings.inv_hertz = m_testSettings.hertz != 0.0f ? 1.0f / m_testSettings.hertz : 0.0f;
|
if (m_pause)
|
||||||
|
|
||||||
if (m_settings.pause)
|
|
||||||
{
|
{
|
||||||
if (m_settings.singleStep)
|
if (m_singlePlay)
|
||||||
{
|
{
|
||||||
m_settings.singleStep = false;
|
// !
|
||||||
|
g_testSettings->inv_hertz = g_testSettings->hertz > 0.0f ? 1.0f / g_testSettings->hertz : 0.0f;
|
||||||
|
m_singlePlay = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_testSettings.inv_hertz = 0.0f;
|
// !
|
||||||
|
g_testSettings->inv_hertz = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// !
|
||||||
|
g_testSettings->inv_hertz = g_testSettings->hertz > 0.0f ? 1.0f / g_testSettings->hertz : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
m_test->Step();
|
m_test->Step();
|
||||||
|
|
||||||
|
@ -21,40 +21,10 @@
|
|||||||
|
|
||||||
#include <testbed/framework/draw.h>
|
#include <testbed/framework/draw.h>
|
||||||
#include <testbed/framework/testbed_listener.h>
|
#include <testbed/framework/testbed_listener.h>
|
||||||
#include <testbed/framework/test.h>
|
|
||||||
|
|
||||||
struct Settings
|
class Test;
|
||||||
{
|
|
||||||
Settings()
|
|
||||||
{
|
|
||||||
lastTestID = -1;
|
|
||||||
testID = 0;
|
|
||||||
pause = false;
|
|
||||||
singleStep = false;
|
|
||||||
drawPoints = true;
|
|
||||||
drawLines = true;
|
|
||||||
drawTriangles = true;
|
|
||||||
drawGrid = true;
|
|
||||||
drawProfile = false;
|
|
||||||
drawStats = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lastTestID;
|
class ViewModel;
|
||||||
int testID;
|
|
||||||
|
|
||||||
bool pause;
|
|
||||||
bool singleStep;
|
|
||||||
|
|
||||||
bool drawPoints;
|
|
||||||
bool drawLines;
|
|
||||||
bool drawTriangles;
|
|
||||||
bool drawGrid;
|
|
||||||
bool drawProfile;
|
|
||||||
bool drawStats;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
extern Settings* g_settings;
|
|
||||||
|
|
||||||
class Model
|
class Model
|
||||||
{
|
{
|
||||||
@ -64,88 +34,59 @@ public:
|
|||||||
~Model();
|
~Model();
|
||||||
|
|
||||||
void Action_SaveTest();
|
void Action_SaveTest();
|
||||||
|
void Action_SetTest();
|
||||||
void Action_SelectTest(int selection);
|
|
||||||
void Action_RestartTest();
|
|
||||||
void Action_PreviousTest();
|
|
||||||
void Action_NextTest();
|
|
||||||
void Action_PlayPause();
|
void Action_PlayPause();
|
||||||
void Action_SingleStep();
|
void Action_SinglePlay();
|
||||||
void Action_DefaultCamera();
|
void Action_ResetCamera();
|
||||||
void Action_LeftCamera();
|
|
||||||
void Action_RightCamera();
|
|
||||||
void Action_BottomCamera();
|
|
||||||
void Action_TopCamera();
|
|
||||||
void Action_BackCamera();
|
|
||||||
void Action_FrontCamera();
|
|
||||||
|
|
||||||
void Command_Step();
|
|
||||||
void Command_Press_Key(int button);
|
void Command_Press_Key(int button);
|
||||||
void Command_Release_Key(int button);
|
void Command_Release_Key(int button);
|
||||||
void Command_Press_Mouse_Left(const b3Vec2& ps);
|
void Command_Press_Mouse_Left(const b3Vec2& ps);
|
||||||
void Command_Release_Mouse_Left(const b3Vec2& ps);
|
void Command_Release_Mouse_Left(const b3Vec2& ps);
|
||||||
void Command_Move_Cursor(const b3Vec2& ps);
|
void Command_Move_Cursor(const b3Vec2& ps);
|
||||||
|
|
||||||
void Command_ResizeCamera(float32 w, float32 h);
|
void Command_ResizeCamera(float32 w, float32 h);
|
||||||
void Command_RotateCameraX(float32 angle);
|
void Command_RotateCameraX(float32 angle);
|
||||||
void Command_RotateCameraY(float32 angle);
|
void Command_RotateCameraY(float32 angle);
|
||||||
void Command_TranslateCameraX(float32 d);
|
void Command_TranslateCameraX(float32 d);
|
||||||
void Command_TranslateCameraY(float32 d);
|
void Command_TranslateCameraY(float32 d);
|
||||||
void Command_ZoomCamera(float32 d);
|
void Command_ZoomCamera(float32 d);
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
bool IsPaused() const { return m_pause; }
|
||||||
private:
|
private:
|
||||||
friend class View;
|
friend class ViewModel;
|
||||||
|
|
||||||
// UI State
|
ViewModel* m_viewModel;
|
||||||
Settings m_settings;
|
|
||||||
TestSettings m_testSettings;
|
|
||||||
|
|
||||||
// App State
|
|
||||||
Draw m_draw;
|
Draw m_draw;
|
||||||
Camera m_camera;
|
Camera m_camera;
|
||||||
Profiler m_profiler;
|
Profiler m_profiler;
|
||||||
TestbedListener m_profilerListener;
|
TestbedListener m_profilerListener;
|
||||||
Test* m_test;
|
Test* m_test;
|
||||||
|
bool m_setTest;
|
||||||
|
bool m_pause;
|
||||||
|
bool m_singlePlay;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void Model::Action_SelectTest(int selection)
|
inline void Model::Action_SetTest()
|
||||||
{
|
{
|
||||||
m_settings.testID = selection;
|
m_setTest = true;
|
||||||
m_settings.lastTestID = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_RestartTest()
|
|
||||||
{
|
|
||||||
m_settings.lastTestID = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_PreviousTest()
|
|
||||||
{
|
|
||||||
m_settings.testID = b3Clamp(m_settings.testID - 1, 0, int(g_testCount) - 1);
|
|
||||||
m_settings.lastTestID = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_NextTest()
|
|
||||||
{
|
|
||||||
m_settings.testID = b3Clamp(m_settings.testID + 1, 0, int(g_testCount) - 1);
|
|
||||||
m_settings.lastTestID = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_SaveTest()
|
|
||||||
{
|
|
||||||
m_test->Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Model::Action_PlayPause()
|
inline void Model::Action_PlayPause()
|
||||||
{
|
{
|
||||||
m_settings.pause = !m_settings.pause;
|
m_pause = !m_pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Model::Action_SingleStep()
|
inline void Model::Action_SinglePlay()
|
||||||
{
|
{
|
||||||
m_settings.pause = true;
|
m_pause = true;
|
||||||
m_settings.singleStep = true;
|
m_singlePlay = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Model::Action_DefaultCamera()
|
inline void Model::Action_ResetCamera()
|
||||||
{
|
{
|
||||||
m_camera.m_q = b3QuatRotationX(-0.125f * B3_PI);
|
m_camera.m_q = b3QuatRotationX(-0.125f * B3_PI);
|
||||||
|
|
||||||
@ -157,79 +98,6 @@ inline void Model::Action_DefaultCamera()
|
|||||||
m_camera.m_zoom = 50.0f;
|
m_camera.m_zoom = 50.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Model::Action_LeftCamera()
|
|
||||||
{
|
|
||||||
m_camera.m_q = b3QuatRotationX(0.5f * B3_PI);
|
|
||||||
m_camera.m_center.SetZero();
|
|
||||||
m_camera.m_zoom = 50.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_RightCamera()
|
|
||||||
{
|
|
||||||
m_camera.m_q = b3QuatRotationX(-0.5f * B3_PI);
|
|
||||||
m_camera.m_center.SetZero();
|
|
||||||
m_camera.m_zoom = 50.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_BottomCamera()
|
|
||||||
{
|
|
||||||
m_camera.m_q = b3QuatRotationX(0.5f * B3_PI);
|
|
||||||
m_camera.m_center.SetZero();
|
|
||||||
m_camera.m_zoom = 50.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_TopCamera()
|
|
||||||
{
|
|
||||||
m_camera.m_q = b3QuatRotationX(-0.5f * B3_PI);
|
|
||||||
m_camera.m_center.SetZero();
|
|
||||||
m_camera.m_zoom = 50.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_BackCamera()
|
|
||||||
{
|
|
||||||
m_camera.m_q = b3QuatRotationX(-B3_PI);
|
|
||||||
m_camera.m_center.SetZero();
|
|
||||||
m_camera.m_zoom = 50.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Action_FrontCamera()
|
|
||||||
{
|
|
||||||
m_camera.m_q.SetIdentity();
|
|
||||||
m_camera.m_center.SetZero();
|
|
||||||
m_camera.m_zoom = 50.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Command_Press_Key(int button)
|
|
||||||
{
|
|
||||||
m_test->KeyDown(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Command_Release_Key(int button)
|
|
||||||
{
|
|
||||||
m_test->KeyUp(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Command_Press_Mouse_Left(const b3Vec2& ps)
|
|
||||||
{
|
|
||||||
Ray3 pw = m_camera.ConvertScreenToWorld(ps);
|
|
||||||
|
|
||||||
m_test->MouseLeftDown(pw);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Command_Release_Mouse_Left(const b3Vec2& ps)
|
|
||||||
{
|
|
||||||
Ray3 pw = m_camera.ConvertScreenToWorld(ps);
|
|
||||||
|
|
||||||
m_test->MouseLeftUp(pw);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Command_Move_Cursor(const b3Vec2& ps)
|
|
||||||
{
|
|
||||||
Ray3 pw = m_camera.ConvertScreenToWorld(ps);
|
|
||||||
|
|
||||||
m_test->MouseMove(pw);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Model::Command_ResizeCamera(float32 w, float32 h)
|
inline void Model::Command_ResizeCamera(float32 w, float32 h)
|
||||||
{
|
{
|
||||||
m_camera.m_width = w;
|
m_camera.m_width = w;
|
||||||
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <testbed/framework/presenter.h>
|
|
||||||
#include <testbed/framework/model.h>
|
|
||||||
#include <testbed/framework/view.h>
|
|
||||||
|
|
||||||
// !
|
|
||||||
static inline b3Vec2 GetCursorPosition()
|
|
||||||
{
|
|
||||||
extern GLFWwindow* g_window;
|
|
||||||
|
|
||||||
double x, y;
|
|
||||||
glfwGetCursorPos(g_window, &x, &y);
|
|
||||||
|
|
||||||
return b3Vec2(float32(x), float32(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
Presenter::Presenter(Model* model, View* view)
|
|
||||||
{
|
|
||||||
m_model = model;
|
|
||||||
m_view = view;
|
|
||||||
}
|
|
||||||
|
|
||||||
Presenter::~Presenter()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::Event_SetWindowSize(float w, float h)
|
|
||||||
{
|
|
||||||
m_model->Command_ResizeCamera(w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::Event_Press_Key(int button)
|
|
||||||
{
|
|
||||||
if (m_view->m_shiftDown)
|
|
||||||
{
|
|
||||||
if (button == GLFW_KEY_DOWN)
|
|
||||||
{
|
|
||||||
m_model->Command_ZoomCamera(1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button == GLFW_KEY_UP)
|
|
||||||
{
|
|
||||||
m_model->Command_ZoomCamera(-1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_model->Command_Press_Key(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::Event_Release_Key(int button)
|
|
||||||
{
|
|
||||||
if (!m_view->m_shiftDown)
|
|
||||||
{
|
|
||||||
m_model->Command_Release_Key(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::Event_Press_Mouse(int button)
|
|
||||||
{
|
|
||||||
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
|
||||||
{
|
|
||||||
if (!m_view->m_shiftDown)
|
|
||||||
{
|
|
||||||
m_model->Command_Press_Mouse_Left(GetCursorPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::Event_Release_Mouse(int button)
|
|
||||||
{
|
|
||||||
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
|
||||||
{
|
|
||||||
if (!m_view->m_shiftDown)
|
|
||||||
{
|
|
||||||
m_model->Command_Release_Mouse_Left(GetCursorPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::Event_Move_Cursor(float x, float y)
|
|
||||||
{
|
|
||||||
b3Vec2 ps;
|
|
||||||
ps.Set(x, y);
|
|
||||||
|
|
||||||
b3Vec2 dp = ps - m_view->m_ps0;
|
|
||||||
|
|
||||||
float32 ndx = b3Clamp(dp.x, -1.0f, 1.0f);
|
|
||||||
float32 ndy = b3Clamp(dp.y, -1.0f, 1.0f);
|
|
||||||
|
|
||||||
if (m_view->m_shiftDown)
|
|
||||||
{
|
|
||||||
if (m_view->m_leftDown)
|
|
||||||
{
|
|
||||||
float32 ax = -0.005f * B3_PI * ndx;
|
|
||||||
float32 ay = -0.005f * B3_PI * ndy;
|
|
||||||
|
|
||||||
m_model->Command_RotateCameraY(ax);
|
|
||||||
m_model->Command_RotateCameraX(ay);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_view->m_rightDown)
|
|
||||||
{
|
|
||||||
float32 tx = 0.2f * ndx;
|
|
||||||
float32 ty = -0.2f * ndy;
|
|
||||||
|
|
||||||
m_model->Command_TranslateCameraX(tx);
|
|
||||||
m_model->Command_TranslateCameraY(ty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_model->Command_Move_Cursor(GetCursorPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Presenter::Event_Scroll(float dx, float dy)
|
|
||||||
{
|
|
||||||
if (m_view->m_shiftDown)
|
|
||||||
{
|
|
||||||
float32 ny = b3Clamp(dy, -1.0f, 1.0f);
|
|
||||||
m_model->Command_ZoomCamera(1.0f * ny);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PRESENTER_H
|
|
||||||
#define PRESENTER_H
|
|
||||||
|
|
||||||
class Model;
|
|
||||||
class View;
|
|
||||||
|
|
||||||
class Presenter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Presenter(Model* model, View* view);
|
|
||||||
|
|
||||||
~Presenter();
|
|
||||||
|
|
||||||
void Event_SetWindowSize(float w, float h);
|
|
||||||
void Event_Press_Key(int button);
|
|
||||||
void Event_Release_Key(int button);
|
|
||||||
void Event_Press_Mouse(int button);
|
|
||||||
void Event_Release_Mouse(int button);
|
|
||||||
void Event_Move_Cursor(float x, float y);
|
|
||||||
void Event_Scroll(float dx, float dy);
|
|
||||||
private:
|
|
||||||
friend class Model;
|
|
||||||
friend class View;
|
|
||||||
|
|
||||||
Model* m_model;
|
|
||||||
View* m_view;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -17,7 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <testbed/framework/test.h>
|
#include <testbed/framework/test.h>
|
||||||
#include <testbed/framework/model.h>
|
#include <testbed/framework/profiler.h>
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
extern u32 b3_allocCalls, b3_maxAllocCalls;
|
extern u32 b3_allocCalls, b3_maxAllocCalls;
|
||||||
extern u32 b3_gjkCalls, b3_gjkIters, b3_gjkMaxIters;
|
extern u32 b3_gjkCalls, b3_gjkIters, b3_gjkMaxIters;
|
||||||
@ -34,8 +35,6 @@ void b3PopProfileScope()
|
|||||||
g_profiler->PopEvent();
|
g_profiler->PopEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
TestSettings* g_testSettings = nullptr;
|
|
||||||
|
|
||||||
Test::Test() : m_bodyDragger(&m_bodyRay, &m_world)
|
Test::Test() : m_bodyDragger(&m_bodyRay, &m_world)
|
||||||
{
|
{
|
||||||
b3_allocCalls = 0;
|
b3_allocCalls = 0;
|
||||||
|
@ -20,13 +20,10 @@
|
|||||||
#define TEST_H
|
#define TEST_H
|
||||||
|
|
||||||
#include <glfw/glfw3.h>
|
#include <glfw/glfw3.h>
|
||||||
#include <imgui/imgui.h>
|
|
||||||
|
|
||||||
#include <bounce/bounce.h>
|
#include <bounce/bounce.h>
|
||||||
|
|
||||||
#include <testbed/framework/draw.h>
|
#include <testbed/framework/draw.h>
|
||||||
#include <testbed/framework/profiler.h>
|
#include <testbed/framework/view_model.h>
|
||||||
#include <testbed/framework/recorder_profiler.h>
|
|
||||||
|
|
||||||
inline float32 RandomFloat(float32 a, float32 b)
|
inline float32 RandomFloat(float32 a, float32 b)
|
||||||
{
|
{
|
||||||
@ -36,46 +33,6 @@ inline float32 RandomFloat(float32 a, float32 b)
|
|||||||
return a + r;
|
return a + r;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestSettings
|
|
||||||
{
|
|
||||||
TestSettings()
|
|
||||||
{
|
|
||||||
hertz = 60.0f;
|
|
||||||
inv_hertz = 1.0f / hertz;
|
|
||||||
velocityIterations = 8;
|
|
||||||
positionIterations = 2;
|
|
||||||
sleep = false;
|
|
||||||
warmStart = true;
|
|
||||||
convexCache = true;
|
|
||||||
drawCenterOfMasses = true;
|
|
||||||
drawShapes = true;
|
|
||||||
drawBounds = false;
|
|
||||||
drawJoints = true;
|
|
||||||
drawContactPoints = true;
|
|
||||||
drawContactNormals = false;
|
|
||||||
drawContactTangents = false;
|
|
||||||
drawContactPolygons = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float hertz, inv_hertz;
|
|
||||||
int velocityIterations;
|
|
||||||
int positionIterations;
|
|
||||||
bool sleep;
|
|
||||||
bool warmStart;
|
|
||||||
bool convexCache;
|
|
||||||
|
|
||||||
bool drawCenterOfMasses;
|
|
||||||
bool drawBounds;
|
|
||||||
bool drawShapes;
|
|
||||||
bool drawJoints;
|
|
||||||
bool drawContactPoints;
|
|
||||||
bool drawContactNormals;
|
|
||||||
bool drawContactTangents;
|
|
||||||
bool drawContactPolygons;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern TestSettings* g_testSettings;
|
|
||||||
|
|
||||||
class RayCastListener : public b3RayCastListener
|
class RayCastListener : public b3RayCastListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <testbed/framework/view.h>
|
#include <testbed/framework/view.h>
|
||||||
#include <testbed/framework/model.h>
|
#include <testbed/framework/view_model.h>
|
||||||
|
#include <testbed/framework/test.h>
|
||||||
|
|
||||||
|
#include <imgui/imgui.h>
|
||||||
#if defined (U_OPENGL_2)
|
#if defined (U_OPENGL_2)
|
||||||
#include <imgui/imgui_impl_glfw_gl2.h>
|
#include <imgui/imgui_impl_glfw_gl2.h>
|
||||||
#elif defined (U_OPENGL_4)
|
#elif defined (U_OPENGL_4)
|
||||||
@ -28,7 +30,7 @@
|
|||||||
|
|
||||||
#include <glfw/glfw3.h>
|
#include <glfw/glfw3.h>
|
||||||
|
|
||||||
static bool GetTestName(void* userData, int idx, const char** name)
|
static inline bool GetTestName(void* userData, int idx, const char** name)
|
||||||
{
|
{
|
||||||
assert(u32(idx) < g_testCount);
|
assert(u32(idx) < g_testCount);
|
||||||
*name = g_tests[idx].name;
|
*name = g_tests[idx].name;
|
||||||
@ -111,8 +113,9 @@ static inline void ImGui_GLFW_GL_RenderDrawData(ImDrawData* draw_data)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
View::View(GLFWwindow* window, Model* model) : m_presenter(model, this)
|
View::View(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
m_viewModel = nullptr;
|
||||||
m_window = window;
|
m_window = window;
|
||||||
|
|
||||||
// Create UI
|
// Create UI
|
||||||
@ -127,9 +130,6 @@ View::View(GLFWwindow* window, Model* model) : m_presenter(model, this)
|
|||||||
|
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
m_leftDown = false;
|
|
||||||
m_rightDown = false;
|
|
||||||
m_shiftDown = false;
|
|
||||||
m_ps0.SetZero();
|
m_ps0.SetZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,88 +141,60 @@ View::~View()
|
|||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b3Vec2 View::GetCursorPosition() const
|
||||||
|
{
|
||||||
|
double x, y;
|
||||||
|
glfwGetCursorPos(m_window, &x, &y);
|
||||||
|
return b3Vec2(float32(x), float32(y));
|
||||||
|
}
|
||||||
|
|
||||||
void View::Event_SetWindowSize(int w, int h)
|
void View::Event_SetWindowSize(int w, int h)
|
||||||
{
|
{
|
||||||
m_presenter.Event_SetWindowSize(float32(w), float32(h));
|
m_viewModel->Event_SetWindowSize(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Event_Press_Key(int button)
|
void View::Event_Press_Key(int button)
|
||||||
{
|
{
|
||||||
if (button == GLFW_KEY_LEFT_SHIFT)
|
m_viewModel->Event_Press_Key(button);
|
||||||
{
|
|
||||||
m_shiftDown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_presenter.Event_Press_Key(button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Event_Release_Key(int button)
|
void View::Event_Release_Key(int button)
|
||||||
{
|
{
|
||||||
if (button == GLFW_KEY_LEFT_SHIFT)
|
m_viewModel->Event_Release_Key(button);
|
||||||
{
|
|
||||||
m_shiftDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_presenter.Event_Release_Key(button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Event_Press_Mouse(int button)
|
void View::Event_Press_Mouse(int button)
|
||||||
{
|
{
|
||||||
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
m_viewModel->Event_Press_Mouse(button);
|
||||||
{
|
|
||||||
m_leftDown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button == GLFW_MOUSE_BUTTON_RIGHT)
|
|
||||||
{
|
|
||||||
m_rightDown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_presenter.Event_Press_Mouse(button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Event_Release_Mouse(int button)
|
void View::Event_Release_Mouse(int button)
|
||||||
{
|
{
|
||||||
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
m_viewModel->Event_Release_Mouse(button);
|
||||||
{
|
|
||||||
m_leftDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button == GLFW_MOUSE_BUTTON_RIGHT)
|
|
||||||
{
|
|
||||||
m_rightDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_presenter.Event_Release_Mouse(button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Event_Move_Cursor(float x, float y)
|
void View::Event_Move_Cursor(float x, float y)
|
||||||
{
|
{
|
||||||
b3Vec2 ps(x, y);
|
m_viewModel->Event_Move_Cursor(x, y);
|
||||||
|
m_ps0.Set(x, y);
|
||||||
m_presenter.Event_Move_Cursor(ps.x, ps.y);
|
|
||||||
|
|
||||||
m_ps0 = ps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Event_Scroll(float dx, float dy)
|
void View::Event_Scroll(float dx, float dy)
|
||||||
{
|
{
|
||||||
m_presenter.Event_Scroll(dx, dy);
|
m_viewModel->Event_Scroll(dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Command_PreDraw()
|
void View::BeginInterface()
|
||||||
{
|
{
|
||||||
ImGui_GLFW_GL_NewFrame();
|
ImGui_GLFW_GL_NewFrame();
|
||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Command_Draw()
|
void View::Interface()
|
||||||
{
|
{
|
||||||
Model* model = m_presenter.m_model;
|
Settings& settings = m_viewModel->m_settings;
|
||||||
Settings& settings = model->m_settings;
|
TestSettings& testSettings = m_viewModel->m_testSettings;
|
||||||
TestSettings& testSettings = model->m_testSettings;
|
|
||||||
Camera& camera = model->m_camera;
|
|
||||||
|
|
||||||
bool openControls = false;
|
bool openControls = false;
|
||||||
bool openAbout = false;
|
bool openAbout = false;
|
||||||
@ -232,7 +204,7 @@ void View::Command_Draw()
|
|||||||
{
|
{
|
||||||
if (ImGui::MenuItem("Save"))
|
if (ImGui::MenuItem("Save"))
|
||||||
{
|
{
|
||||||
model->Action_SaveTest();
|
m_viewModel->Action_SaveTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
@ -354,7 +326,7 @@ void View::Command_Draw()
|
|||||||
|
|
||||||
if (ImGui::Combo("##Test", &settings.testID, GetTestName, NULL, g_testCount, g_testCount))
|
if (ImGui::Combo("##Test", &settings.testID, GetTestName, NULL, g_testCount, g_testCount))
|
||||||
{
|
{
|
||||||
model->Action_SelectTest(settings.testID);
|
m_viewModel->Action_SetTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
@ -365,38 +337,38 @@ void View::Command_Draw()
|
|||||||
|
|
||||||
if (ImGui::Button("Previous", menuButtonSize))
|
if (ImGui::Button("Previous", menuButtonSize))
|
||||||
{
|
{
|
||||||
model->Action_PreviousTest();
|
m_viewModel->Action_PreviousTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Button("Next", menuButtonSize))
|
if (ImGui::Button("Next", menuButtonSize))
|
||||||
{
|
{
|
||||||
model->Action_NextTest();
|
m_viewModel->Action_NextTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (ImGui::Button("Play/Pause", menuButtonSize))
|
if (ImGui::Button("Play/Pause", menuButtonSize))
|
||||||
{
|
{
|
||||||
model->Action_PlayPause();
|
m_viewModel->Action_PlayPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Button("Single Step", menuButtonSize))
|
if (ImGui::Button("Single Play", menuButtonSize))
|
||||||
{
|
{
|
||||||
model->Action_SingleStep();
|
m_viewModel->Action_SinglePlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (ImGui::Button("Restart", menuButtonSize))
|
if (ImGui::Button("Restart", menuButtonSize))
|
||||||
{
|
{
|
||||||
model->Action_RestartTest();
|
m_viewModel->Action_SetTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (ImGui::Button("Reset Camera", menuButtonSize))
|
if (ImGui::Button("Reset Camera", menuButtonSize))
|
||||||
{
|
{
|
||||||
model->Action_DefaultCamera();
|
m_viewModel->Action_ResetCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
@ -406,8 +378,8 @@ void View::Command_Draw()
|
|||||||
|
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(ImVec2(camera.m_width - 250.0f, 40.0f));
|
ImGui::SetNextWindowPos(ImVec2(g_camera->m_width - 250.0f, 40.0f));
|
||||||
ImGui::SetNextWindowSize(ImVec2(250.0f, camera.m_height - 40.0f));
|
ImGui::SetNextWindowSize(ImVec2(250.0f, g_camera->m_height - 40.0f));
|
||||||
ImGui::Begin("Test Settings", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
|
ImGui::Begin("Test Settings", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
|
||||||
|
|
||||||
ImGui::PushItemWidth(-1.0f);
|
ImGui::PushItemWidth(-1.0f);
|
||||||
@ -430,7 +402,7 @@ void View::Command_Draw()
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::Command_PostDraw()
|
void View::EndInterface()
|
||||||
{
|
{
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
|
@ -20,17 +20,15 @@
|
|||||||
#define VIEW_H
|
#define VIEW_H
|
||||||
|
|
||||||
#include <bounce/common/math/vec2.h>
|
#include <bounce/common/math/vec2.h>
|
||||||
#include <testbed/framework/presenter.h>
|
|
||||||
|
|
||||||
struct GLFWwindow;
|
struct GLFWwindow;
|
||||||
|
|
||||||
class Model;
|
class ViewModel;
|
||||||
|
|
||||||
class View
|
class View
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
View(GLFWwindow* window, Model* model);
|
View(GLFWwindow* window);
|
||||||
|
|
||||||
~View();
|
~View();
|
||||||
|
|
||||||
void Event_SetWindowSize(int w, int h);
|
void Event_SetWindowSize(int w, int h);
|
||||||
@ -41,20 +39,18 @@ public:
|
|||||||
void Event_Move_Cursor(float x, float y);
|
void Event_Move_Cursor(float x, float y);
|
||||||
void Event_Scroll(float dx, float dy);
|
void Event_Scroll(float dx, float dy);
|
||||||
|
|
||||||
void Command_PreDraw();
|
void BeginInterface();
|
||||||
void Command_Draw();
|
void Interface();
|
||||||
void Command_PostDraw();
|
void EndInterface();
|
||||||
private:
|
private:
|
||||||
friend class Presenter;
|
friend class ViewModel;
|
||||||
|
|
||||||
Presenter m_presenter;
|
b3Vec2 GetCursorPosition() const;
|
||||||
|
|
||||||
|
ViewModel* m_viewModel;
|
||||||
|
|
||||||
GLFWwindow* m_window;
|
GLFWwindow* m_window;
|
||||||
bool m_leftDown;
|
|
||||||
bool m_rightDown;
|
|
||||||
bool m_shiftDown;
|
|
||||||
b3Vec2 m_ps0;
|
b3Vec2 m_ps0;
|
||||||
// Ray3 m_ray0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
192
examples/testbed/framework/view_model.cpp
Normal file
192
examples/testbed/framework/view_model.cpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <testbed/framework/view_model.h>
|
||||||
|
#include <testbed/framework/model.h>
|
||||||
|
#include <testbed/framework/view.h>
|
||||||
|
#include <testbed/framework/test.h>
|
||||||
|
#include <glfw/glfw3.h>
|
||||||
|
|
||||||
|
TestSettings* g_testSettings = nullptr;
|
||||||
|
Settings* g_settings = nullptr;
|
||||||
|
|
||||||
|
ViewModel::ViewModel(Model* model, View* view)
|
||||||
|
{
|
||||||
|
m_model = model;
|
||||||
|
assert(m_model->m_viewModel == nullptr);
|
||||||
|
m_model->m_viewModel = this;
|
||||||
|
|
||||||
|
m_view = view;
|
||||||
|
assert(m_view->m_viewModel == nullptr);
|
||||||
|
m_view->m_viewModel = this;
|
||||||
|
|
||||||
|
g_settings = &m_settings;
|
||||||
|
g_testSettings = &m_testSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewModel::~ViewModel()
|
||||||
|
{
|
||||||
|
g_settings = nullptr;
|
||||||
|
g_testSettings = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Action_SaveTest()
|
||||||
|
{
|
||||||
|
m_model->Action_SaveTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Action_SetTest()
|
||||||
|
{
|
||||||
|
m_model->Action_SetTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Action_PreviousTest()
|
||||||
|
{
|
||||||
|
m_settings.testID = b3Clamp(m_settings.testID - 1, 0, int(g_testCount) - 1);
|
||||||
|
m_model->Action_SetTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Action_NextTest()
|
||||||
|
{
|
||||||
|
m_settings.testID = b3Clamp(m_settings.testID + 1, 0, int(g_testCount) - 1);
|
||||||
|
m_model->Action_SetTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Action_PlayPause()
|
||||||
|
{
|
||||||
|
m_model->Action_PlayPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Action_SinglePlay()
|
||||||
|
{
|
||||||
|
m_model->Action_SinglePlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Action_ResetCamera()
|
||||||
|
{
|
||||||
|
m_model->Action_ResetCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Event_SetWindowSize(int w, int h)
|
||||||
|
{
|
||||||
|
m_model->Command_ResizeCamera(float32(w), float32(h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Event_Press_Key(int button)
|
||||||
|
{
|
||||||
|
bool shiftDown = glfwGetKey(m_view->m_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
|
||||||
|
if (shiftDown)
|
||||||
|
{
|
||||||
|
if (button == GLFW_KEY_DOWN)
|
||||||
|
{
|
||||||
|
m_model->Command_ZoomCamera(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button == GLFW_KEY_UP)
|
||||||
|
{
|
||||||
|
m_model->Command_ZoomCamera(-1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_model->Command_Press_Key(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Event_Release_Key(int button)
|
||||||
|
{
|
||||||
|
bool shiftDown = glfwGetKey(m_view->m_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
|
||||||
|
if (!shiftDown)
|
||||||
|
{
|
||||||
|
m_model->Command_Release_Key(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Event_Press_Mouse(int button)
|
||||||
|
{
|
||||||
|
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
bool shiftDown = glfwGetKey(m_view->m_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
|
||||||
|
if (!shiftDown)
|
||||||
|
{
|
||||||
|
m_model->Command_Press_Mouse_Left(m_view->GetCursorPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Event_Release_Mouse(int button)
|
||||||
|
{
|
||||||
|
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
bool shiftDown = glfwGetKey(m_view->m_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
|
||||||
|
if (!shiftDown)
|
||||||
|
{
|
||||||
|
m_model->Command_Release_Mouse_Left(m_view->GetCursorPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Event_Move_Cursor(float x, float y)
|
||||||
|
{
|
||||||
|
b3Vec2 ps;
|
||||||
|
ps.Set(x, y);
|
||||||
|
|
||||||
|
b3Vec2 dp = ps - m_view->m_ps0;
|
||||||
|
|
||||||
|
float32 ndx = b3Clamp(dp.x, -1.0f, 1.0f);
|
||||||
|
float32 ndy = b3Clamp(dp.y, -1.0f, 1.0f);
|
||||||
|
|
||||||
|
bool shiftDown = glfwGetKey(m_view->m_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
|
||||||
|
bool leftDown = glfwGetMouseButton(m_view->m_window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS;
|
||||||
|
bool rightDown = glfwGetMouseButton(m_view->m_window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS;
|
||||||
|
|
||||||
|
if (shiftDown)
|
||||||
|
{
|
||||||
|
if (leftDown)
|
||||||
|
{
|
||||||
|
float32 ax = -0.005f * B3_PI * ndx;
|
||||||
|
float32 ay = -0.005f * B3_PI * ndy;
|
||||||
|
|
||||||
|
m_model->Command_RotateCameraY(ax);
|
||||||
|
m_model->Command_RotateCameraX(ay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightDown)
|
||||||
|
{
|
||||||
|
float32 tx = 0.2f * ndx;
|
||||||
|
float32 ty = -0.2f * ndy;
|
||||||
|
|
||||||
|
m_model->Command_TranslateCameraX(tx);
|
||||||
|
m_model->Command_TranslateCameraY(ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_model->Command_Move_Cursor(m_view->GetCursorPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewModel::Event_Scroll(float dx, float dy)
|
||||||
|
{
|
||||||
|
bool shiftDown = glfwGetKey(m_view->m_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
|
||||||
|
if (shiftDown)
|
||||||
|
{
|
||||||
|
float32 ny = b3Clamp(dy, -1.0f, 1.0f);
|
||||||
|
m_model->Command_ZoomCamera(1.0f * ny);
|
||||||
|
}
|
||||||
|
}
|
127
examples/testbed/framework/view_model.h
Normal file
127
examples/testbed/framework/view_model.h
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VIEW_MODEL_H
|
||||||
|
#define VIEW_MODEL_H
|
||||||
|
|
||||||
|
class Model;
|
||||||
|
class View;
|
||||||
|
|
||||||
|
//
|
||||||
|
struct Settings
|
||||||
|
{
|
||||||
|
Settings()
|
||||||
|
{
|
||||||
|
testID = 0;
|
||||||
|
drawPoints = true;
|
||||||
|
drawLines = true;
|
||||||
|
drawTriangles = true;
|
||||||
|
drawGrid = true;
|
||||||
|
drawProfile = false;
|
||||||
|
drawStats = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testID;
|
||||||
|
|
||||||
|
bool drawPoints;
|
||||||
|
bool drawLines;
|
||||||
|
bool drawTriangles;
|
||||||
|
bool drawGrid;
|
||||||
|
bool drawProfile;
|
||||||
|
bool drawStats;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
extern Settings* g_settings;
|
||||||
|
|
||||||
|
//
|
||||||
|
struct TestSettings
|
||||||
|
{
|
||||||
|
TestSettings()
|
||||||
|
{
|
||||||
|
hertz = 60.0f;
|
||||||
|
inv_hertz = 1.0f / hertz;
|
||||||
|
velocityIterations = 8;
|
||||||
|
positionIterations = 2;
|
||||||
|
sleep = false;
|
||||||
|
warmStart = true;
|
||||||
|
convexCache = true;
|
||||||
|
drawCenterOfMasses = true;
|
||||||
|
drawShapes = true;
|
||||||
|
drawBounds = false;
|
||||||
|
drawJoints = true;
|
||||||
|
drawContactPoints = true;
|
||||||
|
drawContactNormals = false;
|
||||||
|
drawContactTangents = false;
|
||||||
|
drawContactPolygons = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float hertz, inv_hertz;
|
||||||
|
int velocityIterations;
|
||||||
|
int positionIterations;
|
||||||
|
bool sleep;
|
||||||
|
bool warmStart;
|
||||||
|
bool convexCache;
|
||||||
|
|
||||||
|
bool drawCenterOfMasses;
|
||||||
|
bool drawBounds;
|
||||||
|
bool drawShapes;
|
||||||
|
bool drawJoints;
|
||||||
|
bool drawContactPoints;
|
||||||
|
bool drawContactNormals;
|
||||||
|
bool drawContactTangents;
|
||||||
|
bool drawContactPolygons;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
extern TestSettings* g_testSettings;
|
||||||
|
|
||||||
|
class ViewModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ViewModel(Model* model, View* view);
|
||||||
|
|
||||||
|
~ViewModel();
|
||||||
|
|
||||||
|
void Action_SaveTest();
|
||||||
|
void Action_SetTest();
|
||||||
|
void Action_PreviousTest();
|
||||||
|
void Action_NextTest();
|
||||||
|
void Action_PlayPause();
|
||||||
|
void Action_SinglePlay();
|
||||||
|
void Action_ResetCamera();
|
||||||
|
|
||||||
|
void Event_SetWindowSize(int w, int h);
|
||||||
|
void Event_Press_Key(int button);
|
||||||
|
void Event_Release_Key(int button);
|
||||||
|
void Event_Press_Mouse(int button);
|
||||||
|
void Event_Release_Mouse(int button);
|
||||||
|
void Event_Move_Cursor(float x, float y);
|
||||||
|
void Event_Scroll(float dx, float dy);
|
||||||
|
private:
|
||||||
|
friend class Model;
|
||||||
|
friend class View;
|
||||||
|
|
||||||
|
Settings m_settings;
|
||||||
|
TestSettings m_testSettings;
|
||||||
|
|
||||||
|
Model* m_model;
|
||||||
|
View* m_view;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -269,7 +269,7 @@ solution (solution_name)
|
|||||||
|
|
||||||
examples_inc_dir .. "/testbed/framework/model.h",
|
examples_inc_dir .. "/testbed/framework/model.h",
|
||||||
examples_inc_dir .. "/testbed/framework/view.h",
|
examples_inc_dir .. "/testbed/framework/view.h",
|
||||||
examples_inc_dir .. "/testbed/framework/presenter.h",
|
examples_inc_dir .. "/testbed/framework/view_model.h",
|
||||||
|
|
||||||
examples_src_dir .. "/testbed/framework/test.h",
|
examples_src_dir .. "/testbed/framework/test.h",
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ solution (solution_name)
|
|||||||
|
|
||||||
examples_inc_dir .. "/testbed/framework/model.cpp",
|
examples_inc_dir .. "/testbed/framework/model.cpp",
|
||||||
examples_inc_dir .. "/testbed/framework/view.cpp",
|
examples_inc_dir .. "/testbed/framework/view.cpp",
|
||||||
examples_inc_dir .. "/testbed/framework/presenter.cpp",
|
examples_inc_dir .. "/testbed/framework/view_model.cpp",
|
||||||
|
|
||||||
examples_src_dir .. "/testbed/framework/test.cpp",
|
examples_src_dir .. "/testbed/framework/test.cpp",
|
||||||
examples_src_dir .. "/testbed/framework/test_entries.cpp",
|
examples_src_dir .. "/testbed/framework/test_entries.cpp",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user