@@ -26,6 +26,11 @@ static constexpr std::array<
26
26
{GameRenderer::ZoneCylinderB, " zonecylb.dff" , " particle" },
27
27
{GameRenderer::Arrow, " arrow.dff" , " " }}};
28
28
const auto kViewerFov = glm::radians(90 .f);
29
+
30
+ auto viewAnglesToQuat (float yaw, float pitch) {
31
+ return glm::angleAxis (glm::radians (yaw), glm::vec3 (0 .f , 0 .f , -1 .f )) *
32
+ glm::angleAxis (glm::radians (pitch), glm::vec3 (0 .f , 1 .f , 0 .f ));
33
+ }
29
34
} // namespace
30
35
31
36
RWViewer::RWViewer (Logger& log, const std::optional<RWArgConfigLayer>& args)
@@ -47,6 +52,7 @@ RWViewer::RWViewer(Logger& log, const std::optional<RWArgConfigLayer>& args)
47
52
48
53
data_.load ();
49
54
textViewer_.emplace (data_);
55
+ iplViewer_.emplace (log , data_);
50
56
51
57
for (const auto & [specialModel, fileName, name] : kSpecialModels ) {
52
58
auto model = data_.loadClump (fileName, name);
@@ -133,15 +139,15 @@ bool RWViewer::updateInput() {
133
139
break ;
134
140
135
141
case SDL_MOUSEWHEEL:
136
- viewParams_ .z =
137
- glm::max (1 .f , viewParams_ .z +
138
- -(event.wheel .y * viewParams_ .z * 0 .1f ));
142
+ viewAngles_ .z =
143
+ glm::max (1 .f , viewAngles_ .z +
144
+ -(event.wheel .y * viewAngles_ .z * 0 .1f ));
139
145
break ;
140
146
141
147
case SDL_MOUSEMOTION:
142
148
if (mouseMode_ == MouseMode::Dragging) {
143
- viewParams_ .x += event.motion .xrel * 0 .5f ;
144
- viewParams_ .y += event.motion .yrel * 0 .5f ;
149
+ viewAngles_ .x += event.motion .xrel * 0 .5f ;
150
+ viewAngles_ .y += event.motion .yrel * 0 .5f ;
145
151
}
146
152
break ;
147
153
}
@@ -166,26 +172,28 @@ void RWViewer::render(float alpha, float time) {
166
172
167
173
ViewCamera viewCam{};
168
174
viewCam.frustum .fov = kViewerFov ;
169
-
170
- if (viewedObject_) {
171
- auto rotation = glm::angleAxis (glm::radians (viewParams_.x ),
172
- glm::vec3 (0 .f , 0 .f , -1 .f )) *
173
- glm::angleAxis (glm::radians (viewParams_.y ),
174
- glm::vec3 (0 .f , 1 .f , 0 .f ));
175
- auto viewDirection = rotation * glm::vec3{-1 .f , 0 .f , 0 .f };
176
- viewCam.position = viewDirection * viewParams_.z ;
177
- viewCam.rotation = rotation;
178
- }
179
-
180
175
viewCam.frustum .aspectRatio =
181
176
windowSize.x / static_cast <float >(windowSize.y );
182
177
178
+ viewCam.rotation = viewAnglesToQuat (viewAngles_.x , viewAngles_.y );
179
+
183
180
glEnable (GL_DEPTH_TEST);
184
181
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
185
182
186
183
renderer_.getRenderer ().pushDebugGroup (" World" );
187
184
188
- renderer_.renderWorld (world_.get (), viewCam, alpha);
185
+ switch (viewMode_) {
186
+ case ViewMode::Model: {
187
+ auto viewDirection = viewCam.rotation * glm::vec3{-1 .f , 0 .f , 0 .f };
188
+ viewCam.position = viewDirection * viewAngles_.z ;
189
+ renderer_.renderWorld (world_.get (), viewCam, alpha);
190
+ break ;
191
+ }
192
+ case ViewMode::World:
193
+ viewCam.position = viewPosition_;
194
+ renderer_.renderWorld (iplViewer_->world (), viewCam, alpha);
195
+ break ;
196
+ }
189
197
190
198
renderer_.getRenderer ().popDebugGroup ();
191
199
@@ -196,13 +204,32 @@ void RWViewer::render(float alpha, float time) {
196
204
}
197
205
198
206
void RWViewer::globalKeyEvent (const SDL_Event& event) {
207
+ auto r = viewAnglesToQuat (viewAngles_.x , viewAngles_.y );
199
208
switch (event.key .keysym .sym ) {
200
209
case SDLK_LEFTBRACKET:
201
210
world_->offsetGameTime (-30 );
202
211
break ;
203
212
case SDLK_RIGHTBRACKET:
204
213
world_->offsetGameTime (30 );
205
214
break ;
215
+
216
+ case SDLK_w:
217
+ case SDLK_UP:
218
+ viewPosition_ += r * glm::vec3{1 .f , 0 .f , 0 .f };
219
+ break ;
220
+ case SDLK_s:
221
+ case SDLK_DOWN:
222
+ viewPosition_ -= r * glm::vec3{1 .f , 0 .f , 0 .f };
223
+ break ;
224
+ case SDLK_a:
225
+ case SDLK_LEFT:
226
+ viewPosition_ += r * glm::vec3{0 .f , 1 .f , 0 .f };
227
+ break ;
228
+ case SDLK_d:
229
+ case SDLK_RIGHT:
230
+ viewPosition_ -= r * glm::vec3{0 .f , 1 .f , 0 .f };
231
+ break ;
232
+
206
233
default :
207
234
break ;
208
235
}
@@ -220,7 +247,10 @@ void RWViewer::drawMenu() {
220
247
}
221
248
});
222
249
menu (" View" , [&]() {
223
- ImGui::MenuItem (" Model" , " " , viewedObject_ != nullptr );
250
+ if (ImGui::MenuItem (" Model" , " " , viewMode_ == ViewMode::Model))
251
+ viewMode_ = ViewMode::Model;
252
+ if (ImGui::MenuItem (" World" , " " , viewMode_ == ViewMode::World))
253
+ viewMode_ = ViewMode::World;
224
254
if (ImGui::MenuItem (" Remove Object" , " " )) {
225
255
if (viewedObject_) {
226
256
world_->destroyObject (viewedObject_);
@@ -231,6 +261,7 @@ void RWViewer::drawMenu() {
231
261
menu (" Windows" , [&]() {
232
262
ImGui::MenuItem (" Models" , " " , &showModelList_);
233
263
ImGui::MenuItem (" Texts" , " " , &showTextViewer_);
264
+ ImGui::MenuItem (" Map" , " " , &showIplViewer_);
234
265
ImGui::Separator ();
235
266
ImGui::MenuItem (" Demo" , " " , &showImGuiDemo_);
236
267
});
@@ -297,6 +328,9 @@ void RWViewer::drawWindows() {
297
328
window (" Texts" , showTextViewer_, {920 , 320 },
298
329
[&]() { textViewer_->draw (renderer_); });
299
330
331
+ window (" Map" , showIplViewer_, {320 , 320 },
332
+ [&]() { iplViewer_->draw (renderer_); });
333
+
300
334
if (showImGuiDemo_) ImGui::ShowDemoWindow (&showImGuiDemo_);
301
335
}
302
336
@@ -327,6 +361,7 @@ void RWViewer::drawModelWindow(ModelID id) {
327
361
}
328
362
329
363
void RWViewer::viewModel (ModelID model) {
364
+ viewMode_ = ViewMode::Model;
330
365
if (viewedObject_) {
331
366
world_->destroyObject (viewedObject_);
332
367
viewedObject_ = nullptr ;
@@ -357,5 +392,5 @@ void RWViewer::viewModel(ModelID model) {
357
392
radius = glm::length (geo.center ) + geo.radius ;
358
393
}
359
394
constexpr auto kViewSlop = 1 .f ;
360
- viewParams_ .z = kViewSlop * ((radius * 2 ) / (glm::tan (kViewerFov / 2 .f )));
395
+ viewAngles_ .z = kViewSlop * ((radius * 2 ) / (glm::tan (kViewerFov / 2 .f )));
361
396
}
0 commit comments