mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-22 22:10:20 +00:00
refactored all the operations on View
This commit is contained in:
parent
65ce70cb2c
commit
96d7496043
@ -622,37 +622,25 @@ void geometry_information::animate_bird(hpcshape& orig, hpcshape_animated& anima
|
||||
// shift_shape(orig, BIRD);
|
||||
}
|
||||
|
||||
EX hyperpoint forward_dir(ld x) { return hybri ? point3(x, 0, 0) : xpush0(x); }
|
||||
EX hyperpoint zforward_dir(ld z) { return hybri ? point3(0, 0, z) : zpush0(z); }
|
||||
|
||||
EX hyperpoint dir_to_point(hyperpoint h) { return hybri ? nisot::direct_exp(h, 100) : h; }
|
||||
|
||||
EX hyperpoint dir_setlength(hyperpoint dir, ld length) {
|
||||
if(dir[0] == 0 && dir[1] == 0 && dir[2] == 0) return dir;
|
||||
if(prod) return dir * (length / hypot_d(3, dir));
|
||||
return rspintox(dir) * xpush0(length);
|
||||
}
|
||||
|
||||
void geometry_information::slimetriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) {
|
||||
dynamicval<int> d(vid.texture_step, 8);
|
||||
texture_order([&] (ld x, ld y) {
|
||||
ld z = 1-x-y;
|
||||
ld r = scalefactor * hcrossf7 * (0 + pow(max(x,max(y,z)), .3) * 0.8) * (hybri ? .5 : 1);
|
||||
hyperpoint h = dir_to_point(dir_setlength(a*x+b*y+c*z, r));
|
||||
hyperpoint h = direct_exp(tangent_length(a*x+b*y+c*z, r), 10);
|
||||
hpcpush(h);
|
||||
});
|
||||
}
|
||||
|
||||
void geometry_information::balltriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) {
|
||||
if(lev == 0) {
|
||||
hpcpush(dir_to_point(a));
|
||||
hpcpush(dir_to_point(b));
|
||||
hpcpush(dir_to_point(c));
|
||||
hpcpush(direct_exp(a, 10));
|
||||
hpcpush(direct_exp(b, 10));
|
||||
hpcpush(direct_exp(c, 10));
|
||||
}
|
||||
else {
|
||||
auto midpoint = [&] (hyperpoint h1, hyperpoint h2) {
|
||||
if(prod) return dir_setlength(h1+h2, rad);
|
||||
else return rspintox(mid(h1,h2)) * xpush0(rad);
|
||||
return tangent_length(h1+h2, rad);
|
||||
};
|
||||
hyperpoint cx = midpoint(a, b);
|
||||
hyperpoint ax = midpoint(b, c);
|
||||
@ -667,8 +655,8 @@ void geometry_information::balltriangle(hyperpoint a, hyperpoint b, hyperpoint c
|
||||
void geometry_information::make_ball(hpcshape& sh, ld rad, int lev) {
|
||||
bshape(sh, sh.prio);
|
||||
sh.flags |= POLY_TRIANGLES;
|
||||
hyperpoint tip = forward_dir(rad);
|
||||
hyperpoint atip = forward_dir(-rad);
|
||||
hyperpoint tip = xtangent(rad);
|
||||
hyperpoint atip = xtangent(-rad);
|
||||
ld z = 63.43 * degree;
|
||||
for(int i=0; i<5; i++) {
|
||||
hyperpoint a = cspin(1, 2, (72 * i ) * degree) * spin(z) * tip;
|
||||
@ -1125,14 +1113,14 @@ void geometry_information::make_3d_models() {
|
||||
|
||||
DEBB(DF_POLY, ("slime"));
|
||||
bshape(shSlime, PPR::MONSTER_BODY);
|
||||
hyperpoint tip = xpush0(1);
|
||||
hyperpoint atip = xpush0(-1);
|
||||
hyperpoint tip = xtangent(1);
|
||||
hyperpoint atip = xtangent(-1);
|
||||
ld z = 63.43 * degree;
|
||||
for(int i=0; i<5; i++) {
|
||||
auto a = cspin(1, 2, (72 * i ) * degree) * spin(z) * forward_dir(1);
|
||||
auto b = cspin(1, 2, (72 * i-72) * degree) * spin(z) * forward_dir(1);
|
||||
auto c = cspin(1, 2, (72 * i+36) * degree) * spin(M_PI-z) * forward_dir(1);
|
||||
auto d = cspin(1, 2, (72 * i-36) * degree) * spin(M_PI-z) * forward_dir(1);
|
||||
auto a = cspin(1, 2, (72 * i ) * degree) * spin(z) * xtangent(1);
|
||||
auto b = cspin(1, 2, (72 * i-72) * degree) * spin(z) * xtangent(1);
|
||||
auto c = cspin(1, 2, (72 * i+36) * degree) * spin(M_PI-z) * xtangent(1);
|
||||
auto d = cspin(1, 2, (72 * i-36) * degree) * spin(M_PI-z) * xtangent(1);
|
||||
slimetriangle(tip, a, b, 1, 0);
|
||||
slimetriangle(a, b, c, 1, 0);
|
||||
slimetriangle(b, c, d, 1, 0);
|
||||
|
36
control.cpp
36
control.cpp
@ -75,8 +75,7 @@ EX movedir vectodir(hyperpoint P) {
|
||||
transmatrix U = ggmatrix(cwt.at);
|
||||
if(GDIM == 3 && WDIM == 2) U = radar_transform * U;
|
||||
|
||||
if(nisot::local_perspective_used()) P = inverse(nisot::local_perspective) * P;
|
||||
if(prod) P = product::direct_exp(P);
|
||||
P = direct_exp(lp_iapply(P), 100);
|
||||
|
||||
hyperpoint H = sphereflip * tC0(U);
|
||||
transmatrix Centered = sphereflip * rgpushxto0(H);
|
||||
@ -113,12 +112,11 @@ EX void remission() {
|
||||
}
|
||||
|
||||
EX hyperpoint move_destination_vec(int d) {
|
||||
hyperpoint Forward = prod ? forward_dir(.5) : tC0(pushone());
|
||||
if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
|
||||
if(WDIM == 2) return spin(-d * M_PI/4) * smalltangent();
|
||||
// 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) * Forward;
|
||||
else return cspin(0, 2, d * M_PI/4) * Forward;
|
||||
else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * smalltangent();
|
||||
else return cspin(0, 2, d * M_PI/4) * smalltangent();
|
||||
}
|
||||
|
||||
EX void movepckeydir(int d) {
|
||||
@ -292,31 +290,28 @@ transmatrix zforward_push(ld z) {
|
||||
}
|
||||
|
||||
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), LPe, View), didsomething = true, playermoved = false;
|
||||
if(sym == PSEUDOKEY_WHEELDOWN) View = solmul(cpush(2, 0.05*shiftmul), LPe, View), didsomething = true, playermoved = false;
|
||||
if(sym == PSEUDOKEY_WHEELUP) shift_view(ztangent(-0.05*shiftmul)), didsomething = true, playermoved = false;
|
||||
if(sym == PSEUDOKEY_WHEELDOWN) shift_view(ztangent(0.05*shiftmul)), 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(zforward_push(-0.2*shiftmul), LPe, View), didsomething = true, playermoved = false;
|
||||
shift_view(ztangent(-0.2*shiftmul)), didsomething = true, playermoved = false;
|
||||
}
|
||||
if(sym == SDLK_HOME && GDIM == 3) {
|
||||
View = solmul(zforward_push(+0.2*shiftmul), LPe, View), didsomething = true, playermoved = false;
|
||||
shift_view(ztangent(+0.2*shiftmul)), didsomething = true, playermoved = false;
|
||||
}
|
||||
if(sym == SDLK_RIGHT) {
|
||||
if(history::on)
|
||||
history::lvspeed += 0.1 * shiftmul;
|
||||
else if(GDIM == 3)
|
||||
LPV = cspin(0, 2, -0.2*shiftmul) * LPV, didsomething = true;
|
||||
rotate_view(cspin(0, 2, -0.2*shiftmul)), didsomething = true;
|
||||
else
|
||||
View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
||||
}
|
||||
@ -324,7 +319,7 @@ EX void handlePanning(int sym, int uni) {
|
||||
if(history::on)
|
||||
history::lvspeed -= 0.1 * shiftmul;
|
||||
else if(GDIM == 3)
|
||||
LPV = cspin(0, 2, 0.2*shiftmul) * LPV, didsomething = true;
|
||||
rotate_view(cspin(0, 2, 0.2*shiftmul)), didsomething = true;
|
||||
else
|
||||
View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
||||
}
|
||||
@ -332,7 +327,7 @@ EX void handlePanning(int sym, int uni) {
|
||||
if(history::on)
|
||||
history::lvspeed += 0.1 * shiftmul;
|
||||
else if(GDIM == 3)
|
||||
LPV = cspin(1, 2, 0.2*shiftmul) * LPV, didsomething = true;
|
||||
rotate_view(cspin(1, 2, 0.2*shiftmul)), didsomething = true;
|
||||
else
|
||||
View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
||||
}
|
||||
@ -340,7 +335,7 @@ EX void handlePanning(int sym, int uni) {
|
||||
if(history::on)
|
||||
history::lvspeed -= 0.1 * shiftmul;
|
||||
else if(GDIM == 3)
|
||||
LPV = cspin(1, 2, -0.2*shiftmul) * LPV, didsomething = true;
|
||||
rotate_view(cspin(1, 2, -0.2*shiftmul)), didsomething = true;
|
||||
else
|
||||
View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
||||
}
|
||||
@ -349,13 +344,13 @@ EX void handlePanning(int sym, int uni) {
|
||||
if(history::on)
|
||||
models::rotation++;
|
||||
else
|
||||
LPV = spin(M_PI/cgi.S21/2*shiftmul) * LPV, didsomething = true;
|
||||
rotate_view(spin(M_PI/cgi.S21/2*shiftmul)), didsomething = true;
|
||||
}
|
||||
if(sym == SDLK_PAGEDOWN) {
|
||||
if(history::on)
|
||||
models::rotation++;
|
||||
else
|
||||
LPV = spin(-M_PI/cgi.S21/2*shiftmul) * LPV, didsomething = true;
|
||||
rotate_view(spin(-M_PI/cgi.S21/2*shiftmul)), didsomething = true;
|
||||
}
|
||||
|
||||
if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN)
|
||||
@ -683,8 +678,7 @@ EX void mainloopiter() {
|
||||
|
||||
if(GDIM == 3 && !shmup::on && !rug::rugged) {
|
||||
#if CAP_MOUSEGRAB
|
||||
auto &LPV = prod ? nisot::local_perspective : View;
|
||||
LPV = cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y) * LPV;
|
||||
rotate_view(cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y));
|
||||
mouseaim_x = mouseaim_y = 0;
|
||||
#endif
|
||||
}
|
||||
|
15
graph.cpp
15
graph.cpp
@ -756,7 +756,7 @@ pair<bool, hyperpoint> makeradar(hyperpoint h) {
|
||||
ld d = hdist0(h);
|
||||
|
||||
if(sol && nisot::geodesic_movement) {
|
||||
h = nisot::inverse_exp(h, nisot::iLazy);
|
||||
h = inverse_exp(h, iLazy);
|
||||
ld r = hypot_d(3, h);
|
||||
if(r < 1) h = h * (atanh(r) / r);
|
||||
else return {false, h};
|
||||
@ -3270,7 +3270,7 @@ void drawMovementArrows(cell *c, transmatrix V) {
|
||||
|
||||
for(int d=0; d<8; d++) {
|
||||
|
||||
movedir md = vectodir(spin(-d * M_PI/4) * tC0(pushone()));
|
||||
movedir md = vectodir(spin(-d * M_PI/4) * smalltangent());
|
||||
int u = md.d;
|
||||
cellwalker xc = cwt + u + wstep;
|
||||
if(xc.at == c) {
|
||||
@ -5100,7 +5100,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
hyperpoint H = tC0(V);
|
||||
if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ;
|
||||
else {
|
||||
hyperpoint H2 = nisot::inverse_exp(H, nisot::iLazy);
|
||||
hyperpoint H2 = inverse_exp(H, iLazy);
|
||||
for(hyperpoint& cpoint: clipping_planes) if((H2|cpoint) < -.2) return;
|
||||
}
|
||||
noclipped++;
|
||||
@ -5109,7 +5109,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
hyperpoint H = tC0(V);
|
||||
if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ;
|
||||
else {
|
||||
hyperpoint H2 = nisot::inverse_exp(H, nisot::iLazy);
|
||||
hyperpoint H2 = inverse_exp(H, iLazy);
|
||||
for(hyperpoint& cpoint: clipping_planes) if((H2|cpoint) < -2) return;
|
||||
}
|
||||
noclipped++;
|
||||
@ -7209,7 +7209,7 @@ EX void make_actual_view() {
|
||||
if(max) {
|
||||
transmatrix Start = inverse(actualV(viewctr, actual_view_transform * View));
|
||||
ld d = wall_radar(viewcenter(), Start, nisot::local_perspective, max);
|
||||
actual_view_transform = solmul(zpush(d), nisot::local_perspective, actual_view_transform * View) * inverse(View);
|
||||
actual_view_transform = get_shift_view_of(ztangent(d), actual_view_transform * View) * inverse(View);
|
||||
}
|
||||
camera_level = asin_auto(tC0(inverse(actual_view_transform * View))[2]);
|
||||
}
|
||||
@ -7246,10 +7246,7 @@ EX void precise_mouseover() {
|
||||
if(WDIM == 3) {
|
||||
mouseover2 = mouseover = viewcenter();
|
||||
ld best = HUGE_VAL;
|
||||
hyperpoint h =
|
||||
prod ? product::direct_exp( inverse(nisot::local_perspective) * zforward_dir(1) ) :
|
||||
|
||||
nisot::local_perspective_used() ? inverse(nisot::local_perspective) * zpush0(1) : zpush0(1);
|
||||
hyperpoint h = direct_exp(lp_iapply(ztangent(1)), 100);
|
||||
forCellEx(c1, mouseover2) {
|
||||
ld dist = hdist(tC0(ggmatrix(c1)), h);
|
||||
if(dist < best) mouseover = c1, best = dist;
|
||||
|
@ -81,6 +81,8 @@ struct hyperpoint : array<ld, MAXMDIM> {
|
||||
inline friend hyperpoint operator + (hyperpoint h, hyperpoint h2) { return h += h2; }
|
||||
inline friend hyperpoint operator - (hyperpoint h, hyperpoint h2) { return h -= h2; }
|
||||
|
||||
inline friend hyperpoint operator - (hyperpoint h) { return h * -1; }
|
||||
|
||||
// cross product
|
||||
inline friend hyperpoint operator ^ (hyperpoint h1, hyperpoint h2) {
|
||||
return hyperpoint(
|
||||
@ -929,8 +931,6 @@ EX transmatrix mzscale(const transmatrix& t, double fac) {
|
||||
return res;
|
||||
}
|
||||
|
||||
EX transmatrix pushone() { return xpush(sphere?.5 : 1); }
|
||||
|
||||
EX hyperpoint mid3(hyperpoint h1, hyperpoint h2, hyperpoint h3) {
|
||||
return mid(h1+h2+h3, h1+h2+h3);
|
||||
}
|
||||
@ -978,18 +978,13 @@ 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 LPe, const transmatrix V) {
|
||||
if(nonisotropic || prod) return nisot::transport_view(T, LPe, V);
|
||||
else return T * V;
|
||||
}
|
||||
|
||||
EX transmatrix solmul_pt(const transmatrix Position, const transmatrix T) {
|
||||
if(nonisotropic) return nisot::parallel_transport(Position, Id, T);
|
||||
if(nonisotropic) return nisot::parallel_transport(Position, Id, tC0(T));
|
||||
else return Position * T;
|
||||
}
|
||||
|
||||
EX transmatrix solmul_pt(const transmatrix Position, const transmatrix LPe, const transmatrix T) {
|
||||
if(nonisotropic || prod) return nisot::parallel_transport(Position, LPe, T);
|
||||
if(nonisotropic || prod) return nisot::parallel_transport(Position, LPe, tC0(T));
|
||||
else return Position * T;
|
||||
}
|
||||
|
||||
@ -1065,4 +1060,64 @@ inline hyperpoint tC0(const transmatrix &T) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/** tangent vector in the given direction */
|
||||
EX hyperpoint ctangent(int c, ld x) { return point3(c==0?x:0, c==1?x:0, c==2?x:0); }
|
||||
|
||||
/** tangent vector in direction X */
|
||||
EX hyperpoint xtangent(ld x) { return ctangent(0, x); }
|
||||
|
||||
/** tangent vector in direction Y */
|
||||
EX hyperpoint ztangent(ld z) { return ctangent(2, z); }
|
||||
|
||||
/** change the length of the targent vector */
|
||||
EX hyperpoint tangent_length(hyperpoint dir, ld length) {
|
||||
ld r = hypot_d(GDIM, dir);
|
||||
if(!r) return dir;
|
||||
return dir * (length / r);
|
||||
}
|
||||
|
||||
/** exponential function: follow the geodesic given by v */
|
||||
EX hyperpoint direct_exp(hyperpoint v, int steps) {
|
||||
if(sol) return nisot::numerical_exp(v, steps);
|
||||
if(nil) return nilv::formula_exp(v);
|
||||
if(sl2) return slr::formula_exp(v);
|
||||
if(prod) return product::direct_exp(v);
|
||||
ld d = hypot_d(GDIM, v);
|
||||
if(d > 0) for(int i=0; i<GDIM; i++) v[i] = v[i] * sin_auto(d) / d;
|
||||
v[3] = cos_auto(d);
|
||||
return v;
|
||||
}
|
||||
|
||||
#if HDR
|
||||
enum iePrecision { iLazy, iTable };
|
||||
#endif
|
||||
|
||||
/** inverse exponential function \see hr::direct_exp */
|
||||
EX hyperpoint inverse_exp(const hyperpoint h, iePrecision p, bool just_direction IS(true)) {
|
||||
if(sol) return solv::get_inverse_exp(h, p == iLazy, just_direction);
|
||||
if(nil) return nilv::get_inverse_exp(h, p == iLazy ? 5 : 20);
|
||||
if(sl2) return slr::get_inverse_exp(h);
|
||||
if(prod) return product::inverse_exp(h);
|
||||
ld d = acos_auto_clamp(h[GDIM]);
|
||||
hyperpoint v;
|
||||
if(d && sin_auto(d)) for(int i=0; i<GDIM; i++) v[i] = h[i] * d / sin_auto(d);
|
||||
v[3] = 0;
|
||||
return v;
|
||||
}
|
||||
|
||||
EX ld geo_dist(const hyperpoint h1, const hyperpoint h2, iePrecision p) {
|
||||
if(!nonisotropic) return hdist(h1, h2);
|
||||
return hypot_d(3, inverse_exp(inverse(nisot::translate(h1)) * h2, p, false));
|
||||
}
|
||||
|
||||
hyperpoint lp_iapply(const hyperpoint h) {
|
||||
return nisot::local_perspective_used() ? inverse(nisot::local_perspective) * h : h;
|
||||
}
|
||||
|
||||
hyperpoint lp_apply(const hyperpoint h) {
|
||||
return nisot::local_perspective_used() ? nisot::local_perspective * h : h;
|
||||
}
|
||||
|
||||
EX hyperpoint smalltangent() { return xtangent((sphere || hybri) ?.5 : 1); }
|
||||
|
||||
}
|
||||
|
85
hypgraph.cpp
85
hypgraph.cpp
@ -320,7 +320,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
case mdPerspective: {
|
||||
ld ratio = vid.xres / current_display->tanfov / current_display->radius / 2;
|
||||
if(prod) H = product::inverse_exp(H);
|
||||
if(nisot::local_perspective_used()) H = nisot::local_perspective * H;
|
||||
H = lp_apply(H);
|
||||
if(H[2] == 0) { ret[0] = 1e6; ret[1] = 1e6; ret[2] = 1; return; }
|
||||
ret[0] = H[0]/H[2] * ratio;
|
||||
ret[1] = H[1]/H[2] * ratio;
|
||||
@ -329,8 +329,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
}
|
||||
|
||||
case mdGeodesic: {
|
||||
auto S = nisot::inverse_exp(H, nisot::iTable);
|
||||
if(nisot::local_perspective_used()) S = nisot::local_perspective * S;
|
||||
auto S = lp_apply(inverse_exp(H, iTable));
|
||||
ld ratio = vid.xres / current_display->tanfov / current_display->radius / 2;
|
||||
ret[0] = S[0]/S[2] * ratio;
|
||||
ret[1] = S[1]/S[2] * ratio;
|
||||
@ -711,9 +710,8 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
|
||||
case mdEquidistant: case mdEquiarea: case mdEquivolume: {
|
||||
if(nonisotropic) {
|
||||
H = nisot::inverse_exp(H, nisot::iTable, false);
|
||||
if(nisot::local_perspective_used()) H = nisot::local_perspective * H;
|
||||
ret = H; ret[3] = 1;
|
||||
ret = lp_apply(inverse_exp(H, iTable, false));
|
||||
ret[3] = 1;
|
||||
break;
|
||||
}
|
||||
ld zlev = find_zlev(H);
|
||||
@ -939,9 +937,9 @@ EX transmatrix actualV(const heptspin& hs, const transmatrix& V) {
|
||||
EX bool point_behind(hyperpoint h) {
|
||||
if(sphere) return false;
|
||||
if(!in_perspective()) return false;
|
||||
if(pmodel == mdGeodesic) h = nisot::inverse_exp(h, nisot::iLazy);
|
||||
if(pmodel == mdGeodesic) h = inverse_exp(h, iLazy);
|
||||
if(pmodel == mdPerspective && prod) h = product::inverse_exp(h);
|
||||
if(nisot::local_perspective_used()) h = nisot::local_perspective * h;
|
||||
h = lp_apply(h);
|
||||
return h[2] < 1e-8;
|
||||
}
|
||||
|
||||
@ -1238,7 +1236,6 @@ EX transmatrix eumovedir(int d) {
|
||||
|
||||
EX void spinEdge(ld aspd) {
|
||||
ld downspin = 0;
|
||||
auto& LPV = prod ? nisot::local_perspective : View;
|
||||
if(dual::state == 2 && dual::currently_loaded != dual::main_side) {
|
||||
transmatrix our = dual::get_orientation();
|
||||
transmatrix their = dual::player_orientation[dual::main_side];
|
||||
@ -1249,7 +1246,7 @@ EX void spinEdge(ld aspd) {
|
||||
hyperpoint H = T * xpush0(1);
|
||||
downspin = -atan2(H[1], H[0]);
|
||||
}
|
||||
else LPV = their * inverse(our) * LPV;
|
||||
else rotate_view(their * inverse(our));
|
||||
}
|
||||
else if(playerfound && vid.fixed_facing) {
|
||||
hyperpoint H = gpushxto0(playerV * C0) * playerV * xpush0(5);
|
||||
@ -1262,15 +1259,16 @@ EX void spinEdge(ld aspd) {
|
||||
}
|
||||
else if((WDIM == 2 || prod) && GDIM == 3 && vid.fixed_yz && !CAP_ORIENTATION) {
|
||||
aspd = 999999;
|
||||
auto& vo = get_view_orientation();
|
||||
if(straightDownSeek) {
|
||||
auto sdp = straightDownPoint;
|
||||
if(prod) sdp = LPV * product::inverse_exp(sdp);
|
||||
if(prod) sdp = vo * product::inverse_exp(sdp);
|
||||
if(sdp[0])
|
||||
downspin = models::rotation * degree - atan2(sdp[0], sdp[1]);
|
||||
}
|
||||
else {
|
||||
if(LPV[0][2])
|
||||
downspin = -atan2(LPV[0][2], LPV[1][2]);
|
||||
if(vo[0][2])
|
||||
downspin = -atan2(vo[0][2], vo[1][2]);
|
||||
}
|
||||
}
|
||||
else if(straightDownSeek) {
|
||||
@ -1283,7 +1281,7 @@ EX void spinEdge(ld aspd) {
|
||||
}
|
||||
if(downspin > aspd) downspin = aspd;
|
||||
if(downspin < -aspd) downspin = -aspd;
|
||||
LPV = spin(downspin) * LPV;
|
||||
rotate_view(spin(downspin));
|
||||
}
|
||||
|
||||
EX void centerpc(ld aspd) {
|
||||
@ -1365,11 +1363,10 @@ EX void centerpc(ld aspd) {
|
||||
aspd *= sqrt(R*R - d.first * d.first) / R;
|
||||
}
|
||||
|
||||
if(R < aspd) {
|
||||
View = solmul(gpushxto0(H), Id, View);
|
||||
}
|
||||
if(R < aspd)
|
||||
shift_view_to(H);
|
||||
else
|
||||
View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), Id, View);
|
||||
shift_view_towards(H, aspd);
|
||||
|
||||
fixmatrix(View);
|
||||
spinEdge(aspd);
|
||||
@ -1991,7 +1988,7 @@ EX bool do_draw(cell *c, const transmatrix& T) {
|
||||
if(WDIM == 3) {
|
||||
if(cells_drawn > vid.cells_drawn_limit) return false;
|
||||
if(nil && pmodel == mdGeodesic) {
|
||||
ld dist = hdist0(nisot::inverse_exp(tC0(T), nisot::iLazy));
|
||||
ld dist = hypot_d(3, inverse_exp(tC0(T), iLazy));
|
||||
if(dist > sightranges[geometry] + (vid.sloppy_3d ? 0 : 0.9)) return false;
|
||||
if(dist <= extra_generation_distance && !limited_generation(c)) return false;
|
||||
}
|
||||
@ -2063,4 +2060,54 @@ EX int cone_side(const hyperpoint H) {
|
||||
return (ret1[1] - ret0[1]) * (ret2[0] - ret0[0]) < (ret2[1] - ret0[1]) * (ret1[0] - ret0[0]) ? 1 : -1;
|
||||
}
|
||||
|
||||
/** get the current orientation of the view */
|
||||
EX transmatrix& get_view_orientation() {
|
||||
return prod ? nisot::local_perspective : View;
|
||||
}
|
||||
|
||||
/** rotate the view using the given rotation matrix */
|
||||
EX void rotate_view(transmatrix T) {
|
||||
transmatrix& which = get_view_orientation();
|
||||
which = T * which;
|
||||
}
|
||||
|
||||
/** shift the view according to the given tangent vector */
|
||||
EX transmatrix get_shift_view_of(const hyperpoint H, const transmatrix V) {
|
||||
if(prod) {
|
||||
hyperpoint h = product::direct_exp(inverse(nisot::local_perspective) * H);
|
||||
return rgpushxto0(h) * V;
|
||||
}
|
||||
else if(!nonisotropic) {
|
||||
return gpushxto0(direct_exp(H, 100)) * V;
|
||||
}
|
||||
else if(!nisot::geodesic_movement) {
|
||||
transmatrix IV = inverse(V);
|
||||
nisot::fixmatrix(IV);
|
||||
const transmatrix V1 = inverse(IV);
|
||||
return V1 * eupush(IV * eupush(H) * V1 * C0);
|
||||
}
|
||||
else {
|
||||
return inverse(nisot::parallel_transport(inverse(V), Id, -H));
|
||||
}
|
||||
}
|
||||
|
||||
/** shift the view according to the given tangent vector */
|
||||
EX void shift_view(hyperpoint H) {
|
||||
View = get_shift_view_of(H, View);
|
||||
}
|
||||
|
||||
EX void shift_view_to(hyperpoint H) {
|
||||
if(!nonisotropic) View = gpushxto0(H) * View;
|
||||
else shift_view(-inverse_exp(H, iTable, false));
|
||||
}
|
||||
|
||||
EX void shift_view_towards(hyperpoint H, ld l) {
|
||||
if(!nonisotropic && !prod)
|
||||
View = rspintox(H) * xpush(-l) * spintox(H) * View;
|
||||
else {
|
||||
hyperpoint ie = nisot::geodesic_movement ? inverse_exp(H, iTable, false) : H-C0;
|
||||
shift_view(tangent_length(ie, -l));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1114,9 +1114,7 @@ namespace mapeditor {
|
||||
unsigned gridcolor = 0xC0C0C040;
|
||||
|
||||
hyperpoint in_front_dist(ld d) {
|
||||
hyperpoint h = prod ? product::direct_exp( inverse(nisot::local_perspective) * zforward_dir(d) ) : zpush0(d);
|
||||
if(nonisotropic && nisot::geodesic_movement) h = nisot::get_exp(inverse(nisot::local_perspective) * h, 100);
|
||||
return h;
|
||||
return direct_exp(lp_iapply(ztangent(d)), 100);
|
||||
}
|
||||
|
||||
hyperpoint find_mouseh3() {
|
||||
@ -1131,7 +1129,7 @@ namespace mapeditor {
|
||||
ld d1 = front_edit;
|
||||
hyperpoint h1 = in_front_dist(d);
|
||||
if(front_config == eFront::sphere_center)
|
||||
d1 = nisot::geo_dist(drawtrans * C0, h1, nisot::iTable);
|
||||
d1 = geo_dist(drawtrans * C0, h1, iTable);
|
||||
if(front_config == eFront::equidistants) {
|
||||
hyperpoint h = idt * in_front_dist(d);
|
||||
d1 = asin_auto(h[2]);
|
||||
@ -1174,9 +1172,7 @@ namespace mapeditor {
|
||||
}
|
||||
if(front_config == eFront::sphere_center) for(int i=0; i<4; i+=2) {
|
||||
auto pt = [&] (ld a, ld b) {
|
||||
hyperpoint h = dir_to_point(spin(a*degree) * cspin(0, 2, b*degree) * forward_dir(front_edit));
|
||||
if(nonisotropic && nisot::geodesic_movement) return d2 * nisot::get_exp(h, 100);
|
||||
return d2 * h;
|
||||
return d2 * direct_exp(spin(a*degree) * cspin(0, 2, b*degree) * xtangent(front_edit), 100);
|
||||
};
|
||||
for(int ai=0; ai<parallels; ai++) {
|
||||
ld a = ai * 360 / parallels;
|
||||
@ -1197,7 +1193,7 @@ namespace mapeditor {
|
||||
for(int i=0; i<4; i+=2) {
|
||||
for(int u=2; u<=20; u++) {
|
||||
PRING(d) {
|
||||
curvepoint(d2 * T * xspinpush(M_PI*d/cgi.S42, u/20.) * zpush(front_edit) * C0);
|
||||
curvepoint(d2 * T * xspinpush(M_PI*d/cgi.S42, u/20.) * zpush0(front_edit));
|
||||
}
|
||||
queuecurve(cols[i + (u%5 != 0)], 0, i < 2 ? PPR::LINE : PPR::SUPERLINE);
|
||||
}
|
||||
@ -1454,9 +1450,8 @@ namespace mapeditor {
|
||||
displayfr(vid.xres-8, vid.yres-8-fs*5, 2, vid.fsize, XLAT("z: %1", fts(mh[2],4)), 0xC0C0C0, 16);
|
||||
if(MDIM == 4)
|
||||
displayfr(vid.xres-8, vid.yres-8-fs*4, 2, vid.fsize, XLAT("w: %1", fts(mh[3],4)), 0xC0C0C0, 16);
|
||||
if(prod) mh = product::inverse_exp(mh);
|
||||
else if(nonisotropic) mh = nisot::inverse_exp(mh, nisot::iTable, false);
|
||||
displayfr(vid.xres-8, vid.yres-8-fs*3, 2, vid.fsize, XLAT("r: %1", fts(prod ? hypot_d(3, mh) : hdist0(mh),4)), 0xC0C0C0, 16);
|
||||
mh = inverse_exp(mh, iTable, false);
|
||||
displayfr(vid.xres-8, vid.yres-8-fs*3, 2, vid.fsize, XLAT("r: %1", fts(hypot_d(3, mh),4)), 0xC0C0C0, 16);
|
||||
if(GDIM == 3) {
|
||||
displayfr(vid.xres-8, vid.yres-8-fs, 2, vid.fsize, XLAT("ϕ: %1°", fts(-atan2(mh[2], hypot_d(2, mh)) / degree,4)), 0xC0C0C0, 16);
|
||||
displayfr(vid.xres-8, vid.yres-8-fs*2, 2, vid.fsize, XLAT("λ: %1°", fts(-atan2(mh[1], mh[0]) / degree,4)), 0xC0C0C0, 16);
|
||||
|
@ -80,7 +80,7 @@ EX namespace solv {
|
||||
return 0.5 - atan((0.5-x) / y) / M_PI;
|
||||
}
|
||||
|
||||
hyperpoint get_inverse_exp(hyperpoint h, bool lazy, bool just_direction) {
|
||||
EX hyperpoint get_inverse_exp(hyperpoint h, bool lazy, bool just_direction) {
|
||||
load_table();
|
||||
|
||||
ld ix = h[0] >= 0. ? x_to_ix(h[0]) : x_to_ix(-h[0]);
|
||||
@ -1089,23 +1089,6 @@ EX namespace nisot {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if HDR
|
||||
enum iePrecision { iLazy, iTable };
|
||||
#endif
|
||||
|
||||
EX hyperpoint inverse_exp(const hyperpoint h, iePrecision p, bool just_direction IS(true)) {
|
||||
if(sol) return solv::get_inverse_exp(h, p == iLazy, just_direction);
|
||||
if(nil) return nilv::get_inverse_exp(h, p == iLazy ? 5 : 20);
|
||||
if(sl2) return slr::get_inverse_exp(h);
|
||||
if(prod) return product::inverse_exp(h);
|
||||
return point3(h[0], h[1], h[2]);
|
||||
}
|
||||
|
||||
EX ld geo_dist(const hyperpoint h1, const hyperpoint h2, iePrecision p) {
|
||||
if(!nonisotropic) return hdist(h1, h2);
|
||||
return hypot_d(3, inverse_exp(inverse(translate(h1)) * h2, p, false));
|
||||
}
|
||||
|
||||
EX void geodesic_step(hyperpoint& at, hyperpoint& velocity) {
|
||||
auto acc = christoffel(at, velocity, velocity);
|
||||
|
||||
@ -1119,7 +1102,7 @@ EX namespace nisot {
|
||||
velocity = velocity + acc;
|
||||
}
|
||||
|
||||
EX hyperpoint direct_exp(hyperpoint v, int steps) {
|
||||
EX hyperpoint numerical_exp(hyperpoint v, int steps) {
|
||||
hyperpoint at = point31(0, 0, 0);
|
||||
v /= steps;
|
||||
v[3] = 0;
|
||||
@ -1127,17 +1110,8 @@ EX namespace nisot {
|
||||
return at;
|
||||
}
|
||||
|
||||
EX hyperpoint get_exp(hyperpoint v, int steps) {
|
||||
if(sol) return direct_exp(v, steps);
|
||||
if(nil) return nilv::formula_exp(v);
|
||||
if(sl2) return slr::formula_exp(v);
|
||||
if(prod) return product::direct_exp(v);
|
||||
return v;
|
||||
}
|
||||
EX transmatrix parallel_transport_bare(transmatrix Pos, hyperpoint h) {
|
||||
|
||||
EX transmatrix parallel_transport_bare(transmatrix Pos, transmatrix T) {
|
||||
|
||||
hyperpoint h = tC0(T);
|
||||
h[3] = 0;
|
||||
|
||||
auto tPos = transpose(Pos);
|
||||
@ -1180,29 +1154,15 @@ EX namespace nisot {
|
||||
T = push * gtl;
|
||||
}
|
||||
|
||||
EX transmatrix parallel_transport(const transmatrix Position, const transmatrix LPe, const transmatrix T) {
|
||||
EX transmatrix parallel_transport(const transmatrix Position, const transmatrix LPe, hyperpoint h) {
|
||||
if(prod) {
|
||||
hyperpoint h = product::direct_exp(inverse(LPe) * product::inverse_exp(tC0(T)));
|
||||
hyperpoint h = product::direct_exp(inverse(LPe) * product::inverse_exp(h));
|
||||
return Position * rgpushxto0(h);
|
||||
}
|
||||
auto P = Position;
|
||||
nisot::fixmatrix(P);
|
||||
if(!geodesic_movement) return inverse(eupush(Position * inverse(T) * inverse(Position) * C0)) * Position;
|
||||
return parallel_transport_bare(P, T);
|
||||
}
|
||||
|
||||
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);
|
||||
const transmatrix V1 = inverse(IV);
|
||||
return V1 * eupush(IV * T * V1 * C0);
|
||||
}
|
||||
return inverse(parallel_transport(inverse(V), Id, inverse(T)));
|
||||
if(!geodesic_movement) return inverse(eupush(Position * translate(-h) * inverse(Position) * C0)) * Position;
|
||||
return parallel_transport_bare(P, h);
|
||||
}
|
||||
|
||||
EX transmatrix spin_towards(const transmatrix Position, const hyperpoint goal) {
|
||||
|
@ -590,8 +590,6 @@ EX void apply() {
|
||||
int t = ticks - lastticks;
|
||||
lastticks = ticks;
|
||||
|
||||
auto& LPV = prod ? nisot::local_perspective : View;
|
||||
|
||||
switch(ma) {
|
||||
case maTranslation:
|
||||
if(history::on) {
|
||||
@ -611,8 +609,9 @@ EX void apply() {
|
||||
fullcenter(); View = spin(rand() % 1000) * View;
|
||||
}
|
||||
}
|
||||
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), nisot::local_perspective, View);
|
||||
shift_view(
|
||||
cspin(0, GDIM-1, movement_angle * degree) * spin(shift_angle * degree) * xtangent(cycle_length * t / period)
|
||||
);
|
||||
moved();
|
||||
if(clearup) {
|
||||
viewcenter()->wall = waNone;
|
||||
@ -623,21 +622,22 @@ EX void apply() {
|
||||
|
||||
case maRotation:
|
||||
if(GDIM == 3) {
|
||||
LPV = spin(-movement_angle * degree) * LPV;
|
||||
LPV = cspin(1, 2, normal_angle * degree) * LPV;
|
||||
rotate_view(spin(-movement_angle * degree));
|
||||
rotate_view(cspin(1, 2, normal_angle * degree));
|
||||
}
|
||||
LPV = spin(2 * M_PI * t / period) * LPV;
|
||||
rotate_view(spin(2 * M_PI * t / period));
|
||||
if(GDIM == 3) {
|
||||
LPV = cspin(2, 1, normal_angle * degree) * LPV;
|
||||
LPV = spin(movement_angle * degree) * LPV;
|
||||
rotate_view(cspin(2, 1, normal_angle * degree));
|
||||
rotate_view(spin(movement_angle * degree));
|
||||
}
|
||||
break;
|
||||
|
||||
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), nisot::local_perspective, View);
|
||||
shift_view(
|
||||
cspin(0, GDIM-1, movement_angle * degree) * spin(shift_angle * degree) * xtangent(cycle_length * t / period)
|
||||
);
|
||||
moved();
|
||||
LPV = cspin(0, GDIM-1, 2 * M_PI * t / period) * LPV;
|
||||
rotate_view(cspin(0, GDIM-1, 2 * M_PI * t / period));
|
||||
if(clearup) {
|
||||
viewcenter()->wall = waNone;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user