1
0
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:
Zeno Rogue 2017-12-16 09:03:50 +01:00
parent e2080cd91e
commit bf24550e82
6 changed files with 164 additions and 27 deletions

View File

@ -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

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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",
[] () {