Skip to content

Commit

Permalink
Map IPL Viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
danhedron committed Jun 5, 2019
1 parent 059a8e0 commit 1781652
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 22 deletions.
73 changes: 54 additions & 19 deletions rwgame/viewer/RWViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ static constexpr std::array<
{GameRenderer::ZoneCylinderB, "zonecylb.dff", "particle"},
{GameRenderer::Arrow, "arrow.dff", ""}}};
const auto kViewerFov = glm::radians(90.f);

auto viewAnglesToQuat(float yaw, float pitch) {
return glm::angleAxis(glm::radians(yaw), glm::vec3(0.f, 0.f, -1.f)) *
glm::angleAxis(glm::radians(pitch), glm::vec3(0.f, 1.f, 0.f));
}
} // namespace

RWViewer::RWViewer(Logger& log, const std::optional<RWArgConfigLayer>& args)
Expand All @@ -47,6 +52,7 @@ RWViewer::RWViewer(Logger& log, const std::optional<RWArgConfigLayer>& args)

data_.load();
textViewer_.emplace(data_);
iplViewer_.emplace(log, data_);

for (const auto& [specialModel, fileName, name] : kSpecialModels) {
auto model = data_.loadClump(fileName, name);
Expand Down Expand Up @@ -133,15 +139,15 @@ bool RWViewer::updateInput() {
break;

case SDL_MOUSEWHEEL:
viewParams_.z =
glm::max(1.f, viewParams_.z +
-(event.wheel.y * viewParams_.z * 0.1f));
viewAngles_.z =
glm::max(1.f, viewAngles_.z +
-(event.wheel.y * viewAngles_.z * 0.1f));
break;

case SDL_MOUSEMOTION:
if (mouseMode_ == MouseMode::Dragging) {
viewParams_.x += event.motion.xrel * 0.5f;
viewParams_.y += event.motion.yrel * 0.5f;
viewAngles_.x += event.motion.xrel * 0.5f;
viewAngles_.y += event.motion.yrel * 0.5f;
}
break;
}
Expand All @@ -166,26 +172,28 @@ void RWViewer::render(float alpha, float time) {

ViewCamera viewCam{};
viewCam.frustum.fov = kViewerFov;

if (viewedObject_) {
auto rotation = glm::angleAxis(glm::radians(viewParams_.x),
glm::vec3(0.f, 0.f, -1.f)) *
glm::angleAxis(glm::radians(viewParams_.y),
glm::vec3(0.f, 1.f, 0.f));
auto viewDirection = rotation * glm::vec3{-1.f, 0.f, 0.f};
viewCam.position = viewDirection * viewParams_.z;
viewCam.rotation = rotation;
}

viewCam.frustum.aspectRatio =
windowSize.x / static_cast<float>(windowSize.y);

viewCam.rotation = viewAnglesToQuat(viewAngles_.x, viewAngles_.y);

glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

renderer_.getRenderer().pushDebugGroup("World");

renderer_.renderWorld(world_.get(), viewCam, alpha);
switch (viewMode_) {
case ViewMode::Model: {
auto viewDirection = viewCam.rotation * glm::vec3{-1.f, 0.f, 0.f};
viewCam.position = viewDirection * viewAngles_.z;
renderer_.renderWorld(world_.get(), viewCam, alpha);
break;
}
case ViewMode::World:
viewCam.position = viewPosition_;
renderer_.renderWorld(iplViewer_->world(), viewCam, alpha);
break;
}

renderer_.getRenderer().popDebugGroup();

Expand All @@ -196,13 +204,32 @@ void RWViewer::render(float alpha, float time) {
}

void RWViewer::globalKeyEvent(const SDL_Event& event) {
auto r = viewAnglesToQuat(viewAngles_.x, viewAngles_.y);
switch (event.key.keysym.sym) {
case SDLK_LEFTBRACKET:
world_->offsetGameTime(-30);
break;
case SDLK_RIGHTBRACKET:
world_->offsetGameTime(30);
break;

case SDLK_w:
case SDLK_UP:
viewPosition_ += r * glm::vec3{1.f, 0.f, 0.f};
break;
case SDLK_s:
case SDLK_DOWN:
viewPosition_ -= r * glm::vec3{1.f, 0.f, 0.f};
break;
case SDLK_a:
case SDLK_LEFT:
viewPosition_ += r * glm::vec3{0.f, 1.f, 0.f};
break;
case SDLK_d:
case SDLK_RIGHT:
viewPosition_ -= r * glm::vec3{0.f, 1.f, 0.f};
break;

default:
break;
}
Expand All @@ -220,7 +247,10 @@ void RWViewer::drawMenu() {
}
});
menu("View", [&]() {
ImGui::MenuItem("Model", "", viewedObject_ != nullptr);
if (ImGui::MenuItem("Model", "", viewMode_ == ViewMode::Model))
viewMode_ = ViewMode::Model;
if (ImGui::MenuItem("World", "", viewMode_ == ViewMode::World))
viewMode_ = ViewMode::World;
if (ImGui::MenuItem("Remove Object", "")) {
if (viewedObject_) {
world_->destroyObject(viewedObject_);
Expand All @@ -231,6 +261,7 @@ void RWViewer::drawMenu() {
menu("Windows", [&]() {
ImGui::MenuItem("Models", "", &showModelList_);
ImGui::MenuItem("Texts", "", &showTextViewer_);
ImGui::MenuItem("Map", "", &showIplViewer_);
ImGui::Separator();
ImGui::MenuItem("Demo", "", &showImGuiDemo_);
});
Expand Down Expand Up @@ -297,6 +328,9 @@ void RWViewer::drawWindows() {
window("Texts", showTextViewer_, {920, 320},
[&]() { textViewer_->draw(renderer_); });

window("Map", showIplViewer_, {320, 320},
[&]() { iplViewer_->draw(renderer_); });

if (showImGuiDemo_) ImGui::ShowDemoWindow(&showImGuiDemo_);
}

Expand Down Expand Up @@ -327,6 +361,7 @@ void RWViewer::drawModelWindow(ModelID id) {
}

void RWViewer::viewModel(ModelID model) {
viewMode_ = ViewMode::Model;
if (viewedObject_) {
world_->destroyObject(viewedObject_);
viewedObject_ = nullptr;
Expand Down Expand Up @@ -357,5 +392,5 @@ void RWViewer::viewModel(ModelID model) {
radius = glm::length(geo.center) + geo.radius;
}
constexpr auto kViewSlop = 1.f;
viewParams_.z = kViewSlop * ((radius * 2) / (glm::tan(kViewerFov / 2.f)));
viewAngles_.z = kViewSlop * ((radius * 2) / (glm::tan(kViewerFov / 2.f)));
}
16 changes: 13 additions & 3 deletions rwgame/viewer/RWViewer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,22 @@ class RWViewer final : public GameBase {
bool showTextViewer_ = false;
std::optional<TextViewer> textViewer_;
bool showImGuiDemo_ = false;
bool showIplViewer_ = false;
std::optional<IPLViewer> iplViewer_;
std::set<ModelID> showModels_;

GameObject* viewedObject_ = nullptr;
glm::vec3 viewParams_{};
enum MouseMode { Hovering, Dragging };
enum class ViewMode {
World,
Model,
};
ViewMode viewMode_ = ViewMode::World;
enum class MouseMode { Hovering, Dragging };
MouseMode mouseMode_ = MouseMode::Hovering;

GameObject* viewedObject_ = nullptr;
glm::vec3 viewAngles_{};

glm::vec3 viewPosition_{};
};

#endif
50 changes: 50 additions & 0 deletions rwgame/viewer/RWViewerWindows.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
#include <viewer/RWViewerWindows.hpp>

#include <engine/GameWorld.hpp>
#include <loaders/LoaderGXT.hpp>
#include <objects/InstanceObject.hpp>
#include <platform/FileHandle.hpp>

#include <imgui.h>
#include "RWViewerWindows.hpp"

#include <algorithm>
#include <filesystem>

namespace {
std::array<int, 3> kFonts{{FONT_PAGER, FONT_PRICEDOWN, FONT_ARIAL}};
Expand Down Expand Up @@ -158,3 +164,47 @@ void TextViewer::draw(GameRenderer& r) {
}
}
}

IPLViewer::IPLViewer(Logger& log, GameData& data)
: data_(data), world_(std::make_unique<GameWorld>(&log, &data)) {
std::transform(begin(data_.iplLocations), end(data_.iplLocations),
std::back_inserter(ipls_), [](const auto& a) -> IPLFileData {
return {false, a.first, a.second, {}, {}};
});
world_->state = &state_;
}

void IPLViewer::draw(GameRenderer& r) {
for (auto& ipl : ipls_) {
if (ImGui::Checkbox(ipl.name.c_str(), &ipl.enabled)) {
if (ipl.enabled)
showIPL(ipl);
else
hideIPL(ipl);
}
}
}

void IPLViewer::showIPL(IPLViewer::IPLFileData& ipl) {
if (ipl.loader.m_instances.empty()) {
ipl.loader.load(ipl.path);
}

for (const auto& inst : ipl.loader.m_instances) {
auto instance = world_->createInstance(inst.id, inst.pos, inst.rot);
if (!instance) {
world_->logger->error("World", "No object data for instance " +
std::to_string(inst.id) +
" in " + ipl.name);
} else {
ipl.objects.push_back(instance);
}
}
}

void IPLViewer::hideIPL(IPLViewer::IPLFileData& ipl) {
for (auto& object : ipl.objects) {
world_->destroyObject(object);
}
ipl.objects.clear();
}
34 changes: 34 additions & 0 deletions rwgame/viewer/RWViewerWindows.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
#define RWGAME_RWVIEWERWINDOWS_HPP

#include <engine/GameData.hpp>
#include <engine/GameState.hpp>
#include <fonts/GameTexts.hpp>
#include <loaders/LoaderIPL.hpp>
#include <objects/GameObject.hpp>
#include <render/GameRenderer.hpp>

#include <core/Logger.hpp>

#include <string>
#include <vector>

class TextViewer {
public:
Expand All @@ -26,4 +32,32 @@ class TextViewer {
bool drawPreview_ = true;
};

class IPLViewer {
public:
IPLViewer(Logger&, GameData& data);

void draw(GameRenderer& r);

GameWorld* world() const {
return world_.get();
}

private:
struct IPLFileData {
bool enabled;
std::string name;
std::string path;
LoaderIPL loader;
std::vector<GameObject*> objects;
};

void showIPL(IPLFileData&);
void hideIPL(IPLFileData&);

GameData& data_;
GameState state_;
std::unique_ptr<GameWorld> world_;
std::vector<IPLFileData> ipls_;
};

#endif // RWGAME_RWVIEWERWINDOWS_HPP

0 comments on commit 1781652

Please sign in to comment.