Add surface normal debug tool
This commit is contained in:
parent
dda3e8a9c7
commit
8c2a7e4312
60
src/debug/SurfaceNormals.cpp
Normal file
60
src/debug/SurfaceNormals.cpp
Normal 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 });
|
||||||
|
}
|
17
src/debug/SurfaceNormals.h
Normal file
17
src/debug/SurfaceNormals.h
Normal 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;
|
||||||
|
};
|
@ -3,4 +3,5 @@ powder_files += files(
|
|||||||
'DebugParts.cpp',
|
'DebugParts.cpp',
|
||||||
'ElementPopulation.cpp',
|
'ElementPopulation.cpp',
|
||||||
'ParticleDebug.cpp',
|
'ParticleDebug.cpp',
|
||||||
|
'SurfaceNormals.cpp',
|
||||||
)
|
)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "debug/DebugParts.h"
|
#include "debug/DebugParts.h"
|
||||||
#include "debug/ElementPopulation.h"
|
#include "debug/ElementPopulation.h"
|
||||||
#include "debug/ParticleDebug.h"
|
#include "debug/ParticleDebug.h"
|
||||||
|
#include "debug/SurfaceNormals.h"
|
||||||
#include "graphics/Renderer.h"
|
#include "graphics/Renderer.h"
|
||||||
#include "simulation/Air.h"
|
#include "simulation/Air.h"
|
||||||
#include "simulation/ElementClasses.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<ElementPopulationDebug>(DEBUG_ELEMENTPOP, gameModel->GetSimulation()));
|
||||||
debugInfo.push_back(std::make_unique<DebugLines >(DEBUG_LINES , gameView, this));
|
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<ParticleDebug >(DEBUG_PARTICLE , gameModel->GetSimulation(), gameModel));
|
||||||
|
debugInfo.push_back(std::make_unique<SurfaceNormals >(DEBUG_SURFNORM , gameModel->GetSimulation(), gameView, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
GameController::~GameController()
|
GameController::~GameController()
|
||||||
|
@ -15,6 +15,7 @@ constexpr auto DEBUG_PARTS = 0x0001;
|
|||||||
constexpr auto DEBUG_ELEMENTPOP = 0x0002;
|
constexpr auto DEBUG_ELEMENTPOP = 0x0002;
|
||||||
constexpr auto DEBUG_LINES = 0x0004;
|
constexpr auto DEBUG_LINES = 0x0004;
|
||||||
constexpr auto DEBUG_PARTICLE = 0x0008;
|
constexpr auto DEBUG_PARTICLE = 0x0008;
|
||||||
|
constexpr auto DEBUG_SURFNORM = 0x0010;
|
||||||
|
|
||||||
class DebugInfo;
|
class DebugInfo;
|
||||||
class SaveFile;
|
class SaveFile;
|
||||||
|
@ -175,6 +175,7 @@ public:
|
|||||||
bool GetDrawSnap() { return drawSnap; }
|
bool GetDrawSnap() { return drawSnap; }
|
||||||
ui::Point GetLineStartCoords() { return drawPoint1; }
|
ui::Point GetLineStartCoords() { return drawPoint1; }
|
||||||
ui::Point GetLineFinishCoords() { return currentMouse; }
|
ui::Point GetLineFinishCoords() { return currentMouse; }
|
||||||
|
ui::Point GetCurrentMouse() { return currentMouse; }
|
||||||
ui::Point lineSnapCoords(ui::Point point1, ui::Point point2);
|
ui::Point lineSnapCoords(ui::Point point1, ui::Point point2);
|
||||||
ui::Point rectSnapCoords(ui::Point point1, ui::Point point2);
|
ui::Point rectSnapCoords(ui::Point point1, ui::Point point2);
|
||||||
|
|
||||||
|
@ -1793,7 +1793,7 @@ int Simulation::find_next_boundary(int pt, int *x, int *y, int dm, int *em, bool
|
|||||||
return 0;
|
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 ldm, rdm, lm, rm;
|
||||||
int lx, ly, lv, rx, ry, rv;
|
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;
|
float r, ex, ey;
|
||||||
|
|
||||||
if (!dx && !dy)
|
if (!dx && !dy)
|
||||||
return 0;
|
return { false };
|
||||||
|
|
||||||
if (!is_boundary(pt, x, y))
|
if (!is_boundary(pt, x, y))
|
||||||
return 0;
|
return { false };
|
||||||
|
|
||||||
ldm = 0xFF;
|
ldm = 0xFF;
|
||||||
rdm = 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)
|
if (j < NORMAL_MIN_EST)
|
||||||
return 0;
|
return { false };
|
||||||
|
|
||||||
if ((lx == rx) && (ly == ry))
|
if ((lx == rx) && (ly == ry))
|
||||||
return 0;
|
return { false };
|
||||||
ex = float(rx - lx);
|
ex = float(rx - lx);
|
||||||
ey = float(ry - ly);
|
ey = float(ry - ly);
|
||||||
r = 1.0f/hypot(ex, ey);
|
r = 1.0f/hypot(ex, ey);
|
||||||
*nx = ey * r;
|
auto nx = ey * r;
|
||||||
*ny = -ex * 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;
|
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);
|
y = (int)(y0 + 0.5f);
|
||||||
if (x < 0 || y < 0 || x >= XRES || y >= YRES)
|
if (x < 0 || y < 0 || x >= XRES || y >= YRES)
|
||||||
{
|
{
|
||||||
return 0;
|
return { false };
|
||||||
}
|
}
|
||||||
if (is_boundary(pt, x, y))
|
if (is_boundary(pt, x, y))
|
||||||
break;
|
break;
|
||||||
@ -1858,12 +1858,12 @@ int Simulation::get_normal_interp(int pt, float x0, float y0, float dx, float dy
|
|||||||
y0 += dy;
|
y0 += dy;
|
||||||
}
|
}
|
||||||
if (i >= NORMAL_INTERP)
|
if (i >= NORMAL_INTERP)
|
||||||
return 0;
|
return { false };
|
||||||
|
|
||||||
if (pt == PT_PHOT)
|
if (pt == PT_PHOT)
|
||||||
photoelectric_effect(x, y);
|
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
|
void Simulation::kill_part(int i)//kills particle number i
|
||||||
@ -3074,12 +3074,13 @@ killed:
|
|||||||
int lt_glas = (lt == PT_GLAS) || (lt == PT_BGLA);
|
int lt_glas = (lt == PT_GLAS) || (lt == PT_BGLA);
|
||||||
if ((rt_glas && !lt_glas) || (lt_glas && !rt_glas))
|
if ((rt_glas && !lt_glas) || (lt_glas && !rt_glas))
|
||||||
{
|
{
|
||||||
float nrx, nry;
|
auto gn = get_normal_interp(REFRACT|t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy);
|
||||||
if (!get_normal_interp(REFRACT|t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy, &nrx, &nry)) {
|
if (!gn.success) {
|
||||||
kill_part(i);
|
kill_part(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
auto nrx = gn.nx;
|
||||||
|
auto nry = gn.ny;
|
||||||
auto r = get_wavelength_bin(&parts[i].ctype);
|
auto r = get_wavelength_bin(&parts[i].ctype);
|
||||||
if (r == -1 || !(parts[i].ctype&0x3FFFFFFF))
|
if (r == -1 || !(parts[i].ctype&0x3FFFFFFF))
|
||||||
{
|
{
|
||||||
@ -3157,9 +3158,11 @@ killed:
|
|||||||
parts[i].ctype &= mask;
|
parts[i].ctype &= mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
float nrx, nry;
|
auto gn = get_normal_interp(t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy);
|
||||||
if (get_normal_interp(t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy, &nrx, &nry))
|
if (gn.success)
|
||||||
{
|
{
|
||||||
|
auto nrx = gn.nx;
|
||||||
|
auto nry = gn.ny;
|
||||||
if (TYP(r) == PT_CRMC)
|
if (TYP(r) == PT_CRMC)
|
||||||
{
|
{
|
||||||
float r = rng.between(-50, 50) * 0.01f, rx, ry, anrx, anry;
|
float r = rng.between(-50, 50) * 0.01f, rx, ry, anrx, anry;
|
||||||
|
@ -219,8 +219,14 @@ public:
|
|||||||
void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
|
void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
|
||||||
void orbitalparts_set(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_wavelength_bin(int *wm);
|
||||||
int get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny);
|
struct GetNormalResult
|
||||||
int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, float *ny);
|
{
|
||||||
|
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();
|
void clear_sim();
|
||||||
Simulation();
|
Simulation();
|
||||||
~Simulation();
|
~Simulation();
|
||||||
|
Reference in New Issue
Block a user