EntityManager.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314
  1. #include <OgreEntity.h>
  2. #include <OgreRoot.h>
  3. #include "core/CameraManager.h"
  4. #include "core/ConfigVar.h"
  5. #include "core/DebugDraw.h"
  6. #include "core/EntityManager.h"
  7. #include "core/EntityModel.h"
  8. #include "core/InputManager.h"
  9. #include "core/Logger.h"
  10. #include "core/ScriptManager.h"
  11. #include "core/Timer.h"
  12. template<>EntityManager *Ogre::Singleton<EntityManager>::msSingleton = nullptr;
  13. ConfigVar cv_debug_grid("debug_grid", "Draw debug grid", "false");
  14. ConfigVar cv_debug_axis("debug_axis", "Draw debug axis", "false");
  15. float
  16. PointElevation(const Ogre::Vector2& point, const Ogre::Vector3& A, const Ogre::Vector3& B, const Ogre::Vector3& C)
  17. {
  18. float _A = A.z * (B.y - C.y) + B.z * (C.y - A.y) + C.z * (A.y - B.y);
  19. float _B = A.y * (B.x - C.x) + B.y * (C.x - A.x) + C.y * (A.x - B.x);
  20. float _C = A.x * (B.z - C.z) + B.x * (C.z - A.z) + C.x * (A.z - B.z);
  21. float _D = A.x * (B.z * C.y - C.z * B.y) + B.x * (C.z * A.y - A.z * C.y) + C.x * (A.z * B.y - B.z * A.y);
  22. return (_D - _C * point.y - _A * point.x) / _B;
  23. }
  24. float
  25. SideOfVector(const Ogre::Vector2& point, const Ogre::Vector2& p1, const Ogre::Vector2& p2)
  26. {
  27. Ogre::Vector2 AB = p2 - p1;
  28. Ogre::Vector2 AP = point - p1;
  29. return AB.x * AP.y - AB.y * AP.x;
  30. }
  31. float
  32. SquareDistanceToLine(const Ogre::Vector3& p, const Ogre::Vector3& p1, const Ogre::Vector3& p2, Ogre::Vector3& proj)
  33. {
  34. float temp = -((p1.x - p.x) * (p2.x - p1.x) + (p1.y - p.y) *
  35. (p2.y - p1.y) + (p1.z - p.z) * (p2.z - p1.z)) /
  36. ((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) *
  37. (p2.y - p1.y) + (p2.z - p1.z) * (p2.z - p1.z));
  38. proj.x = temp * (p2.x - p1.x) + p1.x;
  39. proj.y = temp * (p2.y - p1.y) + p1.y;
  40. proj.z = temp * (p2.z - p1.z) + p1.z;
  41. if(((p1.x >= proj.x && p2.x <= proj.x) || (p1.x < proj.x && p2.x >= proj.x)) &&
  42. ((p1.y >= proj.y && p2.y <= proj.y) || (p1.y < proj.y && p2.y >= proj.y)))
  43. {
  44. return (proj.x - p.x) * (proj.x - p.x) + (proj.y - p.y) * (proj.y - p.y) + (proj.z - p.z) * (proj.z - p.z);
  45. }
  46. return -1;
  47. }
  48. Ogre::Degree
  49. GetDirectionToPoint(const Ogre::Vector3& current_point, const Ogre::Vector3& direction_point)
  50. {
  51. Ogre::Vector2 up(0.0f, -1.0f);
  52. Ogre::Vector2 dir(direction_point.x - current_point.x, direction_point.y - current_point.y);
  53. // angle between vectors
  54. Ogre::Degree angle(Ogre::Radian(acosf(dir.dotProduct(up) / (dir.length() * up.length()))));
  55. return (dir.x < 0) ? Ogre::Degree(360) - angle : angle;
  56. }
  57. EntityManager::EntityManager():
  58. m_Paused(false),
  59. m_PlayerEntity(nullptr),
  60. m_PlayerMove(Ogre::Vector3::ZERO),
  61. m_PlayerMoveRotation(0),
  62. m_PlayerLock(false)
  63. {
  64. LOG_TRIVIAL("EntityManager created.");
  65. m_SceneNode = Ogre::Root::getSingleton().getSceneManager("Scene")->getRootSceneNode()->createChildSceneNode("EntityManager");
  66. m_Grid = Ogre::Root::getSingleton().getSceneManager("Scene")->createEntity("Grid", "system/grid.mesh");
  67. m_SceneNode->attachObject(m_Grid);
  68. m_Axis = Ogre::Root::getSingleton().getSceneManager("Scene")->createEntity("Axis", "system/axis.mesh");
  69. m_SceneNode->attachObject(m_Axis);
  70. }
  71. EntityManager::~EntityManager()
  72. {
  73. if(m_Grid != nullptr)
  74. {
  75. Ogre::Root::getSingleton().getSceneManager("Scene")->destroyEntity(m_Grid);
  76. }
  77. if(m_Axis != nullptr)
  78. {
  79. Ogre::Root::getSingleton().getSceneManager("Scene")->destroyEntity(m_Axis);
  80. }
  81. Clear();
  82. Ogre::Root::getSingleton().getSceneManager("Scene")->getRootSceneNode()->removeAndDestroyChild("EntityManager");
  83. LOG_TRIVIAL("EntityManager destroyed.");
  84. }
  85. void
  86. EntityManager::Input(const QGears::Event& event)
  87. {
  88. m_Background2D.InputDebug(event);
  89. if(m_Paused == true)
  90. {
  91. return;
  92. }
  93. if(m_PlayerEntity != nullptr && m_PlayerLock == false)
  94. {
  95. if ((event.type == QGears::ET_KEY_IMPULSE) && (event.param1 == OIS::KC_LEFT))
  96. {
  97. m_PlayerMove.x = -1;
  98. }
  99. else if ((event.type == QGears::ET_KEY_IMPULSE) && (event.param1 == OIS::KC_RIGHT))
  100. {
  101. m_PlayerMove.x = 1;
  102. }
  103. if ((event.type == QGears::ET_KEY_IMPULSE) && (event.param1 == OIS::KC_DOWN))
  104. {
  105. m_PlayerMove.y = -1;
  106. }
  107. if ((event.type == QGears::ET_KEY_IMPULSE) && (event.param1 == OIS::KC_UP))
  108. {
  109. m_PlayerMove.y = 1;
  110. }
  111. //rotate move vector to field move rotation
  112. Ogre::Quaternion q1;
  113. q1.FromAngleAxis(m_PlayerMoveRotation, Ogre::Vector3::UNIT_Z);
  114. m_PlayerMove = q1 * m_PlayerMove;
  115. }
  116. }
  117. void
  118. EntityManager::Update()
  119. {
  120. UpdateDebug();
  121. if(m_Paused == true)
  122. {
  123. return;
  124. }
  125. // update all entity scripts
  126. ScriptManager::getSingleton().Update(ScriptManager::ENTITY);
  127. // set move point for player entity
  128. if(m_PlayerEntity != nullptr && m_PlayerMove != Ogre::Vector3::ZERO)
  129. {
  130. Entity::State state = m_PlayerEntity->GetState();
  131. if(state == Entity::WALKMESH || state == Entity::NONE)
  132. {
  133. m_PlayerMove *= m_PlayerEntity->GetMoveWalkSpeed() * Timer::getSingleton().GetGameTimeDelta();
  134. m_PlayerEntity->SetMovePosition(m_PlayerEntity->GetPosition() + m_PlayerMove);
  135. m_PlayerEntity->SetState(Entity::WALKMESH);
  136. }
  137. }
  138. for(unsigned int i = 0; i < m_Entity.size(); ++i)
  139. {
  140. m_Entity[i]->Update();
  141. // it's not needed to update movements it delta time == 0 (for example if we stop time)
  142. if(Timer::getSingleton().GetGameTimeDelta() == 0)
  143. {
  144. continue;
  145. }
  146. // update screen scroll
  147. Entity* scroll_entity = m_Background2D.GetAutoScrollEntity();
  148. if(scroll_entity == m_Entity[i])
  149. {
  150. CameraManager &camera_manager(CameraManager::getSingleton());
  151. Ogre::Vector3 view = camera_manager.ProjectPointToScreen(scroll_entity->GetPosition());
  152. Ogre::Vector2 pos = m_Background2D.GetScreenScroll();
  153. Ogre::Viewport *viewport(camera_manager.getViewport());
  154. float width = float(viewport->getActualWidth());
  155. float height = float(viewport->getActualHeight());
  156. view.x = view.x - width / 2 - pos.x;
  157. view.y = view.y - height / 2 - pos.y;
  158. m_Background2D.SetScreenScroll(Ogre::Vector2(-view.x, -view.y));
  159. }
  160. // update offseting
  161. if(m_Entity[i]->GetOffsetType() != AT_NONE)
  162. {
  163. SetNextOffsetStep(m_Entity[i]);
  164. }
  165. // update turning
  166. if(m_Entity[i]->GetTurnType() != AT_NONE)
  167. {
  168. SetNextTurnStep(m_Entity[i]);
  169. }
  170. // update movement
  171. switch(m_Entity[i]->GetState())
  172. {
  173. case Entity::WALKMESH:
  174. {
  175. bool is_move = false;
  176. // try set entity on walkmesh it it's still don't has triangle
  177. if(m_Entity[i]->GetMoveTriangleId() == -1)
  178. {
  179. if(SetEntityOnWalkmesh(m_Entity[i]) == false)
  180. {
  181. LOG_TRIVIAL("Can't set entity \"" + m_Entity[i]->GetName() + "\" on walkmesh. Finish move.");
  182. m_Entity[i]->UnsetMove();
  183. }
  184. }
  185. // perform move
  186. if(m_Entity[i]->GetState() == Entity::WALKMESH)
  187. {
  188. float speed = 0;
  189. if(m_PlayerLock == false && m_PlayerEntity == m_Entity[i])
  190. {
  191. speed = m_Entity[i]->GetMoveWalkSpeed();
  192. if(InputManager::getSingleton().IsButtonPressed(OIS::KC_LCONTROL) == true)
  193. {
  194. speed *= 4;
  195. }
  196. }
  197. else
  198. {
  199. speed = m_Entity[i]->GetMoveAutoSpeed();
  200. }
  201. is_move = PerformWalkmeshMove(m_Entity[i], speed);
  202. if(m_Entity[i]->GetMoveAutoAnimation() == true)
  203. {
  204. if(is_move == true)
  205. {
  206. if(speed >= m_Entity[i]->GetMoveRunSpeed())
  207. {
  208. m_Entity[i]->PlayAnimationContinue(m_Entity[i]->GetMoveAnimationRunName());
  209. }
  210. else
  211. {
  212. m_Entity[i]->PlayAnimationContinue(m_Entity[i]->GetMoveAnimationWalkName());
  213. }
  214. }
  215. else if (m_Entity[i]->GetAnimationState() != Entity::REQUESTED_ANIMATION)
  216. {
  217. m_Entity[i]->PlayAnimationContinue(m_Entity[i]->GetDefaultAnimationName());
  218. }
  219. }
  220. }
  221. }
  222. break;
  223. case Entity::LINEAR:
  224. {
  225. SetNextLinearStep(m_Entity[i]);
  226. }
  227. break;
  228. case Entity::JUMP:
  229. {
  230. SetNextJumpStep(m_Entity[i]);
  231. }
  232. break;
  233. case Entity::NONE:
  234. {
  235. if(m_Entity[i]->GetAnimationState() != Entity::REQUESTED_ANIMATION)
  236. {
  237. m_Entity[i]->PlayAnimationContinue(m_Entity[i]->GetDefaultAnimationName());
  238. }
  239. }
  240. break;
  241. }
  242. }
  243. // reset player move. It already must be handled in update
  244. m_PlayerMove = Ogre::Vector3::ZERO;
  245. if(m_Background2D.GetScrollType() != Background2D::NONE)
  246. {
  247. SetNextScrollStep();
  248. }
  249. m_Background2D.Update();
  250. }
  251. void
  252. EntityManager::UpdateDebug()
  253. {
  254. m_Grid->setVisible(cv_debug_grid.GetB());
  255. m_Axis->setVisible(cv_debug_axis.GetB());
  256. for(unsigned int i = 0; i < m_Entity.size(); ++i)
  257. {
  258. m_Entity[i]->UpdateDebug();
  259. }
  260. for(unsigned int i = 0; i < m_EntityTriggers.size(); ++i)
  261. {
  262. m_EntityTriggers[i]->UpdateDebug();
  263. }
  264. for(unsigned int i = 0; i < m_EntityPoints.size(); ++i)
  265. {
  266. m_EntityPoints[i]->UpdateDebug();
  267. }
  268. m_Walkmesh.UpdateDebug();
  269. m_Background2D.UpdateDebug();
  270. }
  271. void
  272. EntityManager::OnResize()
  273. {
  274. m_Background2D.OnResize();
  275. }
  276. void
  277. EntityManager::Clear()
  278. {
  279. m_Walkmesh.Clear();
  280. m_Background2D.Clear();
  281. for(unsigned int i = 0; i < m_Entity.size(); ++i)
  282. {
  283. ScriptManager::getSingleton().RemoveEntity(ScriptManager::ENTITY, m_Entity[i]->GetName());
  284. delete m_Entity[i];
  285. }
  286. m_Entity.clear();
  287. m_PlayerEntity = nullptr;
  288. m_PlayerMove = Ogre::Vector3::ZERO;
  289. m_PlayerMoveRotation = 0;
  290. m_PlayerLock = false;
  291. for(unsigned int i = 0; i < m_EntityTriggers.size(); ++i)
  292. {
  293. ScriptManager::getSingleton().RemoveEntity(ScriptManager::ENTITY, m_EntityTriggers[i]->GetName());
  294. delete m_EntityTriggers[i];
  295. }
  296. m_EntityTriggers.clear();
  297. for(unsigned int i = 0; i < m_EntityPoints.size(); ++i)
  298. {
  299. delete m_EntityPoints[i];
  300. }
  301. m_EntityPoints.clear();
  302. for(unsigned int i = 0; i < m_EntityScripts.size(); ++i)
  303. {
  304. ScriptManager::getSingleton().RemoveEntity(ScriptManager::ENTITY, m_EntityScripts[i]);
  305. }
  306. m_SceneNode->removeAndDestroyAllChildren();
  307. }
  308. void
  309. EntityManager::ScriptSetPaused(const bool paused)
  310. {
  311. m_Paused = paused;
  312. }
  313. Walkmesh*
  314. EntityManager::GetWalkmesh()
  315. {
  316. return &m_Walkmesh;
  317. }
  318. Background2D*
  319. EntityManager::GetBackground2D()
  320. {
  321. return &m_Background2D;
  322. }
  323. void
  324. EntityManager::AddEntity(const Ogre::String& name, const Ogre::String& file_name, const Ogre::Vector3& position, const Ogre::Degree& rotation)
  325. {
  326. AddEntity(name, file_name, position, rotation, Ogre::Vector3::UNIT_SCALE, Ogre::Quaternion::IDENTITY);
  327. }
  328. void
  329. EntityManager::AddEntity(const Ogre::String& name, const Ogre::String& file_name, const Ogre::Vector3& position, const Ogre::Degree& rotation, const Ogre::Vector3& scale, const Ogre::Quaternion& root_orientation)
  330. {
  331. Ogre::SceneNode* node = m_SceneNode->createChildSceneNode("Model_" + name);
  332. EntityModel* entity = new EntityModel(name, file_name, node);
  333. entity->SetPosition(position);
  334. entity->SetRotation(rotation);
  335. entity->setScale(scale);
  336. entity->setRootOrientation(root_orientation);
  337. m_Entity.push_back(entity);
  338. ScriptManager::getSingleton().AddEntity(ScriptManager::ENTITY, entity->GetName(), entity);
  339. }
  340. void
  341. EntityManager::ScriptAddEntity(const char* name, const char* file_name, const float x, const float y, const float z, const float rotation)
  342. {
  343. AddEntity(name, file_name, Ogre::Vector3(x, y, z), Ogre::Degree(rotation));
  344. }
  345. void
  346. EntityManager::AddEntityTrigger(const Ogre::String& name, const Ogre::Vector3& point1, const Ogre::Vector3& point2, const bool enabled)
  347. {
  348. EntityTrigger* trigger = new EntityTrigger(name);
  349. trigger->SetPoints(point1, point2);
  350. trigger->SetEnabled(enabled);
  351. m_EntityTriggers.push_back(trigger);
  352. ScriptManager::getSingleton().AddEntity(ScriptManager::ENTITY, trigger->GetName(), nullptr);
  353. }
  354. void
  355. EntityManager::AddEntityPoint(const Ogre::String& name, const Ogre::Vector3& position, const float rotation)
  356. {
  357. EntityPoint* entity_point = new EntityPoint(name);
  358. entity_point->SetPosition(position);
  359. entity_point->SetRotation(rotation);
  360. m_EntityPoints.push_back(entity_point);
  361. }
  362. void
  363. EntityManager::AddEntityScript(const Ogre::String& name)
  364. {
  365. m_EntityScripts.push_back(name);
  366. ScriptManager::getSingleton().AddEntity(ScriptManager::ENTITY, name, nullptr);
  367. }
  368. void
  369. EntityManager::ScriptAddEntityScript(const char* name)
  370. {
  371. AddEntityScript(name);
  372. }
  373. Entity*
  374. EntityManager::GetEntity(const Ogre::String& name) const
  375. {
  376. for(unsigned int i = 0; i < m_Entity.size(); ++i)
  377. {
  378. if(m_Entity[i]->GetName() == name)
  379. {
  380. return m_Entity[i];
  381. }
  382. }
  383. return nullptr;
  384. }
  385. Entity*
  386. EntityManager::ScriptGetEntity(const char* name) const
  387. {
  388. return GetEntity(Ogre::String(name));
  389. }
  390. EntityPoint*
  391. EntityManager::ScriptGetEntityPoint(const char* name) const
  392. {
  393. for(unsigned int i = 0; i < m_EntityPoints.size(); ++i)
  394. {
  395. if(m_EntityPoints[i]->GetName() == name)
  396. {
  397. return m_EntityPoints[i];
  398. }
  399. }
  400. return nullptr;
  401. }
  402. void
  403. EntityManager::ScriptSetPlayerEntity(const char* name)
  404. {
  405. for(unsigned int i = 0; i < m_Entity.size(); ++i)
  406. {
  407. if(m_Entity[i]->GetName() == name)
  408. {
  409. m_PlayerEntity = m_Entity[i];
  410. }
  411. }
  412. }
  413. void
  414. EntityManager::ScriptUnsetPlayerEntity()
  415. {
  416. m_PlayerEntity = nullptr;
  417. }
  418. void
  419. EntityManager::ScriptPlayerLock(const bool lock)
  420. {
  421. m_PlayerLock = lock;
  422. if(lock == true)
  423. {
  424. m_PlayerMove = Ogre::Vector3::ZERO;
  425. }
  426. }
  427. void
  428. EntityManager::SetPlayerMoveRotation(const Ogre::Radian rotation)
  429. {
  430. m_PlayerMoveRotation = rotation;
  431. }
  432. bool
  433. EntityManager::SetEntityOnWalkmesh(Entity* entity)
  434. {
  435. Ogre::Vector3 position3 = entity->GetPosition();
  436. Ogre::Vector2 position2;
  437. position2.x = position3.x;
  438. position2.y = position3.y;
  439. std::vector< std::pair< int, float > > triangles;
  440. // we search for posible triangles
  441. for(int i = 0; i < m_Walkmesh.GetNumberOfTriangles(); ++i)
  442. {
  443. Ogre::Vector3 A3 = m_Walkmesh.GetA(i);
  444. Ogre::Vector3 B3 = m_Walkmesh.GetB(i);
  445. Ogre::Vector3 C3 = m_Walkmesh.GetC(i);
  446. Ogre::Vector2 A2(A3.x, A3.y);
  447. Ogre::Vector2 B2(B3.x, B3.y);
  448. Ogre::Vector2 C2(C3.x, C3.y);
  449. if(Ogre::Math::pointInTri2D(position2, A2, B2, C2) == true)
  450. {
  451. triangles.push_back(std::make_pair(i, PointElevation(position2, m_Walkmesh.GetA(i), m_Walkmesh.GetB(i), m_Walkmesh.GetC(i))));
  452. }
  453. }
  454. // if our coords doesn't match any triangle
  455. if(triangles.size() == 0)
  456. {
  457. LOG_ERROR("Can't find any triangle to place entity \"" + entity->GetName() + "\" on walkmesh.");
  458. return false;
  459. }
  460. /*
  461. int triangle = m_Models[entity_id]->GetTriangle();
  462. if (triangle != -1)
  463. {
  464. for (int i = 0; i < triangles.size(); ++i)
  465. {
  466. if (triangles[i].first == triangle)
  467. {
  468. m_Models[entity_id]->SetPosition(Ogre::Vector3(position2.x, position2.y, triangles[i].second));
  469. return;
  470. }
  471. }
  472. }
  473. */
  474. // place entity on fount triangles
  475. // first try to set on top triangle less than current pos of entity
  476. float pos_z = position3.z;
  477. int triangle_id = -1;
  478. for(size_t i = 0; i < triangles.size(); ++i)
  479. {
  480. if(triangles[i].second <= pos_z)
  481. {
  482. pos_z = triangles[i].second;
  483. triangle_id = triangles[i].first;
  484. break;
  485. }
  486. }
  487. // if every triangle are higher than entity
  488. if(triangle_id == -1)
  489. {
  490. for(size_t i = 0; i < triangles.size(); ++i)
  491. {
  492. if(triangles[i].second >= pos_z)
  493. {
  494. pos_z = triangles[i].second;
  495. triangle_id = triangles[i].first;
  496. }
  497. }
  498. }
  499. entity->SetPosition(Ogre::Vector3(position2.x, position2.y, pos_z));
  500. entity->SetMoveTriangleId(triangle_id);
  501. return true;
  502. }
  503. bool
  504. EntityManager::PerformWalkmeshMove(Entity* entity, const float speed)
  505. {
  506. Ogre::Vector3 start_point = entity->GetPosition();
  507. Ogre::Vector3 move_vector = entity->GetMovePosition() - start_point;
  508. Ogre::Vector2 direction(move_vector.x, move_vector.y);
  509. direction.normalise();
  510. direction *= Timer::getSingleton().GetGameTimeDelta();
  511. direction *= speed;
  512. // if we still need to move but speed ot time don't allow us to do this just return for now
  513. if(direction.isZeroLength() == true)
  514. {
  515. return false;
  516. }
  517. int current_triangle = entity->GetMoveTriangleId();
  518. if(current_triangle == -1)
  519. {
  520. LOG_ERROR("Entity \"" + entity->GetName() + "\" not placed on walkmesh and can't move.");
  521. return false;
  522. }
  523. //LOG_TRIVIAL("Start position calculation.");
  524. //LOG_TRIVIAL("Start point: " + Ogre::StringConverter::toString(start_point) + ".");
  525. //LOG_TRIVIAL("Move vector: " + Ogre::StringConverter::toString(direction) + ".");
  526. Ogre::Vector3 rotation(0.0f, 0.0f, 0.0f);
  527. Ogre::Quaternion q1(0.0f, 0.0f, 0.0f, 1.0f);
  528. Ogre::Vector3 end_point(0.0f, 0.0f, 0.0f);
  529. Ogre::Vector3 end_point2(0.0f, 0.0f, 0.0f);
  530. bool first_triangle_check = false;
  531. bool second_triangle_check = false;
  532. bool third_triangle_check = false;
  533. bool last_triangle_check = false;
  534. bool first_entity_check = false;
  535. bool second_entity_check = false;
  536. bool third_entity_check = false;
  537. // shorten move vector by triangle angle
  538. end_point.x = start_point.x + direction.x;
  539. end_point.y = start_point.y + direction.y;
  540. Ogre::Vector3 A3 = m_Walkmesh.GetA(current_triangle);
  541. Ogre::Vector3 B3 = m_Walkmesh.GetB(current_triangle);
  542. Ogre::Vector3 C3 = m_Walkmesh.GetC(current_triangle);
  543. end_point.z = PointElevation(Ogre::Vector2(end_point.x, end_point.y), A3, B3, C3);
  544. Ogre::Vector3 temp = end_point - start_point;
  545. temp.normalise();
  546. temp = temp * direction.length();
  547. direction.x = temp.x;
  548. direction.y = temp.y;
  549. //LOG_TRIVIAL("Shortened Direction:(" + Ogre::StringConverter::toString(direction) + ").");
  550. // set direction for entity if we want to move
  551. if(entity->GetMoveAutoRotation() == true)
  552. {
  553. Ogre::Vector2 up(0.0f, -1.0f);
  554. // angle between vectors
  555. Ogre::Degree angle(Ogre::Radian(acosf(direction.dotProduct(up) / (direction.length() * up.length()))));
  556. angle = (direction.x < 0) ? Ogre::Degree(360) - angle : angle;
  557. entity->SetRotation(Ogre::Degree(angle));
  558. }
  559. float solid = (entity->IsSolid() == true) ? entity->GetSolidRadius() : 0.01f;
  560. // get ending point
  561. end_point.z = start_point.z;
  562. //LOG_TRIVIAL("End point: (" + Ogre::StringConverter::toString(end_point) + ").");
  563. //LOG_TRIVIAL("Start cycle.");
  564. for(int i = 0; (entity == m_PlayerEntity && /*m_PlayerModelSlip == true &&*/ i < 16) ||
  565. (entity == m_PlayerEntity && /*m_PlayerModelSlip == false &&*/ i < 3) ||
  566. (entity != m_PlayerEntity && i <= 16); ++i)
  567. {
  568. //LOG_TRIVIAL("Cycle " + Ogre::StringConverter::toString(i) + ".");
  569. end_point = Ogre::Vector3(start_point.x + direction.x, start_point.y + direction.y, start_point.z);
  570. // 1st check
  571. // rotate move_vector +45
  572. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(45)), Ogre::Vector3::UNIT_Z);
  573. rotation.x = direction.x;
  574. rotation.y = direction.y;
  575. rotation.z = 0;
  576. rotation.normalise();
  577. rotation = q1 * rotation;
  578. //LOG_TRIVIAL("Move vector length: " + Ogre::StringConverter::toString(rotation.length()) + ".");
  579. // multiply move_vector by solid range
  580. rotation = rotation * solid;
  581. end_point2.x = end_point.x + rotation.x;
  582. end_point2.y = end_point.y + rotation.y;
  583. //LOG_TRIVIAL("Left sector part end point:(" + Ogre::StringConverter::toString(end_point2) + ").");
  584. // check_triangle
  585. first_triangle_check = WalkmeshBorderCross(entity, end_point2, direction);
  586. entity->SetMoveTriangleId(current_triangle);
  587. // model_check
  588. first_entity_check = CheckSolidCollisions(entity, end_point2);
  589. //LOG_TRIVIAL("Entity \"" + entity->GetName() + "\" check1: " + Ogre::StringConverter::toString(first_triangle_check) + " " + Ogre::StringConverter::toString(first_entity_check) + ".");
  590. // 2nd check
  591. // rotate move_vector +45
  592. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(-45)), Ogre::Vector3::UNIT_Z);
  593. rotation.x = direction.x;
  594. rotation.y = direction.y;
  595. rotation.z = 0;
  596. rotation.normalise();
  597. rotation = q1 * rotation;
  598. // multiply move_vector by solid range
  599. rotation = rotation * solid;
  600. end_point2.x = end_point.x + rotation.x;
  601. end_point2.y = end_point.y + rotation.y;
  602. // check triangle
  603. second_triangle_check = WalkmeshBorderCross(entity, end_point2, direction);
  604. entity->SetMoveTriangleId(current_triangle);
  605. // model_check
  606. second_entity_check = CheckSolidCollisions(entity, end_point2);
  607. //LOG_TRIVIAL("Entity \"" + entity->GetName() + "\" check2: " + Ogre::StringConverter::toString(second_triangle_check) + " " + Ogre::StringConverter::toString(second_entity_check) + ".");
  608. // 3rd check
  609. rotation.x = direction.x;
  610. rotation.y = direction.y;
  611. rotation.z = 0;
  612. rotation.normalise();
  613. rotation = rotation * solid;
  614. end_point2.x = end_point.x + rotation.x;
  615. end_point2.y = end_point.y + rotation.y;
  616. // check triangle
  617. third_triangle_check = WalkmeshBorderCross(entity, end_point2, direction);
  618. entity->SetMoveTriangleId(current_triangle);
  619. // model_check
  620. third_entity_check = CheckSolidCollisions(entity, end_point2);
  621. //LOG_TRIVIAL("Entity \"" + entity->GetName() + "\" check3: " + Ogre::StringConverter::toString(third_triangle_check) + " " + Ogre::StringConverter::toString(third_entity_check) + ".");
  622. // check condition and modify move_vector
  623. if(first_triangle_check != false || second_triangle_check != false || third_triangle_check != false ||
  624. first_entity_check != false || second_entity_check != false || third_entity_check != false)
  625. {
  626. // only for NPC
  627. if(entity != m_PlayerEntity)
  628. {
  629. // if we collide only directly into triangle border
  630. if(first_triangle_check == false && second_triangle_check == false && third_triangle_check != false)
  631. {
  632. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(-7)), Ogre::Vector3::UNIT_Z);
  633. rotation.x = direction.x;
  634. rotation.y = direction.y;
  635. rotation = q1 * rotation;
  636. direction.x = rotation.x;
  637. direction.y = rotation.y;
  638. }
  639. // or if we only collide into others entity directly
  640. else if(first_entity_check == false && second_entity_check == false && third_entity_check != false)
  641. {
  642. //LOG_TRIVIAL("Entity \"" + entity->GetName() + "\" try to rotate.");
  643. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(-11.25f)), Ogre::Vector3::UNIT_Z);
  644. rotation.x = direction.x;
  645. rotation.y = direction.y;
  646. rotation = q1 * rotation;
  647. direction.x = rotation.x;
  648. direction.y = rotation.y;
  649. }
  650. // if not both left and right check was fail
  651. if(first_triangle_check == false || second_triangle_check == false)
  652. {
  653. if((first_triangle_check == false && first_entity_check != false) || (first_triangle_check != false && second_triangle_check == false))
  654. {
  655. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(-11.25f)), Ogre::Vector3::UNIT_Z);
  656. rotation.x = direction.x;
  657. rotation.y = direction.y;
  658. rotation = q1 * rotation;
  659. direction.x = rotation.x;
  660. direction.y = rotation.y;
  661. //LOGGER->Log(LOGGER_WARNING, "New move vector: %f %f.", direction.x, direction.y);
  662. }
  663. if(first_triangle_check == false && first_entity_check == false && (second_triangle_check != false || second_entity_check != false))
  664. {
  665. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(11.25f)), Ogre::Vector3::UNIT_Z);
  666. rotation.x = direction.x;
  667. rotation.y = direction.y;
  668. rotation = q1 * rotation;
  669. direction.x = rotation.x;
  670. direction.y = rotation.y;
  671. //LOGGER->Log(LOGGER_WARNING, "New move vector: %f %f.", direction.x, direction.y);
  672. }
  673. continue;
  674. }
  675. break;
  676. }
  677. // only for PC
  678. else
  679. {
  680. if(first_entity_check == false && second_entity_check == false && third_entity_check == false)
  681. {
  682. // if not both left and right check was fail
  683. if(first_triangle_check == false || second_triangle_check == false)
  684. {
  685. if((first_triangle_check == false && first_entity_check != false) ||
  686. (first_triangle_check != false && second_triangle_check == false))
  687. {
  688. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(-11.25f)), Ogre::Vector3::UNIT_Z);
  689. rotation.x = direction.x;
  690. rotation.y = direction.y;
  691. rotation = q1 * rotation;
  692. direction.x = rotation.x;
  693. direction.y = rotation.y;
  694. //LOG_TRIVIAL("Entity \"" + entity->GetName() + "\" new move vector: " + Ogre::StringConverter::toString(direction.x) + " " + Ogre::StringConverter::toString(direction.y) + ".");
  695. }
  696. if(first_triangle_check == false && first_entity_check == false && (second_triangle_check != false || second_entity_check != false))
  697. {
  698. q1.FromAngleAxis(Ogre::Radian(Ogre::Degree(11.25f)), Ogre::Vector3::UNIT_Z);
  699. rotation.x = direction.x;
  700. rotation.y = direction.y;
  701. rotation = q1 * rotation;
  702. direction.x = rotation.x;
  703. direction.y = rotation.y;
  704. //LOG_TRIVIAL("Entity \"" + entity->GetName() + "\" new move vector: " + Ogre::StringConverter::toString(direction.x) + " " + Ogre::StringConverter::toString(direction.y) + ".");
  705. }
  706. continue;
  707. }
  708. break;
  709. }
  710. }
  711. }
  712. }
  713. //LOG_TRIVIAL("Stop cycle.");
  714. // set new X, Y and Z
  715. last_triangle_check = WalkmeshBorderCross(entity, end_point, direction);
  716. if(first_triangle_check != false || second_triangle_check != false || third_triangle_check != false || last_triangle_check != false ||
  717. first_entity_check != false || second_entity_check != false || third_entity_check != false)
  718. {
  719. LOG_TRIVIAL("Entity \"" + entity->GetName() + "\" can't move to specified position.");
  720. return false;
  721. }
  722. // check triggers before set entity position because we check move line
  723. CheckTriggers(entity, end_point);
  724. entity->SetPosition(end_point);
  725. // if we come to destination point - finish movement
  726. Ogre::Vector3 final = entity->GetMovePosition() - end_point;
  727. if(Ogre::Vector2(final.x, final.y).length() <= entity->GetMoveStopDistance() + speed / 10)
  728. {
  729. entity->UnsetMove();
  730. }
  731. return true;
  732. }
  733. bool
  734. EntityManager::WalkmeshBorderCross(Entity* entity, Ogre::Vector3& position, const Ogre::Vector2& move_vector)
  735. {
  736. int current_triangle = entity->GetMoveTriangleId();
  737. if (current_triangle == -1)
  738. {
  739. return true;
  740. }
  741. Ogre::Vector2 pos = Ogre::Vector2(position.x, position.y);
  742. for(;;)
  743. {
  744. Ogre::Vector3 A3 = m_Walkmesh.GetA(current_triangle);
  745. Ogre::Vector3 B3 = m_Walkmesh.GetB(current_triangle);
  746. Ogre::Vector3 C3 = m_Walkmesh.GetC(current_triangle);
  747. /*LOG_ERROR("Triangle:A(" + Ogre::StringConverter::toString(A3.x) +
  748. " " + Ogre::StringConverter::toString(A3.y) +
  749. " " + Ogre::StringConverter::toString(A3.z) +
  750. ") B(" + Ogre::StringConverter::toString(B3.x) +
  751. " " + Ogre::StringConverter::toString(B3.y) +
  752. " " + Ogre::StringConverter::toString(B3.z) +
  753. ") C(" + Ogre::StringConverter::toString(C3.x) +
  754. " " + Ogre::StringConverter::toString(C3.y) +
  755. " " + Ogre::StringConverter::toString(C3.z) + ").");*/
  756. Ogre::Vector2 A(A3.x, A3.y);
  757. Ogre::Vector2 B(B3.x, B3.y);
  758. Ogre::Vector2 C(C3.x, C3.y);
  759. float sign1 = SideOfVector(pos, B, A);
  760. float sign2 = SideOfVector(pos, C, B);
  761. float sign3 = SideOfVector(pos, A, C);
  762. int next_triangle = -1;
  763. if(sign1 < 0)
  764. {
  765. next_triangle = m_Walkmesh.GetAccessSide(current_triangle, 0);
  766. }
  767. else if(sign2 < 0)
  768. {
  769. next_triangle = m_Walkmesh.GetAccessSide(current_triangle, 1);
  770. }
  771. else if(sign3 < 0)
  772. {
  773. next_triangle = m_Walkmesh.GetAccessSide(current_triangle, 2);
  774. }
  775. else
  776. {
  777. position.z = PointElevation(pos, A3, B3, C3);
  778. //LOG_ERROR("In triangle.");
  779. //LOG_ERROR("Stop CheckTriangles with false and triangle " + Ogre::StringConverter::toString(current_triangle) + ".");
  780. entity->SetMoveTriangleId(current_triangle);
  781. return false;
  782. }
  783. if(next_triangle >= 0)
  784. {
  785. bool lock = m_Walkmesh.IsLocked(next_triangle);
  786. if(lock == false)
  787. {
  788. current_triangle = next_triangle;
  789. continue;
  790. }
  791. }
  792. position.z = PointElevation(pos, A3, B3, C3);
  793. entity->SetMoveTriangleId(current_triangle);
  794. return true;
  795. }
  796. }
  797. bool
  798. EntityManager::CheckSolidCollisions(Entity* entity, Ogre::Vector3& position)
  799. {
  800. if(entity->IsSolid() == false)
  801. {
  802. return false;
  803. }
  804. for(size_t i = 0; i < m_Entity.size(); ++i)
  805. {
  806. if(m_Entity[i]->IsSolid() == false)
  807. {
  808. continue;
  809. }
  810. if(m_Entity[i] == entity)
  811. {
  812. continue;
  813. }
  814. Ogre::Vector3 pos1 = m_Entity[i]->GetPosition();
  815. float solid_range = m_Entity[i]->GetSolidRadius();
  816. solid_range *= solid_range;
  817. float height = (pos1.z < position.z) ? m_Entity[i]->GetHeight() : entity->GetHeight();
  818. //log->logMessage("Height collision(" + Ogre::StringConverter::toString(pos1.z) + " " + Ogre::StringConverter::toString(position.z) + " " + Ogre::StringConverter::toString(height) + ").");
  819. if(((pos1.z - position.z + height) < (height * 2)) && ((pos1.z - position.z + height) >= 0))
  820. {
  821. float distance = (pos1.x - position.x) * (pos1.x - position.x) + (pos1.y - position.y) * (pos1.y - position.y);
  822. //log->logMessage("Dist collision(" + Ogre::StringConverter::toString(solid_range) + " " + Ogre::StringConverter::toString(distance) + ").");
  823. if(distance < solid_range)
  824. {
  825. //log->logMessage("Collide with entity.");
  826. // if this is player and we move by ourself (in ffvii only player model checked)
  827. /*
  828. if (model_id == m_PlayerModelId && m_PlayerModelLock == false)
  829. {
  830. m_FieldScriptManager->AddScript(m_Models[i]->GetName(), "on_collide", 1);
  831. }
  832. */
  833. return true;
  834. }
  835. }
  836. }
  837. //LOGGER->Log(LOGGER_INFO, "Not collide with entity");
  838. return false;
  839. }
  840. void
  841. EntityManager::CheckTriggers(Entity* entity, Ogre::Vector3& position)
  842. {
  843. if(entity->IsSolid() == false)
  844. {
  845. return;
  846. }
  847. for(unsigned int i = 0; i < m_EntityTriggers.size(); ++i)
  848. {
  849. ScriptEntity* scr_entity = ScriptManager::getSingleton().GetScriptEntityByName(ScriptManager::ENTITY, m_EntityTriggers[i]->GetName());
  850. if(scr_entity != nullptr && m_EntityTriggers[i]->IsEnabled() == true)
  851. {
  852. Ogre::Vector3 lp1 = m_EntityTriggers[i]->GetPoint1();
  853. Ogre::Vector3 lp2 = m_EntityTriggers[i]->GetPoint2();
  854. Ogre::Vector3 mp1 = entity->GetPosition();
  855. Ogre::Vector3 proj;
  856. // calculate distance
  857. float square_dist = SquareDistanceToLine(mp1, lp1, lp2, proj);
  858. float solid = entity->GetSolidRadius();
  859. if(square_dist != -1 && square_dist < solid * solid)
  860. {
  861. if(m_EntityTriggers[i]->IsActivator(entity) == false)
  862. {
  863. bool added = ScriptManager::getSingleton().ScriptRequest(scr_entity, "on_enter_line", 1, entity->GetName(), "", false, false);
  864. if(added == false)
  865. {
  866. LOG_WARNING("Script \"on_enter_line\" for entity \"" + m_EntityTriggers[i]->GetName() + "\" doesn't exist.");
  867. }
  868. m_EntityTriggers[i]->AddActivator(entity);
  869. }
  870. // check that 1st and 2nd points are on different side of line
  871. float cond1 = ((lp2.x - lp1.x) * (mp1.y - lp1.y)) - ((mp1.x - lp1.x) * (lp2.y - lp1.y));
  872. float cond2 = ((lp2.x - lp1.x) * (position.y - lp1.y)) - ((position.x - lp1.x) * (lp2.y - lp1.y));
  873. // if we cross the line
  874. if((cond1 > 0 && cond2 <= 0) || (cond2 > 0 && cond1 <= 0) || (cond1 >= 0 && cond2 < 0) || (cond2 >= 0 && cond1 < 0))
  875. {
  876. bool added = ScriptManager::getSingleton().ScriptRequest(scr_entity, "on_cross_line", 1, entity->GetName(), "", false, false);
  877. if(added == false)
  878. {
  879. LOG_WARNING("Script \"on_cross_line\" for entity \"" + m_EntityTriggers[i]->GetName() + "\" doesn't exist.");
  880. }
  881. }
  882. // if we not move in line
  883. if(mp1 == position)
  884. {
  885. bool added = ScriptManager::getSingleton().ScriptRequest(scr_entity, "on_move_to_line", 1, entity->GetName(), "", false, false);
  886. if(added == false)
  887. {
  888. LOG_WARNING("Script \"on_move_to_line\" for entity \"" + m_EntityTriggers[i]->GetName() + "\" doesn't exist.");
  889. }
  890. }
  891. else
  892. {
  893. const Ogre::Degree direction_to_line = GetDirectionToPoint(mp1, proj);
  894. const Ogre::Degree movement_direction = GetDirectionToPoint(mp1, position);
  895. // if we move to line
  896. Ogre::Degree angle = direction_to_line - movement_direction + Ogre::Degree(90);
  897. angle = (angle > Ogre::Degree(360)) ? angle - Ogre::Degree(360) : angle;
  898. if(angle < Ogre::Degree(180) && angle > Ogre::Degree(0))
  899. {
  900. bool added = ScriptManager::getSingleton().ScriptRequest(scr_entity, "on_move_to_line", 1, entity->GetName(), "", false, false);
  901. if(added == false)
  902. {
  903. LOG_WARNING("Script \"on_move_to_line\" for entity \"" + m_EntityTriggers[i]->GetName() + "\" doesn't exist.");
  904. }
  905. }
  906. }
  907. }
  908. else
  909. {
  910. if(m_EntityTriggers[i]->IsActivator(entity) == true)
  911. {
  912. bool added = ScriptManager::getSingleton().ScriptRequest(scr_entity, "on_leave_line", 1, entity->GetName(), "", false, false);
  913. if(added == false)
  914. {
  915. LOG_WARNING("Script \"on_leave_line\" for entity \"" + m_EntityTriggers[i]->GetName() + "\" doesn't exist.");
  916. }
  917. m_EntityTriggers[i]->RemoveActivator(entity);
  918. }
  919. }
  920. }
  921. }
  922. }
  923. void
  924. EntityManager::SetNextOffsetStep(Entity* entity)
  925. {
  926. ActionType type = entity->GetOffsetType();
  927. float total = entity->GetOffsetSeconds();
  928. float current = entity->GetOffsetCurrentSeconds();
  929. current += Timer::getSingleton().GetGameTimeDelta();
  930. current = (current > total) ? total : current;
  931. Ogre::Vector3 start = entity->GetOffsetPositionStart();
  932. Ogre::Vector3 end = entity->GetOffsetPositionEnd();
  933. float x = current / total;
  934. float smooth_modifier = (type == AT_SMOOTH) ? -2 * x * x * x + 3 * x * x : x;
  935. Ogre::Vector3 offset = start + (end - start) * smooth_modifier;
  936. entity->SetOffset(offset);
  937. if(current == total)
  938. {
  939. entity->UnsetOffset();
  940. }
  941. else
  942. {
  943. entity->SetOffsetCurrentSeconds(current);
  944. }
  945. }
  946. void
  947. EntityManager::SetNextTurnStep(Entity* entity)
  948. {
  949. ActionType type = entity->GetTurnType();
  950. float total = entity->GetTurnSeconds();
  951. float current = entity->GetTurnCurrentSeconds();
  952. current += Timer::getSingleton().GetGameTimeDelta();
  953. current = (current > total) ? total : current;
  954. Ogre::Degree start = entity->GetTurnDirectionStart();
  955. Ogre::Degree end = entity->GetTurnDirectionEnd();
  956. float x = current / total;
  957. float smooth_modifier = (type == AT_SMOOTH) ? -2 * x * x * x + 3 * x * x : x;
  958. Ogre::Degree rotation = start + (end - start) * smooth_modifier;
  959. entity->SetRotation(rotation);
  960. if(current == total)
  961. {
  962. entity->UnsetTurn();
  963. }
  964. else
  965. {
  966. entity->SetTurnCurrentSeconds(current);
  967. }
  968. }
  969. void
  970. EntityManager::SetNextLinearStep(Entity* entity)
  971. {
  972. bool to_end = true;
  973. bool is_move = false;
  974. Ogre::Vector3 start = entity->GetLinearStart();
  975. Ogre::Vector3 end = entity->GetLinearEnd();
  976. Ogre::Vector3 current = entity->GetPosition();
  977. float delta = Timer::getSingleton().GetGameTimeDelta();
  978. if(entity == m_PlayerEntity)
  979. {
  980. LinearMovement move = entity->GetLinearMovement();
  981. if(move == LM_DOWN_TO_UP || move == LM_UP_TO_DOWN)
  982. {
  983. if(m_PlayerMove.y > 0) // move up
  984. {
  985. to_end = (move == LM_DOWN_TO_UP) ? true : false;
  986. is_move = true;
  987. }
  988. else if(m_PlayerMove.y < 0) // move down
  989. {
  990. to_end = (move == LM_DOWN_TO_UP) ? false : true;
  991. is_move = true;
  992. }
  993. }
  994. else if(move == LM_LEFT_TO_RIGHT || move == LM_RIGHT_TO_LEFT)
  995. {
  996. if(m_PlayerMove.x > 0) // move right
  997. {
  998. to_end = (move == LM_LEFT_TO_RIGHT) ? true : false;
  999. is_move = true;
  1000. }
  1001. else if(m_PlayerMove.x < 0) // move left
  1002. {
  1003. to_end = (move == LM_LEFT_TO_RIGHT) ? false : true;
  1004. is_move = true;
  1005. }
  1006. }
  1007. }
  1008. else
  1009. {
  1010. is_move = true;
  1011. }
  1012. if(is_move == true)
  1013. {
  1014. Ogre::Vector3 position;
  1015. if(to_end == true)
  1016. {
  1017. Ogre::Vector3 end_start = end - start;
  1018. float time = end_start.length() / 1.2f; // move whole line by this number of seconds
  1019. position.x = current.x + (end_start.x / time) * delta;
  1020. position.y = current.y + (end_start.y / time) * delta;
  1021. position.z = current.z + (end_start.z / time) * delta;
  1022. position.x = (end_start.x < 0) ? std::max(position.x, end.x) : std::min(position.x, end.x);
  1023. position.y = (end_start.y < 0) ? std::max(position.y, end.y) : std::min(position.y, end.y);
  1024. position.z = (end_start.z < 0) ? std::max(position.z, end.z) : std::min(position.z, end.z);
  1025. if(position == end)
  1026. {
  1027. entity->UnsetLinear();
  1028. }
  1029. }
  1030. else
  1031. {
  1032. Ogre::Vector3 end_start = start - end;
  1033. float time = end_start.length() / 1.2f; // move whole line by this number of seconds
  1034. position.x = current.x + (end_start.x / time) * delta;
  1035. position.y = current.y + (end_start.y / time) * delta;
  1036. position.z = current.z + (end_start.z / time) * delta;
  1037. position.x = (end_start.x < 0) ? std::max(position.x, start.x) : std::min(position.x, start.x);
  1038. position.y = (end_start.y < 0) ? std::max(position.y, start.y) : std::min(position.y, start.y);
  1039. position.z = (end_start.z < 0) ? std::max(position.z, start.z) : std::min(position.z, start.z);
  1040. if(position == start)
  1041. {
  1042. entity->UnsetLinear();
  1043. }
  1044. }
  1045. entity->SetPosition(position);
  1046. entity->UpdateAnimation((to_end == true) ? delta : -delta);
  1047. }
  1048. }
  1049. void
  1050. EntityManager::SetNextJumpStep(Entity* entity)
  1051. {
  1052. float total = entity->GetJumpSeconds();
  1053. float current = entity->GetJumpCurrentSeconds();
  1054. current += Timer::getSingleton().GetGameTimeDelta();
  1055. current = (current > total) ? total : current;
  1056. Ogre::Vector3 start_position = entity->GetJumpStart();
  1057. Ogre::Vector3 end_position = entity->GetJumpEnd();
  1058. Ogre::Vector3 position;
  1059. position.x = start_position.x + ((end_position.x - start_position.x) / total) * current;
  1060. position.y = start_position.y + ((end_position.y - start_position.y) / total) * current;
  1061. position.z = current * current * -13.08f + current * ((end_position.z - start_position.z) / total + total * 13.08f) + start_position.z;
  1062. entity->SetPosition(position);
  1063. if(total == current)
  1064. {
  1065. entity->UnsetJump();
  1066. }
  1067. else
  1068. {
  1069. entity->SetJumpCurrentSeconds(current);
  1070. }
  1071. }
  1072. void
  1073. EntityManager::SetNextScrollStep()
  1074. {
  1075. Background2D::ScrollType type = m_Background2D.GetScrollType();
  1076. float total = m_Background2D.GetScrollSeconds();
  1077. float current = m_Background2D.GetScrollCurrentSeconds();
  1078. current += Timer::getSingleton().GetGameTimeDelta();
  1079. current = (current > total) ? total : current;
  1080. Ogre::Vector2 start = m_Background2D.GetScrollPositionStart();
  1081. Ogre::Vector2 end = m_Background2D.GetScrollPositionEnd();
  1082. float x = current / total;
  1083. float smooth_modifier = (type == Background2D::SMOOTH) ? -2 * x * x * x + 3 * x * x : x;
  1084. Ogre::Vector2 scroll = start + (end - start) * smooth_modifier;
  1085. m_Background2D.SetScroll(scroll);
  1086. if(current == total)
  1087. {
  1088. m_Background2D.UnsetScroll();
  1089. }
  1090. else
  1091. {
  1092. m_Background2D.SetScrollCurrentSeconds(current);
  1093. }
  1094. }