From 8c2a7e4312d9159e406b8688d44205b27db06c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20B=C3=A1lint=20Misius?= Date: Sun, 22 Oct 2023 09:57:12 +0200 Subject: [PATCH] Add surface normal debug tool --- src/debug/SurfaceNormals.cpp | 60 +++++++++++++++++++++++++++++++++ src/debug/SurfaceNormals.h | 17 ++++++++++ src/debug/meson.build | 1 + src/gui/game/GameController.cpp | 2 ++ src/gui/game/GameController.h | 1 + src/gui/game/GameView.h | 1 + src/simulation/Simulation.cpp | 37 ++++++++++---------- src/simulation/Simulation.h | 10 ++++-- 8 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 src/debug/SurfaceNormals.cpp create mode 100644 src/debug/SurfaceNormals.h diff --git a/src/debug/SurfaceNormals.cpp b/src/debug/SurfaceNormals.cpp new file mode 100644 index 000000000..9cf8e6da1 --- /dev/null +++ b/src/debug/SurfaceNormals.cpp @@ -0,0 +1,60 @@ +#include "SurfaceNormals.h" +#include "gui/game/GameView.h" +#include "gui/game/GameController.h" +#include "gui/interface/Engine.h" +#include "simulation/Simulation.h" +#include "simulation/ElementClasses.h" +#include "graphics/Graphics.h" + +SurfaceNormals::SurfaceNormals(unsigned int id, Simulation *newSim, GameView *newView, GameController *newController) : + DebugInfo(id), sim(newSim), view(newView), controller(newController) +{ +} + +void SurfaceNormals::Draw() +{ + auto *g = ui::Engine::Ref().g; + ui::Point pos = controller->PointTranslate(view->GetCurrentMouse()); + auto p = sim->photons[pos.Y][pos.X]; + if (!p) + { + p = sim->pmap[pos.Y][pos.X]; + } + if (!p) + { + return; + } + auto i = ID(p); + auto t = TYP(p); + auto &parts = sim->parts; + auto x = int(parts[i].x + 0.5f); + auto y = int(parts[i].y + 0.5f); + auto mr = sim->PlanMove(i, x, y, false); + if (t == PT_PHOT) + { + if (parts[i].flags & FLAG_SKIPMOVE) + { + return; + } + if (sim->eval_move(PT_PHOT, mr.fin_x, mr.fin_y, NULL)) + { + int rt = TYP(sim->pmap[mr.fin_y][mr.fin_x]); + int lt = TYP(sim->pmap[y][x]); + int rt_glas = (rt == PT_GLAS) || (rt == PT_BGLA); + int lt_glas = (lt == PT_GLAS) || (lt == PT_BGLA); + if ((rt_glas && !lt_glas) || (lt_glas && !rt_glas)) + { + t |= REFRACT; + } + } + } + auto gn = sim->get_normal_interp(t, parts[i].x, parts[i].y, mr.vx, mr.vy); + if (!gn.success) + { + return; + } + g->XorLine({ x, y }, { mr.fin_x, mr.fin_y }); + g->XorLine({ mr.fin_x, mr.fin_y }, { int((mr.fin_x + gn.nx * SURF_RANGE) + 0.5f), int((mr.fin_y + gn.ny * SURF_RANGE) + 0.5f) }); + g->XorLine({ mr.fin_x, mr.fin_y }, { gn.lx, gn.ly }); + g->XorLine({ mr.fin_x, mr.fin_y }, { gn.rx, gn.ry }); +} diff --git a/src/debug/SurfaceNormals.h b/src/debug/SurfaceNormals.h new file mode 100644 index 000000000..48bcf5d96 --- /dev/null +++ b/src/debug/SurfaceNormals.h @@ -0,0 +1,17 @@ +#pragma once +#include "DebugInfo.h" + +class Simulation; +class GameView; +class GameController; +class SurfaceNormals : public DebugInfo +{ + Simulation *sim; + GameView *view; + GameController *controller; + +public: + SurfaceNormals(unsigned int id, Simulation *newSim, GameView *newView, GameController *newController); + + void Draw() override; +}; diff --git a/src/debug/meson.build b/src/debug/meson.build index dacd1f818..8b21df33b 100644 --- a/src/debug/meson.build +++ b/src/debug/meson.build @@ -3,4 +3,5 @@ powder_files += files( 'DebugParts.cpp', 'ElementPopulation.cpp', 'ParticleDebug.cpp', + 'SurfaceNormals.cpp', ) diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index d84f1293e..add450109 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -24,6 +24,7 @@ #include "debug/DebugParts.h" #include "debug/ElementPopulation.h" #include "debug/ParticleDebug.h" +#include "debug/SurfaceNormals.h" #include "graphics/Renderer.h" #include "simulation/Air.h" #include "simulation/ElementClasses.h" @@ -96,6 +97,7 @@ GameController::GameController(): debugInfo.push_back(std::make_unique(DEBUG_ELEMENTPOP, gameModel->GetSimulation())); debugInfo.push_back(std::make_unique(DEBUG_LINES , gameView, this)); debugInfo.push_back(std::make_unique(DEBUG_PARTICLE , gameModel->GetSimulation(), gameModel)); + debugInfo.push_back(std::make_unique(DEBUG_SURFNORM , gameModel->GetSimulation(), gameView, this)); } GameController::~GameController() diff --git a/src/gui/game/GameController.h b/src/gui/game/GameController.h index d38d7dd8f..f92fa7af5 100644 --- a/src/gui/game/GameController.h +++ b/src/gui/game/GameController.h @@ -15,6 +15,7 @@ constexpr auto DEBUG_PARTS = 0x0001; constexpr auto DEBUG_ELEMENTPOP = 0x0002; constexpr auto DEBUG_LINES = 0x0004; constexpr auto DEBUG_PARTICLE = 0x0008; +constexpr auto DEBUG_SURFNORM = 0x0010; class DebugInfo; class SaveFile; diff --git a/src/gui/game/GameView.h b/src/gui/game/GameView.h index 70e732073..95d193cc7 100644 --- a/src/gui/game/GameView.h +++ b/src/gui/game/GameView.h @@ -175,6 +175,7 @@ public: bool GetDrawSnap() { return drawSnap; } ui::Point GetLineStartCoords() { return drawPoint1; } ui::Point GetLineFinishCoords() { return currentMouse; } + ui::Point GetCurrentMouse() { return currentMouse; } ui::Point lineSnapCoords(ui::Point point1, ui::Point point2); ui::Point rectSnapCoords(ui::Point point1, ui::Point point2); diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index f0eeb2cc0..84102eee5 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -1793,7 +1793,7 @@ int Simulation::find_next_boundary(int pt, int *x, int *y, int dm, int *em, bool return 0; } -int Simulation::get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny) +Simulation::GetNormalResult Simulation::get_normal(int pt, int x, int y, float dx, float dy) { int ldm, rdm, lm, rm; int lx, ly, lv, rx, ry, rv; @@ -1801,10 +1801,10 @@ int Simulation::get_normal(int pt, int x, int y, float dx, float dy, float *nx, float r, ex, ey; if (!dx && !dy) - return 0; + return { false }; if (!is_boundary(pt, x, y)) - return 0; + return { false }; ldm = 0xFF; rdm = 0xFF; @@ -1825,20 +1825,20 @@ int Simulation::get_normal(int pt, int x, int y, float dx, float dy, float *nx, } if (j < NORMAL_MIN_EST) - return 0; + return { false }; if ((lx == rx) && (ly == ry)) - return 0; + return { false }; ex = float(rx - lx); ey = float(ry - ly); r = 1.0f/hypot(ex, ey); - *nx = ey * r; - *ny = -ex * r; + auto nx = ey * r; + auto ny = -ex * r; - return 1; + return { true, nx, ny, lx, ly, rx, ry }; } -int Simulation::get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, float *ny) +Simulation::GetNormalResult Simulation::get_normal_interp(int pt, float x0, float y0, float dx, float dy) { int x, y, i; @@ -1850,7 +1850,7 @@ int Simulation::get_normal_interp(int pt, float x0, float y0, float dx, float dy y = (int)(y0 + 0.5f); if (x < 0 || y < 0 || x >= XRES || y >= YRES) { - return 0; + return { false }; } if (is_boundary(pt, x, y)) break; @@ -1858,12 +1858,12 @@ int Simulation::get_normal_interp(int pt, float x0, float y0, float dx, float dy y0 += dy; } if (i >= NORMAL_INTERP) - return 0; + return { false }; if (pt == PT_PHOT) photoelectric_effect(x, y); - return get_normal(pt, x, y, dx, dy, nx, ny); + return get_normal(pt, x, y, dx, dy); } void Simulation::kill_part(int i)//kills particle number i @@ -3074,12 +3074,13 @@ killed: int lt_glas = (lt == PT_GLAS) || (lt == PT_BGLA); if ((rt_glas && !lt_glas) || (lt_glas && !rt_glas)) { - float nrx, nry; - if (!get_normal_interp(REFRACT|t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy, &nrx, &nry)) { + auto gn = get_normal_interp(REFRACT|t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy); + if (!gn.success) { kill_part(i); continue; } - + auto nrx = gn.nx; + auto nry = gn.ny; auto r = get_wavelength_bin(&parts[i].ctype); if (r == -1 || !(parts[i].ctype&0x3FFFFFFF)) { @@ -3157,9 +3158,11 @@ killed: parts[i].ctype &= mask; } - float nrx, nry; - if (get_normal_interp(t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy, &nrx, &nry)) + auto gn = get_normal_interp(t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy); + if (gn.success) { + auto nrx = gn.nx; + auto nry = gn.ny; if (TYP(r) == PT_CRMC) { float r = rng.between(-50, 50) * 0.01f, rx, ry, anrx, anry; diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index 977c7ced3..2189f5a3f 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -219,8 +219,14 @@ public: void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]); void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]); int get_wavelength_bin(int *wm); - int get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny); - int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, float *ny); + struct GetNormalResult + { + bool success; + float nx, ny; + int lx, ly, rx, ry; + }; + GetNormalResult get_normal(int pt, int x, int y, float dx, float dy); + GetNormalResult get_normal_interp(int pt, float x0, float y0, float dx, float dy); void clear_sim(); Simulation(); ~Simulation();