mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 21:42:59 +00:00 
			
		
		
		
	refactored all the operations on View
This commit is contained in:
		| @@ -622,37 +622,25 @@ void geometry_information::animate_bird(hpcshape& orig, hpcshape_animated& anima | |||||||
|   // shift_shape(orig, BIRD); |   // 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) { | void geometry_information::slimetriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) { | ||||||
|   dynamicval<int> d(vid.texture_step, 8); |   dynamicval<int> d(vid.texture_step, 8); | ||||||
|   texture_order([&] (ld x, ld y) { |   texture_order([&] (ld x, ld y) { | ||||||
|     ld z = 1-x-y; |     ld z = 1-x-y; | ||||||
|     ld r = scalefactor * hcrossf7 * (0 + pow(max(x,max(y,z)), .3) * 0.8) * (hybri ? .5 : 1); |     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); |     hpcpush(h); | ||||||
|     });   |     });   | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void geometry_information::balltriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) { | void geometry_information::balltriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) { | ||||||
|   if(lev == 0) { |   if(lev == 0) { | ||||||
|     hpcpush(dir_to_point(a)); |     hpcpush(direct_exp(a, 10)); | ||||||
|     hpcpush(dir_to_point(b)); |     hpcpush(direct_exp(b, 10)); | ||||||
|     hpcpush(dir_to_point(c)); |     hpcpush(direct_exp(c, 10)); | ||||||
|     } |     } | ||||||
|   else { |   else { | ||||||
|     auto midpoint = [&] (hyperpoint h1, hyperpoint h2) { |     auto midpoint = [&] (hyperpoint h1, hyperpoint h2) { | ||||||
|       if(prod) return dir_setlength(h1+h2, rad); |       return tangent_length(h1+h2, rad); | ||||||
|       else return rspintox(mid(h1,h2)) * xpush0(rad); |  | ||||||
|       }; |       }; | ||||||
|     hyperpoint cx = midpoint(a, b); |     hyperpoint cx = midpoint(a, b); | ||||||
|     hyperpoint ax = midpoint(b, c); |     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) { | void geometry_information::make_ball(hpcshape& sh, ld rad, int lev) { | ||||||
|   bshape(sh, sh.prio); |   bshape(sh, sh.prio); | ||||||
|   sh.flags |= POLY_TRIANGLES; |   sh.flags |= POLY_TRIANGLES; | ||||||
|   hyperpoint tip = forward_dir(rad); |   hyperpoint tip = xtangent(rad); | ||||||
|   hyperpoint atip = forward_dir(-rad); |   hyperpoint atip = xtangent(-rad); | ||||||
|   ld z = 63.43 * degree; |   ld z = 63.43 * degree; | ||||||
|   for(int i=0; i<5; i++) { |   for(int i=0; i<5; i++) { | ||||||
|     hyperpoint a = cspin(1, 2, (72 * i   ) * degree) * spin(z) * tip; |     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")); |   DEBB(DF_POLY, ("slime")); | ||||||
|   bshape(shSlime, PPR::MONSTER_BODY); |   bshape(shSlime, PPR::MONSTER_BODY); | ||||||
|   hyperpoint tip = xpush0(1); |   hyperpoint tip = xtangent(1); | ||||||
|   hyperpoint atip = xpush0(-1); |   hyperpoint atip = xtangent(-1); | ||||||
|   ld z = 63.43 * degree; |   ld z = 63.43 * degree; | ||||||
|   for(int i=0; i<5; i++) { |   for(int i=0; i<5; i++) { | ||||||
|     auto a = cspin(1, 2, (72 * i   ) * degree) * spin(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) * forward_dir(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) * forward_dir(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) * forward_dir(1); |     auto d = cspin(1, 2, (72 * i-36) * degree) * spin(M_PI-z) * xtangent(1); | ||||||
|     slimetriangle(tip, a, b, 1, 0); |     slimetriangle(tip, a, b, 1, 0); | ||||||
|     slimetriangle(a, b, c, 1, 0); |     slimetriangle(a, b, c, 1, 0); | ||||||
|     slimetriangle(b, c, d, 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); |   transmatrix U = ggmatrix(cwt.at); | ||||||
|   if(GDIM == 3 && WDIM == 2)  U = radar_transform * U; |   if(GDIM == 3 && WDIM == 2)  U = radar_transform * U; | ||||||
|  |  | ||||||
|   if(nisot::local_perspective_used()) P = inverse(nisot::local_perspective) * P; |   P = direct_exp(lp_iapply(P), 100); | ||||||
|   if(prod) P = product::direct_exp(P); |  | ||||||
|  |  | ||||||
|   hyperpoint H = sphereflip * tC0(U); |   hyperpoint H = sphereflip * tC0(U); | ||||||
|   transmatrix Centered = sphereflip * rgpushxto0(H); |   transmatrix Centered = sphereflip * rgpushxto0(H); | ||||||
| @@ -113,12 +112,11 @@ EX void remission() { | |||||||
|  } |  } | ||||||
|  |  | ||||||
| EX hyperpoint move_destination_vec(int d) { | EX hyperpoint move_destination_vec(int d) { | ||||||
|   hyperpoint Forward = prod ? forward_dir(.5) : tC0(pushone()); |   if(WDIM == 2) return spin(-d * M_PI/4) * smalltangent(); | ||||||
|   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 && 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(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 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) * Forward; |   else return cspin(0, 2, d * M_PI/4) * smalltangent(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| EX void movepckeydir(int d) { | EX void movepckeydir(int d) { | ||||||
| @@ -292,31 +290,28 @@ transmatrix zforward_push(ld z) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| EX void handlePanning(int sym, int uni) { | EX void handlePanning(int sym, int uni) { | ||||||
|   auto& LPe = nisot::local_perspective; |  | ||||||
|   if(mousepan && dual::split([=] { handlePanning(sym, uni); })) return; |   if(mousepan && dual::split([=] { handlePanning(sym, uni); })) return; | ||||||
|   if(GDIM == 3) { |   if(GDIM == 3) { | ||||||
|     if(sym == PSEUDOKEY_WHEELUP) 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) View = solmul(cpush(2, 0.05*shiftmul), LPe, View), didsomething = true, playermoved = false; |     if(sym == PSEUDOKEY_WHEELDOWN) shift_view(ztangent(0.05*shiftmul)), didsomething = true, playermoved = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if(rug::rugged || smooth_scrolling) { |   if(rug::rugged || smooth_scrolling) { | ||||||
|     return; |     return; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|   auto& LPV = prod ? nisot::local_perspective : View; |  | ||||||
|    |  | ||||||
| #if !ISPANDORA | #if !ISPANDORA | ||||||
|   if(sym == SDLK_END && GDIM == 3) {  |   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) {  |   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(sym == SDLK_RIGHT) {  | ||||||
|     if(history::on) |     if(history::on) | ||||||
|       history::lvspeed += 0.1 * shiftmul; |       history::lvspeed += 0.1 * shiftmul; | ||||||
|     else if(GDIM == 3) |     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 |     else | ||||||
|       View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; |       View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; | ||||||
|     } |     } | ||||||
| @@ -324,7 +319,7 @@ EX void handlePanning(int sym, int uni) { | |||||||
|     if(history::on) |     if(history::on) | ||||||
|       history::lvspeed -= 0.1 * shiftmul; |       history::lvspeed -= 0.1 * shiftmul; | ||||||
|     else if(GDIM == 3) |     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 |     else | ||||||
|       View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; |       View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; | ||||||
|     } |     } | ||||||
| @@ -332,7 +327,7 @@ EX void handlePanning(int sym, int uni) { | |||||||
|     if(history::on) |     if(history::on) | ||||||
|       history::lvspeed += 0.1 * shiftmul; |       history::lvspeed += 0.1 * shiftmul; | ||||||
|     else if(GDIM == 3) |     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 |     else | ||||||
|       View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; |       View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; | ||||||
|     } |     } | ||||||
| @@ -340,7 +335,7 @@ EX void handlePanning(int sym, int uni) { | |||||||
|     if(history::on) |     if(history::on) | ||||||
|       history::lvspeed -= 0.1 * shiftmul; |       history::lvspeed -= 0.1 * shiftmul; | ||||||
|     else if(GDIM == 3) |     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 |     else | ||||||
|       View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; |       View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; | ||||||
|     } |     } | ||||||
| @@ -349,13 +344,13 @@ EX void handlePanning(int sym, int uni) { | |||||||
|     if(history::on) |     if(history::on) | ||||||
|       models::rotation++; |       models::rotation++; | ||||||
|     else |     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(sym == SDLK_PAGEDOWN) { | ||||||
|     if(history::on) |     if(history::on) | ||||||
|       models::rotation++; |       models::rotation++; | ||||||
|     else |     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)  |   if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN)  | ||||||
| @@ -683,8 +678,7 @@ EX void mainloopiter() { | |||||||
|    |    | ||||||
|   if(GDIM == 3 && !shmup::on && !rug::rugged) { |   if(GDIM == 3 && !shmup::on && !rug::rugged) { | ||||||
|     #if CAP_MOUSEGRAB |     #if CAP_MOUSEGRAB | ||||||
|     auto &LPV = prod ? nisot::local_perspective : View; |     rotate_view(cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y)); | ||||||
|     LPV = cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y) * LPV; |  | ||||||
|     mouseaim_x = mouseaim_y = 0; |     mouseaim_x = mouseaim_y = 0; | ||||||
|     #endif |     #endif | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								graph.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								graph.cpp
									
									
									
									
									
								
							| @@ -756,7 +756,7 @@ pair<bool, hyperpoint> makeradar(hyperpoint h) { | |||||||
|   ld d = hdist0(h); |   ld d = hdist0(h); | ||||||
|  |  | ||||||
|   if(sol && nisot::geodesic_movement) { |   if(sol && nisot::geodesic_movement) { | ||||||
|     h = nisot::inverse_exp(h, nisot::iLazy); |     h = inverse_exp(h, iLazy); | ||||||
|     ld r = hypot_d(3, h); |     ld r = hypot_d(3, h); | ||||||
|     if(r < 1) h = h * (atanh(r) / r); |     if(r < 1) h = h * (atanh(r) / r); | ||||||
|     else return {false, h}; |     else return {false, h}; | ||||||
| @@ -3270,7 +3270,7 @@ void drawMovementArrows(cell *c, transmatrix V) { | |||||||
|  |  | ||||||
|   for(int d=0; d<8; d++) { |   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; |     int u = md.d; | ||||||
|     cellwalker xc = cwt + u + wstep; |     cellwalker xc = cwt + u + wstep; | ||||||
|     if(xc.at == c) { |     if(xc.at == c) { | ||||||
| @@ -5100,7 +5100,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | |||||||
|     hyperpoint H = tC0(V); |     hyperpoint H = tC0(V); | ||||||
|     if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ; |     if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ; | ||||||
|     else { |     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; |       for(hyperpoint& cpoint: clipping_planes) if((H2|cpoint) < -.2) return; | ||||||
|       } |       } | ||||||
|     noclipped++; |     noclipped++; | ||||||
| @@ -5109,7 +5109,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | |||||||
|     hyperpoint H = tC0(V); |     hyperpoint H = tC0(V); | ||||||
|     if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ; |     if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ; | ||||||
|     else { |     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; |       for(hyperpoint& cpoint: clipping_planes) if((H2|cpoint) < -2) return; | ||||||
|       } |       } | ||||||
|     noclipped++; |     noclipped++; | ||||||
| @@ -7209,7 +7209,7 @@ EX void make_actual_view() { | |||||||
|     if(max) { |     if(max) { | ||||||
|       transmatrix Start = inverse(actualV(viewctr, actual_view_transform * View)); |       transmatrix Start = inverse(actualV(viewctr, actual_view_transform * View)); | ||||||
|       ld d = wall_radar(viewcenter(), Start, nisot::local_perspective, max); |       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]); |     camera_level = asin_auto(tC0(inverse(actual_view_transform * View))[2]); | ||||||
|     } |     } | ||||||
| @@ -7246,10 +7246,7 @@ EX void precise_mouseover() { | |||||||
|   if(WDIM == 3) {  |   if(WDIM == 3) {  | ||||||
|     mouseover2 = mouseover = viewcenter(); |     mouseover2 = mouseover = viewcenter(); | ||||||
|     ld best = HUGE_VAL; |     ld best = HUGE_VAL; | ||||||
|     hyperpoint h =  |     hyperpoint h = direct_exp(lp_iapply(ztangent(1)), 100); | ||||||
|       prod ? product::direct_exp( inverse(nisot::local_perspective) * zforward_dir(1) ) : |  | ||||||
|        |  | ||||||
|       nisot::local_perspective_used() ? inverse(nisot::local_perspective) * zpush0(1) : zpush0(1); |  | ||||||
|     forCellEx(c1, mouseover2) { |     forCellEx(c1, mouseover2) { | ||||||
|       ld dist = hdist(tC0(ggmatrix(c1)), h); |       ld dist = hdist(tC0(ggmatrix(c1)), h); | ||||||
|       if(dist < best) mouseover = c1, best = dist; |       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, 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   |   // cross product   | ||||||
|   inline friend hyperpoint operator ^ (hyperpoint h1, hyperpoint h2) { |   inline friend hyperpoint operator ^ (hyperpoint h1, hyperpoint h2) { | ||||||
|     return hyperpoint( |     return hyperpoint( | ||||||
| @@ -929,8 +931,6 @@ EX transmatrix mzscale(const transmatrix& t, double fac) { | |||||||
|   return res; |   return res; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| EX transmatrix pushone() { return xpush(sphere?.5 : 1); } |  | ||||||
|  |  | ||||||
| EX hyperpoint mid3(hyperpoint h1, hyperpoint h2, hyperpoint h3) { | EX hyperpoint mid3(hyperpoint h1, hyperpoint h2, hyperpoint h3) { | ||||||
|   return mid(h1+h2+h3, h1+h2+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); } | 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) { | 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; |   else return Position * T; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| EX transmatrix solmul_pt(const transmatrix Position, const transmatrix LPe, const transmatrix 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; |   else return Position * T; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1065,4 +1060,64 @@ inline hyperpoint tC0(const transmatrix &T) { | |||||||
|   } |   } | ||||||
| #endif | #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: { |     case mdPerspective: { | ||||||
|       ld ratio = vid.xres / current_display->tanfov / current_display->radius / 2; |       ld ratio = vid.xres / current_display->tanfov / current_display->radius / 2; | ||||||
|       if(prod) H = product::inverse_exp(H); |       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; } |       if(H[2] == 0) { ret[0] = 1e6; ret[1] = 1e6; ret[2] = 1; return; } | ||||||
|       ret[0] = H[0]/H[2] * ratio; |       ret[0] = H[0]/H[2] * ratio; | ||||||
|       ret[1] = H[1]/H[2] * ratio; |       ret[1] = H[1]/H[2] * ratio; | ||||||
| @@ -329,8 +329,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|     case mdGeodesic: { |     case mdGeodesic: { | ||||||
|       auto S = nisot::inverse_exp(H, nisot::iTable); |       auto S = lp_apply(inverse_exp(H, iTable)); | ||||||
|       if(nisot::local_perspective_used()) S = nisot::local_perspective * S; |  | ||||||
|       ld ratio = vid.xres / current_display->tanfov / current_display->radius / 2; |       ld ratio = vid.xres / current_display->tanfov / current_display->radius / 2; | ||||||
|       ret[0] = S[0]/S[2] * ratio; |       ret[0] = S[0]/S[2] * ratio; | ||||||
|       ret[1] = S[1]/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: { |     case mdEquidistant: case mdEquiarea: case mdEquivolume: { | ||||||
|       if(nonisotropic) { |       if(nonisotropic) { | ||||||
|         H = nisot::inverse_exp(H, nisot::iTable, false); |         ret = lp_apply(inverse_exp(H, iTable, false)); | ||||||
|         if(nisot::local_perspective_used()) H = nisot::local_perspective * H; |         ret[3] = 1; | ||||||
|         ret = H; ret[3] = 1; |  | ||||||
|         break; |         break; | ||||||
|         } |         } | ||||||
|       ld zlev = find_zlev(H); |       ld zlev = find_zlev(H); | ||||||
| @@ -939,9 +937,9 @@ EX transmatrix actualV(const heptspin& hs, const transmatrix& V) { | |||||||
| EX bool point_behind(hyperpoint h) { | EX bool point_behind(hyperpoint h) { | ||||||
|   if(sphere) return false; |   if(sphere) return false; | ||||||
|   if(!in_perspective()) 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(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; |   return h[2] < 1e-8; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1238,7 +1236,6 @@ EX transmatrix eumovedir(int d) { | |||||||
|  |  | ||||||
| EX void spinEdge(ld aspd) {  | EX void spinEdge(ld aspd) {  | ||||||
|   ld downspin = 0; |   ld downspin = 0; | ||||||
|   auto& LPV = prod ? nisot::local_perspective : View; |  | ||||||
|   if(dual::state == 2 && dual::currently_loaded != dual::main_side) { |   if(dual::state == 2 && dual::currently_loaded != dual::main_side) { | ||||||
|     transmatrix our   = dual::get_orientation(); |     transmatrix our   = dual::get_orientation(); | ||||||
|     transmatrix their = dual::player_orientation[dual::main_side]; |     transmatrix their = dual::player_orientation[dual::main_side]; | ||||||
| @@ -1249,7 +1246,7 @@ EX void spinEdge(ld aspd) { | |||||||
|       hyperpoint H = T * xpush0(1); |       hyperpoint H = T * xpush0(1); | ||||||
|       downspin = -atan2(H[1], H[0]); |       downspin = -atan2(H[1], H[0]); | ||||||
|       } |       } | ||||||
|     else LPV = their * inverse(our) * LPV; |     else rotate_view(their * inverse(our)); | ||||||
|     } |     } | ||||||
|   else if(playerfound && vid.fixed_facing) { |   else if(playerfound && vid.fixed_facing) { | ||||||
|     hyperpoint H = gpushxto0(playerV * C0) * playerV * xpush0(5); |     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) { |   else if((WDIM == 2 || prod) && GDIM == 3 && vid.fixed_yz && !CAP_ORIENTATION) { | ||||||
|     aspd = 999999; |     aspd = 999999; | ||||||
|  |     auto& vo = get_view_orientation(); | ||||||
|     if(straightDownSeek) { |     if(straightDownSeek) { | ||||||
|       auto sdp = straightDownPoint; |       auto sdp = straightDownPoint; | ||||||
|       if(prod) sdp = LPV * product::inverse_exp(sdp); |       if(prod) sdp = vo * product::inverse_exp(sdp); | ||||||
|       if(sdp[0]) |       if(sdp[0]) | ||||||
|         downspin = models::rotation * degree - atan2(sdp[0], sdp[1]); |         downspin = models::rotation * degree - atan2(sdp[0], sdp[1]); | ||||||
|       } |       } | ||||||
|     else { |     else { | ||||||
|       if(LPV[0][2])  |       if(vo[0][2])  | ||||||
|         downspin = -atan2(LPV[0][2], LPV[1][2]); |         downspin = -atan2(vo[0][2], vo[1][2]); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   else if(straightDownSeek) { |   else if(straightDownSeek) { | ||||||
| @@ -1283,7 +1281,7 @@ EX void spinEdge(ld aspd) { | |||||||
|     } |     } | ||||||
|   if(downspin >  aspd) downspin =  aspd; |   if(downspin >  aspd) downspin =  aspd; | ||||||
|   if(downspin < -aspd) downspin = -aspd; |   if(downspin < -aspd) downspin = -aspd; | ||||||
|   LPV = spin(downspin) * LPV; |   rotate_view(spin(downspin)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| EX void centerpc(ld aspd) {  | EX void centerpc(ld aspd) {  | ||||||
| @@ -1365,11 +1363,10 @@ EX void centerpc(ld aspd) { | |||||||
|       aspd *= sqrt(R*R - d.first * d.first) / R; |       aspd *= sqrt(R*R - d.first * d.first) / R; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     if(R < aspd) { |     if(R < aspd)  | ||||||
|       View = solmul(gpushxto0(H), Id, View); |       shift_view_to(H); | ||||||
|       } |  | ||||||
|     else  |     else  | ||||||
|       View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), Id, View); |       shift_view_towards(H, aspd); | ||||||
|        |        | ||||||
|     fixmatrix(View); |     fixmatrix(View); | ||||||
|     spinEdge(aspd); |     spinEdge(aspd); | ||||||
| @@ -1991,7 +1988,7 @@ EX bool do_draw(cell *c, const transmatrix& T) { | |||||||
|   if(WDIM == 3) { |   if(WDIM == 3) { | ||||||
|     if(cells_drawn > vid.cells_drawn_limit) return false; |     if(cells_drawn > vid.cells_drawn_limit) return false; | ||||||
|     if(nil && pmodel == mdGeodesic) { |     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 > sightranges[geometry] + (vid.sloppy_3d ? 0 : 0.9)) return false; | ||||||
|       if(dist <= extra_generation_distance && !limited_generation(c)) 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; |   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; |   unsigned gridcolor = 0xC0C0C040; | ||||||
|    |    | ||||||
|   hyperpoint in_front_dist(ld d) { |   hyperpoint in_front_dist(ld d) { | ||||||
|     hyperpoint h = prod ? product::direct_exp( inverse(nisot::local_perspective) * zforward_dir(d) ) : zpush0(d); |     return direct_exp(lp_iapply(ztangent(d)), 100); | ||||||
|     if(nonisotropic && nisot::geodesic_movement) h = nisot::get_exp(inverse(nisot::local_perspective) * h, 100); |  | ||||||
|     return h; |  | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   hyperpoint find_mouseh3() { |   hyperpoint find_mouseh3() { | ||||||
| @@ -1131,7 +1129,7 @@ namespace mapeditor { | |||||||
|       ld d1 = front_edit; |       ld d1 = front_edit; | ||||||
|       hyperpoint h1 = in_front_dist(d); |       hyperpoint h1 = in_front_dist(d); | ||||||
|       if(front_config == eFront::sphere_center)  |       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) { |       if(front_config == eFront::equidistants) { | ||||||
|         hyperpoint h = idt * in_front_dist(d); |         hyperpoint h = idt * in_front_dist(d); | ||||||
|         d1 = asin_auto(h[2]); |         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) { |       if(front_config == eFront::sphere_center) for(int i=0; i<4; i+=2) { | ||||||
|         auto pt = [&] (ld a, ld b) { |         auto pt = [&] (ld a, ld b) { | ||||||
|           hyperpoint h = dir_to_point(spin(a*degree) * cspin(0, 2, b*degree) * forward_dir(front_edit)); |           return d2 * direct_exp(spin(a*degree) * cspin(0, 2, b*degree) * xtangent(front_edit), 100); | ||||||
|           if(nonisotropic && nisot::geodesic_movement) return d2 * nisot::get_exp(h, 100); |  | ||||||
|           return d2 * h; |  | ||||||
|           }; |           }; | ||||||
|         for(int ai=0; ai<parallels; ai++) { |         for(int ai=0; ai<parallels; ai++) { | ||||||
|           ld a = ai * 360 / parallels; |           ld a = ai * 360 / parallels; | ||||||
| @@ -1197,7 +1193,7 @@ namespace mapeditor { | |||||||
|       for(int i=0; i<4; i+=2) { |       for(int i=0; i<4; i+=2) { | ||||||
|         for(int u=2; u<=20; u++) { |         for(int u=2; u<=20; u++) { | ||||||
|           PRING(d) { |           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); |           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); |       displayfr(vid.xres-8, vid.yres-8-fs*5, 2, vid.fsize, XLAT("z: %1", fts(mh[2],4)), 0xC0C0C0, 16); | ||||||
|       if(MDIM == 4) |       if(MDIM == 4) | ||||||
|         displayfr(vid.xres-8, vid.yres-8-fs*4, 2, vid.fsize, XLAT("w: %1", fts(mh[3],4)), 0xC0C0C0, 16); |         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); |       mh = inverse_exp(mh, iTable, false); | ||||||
|       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(hypot_d(3, mh),4)), 0xC0C0C0, 16); | ||||||
|       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); |  | ||||||
|       if(GDIM == 3) { |       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, 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); |         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; |     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(); |     load_table(); | ||||||
|      |      | ||||||
|     ld ix = h[0] >= 0. ? x_to_ix(h[0]) : x_to_ix(-h[0]); |     ld ix = h[0] >= 0. ? x_to_ix(h[0]) : x_to_ix(-h[0]); | ||||||
| @@ -1089,23 +1089,6 @@ EX namespace nisot { | |||||||
|     return true; |     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) { |   EX void geodesic_step(hyperpoint& at, hyperpoint& velocity) { | ||||||
|     auto acc = christoffel(at, velocity, velocity); |     auto acc = christoffel(at, velocity, velocity); | ||||||
|      |      | ||||||
| @@ -1119,7 +1102,7 @@ EX namespace nisot { | |||||||
|     velocity = velocity + acc; |     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); |     hyperpoint at = point31(0, 0, 0); | ||||||
|     v /= steps; |     v /= steps; | ||||||
|     v[3] = 0; |     v[3] = 0; | ||||||
| @@ -1127,17 +1110,8 @@ EX namespace nisot { | |||||||
|     return at; |     return at; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   EX hyperpoint get_exp(hyperpoint v, int steps) { |   EX transmatrix parallel_transport_bare(transmatrix Pos, hyperpoint h) { | ||||||
|     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) { |  | ||||||
|    |  | ||||||
|     hyperpoint h = tC0(T); |  | ||||||
|     h[3] = 0; |     h[3] = 0; | ||||||
|    |    | ||||||
|     auto tPos = transpose(Pos); |     auto tPos = transpose(Pos); | ||||||
| @@ -1180,29 +1154,15 @@ EX namespace nisot { | |||||||
|     T = push * gtl; |     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) { |     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); |       return Position * rgpushxto0(h); | ||||||
|       } |       } | ||||||
|     auto P = Position; |     auto P = Position; | ||||||
|     nisot::fixmatrix(P);   |     nisot::fixmatrix(P);   | ||||||
|     if(!geodesic_movement) return inverse(eupush(Position * inverse(T) * inverse(Position) * C0)) * Position; |     if(!geodesic_movement) return inverse(eupush(Position * translate(-h) * inverse(Position) * C0)) * Position; | ||||||
|     return parallel_transport_bare(P, T); |     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) { |   EX transmatrix spin_towards(const transmatrix Position, const hyperpoint goal) { | ||||||
|   | |||||||
| @@ -590,8 +590,6 @@ EX void apply() { | |||||||
|   int t = ticks - lastticks; |   int t = ticks - lastticks; | ||||||
|   lastticks = ticks; |   lastticks = ticks; | ||||||
|  |  | ||||||
|   auto& LPV = prod ? nisot::local_perspective : View; |  | ||||||
|  |  | ||||||
|   switch(ma) { |   switch(ma) { | ||||||
|     case maTranslation: |     case maTranslation: | ||||||
|       if(history::on) { |       if(history::on) { | ||||||
| @@ -611,8 +609,9 @@ EX void apply() { | |||||||
|             fullcenter(); View = spin(rand() % 1000) * View; |             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) *  |         shift_view( | ||||||
|           cspin(0, GDIM-1, -movement_angle * degree), nisot::local_perspective, View); |           cspin(0, GDIM-1, movement_angle * degree) * spin(shift_angle * degree) * xtangent(cycle_length * t / period) | ||||||
|  |           ); | ||||||
|         moved(); |         moved(); | ||||||
|         if(clearup) { |         if(clearup) { | ||||||
|           viewcenter()->wall = waNone; |           viewcenter()->wall = waNone; | ||||||
| @@ -623,21 +622,22 @@ EX void apply() { | |||||||
|  |  | ||||||
|     case maRotation: |     case maRotation: | ||||||
|       if(GDIM == 3) { |       if(GDIM == 3) { | ||||||
|         LPV = spin(-movement_angle * degree) * LPV; |         rotate_view(spin(-movement_angle * degree)); | ||||||
|         LPV = cspin(1, 2, normal_angle * degree) * LPV; |         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) { |       if(GDIM == 3) { | ||||||
|         LPV = cspin(2, 1, normal_angle * degree) * LPV; |         rotate_view(cspin(2, 1, normal_angle * degree)); | ||||||
|         LPV = spin(movement_angle * degree) * LPV; |         rotate_view(spin(movement_angle * degree)); | ||||||
|         } |         } | ||||||
|       break; |       break; | ||||||
|      |      | ||||||
|     case maTranslationRotation: |     case maTranslationRotation: | ||||||
|       View = solmul(cspin(0, GDIM-1, movement_angle * degree) * ypush(shift_angle * degree) * xpush(cycle_length * t / period) * ypush(-shift_angle * degree) *  |       shift_view( | ||||||
|         cspin(0, GDIM-1, -movement_angle * degree), nisot::local_perspective, View); |         cspin(0, GDIM-1, movement_angle * degree) * spin(shift_angle * degree) * xtangent(cycle_length * t / period) | ||||||
|  |         ); | ||||||
|       moved(); |       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) { |       if(clearup) { | ||||||
|         viewcenter()->wall = waNone; |         viewcenter()->wall = waNone; | ||||||
|         } |         } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue