1 #include "CamWnd.h"
2
3 #include "iscenegraph.h"
4 #include "ieventmanager.h"
5 #include "iclipper.h"
6
7 #include <gdk/gdkkeysyms.h>
8
9 #include "gtkutil/glwidget.h"
10 #include "gtkutil/widget.h"
11 #include "gtkutil/GLWidgetSentry.h"
12
13 #include "../windowobservers.h"
14 #include "../plugin.h"
15 #include "../ui/mainframe/mainframe.h"
16 #include "../renderer.h"
17 #include "../render/RenderStatistics.h"
18
19 #include "CamRenderer.h"
20 #include "CameraSettings.h"
21 #include "GlobalCamera.h"
22
23 class ObjectFinder: public scene::Graph::Walker
24 {
25 scene::Instance*& _instance;
26 SelectionTest& _selectionTest;
27
28 // To store the best intersection candidate
29 mutable SelectionIntersection _bestIntersection;
30 public:
31 // Constructor
ObjectFinder(SelectionTest & test,scene::Instance * & instance)32 ObjectFinder (SelectionTest& test, scene::Instance*& instance) :
33 _instance(instance), _selectionTest(test)
34 {
35 _instance = NULL;
36 }
37
38 // The visitor function
pre(const scene::Path & path,scene::Instance & instance) const39 bool pre (const scene::Path& path, scene::Instance& instance) const
40 {
41 // Check if the node is filtered
42 if (path.top().get().visible()) {
43 SelectionTestable* selectionTestable = Instance_getSelectionTestable(instance);
44
45 if (selectionTestable != NULL) {
46 bool occluded;
47 OccludeSelector selector(_bestIntersection, occluded);
48 selectionTestable->testSelect(selector, _selectionTest);
49
50 if (occluded) {
51 _instance = &instance;
52 }
53 }
54 }
55
56 return true;
57 }
58 };
59
60
windowvector_for_widget_centre(GtkWidget * widget)61 inline WindowVector windowvector_for_widget_centre(GtkWidget* widget) {
62 return WindowVector(static_cast<float>(widget->allocation.width / 2), static_cast<float>(widget->allocation.height / 2));
63 }
64
65 class FloorHeightWalker : public scene::Graph::Walker
66 {
67 float m_current;
68 float& m_bestUp;
69 float& m_bestDown;
70
71 public:
FloorHeightWalker(float current,float & bestUp,float & bestDown)72 FloorHeightWalker(float current, float& bestUp, float& bestDown) :
73 m_current(current), m_bestUp(bestUp), m_bestDown(bestDown) {
74 bestUp = GlobalRegistry().getFloat("game/defaults/maxWorldCoord");
75 bestDown = -GlobalRegistry().getFloat("game/defaults/maxWorldCoord");
76 }
77
pre(const scene::Path & path,scene::Instance & instance) const78 bool pre(const scene::Path& path, scene::Instance& instance) const {
79 if (path.top().get().visible() && Node_isBrush(path.top())) // this node is a floor
80 {
81
82 const AABB& aabb = instance.worldAABB();
83
84 float floorHeight = aabb.origin.z() + aabb.extents.z();
85
86 if (floorHeight > m_current && floorHeight < m_bestUp) {
87 m_bestUp = floorHeight;
88 }
89
90 if (floorHeight < m_current && floorHeight > m_bestDown) {
91 m_bestDown = floorHeight;
92 }
93 }
94
95 return true;
96 }
97 };
98
99 // --------------- Callbacks ---------------------------------------------------------
100
selection_motion(gdouble x,gdouble y,guint state,void * data)101 static void selection_motion(gdouble x, gdouble y, guint state, void* data) {
102 //globalOutputStream() << "motion... ";
103 reinterpret_cast<WindowObserver*>(data)->onMouseMotion(WindowVector(x, y), state);
104 }
105
106 namespace {
107
camwnd_update_xor_rectangle(CamWnd & self,SelectionRectangle area)108 void camwnd_update_xor_rectangle(CamWnd& self, SelectionRectangle area) {
109 if (GTK_WIDGET_VISIBLE(self.m_gl_widget)) {
110 self.m_XORRectangle.set(rectangle_from_area(area.min, area.max, self.getCamera().width, self.getCamera().height));
111 }
112 }
113
114 }
115
camera_size_allocate(GtkWidget * widget,GtkAllocation * allocation,CamWnd * camwnd)116 gboolean CamWnd::camera_size_allocate(GtkWidget* widget, GtkAllocation* allocation, CamWnd* camwnd) {
117 camwnd->getCamera().width = allocation->width;
118 camwnd->getCamera().height = allocation->height;
119 camwnd->getCamera().updateProjection();
120 camwnd->m_window_observer->onSizeChanged(camwnd->getCamera().width, camwnd->getCamera().height);
121 camwnd->queueDraw();
122 return FALSE;
123 }
124
camera_expose(GtkWidget * widget,GdkEventExpose * event,gpointer data)125 gboolean CamWnd::camera_expose(GtkWidget* widget, GdkEventExpose* event, gpointer data) {
126 reinterpret_cast<CamWnd*>(data)->draw();
127 return FALSE;
128 }
129
Camera_motionDelta(int x,int y,unsigned int state,void * data)130 static void Camera_motionDelta(int x, int y, unsigned int state, void* data) {
131 Camera* cam = reinterpret_cast<Camera*>(data);
132
133 cam->m_mouseMove.motion_delta(x, y, state);
134 cam->m_strafe = GlobalEventManager().MouseEvents().strafeActive(state);
135
136 if (cam->m_strafe) {
137 cam->m_strafe_forward = GlobalEventManager().MouseEvents().strafeForwardActive(state);
138 } else {
139 cam->m_strafe_forward = false;
140 }
141 }
142
143 // greebo: The GTK Callback during freemove mode for mouseDown. Passes the call on to the Windowobserver
selection_button_press_freemove(GtkWidget * widget,GdkEventButton * event,WindowObserver * observer)144 gboolean CamWnd::selection_button_press_freemove(GtkWidget* widget, GdkEventButton* event, WindowObserver* observer) {
145 // Check for the correct event type
146 if (event->type == GDK_BUTTON_PRESS) {
147 observer->onMouseDown(windowvector_for_widget_centre(widget), event);
148 }
149 return FALSE;
150 }
151
152 // greebo: The GTK Callback during freemove mode for mouseUp. Passes the call on to the Windowobserver
selection_button_release_freemove(GtkWidget * widget,GdkEventButton * event,WindowObserver * observer)153 gboolean CamWnd::selection_button_release_freemove(GtkWidget* widget, GdkEventButton* event, WindowObserver* observer) {
154 if (event->type == GDK_BUTTON_RELEASE) {
155 observer->onMouseUp(windowvector_for_widget_centre(widget), event);
156 }
157 return FALSE;
158 }
159
160 // greebo: The GTK Callback during freemove mode for mouseMoved. Passes the call on to the Windowobserver
selection_motion_freemove(GtkWidget * widget,GdkEventMotion * event,WindowObserver * observer)161 gboolean CamWnd::selection_motion_freemove(GtkWidget *widget, GdkEventMotion *event, WindowObserver* observer) {
162 observer->onMouseMotion(windowvector_for_widget_centre(widget), event->state);
163 return FALSE;
164 }
165
166 // greebo: The GTK Callback during freemove mode for scroll events.
wheelmove_scroll(GtkWidget * widget,GdkEventScroll * event,CamWnd * camwnd)167 gboolean CamWnd::wheelmove_scroll(GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd) {
168
169 // Set the GTK focus to this widget
170 gtk_widget_grab_focus(widget);
171
172 // Determine the direction we are moving.
173 if (event->direction == GDK_SCROLL_UP) {
174 camwnd->getCamera().freemoveUpdateAxes();
175 camwnd->setCameraOrigin(camwnd->getCameraOrigin() + camwnd->getCamera().forward * static_cast<float>(getCameraSettings()->movementSpeed()));
176 }
177 else if (event->direction == GDK_SCROLL_DOWN) {
178 camwnd->getCamera().freemoveUpdateAxes();
179 camwnd->setCameraOrigin(camwnd->getCameraOrigin() + camwnd->getCamera().forward * (-static_cast<float>(getCameraSettings()->movementSpeed())));
180 }
181
182 return FALSE;
183 }
184
185 /* greebo: GTK Callback: This gets called on "button_press_event" and basically just passes the call on
186 * to the according window observer. */
selection_button_press(GtkWidget * widget,GdkEventButton * event,WindowObserver * observer)187 gboolean CamWnd::selection_button_press(GtkWidget* widget, GdkEventButton* event, WindowObserver* observer) {
188
189 // Set the GTK focus to this widget
190 gtk_widget_grab_focus(widget);
191
192 // Check for the correct event type
193 if (event->type == GDK_BUTTON_PRESS) {
194 observer->onMouseDown(WindowVector(event->x, event->y), event);
195 }
196 return FALSE;
197 }
198
199 /* greebo: GTK Callback: This gets called on "button_release_event" and basically just passes the call on
200 * to the according window observer. */
selection_button_release(GtkWidget * widget,GdkEventButton * event,WindowObserver * observer)201 gboolean CamWnd::selection_button_release(GtkWidget* widget, GdkEventButton* event, WindowObserver* observer) {
202 if (event->type == GDK_BUTTON_RELEASE) {
203 observer->onMouseUp(WindowVector(event->x, event->y), event);
204 }
205 return FALSE;
206 }
207
enable_freelook_button_press(GtkWidget * widget,GdkEventButton * event,CamWnd * camwnd)208 gboolean CamWnd::enable_freelook_button_press(GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd) {
209 if (event->type == GDK_BUTTON_PRESS) {
210
211 if (GlobalEventManager().MouseEvents().stateMatchesCameraViewEvent(ui::camEnableFreeLookMode, event)) {
212 camwnd->enableFreeMove();
213 return TRUE;
214 }
215 }
216 return FALSE;
217 }
218
disable_freelook_button_press(GtkWidget * widget,GdkEventButton * event,CamWnd * camwnd)219 gboolean CamWnd::disable_freelook_button_press(GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd) {
220 if (event->type == GDK_BUTTON_PRESS) {
221 if (GlobalEventManager().MouseEvents().stateMatchesCameraViewEvent(ui::camDisableFreeLookMode, event)) {
222 camwnd->disableFreeMove();
223 return TRUE;
224 }
225 }
226 return FALSE;
227 }
228
229 // ---------- CamWnd Implementation --------------------------------------------------
230
CamWnd()231 CamWnd::CamWnd() :
232 m_view(true),
233 m_Camera(&m_view, CamWndQueueDraw(*this)),
234 m_cameraview(m_Camera, &m_view, CamWndUpdate(*this)),
235 m_drawing(false),
236 _glWidget(true), m_gl_widget(static_cast<GtkWidget*>(_glWidget)),
237 m_window_observer(NewWindowObserver()),
238 m_XORRectangle(m_gl_widget),
239 m_deferredDraw(WidgetQueueDrawCaller(*m_gl_widget)),
240 m_deferred_motion(selection_motion, m_window_observer),
241 m_selection_button_press_handler(0),
242 m_selection_button_release_handler(0),
243 m_selection_motion_handler(0),
244 m_freelook_button_press_handler(0) {
245 m_bFreeMove = false;
246
247 GlobalWindowObservers_add(m_window_observer);
248 GlobalWindowObservers_connectWidget(m_gl_widget);
249
250 m_window_observer->setRectangleDrawCallback(ReferenceCaller1<CamWnd, SelectionRectangle, camwnd_update_xor_rectangle>(*this));
251 m_window_observer->setView(m_view);
252
253 gtk_widget_ref(m_gl_widget);
254
255 gtk_widget_set_events(m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
256 GTK_WIDGET_SET_FLAGS (m_gl_widget, GTK_CAN_FOCUS);
257 gtk_widget_set_size_request(m_gl_widget, CAMWND_MINSIZE_X, CAMWND_MINSIZE_Y);
258 g_object_set(m_gl_widget, "can-focus", TRUE, NULL);
259
260 m_sizeHandler = g_signal_connect(G_OBJECT(m_gl_widget), "size_allocate", G_CALLBACK(camera_size_allocate), this);
261 m_exposeHandler = g_signal_connect(G_OBJECT(m_gl_widget), "expose_event", G_CALLBACK(camera_expose), this);
262
263 GlobalMap().addValidCallback(DeferredDrawOnMapValidChangedCaller(m_deferredDraw));
264
265 // Deactivate all commands, just to make sure
266 disableDiscreteMoveEvents();
267 disableFreeMoveEvents();
268
269 // Now add the handlers for the non-freelook mode, the events are activated by this
270 addHandlersMove();
271
272 g_signal_connect(G_OBJECT(m_gl_widget), "scroll_event", G_CALLBACK(wheelmove_scroll), this);
273
274 GlobalSceneGraph().addSceneObserver(this);
275
276 GlobalEventManager().connect(GTK_OBJECT(m_gl_widget));
277 }
278
onSceneGraphChange()279 void CamWnd::onSceneGraphChange ()
280 {
281 update();
282 }
283
jumpToObject(SelectionTest & selectionTest)284 void CamWnd::jumpToObject(SelectionTest& selectionTest) {
285 // Find a suitable target Instance
286 scene::Instance* instance;
287 GlobalSceneGraph().traverse(ObjectFinder(selectionTest, instance));
288
289 if (instance != NULL) {
290 // An instance has been found, get the bounding box
291 AABB found = instance->worldAABB();
292
293 // Focuse the view at the center of the found AABB
294 GlobalMap().FocusViews(found.origin, getCameraAngles()[CAMERA_YAW]);
295 }
296 }
297
changeFloor(bool up)298 void CamWnd::changeFloor(bool up) {
299 float current = m_Camera.getOrigin()[2] - 48;
300 float bestUp;
301 float bestDown;
302 GlobalSceneGraph().traverse(FloorHeightWalker(current, bestUp, bestDown));
303
304 if (up && bestUp != GlobalRegistry().getFloat("game/defaults/maxWorldCoord")) {
305 current = bestUp;
306 }
307
308 if (!up && bestDown != -GlobalRegistry().getFloat("game/defaults/maxWorldCoord")) {
309 current = bestDown;
310 }
311
312 const Vector3& org = m_Camera.getOrigin();
313 m_Camera.setOrigin(Vector3(org[0], org[1], current + 48));
314
315 m_Camera.updateModelview();
316 update();
317 GlobalCamera().movedNotify();
318 }
319
320 // NOTE TTimo if there's an OS-level focus out of the application
321 // then we can release the camera cursor grab
camwindow_freemove_focusout(GtkWidget * widget,GdkEventFocus * event,gpointer data)322 static gboolean camwindow_freemove_focusout(GtkWidget* widget, GdkEventFocus* event, gpointer data) {
323 reinterpret_cast<CamWnd*>(data)->disableFreeMove();
324 return FALSE;
325 }
326
enableFreeMove()327 void CamWnd::enableFreeMove() {
328 ASSERT_MESSAGE(!m_bFreeMove, "EnableFreeMove: free-move was already enabled");
329 m_bFreeMove = true;
330 m_Camera.clearMovementFlags(MOVE_ALL);
331
332 removeHandlersMove();
333
334 m_selection_button_press_handler = g_signal_connect(G_OBJECT(m_gl_widget), "button_press_event", G_CALLBACK(selection_button_press_freemove), m_window_observer);
335 m_selection_button_release_handler = g_signal_connect(G_OBJECT(m_gl_widget), "button_release_event", G_CALLBACK(selection_button_release_freemove), m_window_observer);
336 m_selection_motion_handler = g_signal_connect(G_OBJECT(m_gl_widget), "motion_notify_event", G_CALLBACK(selection_motion_freemove), m_window_observer);
337 m_freelook_button_press_handler = g_signal_connect(G_OBJECT(m_gl_widget), "button_press_event", G_CALLBACK(disable_freelook_button_press), this);
338
339 enableFreeMoveEvents();
340
341 gtk_window_set_focus(m_parent, m_gl_widget);
342 m_freemove_handle_focusout = g_signal_connect(G_OBJECT(m_gl_widget), "focus_out_event", G_CALLBACK(camwindow_freemove_focusout), this);
343 m_freezePointer.freeze_pointer(m_parent, Camera_motionDelta, &m_Camera);
344
345 update();
346 }
347
disableFreeMove()348 void CamWnd::disableFreeMove() {
349 ASSERT_MESSAGE(m_bFreeMove, "DisableFreeMove: free-move was not enabled");
350 m_bFreeMove = false;
351 m_Camera.clearMovementFlags(MOVE_ALL);
352
353 disableFreeMoveEvents();
354
355 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_selection_button_press_handler);
356 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_selection_button_release_handler);
357 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_selection_motion_handler);
358 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_freelook_button_press_handler);
359
360 addHandlersMove();
361
362 m_freezePointer.unfreeze_pointer(m_parent);
363 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_freemove_handle_focusout);
364
365 update();
366 }
367
Cam_Draw()368 void CamWnd::Cam_Draw() {
369 glViewport(0, 0, m_Camera.width, m_Camera.height);
370
371 // enable depth buffer writes
372 glDepthMask(GL_TRUE);
373
374 Vector3 clearColour(0, 0, 0);
375 clearColour = ColourSchemes().getColourVector3("camera_background");
376
377 glClearColor(clearColour[0], clearColour[1], clearColour[2], 0);
378 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
379
380 render::RenderStatistics::Instance().resetStats();
381
382 Cull_ResetStats();
383
384 glMatrixMode(GL_PROJECTION);
385 glLoadMatrixf(m_Camera.projection);
386
387 glMatrixMode(GL_MODELVIEW);
388 glLoadMatrixf(m_Camera.modelview);
389
390 // one directional light source directly behind the viewer
391 {
392 GLfloat inverse_cam_dir[4], ambient[4], diffuse[4];//, material[4];
393
394 ambient[0] = ambient[1] = ambient[2] = 0.4f;
395 ambient[3] = 1.0f;
396 diffuse[0] = diffuse[1] = diffuse[2] = 0.4f;
397 diffuse[3] = 1.0f;
398
399 inverse_cam_dir[0] = m_Camera.vpn[0];
400 inverse_cam_dir[1] = m_Camera.vpn[1];
401 inverse_cam_dir[2] = m_Camera.vpn[2];
402 inverse_cam_dir[3] = 0;
403
404 glLightfv(GL_LIGHT0, GL_POSITION, inverse_cam_dir);
405
406 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
407 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
408
409 glEnable(GL_LIGHT0);
410 }
411
412 unsigned int globalstate = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_ALPHATEST
413 | RENDER_BLEND | RENDER_CULLFACE | RENDER_COLOURARRAY | RENDER_COLOURCHANGE;
414 switch (getCameraSettings()->getMode()) {
415 case drawWire:
416 break;
417 case drawSolid:
418 globalstate |= (RENDER_FILL | RENDER_LIGHTING | RENDER_SMOOTH | RENDER_SCALED);
419 break;
420 case drawTexture:
421 globalstate |= (RENDER_FILL | RENDER_LIGHTING | RENDER_TEXTURE_2D | RENDER_SMOOTH | RENDER_SCALED);
422 break;
423 default:
424 globalstate = 0;
425 break;
426 }
427
428 if (!getCameraSettings()->solidSelectionBoxes()) {
429 globalstate |= RENDER_LINESTIPPLE;
430 }
431
432 {
433 CamRenderer renderer(globalstate, m_state_select2, m_state_select1, m_view.getViewer());
434
435 Scene_Render(renderer, m_view);
436
437 renderer.render(m_Camera.modelview, m_Camera.projection);
438 }
439
440 // greebo: Draw the clipper's points (skipping the depth-test)
441 {
442 glDisable(GL_DEPTH_TEST);
443
444 glColor4f(1, 1, 1, 1);
445
446 glPointSize(5);
447
448 if (GlobalClipper().clipMode()) {
449 GlobalClipper().draw(1.0f);
450 }
451
452 glPointSize(1);
453 }
454
455 // prepare for 2d stuff
456 glColor4f(1, 1, 1, 1);
457 glDisable(GL_BLEND);
458 glMatrixMode(GL_PROJECTION);
459 glLoadIdentity();
460 glOrtho(0, (float) m_Camera.width, 0, (float) m_Camera.height, -100, 100);
461 glScalef(1, -1, 1);
462 glTranslatef(0, -(float) m_Camera.height, 0);
463 glMatrixMode(GL_MODELVIEW);
464 glLoadIdentity();
465
466 if (GlobalOpenGL().GL_1_3()) {
467 glClientActiveTexture(GL_TEXTURE0);
468 glActiveTexture(GL_TEXTURE0);
469 }
470
471 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
472 glDisableClientState(GL_NORMAL_ARRAY);
473 glDisableClientState(GL_COLOR_ARRAY);
474
475 glDisable(GL_TEXTURE_2D);
476 glDisable(GL_LIGHTING);
477 glDisable(GL_COLOR_MATERIAL);
478 glDisable(GL_DEPTH_TEST);
479 glLineWidth(1);
480
481 // draw the crosshair
482 if (m_bFreeMove) {
483 glBegin(GL_LINES);
484 glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f + 6);
485 glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f + 2);
486 glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f - 6);
487 glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f - 2);
488 glVertex2f((float) m_Camera.width / 2.f + 6, (float) m_Camera.height / 2.f);
489 glVertex2f((float) m_Camera.width / 2.f + 2, (float) m_Camera.height / 2.f);
490 glVertex2f((float) m_Camera.width / 2.f - 6, (float) m_Camera.height / 2.f);
491 glVertex2f((float) m_Camera.width / 2.f - 2, (float) m_Camera.height / 2.f);
492 glEnd();
493 }
494
495 glRasterPos3f(1.0f, static_cast<float> (m_Camera.height) - 1.0f, 0.0f);
496 GlobalOpenGL().drawString(render::RenderStatistics::Instance().getStatString());
497
498 glRasterPos3f(1.0f, static_cast<float> (m_Camera.height) - 11.0f, 0.0f);
499 GlobalOpenGL().drawString(Cull_GetStats());
500
501 // bind back to the default texture so that we don't have problems
502 // elsewhere using/modifying texture maps between contexts
503 glBindTexture(GL_TEXTURE_2D, 0);
504 }
505
draw()506 void CamWnd::draw() {
507 m_drawing = true;
508
509 gtkutil::GLWidgetSentry sentry(m_gl_widget);
510 if (GlobalMap().isValid() && ScreenUpdates_Enabled()) {
511 Cam_Draw();
512
513 m_XORRectangle.set(rectangle_t());
514 }
515
516 m_drawing = false;
517 }
518
~CamWnd()519 CamWnd::~CamWnd() {
520 // Subscribe to the global scene graph update
521 GlobalSceneGraph().removeSceneObserver(this);
522
523 if (m_bFreeMove) {
524 disableFreeMove();
525 }
526
527 removeHandlersMove();
528
529 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_sizeHandler);
530 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_exposeHandler);
531
532 gtk_widget_unref(m_gl_widget);
533
534 // Disconnect self from EventManager\r
535 GlobalEventManager().disconnect(GTK_OBJECT(m_gl_widget));
536 GlobalEventManager().disconnect(GTK_OBJECT(m_parent));
537
538 delete m_window_observer;
539 }
540
541 // ----------------------------------------------------------
542
enableFreeMoveEvents()543 void CamWnd::enableFreeMoveEvents() {
544 GlobalEventManager().enableEvent("CameraFreeMoveForward");
545 GlobalEventManager().enableEvent("CameraFreeMoveBack");
546 GlobalEventManager().enableEvent("CameraFreeMoveLeft");
547 GlobalEventManager().enableEvent("CameraFreeMoveRight");
548 GlobalEventManager().enableEvent("CameraFreeMoveUp");
549 GlobalEventManager().enableEvent("CameraFreeMoveDown");
550 }
551
disableFreeMoveEvents()552 void CamWnd::disableFreeMoveEvents() {
553 GlobalEventManager().disableEvent("CameraFreeMoveForward");
554 GlobalEventManager().disableEvent("CameraFreeMoveBack");
555 GlobalEventManager().disableEvent("CameraFreeMoveLeft");
556 GlobalEventManager().disableEvent("CameraFreeMoveRight");
557 GlobalEventManager().disableEvent("CameraFreeMoveUp");
558 GlobalEventManager().disableEvent("CameraFreeMoveDown");
559 }
560
enableDiscreteMoveEvents()561 void CamWnd::enableDiscreteMoveEvents() {
562 GlobalEventManager().enableEvent("CameraForward");
563 GlobalEventManager().enableEvent("CameraBack");
564 GlobalEventManager().enableEvent("CameraLeft");
565 GlobalEventManager().enableEvent("CameraRight");
566 GlobalEventManager().enableEvent("CameraStrafeRight");
567 GlobalEventManager().enableEvent("CameraStrafeLeft");
568 GlobalEventManager().enableEvent("CameraUp");
569 GlobalEventManager().enableEvent("CameraDown");
570 GlobalEventManager().enableEvent("CameraAngleUp");
571 GlobalEventManager().enableEvent("CameraAngleDown");
572 }
573
disableDiscreteMoveEvents()574 void CamWnd::disableDiscreteMoveEvents() {
575 GlobalEventManager().disableEvent("CameraForward");
576 GlobalEventManager().disableEvent("CameraBack");
577 GlobalEventManager().disableEvent("CameraLeft");
578 GlobalEventManager().disableEvent("CameraRight");
579 GlobalEventManager().disableEvent("CameraStrafeRight");
580 GlobalEventManager().disableEvent("CameraStrafeLeft");
581 GlobalEventManager().disableEvent("CameraUp");
582 GlobalEventManager().disableEvent("CameraDown");
583 GlobalEventManager().disableEvent("CameraAngleUp");
584 GlobalEventManager().disableEvent("CameraAngleDown");
585 }
586
addHandlersMove()587 void CamWnd::addHandlersMove() {
588 m_selection_button_press_handler = g_signal_connect(G_OBJECT(m_gl_widget), "button_press_event", G_CALLBACK(selection_button_press), m_window_observer);
589 m_selection_button_release_handler = g_signal_connect(G_OBJECT(m_gl_widget), "button_release_event", G_CALLBACK(selection_button_release), m_window_observer);
590 m_selection_motion_handler = g_signal_connect(G_OBJECT(m_gl_widget), "motion_notify_event", G_CALLBACK(DeferredMotion::gtk_motion), &m_deferred_motion);
591
592 m_freelook_button_press_handler = g_signal_connect(G_OBJECT(m_gl_widget), "button_press_event", G_CALLBACK(enable_freelook_button_press), this);
593
594 // Enable either the free-look movement commands or the discrete ones, depending on the selection
595 if (getCameraSettings()->discreteMovement()) {
596 enableDiscreteMoveEvents();
597 } else {
598 enableFreeMoveEvents();
599 }
600 }
601
removeHandlersMove()602 void CamWnd::removeHandlersMove() {
603 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_selection_button_press_handler);
604 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_selection_button_release_handler);
605 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_selection_motion_handler);
606
607 g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_freelook_button_press_handler);
608
609 // Disable either the free-look movement commands or the discrete ones, depending on the selection
610 if (getCameraSettings()->discreteMovement()) {
611 disableDiscreteMoveEvents();
612 } else {
613 disableFreeMoveEvents();
614 }
615 }
616
update()617 void CamWnd::update() {
618 queueDraw();
619 }
620
getCamera()621 Camera& CamWnd::getCamera() {
622 return m_Camera;
623 }
624
captureStates()625 void CamWnd::captureStates() {
626 m_state_select1 = GlobalShaderCache().capture("$CAM_HIGHLIGHT");
627 m_state_select2 = GlobalShaderCache().capture("$CAM_OVERLAY");
628 }
629
releaseStates()630 void CamWnd::releaseStates() {
631 GlobalShaderCache().release("$CAM_HIGHLIGHT");
632 GlobalShaderCache().release("$CAM_OVERLAY");
633 }
634
queueDraw()635 void CamWnd::queueDraw() {
636 if (m_drawing) {
637 return;
638 }
639
640 m_deferredDraw.draw();
641 }
642
getCameraOrigin() const643 const Vector3& CamWnd::getCameraOrigin () const {
644 return m_Camera.getOrigin();
645 }
646
setCameraOrigin(const Vector3 & origin)647 void CamWnd::setCameraOrigin (const Vector3& origin) {
648 m_Camera.setOrigin(origin);
649 }
650
getCameraAngles() const651 const Vector3& CamWnd::getCameraAngles () const {
652 return m_Camera.getAngles();
653 }
654
setCameraAngles(const Vector3 & angles)655 void CamWnd::setCameraAngles (const Vector3& angles) {
656 m_Camera.setAngles(angles);
657 }
658
cubicScaleIn()659 void CamWnd::cubicScaleIn ()
660 {
661 getCameraSettings()->setCubicScale( getCameraSettings()->cubicScale() - 1 );
662 m_Camera.updateProjection();
663 update();
664 }
665
cubicScaleOut()666 void CamWnd::cubicScaleOut ()
667 {
668 getCameraSettings()->setCubicScale( getCameraSettings()->cubicScale() + 1 );
669 m_Camera.updateProjection();
670 update();
671 }
672
getCameraView()673 CameraView* CamWnd::getCameraView() {
674 return &m_cameraview;
675 }
676
getWidget()677 GtkWidget* CamWnd::getWidget()
678 {
679 return m_gl_widget;
680 }
681
setParent(GtkWindow * parent)682 void CamWnd::setParent(GtkWindow* parent) {
683 m_parent = parent;
684 GlobalEventManager().connect(GTK_OBJECT(m_parent));
685 }
686
getParent()687 GtkWindow* CamWnd::getParent() {
688 return m_parent;
689 }
690
691 Shader* CamWnd::m_state_select1 = 0;
692 Shader* CamWnd::m_state_select2 = 0;
693