Browse Source

Improved Selector, fixed depth sorting issue

Thomas Buck 8 years ago
parent
commit
704b2eb2fe
5 changed files with 91 additions and 66 deletions
  1. 1
    1
      include/BoundingSphere.h
  2. 8
    0
      include/Selector.h
  3. 11
    0
      include/global.h
  4. 3
    0
      src/Render.cpp
  5. 68
    65
      src/Selector.cpp

+ 1
- 1
include/BoundingSphere.h View File

@@ -12,7 +12,7 @@
12 12
 
13 13
 class BoundingSphere {
14 14
   public:
15
-    BoundingSphere(glm::vec3 p = glm::vec3(0.0f, 0.0f, 0.0f), float r = 100.0f, int res = 10) : pos(p), radius(r), resolution(res) { }
15
+    BoundingSphere(glm::vec3 p = glm::vec3(0.0f, 0.0f, 0.0f), float r = 100.0f, int res = 42) : pos(p), radius(r), resolution(res) { }
16 16
 
17 17
     void setPosition(glm::vec3 p) { pos = p; }
18 18
     glm::vec3 getPosition() { return pos; }

+ 8
- 0
include/Selector.h View File

@@ -8,8 +8,11 @@
8 8
 #ifndef _SELECTOR_H_
9 9
 #define _SELECTOR_H_
10 10
 
11
+#include <array>
12
+
11 13
 class Selector {
12 14
   public:
15
+    static void displaySelection();
13 16
     static void display();
14 17
 
15 18
     static bool isVisible() { return visible; }
@@ -19,6 +22,11 @@ class Selector {
19 22
 
20 23
   private:
21 24
     static bool visible;
25
+    static WorldObjects lastClickedObject;
26
+    static std::array<bool, WorldObjectCount> clickOnObject;
27
+    static glm::i32vec2 rayScreen;
28
+    static glm::vec3 rayWorld, lastIntersectPos, lastIntersectNorm;
29
+    static unsigned long lastIndexA, lastIndexB;
22 30
 };
23 31
 
24 32
 #endif

+ 11
- 0
include/global.h View File

@@ -11,6 +11,17 @@
11 11
 
12 12
 void renderFrame();
13 13
 
14
+typedef enum {
15
+    geometryObject = 0,
16
+    roomSpriteObject,
17
+    roomModelObject,
18
+    spriteObject,
19
+    meshObject,
20
+    modelObject,
21
+
22
+    WorldObjectCount // Should always be at the end
23
+} WorldObjects;
24
+
14 25
 // Actions that can be bound to a key and sent to the game engine
15 26
 typedef enum {
16 27
     menuAction = 0,

+ 3
- 0
src/Render.cpp View File

@@ -15,6 +15,7 @@
15 15
 #include "Camera.h"
16 16
 #include "Log.h"
17 17
 #include "Menu.h"
18
+#include "Selector.h"
18 19
 #include "StaticMesh.h"
19 20
 #include "World.h"
20 21
 #include "system/Shader.h"
@@ -91,6 +92,8 @@ void Render::display() {
91 92
     if (displayViewFrustum)
92 93
         Camera::displayFrustum(VP);
93 94
 
95
+    Selector::displaySelection();
96
+
94 97
     BoundingBox::display();
95 98
     BoundingSphere::display();
96 99
 

+ 68
- 65
src/Selector.cpp View File

@@ -19,101 +19,103 @@
19 19
 #include <glm/gtx/intersect.hpp>
20 20
 
21 21
 bool Selector::visible = false;
22
-
23
-static int lastX = -1, lastY = -1;
24
-static bool workToDo = false;
25
-static bool clickOnGeometry = false, clickOnRoomModels = true, clickOnRoomSprites = true;
26
-static bool clickOnSprites = true, clickOnMeshes = false, clickOnModels = false;
22
+WorldObjects Selector::lastClickedObject = WorldObjectCount;
23
+std::array<bool, WorldObjectCount> Selector::clickOnObject = {{ false, true, true, true, false, false }};
24
+glm::i32vec2 Selector::rayScreen(-1, -1);
25
+glm::vec3 Selector::rayWorld, Selector::lastIntersectPos, Selector::lastIntersectNorm;
26
+unsigned long Selector::lastIndexA, Selector::lastIndexB;
27 27
 
28 28
 void Selector::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
29 29
     if ((button == leftmouseKey) && (!released)) {
30
-        lastX = x;
31
-        lastY = y;
32
-
33
-        if (workToDo) {
34
-            Log::get(LOG_DEBUG) << "Selector missed mouse click event!" << Log::endl;
35
-        }
36
-
37
-        workToDo = true;
38
-    }
39
-}
40
-
41
-void Selector::display() {
42
-    if (!visible)
43
-        return;
44
-
45
-    if (!ImGui::Begin("Object Selector", &visible, ImVec2(500, 200))) {
46
-        ImGui::End();
47
-        return;
48
-    }
49
-
50
-    static glm::vec3 rayWorld;
51
-    static glm::vec3 lastIntersectPos, lastIntersectNorm;
52
-    static unsigned long lastRoom, lastModel;
53
-    static bool foundSomething = false;
54
-
55
-    if (workToDo) {
56 30
         // Calculate click ray
57
-        glm::vec2 normalized = glm::vec2((2.0f * lastX) / Window::getSize().x - 1.0f,
58
-                                         1.0f - (2.0f * lastY) / Window::getSize().y);
31
+        rayScreen = glm::vec2(x, y);
32
+        glm::vec2 normalized = glm::vec2((2.0f * rayScreen.x) / Window::getSize().x - 1.0f,
33
+                                         1.0f - (2.0f * rayScreen.y) / Window::getSize().y);
59 34
         glm::vec4 rayClip(normalized.x, normalized.y, -1.0f, 1.0f);
60 35
         glm::vec4 rayEye(glm::inverse(Camera::getProjectionMatrix()) * rayClip);
61 36
         rayEye = glm::vec4(rayEye.x, rayEye.y, -1.0f, 0.0f);
62 37
         rayWorld = glm::vec3(glm::inverse(Camera::getViewMatrix()) * rayEye);
63 38
         rayWorld = glm::normalize(rayWorld);
64
-        workToDo = false;
65 39
 
66 40
         // Check for any intersections with object bounding spheres
67
-        if (clickOnModels) {
41
+        bool foundSomething = false;
42
+        float depth = -1.0f;
43
+
44
+        if (clickOnObject[modelObject]) {
68 45
 
69 46
         }
70 47
 
71
-        if (clickOnMeshes) {
48
+        if (clickOnObject[meshObject]) {
72 49
 
73 50
         }
74 51
 
75
-        if (clickOnSprites) {
52
+        if (clickOnObject[spriteObject]) {
76 53
 
77 54
         }
78 55
 
79
-        if (clickOnRoomModels) {
56
+        if (clickOnObject[roomModelObject]) {
80 57
             for (unsigned long i = 0; i < World::sizeRoom(); i++) {
81
-                Room& r = World::getRoom(i);
58
+                Room &r = World::getRoom(i);
82 59
                 for (unsigned long j = 0; j < r.sizeModels(); j++) {
83
-                    StaticModel& sm = r.getModel(j);
60
+                    StaticModel &sm = r.getModel(j);
84 61
                     glm::vec3 pos, norm;
85 62
                     if (glm::intersectRaySphere(Camera::getPosition(), rayWorld, sm.getCenter(), sm.getRadius(),
86 63
                                                 pos, norm)) {
87
-                        //! \fixme This is not enough. Should be depth sorted?!
88
-                        lastRoom = i;
89
-                        lastModel = j;
90
-                        lastIntersectPos = pos;
91
-                        lastIntersectNorm = norm;
92
-                        foundSomething = true;
64
+                        float newDepth = glm::abs(glm::distance(sm.getCenter(), Camera::getPosition()));
65
+                        if ((newDepth < depth) || (depth < 0.0f)) {
66
+                            depth = newDepth;
67
+                            lastIndexA = i;
68
+                            lastIndexB = j;
69
+                            lastIntersectPos = pos;
70
+                            lastIntersectNorm = norm;
71
+                            lastClickedObject = roomModelObject;
72
+                            foundSomething = true;
73
+                        }
93 74
                     }
94 75
                 }
95 76
             }
96 77
         }
97 78
 
98
-        if (clickOnRoomSprites) {
79
+        if (clickOnObject[roomSpriteObject]) {
99 80
 
100 81
         }
101 82
 
102
-        if (clickOnGeometry) {
83
+        if (clickOnObject[geometryObject]) {
103 84
 
85
+
86
+        }
87
+
88
+        if (!foundSomething) {
89
+            lastClickedObject = WorldObjectCount;
104 90
         }
105 91
     }
92
+}
106 93
 
107
-    ImGui::Checkbox("Geometry", &clickOnGeometry);
94
+void Selector::displaySelection() {
95
+    if (lastClickedObject == roomModelObject) {
96
+        World::getRoom(lastIndexA).getModel(lastIndexB).displayBoundingSphere(Camera::getProjectionMatrix() * Camera::getViewMatrix(), glm::vec3(1.0f, 0.0f, 0.0f));
97
+    }
98
+}
99
+
100
+void Selector::display() {
101
+    if (!visible)
102
+        return;
103
+
104
+    if (!ImGui::Begin("Object Selector", &visible, ImVec2(500, 200))) {
105
+        ImGui::End();
106
+        return;
107
+    }
108
+
109
+    ImGui::Checkbox("Geometry", &clickOnObject[geometryObject]);
108 110
     ImGui::SameLine();
109
-    ImGui::Checkbox("RoomModels", &clickOnRoomModels);
111
+    ImGui::Checkbox("RoomModels", &clickOnObject[roomModelObject]);
110 112
     ImGui::SameLine();
111
-    ImGui::Checkbox("RoomSprites", &clickOnRoomSprites);
112
-    ImGui::Checkbox("Sprites", &clickOnSprites);
113
+    ImGui::Checkbox("RoomSprites", &clickOnObject[roomSpriteObject]);
114
+    ImGui::Checkbox("Sprites", &clickOnObject[spriteObject]);
113 115
     ImGui::SameLine();
114
-    ImGui::Checkbox("Meshes", &clickOnMeshes);
116
+    ImGui::Checkbox("Meshes", &clickOnObject[meshObject]);
115 117
     ImGui::SameLine();
116
-    ImGui::Checkbox("Models", &clickOnModels);
118
+    ImGui::Checkbox("Models", &clickOnObject[modelObject]);
117 119
     ImGui::SameLine();
118 120
     if (ImGui::Button("Hide Selector")) {
119 121
         visible = false;
@@ -121,25 +123,26 @@ void Selector::display() {
121 123
     ImGui::Separator();
122 124
 
123 125
     // Not yet implemented!
124
-    clickOnModels = false;
125
-    clickOnMeshes = false;
126
-    clickOnSprites = false;
127
-    clickOnRoomSprites = false;
128
-    clickOnGeometry = false;
126
+    clickOnObject[modelObject] = false;
127
+    clickOnObject[meshObject] = false;
128
+    clickOnObject[spriteObject] = false;
129
+    clickOnObject[roomSpriteObject] = false;
130
+    clickOnObject[geometryObject] = false;
129 131
 
130 132
     ImGui::Text("Camera: (%.2f %.2f %.2f)", Camera::getPosition().x, Camera::getPosition().y, Camera::getPosition().z);
131
-    ImGui::Text("Last click: (%d %d)", lastX, lastY);
132
-    if ((lastX >= 0) && (lastY >= 0)) {
133
+    ImGui::Text("Last click: (%d %d)", rayScreen.x, rayScreen.y);
134
+    if ((rayScreen.x >= 0) && (rayScreen.y >= 0)) {
133 135
         ImGui::Text("Normalized Ray: (%.3f %.3f %.3f)", rayWorld.x, rayWorld.y, rayWorld.z);
134 136
     }
135 137
 
136
-    if (foundSomething) {
138
+    if (lastClickedObject != WorldObjectCount) {
137 139
         ImGui::Text("Intersect Pos: (%.2f %.2f %.2f)", lastIntersectPos.x, lastIntersectPos.y, lastIntersectPos.z);
138 140
         ImGui::Text("Intersect Norm: (%.2f %.2f %.2f)", lastIntersectNorm.x, lastIntersectNorm.y, lastIntersectNorm.z);
139
-        ImGui::Text("Last Room: %lu", lastRoom);
140
-        ImGui::Text("Last RoomModel: %lu", lastModel);
141
+    }
141 142
 
142
-        World::getRoom(lastRoom).getModel(lastModel).displayBoundingSphere(Camera::getProjectionMatrix() * Camera::getViewMatrix(), glm::vec3(1.0f, 0.0f, 0.0f));
143
+    if (lastClickedObject == roomModelObject) {
144
+        ImGui::Text("Last Room: %lu", lastIndexA);
145
+        ImGui::Text("Last RoomModel: %lu", lastIndexB);
143 146
     }
144 147
 
145 148
     ImGui::End();

Loading…
Cancel
Save