1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 01:00:25 +00:00

fully turnable product spaces

This commit is contained in:
Zeno Rogue 2019-08-18 01:31:37 +02:00
parent 52f19a26a8
commit 00f4f4fca5
10 changed files with 63 additions and 35 deletions

View File

@ -400,8 +400,13 @@ void display_data::set_projection(int ed) {
if(pers3) {
glhr::projection_multiply(glhr::frustum(current_display->tanfov, current_display->tanfov * cd->ysize / cd->xsize));
glhr::projection_multiply(glhr::scale(1, -1, -1));
if(nisot::local_perspective_used())
if(nisot::local_perspective_used()) {
if(prod) {
for(int i=0; i<3; i++) nisot::local_perspective[3][i] = nisot::local_perspective[i][3] = 0;
nisot::local_perspective[3][3] = 1;
}
glhr::projection_multiply(glhr::tmtogl_transpose(nisot::local_perspective));
}
}
else if(GDIM == 3) {
glhr::glmatrix M = glhr::ortho(cd->xsize/current_display->radius/2, -cd->ysize/current_display->radius/2, 1);

View File

@ -70,11 +70,13 @@ EX bool mouseout2() {
return outofmap(mouseh) || outofmap(mouseoh);
}
EX movedir vectodir(const hyperpoint& P) {
EX movedir vectodir(hyperpoint P) {
transmatrix U = ggmatrix(cwt.at);
if(GDIM == 3 && WDIM == 2) U = radar_transform * U;
if(nisot::local_perspective_used()) U = nisot::local_perspective * U;
if(nisot::local_perspective_used()) P = inverse(nisot::local_perspective) * P;
if(prod) P = product::direct_exp(P);
hyperpoint H = sphereflip * tC0(U);
transmatrix Centered = sphereflip * rgpushxto0(H);
@ -111,13 +113,12 @@ EX void remission() {
}
EX hyperpoint move_destination_vec(int d) {
hyperpoint Forward = prod ? hpxy3(1,0,0) : tC0(pushone());
if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
// else if(WDIM == 2 && pmodel == mdPerspective) return cspin(0, 2, d * M_PI/4) * tC0(pushone());
// else if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * tC0(pushone());
else if(prod && d == 6) return zshift(C0, product::plevel);
else if(prod && d == 2) return zshift(C0, -product::plevel);
else return cspin(0, 2, d * M_PI/4) * tC0(pushone());
else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * Forward;
else return cspin(0, 2, d * M_PI/4) * Forward;
}
EX void movepckeydir(int d) {
@ -284,28 +285,31 @@ typedef SDL_Event eventtype;
EX bool smooth_scrolling = false;
EX void handlePanning(int sym, int uni) {
auto& LPe = nisot::local_perspective;
if(mousepan && dual::split([=] { handlePanning(sym, uni); })) return;
if(GDIM == 3) {
if(sym == PSEUDOKEY_WHEELUP) View = solmul(cpush(2, -0.05*shiftmul), View), didsomething = true, playermoved = false;
if(sym == PSEUDOKEY_WHEELDOWN) View = solmul(cpush(2, 0.05*shiftmul), View), didsomething = true, playermoved = false;
if(sym == PSEUDOKEY_WHEELUP) View = solmul(cpush(2, -0.05*shiftmul), LPe, View), didsomething = true, playermoved = false;
if(sym == PSEUDOKEY_WHEELDOWN) View = solmul(cpush(2, 0.05*shiftmul), LPe, View), didsomething = true, playermoved = false;
}
if(rug::rugged || smooth_scrolling) {
return;
}
auto& LPV = prod ? nisot::local_perspective : View;
#if !ISPANDORA
if(sym == SDLK_END && GDIM == 3) {
View = solmul(cpush(2, -0.2*shiftmul), View), didsomething = true, playermoved = false;
View = solmul(cpush(2, -0.2*shiftmul), LPe, View), didsomething = true, playermoved = false;
}
if(sym == SDLK_HOME && GDIM == 3) {
View = solmul(cpush(2, +0.2*shiftmul), View), didsomething = true, playermoved = false;
View = solmul(cpush(2, +0.2*shiftmul), LPe, View), didsomething = true, playermoved = false;
}
if(sym == SDLK_RIGHT) {
if(history::on)
history::lvspeed += 0.1 * shiftmul;
else if(GDIM == 3)
View = cspin(0, 2, -0.2*shiftmul) * View, didsomething = true;
LPV = cspin(0, 2, -0.2*shiftmul) * LPV, didsomething = true;
else
View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
}
@ -313,7 +317,7 @@ EX void handlePanning(int sym, int uni) {
if(history::on)
history::lvspeed -= 0.1 * shiftmul;
else if(GDIM == 3)
View = cspin(0, 2, 0.2*shiftmul) * View, didsomething = true;
LPV = cspin(0, 2, 0.2*shiftmul) * LPV, didsomething = true;
else
View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
}
@ -321,7 +325,7 @@ EX void handlePanning(int sym, int uni) {
if(history::on)
history::lvspeed += 0.1 * shiftmul;
else if(GDIM == 3)
View = cspin(1, 2, 0.2*shiftmul) * View, didsomething = true;
LPV = cspin(1, 2, 0.2*shiftmul) * LPV, didsomething = true;
else
View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
}
@ -329,7 +333,7 @@ EX void handlePanning(int sym, int uni) {
if(history::on)
history::lvspeed -= 0.1 * shiftmul;
else if(GDIM == 3)
View = cspin(1, 2, -0.2*shiftmul) * View, didsomething = true;
LPV = cspin(1, 2, -0.2*shiftmul) * LPV, didsomething = true;
else
View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
}
@ -338,13 +342,13 @@ EX void handlePanning(int sym, int uni) {
if(history::on)
models::rotation++;
else
View = spin(M_PI/cgi.S21/2*shiftmul) * View, didsomething = true;
LPV = spin(M_PI/cgi.S21/2*shiftmul) * LPV, didsomething = true;
}
if(sym == SDLK_PAGEDOWN) {
if(history::on)
models::rotation++;
else
View = spin(-M_PI/cgi.S21/2*shiftmul) * View, didsomething = true;
LPV = spin(-M_PI/cgi.S21/2*shiftmul) * LPV, didsomething = true;
}
if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN)
@ -672,7 +676,8 @@ EX void mainloopiter() {
if(GDIM == 3 && !shmup::on && !rug::rugged) {
#if CAP_MOUSEGRAB
View = cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y) * View;
auto &LPV = prod ? nisot::local_perspective : View;
LPV = cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y) * LPV;
mouseaim_x = mouseaim_y = 0;
#endif
}

View File

@ -897,7 +897,7 @@ void dqi_poly::draw() {
auto npoly = *this;
glcoords.clear();
for(int i=0; i<cnt; i++)
glcoords.push_back(glhr::pointtogl(product::where(V * glhr::gltopoint( (*tab)[offset+i]))));
glcoords.push_back(glhr::pointtogl(product::inverse_exp(V * glhr::gltopoint( (*tab)[offset+i]))));
npoly.offset = 0;
npoly.tab = &glcoords;

View File

@ -4483,7 +4483,7 @@ EX int noclipped;
void make_clipping_planes() {
#if MAXMDIM >= 4
clipping_planes.clear();
if(sphere) return;
if(sphere || prod) return;
auto add_clipping_plane = [] (ld x1, ld y1, ld x2, ld y2) {
ld z1 = 1, z2 = 1;
hyperpoint sx = point3(y1 * z2 - y2 * z1, z1 * x2 - z2 * x1, x1 * y2 - x2 * y1);
@ -5994,7 +5994,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
for(int a=0; a<c->type; a++)
if(c->move(a) && !isWall3(c->move(a), dummy)) {
if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic) {
if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic && !prod) {
if(a < 4 && among(geometry, gHoroTris, gBinary3) && celldistAlt(c) >= celldistAlt(viewcenter())) continue;
else if(a < 2 && among(geometry, gHoroRec) && celldistAlt(c) >= celldistAlt(viewcenter())) continue;
else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue;
@ -7149,7 +7149,7 @@ EX void make_actual_view() {
if(GDIM == 3) {
ld max = WDIM == 2 ? vid.camera : vid.yshift;
if(max)
actual_view_transform = solmul(zpush(wall_radar((masterless ? centerover.at : viewcenter()), inverse(View), max)), actual_view_transform * View) * inverse(View);
actual_view_transform = solmul(zpush(wall_radar((masterless ? centerover.at : viewcenter()), inverse(View), max)), nisot::local_perspective, actual_view_transform * View) * inverse(View);
camera_level = asin_auto(tC0(inverse(actual_view_transform * View))[2]);
}
if(nonisotropic) {

View File

@ -449,6 +449,8 @@ EX transmatrix euaffine(hyperpoint h) {
EX transmatrix cpush(int cid, ld alpha) {
transmatrix T = Id;
if(prod && cid == 2)
return mscale(Id, exp(alpha));
if(nonisotropic)
return eupush3(cid == 0 ? alpha : 0, cid == 1 ? alpha : 0, cid == 2 ? alpha : 0);
T[LDIM][LDIM] = T[cid][cid] = cos_auto(alpha);
@ -926,8 +928,8 @@ bool asign(ld y1, ld y2) { return signum(y1) != signum(y2); }
ld xcross(ld x1, ld y1, ld x2, ld y2) { return x1 + (x2 - x1) * y1 / (y1 - y2); }
EX transmatrix solmul(const transmatrix T, const transmatrix V) {
if(nonisotropic) return nisot::transport_view(T, V);
EX transmatrix solmul(const transmatrix T, const transmatrix LPe, const transmatrix V) {
if(nonisotropic || prod) return nisot::transport_view(T, LPe, V);
else return T * V;
}

View File

@ -1358,10 +1358,10 @@ EX void centerpc(ld aspd) {
}
if(R < aspd) {
View = solmul(gpushxto0(H), View);
View = solmul(gpushxto0(H), Id, View);
}
else
View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), View);
View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), Id, View);
fixmatrix(View);
spinEdge(aspd);
@ -1472,6 +1472,7 @@ EX void resetview() {
viewctr.spin = cwt.spin;
else centerover = cwt;
cwtV = View;
nisot::local_perspective = Id;
// SDL_LockSurface(s);
// SDL_UnlockSurface(s);
}

View File

@ -141,7 +141,7 @@ EX namespace models {
#endif
EX transmatrix rotmatrix() {
if(GDIM == 2) return spin(rotation * degree);
if(GDIM == 2 || prod) return spin(rotation * degree);
return spin(rotation_xy2 * degree) * cspin(0, 2, -rotation_xz * degree) * spin(rotation * degree);
}

View File

@ -12,7 +12,7 @@ EX namespace nisot {
EX transmatrix local_perspective;
#if HDR
inline bool local_perspective_used() { return nonisotropic; }
inline bool local_perspective_used() { return nonisotropic || prod; }
#endif
EX bool geodesic_movement = true;
@ -582,7 +582,8 @@ EX namespace product {
heptagon *getOrigin() override { return underlying_map->getOrigin(); }
template<class T> auto in_underlying(const T& t) {
pcgip = cgip; pmap = this;
pcgip = cgip;
dynamicval<hrmap*> gpm(pmap, this);
dynamicval<eGeometry> g(geometry, underlying);
dynamicval<geometry_information*> gc(cgip, underlying_cgip);
dynamicval<hrmap*> gu(currentmap, underlying_map);
@ -638,10 +639,10 @@ EX namespace product {
return mscale(get_corner_position(c, i), exp(plevel * z/2));
}
EX hyperpoint where(hyperpoint h) {
EX hyperpoint inverse_exp(hyperpoint h) {
hyperpoint res;
res[2] = zlevel(h);
h = mscale(h, exp(-res[2]));
h = zshift(h, -res[2]);
ld r = hypot_d(2, h);
if(r < 1e-6 || h[2] < 1) {
res[0] = h[0];
@ -655,6 +656,16 @@ EX namespace product {
return res;
}
EX hyperpoint direct_exp(hyperpoint h) {
hyperpoint res;
ld d = hypot_d(2, h);
ld cd = d == 0 ? 0 : sinh(d) / d;
res[0] = h[0] * cd;
res[1] = h[1] * cd;
res[2] = cosh(d);
return zshift(res, h[2]);
}
EX void in_underlying_map(const reaction_t& f) {
((hrmap_product*)currentmap)->in_underlying(f);
}
@ -762,7 +773,11 @@ EX namespace nisot {
return parallel_transport_bare(P, T);
}
EX transmatrix transport_view(const transmatrix T, const transmatrix V) {
EX transmatrix transport_view(const transmatrix T, const transmatrix LPe, const transmatrix V) {
if(prod) {
hyperpoint h = product::direct_exp(inverse(LPe) * product::inverse_exp(tC0(T)));
return rgpushxto0(h) * V;
}
if(!geodesic_movement) {
transmatrix IV = inverse(V);
nisot::fixmatrix(IV);

View File

@ -610,7 +610,7 @@ EX void apply() {
}
}
View = solmul(cspin(0, GDIM-1, movement_angle * degree) * ypush(shift_angle * degree) * xpush(cycle_length * t / period) * ypush(-shift_angle * degree) *
cspin(0, GDIM-1, -movement_angle * degree), View);
cspin(0, GDIM-1, -movement_angle * degree), nisot::local_perspective, View);
moved();
if(clearup) {
viewcenter()->wall = waNone;
@ -633,7 +633,7 @@ EX void apply() {
case maTranslationRotation:
View = solmul(cspin(0, GDIM-1, movement_angle * degree) * ypush(shift_angle * degree) * xpush(cycle_length * t / period) * ypush(-shift_angle * degree) *
cspin(0, GDIM-1, -movement_angle * degree), View);
cspin(0, GDIM-1, -movement_angle * degree), nisot::local_perspective, View);
moved();
View = cspin(0, GDIM-1, 2 * M_PI * t / period) * View;
if(clearup) {

View File

@ -794,7 +794,7 @@ EX hyperpoint gltopoint(const glvertex& t) {
EX glvertex pointtogl(const hyperpoint& t) {
glvertex h;
h[0] = t[0]; h[1] = t[1]; h[2] = t[2];
if(SHDIM == 4) h[3] = (GDIM == 3) ? t[3] : 1;
if(SHDIM == 4) h[3] = (MDIM == 4) ? t[3] : 1;
return h;
}