#include "renderable.h"
#include "preferencesystem.h"
-#include "generic/callback.h"
+#include "signal/signal.h"
#include "container/array.h"
#include "scenelib.h"
#include "render.h"
#include "timer.h"
-std::vector<Callback> g_cameraMoved_callbacks;
+Signal0 g_cameraMoved_callbacks;
-void AddCameraMovedCallback(const Callback& callback)
+void AddCameraMovedCallback(const SignalHandler& handler)
{
- g_cameraMoved_callbacks.push_back(callback);
+ g_cameraMoved_callbacks.connectLast(handler);
}
void CameraMovedNotify()
{
- std::for_each(g_cameraMoved_callbacks.begin(), g_cameraMoved_callbacks.end(), CallbackInvoke());
+ g_cameraMoved_callbacks();
}
struct camwindow_globals_private_t
{
int m_nMoveSpeed;
+ bool m_bCamLinkSpeed;
int m_nAngleSpeed;
bool m_bCamInverseMouse;
bool m_bCamDiscrete;
bool m_bCubicClipping;
+ bool m_showStats;
camwindow_globals_private_t() :
m_nMoveSpeed(100),
+ m_bCamLinkSpeed(true),
m_nAngleSpeed(3),
m_bCamInverseMouse(false),
m_bCamDiscrete(true),
- m_bCubicClipping(true)
+ m_bCubicClipping(true),
+ m_showStats(true)
{
}
Matrix4 projection;
Matrix4 modelview;
+ bool m_strafe; // true when in strafemode toggled by the ctrl-key
+ bool m_strafe_forward; // true when in strafemode by ctrl-key and shift is pressed for forward strafing
+
unsigned int movementflags; // movement flags
Timer m_keycontrol_timer;
guint m_keymove_handler;
void Camera_FreeMove(camera_t& camera, int dx, int dy)
{
- float dtime = 0.1f;
- if (g_camwindow_globals_private.m_bCamInverseMouse)
- camera.angles[CAMERA_PITCH] -= dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- else
- camera.angles[CAMERA_PITCH] += dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
+ // free strafe mode, toggled by the ctrl key with optional shift for forward movement
+ if(camera.m_strafe)
+ {
+ float strafespeed = 0.65f;
- camera.angles[CAMERA_YAW] += dx * dtime * g_camwindow_globals_private.m_nAngleSpeed;
+ if(g_camwindow_globals_private.m_bCamLinkSpeed)
+ {
+ strafespeed = (float)g_camwindow_globals_private.m_nMoveSpeed / 100;
+ }
- if (camera.angles[CAMERA_PITCH] > 90)
- camera.angles[CAMERA_PITCH] = 90;
- else if (camera.angles[CAMERA_PITCH] < -90)
- camera.angles[CAMERA_PITCH] = -90;
+ camera.origin -= camera.vright * strafespeed * dx;
+ if(camera.m_strafe_forward)
+ camera.origin += camera.vpn * strafespeed * dy;
+ else
+ camera.origin += camera.vup * strafespeed * dy;
+ }
+ else// free rotation
+ {
+ const float dtime = 0.1f;
+
+ if (g_camwindow_globals_private.m_bCamInverseMouse)
+ camera.angles[CAMERA_PITCH] -= dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
+ else
+ camera.angles[CAMERA_PITCH] += dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
+
+ camera.angles[CAMERA_YAW] += dx * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- if (camera.angles[CAMERA_YAW] >= 360)
- camera.angles[CAMERA_YAW] -=360;
- else if (camera.angles[CAMERA_YAW] <= 0)
- camera.angles[CAMERA_YAW] +=360;
+ if (camera.angles[CAMERA_PITCH] > 90)
+ camera.angles[CAMERA_PITCH] = 90;
+ else if (camera.angles[CAMERA_PITCH] < -90)
+ camera.angles[CAMERA_PITCH] = -90;
+
+ if (camera.angles[CAMERA_YAW] >= 360)
+ camera.angles[CAMERA_YAW] -=360;
+ else if (camera.angles[CAMERA_YAW] <= 0)
+ camera.angles[CAMERA_YAW] +=360;
+ }
Camera_updateModelview(camera);
Camera_Freemove_updateAxes(camera);
#define SPEED_MOVE 32
#define SPEED_TURN 22.5
+#define MIN_CAM_SPEED 10
+#define MAX_CAM_SPEED 610
+#define CAM_SPEED_STEP 50
void Camera_MoveForward_Discrete(camera_t& camera)
{
void Camera_motionDelta(int x, int y, unsigned int state, void* data)
{
- reinterpret_cast<camera_t*>(data)->m_mouseMove.motion_delta(x, y, state);
+ camera_t* cam = reinterpret_cast<camera_t*>(data);
+
+ cam->m_mouseMove.motion_delta(x, y, state);
+ cam->m_strafe = (state & GDK_CONTROL_MASK) != 0;
+
+ if(cam->m_strafe)
+ cam->m_strafe_forward = (state & GDK_SHIFT_MASK) != 0;
+ else
+ cam->m_strafe_forward = false;
}
class CamWnd
}
+
void CamWnd_Add_Handlers_Move(CamWnd& camwnd)
{
camwnd.m_selection_button_press_handler = g_signal_connect(G_OBJECT(camwnd.m_gl_widget), "button_press_event", G_CALLBACK(selection_button_press), camwnd.m_window_observer);
void CamWnd::EnableFreeMove()
{
-#if 0
- globalOutputStream() << "EnableFreeMove\n";
-#endif
+ //globalOutputStream() << "EnableFreeMove\n";
+
ASSERT_MESSAGE(!m_bFreeMove, "EnableFreeMove: free-move was already enabled");
m_bFreeMove = true;
Camera_clearMovementFlags(getCamera(), MOVE_ALL);
void CamWnd::DisableFreeMove()
{
-#if 0
- globalOutputStream() << "DisableFreeMove\n";
-#endif
+ //globalOutputStream() << "DisableFreeMove\n";
+
ASSERT_MESSAGE(m_bFreeMove, "DisableFreeMove: free-move was not enabled");
m_bFreeMove = false;
Camera_clearMovementFlags(getCamera(), MOVE_ALL);
==============
*/
+void ShowStatsToggle()
+{
+ g_camwindow_globals_private.m_showStats ^= 1;
+}
+typedef FreeCaller<ShowStatsToggle> ShowStatsToggleCaller;
+
+void ShowStatsExport(const BoolImportCallback& importer)
+{
+ importer(g_camwindow_globals_private.m_showStats);
+}
+typedef FreeCaller1<const BoolImportCallback&, ShowStatsExport> ShowStatsExportCaller;
+
+ShowStatsExportCaller g_show_stats_caller;
+BoolExportCallback g_show_stats_callback(g_show_stats_caller);
+ToggleItem g_show_stats(g_show_stats_callback);
+
void CamWnd::Cam_Draw()
{
glViewport(0, 0, m_Camera.width, m_Camera.height);
}
- unsigned int globalstate = RENDER_DEPTHTEST|RENDER_COLOURWRITE|RENDER_DEPTHWRITE|RENDER_ALPHATEST|RENDER_BLEND|RENDER_CULLFACE|RENDER_COLOUR|RENDER_OFFSETLINE;
+ unsigned int globalstate = RENDER_DEPTHTEST|RENDER_COLOURWRITE|RENDER_DEPTHWRITE|RENDER_ALPHATEST|RENDER_BLEND|RENDER_CULLFACE|RENDER_COLOURARRAY|RENDER_OFFSETLINE|RENDER_POLYGONSMOOTH|RENDER_LINESMOOTH|RENDER_FOG|RENDER_COLOURCHANGE;
switch (m_Camera.draw_mode)
{
case cd_wire:
glEnd();
}
- glRasterPos3f(1.0f, static_cast<float>(m_Camera.height) - 1.0f, 0.0f);
- extern const char* Renderer_GetStats();
- GlobalOpenGL().drawString(Renderer_GetStats());
+ if(g_camwindow_globals_private.m_showStats)
+ {
+ glRasterPos3f(1.0f, static_cast<float>(m_Camera.height) - 1.0f, 0.0f);
+ extern const char* Renderer_GetStats();
+ GlobalOpenGL().drawString(Renderer_GetStats());
- glRasterPos3f(1.0f, static_cast<float>(m_Camera.height) - 11.0f, 0.0f);
- extern const char* Cull_GetStats();
- GlobalOpenGL().drawString(Cull_GetStats());
+ glRasterPos3f(1.0f, static_cast<float>(m_Camera.height) - 11.0f, 0.0f);
+ extern const char* Cull_GetStats();
+ GlobalOpenGL().drawString(Cull_GetStats());
+ }
// bind back to the default texture so that we don't have problems
// elsewhere using/modifying texture maps between contexts
void CamWnd_constructToolbar(GtkToolbar* toolbar)
{
- toolbar_append_toggle_button(toolbar, "Cubic clip the camera view", "view_cubicclipping.bmp", "ToggleCubicClip");
+ toolbar_append_toggle_button(toolbar, "Cubic clip the camera view (\\)", "view_cubicclipping.bmp", "ToggleCubicClip");
}
void CamWnd_registerShortcuts()
{
command_connect_accelerator("TogglePreview");
}
+
+ command_connect_accelerator("CameraSpeedInc");
+ command_connect_accelerator("CameraSpeedDec");
}
void Camera_constructPreferences(PreferencesPage& page)
{
- page.appendSlider("Movement Speed", g_camwindow_globals_private.m_nMoveSpeed, TRUE, 0, 0, 100, 50, 300, 1, 10, 10);
+ page.appendSlider("Movement Speed", g_camwindow_globals_private.m_nMoveSpeed, TRUE, 0, 0, 100, MIN_CAM_SPEED, MAX_CAM_SPEED, 1, 10, 10);
+ page.appendCheckBox("", "Link strafe speed to movement speed", g_camwindow_globals_private.m_bCamLinkSpeed);
page.appendSlider("Rotation Speed", g_camwindow_globals_private.m_nAngleSpeed, TRUE, 0, 0, 3, 1, 180, 1, 10, 10);
page.appendCheckBox("", "Invert mouse vertical axis", g_camwindow_globals_private.m_bCamInverseMouse);
page.appendCheckBox(
typedef FreeCaller1<bool, CamWnd_Move_Discrete_Import> CamWndMoveDiscreteImportCaller;
+void CameraSpeed_increase()
+{
+ if(g_camwindow_globals_private.m_nMoveSpeed <= (MAX_CAM_SPEED - CAM_SPEED_STEP - 10))
+ {
+ g_camwindow_globals_private.m_nMoveSpeed += CAM_SPEED_STEP;
+ } else {
+ g_camwindow_globals_private.m_nMoveSpeed = MAX_CAM_SPEED - 10;
+ }
+}
+
+void CameraSpeed_decrease()
+{
+ if(g_camwindow_globals_private.m_nMoveSpeed >= (MIN_CAM_SPEED + CAM_SPEED_STEP))
+ {
+ g_camwindow_globals_private.m_nMoveSpeed -= CAM_SPEED_STEP;
+ } else {
+ g_camwindow_globals_private.m_nMoveSpeed = MIN_CAM_SPEED;
+ }
+}
+
/// \brief Initialisation for things that have the same lifespan as this module.
void CamWnd_Construct()
{
GlobalCommands_insert("TogglePreview", FreeCaller<CamWnd_TogglePreview>(), Accelerator(GDK_F3));
}
+ GlobalCommands_insert("CameraSpeedInc", FreeCaller<CameraSpeed_increase>(), Accelerator(GDK_KP_Add, (GdkModifierType)GDK_SHIFT_MASK));
+ GlobalCommands_insert("CameraSpeedDec", FreeCaller<CameraSpeed_decrease>(), Accelerator(GDK_KP_Subtract, (GdkModifierType)GDK_SHIFT_MASK));
+
GlobalShortcuts_insert("CameraForward", Accelerator(GDK_Up));
GlobalShortcuts_insert("CameraBack", Accelerator(GDK_Down));
GlobalShortcuts_insert("CameraLeft", Accelerator(GDK_Left));
GlobalShortcuts_insert("CameraFreeMoveLeft", Accelerator(GDK_Left));
GlobalShortcuts_insert("CameraFreeMoveRight", Accelerator(GDK_Right));
+ GlobalToggles_insert("ShowStats", ShowStatsToggleCaller(), ToggleItem::AddCallbackCaller(g_show_stats));
+
+ GlobalPreferenceSystem().registerPreference("ShowStats", BoolImportStringCaller(g_camwindow_globals_private.m_showStats), BoolExportStringCaller(g_camwindow_globals_private.m_showStats));
GlobalPreferenceSystem().registerPreference("MoveSpeed", IntImportStringCaller(g_camwindow_globals_private.m_nMoveSpeed), IntExportStringCaller(g_camwindow_globals_private.m_nMoveSpeed));
+ GlobalPreferenceSystem().registerPreference("CamLinkSpeed", BoolImportStringCaller(g_camwindow_globals_private.m_bCamLinkSpeed), BoolExportStringCaller(g_camwindow_globals_private.m_bCamLinkSpeed));
GlobalPreferenceSystem().registerPreference("AngleSpeed", IntImportStringCaller(g_camwindow_globals_private.m_nAngleSpeed), IntExportStringCaller(g_camwindow_globals_private.m_nAngleSpeed));
GlobalPreferenceSystem().registerPreference("CamInverseMouse", BoolImportStringCaller(g_camwindow_globals_private.m_bCamInverseMouse), BoolExportStringCaller(g_camwindow_globals_private.m_bCamInverseMouse));
GlobalPreferenceSystem().registerPreference("CamDiscrete", makeBoolStringImportCallback(CamWndMoveDiscreteImportCaller()), BoolExportStringCaller(g_camwindow_globals_private.m_bCamDiscrete));