mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-26 03:17:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			170 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "rogueviz.h"
 | |
| 
 | |
| // 'hyperbolic city' demo
 | |
| // download the model from https://sketchfab.com/3d-models/night-city-p2-82637933a7cb4fafadb0e2a79415c438 as rogueviz/models/emilejohansson_p2.obj
 | |
| 
 | |
| // see the results posted here:
 | |
| 
 | |
| // https://twitter.com/ZenoRogue/status/1375750351391981570
 | |
| // -hypcity -noplayer -geo 4x5 -gp 1 1 -unrectified -switch-fpp -canvas 303030 camera=0 depth=0 -sr 3 -PM 0 -alpha 1 -zoom .95
 | |
| 
 | |
| // https://twitter.com/ZenoRogue/status/1375748835046215682
 | |
| // -hypcity -noplayer -geo nil -canvas 303030 -back 44e4 -sight3 3
 | |
| 
 | |
| // https://twitter.com/ZenoRogue/status/1375754422752575488
 | |
| //  add -PM 0 -alpha 1
 | |
| 
 | |
| namespace hr {
 | |
| #if CAP_MODELS
 | |
| namespace hypcity {
 | |
| 
 | |
| using namespace rogueviz::objmodels;
 | |
| 
 | |
| void prepare_tf();
 | |
| 
 | |
| struct citymodel : model {
 | |
|   citymodel() : model("rogueviz/models/", "emilejohansson_p2.obj") {}
 | |
| 
 | |
|   hyperpoint low, high;
 | |
|   ld t;
 | |
| 
 | |
|   void prepare() override {
 | |
|     for(int i=0; i<4; i++) low[i] = 100, high[i] = -100;
 | |
| 
 | |
|     cgi.require_basics();
 | |
|     hyperpoint corner = get_corner_position(cwt.at, 0);
 | |
|     
 | |
|     t = abs(corner[0] / corner[3]);
 | |
|     }
 | |
| 
 | |
|   hyperpoint transform(hyperpoint h) override {
 | |
|     swap(h[1], h[2]);
 | |
|     h[2] = -h[2];
 | |
|     h[2] += 0.063;
 | |
|     h[0] -= 0.063;
 | |
|     h[1] += 0.063;
 | |
|     h *= 6;
 | |
|     // h[0] -= .5;
 | |
|     // h[1] += .5;
 | |
| 
 | |
|     for(int i=0; i<4; i++)
 | |
|       low[i] = min(low[i], h[i]),
 | |
|       high[i] = max(high[i], h[i]);
 | |
|       
 | |
|     if(hyperbolic || sphere) {
 | |
|     
 | |
|       hyperpoint hx;
 | |
|       hx[0] = h[0] * t * 2;
 | |
|       hx[1] = h[1] * t * 2;
 | |
|       hx[2] = 0;
 | |
|       hx[3] = 1;
 | |
|       if(hyperbolic) hx = spin(45._deg) * hx;
 | |
|       hx = normalize(hx);
 | |
|       hx = orthogonal_move(hx, h[2]*(t*(sphere ? 3 : 7)));
 | |
| 
 | |
|       return hx;
 | |
|       }
 | |
|     
 | |
|     if(nil || sol) {
 | |
|       if(nil) swap(h[1], h[2]);
 | |
|       h *= 0.5 / 0.378;
 | |
|       if(sol) h *= vid.binary_width;
 | |
|       if(nil) h *= nilv::nilwidth;
 | |
|       h[3] = 1;
 | |
|       return h;
 | |
|       }
 | |
|     
 | |
|     return h;
 | |
|     }
 | |
| 
 | |
|   void postprocess() override {
 | |
|     println(hlog, "low = ", low);
 | |
|     println(hlog, "high = ", high);
 | |
|     }
 | |
|   };
 | |
| 
 | |
| citymodel city;
 | |
| 
 | |
| bool draw_city_at(cell *c, const shiftmatrix& V) {
 | |
|   if(nil) {
 | |
|     auto co = nilv::get_coord(c->master);
 | |
|     if(co[1]) return false;
 | |
|     }
 | |
| 
 | |
|   if(sol) {
 | |
|     auto co = c->master->distance;
 | |
|     if(co) return false;
 | |
|     }
 | |
|   
 | |
|   if(c == cwt.at || true) 
 | |
|     city.render(V);
 | |
| 
 | |
|   return false;
 | |
|   }
 | |
| 
 | |
| void enable() { 
 | |
|   rogueviz::rv_hook(hooks_drawcell, 100, draw_city_at); 
 | |
|   add_model_settings();
 | |
|   }
 | |
| 
 | |
| auto hypcity_ah = arg::add3("-hypcity", enable)
 | |
| + addHook_slideshows(120, [] (tour::ss::slideshow_callback cb) {
 | |
| 
 | |
|     using namespace rogueviz::pres;
 | |
|     static vector<slide> hypcity_slides;
 | |
| 
 | |
|     if(hypcity_slides.empty()) {
 | |
|       hypcity_slides.emplace_back(
 | |
|         slide{"Introduction", 999, LEGAL::NONE, 
 | |
|           "Here we put a 3D model of a city into various geometries. Don't forget to try changing RogueViz projection and view range settings!\n\n"
 | |
|           "Remember to try different projections (press '1')!"
 | |
|           ,
 | |
|           [] (presmode mode) {
 | |
|           slide_url(mode, 'm', "original model by Emile Johansson", "https://sketchfab.com/3d-models/night-city-p2-82637933a7cb4fafadb0e2a79415c438");
 | |
|           slide_url(mode, 't', "original Tweets by Nico Belmonte", "https://twitter.com/philogb/status/1375147728389476356");
 | |
|           }});
 | |
|       
 | |
|       auto add = [&] (string s, string text, int dim, reaction_t setter) {
 | |
|         hypcity_slides.emplace_back(
 | |
|           tour::slide{s, 100, LEGAL::NONE | QUICKGEO, text,
 | |
|             [=] (presmode mode) {
 | |
|               if(mode == pmStart && dim == 2 && !vid.always3) {
 | |
|                 geom3::switch_fpp();
 | |
|                 }
 | |
|               setWhiteCanvas(mode, [setter, dim] {
 | |
|                 slide_backup(canvas_default_wall, waInvisibleFloor);
 | |
|                 if(dim == 2) slide_backup(vid.camera, 0);
 | |
|                 if(dim == 2) slide_backup(vid.depth, 0);
 | |
|                 slide_backup(context_fog, false);
 | |
|                 setter();
 | |
|                 });
 | |
|               if(mode == pmStart) enable();
 | |
|               non_game_slide_scroll(mode);
 | |
|               }});
 | |
|         };
 | |
|       
 | |
|       add("hyperbolic", "Hyperbolic geometry.", 2, [] {
 | |
|         set_geometry(g45);
 | |
|         gp::param = {1, 1};
 | |
|         set_variation(eVariation::unrectified);
 | |
|         });
 | |
|       add("spherical", "Spherical geometry.", 2, [] {
 | |
|         set_geometry(gSmallSphere);
 | |
|         set_variation(eVariation::pure);
 | |
|         });
 | |
|       add("Nil", "Nil geometry.", 3, [] {
 | |
|         set_geometry(gNil);
 | |
|         });
 | |
|       add("Solv", "Solv geometry.", 3, [] {
 | |
|         set_geometry(gSol);
 | |
|         });
 | |
|       add_end(hypcity_slides);
 | |
|       }
 | |
| 
 | |
|     cb(XLAT("non-Euclidean city"), &hypcity_slides[0], 'c');
 | |
|     });
 | |
| 
 | |
| }
 | |
| #endif
 | |
| }
 | 
