mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-23 16:33:00 +02:00
Make heat display scale variable
No UI for it yet though.
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#include "simulation/gravity/Gravity.h"
|
#include "simulation/gravity/Gravity.h"
|
||||||
#include "simulation/orbitalparts.h"
|
#include "simulation/orbitalparts.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
void Renderer::RenderBackground()
|
void Renderer::RenderBackground()
|
||||||
{
|
{
|
||||||
@@ -264,7 +265,7 @@ void Renderer::render_parts()
|
|||||||
BlendPixel({ nx, ny }, 0x646464_rgb .WithAlpha(80));
|
BlendPixel({ nx, ny }, 0x646464_rgb .WithAlpha(80));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foundParticles = 0;
|
stats.foundParticles = 0;
|
||||||
for(i = 0; i<=sim->parts.lastActiveIndex; i++) {
|
for(i = 0; i<=sim->parts.lastActiveIndex; i++) {
|
||||||
if (sim->parts[i].type && sim->parts[i].type >= 0 && sim->parts[i].type < PT_NUM) {
|
if (sim->parts[i].type && sim->parts[i].type >= 0 && sim->parts[i].type < PT_NUM) {
|
||||||
t = sim->parts[i].type;
|
t = sim->parts[i].type;
|
||||||
@@ -360,10 +361,8 @@ void Renderer::render_parts()
|
|||||||
//Alter colour based on display mode
|
//Alter colour based on display mode
|
||||||
if(colorMode & COLOUR_HEAT)
|
if(colorMode & COLOUR_HEAT)
|
||||||
{
|
{
|
||||||
constexpr float min_temp = MIN_TEMP;
|
|
||||||
constexpr float max_temp = MAX_TEMP;
|
|
||||||
firea = 255;
|
firea = 255;
|
||||||
RGB color = heatTableAt(int((sim->parts[i].temp - min_temp) / (max_temp - min_temp) * 1024));
|
RGB color = heatTableAt(int((sim->parts[i].temp - stats.hdispLimitMin) / (stats.hdispLimitMax - stats.hdispLimitMin) * 1024));
|
||||||
firer = colr = color.Red;
|
firer = colr = color.Red;
|
||||||
fireg = colg = color.Green;
|
fireg = colg = color.Green;
|
||||||
fireb = colb = color.Blue;
|
fireb = colb = color.Blue;
|
||||||
@@ -485,7 +484,7 @@ void Renderer::render_parts()
|
|||||||
{
|
{
|
||||||
colr = firer = 255;
|
colr = firer = 255;
|
||||||
colg = fireg = colb = fireb = 0;
|
colg = fireg = colb = fireb = 0;
|
||||||
foundParticles++;
|
stats.foundParticles++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -952,7 +951,7 @@ void Renderer::draw_air()
|
|||||||
}
|
}
|
||||||
else if (displayMode & DISPLAY_AIRH)
|
else if (displayMode & DISPLAY_AIRH)
|
||||||
{
|
{
|
||||||
c = RGB::Unpack(HeatToColour(hv[y][x]));
|
c = RGB::Unpack(HeatToColour(hv[y][x], stats.hdispLimitMin, stats.hdispLimitMax));
|
||||||
//c = RGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red
|
//c = RGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red
|
||||||
// clamp_flt(hv[y][x], 0.0f, 1600.0f),//heat adds green
|
// clamp_flt(hv[y][x], 0.0f, 1600.0f),//heat adds green
|
||||||
// clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f)).Pack();//vy adds blue
|
// clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f)).Pack();//vy adds blue
|
||||||
@@ -1296,11 +1295,9 @@ void Renderer::render_fire()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int HeatToColour(float temp)
|
int HeatToColour(float temp, float hdispLimitMin, float hdispLimitMax)
|
||||||
{
|
{
|
||||||
constexpr float min_temp = MIN_TEMP;
|
RGB color = Renderer::heatTableAt(int((temp - hdispLimitMin) / (hdispLimitMax - hdispLimitMin) * 1024));
|
||||||
constexpr float max_temp = MAX_TEMP;
|
|
||||||
RGB color = Renderer::heatTableAt(int((temp - min_temp) / (max_temp - min_temp) * 1024));
|
|
||||||
color.Red = uint8_t(color.Red * 0.7f);
|
color.Red = uint8_t(color.Red * 0.7f);
|
||||||
color.Green = uint8_t(color.Green * 0.7f);
|
color.Green = uint8_t(color.Green * 0.7f);
|
||||||
color.Blue = uint8_t(color.Blue * 0.7f);
|
color.Blue = uint8_t(color.Blue * 0.7f);
|
||||||
@@ -1376,6 +1373,62 @@ const std::vector<RenderPreset> Renderer::renderModePresets = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void Renderer::AdjustHdispLimit()
|
||||||
|
{
|
||||||
|
stats.hdispLimitValid = false;
|
||||||
|
float autoHdispLimitMin = MAX_TEMP;
|
||||||
|
float autoHdispLimitMax = MIN_TEMP;
|
||||||
|
auto visit = [this, &autoHdispLimitMin, &autoHdispLimitMax](Vec2<int> point, float value) {
|
||||||
|
if (autoHdispLimitArea.Contains(point))
|
||||||
|
{
|
||||||
|
autoHdispLimitMin = std::min(autoHdispLimitMin, value);
|
||||||
|
autoHdispLimitMax = std::max(autoHdispLimitMax, value);
|
||||||
|
stats.hdispLimitValid = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (std::holds_alternative<HdispLimitAuto>(wantHdispLimitMin) ||
|
||||||
|
std::holds_alternative<HdispLimitAuto>(wantHdispLimitMax))
|
||||||
|
{
|
||||||
|
auto &sd = SimulationData::CRef();
|
||||||
|
for (int i = 0; i <= sim->parts.lastActiveIndex; ++i)
|
||||||
|
{
|
||||||
|
auto t = sim->parts[i].type;
|
||||||
|
if (t > 0 && t < PT_NUM)
|
||||||
|
{
|
||||||
|
if (!sd.elements[t].HeatConduct)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto nx = int(sim->parts[i].x + 0.5f);
|
||||||
|
auto ny = int(sim->parts[i].y + 0.5f);
|
||||||
|
visit({ nx, ny }, sim->parts[i].temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sim->aheat_enable && (displayMode & DISPLAY_AIR) && (displayMode & DISPLAY_AIRH))
|
||||||
|
{
|
||||||
|
auto *hv = sim->hv;
|
||||||
|
for (auto p : CELLS.OriginRect())
|
||||||
|
{
|
||||||
|
visit(p * CELL, hv[p.Y][p.X]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stats.hdispLimitMin = autoHdispLimitMin;
|
||||||
|
stats.hdispLimitMax = autoHdispLimitMax;
|
||||||
|
if (auto *hdispLimitExplicit = std::get_if<HdispLimitExplicit>(&wantHdispLimitMin))
|
||||||
|
{
|
||||||
|
stats.hdispLimitMin = hdispLimitExplicit->value;
|
||||||
|
}
|
||||||
|
if (auto *hdispLimitExplicit = std::get_if<HdispLimitExplicit>(&wantHdispLimitMax))
|
||||||
|
{
|
||||||
|
stats.hdispLimitMax = hdispLimitExplicit->value;
|
||||||
|
}
|
||||||
|
if (std::isnan(stats.hdispLimitMin)) stats.hdispLimitMin = MIN_TEMP;
|
||||||
|
if (std::isnan(stats.hdispLimitMax)) stats.hdispLimitMax = MAX_TEMP;
|
||||||
|
stats.hdispLimitMax = std::clamp(stats.hdispLimitMax, MIN_TEMP, MAX_TEMP);
|
||||||
|
stats.hdispLimitMin = std::clamp(stats.hdispLimitMin, MIN_TEMP, stats.hdispLimitMax);
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::Clear()
|
void Renderer::Clear()
|
||||||
{
|
{
|
||||||
if(displayMode & DISPLAY_PERS)
|
if(displayMode & DISPLAY_PERS)
|
||||||
@@ -1386,6 +1439,7 @@ void Renderer::Clear()
|
|||||||
{
|
{
|
||||||
std::fill_n(video.data(), WINDOWW * YRES, 0);
|
std::fill_n(video.data(), WINDOWW * YRES, 0);
|
||||||
}
|
}
|
||||||
|
AdjustHdispLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawBlob(Vec2<int> pos, RGB colour)
|
void Renderer::DrawBlob(Vec2<int> pos, RGB colour)
|
||||||
|
@@ -25,14 +25,14 @@ struct GraphicsFuncContext
|
|||||||
Particle *pipeSubcallTpart;
|
Particle *pipeSubcallTpart;
|
||||||
};
|
};
|
||||||
|
|
||||||
int HeatToColour(float temp);
|
int HeatToColour(float temp, float hdispLimitMin, float hdispLimitMax);
|
||||||
|
|
||||||
class Renderer : private RendererSettings, public RasterDrawMethods<Renderer>
|
class Renderer : private RendererSettings, public RasterDrawMethods<Renderer>
|
||||||
{
|
{
|
||||||
RendererFrame video;
|
RendererFrame video;
|
||||||
std::array<pixel, WINDOW.X * RES.Y> persistentVideo;
|
std::array<pixel, WINDOW.X * RES.Y> persistentVideo;
|
||||||
RendererFrame warpVideo;
|
RendererFrame warpVideo;
|
||||||
int foundParticles = 0;
|
RendererStats stats;
|
||||||
|
|
||||||
Rect<int> GetClipRect() const
|
Rect<int> GetClipRect() const
|
||||||
{
|
{
|
||||||
@@ -59,6 +59,8 @@ class Renderer : private RendererSettings, public RasterDrawMethods<Renderer>
|
|||||||
void draw_grav();
|
void draw_grav();
|
||||||
void draw_other();
|
void draw_other();
|
||||||
|
|
||||||
|
void AdjustHdispLimit();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
void ApplySettings(const RendererSettings &newSettings);
|
void ApplySettings(const RendererSettings &newSettings);
|
||||||
@@ -73,9 +75,9 @@ public:
|
|||||||
return video;
|
return video;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFoundParticles() const
|
RendererStats GetStats() const
|
||||||
{
|
{
|
||||||
return foundParticles;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RenderableSimulation *sim = nullptr;
|
const RenderableSimulation *sim = nullptr;
|
||||||
|
@@ -6,3 +6,11 @@
|
|||||||
|
|
||||||
constexpr auto RendererFrameSize = Vec2<int>{ WINDOW.X, RES.Y };
|
constexpr auto RendererFrameSize = Vec2<int>{ WINDOW.X, RES.Y };
|
||||||
using RendererFrame = PlaneAdapter<std::array<pixel, WINDOW.X * RES.Y>, RendererFrameSize.X, RendererFrameSize.Y>;
|
using RendererFrame = PlaneAdapter<std::array<pixel, WINDOW.X * RES.Y>, RendererFrameSize.X, RendererFrameSize.Y>;
|
||||||
|
|
||||||
|
struct RendererStats
|
||||||
|
{
|
||||||
|
int foundParticles = 0;
|
||||||
|
float hdispLimitMin = 0;
|
||||||
|
float hdispLimitMax = 0;
|
||||||
|
bool hdispLimitValid = false;
|
||||||
|
};
|
||||||
|
@@ -1,9 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "gui/interface/Point.h"
|
#include "gui/interface/Point.h"
|
||||||
#include "simulation/ElementGraphics.h"
|
#include "simulation/ElementGraphics.h"
|
||||||
|
#include "simulation/ElementDefs.h"
|
||||||
#include "FindingElement.h"
|
#include "FindingElement.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
struct HdispLimitExplicit
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
};
|
||||||
|
struct HdispLimitAuto
|
||||||
|
{
|
||||||
|
};
|
||||||
|
using HdispLimit = std::variant<
|
||||||
|
HdispLimitExplicit,
|
||||||
|
HdispLimitAuto
|
||||||
|
>;
|
||||||
|
|
||||||
struct RendererSettings
|
struct RendererSettings
|
||||||
{
|
{
|
||||||
@@ -24,4 +38,7 @@ struct RendererSettings
|
|||||||
ui::Point mousePos = { 0, 0 };
|
ui::Point mousePos = { 0, 0 };
|
||||||
int gridSize = 0;
|
int gridSize = 0;
|
||||||
float fireIntensity = 1;
|
float fireIntensity = 1;
|
||||||
|
HdispLimit wantHdispLimitMin = HdispLimitExplicit{ MIN_TEMP };
|
||||||
|
HdispLimit wantHdispLimitMax = HdispLimitExplicit{ MAX_TEMP };
|
||||||
|
Rect<int> autoHdispLimitArea = RES.OriginRect();
|
||||||
};
|
};
|
||||||
|
@@ -2166,7 +2166,7 @@ void GameView::OnDraw()
|
|||||||
StartRendererThread();
|
StartRendererThread();
|
||||||
WaitForRendererThread();
|
WaitForRendererThread();
|
||||||
AfterSimDraw(*sim);
|
AfterSimDraw(*sim);
|
||||||
foundParticles = ren->GetFoundParticles();
|
rendererStats = ren->GetStats();
|
||||||
*rendererThreadResult = ren->GetVideo();
|
*rendererThreadResult = ren->GetVideo();
|
||||||
rendererFrame = rendererThreadResult.get();
|
rendererFrame = rendererThreadResult.get();
|
||||||
DispatchRendererThread();
|
DispatchRendererThread();
|
||||||
@@ -2177,7 +2177,7 @@ void GameView::OnDraw()
|
|||||||
ren->ApplySettings(*rendererSettings);
|
ren->ApplySettings(*rendererSettings);
|
||||||
RenderSimulation(*sim, true);
|
RenderSimulation(*sim, true);
|
||||||
AfterSimDraw(*sim);
|
AfterSimDraw(*sim);
|
||||||
foundParticles = ren->GetFoundParticles();
|
rendererStats = ren->GetStats();
|
||||||
rendererFrame = &ren->GetVideo();
|
rendererFrame = &ren->GetVideo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2525,10 +2525,19 @@ void GameView::OnDraw()
|
|||||||
if (showDebug)
|
if (showDebug)
|
||||||
{
|
{
|
||||||
if (rendererSettings->findingElement)
|
if (rendererSettings->findingElement)
|
||||||
fpsInfo << " Parts: " << foundParticles << "/" << sample.NumParts;
|
fpsInfo << " Parts: " << rendererStats.foundParticles << "/" << sample.NumParts;
|
||||||
else
|
else
|
||||||
fpsInfo << " Parts: " << sample.NumParts;
|
fpsInfo << " Parts: " << sample.NumParts;
|
||||||
}
|
}
|
||||||
|
if ((std::holds_alternative<HdispLimitAuto>(rendererSettings->wantHdispLimitMin) ||
|
||||||
|
std::holds_alternative<HdispLimitAuto>(rendererSettings->wantHdispLimitMax)) && rendererStats.hdispLimitValid)
|
||||||
|
{
|
||||||
|
fpsInfo << " [TEMP L:";
|
||||||
|
format::RenderTemperature(fpsInfo, rendererStats.hdispLimitMin, c->GetTemperatureScale());
|
||||||
|
fpsInfo << " H:";
|
||||||
|
format::RenderTemperature(fpsInfo, rendererStats.hdispLimitMax, c->GetTemperatureScale());
|
||||||
|
fpsInfo << "]";
|
||||||
|
}
|
||||||
if (c->GetReplaceModeFlags()&REPLACE_MODE)
|
if (c->GetReplaceModeFlags()&REPLACE_MODE)
|
||||||
fpsInfo << " [REPLACE MODE]";
|
fpsInfo << " [REPLACE MODE]";
|
||||||
if (c->GetReplaceModeFlags()&SPECIFIC_DELETE)
|
if (c->GetReplaceModeFlags()&SPECIFIC_DELETE)
|
||||||
|
@@ -174,7 +174,7 @@ private:
|
|||||||
void DispatchRendererThread();
|
void DispatchRendererThread();
|
||||||
std::unique_ptr<RenderableSimulation> rendererThreadSim;
|
std::unique_ptr<RenderableSimulation> rendererThreadSim;
|
||||||
std::unique_ptr<RendererFrame> rendererThreadResult;
|
std::unique_ptr<RendererFrame> rendererThreadResult;
|
||||||
int foundParticles = 0;
|
RendererStats rendererStats;
|
||||||
const RendererFrame *rendererFrame = nullptr;
|
const RendererFrame *rendererFrame = nullptr;
|
||||||
|
|
||||||
SimFpsLimit simFpsLimit = FpsLimitExplicit{ 60.f };
|
SimFpsLimit simFpsLimit = FpsLimitExplicit{ 60.f };
|
||||||
|
@@ -411,7 +411,7 @@ void OptionsView::UpdateAmbientAirTempPreview(float airTemp, bool isValid)
|
|||||||
{
|
{
|
||||||
if (isValid)
|
if (isValid)
|
||||||
{
|
{
|
||||||
ambientAirTempPreview->Appearance.BackgroundInactive = RGB::Unpack(HeatToColour(airTemp)).WithAlpha(0xFF);
|
ambientAirTempPreview->Appearance.BackgroundInactive = RGB::Unpack(HeatToColour(airTemp, MIN_TEMP, MAX_TEMP)).WithAlpha(0xFF);
|
||||||
ambientAirTempPreview->SetText("");
|
ambientAirTempPreview->SetText("");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -243,6 +243,62 @@ static int separateThread(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int heatDisplayLimits(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
lsi->AssertInterfaceEvent();
|
||||||
|
auto &rendererSettings = lsi->gameModel->GetRendererSettings();
|
||||||
|
if (lua_gettop(L))
|
||||||
|
{
|
||||||
|
auto write = [L](auto &setting, int index) {
|
||||||
|
if (lua_isstring(L, index) && byteStringEqualsLiteral(tpt_lua_toByteString(L, index), "auto"))
|
||||||
|
{
|
||||||
|
setting = HdispLimitAuto{};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setting = HdispLimitExplicit{ float(luaL_checknumber(L, index)) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
write(rendererSettings.wantHdispLimitMin, 1);
|
||||||
|
write(rendererSettings.wantHdispLimitMax, 2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto read = [L](auto &setting) {
|
||||||
|
if (auto *hdispLimitExplicit = std::get_if<HdispLimitExplicit>(&setting))
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, hdispLimitExplicit->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lua_pushliteral(L, "auto");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
read(rendererSettings.wantHdispLimitMin);
|
||||||
|
read(rendererSettings.wantHdispLimitMax);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int heatDisplayAutoArea(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
lsi->AssertInterfaceEvent();
|
||||||
|
auto &rendererSettings = lsi->gameModel->GetRendererSettings();
|
||||||
|
if (lua_gettop(L))
|
||||||
|
{
|
||||||
|
rendererSettings.autoHdispLimitArea.pos .X = luaL_checkinteger(L, 1);
|
||||||
|
rendererSettings.autoHdispLimitArea.pos .Y = luaL_checkinteger(L, 2);
|
||||||
|
rendererSettings.autoHdispLimitArea.size.X = luaL_checkinteger(L, 3);
|
||||||
|
rendererSettings.autoHdispLimitArea.size.Y = luaL_checkinteger(L, 4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lua_pushinteger(L, rendererSettings.autoHdispLimitArea.pos .X);
|
||||||
|
lua_pushinteger(L, rendererSettings.autoHdispLimitArea.pos .Y);
|
||||||
|
lua_pushinteger(L, rendererSettings.autoHdispLimitArea.size.X);
|
||||||
|
lua_pushinteger(L, rendererSettings.autoHdispLimitArea.size.Y);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
void LuaRenderer::Open(lua_State *L)
|
void LuaRenderer::Open(lua_State *L)
|
||||||
{
|
{
|
||||||
static const luaL_Reg reg[] = {
|
static const luaL_Reg reg[] = {
|
||||||
@@ -262,6 +318,8 @@ void LuaRenderer::Open(lua_State *L)
|
|||||||
LFUNC(fireSize),
|
LFUNC(fireSize),
|
||||||
LFUNC(useDisplayPreset),
|
LFUNC(useDisplayPreset),
|
||||||
LFUNC(separateThread),
|
LFUNC(separateThread),
|
||||||
|
LFUNC(heatDisplayLimits),
|
||||||
|
LFUNC(heatDisplayAutoArea),
|
||||||
#undef LFUNC
|
#undef LFUNC
|
||||||
{ nullptr, nullptr }
|
{ nullptr, nullptr }
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user