瀏覽代碼

Improved Selector, fixed depth sorting issue

Thomas Buck 9 年之前
父節點
當前提交
704b2eb2fe
共有 5 個檔案被更改,包括 91 行新增66 行删除
  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 查看文件

12
 
12
 
13
 class BoundingSphere {
13
 class BoundingSphere {
14
   public:
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
     void setPosition(glm::vec3 p) { pos = p; }
17
     void setPosition(glm::vec3 p) { pos = p; }
18
     glm::vec3 getPosition() { return pos; }
18
     glm::vec3 getPosition() { return pos; }

+ 8
- 0
include/Selector.h 查看文件

8
 #ifndef _SELECTOR_H_
8
 #ifndef _SELECTOR_H_
9
 #define _SELECTOR_H_
9
 #define _SELECTOR_H_
10
 
10
 
11
+#include <array>
12
+
11
 class Selector {
13
 class Selector {
12
   public:
14
   public:
15
+    static void displaySelection();
13
     static void display();
16
     static void display();
14
 
17
 
15
     static bool isVisible() { return visible; }
18
     static bool isVisible() { return visible; }
19
 
22
 
20
   private:
23
   private:
21
     static bool visible;
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
 #endif
32
 #endif

+ 11
- 0
include/global.h 查看文件

11
 
11
 
12
 void renderFrame();
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
 // Actions that can be bound to a key and sent to the game engine
25
 // Actions that can be bound to a key and sent to the game engine
15
 typedef enum {
26
 typedef enum {
16
     menuAction = 0,
27
     menuAction = 0,

+ 3
- 0
src/Render.cpp 查看文件

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

+ 68
- 65
src/Selector.cpp 查看文件

19
 #include <glm/gtx/intersect.hpp>
19
 #include <glm/gtx/intersect.hpp>
20
 
20
 
21
 bool Selector::visible = false;
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
 void Selector::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
28
 void Selector::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
29
     if ((button == leftmouseKey) && (!released)) {
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
         // Calculate click ray
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
         glm::vec4 rayClip(normalized.x, normalized.y, -1.0f, 1.0f);
34
         glm::vec4 rayClip(normalized.x, normalized.y, -1.0f, 1.0f);
60
         glm::vec4 rayEye(glm::inverse(Camera::getProjectionMatrix()) * rayClip);
35
         glm::vec4 rayEye(glm::inverse(Camera::getProjectionMatrix()) * rayClip);
61
         rayEye = glm::vec4(rayEye.x, rayEye.y, -1.0f, 0.0f);
36
         rayEye = glm::vec4(rayEye.x, rayEye.y, -1.0f, 0.0f);
62
         rayWorld = glm::vec3(glm::inverse(Camera::getViewMatrix()) * rayEye);
37
         rayWorld = glm::vec3(glm::inverse(Camera::getViewMatrix()) * rayEye);
63
         rayWorld = glm::normalize(rayWorld);
38
         rayWorld = glm::normalize(rayWorld);
64
-        workToDo = false;
65
 
39
 
66
         // Check for any intersections with object bounding spheres
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
             for (unsigned long i = 0; i < World::sizeRoom(); i++) {
57
             for (unsigned long i = 0; i < World::sizeRoom(); i++) {
81
-                Room& r = World::getRoom(i);
58
+                Room &r = World::getRoom(i);
82
                 for (unsigned long j = 0; j < r.sizeModels(); j++) {
59
                 for (unsigned long j = 0; j < r.sizeModels(); j++) {
83
-                    StaticModel& sm = r.getModel(j);
60
+                    StaticModel &sm = r.getModel(j);
84
                     glm::vec3 pos, norm;
61
                     glm::vec3 pos, norm;
85
                     if (glm::intersectRaySphere(Camera::getPosition(), rayWorld, sm.getCenter(), sm.getRadius(),
62
                     if (glm::intersectRaySphere(Camera::getPosition(), rayWorld, sm.getCenter(), sm.getRadius(),
86
                                                 pos, norm)) {
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
     ImGui::SameLine();
110
     ImGui::SameLine();
109
-    ImGui::Checkbox("RoomModels", &clickOnRoomModels);
111
+    ImGui::Checkbox("RoomModels", &clickOnObject[roomModelObject]);
110
     ImGui::SameLine();
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
     ImGui::SameLine();
115
     ImGui::SameLine();
114
-    ImGui::Checkbox("Meshes", &clickOnMeshes);
116
+    ImGui::Checkbox("Meshes", &clickOnObject[meshObject]);
115
     ImGui::SameLine();
117
     ImGui::SameLine();
116
-    ImGui::Checkbox("Models", &clickOnModels);
118
+    ImGui::Checkbox("Models", &clickOnObject[modelObject]);
117
     ImGui::SameLine();
119
     ImGui::SameLine();
118
     if (ImGui::Button("Hide Selector")) {
120
     if (ImGui::Button("Hide Selector")) {
119
         visible = false;
121
         visible = false;
121
     ImGui::Separator();
123
     ImGui::Separator();
122
 
124
 
123
     // Not yet implemented!
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
     ImGui::Text("Camera: (%.2f %.2f %.2f)", Camera::getPosition().x, Camera::getPosition().y, Camera::getPosition().z);
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
         ImGui::Text("Normalized Ray: (%.3f %.3f %.3f)", rayWorld.x, rayWorld.y, rayWorld.z);
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
         ImGui::Text("Intersect Pos: (%.2f %.2f %.2f)", lastIntersectPos.x, lastIntersectPos.y, lastIntersectPos.z);
139
         ImGui::Text("Intersect Pos: (%.2f %.2f %.2f)", lastIntersectPos.x, lastIntersectPos.y, lastIntersectPos.z);
138
         ImGui::Text("Intersect Norm: (%.2f %.2f %.2f)", lastIntersectNorm.x, lastIntersectNorm.y, lastIntersectNorm.z);
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
     ImGui::End();
148
     ImGui::End();

Loading…
取消
儲存