OgreBase.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #pragma once
  16. #include <Ogre.h>
  17. #include <OgreTextAreaOverlayElement.h>
  18. #include <OgreOverlay.h>
  19. #include <OgreOverlayManager.h>
  20. #include <Bites/OgreWindowEventUtilities.h>
  21. #include <OIS/OIS.h>
  22. #include "common/FileSystem.h"
  23. #include "Logger.h"
  24. /**
  25. * The Ogre system root component.
  26. */
  27. extern Ogre::Root* root;
  28. /**
  29. * The Ogre render window.
  30. */
  31. extern Ogre::RenderWindow* window;
  32. /**
  33. * List of Ogre entities.
  34. */
  35. extern std::vector<Ogre::Entity*> entities;
  36. /**
  37. * The Ogre camera.
  38. */
  39. extern Ogre::Camera* camera;
  40. class DisplayFrameListener;
  41. /**
  42. * The display frame listener.
  43. */
  44. extern DisplayFrameListener* frame_listener;
  45. /**
  46. * The display frame listener.
  47. *
  48. * It listens and responds to input events, such as window changes or mouse and
  49. * keyboard inputs.
  50. */
  51. class DisplayFrameListener :
  52. public Ogre::FrameListener, public Ogre::WindowEventListener,
  53. public OIS::KeyListener, public OIS::MouseListener
  54. {
  55. public:
  56. // Constructor takes a RenderWindow because it uses that to determine input context
  57. /**
  58. * Constructor.
  59. *
  60. * @param[in] win The render window. Used to determine input context.
  61. */
  62. DisplayFrameListener(Ogre::RenderWindow* win):
  63. window_(win), input_manager_(0), keyboard_(0),
  64. mouse_(0), mouse_rotate_(false), exit_(false)
  65. {
  66. using namespace OIS;
  67. Ogre::LogManager::getSingletonPtr()->logMessage("[OIS] Initializing...");
  68. ParamList pl;
  69. size_t window_hnd = 0; // TODO What does HND stand for?
  70. std::ostringstream window_hnd_str;
  71. win->getCustomAttribute("WINDOW", &window_hnd);
  72. window_hnd_str << window_hnd;
  73. pl.insert(std::make_pair(std::string("WINDOW"), window_hnd_str.str()));
  74. input_manager_ = InputManager::createInputSystem(pl);
  75. keyboard_ = static_cast<Keyboard*>(
  76. input_manager_->createInputObject(OIS::OISKeyboard, true)
  77. );
  78. keyboard_->setEventCallback(this);
  79. mouse_ = static_cast<OIS::Mouse*>(
  80. input_manager_->createInputObject(OIS::OISMouse, true)
  81. );
  82. mouse_->setEventCallback(this);
  83. //Register as a Window listener.
  84. Ogre::WindowEventUtilities::addWindowEventListener(window_, this);
  85. // Debug info.
  86. info_text = new Ogre::TextAreaOverlayElement("DebugText");
  87. info_text->setCaption("");
  88. info_text->setMetricsMode(Ogre::GMM_PIXELS);
  89. info_text->setPosition(5, 5);
  90. // info_text->setFontName("BlueHighway");
  91. info_text->setCharHeight(18);
  92. info_overlay = Ogre::OverlayManager::getSingleton().create("DebugOverlay");
  93. info_overlay->setZOrder(1);
  94. info_overlay->add2D((Ogre::OverlayContainer*) info_text);
  95. info_overlay->show();
  96. }
  97. virtual ~DisplayFrameListener(){
  98. input_manager_->destroyInputObject(keyboard_);
  99. OIS::InputManager::destroyInputSystem(input_manager_);
  100. //Remove self as a Window listener.
  101. Ogre::WindowEventUtilities::removeWindowEventListener(window_, this);
  102. windowClosed(window_);
  103. }
  104. /**
  105. * Called on window closing.
  106. *
  107. * Detaches OIS before window shutdown (very important under Linux).
  108. */
  109. virtual void windowClosed(Ogre::RenderWindow* rw){exit_ = true;}
  110. /**
  111. * Called when a frame is about to begin rendering.
  112. *
  113. * This event happens before any render targets have begun updating.
  114. * It captures input events and checks the state of entities.
  115. *
  116. * @param[in] evt Triggering event. Unused.
  117. * @return True to go ahead, false to abort rendering and drop out of
  118. * the rendering loop.
  119. */
  120. bool frameStarted(const Ogre::FrameEvent& evt){
  121. // TODO: Move implementation to cpp file.
  122. if (exit_ == true) return false;
  123. if (keyboard_) keyboard_->capture();
  124. if (mouse_) mouse_->capture();
  125. for (unsigned int i = 0; i < entities.size(); ++ i){
  126. if (entities[i]->isVisible() == true){
  127. Ogre::AnimationStateIterator animations
  128. = entities[i]->getAllAnimationStates()->getAnimationStateIterator();
  129. while (animations.hasMoreElements() == true){
  130. Ogre::AnimationState* state = animations.getNext();
  131. if (state->getEnabled() == true){
  132. state->addTime(evt.timeSinceLastFrame);
  133. info_text->setCaption(
  134. entities[i]->getName() + ": " + state->getAnimationName()
  135. );
  136. }
  137. }
  138. break;
  139. }
  140. }
  141. if (keyboard_->isKeyDown(OIS::KC_A)){
  142. assert(camera_);
  143. camera_->getParentSceneNode()->translate(
  144. Ogre::Vector3(-0.005f, 0.0f, 0.0f), Ogre::Node::TS_LOCAL
  145. );
  146. }
  147. if (keyboard_->isKeyDown(OIS::KC_D)){
  148. assert(camera_);
  149. camera_->getParentSceneNode()->translate(
  150. Ogre::Vector3(0.005f, 0.0f, 0.0f), Ogre::Node::TS_LOCAL
  151. );
  152. }
  153. if (keyboard_->isKeyDown(OIS::KC_W)){
  154. assert(camera_);
  155. camera_->getParentSceneNode()->translate(
  156. Ogre::Vector3(0.0f, 0.0f, -0.005f), Ogre::Node::TS_LOCAL
  157. );
  158. }
  159. if (keyboard_->isKeyDown(OIS::KC_S)){
  160. assert(camera_);
  161. camera_->getParentSceneNode()->translate(
  162. Ogre::Vector3(0.0f, 0.0f, 0.005f), Ogre::Node::TS_LOCAL
  163. );
  164. }
  165. if (mouse_rotate_ == true){
  166. assert(camera_);
  167. camera_->getParentSceneNode()->yaw(Ogre::Degree(-mouse_move_x_ * 0.13f));
  168. camera_->getParentSceneNode()->pitch(Ogre::Degree(-mouse_move_y_ * 0.13f));
  169. mouse_move_x_ = 0;
  170. mouse_move_y_ = 0;
  171. }
  172. return true;
  173. }
  174. /**
  175. * The key listener.
  176. *
  177. * Parses keyboard events.
  178. *
  179. * @param[in] e Triggering event.
  180. * @return Always true
  181. */
  182. bool keyPressed(const OIS::KeyEvent& e){
  183. switch(e.key){
  184. case OIS::KC_RIGHT:
  185. {
  186. bool change = false;
  187. for (unsigned int i = 0; i < entities.size(); ++ i){
  188. if (change == true){
  189. entities[i]->setVisible(true);
  190. break;
  191. }
  192. if (entities[i]->isVisible() == true && (i != entities.size() - 1)){
  193. entities[i]->setVisible(false);
  194. change = true;
  195. }
  196. }
  197. }
  198. break;
  199. case OIS::KC_LEFT:
  200. {
  201. bool change = false;
  202. for(int i = entities.size() - 1; i >= 0; -- i){
  203. if (change == true){
  204. entities[i]->setVisible(true);
  205. break;
  206. }
  207. if (entities[i]->isVisible() == true && i != 0){
  208. entities[i]->setVisible(false);
  209. change = true;
  210. }
  211. }
  212. }
  213. break;
  214. case OIS::KC_UP:
  215. {
  216. bool change = false;
  217. for (unsigned int i = 0; i < entities.size(); ++ i){
  218. if (entities[i]->isVisible() == true){
  219. Ogre::AnimationStateIterator animations
  220. = entities[i]->getAllAnimationStates()
  221. ->getAnimationStateIterator();
  222. Ogre::AnimationState* old_state;
  223. Ogre::AnimationState* new_state = animations.getNext();
  224. while (animations.hasMoreElements() == true){
  225. old_state = new_state;
  226. new_state = animations.getNext();
  227. if (new_state->getEnabled() == true){
  228. new_state->setEnabled(false);
  229. new_state->setLoop(false);
  230. old_state->setEnabled(true);
  231. old_state->setLoop(true);
  232. }
  233. }
  234. break;
  235. }
  236. }
  237. }
  238. break;
  239. case OIS::KC_DOWN:{
  240. bool change = false;
  241. for (unsigned int i = 0; i < entities.size(); ++ i){
  242. if (entities[i]->isVisible() == true){
  243. Ogre::AnimationStateIterator animations
  244. = entities[i]->getAllAnimationStates()->getAnimationStateIterator();
  245. while (animations.hasMoreElements() == true){
  246. Ogre::AnimationState* state = animations.getNext();
  247. if (change == true){
  248. state->setEnabled(true);
  249. state->setLoop(true);
  250. break;
  251. }
  252. if (
  253. state->getEnabled() == true
  254. && animations.hasMoreElements() != false
  255. ){
  256. state->setEnabled(false);
  257. state->setLoop(false);
  258. change = true;
  259. }
  260. }
  261. break;
  262. }
  263. }
  264. }
  265. break;
  266. }
  267. return true;
  268. }
  269. /**
  270. * Handles key releasing events.
  271. *
  272. * It does nothing.
  273. *
  274. * @param[in] e Triggering event.
  275. * @return Always true.
  276. */
  277. bool keyReleased(const OIS::KeyEvent& e){return true;}
  278. /**
  279. * Handles mouse movement events.
  280. *
  281. * @param[in] e Triggering event.
  282. * @return Always true.
  283. */
  284. bool mouseMoved(const OIS::MouseEvent& e){
  285. mouse_move_x_ = float(e.state.X.rel);
  286. mouse_move_y_ = float(e.state.Y.rel);
  287. return true;
  288. }
  289. /**
  290. * Handles mouse button-down events.
  291. *
  292. * @param[in] e Triggering event.
  293. * @param[in] id Button ID.
  294. * @return Always true.
  295. */
  296. bool mousePressed(const OIS::MouseEvent& e, OIS::MouseButtonID id){
  297. if (id == OIS::MB_Right) mouse_rotate_ = true;
  298. return true;
  299. }
  300. /**
  301. * Handles mouse button-up events.
  302. *
  303. * @param[in] e Triggering event.
  304. * @param[in] id Button ID.
  305. * @return Always true.
  306. */
  307. bool mouseReleased(const OIS::MouseEvent& e, OIS::MouseButtonID id){
  308. if (id == OIS::MB_Right) mouse_rotate_ = false;
  309. return true;
  310. }
  311. /**
  312. * The information text.
  313. */
  314. Ogre::TextAreaOverlayElement* info_text;
  315. /**
  316. * The information overlay.
  317. */
  318. Ogre::Overlay* info_overlay;
  319. /**
  320. * Sets the viewport camera
  321. */
  322. virtual void setCamera(Ogre::Camera *camera){camera_ = camera;}
  323. private:
  324. /**
  325. * The render window.
  326. */
  327. Ogre::RenderWindow* window_;
  328. /**
  329. * The OIS input manager.
  330. */
  331. OIS::InputManager* input_manager_;
  332. /**
  333. * The OIS keyboard.
  334. */
  335. OIS::Keyboard* keyboard_;
  336. /**
  337. * The OIS mouse.
  338. */
  339. OIS::Mouse* mouse_;
  340. /**
  341. * The camera.
  342. */
  343. Ogre::Camera *camera_;
  344. /**
  345. * Mouse horizontal movement.
  346. */
  347. float mouse_move_x_;
  348. /**
  349. * Mouse vertical movement.
  350. */
  351. float mouse_move_y_;
  352. /**
  353. * Indicates if the mouse is being rotated.
  354. */
  355. bool mouse_rotate_;
  356. /**
  357. * Flag for application exit.
  358. */
  359. bool exit_;
  360. };
  361. /**
  362. * Initializes the Ogre system.
  363. *
  364. * @param[in] name Application title.
  365. */
  366. void InitializeOgreBase(const Ogre::String& name);
  367. /**
  368. * Destructs the Ogre system.
  369. */
  370. void DeinitializeOgreBase();