00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include<cfloat>
00011
00012 #include "DEBUG.h"
00013 #include <engine.h>
00014 #include <uiMgr.h>
00015 #include <GraphicsInteractionManager.h>
00016
00017 #include <DebugDrawer.h>
00018
00019 #include <groupAI.h>
00020 #include <unitAI.h>
00021 #include <flock.h>
00022 #include <target.h>
00023 #include <command.h>
00024
00025 #include <commandHelp.h>
00026 #include <const.h>
00027 #include <enums.h>
00028
00029 #include <ent.h>
00030
00031 #include <creationMouseHandler.h>
00032 #include <controlGroupsHandler.h>
00033 #include "Rect.h"
00034 #include "HealthBar.h"
00035 #include <OgreEntity.h>
00036 #include <OGRE/OgreSubEntity.h>
00037
00038 OgreGFX::UIMgr::UIMgr(OgreGFX::GraphicsInteractionManager *gim) : GFXMgr(gim), OIS::KeyListener(), OIS::MouseListener(), bars(HealthBar(gim->mSceneMgr->createManualObject("manual"), 100.0f, true)), buttonActive(NULL), ghostUnderMouse(NULL)
00039 {
00040 shutDown = false;
00041 selectionDistanceSquaredThreshold = 10000;
00042 camera = gfx->mCamera;
00043 renderWindow = gfx->mWindow;
00044 sceneManager = gfx->mSceneMgr;
00045 createInputSystem();
00046
00047 cameraMgr = new OgreGFX::CameraMgr(gfx);
00048
00049 selectionBox = new OgreGFX::SelectionBox("SelectionBox");
00050 sceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(selectionBox);
00051 volQuery = sceneManager->createPlaneBoundedVolumeQuery(Ogre::PlaneBoundedVolumeList());
00052 rayDistanceForVolume = 10;
00053 selectingNow = false;
00054 volumeSelectingNow = false;
00055
00056 clearModifiersDown();
00057
00058
00059 new DebugDrawer(gfx->mSceneMgr, 0.5f);
00060 this->posUnderMouse = Ogre::Vector3::NEGATIVE_UNIT_Y;
00061 sceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(bars.emptyBar->mObj);
00062
00063 }
00064
00065 void OgreGFX::UIMgr::initialize()
00066 {
00067 DEBUG(std::cout << "Calling uiMgr initializer" << std::endl;)
00068
00069 mouse->setEventCallback(this);
00070 keyboard->setEventCallback(this);
00071
00072 std::set<OIS::KeyCode> *creationMods = new std::set<OIS::KeyCode > ();
00073 creationMods->insert(OIS::KC_LCONTROL);
00074 CreationMouseHandler *cmh = new CreationMouseHandler(this->gfx, creationMods);
00075 this->registerMouseHandler(creationMods, OIS::MB_Left, cmh);
00076 DEBUG(std::cout << "Registered creation mouse handler" << std::endl;)
00077
00078 controlGroupsHandler = new ControlGroupsHandler(gfx);
00079
00080 minimap = new Minimap(gfx);
00081
00082
00083 }
00084
00085 void OgreGFX::UIMgr::clearModifiersDown()
00086 {
00087 shiftDown = false;
00088 ctrlDown = false;
00089 altDown = false;
00090 }
00091
00092 void OgreGFX::UIMgr::createInputSystem()
00093 {
00094
00095 DEBUG(std::cout << "*** Initializing OIS ***" << std::endl;)
00096 OIS::ParamList pl;
00097 size_t windowHnd = 0;
00098 std::ostringstream windowHndStr;
00099
00100 renderWindow->getCustomAttribute("WINDOW", &windowHnd);
00101 windowHndStr << windowHnd;
00102 pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
00103
00104
00105 #if defined OIS_LINUX_PLATFORM
00106 pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
00107 pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
00108 pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
00109 pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
00110 #elif defined OIS_WIN32_PLATFORM
00111 pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
00112 pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCUSIVE")));
00113 pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
00114 pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
00115 #endif
00116
00117
00118 inputManager = OIS::InputManager::createInputSystem(pl);
00119
00120 keyboard = static_cast<OIS::Keyboard*> (inputManager->createInputObject(OIS::OISKeyboard, true));
00121 mouse = static_cast<OIS::Mouse*> (inputManager->createInputObject(OIS::OISMouse, true));
00122 mouse->capture();
00123 ms = mouse->getMouseState();
00124 ms.width = gfx->mWindow->getWidth();
00125 ms.height = gfx->mWindow->getHeight();
00126
00127
00128 windowResized(renderWindow);
00129
00130
00131 Ogre::WindowEventUtilities::addWindowEventListener(renderWindow, this);
00132
00133
00134 }
00135 void OgreGFX::UIMgr::CreateGhostUnderMouse(std::string meshName)
00136 {
00137 if (meshName != "")
00138 {
00139 Ogre::Entity* ent = this->gfx->mSceneMgr->createEntity(meshName);
00140 ent->setVisibilityFlags(OgreGFX::ENT_VISIBILITY_FLAG);
00141 for(int i = ent->getNumSubEntities()-1; i >= 0; i--)
00142 {
00143
00144 ent->getSubEntity(i)->setMaterial(ent->getSubEntity(i)->getMaterial()->clone(ent->getSubEntity(i)->getMaterialName() + ent->getName()));
00145 ent->getSubEntity(i)->getMaterial()->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
00146 ent->getSubEntity(i)->getMaterial()->setAmbient(0.5,0.5,0.5);
00147 ent->getSubEntity(i)->getMaterial()->setDepthWriteEnabled(false);
00148 ent->getSubEntity(i)->getMaterial()->setDiffuse(0.0,1.0,0.0,0.4);
00149 }
00150 ghostUnderMouse = this->gfx->mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0,0,0));
00151 ghostUnderMouse->attachObject(ent);
00152 }
00153
00154 }
00155 void OgreGFX::UIMgr::DestroyGhostUnderMouse(Ogre::SceneNode* node)
00156 {
00157 if(node != NULL)
00158 {
00159 this->gfx->mSceneMgr->destroyEntity(node->getAttachedObject(0)->getName());
00160 this->gfx->mSceneMgr->destroySceneNode(node);
00161 node = NULL;
00162 }
00163 }
00164
00165
00166 void OgreGFX::UIMgr::DebugDrawTest()
00167 {
00168 for (int i = 0; i < 5; ++i)
00169 {
00170 for (int j = 0; j < 5; j++)
00171 {
00172 for (int k = 0; k < 5; k++)
00173 {
00174 Ogre::AxisAlignedBox box(Ogre::Vector3(i * 10.0f + 2.0f, j * 10.0f + 2.0f, k * 10.0f + 2.0f),
00175 Ogre::Vector3((i + 1) * 10.0f - 2.0f, (j + 1) * 10.0f - 2.0f, (k + 1) * 10.0f - 2.0f));
00176 DebugDrawer::getSingleton().drawCuboid(box.getAllCorners(),
00177 Ogre::ColourValue(51.0f * i / 255.0f, 51.0f * j / 255.0f, 51.0f * k / 255.0f), true);
00178 }
00179 }
00180 }
00181
00182 }
00183
00184 bool OgreGFX::UIMgr::frameStarted(const Ogre::FrameEvent& evt)
00185 {
00186
00187
00188 decorateSelectedEntities();
00189 drawUnderMouseCircle();
00190
00191 DebugDrawer::getSingletonPtr()->build();
00192
00193 DEBUG(std::cout << renderWindow->getAverageFPS() << std::endl;)
00194 return true;
00195 }
00196
00197 bool OgreGFX::UIMgr::frameEnded(const Ogre::FrameEvent& evt)
00198 {
00199 DebugDrawer::getSingletonPtr()->clear();
00200 bars.ClearVertices();
00201
00202
00203
00204
00205
00206
00207
00208 return true;
00209 }
00210
00211 bool mouseDidScroll(int z)
00212 {
00213 return (z < -1.0 || z > 1.0);
00214 }
00215
00216 bool OgreGFX::UIMgr::frameRenderingQueued(const Ogre::FrameEvent& evt)
00217 {
00218 if (renderWindow->isClosed())
00219 return false;
00220
00221
00222 keyboard->capture();
00223 mouse->capture();
00224
00225 cameraMgr->frameRenderingQueued(evt);
00226 for(std::list<std::pair<std::deque<FastEcslent::Command*>, Ogre::SceneNode*> >::iterator it = waitingGhosts.begin(); it!= waitingGhosts.end(); it++)
00227 {
00228 bool commandWaiting = false;
00229 for(std::deque<FastEcslent::Command*>::iterator c = it->first.begin(); c != it->first.end() && !commandWaiting; c++)
00230 {
00231 for(std::deque<FastEcslent::Command*>::iterator entCommands = (*c)->entity->ai->commands.begin(); entCommands != (*c)->entity->ai->commands.end(); entCommands++)
00232 {
00233 if((*c) == (*entCommands))
00234 {
00235 commandWaiting = true;
00236 break;
00237 }
00238 }
00239 if(!commandWaiting)
00240 {
00241 it->first.pop_front();
00242 break;
00243 }
00244 }
00245 if(it->first.size() == 0)
00246 {
00247 DestroyGhostUnderMouse(it->second);
00248 waitingGhosts.erase(it);
00249 break;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 }
00259
00260 if(ghostUnderMouse != NULL)
00261 {
00262
00263
00264
00265
00266
00267
00268
00269
00270 IncreaseGhostAlpha(ghostUnderMouse,5);
00271 }
00272
00273
00274 return true;
00275 }
00276
00277 void OgreGFX::UIMgr::ChangeGhostTextureRBGA(Ogre::SceneNode* ghost, Ogre::ColourValue color)
00278 {
00279 if(ghost != NULL)
00280 {
00281 Ogre::Entity* ent = this->gfx->mSceneMgr->getEntity(ghost->getAttachedObject(0)->getName());
00282 for(int i = ent->getNumSubEntities()-1; i >= 0; i--)
00283 {
00284
00285
00286 ent->getSubEntity(i)->getMaterial()->setDiffuse(color);
00287 }
00288 }
00289
00290 }
00291
00292 Ogre::ColourValue OgreGFX::UIMgr::GetGhostTextureRBGA(Ogre::SceneNode* ghost)
00293 {
00294 if(ghost != NULL)
00295 {
00296 return this->gfx->mSceneMgr->getEntity(ghostUnderMouse->getAttachedObject(0)->getName())->getSubEntity(0)->getMaterial()->getTechnique(0)->getPass(0)->getDiffuse();
00297 }
00298
00299 }
00300
00301 void OgreGFX::UIMgr::IncreaseGhostAlpha(Ogre::SceneNode* ghost, int percentIncrease)
00302 {
00303 if(ghost != NULL)
00304 {
00305 Ogre::ColourValue color = GetGhostTextureRBGA(ghost);
00306 color.a = ((Ogre::Real)(( ((int)(color.a * 100)) + percentIncrease) % 100)) / 100.0;
00307 ChangeGhostTextureRBGA(ghost, color);
00308 }
00309
00310 }
00311
00312 void OgreGFX::UIMgr::checkSetModifiers(const OIS::KeyEvent &arg, bool value)
00313 {
00314 if (arg.key == OIS::KC_LSHIFT || arg.key == OIS::KC_RSHIFT)
00315 {
00316 shiftDown = value;
00317
00318 }
00319 else if (arg.key == OIS::KC_LCONTROL || arg.key == OIS::KC_RCONTROL)
00320 {
00321 ctrlDown = value;
00322
00323 }
00324 else if (arg.key == OIS::KC_LMENU || arg.key == OIS::KC_RMENU)
00325 {
00326 altDown = value;
00327
00328 }
00329
00330 }
00331
00332 bool OgreGFX::UIMgr::keyPressed(const OIS::KeyEvent &arg)
00333 {
00334 if (arg.key == OIS::KC_ESCAPE)
00335 {
00336 shutDown = true;
00337
00338 }
00339 DEBUG(std::cout << "Key pressed: " << arg.key << std::endl;)
00340 checkSetModifiers(arg, true);
00341
00342
00343
00344
00345
00346
00347
00348 cameraMgr->injectKeyDown(arg);
00349
00350
00351
00352
00353
00354 callKeyHandlers(arg);
00355 DEBUG(std::cout << "Control down is: " << ctrlDown << std::endl;)
00356 controlGroupsHandler->checkHandleControlGroupKeys(ctrlDown, arg.key);
00357
00358 return true;
00359 }
00360
00361 bool OgreGFX::UIMgr::keyReleased(const OIS::KeyEvent &arg)
00362 {
00363 checkSetModifiers(arg, false);
00364 cameraMgr->injectKeyUp(arg);
00365 return true;
00366 }
00367
00368 bool OgreGFX::UIMgr::mouseMoved(const OIS::MouseEvent &arg)
00369 {
00370 if (selectingNow)
00371 {
00372 volumeSelectingNow = true;
00373 ms = mouse->getMouseState();
00374 stopPos.x = ms.X.abs / (float) ms.width;
00375 stopPos.y = ms.Y.abs / (float) ms.height;
00376 selectionBox->setCorners(startPos, stopPos);
00377 }
00378 else if (mouseDidScroll(arg.state.Z.rel) && !arg.state.buttonDown(OIS::MB_Left) && !arg.state.buttonDown(OIS::MB_Right) && !arg.state.buttonDown(OIS::MB_Middle))
00379 {
00380 cameraMgr->handleMouseScrollCameraZoom(arg);
00381 }
00382 else if (ghostUnderMouse != NULL)
00383 {
00384 Ogre::Vector3 ghostPos = getMouseWorldPos(mouse->getMouseState()).second;
00385 Ogre::ColourValue ghostColour = GetGhostTextureRBGA(ghostUnderMouse);
00386 if(this->buttonActive != NULL && this->buttonActive->commandFactory!= NULL && this->buttonActive->commandFactory->requiredTarget == FastEcslent::TargetEntity)
00387 {
00388 std::pair<int, Ogre::Vector3> entUnderMouse = this->entIndexUnderMouse();
00389 if(entUnderMouse.first != -1 && (this->buttonActive->commandFactory->targetEntityType == FastEcslent::NENTITYTYPES || this->buttonActive->commandFactory->targetEntityType == this->gfx->gfxNodes[entUnderMouse.first].entType))
00390 {
00391 ghostPos = this->gfx->gfxNodes[entUnderMouse.first].node->getPosition();
00392 ghostColour = Ogre::ColourValue(0.0,1.0,0.0,ghostColour.a);
00393 }
00394 else
00395 {
00396 ghostColour = Ogre::ColourValue(1.0,0.0,0.0,ghostColour.a);
00397 }
00398 }
00399 ghostUnderMouse->setPosition(ghostPos);
00400 ChangeGhostTextureRBGA(ghostUnderMouse, ghostColour);
00401 }
00402
00403 this->gfx->widgetMgr->mouseOverButton(arg);
00404 return true;
00405 }
00406
00407
00408
00409 void OgreGFX::UIMgr::decorateSelectedEntities()
00410 {
00411 Ogre::Vector3 pos;
00412 Ogre::Vector3 start;
00413 Ogre::Vector3 end;
00414 float selectionCircleRadius = 100.0f;
00415 FastEcslent::Entity* ent;
00416 int entId;
00417 for (std::list<OgreGFX::GFXNode*>::iterator it = currentSelections.begin(); it != currentSelections.end(); ++it)
00418 {
00419 pos = (*it)->node->getPosition();
00420 Ogre::Vector3 cpos = Ogre::Vector3(pos.x, pos.y + 1, pos.z);
00421 selectionCircleRadius = gfx->engine->entityMgr->ents[(*it)->id]->length;
00422 DebugDrawer::getSingleton().drawCircle(cpos, selectionCircleRadius, FastEcslent::NCircleSegments, Ogre::ColourValue(0.5f, 0.5f, 0.9f, 0.2f), true);
00423
00424 entId = (*it)->id;
00425 ent = gfx->engine->entityMgr->ents[entId];
00426 start = ent->pos;
00427
00428 if (ent->entityClass != FastEcslent::STATIC)
00429 {
00430 float lineLength = ent->length * (1.0 + (ent->speed / ent->speedRange));
00431 DebugDrawer::getSingleton().drawAngleLine(cpos, Ogre::Radian(ent->heading), lineLength, Ogre::ColourValue(1.0f, 1.0f, 0.0f, 1.0));
00432 lineLength = ent->length * (1.0 + ent->desiredSpeed / ent->speedRange);
00433 DebugDrawer::getSingleton().drawAngleLine(cpos, Ogre::Radian(ent->desiredHeading), lineLength, Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.5));
00434 }
00435 Ogre::Vector3 leftPoint = Ogre::Vector3(cpos.x - FastEcslent::healthLineLength / 2, cpos.y, cpos.z - ent->length);
00436 Ogre::Vector3 rightPoint = Ogre::Vector3(cpos.x + FastEcslent::healthLineLength / 2, cpos.y, cpos.z - ent->length);
00437 DebugDrawer::getSingleton().drawLine(leftPoint, rightPoint, Ogre::ColourValue(1.0f, 0.0f, 0.0f, 0.5f));
00438 DEBUG(std::cout << "Hit points: " << ent->hitpoints << " Max Hit Points: " << gfx->engine->weaponMgr->maxHitpoints[ent->entityType] << std::endl;)
00439 float healthNow = FastEcslent::healthLineLength * ent->hitpoints / gfx->engine->weaponMgr->maxHitpoints[ent->entityType];
00440 rightPoint.x = leftPoint.x + healthNow;
00441 DebugDrawer::getSingleton().drawLine(leftPoint, rightPoint, Ogre::ColourValue(0.0f, 1.0f, 0.0f, 0.5f));
00442
00443
00444 bars.percent = 100.0 * (ent->hitpoints / gfx->engine->weaponMgr->maxHitpoints[ent->entityType]);
00445 bars.Draw(Ogre::Vector3(pos.x, pos.y + 1, pos.z - selectionCircleRadius));
00446
00447
00448
00449
00450
00451 }
00452
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 void OgreGFX::UIMgr::drawUnderMouseCircle()
00470 {
00471 Ogre::Vector3 pos;
00472 Ogre::Vector3 newPos;
00473 std::pair<int, Ogre::Vector3> underMouse;
00474 float radius;
00475 int id;
00476 underMouse = entIndexUnderMouse();
00477 if (underMouse.first >= 0 && underMouse.first < gfx->nGFXNodes)
00478 {
00479 DEBUG(std::cout << "Found an ent under mouse" << "\n";)
00480 id = gfx->gfxNodes[underMouse.first].id;
00481 pos = gfx->engine->entityMgr->ents[id]->pos;
00482 newPos = Ogre::Vector3(pos.x, pos.y + 1, pos.z);
00483 radius = gfx->engine->entityMgr->ents[id]->length;
00484 DebugDrawer::getSingleton().drawCircle(newPos, radius * 1.5, FastEcslent::NCircleSegments, Ogre::ColourValue(0.0f, 0.0f, 1.0f, 1.0f), false);
00485 }
00486 }
00487
00488 std::pair<int, Ogre::Vector3> OgreGFX::UIMgr::entIndexUnderMouse()
00489 {
00490 OIS::MouseState ms;
00491 ms = mouse->getMouseState();
00492 return entIndexUnderMouse(ms);
00493 }
00494
00495 std::pair<int, Ogre::Vector3> OgreGFX::UIMgr::entIndexUnderMouse(const OIS::MouseEvent &arg)
00496 {
00497 OIS::MouseState ms;
00498 ms = mouse->getMouseState();
00499 return entIndexUnderMouse(ms);
00500 }
00501
00502 std::pair<bool, Ogre::Vector3> OgreGFX::UIMgr::getMouseWorldPos(const OIS::MouseState &arg)
00503 {
00504 Ogre::Vector3 pos = Ogre::Vector3::NEGATIVE_UNIT_Y;
00505 Ogre::Ray mouseRay = camera->getCameraToViewportRay(arg.X.abs / (float) ms.width, arg.Y.abs / (float) ms.height);
00506
00507 std::pair<bool, float> result = mouseRay.intersects(gfx->oceanSurface);
00508 if (result.first)
00509 {
00510 pos = mouseRay.getPoint(result.second);
00511 }
00512
00513 return std::pair<bool, Ogre::Vector3 > (result.first, pos);
00514
00515 }
00516
00517 std::pair<int, Ogre::Vector3> OgreGFX::UIMgr::entIndexUnderMouse(const OIS::MouseState &arg)
00518 {
00519
00520 int index = -1;
00521 std::pair<bool, Ogre::Vector3> mousePos = getMouseWorldPos(arg);
00522
00523 Ogre::Ray mouseRay = camera->getCameraToViewportRay(arg.X.abs / (float) ms.width, arg.Y.abs / (float) ms.height);
00524
00525 std::pair<bool, float> result = mouseRay.intersects(gfx->oceanSurface);
00526 if (result.first)
00527 {
00528 this->posUnderMouse = mouseRay.getPoint(result.second);
00529
00530 float minDistanceSquared = FLT_MAX;
00531 float distanceSquared;
00532
00533 for (int i = 0; i < gfx->nGFXNodes; i++)
00534 {
00535 if (gfx->gfxNodes[i].selectable)
00536 {
00537 distanceSquared = this->posUnderMouse.squaredDistance(gfx->gfxNodes[i].node->getPosition());
00538 if (distanceSquared < selectionDistanceSquaredThreshold)
00539 {
00540 if (distanceSquared < minDistanceSquared)
00541 {
00542 index = i;
00543 minDistanceSquared = distanceSquared;
00544 }
00545 }
00546 }
00547 }
00548 }
00549 return std::pair<int, Ogre::Vector3 > (index, this->posUnderMouse);
00550 }
00551
00552 void OgreGFX::UIMgr::selectEntity(int index)
00553 {
00554 currentSelections.push_back(&gfx->gfxNodes[index]);
00555
00556
00557 }
00558
00559 void OgreGFX::UIMgr::handleSingleSelection(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
00560 {
00561
00562 if (volumeSelectingNow) return;
00563
00564 std::pair<int, Ogre::Vector3> result = entIndexUnderMouse(arg);
00565
00566 if(buttonActive != NULL)
00567 {
00568 buttonActive->handleMouseEvent(arg);
00569 }
00570 else
00571 {
00572 int index = result.first;
00573
00574 if (index >= 0 && index < gfx->nGFXNodes)
00575 {
00576 if (!shiftDown)
00577 {
00578 clearSelectionsAndUpdateFEEngine();
00579 }
00580 selectEntity(index);
00581
00582 }
00583 else
00584 {
00585 clearSelectionsAndUpdateFEEngine();
00586 }
00587 updateFEEngineWithSelections();
00588 }
00589 }
00590
00591 FastEcslent::Group* OgreGFX::UIMgr::groupFromSelections()
00592 {
00593
00594 FastEcslent::Entity * ents[FastEcslent::MaxEnts];
00595 int i = 0;
00596 for (std::list<OgreGFX::GFXNode*>::iterator it = currentSelections.begin(); it != currentSelections.end(); ++it)
00597 {
00598 ents[i++] = gfx->engine->entityMgr->ents[(*it)->id];
00599 }
00600 FastEcslent::Group* group = gfx->engine->groupMgr->createGroup(ents, i);
00601
00602
00603 return group;
00604 }
00605
00606 void OgreGFX::UIMgr::handleVolumeSelection(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
00607 {
00608
00609 startPos.x = arg.state.X.abs / (float) ms.width;
00610 startPos.y = arg.state.Y.abs / (float) ms.height;
00611 stopPos = startPos;
00612 selectingNow = true;
00613 selectionBox->clear();
00614 selectionBox->setVisible(true);
00615 }
00616
00617 void OgreGFX::UIMgr::printCurrentSelections()
00618 {
00619 for (std::list<OgreGFX::GFXNode*>::iterator it = currentSelections.begin(); it != currentSelections.end(); ++it)
00620 {
00621 DEBUG(std::cout << (*it)->id << ", ";)
00622 }
00623 DEBUG(std::cout << std::endl;)
00624
00625
00626
00627 DEBUG(std::cout << std::endl;)
00628 }
00629
00630 void OgreGFX::UIMgr::updateFEEngineWithSelections()
00631 {
00632 boost::mutex::scoped_lock scoped_lock(selectionUpdateLock);
00633 for (std::list<OgreGFX::GFXNode*>::iterator it = currentSelections.begin(); it != currentSelections.end(); ++it)
00634 {
00635 gfx->engine->selectionMgr->select((*it)->id);
00636 }
00637
00638 if (currentSelections.size() == 0 || gfx->engine->selectionMgr->getPrimarySelection()->entityId.player != gfx->engine->options.player || gfx->engine->selectionMgr->getPrimarySelection()->entityId.side != gfx->engine->options.side)
00639 {
00640 gfx->widgetMgr->deactivateMenu();
00641 }
00642 else
00643 {
00644 gfx->widgetMgr->activateMenu(gfx->engine->selectionMgr->getPrimarySelection());
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 }
00656
00657 void OgreGFX::UIMgr::clearSelectionsAndUpdateFEEngine()
00658 {
00659 boost::mutex::scoped_lock scoped_lock(selectionUpdateLock);
00660 for (std::list<OgreGFX::GFXNode*>::iterator it = currentSelections.begin(); it != currentSelections.end(); ++it)
00661 {
00662
00663 gfx->engine->selectionMgr->unselect((*it)->id);
00664 }
00665
00666 currentSelections.clear();
00667 }
00668
00669 void swap(float &x, float &y)
00670 {
00671 float tmp = x;
00672 x = y;
00673 y = tmp;
00674 }
00675
00676 void OgreGFX::UIMgr::doVolumeSelection(const Ogre::Vector2& first, const Ogre::Vector2& second)
00677 {
00678
00679 float left = first.x, right = second.x, top = first.y, bottom = second.y;
00680 if (left > right) swap(left, right);
00681 if (top > bottom) swap(top, bottom);
00682 if ((right - left) * (bottom - top) < 0.01) return;
00683
00684 Ogre::Ray topLeft = camera->getCameraToViewportRay(left, top);
00685 Ogre::Ray topRight = camera->getCameraToViewportRay(right, top);
00686 Ogre::Ray bottomLeft = camera->getCameraToViewportRay(left, bottom);
00687 Ogre::Ray bottomRight = camera->getCameraToViewportRay(right, bottom);
00688
00689 Ogre::PlaneBoundedVolume vol;
00690 vol.planes.push_back(Ogre::Plane(topLeft.getPoint(3), topRight.getPoint(3), bottomRight.getPoint(3)));
00691 vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), topLeft.getPoint(10), topRight.getPoint(10)));
00692 vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), bottomLeft.getPoint(10), topLeft.getPoint(10)));
00693 vol.planes.push_back(Ogre::Plane(bottomLeft.getOrigin(), bottomRight.getPoint(10), bottomLeft.getPoint(10)));
00694 vol.planes.push_back(Ogre::Plane(topRight.getOrigin(), topRight.getPoint(10), bottomRight.getPoint(10)));
00695
00696 Ogre::PlaneBoundedVolumeList volList;
00697 volList.push_back(vol);
00698
00699 volQuery->setVolumes(volList);
00700 Ogre::SceneQueryResult result = volQuery->execute();
00701 clearSelectionsAndUpdateFEEngine();
00702
00703 Ogre::SceneQueryResultMovableList::iterator iter;
00704 int n = result.movables.size();
00705
00706
00707
00708 DEBUG(std::cout << "Number of movables: " << n << std::endl;)
00709
00710 for (iter = result.movables.begin(); iter != result.movables.end(); ++iter)
00711 {
00712
00713
00714 if (gfx->sceneNodeToEntIdMap.find((*iter)->getParentSceneNode()) != gfx->sceneNodeToEntIdMap.end())
00715 {
00716 selectEntity(gfx->sceneNodeToEntIdMap[(*iter)->getParentSceneNode()]);
00717 }
00718 }
00719 updateFEEngineWithSelections();
00720 }
00721
00722
00723
00724
00725 void OgreGFX::UIMgr::CommandMaintainAttack(int i)
00726 {
00727 DEBUG(std::cout << "MaintainAttacking: (" << gfx->engine->entityMgr->ents[i]->uiname << ")" << std::endl;)
00728 }
00729
00730 void OgreGFX::UIMgr::CommandGatherOrPFMove(int i)
00731 {
00732 DEBUG(std::cout << "Gathing (" << gfx->engine->entityMgr->ents[i]->uiname << ")" << std::endl;)
00733 FastEcslent::Entity * ent;
00734 for (std::list<OgreGFX::GFXNode*>::iterator it = currentSelections.begin(); it != currentSelections.end(); ++it)
00735 {
00736 ent = gfx->engine->entityMgr->ents[(*it)->id];
00737 if (ent->entityClass == FastEcslent::STATIC)
00738 {
00739 continue;
00740 }else if (ent->entityType == FastEcslent::SCV){
00741 if(gfx->engine->entityMgr->ents[i]->entityType == FastEcslent::REFINERY){
00742 FastEcslent::Refinery* ref = dynamic_cast<FastEcslent::Refinery*>(gfx->engine->entityMgr->ents[i]);
00743 FastEcslent::setGatherForEnt(ent, ref->associatedOilField, shiftDown);
00744 }else{
00745 FastEcslent::setGatherForEnt(ent, gfx->engine->entityMgr->ents[i], shiftDown);
00746 }
00747 }else {
00748 FastEcslent::setPotentialMoveForEnt(ent, gfx->engine->entityMgr->ents[i]->pos, shiftDown);
00749 }
00750 }
00751 }
00752
00753 void OgreGFX::UIMgr::CommandPotentialFieldsMove(Ogre::Vector3 pos)
00754 {
00755 DEBUG(std::cout << "Potential Fields: Moving to: (" << pos.x << ", " << pos.z << ")" << std::endl;)
00756 FastEcslent::Entity * ent;
00757 for (std::list<OgreGFX::GFXNode*>::iterator it = currentSelections.begin(); it != currentSelections.end(); ++it)
00758 {
00759 ent = gfx->engine->entityMgr->ents[(*it)->id];
00760 if (ent->entityClass == FastEcslent::STATIC)
00761 {
00762 continue;
00763 }
00764 FastEcslent::setPotentialMoveForEnt(ent, pos, shiftDown);
00765 }
00766 }
00767
00768 void OgreGFX::UIMgr::CommandMove(Ogre::Vector3 pos)
00769 {
00770 DEBUG(std::cout << "Moving to: (" << pos.x << ", " << pos.z << ")" << std::endl;)
00771
00772 if (currentSelections.size() <= 0) return;
00773
00774 if (currentSelections.size() > 1)
00775 {
00776 FastEcslent::Group* group = groupFromSelections();
00777 for (int i = 0; i < group->nEntitiesInGroup; i++)
00778 {
00779 group->members[i]->ai->commands.clear();
00780 }
00781 group->setLeaderByIndex(0);
00782 FastEcslent::GroupAI* gai = new FastEcslent::GroupAI(group, FastEcslent::GROUPAI);
00783 FastEcslent::GroupTarget* gt = new FastEcslent::GroupTarget;
00784 gt->target.location = pos;
00785 FastEcslent::Flock* flock = new FastEcslent::Flock(group, gt);
00786
00787 DEBUG(std::cout << "Left Shift: " << shiftDown << std::endl;)
00788 if (shiftDown)
00789 {
00790 DEBUG(std::cout << "Adding flock" << std::endl;)
00791 FastEcslent::addMoveForEnt(gfx->engine->entityMgr->ents[currentSelections.front()->id], pos);
00792
00793 }
00794 else
00795 {
00796 FastEcslent::setMoveForEnt(gfx->engine->entityMgr->ents[currentSelections.front()->id], pos);
00797
00798 }
00799 group->addAspect(gai);
00800 }
00801 else
00802 {
00803 FastEcslent::Entity * ent = gfx->engine->entityMgr->ents[currentSelections.front()->id];
00804 boost::mutex::scoped_lock scoped_lock(selectionUpdateLock);
00805 FastEcslent::setPotentialMoveForEnt(ent, pos, shiftDown);
00806 }
00807 }
00808
00809 void OgreGFX::UIMgr::handleCommand(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
00810 {
00811 std::pair<int, Ogre::Vector3> result = entIndexUnderMouse(arg);
00812 int index = result.first;
00813
00814 if (index >= 0 && index < gfx->nGFXNodes)
00815 {
00816 if(gfx->engine->entityMgr->ents[index]->entityType == FastEcslent::MINERALS ||
00817 gfx->engine->entityMgr->ents[index]->entityType == FastEcslent::REFINERY){
00818 CommandGatherOrPFMove(index);
00819 }else{
00820 CommandMaintainAttack(index);
00821 }
00822 }
00823 else
00824 {
00825 CommandPotentialFieldsMove(result.second);
00826 }
00827 DEBUG(std::cout << "MousePos: " << getMouseWorldPos(arg.state).second << std::endl;)
00828 DEBUG(std::cout << "Game State: ";)
00829 for (int i = 0; i < this->gfx->engine->entityMgr->nEnts; i++)
00830 {
00831 DEBUG(std::cout << this->gfx->engine->entityMgr->ents[i]->entityType << "," << this->gfx->engine->entityMgr->ents[i]->pos.x << "," << this->gfx->engine->entityMgr->ents[i]->pos.y << "," << this->gfx->engine->entityMgr->ents[i]->pos.z << " || ";)
00832
00833 }
00834 DEBUG(std::cout << std::endl;)
00835
00836 }
00837
00838
00839 bool OgreGFX::UIMgr::mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
00840 {
00841 DEBUG(std::cout << "Input System: Mouse Pressed (" << arg.state.X.abs << ", " << arg.state.Y.abs << ")" << std::endl;)
00842 if (this->gfx->widgetMgr->mouseOverOverlay(arg)) return true;
00843 if (id == OIS::MB_Left)
00844 {
00845 handleSingleSelection(arg, id);
00846 handleVolumeSelection(arg, id);
00847 }
00848 else if (id == OIS::MB_Right)
00849 {
00850 handleCommand(arg, id);
00851 }
00852
00853 return true;
00854 }
00855
00856 bool OgreGFX::UIMgr::mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
00857 {
00858 if (id == OIS::MB_Left)
00859 {
00860 doVolumeSelection(startPos, stopPos);
00861 selectingNow = false;
00862 volumeSelectingNow = false;
00863 selectionBox->setVisible(false);
00864 }
00865 callMouseHandlers(arg, id);
00866 return true;
00867 }
00868
00869
00870
00871 bool OgreGFX::UIMgr::registerKeyHandler(const std::set<OIS::KeyCode> *modifiers, const OIS::KeyCode key, OgreGFX::KeyHandler *handler)
00872 {
00873 OgreGFX::KeySet keySet = OgreGFX::KeySet(modifiers, key);
00874 std::string keySetString = keySet.toString();
00875
00876 keyHandlers[keySetString].push_back(handler);
00877 return true;
00878 }
00879
00880 bool OgreGFX::UIMgr::registerMouseHandler(const std::set<OIS::KeyCode> *modifiers, const OIS::MouseButtonID buttonId, OgreGFX::MouseHandler *handler)
00881 {
00882 OgreGFX::MouseButtonKeySet mbKeySet = OgreGFX::MouseButtonKeySet(modifiers, buttonId);
00883 std::string mouseButtonKeySetString = mbKeySet.toString();
00884
00885 mouseHandlers[mouseButtonKeySetString].push_back(handler);
00886 return true;
00887 }
00888
00889
00890
00891 std::set<OIS::KeyCode> *OgreGFX::UIMgr::makeModifiersSet()
00892 {
00893 std::set<OIS::KeyCode> *mods = new std::set<OIS::KeyCode > ();
00894 if (shiftDown)
00895 mods->insert(OIS::KC_LSHIFT);
00896 if (altDown)
00897 mods->insert(OIS::KC_LMENU);
00898 if (ctrlDown)
00899 mods->insert(OIS::KC_LCONTROL);
00900 return mods;
00901 }
00902
00903 std::string OgreGFX::UIMgr::modifierKeyHash(const OIS::KeyCode keyCode)
00904 {
00905
00906 std::set<OIS::KeyCode> *mods = makeModifiersSet();
00907 OgreGFX::KeySet ks = OgreGFX::KeySet(mods, keyCode);
00908 return ks.toString();
00909 }
00910
00911 std::string OgreGFX::UIMgr::modifierKeyMouseHash(const OIS::MouseButtonID id)
00912 {
00913
00914 std::set<OIS::KeyCode> *mods = makeModifiersSet();
00915 OgreGFX::MouseButtonKeySet mbks = OgreGFX::MouseButtonKeySet(mods, id);
00916 return mbks.toString();
00917 }
00918
00919 bool OgreGFX::UIMgr::callKeyHandlers(const OIS::KeyEvent &arg)
00920 {
00921
00922 std::string keySetHash = modifierKeyHash(arg.key);
00923 if (this->keyHandlers.count(keySetHash) > 0)
00924 {
00925 for (std::list<KeyHandler *>::iterator khi = this->keyHandlers[keySetHash].begin(); khi != this->keyHandlers[keySetHash].end(); ++khi)
00926 {
00927 (*khi)->handleKeyEvent();
00928 }
00929
00930 return true;
00931 }
00932 return false;
00933 }
00934
00935 bool OgreGFX::UIMgr::callMouseHandlers(const OIS::MouseEvent &arg, const OIS::MouseButtonID id)
00936 {
00937
00938 std::string mouseButtonKeySetHash = modifierKeyMouseHash(id);
00939 if (this->mouseHandlers.count(mouseButtonKeySetHash) > 0)
00940 {
00941 for (std::list<MouseHandler *>::iterator mhi = this->mouseHandlers[mouseButtonKeySetHash].begin(); mhi != this->mouseHandlers[mouseButtonKeySetHash].end(); ++mhi)
00942 {
00943 (*mhi)->handleMouseEvent(arg);
00944 }
00945
00946 return true;
00947 }
00948 return false;
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 void OgreGFX::UIMgr::windowResized(Ogre::RenderWindow* rw)
00961 {
00962 unsigned int width, height, depth;
00963 int left, top;
00964 rw->getMetrics(width, height, depth, left, top);
00965
00966 const OIS::MouseState &ms = mouse->getMouseState();
00967 ms.width = width;
00968 ms.height = height;
00969 }
00970
00971 OgreGFX::UIMgr::~UIMgr()
00972 {
00973
00974 kill();
00975 }
00976
00977 void OgreGFX::UIMgr::kill()
00978 {
00979
00980
00981
00982
00983 if (selectionBox)
00984 {
00985
00986 }
00987
00988 delete DebugDrawer::getSingletonPtr();
00989
00990 if (cameraMgr)
00991 {
00992 delete cameraMgr;
00993 cameraMgr = 0;
00994 }
00995 if (inputManager)
00996 {
00997 inputManager->destroyInputObject(mouse);
00998 inputManager->destroyInputObject(keyboard);
00999
01000 OIS::InputManager::destroyInputSystem(inputManager);
01001 inputManager = 0;
01002 }
01003 if (renderWindow)
01004 {
01005 Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow, this);
01006
01007 }
01008
01009
01010 }
01011
01012 void OgreGFX::UIMgr::windowClosed(Ogre::RenderWindow* rw)
01013 {
01014
01015 if (rw == renderWindow)
01016 {
01017 kill();
01018 }
01019 }
01020
01021
01022
01023
01024