diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-04-09 20:32:12 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-04-09 20:32:12 +0100 |
commit | eaae60886c432b6d9d5862a04f3abf03f7a13fee (patch) | |
tree | e72be4f5a9c9b6162e592aaa1e5d2d78c9611559 | |
parent | Remove GameMainWindow empty destructor and special members (diff) | |
download | ilt-eaae60886c432b6d9d5862a04f3abf03f7a13fee.tar.bz2 ilt-eaae60886c432b6d9d5862a04f3abf03f7a13fee.tar.xz ilt-eaae60886c432b6d9d5862a04f3abf03f7a13fee.zip |
Reasonably function asset viewing functionality
-rw-r--r-- | application/resviewer.cpp | 155 |
1 files changed, 154 insertions, 1 deletions
diff --git a/application/resviewer.cpp b/application/resviewer.cpp index 2eb40f2..e512b41 100644 --- a/application/resviewer.cpp +++ b/application/resviewer.cpp @@ -1,13 +1,165 @@ #include <backends/imgui_impl_opengl3.h> #include <backends/imgui_impl_sdl2.h> +#include <game/environment.h> #include <game/gamestate.h> +#include <game/terrain.h> #include <gfx/gl/sceneProvider.h> #include <gfx/gl/sceneRenderer.h> +#include <gfx/renderable.h> +#include <location.h> #include <ui/applicationBase.h> #include <ui/mainApplication.h> #include <ui/mainWindow.h> constexpr ScreenAbsCoord DEFAULT_WINDOW_SIZE {800, 600}; +constexpr GlobalDistance TERRAIN_LIMIT = 1'000'000; +constexpr GlobalDistance TERRAIN_HEIGHT = 10'000; +constexpr RelativeDistance DEFAULT_CAMERA_DIST = 7'000; +constexpr GlobalDistance DEFAULT_CAMERA_HEIGHT = 5'000; +constexpr GlobalDistance DEFAULT_CAMERA_FOCUS = 3'000; +constexpr GlobalDistance MAX_CAMERA_HEIGHT = 10'000; +constexpr GlobalDistance MIN_CAMERA_DIST = 1'000; +constexpr GlobalDistance MAX_CAMERA_DIST = 30'000; + +class ViewerContent : public WindowContent, SceneRenderer, SceneProvider { +public: + ViewerContent(ScreenAbsCoord size, std::span<char * const> files) : SceneRenderer {size, 0}, fileList(files) + { + camera.setPosition(calcCameraPosition()); + camera.lookAt({0, 0, TERRAIN_HEIGHT + cameraFocus}); + gameState->terrain = std::make_shared<Terrain>( + GeoData::createFlat({-TERRAIN_LIMIT, -TERRAIN_LIMIT}, {TERRAIN_LIMIT, TERRAIN_LIMIT}, TERRAIN_HEIGHT)); + } + +private: + [[nodiscard]] + GlobalPosition3D + calcCameraPosition() const + { + return {sincos(cameraAngle) * cameraDistance, TERRAIN_HEIGHT + cameraHeight}; + } + + void + render() override + { + SceneRenderer::render(*this); + controls(); + } + + void + tick(TickDuration tick) override + { + if (autoRotate != 0) { + cameraAngle = normalize(cameraAngle + autoRotate * tick.count()); + camera.setPosition(calcCameraPosition()); + camera.lookAt({0, 0, TERRAIN_HEIGHT + cameraFocus}); + } + } + + bool + handleInput(const SDL_Event & event) override + { + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) { + SceneRenderer::resize({event.window.data1, event.window.data2}); + } + + return WindowContent::handleInput(event); + } + + void + controls() + { + if (ImGui::Begin("Resource view")) { + ImGui::SetWindowSize({}); + fileSelection(); + assetSelection(); + } + ImGui::End(); + + if (ImGui::Begin("Camera")) { + ImGui::SetWindowSize({}); + if (std::max({ImGui::SliderFloat("Camera position", &cameraAngle, -pi, pi), + ImGui::SliderInt("Camera focus", &cameraFocus, 1, MAX_CAMERA_HEIGHT), + ImGui::SliderInt("Camera height", &cameraHeight, 1, MAX_CAMERA_HEIGHT), + ImGui::SliderFloat("Camera distance", &cameraDistance, MIN_CAMERA_DIST, MAX_CAMERA_DIST)})) { + camera.setPosition(calcCameraPosition()); + camera.lookAt({0, 0, TERRAIN_HEIGHT + cameraFocus}); + } + ImGui::SliderFloat("Auto rotate speed", &autoRotate, -1, 1); + } + ImGui::End(); + } + + void + fileSelection() + { + ImGui::BeginListBox("File"); + for (const auto file : fileList) { + if (ImGui::Selectable(file, file == selectedFile)) { + location.reset(); + selectedAsset = nullptr; + gameState->assets = AssetFactory::loadXML(file)->assets; + selectedFile = file; + } + } + ImGui::EndListBox(); + } + + void + assetSelection() + { + if (!gameState->assets.empty()) { + ImGui::BeginListBox("Asset"); + for (const auto & asset : gameState->assets) { + auto renderable = asset.second.getAs<const Renderable>(); + if (renderable) { + if (ImGui::Selectable(asset.first.c_str(), renderable == selectedAsset)) { + selectedAsset = renderable; + location = asset.second->createAt(position); + } + } + } + ImGui::EndListBox(); + } + } + + void + content(const SceneShader & sceneShader, const Frustum & frustum) const override + { + gameState->terrain->render(sceneShader, frustum); + if (selectedAsset) { + selectedAsset->render(sceneShader, frustum); + } + } + + void + lights(const SceneShader & sceneShader) const override + { + if (selectedAsset) { + selectedAsset->lights(sceneShader); + } + } + + void + shadows(const ShadowMapper & mapper, const Frustum & frustum) const override + { + gameState->terrain->shadows(mapper, frustum); + if (selectedAsset) { + selectedAsset->shadows(mapper, frustum); + } + } + + std::span<char * const> fileList; + char * selectedFile {}; + const Renderable * selectedAsset {}; + Location position {.pos = {0, 0, TERRAIN_HEIGHT}, .rot = {}}; + std::any location; + Angle cameraAngle {0.F}; + RelativeDistance cameraDistance {DEFAULT_CAMERA_DIST}; + GlobalDistance cameraHeight {DEFAULT_CAMERA_HEIGHT}; + GlobalDistance cameraFocus {DEFAULT_CAMERA_FOCUS}; + float autoRotate {0.F}; +}; int main(int argc, char ** argv) @@ -17,7 +169,8 @@ main(int argc, char ** argv) void run(std::span<char * const> fileList) { - windows.create<MainWindow>(DEFAULT_WINDOW_SIZE, "ILT - Resource Viewer"); + windows.create<MainWindow>(DEFAULT_WINDOW_SIZE, "ILT - Resource Viewer") + ->setContent<ViewerContent>(fileList); mainLoop(); } }; |