mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-28 19:10:35 +00:00
rogueviz:: added heatx
This commit is contained in:
parent
b952d03277
commit
d206656724
10
hyperweb.cpp
10
hyperweb.cpp
@ -112,16 +112,6 @@ EX void offer_choose_file(reaction_t r) {
|
||||
});
|
||||
}
|
||||
|
||||
// -- demo --
|
||||
|
||||
#if CAP_URL
|
||||
EX void open_url(string s) {
|
||||
EM_ASM_({
|
||||
window.open(UTF8ToString($0, 1000));
|
||||
}, s.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
// window.open(Pointer_stringify($0));
|
||||
bool demoanim;
|
||||
|
||||
|
145
rogueviz/heatx.cpp
Normal file
145
rogueviz/heatx.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
#include "rogueviz.h"
|
||||
#include <unordered_map>
|
||||
|
||||
// heat equation simulation
|
||||
// https://twitter.com/ZenoRogue/status/1208409387733307392
|
||||
|
||||
// run with e.g.
|
||||
// -geo 1 -canvas 0 -smart 1 -smartlimit 999999 -heatx
|
||||
// -tes tessellations/sample/marjorie-rice.tes heat_scale=0.02 -canvas 0 -smart 1 -smartlimit 999999 -heatx
|
||||
|
||||
namespace hr {
|
||||
|
||||
namespace heatx {
|
||||
|
||||
const int NOT_STARTED = 999999;
|
||||
const int OFF = 999998;
|
||||
|
||||
int last_steps = NOT_STARTED;
|
||||
|
||||
std::unordered_map<cell*, double> m1, m2, m3;
|
||||
|
||||
ld delta = 0.01;
|
||||
|
||||
int mode = 1;
|
||||
|
||||
int qsteps = 2000;
|
||||
|
||||
ld frac_per_frame = .001;
|
||||
|
||||
ld frac;
|
||||
|
||||
ld scale = 0.05;
|
||||
|
||||
void advance_heat_wave() {
|
||||
|
||||
if(euclid && GDIM == 2)
|
||||
pconf.scale = scale / max(frac, .15);
|
||||
|
||||
int steps = mode == 2 ? (frac * qsteps) : (frac * frac * qsteps);
|
||||
|
||||
if(steps != last_steps) {
|
||||
celllister cl(cwt.at, 400, 20000, nullptr);
|
||||
if(steps < last_steps) {
|
||||
last_steps = 0;
|
||||
m1.clear();
|
||||
m2.clear();
|
||||
for(cell *c: cl.lst) m1[c] = 0;
|
||||
m2 = m1;
|
||||
m1[cwt.at] = 1;
|
||||
}
|
||||
while(last_steps < steps) {
|
||||
switch(mode) {
|
||||
case 0:
|
||||
// heat: average of adjacent
|
||||
for(cell *c: cl.lst) {
|
||||
ld v = m1[c];
|
||||
forCellEx(c2, c) {
|
||||
if(m1.count(c2)) v += m1[c2]; else v += m1[c];
|
||||
}
|
||||
v /= (1 + c->type);
|
||||
m2[c] = v;
|
||||
}
|
||||
swap(m1, m2);
|
||||
break;
|
||||
case 1:
|
||||
// heat: transfer to adjacent
|
||||
for(auto& p: m2) p.second = 0;
|
||||
for(cell *c: cl.lst) {
|
||||
ld v = m1[c] / (1 + c->type);
|
||||
m2[c] += v;
|
||||
forCellEx(c2, c) {
|
||||
if(m1.count(c2)) m2[c2] += v; else m2[c] += v;
|
||||
}
|
||||
}
|
||||
swap(m1, m2);
|
||||
break;
|
||||
case 2:
|
||||
// wave
|
||||
for(cell *c: cl.lst) {
|
||||
m3[c] = 0;
|
||||
forCellEx(c2, c) {
|
||||
if(m1.count(c2)) m3[c] += (m1[c2] - m1[c]);
|
||||
}
|
||||
}
|
||||
for(cell *c: cl.lst) {
|
||||
m1[c] += m2[c] * delta + m3[c] * delta * delta / 2;
|
||||
m2[c] += m3[c] * delta;
|
||||
}
|
||||
break;
|
||||
}
|
||||
last_steps++;
|
||||
}
|
||||
ld maxv = 0;
|
||||
for(auto p: m1) maxv = max(maxv, abs(p.second));
|
||||
for(cell *c: cl.lst) {
|
||||
ld x = m1[c] / maxv;
|
||||
if(mode == 2) {
|
||||
if(x < 0) c->landparam = gradient(0x001010, 0x1010FF, -1, x, 0);
|
||||
else c->landparam = gradient(0x1010FF, 0xFFFFFF, 0, x, 1);
|
||||
}
|
||||
else {
|
||||
if(x < 1/2.) c->landparam = gradient(0x001010, 0xFF1010, 0, x, 1/2.);
|
||||
else c->landparam = gradient(0xFF1010, 0xFFFF10, 1/2., x, 1.);
|
||||
if(x > .2 && x < .3) c->landparam |= 0x4040;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return false;
|
||||
}
|
||||
|
||||
void enable() {
|
||||
using rogueviz::rv_hook;
|
||||
rv_hook(hooks_frame, 100, advance_heat_wave);
|
||||
rv_hook(anims::hooks_anim, 100, [] {
|
||||
if(inHighQual) {
|
||||
frac = std::fmod(ticks, anims::period) * 1. / anims::period;
|
||||
}
|
||||
else {
|
||||
frac += frac_per_frame;
|
||||
if(frac > 1) frac--;
|
||||
}
|
||||
});
|
||||
rv_hook(shot::hooks_take, 100, [] {
|
||||
advance_heat_wave(); calcparam(); models::configure();
|
||||
});
|
||||
rv_hook(hooks_drawcell, 100, [] (cell *c, const shiftmatrix& V) {
|
||||
if(WDIM == 3)
|
||||
queuepoly(face_the_player(V), cgi.shRing, darkena(c->landparam_color, 0, 0xFF));
|
||||
return false;
|
||||
});
|
||||
rogueviz::cleanup.push_back([] { m1.clear(); m2.clear(); m3.clear(); last_steps = OFF; });
|
||||
last_steps = NOT_STARTED; frac = 0;
|
||||
}
|
||||
|
||||
auto heathook = arg::add3("-heatx", enable)
|
||||
+ addHook(hooks_configfile, 100, [] {
|
||||
param_f(delta, "heat_delta");
|
||||
param_i(qsteps, "heat_qsteps");
|
||||
param_f(frac_per_frame, "heat_pf");
|
||||
param_f(scale, "heat_scale");
|
||||
});
|
||||
|
||||
}
|
||||
}
|
@ -36,6 +36,8 @@
|
||||
#include "hypcity.cpp"
|
||||
#include "hypocycloid.cpp"
|
||||
|
||||
#include "heatx.cpp"
|
||||
|
||||
#include "notknot.cpp"
|
||||
|
||||
#include "inner-maps.cpp"
|
||||
|
@ -79,6 +79,10 @@
|
||||
#define CAP_GMP 0
|
||||
#endif
|
||||
|
||||
#ifndef CAP_URL
|
||||
#define CAP_URL 1
|
||||
#endif
|
||||
|
||||
#define CAP_FRAMELIMIT (!ISMOBWEB)
|
||||
|
||||
#if ISMOBILE
|
||||
@ -339,6 +343,8 @@
|
||||
#define hyper fake_hyper // avoid "hyper" typedef in <_mingw.h>
|
||||
#define WIN32_LEAN_AND_MEAN // avoid "rad1" macro in <windows.h>
|
||||
#define NOMINMAX // avoid "min" and "max" macros in <windows.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
21
util.cpp
21
util.cpp
@ -703,4 +703,25 @@ EX bool file_exists(string fname) {
|
||||
return access(fname.c_str(), F_OK) != -1;
|
||||
}
|
||||
|
||||
EX void open_url(string s) {
|
||||
#if ISWEB
|
||||
EM_ASM_({
|
||||
window.open(UTF8ToString($0, 1000));
|
||||
}, s.c_str());
|
||||
#else
|
||||
|
||||
#ifdef WINDOWS
|
||||
ShellExecute(0, 0, s.c_str(), 0, 0, SW_SHOW);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX
|
||||
system(("xdg-open "+s).c_str());
|
||||
#endif
|
||||
|
||||
#ifdef MAC
|
||||
system(("open "+s).c_str());
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user