|
@@ -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();
|