1
#include "CEventManager.h"
3
#define PI2 (PI / 2.0f)
6
enum GUI_WINDOW_ID { TOOLBAR_EDIT_TRACK = 1,
14
CEventManager::CEventManager()
15
: m_device(NULL), m_camera(NULL), fRot(0.0f), m_previous_time(0), m_up(false), m_down(false), m_left(false), m_right(false),
16
m_r_down(false), m_x_prev(0), m_y_prev(0), m_x_cur(0), m_y_cur(0), m_x_diff(0), m_y_diff(0), m_radius(3.0f), m_mode(CM_SELECT),
17
m_dialog_edittrack(NULL), m_dialog_addtrain(NULL)
21
CEventManager::~CEventManager()
27
void CEventManager::SetDevice(IrrlichtDevice * pDevice, CTrackManager * track, CTrainManager * train, CGround * ground)
29
// Here we initialize a few things...
32
m_camera = pDevice->getSceneManager()->addCameraSceneNode();
34
// Set the camera's rotation, target, FOV, etc.
35
m_camera->bindTargetAndRotation(true);
36
m_camera->setPosition(vector3df(30,4,2));
37
m_camera->setTarget(vector3df(30,2,5));
38
m_camera->setFOV(PI / 3.5f);
39
m_camera->setAspectRatio(1.66f);
41
// Grab a copy of the device
45
// Grab a copy of the track manager
51
// Now start creating the GUI environment
52
IGUIEnvironment* pGUI = m_device->getGUIEnvironment();
59
m_straight_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/track_straight.b3d");
60
m_straight_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_straight_ghost);
62
m_curve_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/track_small_curve.b3d");
63
m_curve_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_curve_ghost);
65
m_engine_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/simple_engine_ghost.b3d");
66
m_engine_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_engine_ghost);
68
// Make them all invisible
69
m_straight_ghost_node->setVisible(false);
70
m_curve_ghost_node->setVisible(false);
71
m_engine_ghost_node->setVisible(false);
74
bool CEventManager::OnEvent(const SEvent& event)
76
// Switch on the event type
77
switch(event.EventType)
79
case EET_KEY_INPUT_EVENT:
81
// We do two seperate things here.
82
// If the key was held down, we process
83
// it in the following switch block
85
// See which key was pushed.
86
switch(event.KeyInput.Key)
89
m_up = event.KeyInput.PressedDown;
93
m_down = event.KeyInput.PressedDown;
97
m_left = event.KeyInput.PressedDown;
101
m_right = event.KeyInput.PressedDown;
108
// Otherwise, react to a key-up event
109
if(!event.KeyInput.PressedDown)
111
if(event.KeyInput.Key == KEY_RETURN)
113
if(m_mode == CM_PLACE_STRAIGHT_TRACK)
115
if(cur == TT_VERTICAL_STRAIGHT) cur = TT_HORIZONTAL_STRAIGHT;
116
else if(cur == TT_HORIZONTAL_STRAIGHT) cur = TT_VERTICAL_STRAIGHT;
118
if(m_mode == CM_PLACE_CURVE_TRACK)
120
if(cur == TT_CURVE_NE) cur = TT_CURVE_SE;
121
else if(cur == TT_CURVE_SE) cur = TT_CURVE_SW;
122
else if(cur == TT_CURVE_SW) cur = TT_CURVE_NW;
123
else if(cur == TT_CURVE_NW) cur = TT_CURVE_NE;
126
else if(event.KeyInput.Key == KEY_ESCAPE)
135
case EET_MOUSE_INPUT_EVENT:
137
// First, make sure that the coords
138
// do not confilct with the GUI
139
// Get the current values
140
m_x_cur = event.MouseInput.X;
141
m_y_cur = event.MouseInput.Y;
144
IGUIElement * root = m_device->getGUIEnvironment()->getRootGUIElement();
146
if(root != root->getElementFromPoint(position2d<s32>(m_x_cur,m_y_cur)))
148
m_device->getGUIEnvironment()->postEventFromUser(event);
154
// See which event was generated
155
switch(event.MouseInput.Event)
157
case EMIE_RMOUSE_PRESSED_DOWN:
160
// Also reset mousemove values
161
m_x_diff = m_y_diff = 0;
165
case EMIE_RMOUSE_LEFT_UP:
168
case EMIE_MOUSE_MOVED:
170
// Add the new offsets to the existing ones
171
m_x_diff += m_x_cur - m_x_prev;
172
m_y_diff += m_y_cur - m_y_prev;
174
// Now set the previous values
178
// Given the cursor position, calculate a ray
179
// that projects from the camera.
180
m_cursor_ray = m_device->getSceneManager()->
181
getSceneCollisionManager()->
182
getRayFromScreenCoordinates(position2d<s32>(m_x_cur,m_y_cur),
187
case EMIE_LMOUSE_LEFT_UP:
189
// Now we need to place the piece of track
190
// at the current place.
191
if(m_mode == CM_PLACE_STRAIGHT_TRACK || m_mode == CM_PLACE_CURVE_TRACK)
195
// Now place this piece
196
if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
197
m_track->SetPiece(cur,x,z);
199
else if(m_mode == CM_PLACE_TRAIN)
203
// Now place this train
204
if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
206
m_train->AddTrain(m_device, m_device->getTimer()->getTime(), x, z);
215
case EMIE_MOUSE_WHEEL:
218
float fChange = event.MouseInput.Wheel * 0.1f;
220
// Now calculate the amount to move the camera
221
// along the vector defined by the camera to target
222
vector3df v_target = m_camera->getTarget();
223
vector3df v_position = m_camera->getPosition();
225
float x_total = v_position.X - v_target.X;
226
float y_total = v_position.Y - v_target.Y;
227
float z_total = v_position.Z - v_target.Z;
229
// Calculate the amount to move along the vector
230
v_position.X -= x_total * fChange;
231
v_position.Y -= y_total * fChange;
232
v_position.Z -= z_total * fChange;
234
m_radius -= m_radius * fChange;
236
m_camera->setPosition(v_position);
250
switch(event.GUIEvent.EventType)
252
// This will be the case for the toolbar buttons
254
case EGET_BUTTON_CLICKED:
256
if(event.GUIEvent.Caller->getID() == TOOLBAR_EDIT_TRACK)
258
if(!m_dialog_edittrack)
260
// Show the track edit dialog
261
m_dialog_edittrack = m_device->getGUIEnvironment()->addWindow(rect<s32>(12,50,230,195), false, L"Edit Track");
263
// Put the buttons in the window
264
m_device->getGUIEnvironment()->addStaticText(L"Track type:", rect<s32>(10,35,100,52), false, false, m_dialog_edittrack);
265
IGUIButton * pStraight = m_device->getGUIEnvironment()->addButton(rect<s32>(10,55,74,119),m_dialog_edittrack,EDITTRACK_STRAIGHT);
266
IGUIButton * pCurved = m_device->getGUIEnvironment()->addButton(rect<s32>(80,55,144,119),m_dialog_edittrack,EDITTRACK_CURVED);
268
pStraight->setImage(m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/straight_track.png"));
269
pCurved->setImage(m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/curved_track.png"));
271
pStraight->setUseAlphaChannel(true);
272
pCurved->setUseAlphaChannel(true);
277
m_dialog_edittrack->remove();
278
m_dialog_edittrack = NULL;
281
else if(event.GUIEvent.Caller->getID() == TOOLBAR_ADD_TRAIN)
283
if(!m_dialog_addtrain)
285
// Show the add train dialog
286
m_dialog_addtrain = m_device->getGUIEnvironment()->addWindow(rect<s32>(12,50,230,195), false, L"Add Train");
288
m_device->getGUIEnvironment()->addStaticText(L"Engine:", rect<s32>(10,35,100,60), false, false, m_dialog_addtrain);
290
// At this point, we only have one engine
291
// so we only really need one entry in the
293
IGUIComboBox * pBox = m_device->getGUIEnvironment()->addComboBox(rect<s32>(8,58,210,83), m_dialog_addtrain);
295
pBox->addItem(L"Standard Diesel");
298
m_device->getGUIEnvironment()->addButton(rect<s32>(8,100,210,126),m_dialog_addtrain,ADDTRAIN_ADD,L"Add train...");
302
m_dialog_addtrain->remove();
303
m_dialog_addtrain = NULL;
306
else if(event.GUIEvent.Caller->getID() == EDITTRACK_STRAIGHT)
308
m_mode = CM_PLACE_STRAIGHT_TRACK;
310
cur = TT_VERTICAL_STRAIGHT;
313
else if(event.GUIEvent.Caller->getID() == EDITTRACK_CURVED)
315
m_mode = CM_PLACE_CURVE_TRACK;
320
else if(event.GUIEvent.Caller->getID() == ADDTRAIN_ADD)
322
m_mode = CM_PLACE_TRAIN;
326
m_dialog_addtrain->remove();
327
m_dialog_addtrain = NULL;
329
// Switch off the train dialog
330
IGUIButton * pButton = dynamic_cast<IGUIButton *>(m_toolbar->getElementFromId(TOOLBAR_ADD_TRAIN));
331
pButton->setPressed(false);
336
case EGET_ELEMENT_CLOSED:
338
// Set the mode and update the ghost items
342
// Depending on which dialog was closed, we
343
// may need to unhighlight a button
344
if(event.GUIEvent.Caller == m_dialog_edittrack)
346
IGUIButton * pButton = dynamic_cast<IGUIButton *>(m_toolbar->getElementFromId(TOOLBAR_EDIT_TRACK));
347
pButton->setPressed(false);
349
m_dialog_edittrack = NULL;
351
else if(event.GUIEvent.Caller == m_dialog_addtrain)
353
IGUIButton * pButton = dynamic_cast<IGUIButton *>(m_toolbar->getElementFromId(TOOLBAR_ADD_TRAIN));
354
pButton->setPressed(false);
356
m_dialog_addtrain = NULL;
375
void CEventManager::Process(u32 cur_time)
377
// Get the difference from the previous time
378
u32 diff = cur_time - m_previous_time;
380
// Now get the current position of everything
381
vector3df cur_pos = m_camera->getPosition();
382
vector3df cur_tar = m_camera->getTarget();
384
// Our rotation is increased everytime
385
// the left / right arrow keys are used
386
float fBefore = fRot;
389
fRot += (diff * 0.003f);
391
fRot -= (diff * 0.003f);
393
// Calculate the cos/sin of the before values
394
float bx = cosf(fBefore - PI2) * m_radius;
395
float bz = sinf(fBefore - PI2) * m_radius;
397
// Now for the new values
398
float ax = cosf(fRot - PI2) * m_radius;
399
float az = sinf(fRot - PI2) * m_radius;
401
// Now get the difference
402
cur_tar.X += bx - ax;
403
cur_tar.Z += bz - az;
407
// When the mouse is moved, we track
408
// the amount and move the target and
409
// camera accordingly.
411
// We need to make sure that the angle
412
// of rotation (about the Y-Axis) is
413
// taken into account here.
415
// Precalculated numbers
416
float xdiff = (m_x_diff * 0.01f * (m_radius / 3.0f));
417
float zdiff = (m_y_diff * 0.02f * (m_radius / 3.0f));
419
float xtrans = xdiff * cosf(fRot) + zdiff * sinf(fRot);
420
float ztrans = zdiff * cosf(fRot) + xdiff * sinf(fRot - PI);
427
m_x_diff = m_y_diff = 0;
430
m_camera->setPosition(cur_pos);
431
m_camera->setTarget(cur_tar);
433
// Deal with the track piece
434
if(m_mode == CM_PLACE_STRAIGHT_TRACK || m_mode == CM_PLACE_CURVE_TRACK)
437
if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
439
// Depending on what the current piece is...
440
float x_off = g_trackOrientationInfo[cur].fTrans_x;
441
float z_off = g_trackOrientationInfo[cur].fTrans_z;
443
float y_rot = g_trackOrientationInfo[cur].fRot_y;
445
if(cur <= TT_HORIZONTAL_STRAIGHT)
447
m_straight_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off));
448
m_straight_ghost_node->setRotation(vector3df(0,y_rot,0));
452
m_curve_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off));
453
m_curve_ghost_node->setRotation(vector3df(0,y_rot,0));
457
else if(m_mode == CM_PLACE_TRAIN)
461
if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
462
m_engine_ghost_node->setPosition(vector3df(x * 2.0f + 1.0f, 0.05, z * 2.0f + 1.0f));
465
m_previous_time = cur_time;
468
void CEventManager::CreateToolbar()
470
IGUIEnvironment* pGUI = m_device->getGUIEnvironment();
472
// Begin by creating the toolbar
473
m_toolbar = pGUI->addToolBar();
475
IGUIButton * pEditTrack = m_toolbar->addButton(TOOLBAR_EDIT_TRACK, NULL, NULL, m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/edit_track.png"), NULL, false, true);
476
IGUIButton * pAddTrain = m_toolbar->addButton(TOOLBAR_ADD_TRAIN, NULL, NULL, m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/add_train.png"), NULL, false, true);
478
pEditTrack->setIsPushButton(true);
479
pAddTrain->setIsPushButton(true);
482
void CEventManager::UpdateGhostItems()
484
m_straight_ghost_node->setVisible(m_mode == CM_PLACE_STRAIGHT_TRACK);
485
m_curve_ghost_node->setVisible(m_mode == CM_PLACE_CURVE_TRACK);
486
m_engine_ghost_node->setVisible(m_mode == CM_PLACE_TRAIN);