mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-20 15:40:26 +00:00
Merge branch 'zenorogue:master' into main
This commit is contained in:
commit
6663a33df4
@ -48,8 +48,12 @@ You can aim for the Orb of Yendor, or you can simply aim for as high score as po
|
||||
## Modifications
|
||||
|
||||
OK, now lots of the above can be changed. You can change the geometry and topology (to Euclidean, spherical, or even to nonisotropic 3D geometries). You can play challenges based on
|
||||
various in-game quests, and even try some other game genres in non-Euclidean spaces (roguelite aka shmup, racing, peaceful puzzles). Or use the engine for non-Euclidean computations
|
||||
and visualizations (see [RogueViz](http://roguetemple.com/z/hyper/rogueviz.php)). Have fun!
|
||||
various in-game quests, and even try some other game genres in non-Euclidean spaces (roguelite aka shmup, racing, peaceful puzzles).
|
||||
|
||||
## RogueViz
|
||||
|
||||
HyperRogue uses [RogueViz](http://roguetemple.com/z/hyper/rogueviz.php), which is our engine for non-Euclidean games, computations and visualizations. This repo includes the source code of RogueViz demos in subdirectory `rogueviz`, but
|
||||
not the data, which is available on [itch.io](https://zenorogue.itch.io/rogueviz). RogueViz is funded by the National Science Centre, Poland, grant UMO-2019/35/B/ST6/04456.
|
||||
|
||||
## Development ##
|
||||
|
||||
@ -74,6 +78,7 @@ make
|
||||
|
||||
The `mymake` program builds HyperRogue in parts. It takes longer than the method shown above, but it uses significantly less memory during compilation, and when you change something, `mymake` will only recompile the changed file.
|
||||
Additionally, it can be easily configured, e.g., to produce an optimized build, or to include addons (see `mymake.cpp` for some example invocations, and `devmods` for some example addons).
|
||||
Most useful parameters include `-O3` (optimized build), `-rv` (include the RogueViz demos), `-vr` (build the VR version).
|
||||
|
||||
```
|
||||
make mymake && ./mymake
|
||||
|
@ -4575,3 +4575,21 @@ Geometry:
|
||||
- Goldberg-Coxeter improvements (larger limits supported, warn if outside of the supported limits, some are fixed)
|
||||
- fixed fat edges in some H3 honeycombs
|
||||
- fixed some bugs with Multi-dimensional Crystal quotient space
|
||||
|
||||
2022-03-01 09:39 Update 12.0l:
|
||||
Orb-related fixes:
|
||||
- Curse of Repulsion now correctly marked when used
|
||||
- when having Orb of Freedom + Orb of Time, other orbs are no longer drained by Freedom checks
|
||||
- Valentine's Easter Egg: Add +1 extra charge to Orb of Love
|
||||
|
||||
Geometry:
|
||||
- fixed VR in product geometries
|
||||
- portals between geometries: fixed some formulas, walking mode
|
||||
- fixed dark lines in binary tiling x R raycasting which happened when we got a=0 in quadratic equation
|
||||
- made Yendor/Haunted sight radius consistent when the tiling is changed
|
||||
- infinite generation for single-land Camelot now only happens in hyperbolic geometry (also fixes the missing Grail in Crystal)
|
||||
- additions and fixes to RogueViz
|
||||
|
||||
Other:
|
||||
- fixed Crossroads wiki links
|
||||
- fixed some settings incorrectly showing a warning on editing (this also brings back the 'play music when out of focus' option)
|
||||
|
@ -3075,7 +3075,7 @@ EX void addaura(shiftpoint h, color_t col, int fd) {
|
||||
if(!haveaura_cached) return;
|
||||
apply_joukowsky_aura(h);
|
||||
|
||||
int r = int(2*AURA + atan2(h[1], h[0]) * AURA / 2 / M_PI) % AURA;
|
||||
int r = gmod(atan2(h[1], h[0]) * AURA / 2 / M_PI, AURA);
|
||||
aurac[r][3] += auramemo << fd;
|
||||
col = darkened(col);
|
||||
aurac[r][0] += (col>>16)&255;
|
||||
|
2
help.cpp
2
help.cpp
@ -232,7 +232,7 @@ EX void buildCredits() {
|
||||
"Kojiguchi Kazuki, baconcow, Alan, SurelyYouJest, hotdogPi, DivisionByZero, xXxWeedGokuxXx, jpystynen, Dmitry Marakasov, Alexandre Moine, Arthur O'Dwyer, "
|
||||
"Triple_Agent_AAA, bluetailedgnat, Allalinor, Shitford, KittyTac, Christopher King, KosGD, TravelDemon, Bubbles, rdococ, frozenlake, MagmaMcFry, "
|
||||
"Snakebird Priestess, roaringdragon2, Stopping Dog, bengineer8, Sir Light IJIJ, ShadeBlade, Saplou, shnourok, Ralith, madasa, 6% remaining, Chimera245, Remik Pi, alien foxcat thing, "
|
||||
"Piotr Grochowski, Ann, still-flow, tyzone, Paradoxica, LottieRatWorld"
|
||||
"Piotr Grochowski, Ann, still-flow, tyzone, Paradoxica, LottieRatWorld, aismallard"
|
||||
);
|
||||
#ifdef EXTRALICENSE
|
||||
help += EXTRALICENSE;
|
||||
|
4
hyper.h
4
hyper.h
@ -13,8 +13,8 @@
|
||||
#define _HYPER_H_
|
||||
|
||||
// version numbers
|
||||
#define VER "12.0k"
|
||||
#define VERNUM_HEX 0xA90B
|
||||
#define VER "12.0l"
|
||||
#define VERNUM_HEX 0xA90C
|
||||
|
||||
#include "sysconfig.h"
|
||||
|
||||
|
@ -42,6 +42,7 @@ EX bool doPickupItemsWithMagnetism(cell *c) {
|
||||
c4->item = c3->item;
|
||||
moveEffect(movei(c3, c4, (cw+j).spin), moDeadBird);
|
||||
c3->item = itNone;
|
||||
markOrb(itCurseRepulsion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,15 +11,43 @@ embedding_type etype = eNatural;
|
||||
map<cell*, kohvec> landscape_at;
|
||||
|
||||
map<cellwalker, kohvec> delta_at;
|
||||
map<cellwalker, int> delta_id;
|
||||
|
||||
int qdelta;
|
||||
|
||||
void init_landscape(int dimensions) {
|
||||
etype = eLandscape;
|
||||
landscape_at.clear();
|
||||
delta_at.clear();
|
||||
delta_id.clear();
|
||||
qdelta = 0;
|
||||
landscape_at[currentmap->gamestart()].resize(dimensions, 0);
|
||||
println(hlog, "initialized for ", currentmap->gamestart());
|
||||
}
|
||||
|
||||
kohvec& get_landscape_at(cell *h);
|
||||
|
||||
void init_landscape_det(const vector<cell*>& ac) {
|
||||
etype = eLandscape;
|
||||
landscape_at.clear();
|
||||
delta_at.clear();
|
||||
delta_id.clear();
|
||||
qdelta = 0;
|
||||
landscape_at[currentmap->gamestart()].resize(0, 0);
|
||||
for(cell *c: ac) get_landscape_at(c);
|
||||
int dimensions = isize(delta_at);
|
||||
landscape_at.clear();
|
||||
landscape_at[currentmap->gamestart()].resize(dimensions, 0);
|
||||
println(hlog, "qdelta = ", qdelta, " size of delta_at = ", isize(delta_at));
|
||||
for(auto& d: delta_at) {
|
||||
d.second.resize(dimensions, 0);
|
||||
// d.second[id++] = 1;
|
||||
d.second[delta_id[d.first]] = 1;
|
||||
}
|
||||
|
||||
println(hlog, "initialized for ", currentmap->gamestart(), ", dimensions = ", dimensions);
|
||||
}
|
||||
|
||||
void normalize(cellwalker& cw) {
|
||||
int d = celldist(cw.at);
|
||||
back:
|
||||
@ -55,17 +83,25 @@ void normalize(cellwalker& cw) {
|
||||
}
|
||||
}
|
||||
|
||||
ld hrandd() {
|
||||
return ((hrngen() & HRANDMAX) + .5) / HRANDMAX;
|
||||
}
|
||||
|
||||
ld gaussian_random() {
|
||||
return (hrand(1000) + hrand(1000) - hrand(1000) - hrand(1000)) / 1000.;
|
||||
ld u1 = hrandd();
|
||||
ld u2 = hrandd();
|
||||
return sqrt(-2*log(u1)) * cos(2*M_PI*u2);
|
||||
}
|
||||
|
||||
void apply_delta(cellwalker cw, kohvec& v) {
|
||||
normalize(cw);
|
||||
|
||||
auto& da = delta_at[cw];
|
||||
if(da.empty()) {
|
||||
if(!delta_id.count(cw)) {
|
||||
delta_id[cw] = qdelta++;
|
||||
da.resize(isize(v));
|
||||
for(auto& x: da) x = gaussian_random();
|
||||
for(int i=0; i<min(200, isize(da)); i++)
|
||||
if(i < isize(da)) da[i] = gaussian_random();
|
||||
}
|
||||
|
||||
for(int i=0; i<isize(v); i++) v[i] += da[i];
|
||||
@ -183,7 +219,7 @@ void get_coordinates(kohvec& v, cell *c, cell *c0) {
|
||||
for(int i=0; i<MDIM; i++)
|
||||
v[i] = h[i];
|
||||
}
|
||||
else if(euclid && bounded && WDIM == 2 && T0[0][1] == 0 && T0[1][0] == 0 && T0[0][0] == T0[1][1]) {
|
||||
else if(euclid && bounded && S3 == 3 && WDIM == 2 && T0[0][1] == 0 && T0[1][0] == 0 && T0[0][0] == T0[1][1]) {
|
||||
columns = 6;
|
||||
alloc(v);
|
||||
int s = T0[0][0];
|
||||
@ -191,11 +227,11 @@ void get_coordinates(kohvec& v, cell *c, cell *c0) {
|
||||
hyperpoint h1 = spin(120*degree*i) * h;
|
||||
ld x = h1[1];
|
||||
ld alpha = 2 * M_PI * x / s / (sqrt(3) / 2);
|
||||
println(hlog, kz(x), " -> ", kz(alpha));
|
||||
// println(hlog, kz(x), " -> ", kz(alpha));
|
||||
v[2*i] = cos(alpha);
|
||||
v[2*i+1] = sin(alpha);
|
||||
}
|
||||
println(hlog, kz(h), " -> ", v);
|
||||
// println(hlog, kz(h), " -> ", v);
|
||||
}
|
||||
else if(euclid && bounded && WDIM == 2) {
|
||||
columns = 4;
|
||||
|
@ -452,7 +452,8 @@ auto fifteen_hook =
|
||||
if(fifteen_slides.empty()) {
|
||||
fifteen_slides.emplace_back(
|
||||
slide{"Introduction", 999, LEGAL::NONE,
|
||||
"This is a collection of some geometric and topological variants of the Fifteen puzzle."
|
||||
"This is a collection of some geometric and topological variants of the Fifteen puzzle. Most of these "
|
||||
"are digital implementations of the mechanical designs by Henry Segerman."
|
||||
,
|
||||
[] (presmode mode) {}
|
||||
});
|
||||
@ -490,11 +491,16 @@ auto fifteen_hook =
|
||||
add("coiled", "coiled", "Coiled fifteen puzzle by Henry Segerman.", "https://www.youtube.com/watch?v=rfAEgxNEOrQ");
|
||||
add("Möbius band", "mobiusband", "Fifteen puzzle on a Möbius band.");
|
||||
add("Kite-and-dart", "kitedart", "Kite-and-dart puzzle.");
|
||||
add("29", "29", "The 29 puzzle by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
|
||||
add("12", "12", "The 12 puzzle mentioned in the same video by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
|
||||
add("124", "124", "The 124 puzzle mentioned in the same video by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
|
||||
add("60", "60", "The 124 puzzle mentioned in the same video by Henry Segerman.", "https://www.youtube.com/watch?v=EitWHthBY30");
|
||||
add("Continental drift", "sphere19", "Based on the Continental Drift puzzle by Henry Segerman.", "https://www.youtube.com/watch?v=0uQx33KFMO0");
|
||||
|
||||
add_end(fifteen_slides);
|
||||
}
|
||||
|
||||
cb(XLAT("variants of the fifteen puzzle"), &fifteen_slides[0], 'h');
|
||||
cb(XLAT("variants of the fifteen puzzle"), &fifteen_slides[0], 'f');
|
||||
});
|
||||
#endif
|
||||
|
||||
|
@ -440,6 +440,10 @@ auto msc = arg::add3("-analogs", enable)
|
||||
slide_url(mode, 'm', "HyperRogue page about projections", "http://www.roguetemple.com/z/hyper/models.php");
|
||||
setCanvas(mode, '0');
|
||||
if(mode == pmStart) {
|
||||
slide_backup(mapeditor::drawplayer);
|
||||
slide_backup(vid.use_smart_range);
|
||||
slide_backup(vid.smart_range_detail);
|
||||
slide_backup(vid.linequality);
|
||||
enable();
|
||||
start_game();
|
||||
slide_backup(cycle_models);
|
||||
|
@ -496,6 +496,7 @@ auto hooks =
|
||||
mapstream::loadMap(s);
|
||||
slide_backup(ray::fixed_map, true);
|
||||
slide_backup(ray::max_iter_intra, y);
|
||||
slide_backup(mapeditor::drawplayer, false);
|
||||
};
|
||||
};
|
||||
|
||||
@ -509,6 +510,7 @@ auto hooks =
|
||||
if(twitter != "")
|
||||
slide_url(mode, 't', "Twitter link", twitter);
|
||||
slide_action(mode, 'r', "run this visualization", loader);
|
||||
slidecommand = "portal options";
|
||||
if(mode == tour::pmKey) pushScreen(intra::show_portals);
|
||||
}
|
||||
});
|
||||
|
@ -264,10 +264,7 @@ bool triangulate(kohvec d, neuron& w, map<cell*, neuron*>& find, transmatrix& re
|
||||
}
|
||||
if(diff < bdiff) bdiff = diff, candidate = w2, cdir = i;
|
||||
}
|
||||
if(cdir == -1) {
|
||||
println(hlog, "not enough directions");
|
||||
return false;
|
||||
}
|
||||
if(cdir == -1) break;
|
||||
dirs.push_back(cdir);
|
||||
other.push_back(candidate);
|
||||
kv.push_back(candidate->net);
|
||||
@ -291,6 +288,7 @@ bool triangulate(kohvec d, neuron& w, map<cell*, neuron*>& find, transmatrix& re
|
||||
for(int i=0; i<q; i++) {
|
||||
R[i][i] = vdot(kv[i], kv[i]);
|
||||
if(R[i][i] < 1e-12) {
|
||||
/*
|
||||
auto head = [] (const vector<ld>& v) { vector<ld> res; for(int i=0; i<10; i++) res.push_back(v[i]); return res; };
|
||||
println(hlog, "dot too small, i=", i,", dirs=", dirs);
|
||||
println(hlog, "a = ", head(a));
|
||||
@ -299,6 +297,7 @@ bool triangulate(kohvec d, neuron& w, map<cell*, neuron*>& find, transmatrix& re
|
||||
println(hlog, "orig kv: ", head(z->net), " @ ", z->where);
|
||||
for(auto z: kv)
|
||||
println(hlog, "curr kv: ", head(z));
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
for(int j=i+1; j<q; j++) {
|
||||
@ -445,7 +444,7 @@ struct cellcrawler {
|
||||
store(cw, i, j, cl);
|
||||
}
|
||||
}
|
||||
if(gaussian) for(cellcrawlerdata& s: data)
|
||||
if(gaussian || true) for(cellcrawlerdata& s: data)
|
||||
s.dist = mydistance(s.orig.at, start.at);
|
||||
}
|
||||
|
||||
@ -462,11 +461,13 @@ struct cellcrawler {
|
||||
}
|
||||
}
|
||||
|
||||
vector<vector<ld>> dispersion;
|
||||
vector<vector<float>> dispersion;
|
||||
};
|
||||
|
||||
double dispersion_end_at = 1.6;
|
||||
|
||||
bool dispersion_long;
|
||||
|
||||
double dispersion_precision = .0001;
|
||||
int dispersion_each = 1;
|
||||
|
||||
@ -476,10 +477,10 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
|
||||
cr.build(cellwalker(c,dir));
|
||||
|
||||
if(!gaussian) {
|
||||
vector<ld> curtemp;
|
||||
vector<ld> newtemp;
|
||||
vector<float> curtemp;
|
||||
vector<float> newtemp;
|
||||
vector<int> qty;
|
||||
vector<pair<ld*, ld*> > pairs;
|
||||
vector<pair<float*, float*> > pairs;
|
||||
int N = isize(net);
|
||||
|
||||
curtemp.resize(N, 0);
|
||||
@ -504,7 +505,7 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
|
||||
|
||||
d.clear();
|
||||
|
||||
DEBBI(DF_LOG, ("Building dispersion, precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n"));
|
||||
// DEBBI(DF_LOG, ("Building dispersion, precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n"));
|
||||
|
||||
for(iter=0; dispersion_count ? true : vmax > vmin * dispersion_end_at; iter++) {
|
||||
if(iter % dispersion_each == 0) {
|
||||
@ -527,10 +528,13 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
|
||||
for(int i=0; i<N; i++)
|
||||
if(curtemp[i] < vmin) vmin = curtemp[i];
|
||||
else if(curtemp[i] > vmax) vmax = curtemp[i];
|
||||
// if(iter % 50 == 0) println(hlog, "iter=", iter, " vmin=", vmin, " vmax=", vmax, " pairs=", isize(pairs));
|
||||
}
|
||||
|
||||
dispersion_count = isize(d);
|
||||
DEBB(DF_LOG, ("Dispersion count = ", dispersion_count));
|
||||
if(!dispersion_count) {
|
||||
if(!dispersion_long) dispersion_count = isize(d);
|
||||
DEBB(DF_LOG, ("Dispersion count = ", isize(d), " celldist = ", celldist(c)));
|
||||
}
|
||||
/*
|
||||
println(hlog, "dlast = ", d.back());
|
||||
println(hlog, "dlast2 = ", d[d.size()-2]);
|
||||
@ -542,7 +546,9 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) {
|
||||
map<int, cellcrawler> scc;
|
||||
|
||||
pair<int, int> get_cellcrawler_id(cell *c) {
|
||||
if(among(geometry, gZebraQuotient, gMinimal, gArnoldCat, gField435, gField534) || (euclid && quotient && !bounded) || IRREGULAR || (GDIM == 3 && sphere) || (hyperbolic && GDIM == 3 && quotient)
|
||||
if(!bounded)
|
||||
return make_pair(neuronId(*getNeuronSlow(c)), 0);
|
||||
if(among(geometry, gZebraQuotient, gMinimal, gArnoldCat, gField435, gField534) || (euclid && quotient && !bounded) || IRREGULAR || (GDIM == 3 && sphere) || (hyperbolic && GDIM == 3)
|
||||
|| (euclid && nonorientable)) {
|
||||
// Zebra Quotient does exhibit some symmetries,
|
||||
// but these are so small anyway that it is safer to just build
|
||||
@ -644,20 +650,20 @@ void step() {
|
||||
tt = pow(tt, ttpower);
|
||||
|
||||
double sigma = maxdist * tt;
|
||||
int dispid = int(dispersion_count * tt);
|
||||
|
||||
if(qpct) {
|
||||
int pct = (int) ((qpct * (t+.0)) / tmax);
|
||||
if(pct != lpct) {
|
||||
lpct = pct;
|
||||
analyze();
|
||||
}
|
||||
|
||||
if(gaussian)
|
||||
println(hlog, format("t = %6d/%6d %3d%% sigma=%10.7lf maxudist=%10.7lf\n", t, tmax, pct, sigma, maxudist));
|
||||
else
|
||||
println(hlog, format("t = %6d/%6d %3d%% dispid=%5d maxudist=%10.7lf\n", t, tmax, pct, dispid, maxudist));
|
||||
}
|
||||
}
|
||||
// if(gaussian)
|
||||
// println(hlog, format("t = %6d/%6d %3d%% sigma=%10.7lf maxudist=%10.7lf\n", t, tmax, pct, sigma, maxudist));
|
||||
// else
|
||||
// println(hlog, format("t = %6d/%6d %3d%% dispid=%5d maxudist=%10.7lf\n", t, tmax, pct, dispid, maxudist));
|
||||
// }
|
||||
} //
|
||||
int id = hrand(samples);
|
||||
neuron& n = winner(id);
|
||||
whowon.resize(samples);
|
||||
@ -678,12 +684,18 @@ void step() {
|
||||
cellcrawler& s = scc[cid.first];
|
||||
s.sprawl(cellwalker(n.where, cid.second));
|
||||
|
||||
vector<double> fake(1,1);
|
||||
vector<float> fake(0,0);
|
||||
/* for(auto& sd: s.data)
|
||||
fake.push_back(exp(-sqr(sd.dist/sigma))); */
|
||||
|
||||
int dispersion_count = isize(s.dispersion);
|
||||
int dispid = int(dispersion_count * tt);
|
||||
|
||||
auto it = gaussian ? fake.begin() : s.dispersion[dispid].begin();
|
||||
|
||||
for(auto& sd: s.data) {
|
||||
neuron *n2 = getNeuron(sd.target.at);
|
||||
if(!n2) continue;
|
||||
if(!n2) { it++; continue; }
|
||||
n2->debug++;
|
||||
double nu = learning_factor;
|
||||
|
||||
@ -697,15 +709,15 @@ void step() {
|
||||
|
||||
for(int k=0; k<columns; k++) {
|
||||
n2->net[k] += nu * (data[id].val[k] - n2->net[k]);
|
||||
if(isnan(n2->net[k]))
|
||||
throw hr_exception("obtained nan somehow, nu = " + lalign(0, nu));
|
||||
/* if(isnan(n2->net[k]))
|
||||
throw hr_exception("obtained nan somehow, nu = " + lalign(0, nu)); */
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& n2: net) {
|
||||
/* for(auto& n2: net) {
|
||||
if(n2.debug > 1) throw hr_exception("sprawler error");
|
||||
n2.debug = 0;
|
||||
}
|
||||
} */
|
||||
|
||||
t--;
|
||||
if(t == 0) analyze();
|
||||
@ -893,7 +905,7 @@ void initialize_dispersion() {
|
||||
|
||||
DEBBI(DF_LOG, ("Initializing dispersion"));
|
||||
|
||||
if(gaussian) {
|
||||
if(gaussian || true) {
|
||||
DEBB(DF_LOG, ("dist = ", fts(mydistance(net[0].where, net[1].where))));
|
||||
cell *c1 = net[cells/2].where;
|
||||
vector<double> mapdist;
|
||||
@ -905,16 +917,23 @@ void initialize_dispersion() {
|
||||
|
||||
dispersion_count = 0;
|
||||
|
||||
if(!gaussian)
|
||||
DEBB(DF_LOG, ("dispersion precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n"));
|
||||
|
||||
DEBB(DF_LOG, ("building crawlers...\n"));
|
||||
|
||||
scc.clear();
|
||||
for(int i=0; i<cells; i++) {
|
||||
cell *c = net[i].where;
|
||||
auto cid = get_cellcrawler_id(c);
|
||||
if(!scc.count(cid.first)) {
|
||||
DEBB(DF_LOG, ("Building cellcrawler id = ", itsh(cid.first)));
|
||||
// DEBB(DF_LOG, ("Building cellcrawler id = ", itsh(cid.first)));
|
||||
buildcellcrawler(c, scc[cid.first], cid.second);
|
||||
}
|
||||
}
|
||||
|
||||
DEBB(DF_LOG, ("crawlers constructed = ", isize(scc), "\n"));
|
||||
|
||||
lpct = -46130;
|
||||
state |= KS_DISPERSION;
|
||||
}
|
||||
@ -1552,7 +1571,7 @@ int readArgs() {
|
||||
gaussian = 0;
|
||||
state &=~ KS_DISPERSION;
|
||||
}
|
||||
else if(argis("-somcgauss")) {
|
||||
else if(argis("-somcgauss") || argis("-cgauss")) {
|
||||
gaussian = 1;
|
||||
state &=~ KS_DISPERSION;
|
||||
}
|
||||
@ -1582,11 +1601,18 @@ int readArgs() {
|
||||
shift(); t = (t*1./tmax) * argi();
|
||||
tmax = argi();
|
||||
}
|
||||
else if(argis("-somlong")) {
|
||||
shift(); dispersion_long = argi();
|
||||
}
|
||||
else if(argis("-somlearn")) {
|
||||
// this one can be changed at any moment
|
||||
shift_arg_formula(learning_factor);
|
||||
}
|
||||
|
||||
else if(argis("-som-analyze")) {
|
||||
analyze();
|
||||
}
|
||||
|
||||
else if(argis("-somrun")) {
|
||||
initialize_rv();
|
||||
set_neuron_initial();
|
||||
|
@ -1451,6 +1451,8 @@ void portal_slideshow(tour::ss::slideshow_callback cb) {
|
||||
slide_backup(ray::exp_decay_poly, 30);
|
||||
slide_backup(ray::fixed_map, true);
|
||||
slide_backup(ray::max_iter_iso, 80);
|
||||
slide_backup(vid.cells_drawn_limit, 100);
|
||||
slide_backup(mapeditor::drawplayer, false);
|
||||
#if CAP_VR
|
||||
slide_backup(vrhr::hsm);
|
||||
slide_backup(vrhr::eyes);
|
||||
@ -1472,6 +1474,7 @@ void portal_slideshow(tour::ss::slideshow_callback cb) {
|
||||
loop = 2;
|
||||
});
|
||||
|
||||
slidecommand = "notknot options";
|
||||
if(mode == tour::pmKey) pushScreen(show);
|
||||
}});
|
||||
};
|
||||
|
@ -81,7 +81,8 @@ void model::load_obj(model_data& md) {
|
||||
emit_material();
|
||||
nextcol = 0xFFFFFFFF;
|
||||
texname = "";
|
||||
mtlname = scanline(fsm);
|
||||
fsm.get<char>();
|
||||
scan(fsm, mtlname);
|
||||
}
|
||||
if(s == "map_Kd") {
|
||||
scan(fsm, texname);
|
||||
@ -93,8 +94,12 @@ void model::load_obj(model_data& md) {
|
||||
next_object:
|
||||
object *co = nullptr;
|
||||
bool textured = false;
|
||||
fs.get<char>();
|
||||
string oname = scanline(fs);
|
||||
println(hlog, "reading object: ", oname);
|
||||
md.objindex.push_back(isize(md.objs));
|
||||
hyperpoint ctr = Hypc;
|
||||
int cqty = 0;
|
||||
while(true) {
|
||||
if(feof(fs.f)) {
|
||||
if(co) cgi.finishshape();
|
||||
@ -117,6 +122,7 @@ void model::load_obj(model_data& md) {
|
||||
h[1] /= 100;
|
||||
h[2] /= 100;
|
||||
vertices.push_back(h);
|
||||
ctr += h; cqty++;
|
||||
}
|
||||
else if(s == "vt") {
|
||||
ld u, v;
|
||||
@ -134,7 +140,10 @@ void model::load_obj(model_data& md) {
|
||||
else if(s == "usemtl") {
|
||||
if(co) cgi.finishshape();
|
||||
if(co) println(hlog, "vertices = ", co->sh.e-co->sh.s, " tvertices = ", isize(co->tv.tvertices));
|
||||
string mtlname = scanline(fs);
|
||||
fs.get<char>();
|
||||
string mtlname;
|
||||
scan(fs, mtlname);
|
||||
//string mtlname = scanline(fs);
|
||||
co = nullptr;
|
||||
if(mtlname.find("Layer_Layer0") != string::npos) continue;
|
||||
objects.push_back(make_shared<object>());
|
||||
@ -197,6 +206,14 @@ void model::load_obj(model_data& md) {
|
||||
}
|
||||
if(!co) continue;
|
||||
|
||||
if(shift_to_ctr) {
|
||||
hyperpoint ctr1 = ctr / cqty;
|
||||
ctr1[3] = 0;
|
||||
println(hlog, "ctr1 = ", ctr1, "hys = ", hys[0]);
|
||||
for(auto& h: hys)
|
||||
h -= ctr1;
|
||||
}
|
||||
|
||||
hyperpoint norm = (hys[1] - hys[0]) ^ (hys[2] - hys[0]);
|
||||
norm /= hypot_d(3, norm);
|
||||
ld y = .5 + (.2 * norm[0] + .16 * norm[1] + .14 * norm[2]);
|
||||
@ -255,6 +272,7 @@ void model::load_obj(model_data& md) {
|
||||
|
||||
println(hlog, "reading finished");
|
||||
|
||||
md.objindex.push_back(isize(md.objs));
|
||||
cgi.extra_vertices();
|
||||
}
|
||||
|
||||
@ -277,7 +295,7 @@ model_data& model::get() {
|
||||
}
|
||||
|
||||
void model_data::render(const shiftmatrix& V) {
|
||||
for(auto& obj: objs) {
|
||||
for(auto& obj: objs) if(obj->color) {
|
||||
queuepoly(V, obj->sh, obj->color);
|
||||
}
|
||||
}
|
||||
@ -303,6 +321,7 @@ auto cf = addHook(hooks_configfile, 100, [] {
|
||||
->editable(1, 100, 1, "3D model precision", "higher-precision models take more time to load and to render.", 'p')
|
||||
->set_sets([] { dialog::numberdark = dialog::DONT_SHOW; })
|
||||
;
|
||||
param_b(shift_to_ctr, "shift_to_ctr");
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -435,6 +435,7 @@ void choose_projection() {
|
||||
cmode = sm::SIDE | sm::MAYDARK;
|
||||
gamescreen(0);
|
||||
dialog::init(XLAT("choose projection"), 0xFFFFFFFF, 150, 0);
|
||||
dynamicval<int> di(index);
|
||||
for(int i=0; i<8; i++) {
|
||||
index = i;
|
||||
dynamicval<eModel> md(pmodel, pmodel);
|
||||
@ -520,7 +521,7 @@ auto msc =
|
||||
|
||||
"We can also project a sphere to a sphere of different curvature. For example, what about the azimuthal equidistant projection from Earth to Moon? "
|
||||
"This projection correctly maps the angles and distances from a chosen point at Earth. "
|
||||
"Press 'o' to use the place on Earth you are in as the chosen point, try other projections, or change the other settings!"
|
||||
"Press '5' to use the place on Earth you are in as the chosen point, try other projections, or change the other settings!"
|
||||
,
|
||||
[] (presmode mode) {
|
||||
slide_url(mode, 't', "Twitter link (with description)", "https://twitter.com/ZenoRogue/status/1339946298460483589");
|
||||
@ -533,9 +534,12 @@ auto msc =
|
||||
slide_backup(pmodel, mdDisk);
|
||||
slide_backup(pconf.scale, 1000);
|
||||
slide_backup(pconf.alpha, 1000);
|
||||
slide_backup(mapeditor::drawplayer, false);
|
||||
start_game();
|
||||
slide_backup(max_alpha, 192);
|
||||
}
|
||||
slidecommand = "options";
|
||||
if(mode == tour::pmKey) pushScreen(show);
|
||||
}});
|
||||
});
|
||||
|
||||
|
@ -169,7 +169,13 @@ void geodesic_screen(presmode mode, int id) {
|
||||
use_angledir(mode, id == 0);
|
||||
|
||||
setCanvas(mode, '0');
|
||||
if(mode == pmStart) stop_game(), pmodel = mdHorocyclic, geometry = gCubeTiling, pconf.clip_min = -10000, pconf.clip_max = +100, start_game();
|
||||
if(mode == pmStart) {
|
||||
slide_backup(pmodel);
|
||||
slide_backup(pconf.clip_min);
|
||||
slide_backup(pconf.clip_max);
|
||||
slide_backup(vid.cells_drawn_limit);
|
||||
stop_game(), pmodel = mdHorocyclic, geometry = gCubeTiling, pconf.clip_min = -10000, pconf.clip_max = +100, start_game();
|
||||
}
|
||||
|
||||
add_stat(mode, [id] {
|
||||
cmode |= sm::SIDE;
|
||||
@ -540,6 +546,7 @@ slide dmv_slides[] = {
|
||||
[] (presmode mode) {
|
||||
setCanvas(mode, '0');
|
||||
if(mode == pmStart) {
|
||||
tour::slide_backup(mapeditor::drawplayer, false);
|
||||
enable_earth();
|
||||
|
||||
View = Id;
|
||||
@ -653,6 +660,7 @@ slide dmv_slides[] = {
|
||||
set_geometry(gFieldQuotient);
|
||||
*/
|
||||
start_game();
|
||||
tour::slide_backup(mapeditor::drawplayer, false);
|
||||
pentaroll::create_pentaroll(true);
|
||||
tour::slide_backup(anims::period, 30000.);
|
||||
tour::slide_backup(sightranges[geometry], 4);
|
||||
@ -1132,7 +1140,7 @@ slide dmv_slides[] = {
|
||||
int phooks =
|
||||
0 +
|
||||
addHook_slideshows(100, [] (tour::ss::slideshow_callback cb) {
|
||||
cb(XLAT("Playing with Impossibility"), &dmv_slides[0], 'p');
|
||||
cb(XLAT("Playing with Impossibility"), &dmv_slides[0], 'i');
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -235,6 +235,7 @@ void choose_presentation() {
|
||||
if(!tour::texts) nomenukey = true;
|
||||
popScreenAll();
|
||||
tour::start();
|
||||
if(!tour::on) tour::start();
|
||||
});
|
||||
});
|
||||
|
||||
@ -250,7 +251,7 @@ int phooks =
|
||||
+ addHook(dialog::hooks_display_dialog, 100, [] () {
|
||||
if(current_screen_cfunction() == showStartMenu) {
|
||||
dialog::addBreak(100);
|
||||
dialog::addBigItem(XLAT("RogueViz demos"), 'p');
|
||||
dialog::addBigItem(XLAT("RogueViz demos"), 'd');
|
||||
dialog::add_action([] () { pushScreen(choose_presentation); });
|
||||
}
|
||||
});
|
||||
|
@ -40,11 +40,15 @@ bool snow_glitch = false;
|
||||
/* disable textures */
|
||||
bool snow_texture = true;
|
||||
|
||||
/* draw single objects? */
|
||||
bool single_objects = true;
|
||||
|
||||
int snow_shape = 0;
|
||||
|
||||
struct snowball {
|
||||
transmatrix T;
|
||||
int model_id;
|
||||
int object_id;
|
||||
};
|
||||
|
||||
map<cell*, vector<snowball>> snowballs_at;
|
||||
@ -134,14 +138,29 @@ bool draw_snow(cell *c, const shiftmatrix& V) {
|
||||
}
|
||||
}
|
||||
|
||||
for(int t=0; t<cnt; t++)
|
||||
v.emplace_back(snowball{random_snow_matrix(c), isize(models) ? hrand(isize(models)) : 0});
|
||||
for(int t=0; t<cnt; t++) {
|
||||
snowball b{random_snow_matrix(c), 0, -1};
|
||||
if(isize(models)) {
|
||||
b.model_id = hrand(isize(models));
|
||||
if(single_objects)
|
||||
b.object_id = hrand(isize(models[b.model_id].get().objindex)-1);
|
||||
}
|
||||
v.emplace_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
poly_outline = 0xFF;
|
||||
for(auto& T: snowballs_at[c]) {
|
||||
if(models.size()) {
|
||||
if(T.object_id == -1)
|
||||
models[T.model_id].render(V*T.T);
|
||||
else {
|
||||
auto& m = models[T.model_id].get();
|
||||
for(int i=m.objindex[T.object_id]; i<m.objindex[T.object_id+1]; i++) {
|
||||
auto& obj = m.objs[i];
|
||||
if(obj->color) queuepoly(V*T.T, obj->sh, obj->color);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto& p = queuepoly(V * T.T, shapeid(snow_shape), snow_color);
|
||||
|
Loading…
Reference in New Issue
Block a user