namespace hr { namespace bricks { void draw_ro(); extern void build(bool in_pair); #if !NILRIDER struct brick { euc::coord co; color_t col; int walls; hyperpoint location; hpcshape shRotWall[6]; }; #endif extern vector<brick> bricks; } } namespace nilrider { hpcshape shMini[6]; void create_minitriangle() { using namespace bricks; bricks::bricks.clear(); build(false); hyperpoint ctr = Hypc; for(auto& b: bricks::bricks) ctr += b.location; ctr /= ctr[3]; transmatrix B = gpushxto0(ctr); ld radius = 0; ld sca = .18; for(int f=0; f<6; f++) { cgi.bshape(shMini[f], PPR::WALL); shMini[f].flags |= POLY_TRIANGLES; for(auto& b: bricks::bricks) { transmatrix V = eupush(b.location); int which = b.walls; if(!((1<<f) & which)) continue; auto& sh = b.shRotWall[f]; for(int i=sh.s; i<sh.e; i++) { hyperpoint p = B * V * cgi.hpc[i]; p[0] *= sca; p[1] *= sca; p[2] *= sca*sca; cgi.hpcpush(p); radius = max(radius, sqhypot_d(2, p)); } } cgi.finishshape(); } cgi.extra_vertices(); println(hlog, "radius = ", radius); } /** the texture data used for the castle walls */ texture::texture_data *castle_texture; void create_castle() { if(!castle_texture) { castle_texture = new texture::texture_data; auto& tex = *castle_texture; tex.twidth = 16; tex.theight = 16; tex.stretched = false; tex.strx = tex.tx; tex.stry = tex.ty; tex.base_x = 0; tex.base_y = 0; tex.whitetexture(); for(int y=0; y<16; y++) for(int x=0; x<16; x++) tex.get_texture_pixel(x, y) = bcols[submaps['b'][y][x]]; tex.loadTextureGL(); } } hpcshape shBall; bool open_grid(int x, int y) { return among(y&3, 1, 2) || among(x&3, 0, 3); } bool closed_grid(int x, int y) { return among(y&3, 0, 3) || among(x&3, 0, 3); } template<class T1, class T2> void add_statue(const T1& grid, const T2& f) { auto pt = [&] (int x, int y) { ld x1 = x * M_PI / 16.; ld y1 = y * M_PI / 32.; cgi.hpcpush(f(x1,y1)); }; for(int y=-16; y<16; y++) for(int x=-16; x<16; x++) if(grid(x,y)) { pt(x, y); pt(x, y+1); pt(x+1, y); pt(x+1, y); pt(x, y+1); pt(x+1, y+1); } } hpcshape shGeostatue; void init_statues() { check_cgi(); if(cgi.ext.count("nil-statues")) return; cgi.ext["nil-statues"] = nullptr; create_minitriangle(); cgi.bshape(shBall, PPR::WALL); shBall.flags |= POLY_TRIANGLES; add_statue(open_grid, [] (ld lon, ld lat) { return direct_exp(point3(cos(lat)*sin(lon)*.5, cos(lat)*cos(lon)*.5, sin(lat)*.5)); }); cgi.finishshape(); cgi.extra_vertices(); cgi.add_texture(shBall); cgi.bshape(shGeostatue, PPR::WALL); shGeostatue.flags |= POLY_TRIANGLES; for(int i=0; i<8; i++) { hyperpoint z = point31(0, 1e-6, 8); hyperpoint ih = inverse_exp(shiftless(z)); ih = spin(i * 45 * degree) * ih; add_statue(closed_grid, [&] (ld lon, ld lat) { lat = lat * .75; hyperpoint h = direct_exp(ih * (.5 + lat / M_PI)); return rgpushxto0(h) * sym_to_heis(point31(sin(lon)*.1, cos(lon)*.1, 0)); }); } cgi.finishshape(); cgi.extra_vertices(); cgi.add_texture(shGeostatue); for(ld z: vector<ld> {M_PI/2+1e-2, M_PI+1e-2, M_PI*2+1e-2, 7, 10}) for(hyperpoint h: {point31(0, 0, z), point31(1e-3, 0, z), point31(1e-6, 0, z), point31(0, 1e-6, z)}) { hyperpoint i = inverse_exp(shiftless(h)); println(hlog, i, " @ ", hypot_d(3, i)); } } }