refactored all the operations on View

This commit is contained in:
Zeno Rogue 2019-08-24 18:14:38 +02:00
parent 65ce70cb2c
commit 96d7496043
8 changed files with 189 additions and 153 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, transmatrix T) {
EX transmatrix parallel_transport_bare(transmatrix Pos, hyperpoint h) {
hyperpoint h = tC0(T);
h[3] = 0;
auto tPos = transpose(Pos);
@ -1180,31 +1154,17 @@ 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);
if(!geodesic_movement) return inverse(eupush(Position * translate(-h) * inverse(Position) * C0)) * Position;
return parallel_transport_bare(P, h);
}
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)));
}
EX transmatrix spin_towards(const transmatrix Position, const hyperpoint goal) {
hyperpoint at = tC0(Position);

View File

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