Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Selector.cpp 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*!
  2. * \file src/Selector.cpp
  3. * \brief Selector Window
  4. *
  5. * http://antongerdelan.net/opengl/raycasting.html
  6. *
  7. * \author xythobuz
  8. */
  9. #include "imgui/imgui.h"
  10. #include "global.h"
  11. #include "Camera.h"
  12. #include "Log.h"
  13. #include "World.h"
  14. #include "system/Window.h"
  15. #include "Selector.h"
  16. #include <glm/gtx/intersect.hpp>
  17. bool Selector::visible = false;
  18. static int lastX = -1, lastY = -1;
  19. static bool workToDo = false;
  20. static float grabSphere = 102.4f;
  21. static bool clickOnGeometry = false, clickOnRoomModels = true, clickOnRoomSprites = true;
  22. static bool clickOnSprites = true, clickOnMeshes = false, clickOnModels = false;
  23. void Selector::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
  24. if ((button == leftmouseKey) && (!released)) {
  25. lastX = x;
  26. lastY = y;
  27. if (workToDo) {
  28. Log::get(LOG_DEBUG) << "Selector missed mouse click event!" << Log::endl;
  29. }
  30. workToDo = true;
  31. }
  32. }
  33. void Selector::display() {
  34. if (!visible)
  35. return;
  36. if (!ImGui::Begin("Object Selector", &visible, ImVec2(500, 200))) {
  37. ImGui::End();
  38. return;
  39. }
  40. static glm::vec3 rayWorld;
  41. static glm::vec3 lastIntersectPos, lastIntersectNorm;
  42. static unsigned long lastRoom, lastModel;
  43. static bool foundSomething = false;
  44. if (workToDo) {
  45. // Calculate click ray
  46. glm::vec2 normalized = glm::vec2((2.0f * lastX) / Window::getSize().x - 1.0f,
  47. 1.0f - (2.0f * lastY) / Window::getSize().y);
  48. glm::vec4 rayClip(normalized.x, normalized.y, -1.0f, 1.0f);
  49. glm::vec4 rayEye(glm::inverse(Camera::getProjectionMatrix()) * rayClip);
  50. rayEye = glm::vec4(rayEye.x, rayEye.y, -1.0f, 0.0f);
  51. rayWorld = glm::vec3(glm::inverse(Camera::getViewMatrix()) * rayEye);
  52. rayWorld = glm::normalize(rayWorld);
  53. workToDo = false;
  54. // Check for any intersections with object bounding spheres
  55. if (clickOnModels) {
  56. }
  57. if (clickOnMeshes) {
  58. }
  59. if (clickOnSprites) {
  60. }
  61. if (clickOnRoomModels) {
  62. for (unsigned long i = 0; i < World::sizeRoom(); i++) {
  63. Room& r = World::getRoom(i);
  64. for (unsigned long j = 0; j < r.sizeModels(); j++) {
  65. StaticModel& sm = r.getModel(j);
  66. glm::vec3 pos, norm;
  67. if (glm::intersectRaySphere(Camera::getPosition(), rayWorld, sm.getCenter(), sm.getRadius(),
  68. pos, norm)) {
  69. //! \fixme This is not enough. Should be depth sorted?!
  70. lastRoom = i;
  71. lastModel = j;
  72. lastIntersectPos = pos;
  73. lastIntersectNorm = norm;
  74. foundSomething = true;
  75. }
  76. }
  77. }
  78. }
  79. if (clickOnRoomSprites) {
  80. }
  81. if (clickOnGeometry) {
  82. }
  83. }
  84. ImGui::SliderFloat("Grab Sphere", &grabSphere, 0.1f, 10240.0f);
  85. ImGui::Checkbox("Geometry", &clickOnGeometry);
  86. ImGui::SameLine();
  87. ImGui::Checkbox("RoomModels", &clickOnRoomModels);
  88. ImGui::SameLine();
  89. ImGui::Checkbox("RoomSprites", &clickOnRoomSprites);
  90. ImGui::Checkbox("Sprites", &clickOnSprites);
  91. ImGui::SameLine();
  92. ImGui::Checkbox("Meshes", &clickOnMeshes);
  93. ImGui::SameLine();
  94. ImGui::Checkbox("Models", &clickOnModels);
  95. ImGui::SameLine();
  96. if (ImGui::Button("Hide Selector")) {
  97. visible = false;
  98. }
  99. ImGui::Separator();
  100. // Not yet implemented!
  101. clickOnModels = false;
  102. clickOnMeshes = false;
  103. clickOnSprites = false;
  104. clickOnRoomSprites = false;
  105. clickOnGeometry = false;
  106. ImGui::Text("Camera: (%.2f %.2f %.2f)", Camera::getPosition().x, Camera::getPosition().y, Camera::getPosition().z);
  107. ImGui::Text("Last click: (%d %d)", lastX, lastY);
  108. if ((lastX >= 0) && (lastY >= 0)) {
  109. ImGui::Text("Normalized Ray: (%.3f %.3f %.3f)", rayWorld.x, rayWorld.y, rayWorld.z);
  110. }
  111. if (foundSomething) {
  112. ImGui::Text("Intersect Pos: (%.2f %.2f %.2f)", lastIntersectPos.x, lastIntersectPos.y, lastIntersectPos.z);
  113. ImGui::Text("Intersect Norm: (%.2f %.2f %.2f)", lastIntersectNorm.x, lastIntersectNorm.y, lastIntersectNorm.z);
  114. ImGui::Text("Last Room: %lu", lastRoom);
  115. ImGui::Text("Last RoomModel: %lu", lastModel);
  116. }
  117. ImGui::End();
  118. }