Add surface normal debug tool

This commit is contained in:
Tamás Bálint Misius 2023-10-22 09:57:12 +02:00
parent dda3e8a9c7
commit 8c2a7e4312
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
8 changed files with 110 additions and 19 deletions

View File

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

View File

@ -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;
};

View File

@ -3,4 +3,5 @@ powder_files += files(
'DebugParts.cpp',
'ElementPopulation.cpp',
'ParticleDebug.cpp',
'SurfaceNormals.cpp',
)

View File

@ -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<ElementPopulationDebug>(DEBUG_ELEMENTPOP, gameModel->GetSimulation()));
debugInfo.push_back(std::make_unique<DebugLines >(DEBUG_LINES , gameView, this));
debugInfo.push_back(std::make_unique<ParticleDebug >(DEBUG_PARTICLE , gameModel->GetSimulation(), gameModel));
debugInfo.push_back(std::make_unique<SurfaceNormals >(DEBUG_SURFNORM , gameModel->GetSimulation(), gameView, this));
}
GameController::~GameController()

View File

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

View File

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

View File

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

View File

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