mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
magic adjustment of textures
This commit is contained in:
parent
e2080cd91e
commit
bf24550e82
4
game.cpp
4
game.cpp
@ -145,6 +145,10 @@ int hrand(int i) {
|
||||
return r() % i;
|
||||
}
|
||||
|
||||
ld hrandf() {
|
||||
return (r() & HRANDMAX) / (HRANDMAX + 1.0);
|
||||
}
|
||||
|
||||
void initcell(cell *c) {
|
||||
c->mpdist = INFD; // minimum distance from the player, ever
|
||||
c->cpdist = INFD; // current distance from the player
|
||||
|
12
graph.cpp
12
graph.cpp
@ -4855,6 +4855,12 @@ bool allowIncreasedSight() {
|
||||
|
||||
purehookset hooks_drawmap;
|
||||
|
||||
transmatrix cview() {
|
||||
sphereflip = Id;
|
||||
if(sphereflipped()) sphereflip[2][2] = -1;
|
||||
return ypush(vid.yshift) * sphereflip * View;
|
||||
}
|
||||
|
||||
void drawthemap() {
|
||||
|
||||
callhooks(hooks_drawmap);
|
||||
@ -4924,12 +4930,10 @@ void drawthemap() {
|
||||
|
||||
arrowtraps.clear();
|
||||
|
||||
sphereflip = Id;
|
||||
profile_start(1);
|
||||
if(euclid)
|
||||
drawEuclidean();
|
||||
else {
|
||||
if(sphereflipped()) sphereflip[2][2] = -1;
|
||||
int sr = max(sightrange, ambush_distance);
|
||||
maxreclevel =
|
||||
conformal::on ? sr + 2:
|
||||
@ -4937,9 +4941,7 @@ void drawthemap() {
|
||||
|
||||
if(S3>3) maxreclevel+=2;
|
||||
|
||||
drawrec(viewctr,
|
||||
maxreclevel,
|
||||
hsOrigin, ypush(vid.yshift) * sphereflip * View);
|
||||
drawrec(viewctr, maxreclevel, hsOrigin, cview());
|
||||
}
|
||||
drawBlizzards();
|
||||
drawArrowTraps();
|
||||
|
3
hyper.h
3
hyper.h
@ -2397,3 +2397,6 @@ inline hyperpoint tC0(const transmatrix &T) {
|
||||
z[0] = T[0][2]; z[1] = T[1][2]; z[2] = T[2][2];
|
||||
return z;
|
||||
}
|
||||
|
||||
transmatrix actualV(const heptspin& hs, const transmatrix& V);
|
||||
transmatrix cview();
|
||||
|
@ -329,6 +329,10 @@ bool confusingGeometry() {
|
||||
return elliptic || quotient == 1 || torus;
|
||||
}
|
||||
|
||||
transmatrix actualV(const heptspin& hs, const transmatrix& V) {
|
||||
return (hs.spin || nontruncated) ? V * spin(hs.spin*2*M_PI/S7 + (nontruncated ? M_PI:0)) : V;
|
||||
}
|
||||
|
||||
void drawrec(const heptspin& hs, int lev, hstate s, const transmatrix& V) {
|
||||
|
||||
// shmup::calc_relative_matrix(cwt.c, hs.h);
|
||||
@ -340,8 +344,7 @@ void drawrec(const heptspin& hs, int lev, hstate s, const transmatrix& V) {
|
||||
|
||||
if(dodrawcell(c)) {
|
||||
reclevel = maxreclevel - lev;
|
||||
drawcell(c, (hs.spin || nontruncated) ? V1 * spin(hs.spin*2*M_PI/S7 + (nontruncated ? M_PI:0)) : V1, 0,
|
||||
hs.mirrored);
|
||||
drawcell(c, actualV(hs, V1), 0, hs.mirrored);
|
||||
}
|
||||
|
||||
if(lev <= 0) return;
|
||||
|
25
shmup.cpp
25
shmup.cpp
@ -3276,6 +3276,16 @@ void destroyBoats(cell *c) {
|
||||
}
|
||||
|
||||
transmatrix calc_relative_matrix(cell *c, heptagon *h1) {
|
||||
|
||||
if(sphere) {
|
||||
if(gmatrix0.count(c) && gmatrix0.count(h1->c7))
|
||||
return inverse(gmatrix0[h1->c7]) * gmatrix0[c];
|
||||
else {
|
||||
printf("error: gmatrix0 not known\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
transmatrix gm = Id;
|
||||
heptagon *h2 = c->master;
|
||||
transmatrix where = Id;
|
||||
@ -3316,13 +3326,7 @@ transmatrix calc_relative_matrix(cell *c, heptagon *h1) {
|
||||
transmatrix &ggmatrix(cell *c) {
|
||||
transmatrix& t = gmatrix[c];
|
||||
if(t[2][2] == 0) {
|
||||
if(sphere && gmatrix0.count(c))
|
||||
t = gmatrix[cwt.c] * inverse(gmatrix0[cwt.c]) * gmatrix0[c];
|
||||
else if(sphere) {
|
||||
printf("error: gmatrix0 not known\n");
|
||||
exit(1);
|
||||
}
|
||||
else if(torus) {
|
||||
if(torus) {
|
||||
forCellIdEx(c2, i, c)
|
||||
if(celldistance(c2, centerover) < celldistance(c, centerover))
|
||||
t = ggmatrix(c2) * eumovedir(3+i);
|
||||
@ -3338,11 +3342,8 @@ transmatrix &ggmatrix(cell *c) {
|
||||
printf("gmatrix0 = \n");
|
||||
display(gmatrix0[c]); */
|
||||
}
|
||||
else {
|
||||
t =
|
||||
View * spin(viewctr.spin * 2 * M_PI / S7) * calc_relative_matrix(c, viewctr.h);
|
||||
if(nontruncated) t = t * pispin;
|
||||
}
|
||||
else
|
||||
t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
140
textures.cpp
140
textures.cpp
@ -171,14 +171,13 @@ void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const trans
|
||||
|
||||
ld z = ctof(c) ? rhexf : hexvdist;
|
||||
|
||||
int sym = si.symmetries;
|
||||
// int sym = si.symmetries;
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
int is = i % sym;
|
||||
hyperpoint h1 = spin(M_PI + M_PI * (2*i +1) / c->type) * xpush(z) * C0;
|
||||
hyperpoint h2 = spin(M_PI + M_PI * (2*i -1) / c->type) * xpush(z) * C0;
|
||||
hyperpoint hm1 = spin(M_PI + M_PI * (2*is+1) / c->type) * xpush(z) * C0;
|
||||
hyperpoint hm2 = spin(M_PI + M_PI * (2*is-1) / c->type) * xpush(z) * C0;
|
||||
hyperpoint hm1 = spin(M_PI + M_PI * (2*i +1) / c->type) * xpush(z) * C0;
|
||||
hyperpoint hm2 = spin(M_PI + M_PI * (2*i -1) / c->type) * xpush(z) * C0;
|
||||
mapTextureTriangle(mi, {C0, h1, h2}, {C0, hm1, hm2});
|
||||
}
|
||||
}
|
||||
@ -272,7 +271,7 @@ void perform_mapping() {
|
||||
|
||||
if(!texture_map.count(si.id))
|
||||
replace = true;
|
||||
else if(hdist0(p.second*C0) < hdist0(texture_map[si.id].M * C0))
|
||||
else if(hdist0(p.second*sphereflip * C0) < hdist0(texture_map[si.id].M * sphereflip * C0))
|
||||
replace = true;
|
||||
|
||||
if(replace) {
|
||||
@ -342,7 +341,82 @@ void drawRawTexture() {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
enum eTexturePanstate {tpsModel, tpsMove, tpsScale, tpsAffine, tpsZoom, tpsProjection};
|
||||
struct magicmapper_point {
|
||||
cell *c;
|
||||
hyperpoint cell_relative;
|
||||
hyperpoint texture_coords;
|
||||
};
|
||||
|
||||
vector<magicmapper_point> amp;
|
||||
|
||||
struct magic_param {
|
||||
bool do_spin;
|
||||
ld spinangle, scale, proj, moveangle, shift;
|
||||
|
||||
void shuffle() {
|
||||
do_spin = hrand(2);
|
||||
spinangle = hrandf() - hrandf();
|
||||
moveangle = hrandf() * 2 * M_PI;
|
||||
shift = hrandf() - hrandf();
|
||||
scale = hrandf() - hrandf();
|
||||
proj = hrandf() - hrandf();
|
||||
}
|
||||
|
||||
void apply(ld delta) {
|
||||
vid.alpha *= exp(delta * proj);
|
||||
vid.scale *= exp(delta * scale);
|
||||
|
||||
if(do_spin)
|
||||
View = spin(delta * spinangle) * View;
|
||||
else
|
||||
View = spin(moveangle) * xpush(delta*shift) * spin(-moveangle) * View;
|
||||
|
||||
fixmatrix(View);
|
||||
}
|
||||
};
|
||||
|
||||
ld magic_quality() {
|
||||
gmatrix.clear();
|
||||
calcparam();
|
||||
|
||||
ld q = 0;
|
||||
for(auto& p: amp) {
|
||||
hyperpoint inmodel;
|
||||
applymodel(shmup::ggmatrix(p.c) * p.cell_relative, inmodel);
|
||||
inmodel[0] *= vid.radius * 1. / vid.scrsize;
|
||||
inmodel[1] *= vid.radius * 1. / vid.scrsize;
|
||||
q += intvalxy(inmodel, p.texture_coords);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
void applyMagic() {
|
||||
ld cq = magic_quality();
|
||||
|
||||
int last_success = 0;
|
||||
|
||||
for(int s=0; s<50000 && s<last_success + 1000; s++) {
|
||||
magic_param p;
|
||||
p.shuffle();
|
||||
|
||||
bool failed = false;
|
||||
|
||||
for(ld delta = 1; delta > 1e-9; delta *= (failed ? -.7 : 1.2)) {
|
||||
p.apply(delta);
|
||||
ld nq = magic_quality();
|
||||
if(nq < cq) {
|
||||
cq = nq;
|
||||
last_success = s;
|
||||
}
|
||||
else {
|
||||
p.apply(-delta);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum eTexturePanstate {tpsModel, tpsMove, tpsScale, tpsAffine, tpsZoom, tpsProjection, tpsMagic};
|
||||
eTexturePanstate panstate;
|
||||
|
||||
void mousemovement() {
|
||||
@ -385,7 +459,7 @@ void mousemovement() {
|
||||
case tpsZoom: {
|
||||
// do not zoom in portrait!
|
||||
if(nonzero && !newmove) {
|
||||
View = View * inverse(spintox(mouseeu)) * spintox(lastmouse);
|
||||
View = inverse(spintox(mouseeu)) * spintox(lastmouse) * View;
|
||||
vid.scale = vid.scale * sqrt(intvalxy(C0, mouseeu)) / sqrt(intvalxy(C0, lastmouse));
|
||||
}
|
||||
if(nonzero) lastmouse = mouseeu;
|
||||
@ -401,6 +475,18 @@ void mousemovement() {
|
||||
newmove = false;
|
||||
}
|
||||
|
||||
case tpsMagic: {
|
||||
if(!mouseover) return;
|
||||
if(newmove) {
|
||||
magicmapper_point newpoint;
|
||||
newpoint.c = mouseover;
|
||||
newpoint.cell_relative = inverse(gmatrix[mouseover]) * mouseh;
|
||||
amp.push_back(newpoint);
|
||||
newmove = false;
|
||||
}
|
||||
amp.back().texture_coords = mouseeu;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -490,6 +576,7 @@ bool load_textureconfig() {
|
||||
}
|
||||
|
||||
if(!readtexture()) return false;
|
||||
calcparam();
|
||||
drawthemap();
|
||||
perform_mapping();
|
||||
tstate = tstate_max = tsActive;
|
||||
@ -523,6 +610,13 @@ void showMenu() {
|
||||
dialog::addBoolItem(XLAT("zoom/scale the model"), panstate == tpsZoom, 'z');
|
||||
dialog::addBoolItem(XLAT("projection"), panstate == tpsProjection, 'p');
|
||||
dialog::addBoolItem(XLAT("affine transformations"), panstate == tpsAffine, 'y');
|
||||
dialog::addBoolItem(XLAT("magic"), panstate == tpsMagic, 'A');
|
||||
|
||||
if(panstate == tpsMagic) {
|
||||
dialog::addSelItem(XLAT("delete markers"), its(size(amp)), 'D');
|
||||
dialog::addSelItem(XLAT("perform auto-adjustment"), "...", 'R');
|
||||
}
|
||||
|
||||
dialog::addSelItem(XLAT("precision"), its(gsplits), 'p');
|
||||
}
|
||||
|
||||
@ -546,6 +640,33 @@ void showMenu() {
|
||||
|
||||
dialog::display();
|
||||
|
||||
if(tstate == tsAdjusting) {
|
||||
initquickqueue();
|
||||
char letter = 'A';
|
||||
for(auto& am: amp) {
|
||||
hyperpoint h = shmup::ggmatrix(am.c) * am.cell_relative;
|
||||
display(h);
|
||||
queuechr(h, vid.fsize, letter, 0xC00000, 1);
|
||||
|
||||
hyperpoint inmodel;
|
||||
applymodel(h, inmodel);
|
||||
inmodel[0] *= vid.radius * 1. / vid.scrsize;
|
||||
inmodel[1] *= vid.radius * 1. / vid.scrsize;
|
||||
queuechr(
|
||||
vid.xcenter + vid.scrsize * inmodel[0],
|
||||
vid.ycenter + vid.scrsize * inmodel[1],
|
||||
0, vid.fsize/2, letter, 0xC0C0C0, 1);
|
||||
|
||||
queuechr(
|
||||
vid.xcenter + vid.scrsize * am.texture_coords[0],
|
||||
vid.ycenter + vid.scrsize * am.texture_coords[1],
|
||||
0, vid.fsize, letter, 0x00C000, 1);
|
||||
|
||||
letter++;
|
||||
}
|
||||
quickqueue();
|
||||
}
|
||||
|
||||
if(holdmouse) mousemovement();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
@ -565,7 +686,10 @@ void showMenu() {
|
||||
else if(uni == 'y' && tstate == tsAdjusting) panstate = tpsAffine;
|
||||
else if(uni == 'z' && tstate == tsAdjusting) panstate = tpsZoom;
|
||||
else if(uni == 'p' && tstate == tsAdjusting) panstate = tpsProjection;
|
||||
|
||||
else if(uni == 'A' && tstate == tsAdjusting) panstate = tpsMagic;
|
||||
else if(uni == 'D' && tstate == tsAdjusting) amp.clear();
|
||||
else if(uni == 'R' && tstate == tsAdjusting) applyMagic();
|
||||
|
||||
else if(uni == 's' && tstate == tsActive)
|
||||
dialog::openFileDialog(configname, XLAT("texture config to save:"), ".txc",
|
||||
[] () {
|
||||
|
Loading…
Reference in New Issue
Block a user