OgreBase.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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. /**
  57. * Constructor.
  58. *
  59. * @param win[in] The render window. Used to determine input context.
  60. */
  61. DisplayFrameListener(Ogre::RenderWindow* win):
  62. window_(win), input_manager_(0), keyboard_(0),
  63. mouse_(0), mouse_rotate_(false), exit_(false)
  64. {
  65. using namespace OIS;
  66. Ogre::LogManager::getSingletonPtr()->logMessage("[OIS] Initializing...");
  67. ParamList pl;
  68. size_t window_hnd = 0; // TODO What does HND stand for?
  69. std::ostringstream window_hnd_str;
  70. win->getCustomAttribute("WINDOW", &window_hnd);
  71. window_hnd_str << window_hnd;
  72. pl.insert(
  73. std::make_pair(std::string("WINDOW"), window_hnd_str.str())
  74. );
  75. input_manager_ = InputManager::createInputSystem(pl);
  76. keyboard_ = static_cast<Keyboard*> (
  77. input_manager_->createInputObject(OIS::OISKeyboard, true)
  78. );
  79. keyboard_->setEventCallback(this);
  80. mouse_ = static_cast<OIS::Mouse*> (
  81. input_manager_->createInputObject(OIS::OISMouse, true)
  82. );
  83. mouse_->setEventCallback(this);
  84. //Register as a Window listener.
  85. Ogre::WindowEventUtilities::addWindowEventListener(window_, this);
  86. // Debug info.
  87. info_text = new Ogre::TextAreaOverlayElement("DebugText");
  88. info_text->setCaption("");
  89. info_text->setMetricsMode(Ogre::GMM_PIXELS);
  90. info_text->setPosition(5, 5);
  91. // info_text->setFontName("BlueHighway");
  92. info_text->setCharHeight(18);
  93. info_overlay = Ogre::OverlayManager::getSingleton().create("DebugOverlay");
  94. info_overlay->setZOrder(1);
  95. info_overlay->add2D((Ogre::OverlayContainer*) info_text);
  96. info_overlay->show();
  97. }
  98. virtual ~DisplayFrameListener(){
  99. input_manager_->destroyInputObject(keyboard_);
  100. OIS::InputManager::destroyInputSystem(input_manager_);
  101. //Remove self as a Window listener.
  102. Ogre::WindowEventUtilities::removeWindowEventListener(window_, this);
  103. windowClosed(window_);
  104. }
  105. /**
  106. * Called on window closing.
  107. *
  108. * Detaches OIS before window shutdown (very important under Linux).
  109. */
  110. virtual void windowClosed(Ogre::RenderWindow* rw){exit_ = true;}
  111. /**
  112. * Called when a frame is about to begin rendering.
  113. *
  114. * This event happens before any render targets have begun updating.
  115. * It captures input events and checks the state of entities.
  116. *
  117. * @param evt[in] Triggering event. Unused.
  118. * @return True to go ahead, false to abort rendering and drop out of
  119. * the rendering loop.
  120. */
  121. bool frameStarted(const Ogre::FrameEvent& evt){
  122. // TODO: Move implementation to cpp file.
  123. if (exit_ == true) return false;
  124. if (keyboard_) keyboard_->capture();
  125. if (mouse_) mouse_->capture();
  126. for (unsigned int i = 0; i < entities.size(); ++ i){
  127. if (entities[i]->isVisible() == true){
  128. Ogre::AnimationStateIterator animations
  129. = entities[i]->getAllAnimationStates()->getAnimationStateIterator();
  130. while (animations.hasMoreElements() == true){
  131. Ogre::AnimationState* state = animations.getNext();
  132. if (state->getEnabled() == true){
  133. state->addTime(evt.timeSinceLastFrame);
  134. info_text->setCaption(
  135. entities[i]->getName() + ": " + state->getAnimationName()
  136. );
  137. }
  138. }
  139. break;
  140. }
  141. }
  142. if (keyboard_->isKeyDown(OIS::KC_A)){
  143. assert(camera_);
  144. camera_->moveRelative(Ogre::Vector3(-0.005f, 0.0f, 0.0f));
  145. }
  146. if (keyboard_->isKeyDown(OIS::KC_D)){
  147. assert(camera_);
  148. camera_->moveRelative(Ogre::Vector3(0.005f, 0.0f, 0.0f));
  149. }
  150. if (keyboard_->isKeyDown(OIS::KC_W)){
  151. assert(camera_);
  152. camera_->moveRelative(Ogre::Vector3(0.0f, 0.0f, -0.005f));
  153. }
  154. if (keyboard_->isKeyDown(OIS::KC_S)){
  155. assert(camera_);
  156. camera_->moveRelative(Ogre::Vector3(0.0f, 0.0f, 0.005f));
  157. }
  158. if (mouse_rotate_ == true){
  159. assert(camera_);
  160. camera_->yaw(Ogre::Degree(-mouse_move_x_ * 0.13f));
  161. camera_->pitch(Ogre::Degree(-mouse_move_y_ * 0.13f));
  162. mouse_move_x_ = 0;
  163. mouse_move_y_ = 0;
  164. }
  165. return true;
  166. }
  167. /**
  168. * The key listener.
  169. *
  170. * Parses keyboard events.
  171. *
  172. * @param event[in] Triggering event.
  173. * @return Always true
  174. */
  175. bool keyPressed(const OIS::KeyEvent& e){
  176. switch(e.key){
  177. case OIS::KC_RIGHT:
  178. {
  179. bool change = false;
  180. for (unsigned int i = 0; i < entities.size(); ++ i){
  181. if (change == true){
  182. entities[i]->setVisible(true);
  183. break;
  184. }
  185. if (entities[i]->isVisible() == true && (i != entities.size() - 1)){
  186. entities[i]->setVisible(false);
  187. change = true;
  188. }
  189. }
  190. }
  191. break;
  192. case OIS::KC_LEFT:
  193. {
  194. bool change = false;
  195. for(int i = entities.size() - 1; i >= 0; -- i){
  196. if (change == true){
  197. entities[i]->setVisible(true);
  198. break;
  199. }
  200. if (entities[i]->isVisible() == true && i != 0){
  201. entities[i]->setVisible(false);
  202. change = true;
  203. }
  204. }
  205. }
  206. break;
  207. case OIS::KC_UP:
  208. {
  209. bool change = false;
  210. for (unsigned int i = 0; i < entities.size(); ++i){
  211. if (entities[i]->isVisible() == true){
  212. Ogre::AnimationStateIterator animations
  213. = entities[i]->getAllAnimationStates()
  214. ->getAnimationStateIterator();
  215. Ogre::AnimationState* old_state;
  216. Ogre::AnimationState* new_state = animations.getNext();
  217. while (animations.hasMoreElements() == true){
  218. old_state = new_state;
  219. new_state = animations.getNext();
  220. if (new_state->getEnabled() == true){
  221. new_state->setEnabled(false);
  222. new_state->setLoop(false);
  223. old_state->setEnabled(true);
  224. old_state->setLoop(true);
  225. }
  226. }
  227. break;
  228. }
  229. }
  230. }
  231. break;
  232. case OIS::KC_DOWN:{
  233. bool change = false;
  234. for (unsigned int i = 0; i < entities.size(); ++ i){
  235. if (entities[i]->isVisible() == true){
  236. Ogre::AnimationStateIterator animations
  237. = entities[i]->getAllAnimationStates()->getAnimationStateIterator();
  238. while (animations.hasMoreElements() == true){
  239. Ogre::AnimationState* state = animations.getNext();
  240. if (change == true){
  241. state->setEnabled(true);
  242. state->setLoop(true);
  243. break;
  244. }
  245. if (
  246. state->getEnabled() == true
  247. && animations.hasMoreElements() != false
  248. ){
  249. state->setEnabled(false);
  250. state->setLoop(false);
  251. change = true;
  252. }
  253. }
  254. break;
  255. }
  256. }
  257. }
  258. break;
  259. }
  260. return true;
  261. }
  262. /**
  263. * Handles key releasing events.
  264. *
  265. * It does nothing.
  266. *
  267. * @param e[in] Triggering event.
  268. * @return Always true.
  269. */
  270. bool keyReleased(const OIS::KeyEvent& e){return true;}
  271. /**
  272. * Handles mouse movement events.
  273. *
  274. * @param e[in] Triggering event.
  275. * @return Always true.
  276. */
  277. bool mouseMoved(const OIS::MouseEvent& e){
  278. mouse_move_x_ = float(e.state.X.rel);
  279. mouse_move_y_ = float(e.state.Y.rel);
  280. return true;
  281. }
  282. /**
  283. * Handles mouse button-down events.
  284. *
  285. * @param e[in] Triggering event.
  286. * @param id[in] Button ID.
  287. * @return Always true.
  288. */
  289. bool mousePressed(const OIS::MouseEvent& e, OIS::MouseButtonID id){
  290. if (id == OIS::MB_Right) mouse_rotate_ = true;
  291. return true;
  292. }
  293. /**
  294. * Handles mouse button-up events.
  295. *
  296. * @param e[in] Triggering event.
  297. * @param id[in] Button ID.
  298. * @return Always true.
  299. */
  300. bool mouseReleased(const OIS::MouseEvent& e, OIS::MouseButtonID id){
  301. if (id == OIS::MB_Right) mouse_rotate_ = false;
  302. return true;
  303. }
  304. /**
  305. * The information text.
  306. */
  307. Ogre::TextAreaOverlayElement* info_text;
  308. /**
  309. * The information overlay.
  310. */
  311. Ogre::Overlay* info_overlay;
  312. /**
  313. * Sets the viewport camera
  314. */
  315. virtual void setCamera(Ogre::Camera *camera){camera_ = camera;}
  316. private:
  317. /**
  318. * The render window.
  319. */
  320. Ogre::RenderWindow* window_;
  321. /**
  322. * The OIS input manager.
  323. */
  324. OIS::InputManager* input_manager_;
  325. /**
  326. * The OIS keyboard.
  327. */
  328. OIS::Keyboard* keyboard_;
  329. /**
  330. * The OIS mouse.
  331. */
  332. OIS::Mouse* mouse_;
  333. /**
  334. * The camera.
  335. */
  336. Ogre::Camera *camera_;
  337. /**
  338. * Mouse horizontal movement.
  339. */
  340. float mouse_move_x_;
  341. /**
  342. * Mouse vertical movement.
  343. */
  344. float mouse_move_y_;
  345. /**
  346. * Indicates if the mouse is being rotated.
  347. */
  348. bool mouse_rotate_;
  349. /**
  350. * Flag for application exit.
  351. */
  352. bool exit_;
  353. };
  354. /**
  355. * Initializes the Ogre system.
  356. *
  357. * @param name[in] Application title.
  358. */
  359. void InitializeOgreBase(const Ogre::String& name);
  360. /**
  361. * Destructs the Ogre system.
  362. */
  363. void DeinitializeOgreBase();