2023-05-15 00:48:38 +00:00
# include "rogueviz.h"
// for this video: https://youtu.be/Rhjv_PazzZE
namespace hr {
2023-05-18 12:18:46 +00:00
namespace embchess {
namespace smoothcam { using namespace rogueviz : : smoothcam ; }
2023-05-15 00:48:38 +00:00
/** load Chess? */
EX bool with_chess = false ;
/** load other models? */
EX bool with_models = false ;
/** including the CGtrader models? (not included here) */
EX bool cgtrader_models = false ;
/** floor disabled */
EX bool no_floor = false ;
/** do not include the models inside the house for faster transition */
EX bool light_models = false ;
/** higher periods needs to be set to display scaffold correctly */
int periods = 1 ;
/** how many chess moves performed */
int chess_moves = 0 ;
vector < pair < hyperpoint , hyperpoint > > map54_edges ;
vector < hyperpoint > map54_nodes ;
vector < pair < hyperpoint , hyperpoint > > map534_edges ;
vector < hyperpoint > map534_nodes ;
struct embset {
string name ;
geom3 : : eSpatialEmbedding se ;
ld walls , scale , depth , eye , sun , sky , star ;
} ;
embset current ( ) {
embset e ;
e . name = " current " ;
e . se = geom3 : : spatial_embedding ;
e . scale = geom3 : : euclid_embed_scale ;
auto actscale = e . scale ;
if ( e . se = = geom3 : : seDefault ) { e . scale = 0 ; actscale = 1 ; }
e . walls = vid . wall_height / actscale ;
e . depth = vid . depth / e . walls ;
e . eye = ( vid . eye - vid . depth ) / e . walls ;
e . sun = vid . sun_size / e . walls ;
e . sky = vid . sky_height ;
e . star = vid . star_height ;
e . se = geom3 : : spatial_embedding ;
return e ;
}
void activate ( const embset & e ) {
if ( GDIM = = 2 ) invoke_embed ( geom3 : : seDefault ) ;
embset c = current ( ) ;
auto wh = vid . wall_height ;
geom3 : : changing_embedded_settings = true ;
geom3 : : switch_always3 ( ) ;
geom3 : : euclid_embed_scale = e . se = = geom3 : : seDefault ? 1 : e . scale ;
vid . wall_height = e . walls * geom3 : : euclid_embed_scale ;
vid . depth = e . depth * vid . wall_height ;
vid . eye = vid . depth + e . eye * vid . wall_height ;
vid . sun_size = e . sun * vid . wall_height ;
vid . sky_height = e . sky ;
vid . star_height = e . star ;
geom3 : : spatial_embedding = e . se ;
geom3 : : switch_always3 ( ) ;
geom3 : : changing_embedded_settings = false ;
if ( e . se ! = c . se ) {
if ( vid . usingGL ) resetGL ( ) ;
}
delete_sky ( ) ;
if ( vid . wall_height * wh < 0 ) View = MirrorY * View ;
pmodel = default_model ( ) ;
} ;
2023-05-18 12:18:46 +00:00
embset emb_lerp ( const embset & a , const embset & b , ld f ) {
2023-05-15 00:48:38 +00:00
embset e ;
e . name = lalign ( 0 , " lerp( " , a , " , " , b , " , " , f , " ) " ) ;
e . se = b . se ;
e . scale = lerp ( a . scale , b . scale , f ) ;
e . walls = lerp ( a . walls , b . walls , f ) ;
e . depth = lerp ( a . depth , b . depth , f ) ;
e . eye = lerp ( a . eye , b . eye , f ) ;
e . sun = lerp ( a . sun , b . sun , f ) ;
e . sky = lerp ( a . sky , b . sky , f ) ;
e . star = lerp ( a . star , b . star , f ) ;
return e ;
}
void print ( hstream & hs , const embset & e ) {
print ( hlog , " embset{.name= \" " , e . name , " \" , .se=eEmbeddingMethod( " , int ( e . se ) , " ), .walls= " , e . walls , " , .scale= " , e . scale , " , .depth= " , e . depth , " , .eye= " , e . eye , " , .sun= " , e . sun , " , .sky= " , e . sky , " , .star= " , e . star , " } " ) ;
}
embset edefault = embset { . name = " default " , . se = geom3 : : seDefault , . walls = 1.2 , . scale = 0 , . depth = 0 , . eye = 1.5 , . sun = 0.333333 , . sky = 10 , . star = 9 } ;
embset edefaulti = embset { . name = " default " , . se = geom3 : : seDefault , . walls = - 1.2 , . scale = 0 , . depth = 0 , . eye = - 1.5 , . sun = 0.333333 , . sky = 10 , . star = 9 } ;
// embset eincyl = embset{.name="in cylinder", .se=geom3::seCylinderE, .walls=0.75, .scale=M_PI/10, .depth=0, .eye=1.5, .sun=0.10472, .sky=4, .star=3.6};
embset eincyl = embset { . name = " in cylinder E " , . se = geom3 : : seCylinderE , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset eoutcyl = embset { . name = " out cylinder E " , . se = geom3 : : seCylinderE , . walls = - 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.3 , . sky = 10 , . star = 9 } ;
embset eouthoro = embset { . name = " out horosphere " , . se = geom3 : : seLowerCurvature , . walls = 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 8 , . star = 7.5 } ;
embset einhoro = embset { . name = " in horosphere " , . se = geom3 : : seLowerCurvature , . walls = - 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 12 , . star = 11 } ;
embset einhoro_small = embset { . name = " in horosphere (small sky) " , . se = geom3 : : seLowerCurvature , . walls = - 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 18 , . star = 17 } ;
embset esolv = embset { . name = " solv " , . se = geom3 : : seSol , . walls = 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 12 , . star = 11 } ;
embset einnih = embset { . name = " in NIH " , . se = geom3 : : seNIH , . walls = - 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 12 , . star = 11 } ;
embset eoutnih = embset { . name = " out NIH " , . se = geom3 : : seNIH , . walls = 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 8 , . star = 7.5 } ;
embset eclifford = embset { . name = " Clifford " , . se = geom3 : : seCliffordTorus , . walls = 1.2 , . scale = M_PI / 10 , . depth = - 0.0561826 , . eye = 1.5 , . sun = 0.25 , . sky = 2.55 , . star = 2.3 } ;
embset enil = embset { . name = " Nil flat " , . se = geom3 : : seNil , . walls = 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 12 , . star = 11 } ;
embset esl2 = embset { . name = " SL(2,R) flat " , . se = geom3 : : seSL2 , . walls = 1.2 , . scale = 0.1 , . depth = 0 , . eye = 1.5 , . sun = 0.25 , . sky = 12 , . star = 11 } ;
embset eincylh = embset { . name = " in cylinderH " , . se = geom3 : : seCylinderH , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset eincylhe = embset { . name = " in cylinderHE " , . se = geom3 : : seCylinderHE , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset eincylnil = embset { . name = " in cylinder Nil " , . se = geom3 : : seCylinderNil , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset eincylsl = embset { . name = " in cylinder SL(2,R) " , . se = geom3 : : seCylinderSL2 , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset einhorocyl = embset { . name = " in horocylinder " , . se = geom3 : : seCylinderHoro , . walls = - 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 8 , . star = 7.5 } ;
embset eouthorocyl = embset { . name = " out horocylinder " , . se = geom3 : : seCylinderHoro , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 4 , . star = 3.5 } ;
embset eprodh_flat = embset { . name = " hyperbolic product (flat) " , . se = geom3 : : seProductH , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset eprodh_concave = embset { . name = " hyperbolic product (concave) " , . se = geom3 : : seProductH , . walls = 1.2 , . scale = M_PI / 10 , . depth = 1 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset eprods_flat = embset { . name = " spherical product (flat) " , . se = geom3 : : seProductS , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset eprods_concave = embset { . name = " spherical product (concave) " , . se = geom3 : : seProductS , . walls = 1.2 , . scale = M_PI / 10 , . depth = 0.8333 , . eye = 1.5 , . sun = 0.10472 , . sky = 2.6 , . star = 2.4 } ;
embset & edok ( ) { return vid . wall_height > 0 ? edefault : edefaulti ; }
vector < embset > embsets = {
edefault ,
eincyl , eoutcyl , eouthoro , einhoro , einhoro_small , esolv , eclifford , einnih , eoutnih ,
enil , esl2 , eincylh , eincylhe , eincylnil , eincylsl ,
einhorocyl , eouthorocyl , eprodh_flat , eprodh_concave , eprods_flat , eprods_concave
} ;
ld fix_chess = 0 ;
int draw_digger = 0 ;
bool move_cat = false ;
vector < string > xmap = {
{ " ......B..........p# " } ,
{ " .................p# " } ,
{ " ..xxxxxxxx.......p# " } ,
{ " ..xxxxxxxx..T....p# " } ,
{ " ..xxxxxxxx.....T.p# " } ,
{ " ..xxxxxxxx...~~..p# " } ,
{ " ..xxxxxxxx..~uv~.p# " } ,
{ " ..xxxxxxxx..~vu~.p# " } ,
{ " ..xxxxxxxx..~~~~.p# " } ,
{ " ..xxxxxxxx......Tp# " } ,
{ " .............T...p# " } ,
{ " ......C..........p# " } ,
{ " ......p..........p# " } ,
{ " .>>>..p..DDDDDDD.p# " } ,
{ " .>>>..pK.DddddrD.p# " } ,
{ " .>>>..pK.DdddtdD.p# " } ,
{ " ......pK.DdddddD.p# " } ,
{ " ..e...p..DOD+DOD.p# " } ,
{ " ......p.....p....p# " } ,
{ " ....^.pppppppppppp# " } ,
} ;
void build_map ( ) ;
ld hmul ;
2023-05-18 12:18:46 +00:00
set < cell * > house1 , house2 ;
2023-05-15 00:48:38 +00:00
vector < cell * > ac , bac ;
using namespace rogueviz : : objmodels ;
void prepare_tf ( ) ;
hyperpoint adjust ( hyperpoint h ) {
h = cspin90 ( 1 , 2 ) * h * 40. + point3 ( - 0.5 , - 0.5 , 0 ) ;
return h ;
}
hyperpoint rechess ( hyperpoint h ) {
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , 0.01 - h [ 2 ] / 4 * hmul * 2 / 0.6 ) + fix_chess ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
struct split_model_data : gi_extension {
map < pair < int , int > , vector < shared_ptr < object > > > objs_at ;
void render ( const shiftmatrix & V , int x , int y ) ;
} ;
struct chessmodel : public model {
void process_triangle ( vector < hyperpoint > & hys , vector < hyperpoint > & tot , bool textured , object * co ) override {
for ( auto & h : hys ) h = adjust ( h ) ;
hyperpoint norm = ( hys [ 1 ] - hys [ 0 ] ) ^ ( hys [ 2 ] - hys [ 0 ] ) ;
norm / = hypot_d ( 3 , norm ) ;
ld y = .5 + ( .2 * norm [ 0 ] + .16 * norm [ 1 ] + .14 * norm [ 2 ] ) ;
glvertex shade = glhr : : makevertex ( 0 , y , 0 ) ;
glvertex shadecol = glhr : : makevertex ( y , y , y ) ;
auto elen = [ ] ( hyperpoint a , hyperpoint b ) { return ceil ( hypot_d ( 3 , a - b ) * 5 ) ; } ;
int parts = max ( max ( elen ( hys [ 0 ] , hys [ 1 ] ) , elen ( hys [ 0 ] , hys [ 2 ] ) ) , elen ( hys [ 1 ] , hys [ 1 ] ) ) ;
// if(parts > 8) println(hlog, "parts = ", parts, " levels = ", tie(hys[0][2], hys[1][2], hys[2][2]), " .. ", hys);
// if(parts > 8) return;
auto tri = [ & ] ( int a , int b ) {
cgi . hpcpush ( rechess ( hys [ 0 ] + ( hys [ 1 ] - hys [ 0 ] ) * a / parts + ( hys [ 2 ] - hys [ 0 ] ) * b / parts ) ) ;
if ( textured ) {
co - > tv . tvertices . push_back ( glhr : : pointtogl ( tot [ 0 ] + ( tot [ 1 ] - tot [ 0 ] ) * a / parts + ( tot [ 2 ] - tot [ 0 ] ) * b / parts ) ) ;
co - > tv . colors . push_back ( shadecol ) ;
}
else {
co - > tv . tvertices . push_back ( shade ) ;
}
} ;
for ( int a = 0 ; a < parts ; a + + )
for ( int b = 0 ; b < parts - a ; b + + ) {
tri ( a , b ) ;
tri ( a + 1 , b ) ;
tri ( a , b + 1 ) ;
if ( a + b < parts - 1 ) {
tri ( a , b + 1 ) ;
tri ( a + 1 , b ) ;
tri ( a + 1 , b + 1 ) ;
}
}
}
chessmodel ( string a , string b ) : model ( a , b ) { }
void split ( model_data & md , split_model_data & smd ) ;
split_model_data & get_split ( ) {
auto & md = ( unique_ptr < split_model_data > & ) cgi . ext [ fname + " -SPLIT " ] ;
if ( ! md ) {
md = std : : make_unique < split_model_data > ( ) ;
auto & md0 = get ( ) ;
split ( md0 , * md ) ;
}
return * md ;
}
} ;
bool ispiece ( color_t col ) {
return among ( col , color_t ( 0xFFFFFFFF ) , color_t ( 0x202020FF ) , color_t ( 0x2B2B2BFF ) ) ;
}
void chessmodel : : split ( model_data & md , split_model_data & smd ) {
cgi . extra_vertices ( ) ;
map < pair < int , int > , map < color_t , vector < pair < hyperpoint , glvertex > > > > mm ;
for ( auto & obj : md . objs ) {
for ( int i = obj - > sh . s ; i < obj - > sh . e ; i + = 3 ) {
hyperpoint ctr = Hypc ;
array < hyperpoint , 3 > hs ;
for ( int j = 0 ; j < 3 ; j + + ) hs [ j ] = GDIM = = 2 ? cgi . hpc [ i + j ] : cgi . emb - > actual_to_logical ( cgi . hpc [ i + j ] ) ;
ctr + = hs [ 0 ] ;
ctr + = hs [ 1 ] ;
ctr + = hs [ 2 ] ;
ctr / = 3 ;
int x = floor ( ctr [ 0 ] + .5 ) ;
int y = floor ( ctr [ 1 ] + .5 ) ;
int ax = x + 6 , ay = y + 6 ;
if ( chess_moves > = 1 & & ispiece ( obj - > color ) ) {
if ( ax = = 6 ) { if ( ay = = 8 ) ay = 6 ; else if ( ay = = 6 ) ay = 8 ; }
}
if ( chess_moves > = 2 & & ispiece ( obj - > color ) ) {
if ( ax = = 6 ) { if ( ay = = 3 ) ay = 5 ; else if ( ay = = 5 ) ay = 3 ; }
}
if ( chess_moves > = 3 & & ispiece ( obj - > color ) ) {
if ( ax = = 8 ) { if ( ay = = 9 ) ay = 7 , ax = 7 ; }
}
for ( int j = 0 ; j < 3 ; j + + )
mm [ { ax , ay } ] [ obj - > color ] . emplace_back ( hs [ j ] - hyperpoint ( x , y , 0 , 0 ) , obj - > tv . tvertices [ i + j - obj - > sh . s ] ) ;
}
}
for ( auto & a : mm )
for ( auto & b : a . second ) {
auto & objs = smd . objs_at [ a . first ] ;
objs . push_back ( make_shared < object > ( ) ) ;
auto co = & * objs . back ( ) ;
cgi . bshape ( co - > sh , PPR : : THORNS ) ;
cgi . last - > flags | = POLY_TRIANGLES ;
cgi . last - > texture_offset = 0 ;
cgi . last - > tinf = & co - > tv ;
co - > tv . texture_id = floor_textures - > renderedTexture ;
if ( GDIM = = 2 ) cgi . last - > tinf = nullptr ;
co - > color = b . first ;
if ( co - > color = = 0xCCCCCCFF ) co - > color = GDIM = = 2 ? 0 : 0xFFE080FF ;
else if ( co - > color = = 0x5B5B5BFF ) co - > color = GDIM = = 2 ? 0 : 0x807020FF ;
// else for(auto& v: b.second) v.first = cspin180(0, 1) * v.first;
for ( auto v : b . second ) {
cgi . hpcpush ( GDIM = = 2 ? v . first : cgi . emb - > logical_to_actual ( v . first ) ) ;
co - > tv . tvertices . push_back ( v . second ) ;
}
cgi . finishshape ( ) ;
}
cgi . extra_vertices ( ) ;
if ( 0 ) for ( auto & p : smd . objs_at ) {
println ( hlog , p . first , " : " , isize ( p . second ) , " objects " ) ;
for ( auto & obj : p . second ) {
vector < hyperpoint > hs ;
for ( int i = obj - > sh . s ; i < obj - > sh . e ; i + + ) hs . push_back ( cgi . hpc [ i ] ) ;
if ( isize ( hs ) > 3 ) hs . resize ( 3 ) ;
println ( hlog , " vertices: " , obj - > sh . e - obj - > sh . s , " of color " , obj - > color , " : " , hs ) ;
}
}
}
void split_model_data : : render ( const shiftmatrix & V , int x , int y ) {
for ( auto & obj : objs_at [ { x , y } ] ) if ( obj - > color ) {
queuepoly ( V , obj - > sh , obj - > color ) ;
}
}
chessmodel chess ( " rogueviz/models/ " , " Polyfjord_Chess_Set.obj " ) ;
struct bunnymodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h = cspin ( 0 , 1 , 15. _deg ) * h ;
h [ 0 ] * = 800 ;
h [ 1 ] * = 800 ;
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ilerp ( - 0.000333099 , - 0.00186996 , h [ 2 ] ) * hmul * 4 / 3. ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
bunnymodel ( string a , string b ) : model ( a , b ) { }
} ;
bunnymodel bunny ( " rogueviz/models/ " , " bunny.obj " ) ;
struct catmodel : public model {
hyperpoint transform ( hyperpoint h ) override {
if ( 0 ) println ( hlog , " scale = 1 to " ,
lerp ( cgi . FLOOR , cgi . WALL , ilerp ( 0.00767046 , - 0.184471 , 1 ) * hmul * 4 / 3. )
- lerp ( cgi . FLOOR , cgi . WALL , ilerp ( 0.00767046 , - 0.184471 , 0 ) * hmul * 4 / 3. )
) ;
h = cspin90 ( 1 , 2 ) * h ;
h = cspin180 ( 0 , 1 ) * h ;
h = cspin ( 1 , 0 , 30. _deg ) * h ;
h [ 0 ] * = 6 ;
h [ 1 ] * = 6 ;
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ilerp ( 0.00767046 , - 0.184471 , h [ 2 ] ) * hmul * 4 / 3. ) / 8.3272 * 6 ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
void load_obj ( model_data & md ) override {
model : : load_obj ( md ) ;
for ( auto & o : md . objs ) if ( o - > mtlname = = " whiskers " ) o - > sh . prio = PPR : : TRANSPARENT_WALL ;
}
catmodel ( string a , string b ) : model ( a , b ) { }
} ;
catmodel maxwellcat ( " rogueviz/models/ " , " maxwellcat.obj " ) ;
struct tulipmodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h = cspin180 ( 0 , 1 ) * h ;
h [ 0 ] * = 400 ;
h [ 1 ] * = 400 ;
h [ 0 ] - = 0.1 * 2 ; h [ 1 ] + = 0.36 * 2 ;
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ilerp ( 0 , - 0.00307639 , h [ 2 ] ) * hmul ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
tulipmodel ( string a , string b ) : model ( a , b ) { }
} ;
tulipmodel tulip ( " rogueviz/models/ " , " tulip.obj " ) ;
tulipmodel tulip1 ( " rogueviz/models/ " , " tulip1.obj " ) ;
tulipmodel tulip2 ( " rogueviz/models/ " , " tulip2.obj " ) ;
struct diggermodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h [ 0 ] * = 50 ;
h [ 1 ] * = 50 ;
/* h[0] *= 400;
h [ 1 ] * = 400 ;
h [ 0 ] - = 0.1 * 2 ; h [ 1 ] + = 0.36 * 2 ; */
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ilerp ( 0.00027 , - 0.0549454 , h [ 2 ] ) * hmul * 1.5 ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
diggermodel ( string a , string b ) : model ( a , b ) { }
} ;
diggermodel digger ( " rogueviz/models/ " , " digger.obj " ) ;
struct tablemodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h [ 1 ] - = 0.005 ;
h [ 0 ] * = 100 ;
h [ 1 ] * = 100 ;
/* h[0] *= 400;
h [ 1 ] * = 400 ;
h [ 0 ] - = 0.1 * 2 ; h [ 1 ] + = 0.36 * 2 ; */
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ilerp ( 0 , - 0.008 , h [ 2 ] ) * hmul / 2 ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
tablemodel ( string a , string b ) : model ( a , b ) { }
} ;
tablemodel table ( " rogueviz/models/ " , " table.obj " ) ;
struct cheesemodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h [ 0 ] * = 15 ;
h [ 1 ] * = 15 ;
/* h[0] *= 400;
h [ 1 ] * = 400 ;
h [ 0 ] - = 0.1 * 2 ; h [ 1 ] + = 0.36 * 2 ; */
h [ 0 ] - = 0.2 ;
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ( ilerp ( 0.00577916 , - 0.01166 , h [ 2 ] ) / 3 + 1.05 ) * hmul / 2 ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
cheesemodel ( string a , string b ) : model ( a , b ) { }
} ;
cheesemodel cheese ( " rogueviz/models/ " , " cheese.obj " ) ;
struct coffeemodel : public model {
int cid ;
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h [ 0 ] + = 0.00077 ;
h [ 1 ] + = 0.011 ;
h [ 0 ] * = 200 ; h [ 1 ] * = 200 ;
if ( cid = = 1 ) h [ 0 ] + = 0.3 ;
if ( cid = = 2 ) h [ 1 ] + = 0.5 ;
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ( ilerp ( - 0.0083 , - 0.0089 , h [ 2 ] ) ) * 1.2 / 10 + .51 ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
coffeemodel ( string a , string b , int _id ) : model ( a , b ) , cid ( _id ) { }
} ;
/* need different file names */
coffeemodel coffee1 ( " rogueviz/models/ " , " coffee.obj " , 1 ) , coffee2 ( " rogueviz/models/ " , " ./coffee.obj " , 2 ) ;
struct lilymodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h [ 0 ] + = 0.67 ; h [ 1 ] - = 0.36 ;
h [ 0 ] * = 5 ;
h [ 1 ] * = 5 ;
h [ 2 ] = lerp ( cgi . LAKE , cgi . FLOOR , ilerp ( 0.018 , - 0.0496 , h [ 2 ] ) * hmul ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
lilymodel ( string a , string b ) : model ( a , b ) { }
} ;
lilymodel lily ( " rogueviz/models/ " , " lily.obj " ) ;
struct duckmodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h [ 0 ] + = 3.8 ; h [ 1 ] - = 2 ;
h [ 2 ] = lerp ( cgi . LAKE , cgi . FLOOR , ilerp ( 0.056 , - 0.408 , h [ 2 ] ) * hmul * 1.5 ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
duckmodel ( string a , string b ) : model ( a , b ) { }
} ;
duckmodel duck ( " rogueviz/models/ " , " duck.obj " ) ;
struct ratmodel : public model {
hyperpoint transform ( hyperpoint h ) override {
h = cspin90 ( 1 , 2 ) * h ;
h [ 0 ] * = 100 ;
h [ 1 ] * = 100 ;
h [ 2 ] * = 100 ;
h [ 0 ] / = 3 * 3 ;
h [ 1 ] / = 3 * 3 ;
h [ 2 ] / = 3 * 3 ;
h = cspin ( 0 , 1 , 135. _deg ) * h ;
h [ 2 ] = lerp ( cgi . FLOOR , cgi . WALL , ilerp ( 1 / 9. , 1 / 9. - 1.2 , h [ 2 ] ) * hmul ) ;
if ( GDIM = = 3 ) h = cgi . emb - > logical_to_actual ( h ) ;
else h [ 2 ] = 1 ;
return h ;
}
ratmodel ( string a , string b ) : model ( a , b ) { }
} ;
ratmodel rat ( " rogueviz/models/ " , " spinning-rat.obj " ) ;
bool hedge_constructed = false ;
const int hx = 7 ;
array < char , hx * hx * hx > hedge_visited ;
array < int , 6 > hdirs = { 1 , hx , hx * hx , - 1 , - hx , - hx * hx } ;
array < vector < int > , hx * hx * hx > hedge_dirs ;
int hstart ;
void construct_hedge ( ) {
for ( int x = 0 ; x < hx * hx * hx ; x + + ) hedge_visited [ x ] = false ;
hstart = ( hx / 2 ) + ( hx / 2 ) * hx ;
hedge_visited [ hstart ] = true ;
vector < int > inorder = { hstart } ;
for ( int i = 0 ; i < hx * hx * hx ; i + + ) {
int at = inorder [ i ] ;
for ( int dir : { 0 , 1 , 3 , 4 , 2 , 5 } ) {
int co = ( at / abs ( hdirs [ dir ] ) ) % hx ;
if ( hdirs [ dir ] < 0 & & co = = 0 ) continue ;
if ( hdirs [ dir ] > 0 & & co = = hx - 1 ) continue ;
if ( hedge_visited [ at + hdirs [ dir ] ] ) continue ;
hedge_visited [ at + hdirs [ dir ] ] = true ;
hedge_dirs [ at ] . push_back ( dir ) ;
inorder . push_back ( at + hdirs [ dir ] ) ;
}
}
/*
int qty = hx * hx * hx - 1 ;
while ( qty > 0 ) {
int at = hrand ( hx * hx * hx ) ;
if ( ! hedge_visited [ at ] ) continue ;
int dir = hrand ( 6 ) ;
int co = ( at / abs ( hdirs [ dir ] ) ) % hx ;
if ( hdirs [ dir ] < 0 & & co = = 0 ) continue ;
if ( hdirs [ dir ] > 0 & & co = = hx - 1 ) continue ;
if ( hedge_visited [ at + hdirs [ dir ] ] ) continue ;
hedge_visited [ at + hdirs [ dir ] ] = true ;
hedge_dirs [ at ] . push_back ( dir ) ;
qty - - ;
} */
}
void add_oct ( transmatrix T , int idx , int face , ld len ) {
array < hyperpoint , 3 > p ;
for ( int i = 0 ; i < 3 ; i + + ) { p [ i ] = C03 ; p [ i ] [ i ] = ( ( face > > i ) & 1 ) ? len / 2 : - len / 2 ; p [ i ] = cgi . emb - > logical_scaled_to_intermediate * p [ i ] ; }
hyperpoint c = ( p [ 0 ] + p [ 1 ] + p [ 2 ] ) / 3 ;
for ( int f = 0 ; f < 3 ; f + + ) {
hyperpoint a = p [ f ] - c ;
hyperpoint b = p [ ( f + 1 ) % 3 ] - c ;
texture_order ( [ & ] ( ld x , ld y ) {
hyperpoint h = c + a * x + b * y ;
hyperpoint t = T * cpush ( 0 , h [ 0 ] ) * cpush ( 1 , h [ 1 ] ) * cpush ( 2 , h [ 2 ] ) * C0 ;
cgi . hpcpush ( t ) ;
} ) ;
}
if ( true ) for ( auto d : hedge_dirs [ idx ] ) {
hyperpoint h = C0 ;
h [ d % 3 ] = ( d < 3 ? - len : len ) ;
h = cgi . emb - > logical_scaled_to_intermediate * h ;
transmatrix T1 = T ;
for ( int i = 0 ; i < 3 ; i + + ) if ( h [ i ] ) T1 = T1 * cpush ( i , h [ i ] ) ;
add_oct ( T1 , idx + hdirs [ d ] , face , len ) ;
}
}
void create_hedge ( model_data & md ) {
if ( ! hedge_constructed ) construct_hedge ( ) ;
hyperpoint start = cgi . emb - > logical_to_actual ( point31 ( 0 , 0 , cgi . FLOOR ) ) ;
hyperpoint npt = cgi . emb - > logical_to_actual ( point31 ( 0.01 , 0 , cgi . FLOOR ) ) ;
transmatrix S = cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point31 ( 0 , 0 , cgi . emb - > center_z ( ) + cgi . FLOOR ) ) ;
ld len = hdist ( start , npt ) * 100 / 7 ;
len * = 3 ;
if ( vid . wall_height < 0 ) len = - len ;
md . objs . resize ( 8 ) ;
for ( int i = 0 ; i < 8 ; i + + ) {
md . objs [ i ] = make_shared < object > ( ) ;
auto & obj = * md . objs [ i ] ;
obj . color = 0xFF00FF ;
if ( i & 1 ) obj . color ^ = 0x200000 ;
if ( i & 2 ) obj . color ^ = 0x20000000 ;
if ( i & 4 ) obj . color ^ = 0x2000 ;
cgi . bshape ( obj . sh , PPR : : FLOOR_DRAGON ) ;
cgi . last - > flags | = POLY_TRIANGLES ;
cgi . last - > texture_offset = 0 ;
cgi . last - > tinf = & obj . tv ;
obj . tv . texture_id = floor_textures - > renderedTexture ;
add_oct ( S * lzpush ( - len / 2 ) , hstart , i , len ) ;
cgi . finishshape ( ) ;
bind_floor_texture ( obj . sh , cgi . shFeatherFloor . id ) ;
}
cgi . extra_vertices ( ) ;
}
void draw_hedge ( const shiftmatrix & V ) {
auto & md = ( unique_ptr < model_data > & ) cgi . ext [ " hedge " ] ;
if ( ! md ) {
md = std : : make_unique < model_data > ( ) ;
create_hedge ( * md ) ;
}
md - > render ( V ) ;
}
hyperpoint inverse_exp_newton ( hyperpoint h , int iter ) {
auto approx = inverse_exp ( shiftless ( h ) ) ;
for ( int i = 0 ; i < iter ; i + + ) {
transmatrix T ;
ld eps = 1e-3 ;
hyperpoint cur = direct_exp ( approx ) ;
println ( hlog , approx , " error = " , hdist ( cur , h ) , " iteration " , i , " / " , iter ) ;
for ( int i = 0 ; i < 3 ; i + + )
set_column ( T , i , direct_exp ( approx + ctangent ( i , eps ) ) - h ) ;
set_column ( T , 3 , C03 ) ;
approx = approx - inverse ( T ) * ( cur - h ) * eps ;
}
return approx ;
}
hpcshape & get_noniso_pipe ( hyperpoint target , ld width , ePipeEnd endtype ) {
int id = bucketer ( target ) + int ( 157003 * log ( width + .001 ) ) ;
if ( cgi . shPipe . count ( id ) ) return cgi . shPipe [ id ] ;
hpcshape & pipe = cgi . shPipe [ id ] ;
println ( hlog , " generating pipe at target " , target , " and width " , width ) ;
cgi . bshape ( pipe , PPR : : HEPTAMARK ) ;
# if CAP_GL
auto & utt = cgi . models_texture ;
if ( floor_textures ) {
pipe . tinf = & utt ;
pipe . texture_offset = isize ( utt . tvertices ) ;
}
# endif
hyperpoint lmax = inverse_exp_newton ( target , 10 ) ;
println ( hlog , " error = " , hdist ( direct_exp ( lmax ) , target ) ) ;
transmatrix lT ;
ld length ;
if ( 1 ) {
dynamicval < eGeometry > g ( geometry , gCubeTiling ) ;
length = hdist0 ( lmax ) ;
lT = rspintox ( lmax ) ;
println ( hlog , " target = " , target , " lmax = " , lmax , " length = " , length , " lT = " , kz ( lT ) ) ;
println ( hlog , " test: " , lT * xpush0 ( length ) , " vs " , lmax ) ;
}
const int MAX_X = 32 ;
const int MAX_R = 20 ;
auto at = [ & ] ( ld i , ld a , ld z = 1 , ld s = 1 ) {
a + = 0.5 ;
ld alpha = TAU * a / MAX_R ;
hyperpoint p ;
if ( 1 ) {
dynamicval < eGeometry > g ( geometry , gCubeTiling ) ;
p = xpush ( i * length / MAX_X ) * cspin ( 1 , 2 , alpha ) * ypush0 ( width * z ) ;
p = lT * p ;
}
p = direct_exp ( p ) ;
cgi . hpcpush ( p ) ;
# if CAP_GL
if ( floor_textures ) utt . tvertices . push_back ( glhr : : makevertex ( 0 , true ? 0.549 - s * 0.45 * sin ( alpha ) : 0.999 , 0 ) ) ;
# endif
} ;
for ( int i = 0 ; i < MAX_X ; i + + ) {
for ( int a = 0 ; a < MAX_R ; a + + ) {
at ( i , a , 1 ) ;
at ( i , a + 1 , 1 ) ;
at ( i + 1 , a , 1 ) ;
at ( i + 1 , a + 1 , 1 ) ;
at ( i + 1 , a , 1 ) ;
at ( i , a + 1 , 1 ) ;
}
}
if ( endtype = = ePipeEnd : : sharp ) for ( int a = 0 ; a < MAX_R ; a + + ) for ( int x : { 0 , MAX_X } ) {
at ( x , a , 1 , 0 ) ;
at ( x , a + 1 , 1 , 0 ) ;
at ( x , 0 , 0 , 0 ) ;
}
if ( endtype = = ePipeEnd : : ball ) for ( int a = 0 ; a < MAX_R ; a + + ) for ( int x = - MAX_R ; x < MAX_R ; x + + ) {
ld xb = x < 0 ? 0 : MAX_X ;
ld mul = MAX_X * width / length * .9 ; // .9 to prevent Z-fighting
ld x0 = xb + mul * sin ( x * 90. _deg / MAX_R ) ;
ld x1 = xb + mul * sin ( ( x + 1 ) * 90. _deg / MAX_R ) ;
ld z0 = cos ( x * 90. _deg / MAX_R ) ;
ld z1 = cos ( ( x + 1 ) * 90. _deg / MAX_R ) ;
at ( x0 , a , z0 , z0 ) ;
at ( x0 , a + 1 , z0 , z0 ) ;
at ( x1 , a , z1 , z1 ) ;
at ( x1 , a + 1 , z1 , z1 ) ;
at ( x1 , a , z1 , z1 ) ;
at ( x0 , a + 1 , z0 , z0 ) ;
}
cgi . last - > flags | = POLY_TRIANGLES | POLY_PRINTABLE ;
cgi . finishshape ( ) ;
cgi . extra_vertices ( ) ;
return pipe ;
}
void fat_line ( const shiftmatrix & V1 , const hyperpoint h1 , const shiftmatrix & V2 , const hyperpoint h2 , color_t col , int prec , ld lw ) {
if ( nonisotropic ) {
auto nV1 = V1 * rgpushxto0 ( h1 ) ;
hyperpoint U2 = inverse_shift ( nV1 , V2 * rgpushxto0 ( h2 ) ) * C0 ;
auto & p = get_noniso_pipe ( U2 , lw , ePipeEnd : : ball ) ;
queuepoly ( nV1 , p , col ) ;
return ;
}
ld d = hdist ( V1 . T * h1 , V2 . T * h2 ) ;
shiftmatrix T = V1 * rgpushxto0 ( h1 ) ;
transmatrix S = rspintox ( inverse_shift ( T , V2 ) * h2 ) ;
transmatrix U = rspintoc ( inverse_shift ( T * S , shiftless ( C0 ) ) , 2 , 1 ) ;
auto & p = queuepoly ( T * S * U , cgi . generate_pipe ( d , lw , ePipeEnd : : ball ) , col ) ;
p . intester = xpush0 ( d / 2 ) ;
}
int scaffoldx = 0 , scaffoldy = 0 , scaffoldb = 0 , scaffoldx_move = 0 , scaffoldy_move ;
template < class T > void draw_map54 ( const shiftmatrix & S , const T & f , color_t col ) {
for ( auto p : map54_nodes ) queuepoly ( S * rgpushxto0 ( f ( p ) ) , cgi . shSnowball , 0xFFFFFFFF ) ;
for ( auto & p : map54_edges ) fat_line ( S , f ( p . first ) , S , f ( p . second ) , ( abs ( p . first [ 1 ] ) < 1e-3 & & abs ( p . second [ 1 ] ) < 1e-3 & & scaffoldx & & scaffoldy ) ? 0xFFFFFFFF : col , 2 , 0.01 ) ;
}
void draw_scaffold ( const shiftmatrix & V ) {
ld levz = log ( 2 ) ;
if ( nih ) levz = 1 ;
ld levx = 1 ;
if ( hyperbolic ) levx = exp ( - cgi . FLOOR ) ;
levx * = 5 ;
if ( scaffoldx = = 1 )
for ( int z = - 5 ; z < = 5 ; z + + )
for ( int s = - 20 ; s < = 20 ; s + + ) {
shiftmatrix S = V * lzpush ( cgi . FLOOR + z * levz ) * cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( s * levx , 0 , 0 ) ) ;
queuepoly ( S , cgi . shSnowball , 0xFFFFFFFF ) ;
fat_line ( S , C0 , S , lzpush ( - levz ) * C0 , ( s = = 0 & & scaffoldy ) ? 0xFFFFFFFF : 0xFF0000FF , 2 , 0.01 ) ;
for ( int s = 0 ; s < 8 ; s + + )
fat_line ( S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( levx * ( s + 0 ) / 8. , 0 , 0 ) ) * C0 ,
S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( levx * ( s + 1 ) / 8. , 0 , 0 ) ) * C0 ,
0x8000FFFF , 2 , 0.01 ) ;
}
if ( scaffoldx = = 2 ) {
if ( hyperbolic ) {
draw_map54 ( V , [ ] ( hyperpoint h ) { return cgi . emb - > intermediate_to_actual_translation ( point3 ( h [ 1 ] , 0 , 0 ) ) * zpush ( h [ 0 ] ) * C0 ; } , 0xFFD500FF ) ;
}
if ( sol ) {
draw_map54 ( V , [ ] ( hyperpoint h ) { return cgi . emb - > intermediate_to_actual_translation ( point3 ( h [ 1 ] , 0 , 0 ) ) * zpush ( - h [ 0 ] ) * C0 ; } , 0xFFD500FF ) ;
}
if ( nih ) {
draw_map54 ( V , [ ] ( hyperpoint h ) { return cgi . emb - > intermediate_to_actual_translation ( point3 ( - h [ 1 ] / log ( 2 ) , 0 , 0 ) ) * zpush ( h [ 0 ] / log ( 2 ) ) * C0 ; } , 0xFFD500FF ) ;
}
}
ld levy = 5 ;
if ( scaffoldy = = 1 )
for ( int z = - 5 ; z < = 5 ; z + + )
for ( int s = - 20 ; s < = 20 ; s + + ) {
shiftmatrix S = V * lzpush ( cgi . FLOOR + z * levz ) * cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( 0 , s * levy , 0 ) ) ;
queuepoly ( S , cgi . shSnowball , 0xFFFFFFFF ) ;
fat_line ( S , C0 , S , lzpush ( sol ? levz : - levz ) * C0 , ( s = = 0 & & scaffoldx ) ? 0xFFFFFFFF : 0x0000FFFF , 2 , 0.01 ) ;
for ( int s = 0 ; s < 8 ; s + + )
fat_line ( S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( 0 , levy * ( s + 0 ) / 8. , 0 ) ) * C0 ,
S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( 0 , levy * ( s + 1 ) / 8. , 0 ) ) * C0 ,
0x0080FF , 2 , 0.01 ) ;
}
if ( scaffoldy = = 2 ) {
if ( hyperbolic ) {
draw_map54 ( V , [ ] ( hyperpoint h ) { return cgi . emb - > intermediate_to_actual_translation ( point3 ( 0 , h [ 1 ] , 0 ) ) * zpush ( h [ 0 ] ) * C0 ; } , 0x80D500FF ) ;
}
if ( sol ) {
draw_map54 ( V , [ ] ( hyperpoint h ) { return cgi . emb - > intermediate_to_actual_translation ( point3 ( 0 , h [ 1 ] , 0 ) ) * zpush ( h [ 0 ] ) * C0 ; } , 0x80D500FF ) ;
}
if ( nih ) {
draw_map54 ( V , [ ] ( hyperpoint h ) { return cgi . emb - > intermediate_to_actual_translation ( point3 ( 0 , h [ 1 ] / log ( 3 ) , 0 ) ) * zpush ( h [ 0 ] / log ( 3 ) ) * C0 ; } , 0x80D500FF ) ;
}
}
if ( scaffoldb = = 1 )
for ( int z = - 5 ; z < = 5 ; z + + )
for ( int sx = - 5 ; sx < = 5 ; sx + + )
for ( int sy = - 5 ; sy < = 5 ; sy + + ) {
shiftmatrix S = V * lzpush ( cgi . FLOOR + z * levz ) * cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( sx * levx , sy * levy , 0 ) ) ;
queuepoly ( S , cgi . shSnowball , 0xFFFFFFFF ) ;
fat_line ( S , C0 , S , lzpush ( - levz ) * C0 , 0xFF0000FF , 2 , 0.01 ) ;
for ( int s = 0 ; s < 8 ; s + + ) {
fat_line ( S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( levx * ( s + 0 ) / 8. , 0 , 0 ) ) * C0 ,
S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( levx * ( s + 1 ) / 8. , 0 , 0 ) ) * C0 ,
0xFF8000FF , 2 , 0.01 ) ;
fat_line ( S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( 0 , levy * ( s + 0 ) / 8. , 0 ) ) * C0 ,
S , cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( 0 , levy * ( s + 1 ) / 8. , 0 ) ) * C0 ,
0xFF8000FF , 2 , 0.01 ) ;
}
}
if ( scaffoldb = = 2 & & hyperbolic ) {
for ( auto h : map534_nodes ) queuepoly ( V * rgpushxto0 ( h ) , cgi . shSnowball , 0xFFFFFFFF ) ;
for ( auto h : map534_edges ) fat_line ( V , h . first , V , h . second , 0xFFFFFFFF , 2 , 0.01 ) ;
}
}
2023-05-18 12:18:46 +00:00
string fixed_random_digits = " 1100002102001211 " ;
2023-05-15 00:48:38 +00:00
void draw_shape ( const shiftmatrix & V , vector < ld > tab , color_t col , ld mul = 1 ) {
int n = isize ( tab ) ;
for ( int i = 0 ; i < n ; i + = 2 ) curvepoint ( hpxy ( tab [ i ] * mul , tab [ i + 1 ] * mul ) ) ;
curvepoint ( hpxy ( tab [ 0 ] * mul , tab [ 1 ] * mul ) ) ;
queuecurve ( V , 0xFF , col , PPR : : MONSTER_LEG ) ;
}
bool draw_chess_at ( cell * c , const shiftmatrix & V ) {
if ( c - > item = = itHyperstone ) c - > item = itNone ;
if ( false ) {
if ( c = = cwt . at ) chess . render ( V ) ;
}
else {
auto co = euc : : full_coords2 ( c ) ;
char & chr = xmap [ gmod ( co . second , 20 ) ] [ gmod ( co . first , 20 ) ] ;
char ch = chr ;
if ( no_floor & & ch ! = ' ^ ' ) ch = ' < ' ;
// if(co.first == 0 && co.second == 0) bunny.render(V);
switch ( ch ) {
case ' r ' :
if ( GDIM = = 3 & & with_models ) {
rat . render ( V ) ;
}
else {
drawMonsterType ( moMouse , c , V * spin ( - 135. _deg ) , 0x804000 , 0 , 0x804000 ) ;
}
break ;
case ' < ' :
c - > wall = waChasm ;
2023-05-18 12:18:46 +00:00
house1 . erase ( c ) ; house2 . erase ( c ) ;
2023-05-15 00:48:38 +00:00
fat_line ( V , cgi . emb - > logical_to_actual ( point31 ( 0.5 , 0.5 , 0 ) ) , V , cgi . emb - > logical_to_actual ( point31 ( 0.5 , - 0.5 , 0 ) ) , 0xFFFFFFFF , 2 , 0.001 ) ;
fat_line ( V , cgi . emb - > logical_to_actual ( point31 ( 0.5 , 0.5 , 0 ) ) , V , cgi . emb - > logical_to_actual ( point31 ( - 0.5 , 0.5 , 0 ) ) , 0xFFFFFFFF , 2 , 0.001 ) ;
break ;
case ' u ' : {
2023-05-18 12:18:46 +00:00
if ( ! cgtrader_models ) break ;
2023-05-15 00:48:38 +00:00
if ( GDIM = = 3 & & with_models ) {
lily . render ( V ) ;
c - > item = itNone ;
}
else c - > item = itWet ;
break ;
}
case ' v ' : {
2023-05-18 12:18:46 +00:00
if ( ! cgtrader_models ) break ;
2023-05-15 00:48:38 +00:00
if ( GDIM = = 3 & & with_models ) duck . render ( V ) ;
else {
draw_shape ( V , { - 0.164988 , 0.0033671 , - 0.114197 , 0.0638159 , 0.0401905 , 0.063635 , 0.10735 , 0.0268375 , 0.10735 , - 0.0268375 , 0.0401905 , - 0.063635 , - 0.114197 , - 0.0638159 , - 0.164988 , - 0.0033671 , } , 0xC0C0C0FF , 2 ) ;
draw_shape ( V , { - 0.0753584 , 0.00669852 , - 0.111558 , 0.0184533 , - 0.0812589 , 0.0326711 , - 0.161669 , 0.0479953 , - 0.10074 , 0.0780737 , - 0.0184331 , 0.0896519 , 0.0830064 , 0.065399 , 0.113269 , 0.0335611 , 0.117466 , 0.0151028 , 0.117466 , - 0.0151028 , 0.113269 , - 0.0335611 , 0.0830064 , - 0.065399 , - 0.0184331 , - 0.0896519 , - 0.10074 , - 0.0780737 , - 0.161669 , - 0.0479953 , - 0.0812589 , - 0.0326711 , - 0.111558 , - 0.0184533 , - 0.0753584 , - 0.00669852 , } , 0x806010FF , 2 ) ;
draw_shape ( V , { 0.164139 , 0.0109426 , 0.200142 , 0.0185786 , 0.239985 , 0.00848005 , 0.239985 , - 0.00848005 , 0.200142 , - 0.0185786 , 0.164139 , - 0.0109426 , } , 0xE0E000FF , 2 ) ;
draw_shape ( V , { 0.0820785 , 0.00670028 , 0.0963908 , 0.0243072 , 0.121722 , 0.0352575 , 0.159071 , 0.0361908 , 0.183838 , 0.028672 , 0.199268 , 0.00844354 , 0.199268 , - 0.00844354 , 0.183838 , - 0.028672 , 0.159071 , - 0.0361908 , 0.121722 , - 0.0352575 , 0.0963908 , - 0.0243072 , 0.0820785 , - 0.00670 } , 0x106010FF , 2 ) ;
}
break ;
}
case ' B ' :
if ( GDIM = = 3 & & with_models ) bunny . render ( V ) ;
else {
auto V1 = V * spin270 ( ) ;
draw_shape ( V1 , { - 0.272437 , 0.00681093 , - 0.247911 , 0.0339604 , - 0.199391 , 0.0506926 , - 0.165034 , 0.0336804 , - 0.151363 , 0.0100908 , - 0.151363 , - 0.0100908 , - 0.165034 , - 0.0336804 , - 0.199391 , - 0.0506926 , - 0.247911 , - 0.0339604 , - 0.272437 , - 0.00681093 , } , 0xFFFFFFFF , 2 ) ;
draw_shape ( V1 , { - 0.209613 , 0.00676172 , - 0.161797 , 0.0741567 , - 0.107602 , 0.100877 , 0.0033535 , 0.103959 , 0.100724 , 0.0738645 , 0.134426 , 0.0369672 , 0.14796 , 0.00672545 , 0.14796 , - 0.00672545 , 0.134426 , - 0.0369672 , 0.100724 , - 0.0738645 , 0.0033535 , - 0.103959 , - 0.107602 , - 0.100877 , - 0.161797 , - 0.0741567 , - 0.209613 , - 0.00676172 , } , 0xC0C0C0FF , 2 ) ;
draw_shape ( V1 , { 0.0502023 , 0.0167341 , 0.0737312 , 0.0536227 , 0.151647 , 0.0876183 , 0.240969 , 0.0441211 , 0.272441 , 0.0102165 , 0.272441 , - 0.0102165 , 0.240969 , - 0.0441211 , 0.151647 , - 0.0876183 , 0.0737312 , - 0.0536227 , 0.0502023 , - 0.0167341 , } , 0xD0D0D0FF , 2 ) ;
draw_shape ( V1 , { 0.103977 , 0.0268328 , 0.0267753 , 0.0468568 , - 0.0536042 , 0.063655 , - 0.00335237 , 0.0972189 , 0.094003 , 0.080574 , 0.144678 , 0.0571982 , 0.154836 , 0.0437579 , 0.134405 , 0.0268809 , } , 0xC0C0C0FF , 2 ) ;
draw_shape ( V1 * MirrorY , { 0.103977 , 0.0268328 , 0.0267753 , 0.0468568 , - 0.0536042 , 0.063655 , - 0.00335237 , 0.0972189 , 0.094003 , 0.080574 , 0.144678 , 0.0571982 , 0.154836 , 0.0437579 , 0.134405 , 0.0268809 , } , 0xC0C0C0FF , 2 ) ;
draw_shape ( V1 , { 0.168425 , 0.0235794 , 0.178774 , 0.0505965 , 0.188982 , 0.0269974 , } , 0xC00000FF , 2 ) ;
draw_shape ( V1 * MirrorY , { 0.168425 , 0.0235794 , 0.178774 , 0.0505965 , 0.188982 , 0.0269974 , } , 0xC00000FF , 2 ) ;
}
break ;
case ' t ' :
2023-05-18 12:18:46 +00:00
if ( ! cgtrader_models ) break ;
2023-05-15 00:48:38 +00:00
if ( GDIM = = 2 ) c - > wall = waRoundTable ; else if ( with_models & & ! light_models ) {
c - > wall = waNone ;
table . render ( V ) ;
cheese . render ( V ) ;
coffee1 . render ( V ) ;
coffee2 . render ( V ) ;
}
break ;
case ' C ' :
if ( GDIM = = 3 & & with_models ) maxwellcat . render ( V ) ;
else {
dynamicval < bool > b ( mapeditor : : drawplayer , true ) ;
drawPlayer ( moPlayer , c , V * spin90 ( ) , 0xFFFFFFFF , 0 ) ;
}
if ( move_cat ) {
move_cat = false ;
mapeditor : : drawplayer = true ;
chr = ' . ' ;
cwt . at = c ;
vid . sspeed = - 5 ;
cwt . spin = 1 ;
vid . axes = 0 ;
}
break ;
case ' e ' :
2023-05-18 12:18:46 +00:00
if ( ! cgtrader_models ) break ;
2023-05-15 00:48:38 +00:00
if ( GDIM = = 3 & & draw_digger = = 2 ) digger . render ( V ) ;
break ;
case ' K ' : {
2023-05-18 12:18:46 +00:00
if ( ! cgtrader_models ) break ;
2023-05-15 00:48:38 +00:00
int a = gmod ( co . first + co . second , 3 ) ;
if ( GDIM = = 3 & & with_models ) {
2023-05-18 12:18:46 +00:00
auto gtulip = [ & ] ( int a , int b ) - > tulipmodel & { char ch = fixed_random_digits [ 5 * a + b ] ; if ( ch = = ' 0 ' ) return tulip ; if ( ch = = ' 1 ' ) return tulip1 ; if ( ch = = ' 2 ' ) return tulip2 ; return tulip2 ; } ;
2023-05-15 00:48:38 +00:00
gtulip ( a , 0 ) . render ( V ) ;
gtulip ( a , 1 ) . render ( V * cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( 1 / 3. , 1 / 3. , 0 ) ) ) ;
gtulip ( a , 2 ) . render ( V * cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( 1 / 3. , - 1 / 3. , 0 ) ) ) ;
gtulip ( a , 3 ) . render ( V * cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( - 1 / 3. , 1 / 3. , 0 ) ) ) ;
gtulip ( a , 4 ) . render ( V * cgi . emb - > intermediate_to_actual_translation ( cgi . emb - > logical_to_intermediate * point3 ( - 1 / 3. , - 1 / 3. , 0 ) ) ) ;
}
else {
vector < color_t > tcols = { 0xFFFF80FF , 0xFF1010FF , 0xC000C0FF } ;
draw_shape ( V * spin90 ( ) , { - 0.202738 , 0.0236527 , - 0.145213 , 0.135082 , - 0.0438177 , 0.1719 , 0.0708783 , 0.178883 , 0.220846 , 0.125712 , 0.120989 , 0.0705769 , 0.219991 , 0.00338448 , 0.219991 , - 0.00338448 , 0.120989 , - 0.0705769 , 0.220846 , - 0.125712 , 0.0708783 , - 0.178883 , - 0.0438177 , - 0.1719 , - 0.145213 , - 0.135082 , - 0.202738 , - 0.0236527 } , tcols [ a ] , 2 ) ;
}
break ;
}
case ' H ' :
if ( GDIM = = 3 ) draw_hedge ( V ) ;
else queuepoly ( V , cgi . shGem [ 0 ] , 0xFF00FF ) ;
break ;
case ' ^ ' : {
c - > wall = no_floor ? waChasm : waNone ;
auto ax = co . first - scaffoldx_move * 20 ;
auto ay = co . second - scaffoldy_move * 20 ;
if ( ax > = 0 & & ay > = 0 & & ax < 20 & & ay < 20 )
draw_scaffold ( V ) ;
break ;
}
case ' > ' :
c - > wall = draw_digger ? waChasm : waNone ;
break ;
}
if ( with_chess ) chess . get_split ( ) . render ( V , gmod ( co . first , 20 ) , gmod ( co . second , 20 ) ) ;
}
return false ;
}
ld fov , otanfov ;
void switch_fpp_fixed ( ) {
auto & cd = current_display ;
transmatrix tView ;
ld ys ;
tView = View ;
otanfov = ( cd - > xsize / 2 ) / cd - > radius * 2 ;
auto d = vid . depth ;
if ( GDIM = = 3 ) invoke_embed ( geom3 : : seNone ) ;
else {
invoke_embed ( geom3 : : seDefault ) ;
activate ( edefault ) ;
}
if ( GDIM = = 3 ) {
ld tfov = vid . fov * degree / 2 ;
cd - > tanfov = tan ( tfov ) ;
ld yshift = ( otanfov - vid . depth ) / cd - > tanfov ;
println ( hlog , " yshift = " , yshift , " from " , vid . yshift ) ;
View = Id ;
for ( int a = 0 ; a < 2 ; a + + )
for ( int b = 0 ; b < 2 ; b + + )
View [ a ] [ b ] = tView [ a ] [ b ] ;
for ( int a = 0 ; a < 2 ; a + + )
View [ a ] [ 3 ] = tView [ a ] [ 2 ] ;
println ( hlog , tie ( tView [ 2 ] [ 0 ] , tView [ 2 ] [ 1 ] ) ) ;
shift_view ( zpush0 ( yshift ) ) ;
playermoved = false ;
}
else {
pconf . camera_angle = 0 ;
vid . yshift = 0 ;
ys = tView [ 2 ] [ 3 ] ;
println ( hlog , " ys = " , ys , " from " , tView ) ;
otanfov = ys * cd - > tanfov + d ;
cd - > radius = cd - > xsize / otanfov ;
pconf . scale = cd - > radius / cd - > scrsize ;
}
if ( GDIM = = 2 ) {
View = spin90 ( ) * View ;
View [ 0 ] [ 2 ] = tView [ 0 ] [ 3 ] ;
View [ 1 ] [ 2 ] = tView [ 1 ] [ 3 ] ;
}
}
void load_anim ( string fname ) {
fhstream f ( fname , " r " ) ;
mapstream : : cellbyid = ac ;
while ( isize ( mapstream : : cellbyid ) < 400 * 400 ) for ( auto c : ac ) mapstream : : cellbyid . push_back ( c ) ;
smoothcam : : enable ( ) ;
smoothcam : : load_animation ( f ) ;
}
void append_anim ( string fname ) {
smoothcam : : backup ( ) ;
load_anim ( fname ) ;
smoothcam : : append_backup ( ) ;
}
void save_anim ( string fname ) {
fhstream f ( fname , " w " ) ;
for ( int i = 0 ; i < isize ( ac ) ; i + + ) mapstream : : cellids [ ac [ i ] ] = i ;
smoothcam : : save_animation ( f ) ;
}
void transition ( ld a , ld b , int frames ) {
anims : : noframes = frames ;
auto _edok = edok ( ) ;
auto cu = current ( ) ;
auto vn = glhr : : vnear_default ;
auto vf = glhr : : vfar_default ;
int lev = addHook ( anims : : hooks_anim , 100 , [ & ] {
ld t = ticks / anims : : period ;
println ( hlog , " transition, t = " , t ) ;
indenter ind ( 2 ) ;
t = t * t * ( 3 - 2 * t ) ;
t = lerp ( a , b , t ) ;
sightranges [ geometry ] = 50 * t ;
glhr : : vnear_default = vn * t ;
glhr : : vfar_default = vf * t ;
2023-05-18 12:18:46 +00:00
activate ( emb_lerp ( _edok , cu , t ) ) ;
2023-05-15 00:48:38 +00:00
} ) ;
anims : : record_video ( ) ;
delHook ( anims : : hooks_anim , lev ) ;
activate ( cu ) ;
sightranges [ geometry ] = 50 ;
glhr : : vnear_default = vn ;
glhr : : vfar_default = vf ;
}
void animate_forward ( ld d , int frames ) {
anims : : noframes = frames ;
ld lastt = 0 ;
int lev = addHook ( anims : : hooks_anim , 100 , [ & ] {
println ( hlog , " centerover is " , centerover ) ;
ld t = ticks / anims : : period ;
t = t * t * ( 3 - 2 * t ) ;
shift_view ( ztangent ( - ( t - lastt ) * d ) ) ;
lastt = t ;
spinEdge ( 100 ) ;
anims : : moved ( ) ;
} ) ;
anims : : record_video ( ) ;
delHook ( anims : : hooks_anim , lev ) ;
}
void transition_test ( ld t ) {
auto _edok = edok ( ) ;
auto cu = current ( ) ;
auto vn = glhr : : vnear_default ;
auto vf = glhr : : vfar_default ;
sightranges [ geometry ] = 50 * t ;
glhr : : vnear_default = vn * t ;
glhr : : vfar_default = vf * t ;
2023-05-18 12:18:46 +00:00
activate ( emb_lerp ( _edok , cu , t ) ) ;
2023-05-15 00:48:38 +00:00
}
void embset_list ( ) {
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
dialog : : init ( XLAT ( " embset list " ) , 0xFFFFFFFF , 150 , 0 ) ;
dialog : : start_list ( 900 , 900 , ' 1 ' ) ;
for ( auto & e : embsets ) {
dialog : : addItem ( e . name , dialog : : list_fake_key + + ) ;
dialog : : add_action ( [ & e ] { activate ( e ) ; } ) ;
}
dialog : : end_list ( ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
void look_downwards ( ) {
transmatrix T = View ;
if ( GDIM = = 3 ) {
for ( int i = 0 ; i < 3 ; i + + ) T [ i ] [ 3 ] = T [ 3 ] [ i ] = 0 ;
rotate_view ( inverse ( T ) ) ;
ld x = T [ 3 ] [ 0 ] , y = T [ 3 ] [ 1 ] ;
shift_view ( point31 ( x + .5 , y + .5 , 0 ) ) ;
}
else {
for ( int i = 0 ; i < 2 ; i + + ) T [ i ] [ 2 ] = T [ 2 ] [ i ] = 0 ;
rotate_view ( inverse ( T ) ) ;
}
}
color_t domcol = 0xf8dba0 ;
color_t domcolf = 0x785b20 ;
color_t domroof = 0x802020 ;
color_t our_skycolor ( cell * c ) {
auto co = euc : : full_coords2 ( c ) ;
ld x = co . first * TAU / 20 ;
ld y = co . second * TAU / 20 ;
ld p = sin ( x + 2 * y ) + cos ( 3 * x - y ) + sin ( x ) ;
return gradient ( 0x4040FF , 0xFFFFFF , - 3 , p , 3 ) ;
}
bool chess_ceiling ( celldrawer * cw ) {
auto co = euc : : full_coords2 ( cw - > c ) ;
if ( co = = gp : : loc { 0 , 0 } )
draw_star ( cw - > V , cgi . shSun , 0xFFFF00FF ) ;
2023-05-18 12:18:46 +00:00
if ( house2 . count ( cw - > c ) ) {
2023-05-15 00:48:38 +00:00
color_t col = ( domcol < < 8 ) | 0xFF ;
color_t wcol1 = ( gradient ( 0 , domcol , 0 , .9 , 1 ) < < 8 ) | 0xFF ;
color_t wcol2 = ( gradient ( 0 , domcol , 0 , .8 , 1 ) < < 8 ) | 0xFF ;
2023-05-18 12:18:46 +00:00
if ( house1 . count ( cw - > c ) ) forCellIdEx ( c2 , i , cw - > c ) if ( ! house1 . count ( c2 ) ) {
2023-05-15 00:48:38 +00:00
placeSidewall ( cw - > c , i , SIDE_HIGH , cw - > V , ( i & 1 ) ? wcol1 : wcol2 ) ;
placeSidewall ( cw - > c , i , SIDE_HIGH2 , cw - > V , ( i & 1 ) ? wcol1 : wcol2 ) ;
}
2023-05-18 12:18:46 +00:00
forCellIdEx ( c2 , i , cw - > c ) if ( ! house2 . count ( c2 ) ) {
2023-05-15 00:48:38 +00:00
placeSidewall ( cw - > c , i , SIDE_HIGH2 , cw - > V , ( i & 1 ) ? wcol1 : wcol2 ) ;
}
2023-05-18 12:18:46 +00:00
if ( house1 . count ( cw - > c ) ! = house2 . count ( cw - > c ) )
2023-05-15 00:48:38 +00:00
draw_shapevec ( cw - > c , cw - > V , qfi . fshape - > levels [ SIDE_HIGH ] , col , PPR : : REDWALL ) ;
2023-05-18 12:18:46 +00:00
if ( house2 . count ( cw - > c ) )
2023-05-15 00:48:38 +00:00
draw_shapevec ( cw - > c , cw - > V , qfi . fshape - > levels [ SIDE_HIGH2 ] , ( domroof < < 8 ) | 0xFF , PPR : : REDWALL ) ;
auto co = euc : : full_coords2 ( cw - > c ) ;
int x = gmod ( co . first , 20 ) ;
int y = gmod ( co . second , 20 ) ;
char ch = xmap [ y ] [ x ] ;
if ( ch = = ' O ' ) {
placeSidewall ( cw - > c , 1 , SIDE_HIGH , cw - > V , 0xC0E0FFC0 ) ;
( ( dqi_poly & ) ( * ptds . back ( ) ) ) . tinf = nullptr ;
}
}
color_t skycol = our_skycolor ( cw - > c ) ;
g_add_to_sky ( cw - > c , cw - > V , skycol , skycol ) ;
return true ;
}
int cells_drawn = 50 , split_qty = 1 ;
void build_map ( ) {
for ( cell * c : bac ) {
c - > land = laCanvas ;
c - > wall = waNone ; // Chasm; // waNone;
c - > item = itNone ;
c - > monst = moNone ;
c - > mpdist = 0 ;
c - > landparam = 0x205020 ;
auto co = euc : : full_coords2 ( c ) ;
int x = gmod ( co . first , 20 ) ;
int y = gmod ( co . second , 20 ) ;
ac [ x + 20 * y + gmod ( gdiv ( co . first , 20 ) , periods ) * 400 + gmod ( gdiv ( co . second , 20 ) , periods ) * 400 * periods ] = c ;
char ch = xmap [ y ] [ x ] ;
switch ( ch ) {
case ' x ' :
c - > landparam = ( ( x + y ) & 1 ) ? 0x807020 : 0xFFE080 ;
break ;
case ' 1 ' :
c - > wall = waRed3 ;
2023-05-18 12:18:46 +00:00
house2 . insert ( c ) ;
2023-05-15 00:48:38 +00:00
c - > landparam = domcol ;
break ;
case ' 2 ' :
c - > wall = waRed2 ;
break ;
case ' 3 ' :
c - > wall = waRed3 ;
break ;
case ' # ' :
c - > wall = waBarrier ;
break ;
case ' T ' :
c - > wall = waCTree ;
break ;
case ' D ' :
c - > wall = waWaxWall ;
2023-05-18 12:18:46 +00:00
house1 . insert ( c ) ;
house2 . insert ( c ) ;
2023-05-15 00:48:38 +00:00
c - > landparam = domcol ;
break ;
case ' t ' :
case ' r ' :
case ' d ' :
c - > wall = waNone ;
2023-05-18 12:18:46 +00:00
house2 . insert ( c ) ;
2023-05-15 00:48:38 +00:00
c - > landparam = domcolf ;
break ;
case ' + ' :
c - > wall = waNone ;
2023-05-18 12:18:46 +00:00
house2 . insert ( c ) ;
2023-05-15 00:48:38 +00:00
c - > landparam = domcol ;
break ;
case ' O ' :
c - > wall = waWaxWall ;
2023-05-18 12:18:46 +00:00
house2 . insert ( c ) ;
2023-05-15 00:48:38 +00:00
c - > landparam = domcol ;
break ;
case ' u ' :
case ' v ' :
case ' ~ ' :
c - > wall = waShallow ;
break ;
case ' p ' :
c - > land = laCrossroads ;
floorcolors [ laCrossroads ] = 0x808080 ;
break ;
// c->landparam = 0xC0C080;
case ' > ' :
if ( draw_digger ) c - > wall = waChasm ;
break ;
}
}
}
2023-05-18 12:18:46 +00:00
ld square_diagram_size = 1000 ;
2023-05-15 00:48:38 +00:00
2023-05-18 12:18:46 +00:00
void enable_square_diagram ( ) {
rogueviz : : rv_hook ( hooks_frame , 100 , [ ] {
if ( square_diagram_size > = 1000 ) return ;
auto p = [ ] ( ld x , ld y ) { return hpxy ( x , y ) ; } ;
for ( int i = 0 ; i < 4 ; i + + ) {
ld si = square_diagram_size ;
ld big = 100 ;
curvepoint ( p ( si , big ) ) ;
curvepoint ( p ( si , - big ) ) ;
curvepoint ( p ( big , - big ) ) ;
curvepoint ( p ( big , big ) ) ;
curvepoint ( p ( si , big ) ) ;
queuecurve ( shiftless ( Id ) * cspin ( 0 , 1 , i * 90. _deg ) , 0 , 0xFF , PPR : : CIRCLE ) . flags | = POLY_ALWAYS_IN ;
}
} ) ;
}
bool activated = false ;
void o_key ( o_funcs & v ) ;
void enable ( ) {
if ( activated ) return ;
tour : : slide_backup ( activated , true ) ;
if ( ! params . count ( " square_diagram_size " ) ) param_f ( square_diagram_size , " square_diagram_size " ) ;
2023-05-15 00:48:38 +00:00
stop_game ( ) ;
2023-05-18 12:18:46 +00:00
tour : : slide_backup ( never_invert , true ) ;
tour : : slide_backup ( vid . wallmode , 3 ) ;
tour : : slide_backup ( vid . monmode , 2 ) ;
2023-05-15 00:48:38 +00:00
geometry = gArchimedean ;
variation = eVariation : : pure ;
arcm : : current . parse ( " 4^5 " ) ;
start_game ( ) ;
resetview ( ) ;
View = spin ( 45. _deg ) ;
if ( 1 ) {
dynamicval < int > d ( min_cells_drawn , cells_drawn ) ;
// vid.cells_generated_limit = 9999;
// vid.cells_drawn_limit = 9999;
// vid.use_smart_range = 2;
drawthemap ( ) ;
}
auto f = [ ] ( hyperpoint h ) { return deparabolic13 ( h ) ; } ;
set < cell * > seen ;
for ( auto c : dcal ) if ( gmatrix . count ( c ) ) {
map54_nodes . push_back ( f ( unshift ( gmatrix [ c ] * C0 ) ) ) ;
seen . insert ( c ) ;
}
for ( auto c : dcal ) if ( seen . count ( c ) ) forCellEx ( c1 , c ) if ( seen . count ( c1 ) ) if ( c1 < c ) {
auto h = unshift ( gmatrix [ c ] * C0 ) ;
auto h1 = unshift ( gmatrix [ c1 ] * C0 ) ;
int qty = split_qty ;
vector < hyperpoint > hs ( qty + 1 ) ;
hs [ 0 ] = h ; hs [ qty ] = h1 ;
for ( int a = qty / 2 ; a ; a / = 2 ) for ( int i = 0 ; i < qty ; i + = a * 2 ) hs [ i + a ] = mid ( hs [ i ] , hs [ i + 2 * a ] ) ;
for ( int i = 0 ; i < = qty ; i + + ) hs [ i ] = f ( hs [ i ] ) ;
for ( int i = 0 ; i < qty ; i + + ) map54_edges . emplace_back ( hs [ i ] , hs [ i + 1 ] ) ;
}
println ( hlog , " map54: nodes = " , isize ( map54_nodes ) , " edges = " , isize ( map54_edges ) ) ;
stop_game ( ) ;
geometry = gSpace435 ;
start_game ( ) ;
resetview ( ) ;
if ( 1 ) {
dynamicval < int > d ( min_cells_drawn , 500 ) ;
drawthemap ( ) ;
bfs ( ) ;
println ( hlog , " dcal size = " , isize ( dcal ) , " size map = " , isize ( gmatrix ) ) ;
}
seen . clear ( ) ;
for ( auto c : dcal ) if ( gmatrix . count ( c ) ) {
map534_nodes . push_back ( unshift ( gmatrix [ c ] * C0 ) ) ;
seen . insert ( c ) ;
}
for ( auto c : dcal ) if ( seen . count ( c ) ) forCellEx ( c1 , c ) if ( seen . count ( c1 ) ) if ( c1 < c ) {
map534_edges . emplace_back ( unshift ( gmatrix [ c ] ) * C0 , unshift ( gmatrix [ c1 ] ) * C0 ) ;
}
stop_game ( ) ;
// vid.cells_drawn_limit = 400;
if ( ! floor_textures ) make_floor_textures ( ) ;
auto & T0 = euc : : eu_input . user_axes ;
T0 [ 0 ] [ 0 ] = 20 * periods ;
T0 [ 1 ] [ 1 ] = 20 * periods ;
euc : : eu_input . twisted = 0 ;
T0 [ 0 ] [ 1 ] = 0 ;
T0 [ 1 ] [ 0 ] = 0 ;
euc : : build_torus3 ( ) ;
geometry = gEuclidSquare ;
variation = eVariation : : pure ;
start_game ( ) ;
bac = currentmap - > allcells ( ) ;
ac . resize ( bac . size ( ) ) ;
build_map ( ) ;
rogueviz : : rv_hook ( hooks_drawcell , 100 , draw_chess_at ) ;
// rogueviz::rv_hook(hooks_frame, 100, [] { restart = true; });
rogueviz : : rv_hook ( hooks_ceiling , 100 , chess_ceiling ) ;
rogueviz : : rv_hook ( hooks_o_key , 80 , o_key ) ;
rogueviz : : rv_hook ( hooks_handleKey , 101 , [ ] ( int sym , int uni ) {
if ( ( cmode & sm : : NORMAL ) & & uni = = ' t ' ) {
vid . sspeed = 0 ;
playermoved = true ;
fix_whichcopy ( cwt . at ) ;
// game_keys_scroll = true;
return true ;
}
return false ;
} ) ;
2023-05-18 12:18:46 +00:00
tour : : slide_backup ( frustum_culling , false ) ;
tour : : slide_backup ( game_keys_scroll , true ) ;
tour : : slide_backup ( bright , true ) ;
tour : : slide_backup ( draw_sky , skyAlways ) ;
tour : : slide_backup ( vid . cells_generated_limit , 999999 ) ;
tour : : slide_backup ( noshadow , true ) ;
tour : : slide_backup ( auto_remove_roofs , false ) ;
tour : : slide_backup ( vid . lake_top , 0.2 ) ;
tour : : slide_backup ( simple_sky , true ) ;
}
void show ( ) {
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
dialog : : init ( XLAT ( " embchess " ) , 0xFFFFFFFF , 150 , 0 ) ;
if ( true ) {
dialog : : addItem ( " 2D to 3D " , ' a ' ) ;
dialog : : add_action ( switch_fpp_fixed ) ;
dialog : : addItem ( " look downwards " , ' l ' ) ;
dialog : : add_action ( look_downwards ) ;
}
if ( true ) {
dialog : : addItem ( " save smoothcam animation " , ' s ' ) ;
dialog : : add_action ( [ ] { save_anim ( " emb/animation.sav " ) ; } ) ;
}
if ( true ) {
dialog : : addItem ( " load smoothcam animation " , ' l ' ) ;
dialog : : add_action ( [ ] { load_anim ( " emb/animation.sav " ) ; } ) ;
}
if ( true ) {
dialog : : addItem ( " create smoothcam animation " , ' c ' ) ;
dialog : : add_action ( [ ] { smoothcam : : enable_and_show ( ) ; } ) ;
}
if ( true ) {
dialog : : addBoolItem ( " run the animation " , smoothcam : : animate_on , ' r ' ) ;
dialog : : add_action ( [ ] {
smoothcam : : animate_on = ! smoothcam : : animate_on ;
smoothcam : : last_time = HUGE_VAL ;
} ) ;
}
if ( true ) {
dialog : : addBoolItem ( " animation T0 " , false , ' a ' ) ;
dialog : : add_action ( [ ] { smoothcam : : animate_on = false ; smoothcam : : handle_animation ( 0 ) ; } ) ;
dialog : : addBoolItem ( " animation T1 " , false , ' b ' ) ;
dialog : : add_action ( [ ] { smoothcam : : animate_on = false ; smoothcam : : handle_animation ( 1 - 1e-7 ) ; } ) ;
}
if ( true ) {
dialog : : addSelItem ( " invert walls " , fts ( vid . wall_height ) , ' i ' ) ;
dialog : : add_action ( [ ] {
auto cur = current ( ) ;
cur . walls = - cur . walls ;
activate ( cur ) ;
} ) ;
}
if ( true ) {
dialog : : addSelItem ( " closer to default " , fts ( geom3 : : euclid_embed_scale ) , ' [ ' ) ;
dialog : : add_action ( [ ] {
activate ( emb_lerp ( edok ( ) , current ( ) , .99 ) ) ;
} ) ;
dialog : : addSelItem ( " further from default " , fts ( geom3 : : euclid_embed_scale ) , ' ] ' ) ;
dialog : : add_action ( [ ] {
activate ( emb_lerp ( edok ( ) , current ( ) , 1.01 ) ) ;
} ) ;
}
if ( true ) {
dialog : : addItem ( " embset list " , ' e ' ) ;
dialog : : add_action_push ( embset_list ) ;
}
if ( true ) {
dialog : : addItem ( " print embset " , ' p ' ) ;
dialog : : add_action ( [ ] {
embset e = current ( ) ;
println ( hlog , e ) ;
} ) ;
}
if ( false ) {
dialog : : addItem ( " transition to " , ' u ' ) ;
dialog : : add_action ( [ ] { anims : : videofile = " transition_to.mp4 " ; transition ( 0.01 , 1 , 60 ) ; } ) ;
}
if ( false ) {
dialog : : addItem ( " transition from " , ' i ' ) ;
dialog : : add_action ( [ ] { anims : : videofile = " transition_from.mp4 " ; transition ( 1 , 0.01 , 60 ) ; } ) ;
}
if ( true ) {
static ld dist = 0 ;
dialog : : addSelItem ( " measure forward distance " , fts ( dist ) , ' f ' ) ;
dialog : : add_action ( [ ] {
shift_view ( ztangent ( - 0.2 ) ) ;
spinEdge ( 100 ) ;
dist + = 0.2 ;
} ) ;
dialog : : addSelItem ( " go backward " , fts ( dist ) , ' b ' ) ;
dialog : : add_action ( [ ] {
shift_view ( ztangent ( + 0.05 ) ) ;
spinEdge ( 100 ) ;
dist + = - 0.05 ;
} ) ;
}
if ( true ) {
dialog : : addItem ( " low range " , ' r ' ) ;
dialog : : add_action ( [ ] { vid . cells_drawn_limit = 400 ; delete_sky ( ) ; } ) ;
dialog : : addItem ( " mid range " , ' t ' ) ;
dialog : : add_action ( [ ] { vid . cells_drawn_limit = 2000 ; delete_sky ( ) ; } ) ;
dialog : : addItem ( " high range " , ' y ' ) ;
dialog : : add_action ( [ ] { vid . cells_drawn_limit = 20000 ; delete_sky ( ) ; } ) ;
dialog : : addItem ( " extreme range " , ' u ' ) ;
dialog : : add_action ( [ ] { vid . cells_drawn_limit = 200000 ; delete_sky ( ) ; } ) ;
dialog : : addBoolItem_action ( " with models " , with_models , ' m ' ) ;
dialog : : addBoolItem_action ( " with chess " , with_chess , ' h ' ) ;
dialog : : addSelItem ( " draw the digger " , its ( draw_digger ) , ' g ' ) ;
dialog : : add_action ( [ ] { draw_digger = ( 1 + draw_digger ) % 3 ; } ) ;
}
if ( true ) {
dialog : : addSelItem ( " scaffolding X " , its ( scaffoldx ) , ' X ' ) ;
dialog : : add_action ( [ ] { scaffoldx = ( 1 + scaffoldx ) % 3 ; } ) ;
dialog : : addSelItem ( " scaffolding Y " , its ( scaffoldy ) , ' Y ' ) ;
dialog : : add_action ( [ ] { scaffoldy = ( 1 + scaffoldy ) % 3 ; } ) ;
dialog : : addSelItem ( " scaffolding B " , its ( scaffoldb ) , ' B ' ) ;
dialog : : add_action ( [ ] { scaffoldb = ( 1 + scaffoldb ) % 3 ; } ) ;
dialog : : addSelItem ( " no floor " , ONOFF ( no_floor ) , ' < ' ) ;
dialog : : add_action ( [ ] { no_floor = ! no_floor ; mapeditor : : drawplayer = false ; build_map ( ) ; } ) ;
}
dialog : : addBoolItem ( " move the cat " , mapeditor : : drawplayer , ' d ' ) ;
dialog : : add_action ( [ ] {
move_cat = true ;
game_keys_scroll = false ;
} ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
2023-05-15 00:48:38 +00:00
2023-05-18 12:18:46 +00:00
void o_key ( o_funcs & v ) {
v . push_back ( named_dialog ( " embchess options " , show ) ) ;
2023-05-15 00:48:38 +00:00
}
struct solv_grapher : rogueviz : : pres : : grapher {
solv_grapher ( transmatrix U ) : grapher ( - 2 , - 2 , 12 , 12 ) {
T = T * U ;
using rogueviz : : pres : : p2 ;
for ( int x = - 1 ; x < = 11 ; x + + ) if ( x ) {
line ( p2 ( x , - 2 ) , p2 ( x , 12 ) , 0x8080FFFF ) ;
line ( p2 ( - 2 , x ) , p2 ( 12 , x ) , 0x8080FFFF ) ;
}
vid . linewidth * = 2 ;
arrow ( p2 ( 0 , - 2 ) , p2 ( 0 , 12 ) , .5 ) ;
arrow ( p2 ( - 2 , 0 ) , p2 ( 12 , 0 ) , .5 ) ;
vid . linewidth / = 2 ;
}
} ;
ld geo_zero ;
transmatrix xyzscale ( ld x ) {
transmatrix T = Id ;
T [ 0 ] [ 0 ] = T [ 1 ] [ 1 ] = T [ 2 ] [ 2 ] = x ;
return T ;
}
transmatrix solvscale ( ld x ) {
transmatrix T = Id ;
T [ 0 ] [ 0 ] * = exp ( - x ) ;
T [ 1 ] [ 1 ] * = exp ( x ) ;
return T ;
}
ld geodesic_t = 0 ;
void geodesic_screen ( tour : : presmode mode , int id ) {
if ( ! params . count ( " geodesic_t " ) ) param_f ( geodesic_t , " geodesic_t " ) ;
using namespace rogueviz : : pres ;
if ( mode = = pmStart ) geo_zero = ticks ;
use_angledir ( mode , id = = 0 ) ;
static hyperpoint start , middle , target , nlh , nlh1 , nlh2 ;
const ld coord = 10 ;
setCanvas ( mode , ' 0 ' ) ;
if ( mode = = pmStart ) {
slide_backup ( pmodel ) ;
slide_backup ( pconf . clip_min ) ;
slide_backup ( pconf . clip_max ) ;
slide_backup ( vid . cells_drawn_limit ) ;
stop_game ( ) , pmodel = mdHorocyclic , geometry = gCubeTiling , variation = eVariation : : pure , pconf . clip_min = - 10000 , pconf . clip_max = + 100 , start_game ( ) ;
dynamicval < eGeometry > dg ( geometry , gSol ) ;
dynamicval < int > dr ( nisot : : rk_steps , 500 ) ;
ld x = coord ;
start = C0 ;
middle = point31 ( 0 , x , 0 ) ;
auto bmiddle = point31 ( x , 0 , 0 ) ;
target = point31 ( x , x , 0 ) ;
nlh = inverse_exp_newton ( target , 200 ) ;
nlh [ 2 ] * = - 1 ;
println ( hlog , " best newton: " , hypot_d ( 3 , nlh ) , " via " , nlh , " result " , nisot : : numerical_exp ( nlh ) ) ;
nlh1 = inverse_exp ( shiftless ( middle ) ) ;
nlh2 = inverse_exp ( shiftless ( bmiddle ) ) ;
println ( hlog , " intermediate: " , hypot_d ( 3 , nlh1 ) * 2 , " via " , nlh1 ) ;
println ( hlog , " Pythagoras: " , x * sqrt ( 2 ) ) ;
}
add_stat ( mode , [ id , coord ] {
cmode | = sm : : SIDE ;
calcparam ( ) ;
vid . cells_drawn_limit = 0 ;
drawthemap ( ) ;
// flat_model_enabler fme;
initquickqueue ( ) ;
solv_grapher g ( MirrorZ * ypush ( 5 * angle / 90. _deg ) * cspin ( 1 , 2 , .9 * angle / 90. _deg ) * spin ( angle / 2 ) * xyzscale ( lerp ( 1 , 0.8 , angle / 90. _deg ) ) ) ;
ld maxtime = 10 * sqrt ( 2 ) + 5 ;
auto frac_of = [ & ] ( ld t , ld z ) { return t - z * floor ( t / z ) ; } ;
ld t = inHighQual ? geodesic_t : frac_of ( ( ticks - geo_zero ) / 500 , maxtime ) ;
auto draw_path = [ & ] ( auto f , color_t col ) {
vid . linewidth * = 10 ;
for ( ld t = 0 ; t < = maxtime ; t + = 1 / 16. ) curvepoint ( f ( t ) ) ;
queuecurve ( g . T , col , 0 , PPR : : LINE ) ;
auto be_shadow = [ & ] ( hyperpoint & h ) {
// ld part = 1 - angle / 90._deg;
// h[0] += h[2] * part / 10;
h [ 2 ] = 0 ;
} ;
for ( ld t = 0 ; t < = 25 ; t + = 1 / 16. ) {
hyperpoint h = f ( t ) ;
be_shadow ( h ) ;
curvepoint ( h ) ;
}
queuecurve ( g . T , col & 0xFFFFFF40 , 0 , PPR : : LINE ) ;
vid . linewidth / = 10 ;
hyperpoint eaglepos = f ( t ) ;
hyperpoint next_eaglepos = f ( t + 1e-2 ) ;
auto z = eaglepos [ 2 ] ;
// queuepolyat(g.pos(x+z * .1,y,1.5) * spin(s), cgi.shEagle, 0x40, PPR::MONSTER_SHADOW).outline = 0;
drawMonsterType ( moEagle , nullptr , g . T * eupush ( eaglepos ) * solvscale ( z ) * rspintox ( next_eaglepos - eaglepos ) * xyzscale ( 2 ) , col > > 8 , t , 0 ) ;
be_shadow ( eaglepos ) ;
be_shadow ( next_eaglepos ) ;
auto & bp = cgi . shEagle ;
if ( bp . she > bp . shs & & bp . she < bp . shs + 1000 ) {
auto & p = queuepolyat ( g . T * eupush ( eaglepos ) * solvscale ( z ) * rspintox ( next_eaglepos - eaglepos ) * xyzscale ( 2 ) , bp , 0x18 , PPR : : TRANSPARENT_SHADOW ) ;
p . outline = 0 ;
p . subprio = - 100 ;
p . offset = bp . shs ;
p . cnt = bp . she - bp . shs ;
p . flags & = ~ POLY_TRIANGLES ;
p . tinf = NULL ;
return ;
}
} ;
color_t pythagoras = 0xcd7f32FF ;
color_t hyperb = 0xaaa9adFF ;
color_t solv = 0xFFD500FF ;
write_in_space ( g . T * rgpushxto0 ( point31 ( - .5 , - .5 , 1 ) ) * MirrorY * zpush ( - 1 ) , 72 , 1 , " A " , 0xFF ) ;
write_in_space ( g . T * rgpushxto0 ( point31 ( coord + .5 , coord + .5 , 1 ) ) * MirrorY * zpush ( - 1 ) , 72 , 1 , " B " , 0xFF ) ;
if ( id > = 1 ) write_in_space ( g . T * rgpushxto0 ( point31 ( 0 , coord + .5 , 1 ) ) * MirrorY * zpush ( - 1 ) , 72 , 1 , " C " , 0xFF ) ;
if ( id > = 0 )
draw_path ( [ & ] ( ld t ) { return t < coord * sqrt ( 2 ) ? point31 ( t / sqrt ( 2 ) , t / sqrt ( 2 ) , 0 ) : target ; } , pythagoras ) ;
if ( id > = 1 )
draw_path ( [ & ] ( ld t ) {
ld len = hypot_d ( 3 , nlh1 ) ;
dynamicval < eGeometry > g ( geometry , gSol ) ;
if ( t < len )
return nisot : : numerical_exp ( nlh1 * t / len ) ;
else if ( t < len * 2 )
return rgpushxto0 ( middle ) * nisot : : numerical_exp ( nlh2 * ( t - len ) / len ) ;
else return target ;
} , hyperb ) ;
if ( id > = 2 )
draw_path ( [ & ] ( ld t ) {
ld len = hypot_d ( 3 , nlh ) ;
dynamicval < eGeometry > g ( geometry , gSol ) ;
if ( t < len )
return nisot : : numerical_exp ( nlh * t / len ) ;
else
return target ;
} , solv ) ;
auto cat = [ ] ( PPR x ) {
if ( x = = PPR : : MONSTER_SHADOW ) return 1 ;
else if ( x = = PPR : : MONSTER_BODY ) return 2 ;
else return 0 ;
} ;
for ( int i = 1 ; i < isize ( ptds ) ; )
if ( i & & cat ( ptds [ i ] - > prio ) < cat ( ptds [ i - 1 ] - > prio ) ) {
swap ( ptds [ i ] , ptds [ i - 1 ] ) ;
i - - ;
}
else i + + ;
quickqueue ( ) ;
dialog : : init ( ) ;
dialog_may_latex ( " \\ textsf{from $(0,0,0)$ to $(10,10,0)$} " , " from (0,0,0) to (10,10,0) " , forecolor , 150 ) ;
dialog : : addBreak ( 100 ) ;
dialog_may_latex ( " \\ textsf{XY plane} " , " XY plane " , pythagoras > > 8 ) ;
dialog_may_latex ( " \\ textsf{$ " + fts ( coord ) + " \\ sqrt{2}$ (Pythagoras)} " , fts ( coord ) + " √2 (Pythagoras) " , pythagoras > > 8 ) ;
ld len = coord * sqrt ( 2 ) ;
dialog_may_latex ( " \\ textsf{$ " + fts ( len ) + " $} " , fts ( len ) , pythagoras > > 8 ) ;
if ( id > = 1 ) {
dialog : : addBreak ( 100 ) ;
dialog_may_latex ( " \\ textsf{YZ + XZ} " , " YZ + XZ " , hyperb > > 8 ) ;
dialog_may_latex ( " \\ textsf{hyperbolic geodesics} " , " hyperbolic geodesics " , hyperb > > 8 ) ;
ld len = 2 * hypot_d ( 3 , nlh1 ) ;
dialog_may_latex ( " \\ textsf{$ " + fts ( len ) + " $} " , fts ( len ) , hyperb > > 8 ) ;
}
else dialog : : addBreak ( 300 ) ;
if ( id > = 2 ) {
dialog : : addBreak ( 100 ) ;
dialog_may_latex ( " \\ textsf{optimal} " , " optimal " , solv > > 8 ) ;
dialog_may_latex ( " \\ textsf{no sharp bends} " , " no sharp bends " , solv > > 8 ) ;
ld len = hypot_d ( 3 , nlh ) ;
dialog_may_latex ( " \\ textsf{$ " + fts ( len ) + " $} " , fts ( len ) , solv > > 8 ) ;
}
else dialog : : addBreak ( 300 ) ;
dialog : : display ( ) ;
return false ;
} ) ;
}
using namespace rogueviz : : pres ;
string defs =
" \\ def \\ map{m} "
" \\ def \\ VofH{V} "
" \\ def \\ dist{ \\ delta} "
" \\ def \\ ra{ \\ rightarrow} "
" \\ def \\ bbH{ \\ mathbb{H}} "
" \\ def \\ bbE{ \\ mathbb{E}} "
" \\ renewcommand{ \\ rmdefault}{ \\ sfdefault} \\ sf "
;
2023-05-18 12:18:46 +00:00
void act_or_config ( ) {
if ( activated ) pushScreen ( show ) ;
else enable ( ) ;
}
slide embchess_slides [ ] = {
{ " 3D world " , 999 , LEGAL : : NONE | QUICKGEO | QUICKSKIP | USE_SLIDE_NAME ,
" This is the world from our YouTube video 'Non-Euclidean Third Dimension'. "
" You can activate it by pressing '5', and then press '5' again "
" to access various options. The next slides are slides from that video. \n \n " ,
[ ] ( presmode mode ) {
setCanvas ( mode , ' 0 ' ) ;
slide_url ( mode , ' y ' , " YouTube link " , " https://youtu.be/Rhjv_PazzZE " ) ;
slide_action ( mode , ' a ' , " activate / configure " , act_or_config ) ;
if ( mode = = pmKey ) act_or_config ( ) ;
} } ,
{ " Euler's polyhedron formula " , 999 , LEGAL : : NONE | QUICKGEO | USE_SLIDE_NAME | NOTITLE ,
" This is a proof that a sphere cannot be tiled with squares. " ,
[ ] ( presmode mode ) {
latex_slide ( mode , defs + R " =(
{ \ color { remph } Euler ' s polyhedron formula : }
\ begin { itemize }
\ item $ F + V - E = 2 $
\ item $ F $ - - the number of { \ color { remph } faces } ( square grid : the number of squares $ n $ )
\ item $ V $ - - the number of { \ color { remph } vertices } ( square grid : also $ n $ )
\ item $ E $ - - the number of { \ color { remph } edges } ( square grid : $ 2 n $ )
\ item $ F + V - E = n + n - 2 n = 0 = 2 $
\ end { itemize }
) = " , sm::NOSCR, 150);
} } ,
2023-05-15 00:48:38 +00:00
{ " from A to B in Solv 1 " , 999 , LEGAL : : NONE | QUICKGEO | NOTITLE ,
2023-05-18 12:18:46 +00:00
" How to get from A to B in Solv as quickly as possible? The first attempt is to do so without leaving the plane. Since the XY plane in Solv has Euclidean geometry, we can compute the length of such a path using the Pythagoras theorem. "
" Press '5' to switch to the 3D view. "
2023-05-15 00:48:38 +00:00
,
[ ] ( presmode mode ) {
println ( hlog , " A mode " , int ( mode ) ) ;
empty_screen ( mode ) ;
geodesic_screen ( mode , 0 ) ;
no_other_hud ( mode ) ;
}
} ,
{ " from A to B in Solv 2 " , 999 , LEGAL : : NONE | QUICKGEO | NOTITLE ,
2023-05-18 12:18:46 +00:00
" But we can do it faster like this, using two hyperbolic geodesics. "
2023-05-15 00:48:38 +00:00
,
[ ] ( presmode mode ) {
println ( hlog , " B mode " , int ( mode ) ) ;
empty_screen ( mode ) ;
geodesic_screen ( mode , 1 ) ;
no_other_hud ( mode ) ;
}
} ,
{ " from A to B in Solv 3 " , 999 , LEGAL : : NONE | QUICKGEO | NOTITLE ,
2023-05-18 12:18:46 +00:00
" And even faster, do it like this, avoiding sharp bends. "
2023-05-15 00:48:38 +00:00
,
[ ] ( presmode mode ) {
println ( hlog , " C mode " , int ( mode ) ) ;
empty_screen ( mode ) ;
geodesic_screen ( mode , 2 ) ;
no_other_hud ( mode ) ;
}
} ,
{ " final slide " , 123 , LEGAL : : ANY | NOTITLE | QUICKSKIP | FINALSLIDE ,
2023-05-18 12:18:46 +00:00
" End of the presentation. " ,
2023-05-15 00:48:38 +00:00
2023-05-18 12:18:46 +00:00
[ ] ( presmode mode ) { }
2023-05-15 00:48:38 +00:00
} ,
} ;
auto embchess_ah =
2023-05-18 12:18:46 +00:00
/* enable this unit */
2023-05-15 00:48:38 +00:00
arg : : add3 ( " -embchess " , enable )
+ arg : : add3 ( " -embperiods " , [ ] { arg : : shift ( ) ; periods = arg : : argi ( ) ; } )
+ arg : : add3 ( " -emb-noceil " , [ ] {
rogueviz : : rv_hook ( hooks_ceiling , 100 , [ ] ( celldrawer * ) { return true ; } ) ;
} )
+ arg : : add3 ( " -chessmul " , [ ] { arg : : shift ( ) ; hmul = arg : : argf ( ) ; } )
+ arg : : add3 ( " -embset " , [ ] {
arg : : shift ( ) ; string ss = arg : : args ( ) ;
for ( auto & e : embsets ) if ( appears ( e . name , ss ) ) activate ( e ) ;
} )
+ arg : : add3 ( " -embscaffold " , [ ] {
arg : : shift ( ) ; scaffoldx = arg : : argi ( ) ;
arg : : shift ( ) ; scaffoldy = arg : : argi ( ) ;
arg : : shift ( ) ; scaffoldb = arg : : argi ( ) ;
} )
+ arg : : add3 ( " -embscaffold-move " , [ ] {
arg : : shift ( ) ; scaffoldx_move = arg : : argi ( ) ;
arg : : shift ( ) ; scaffoldy_move = arg : : argi ( ) ;
} )
+ arg : : add3 ( " -embwchess " , [ ] { with_chess = ! with_chess ; } )
+ arg : : add3 ( " -embfix " , [ ] { arg : : shift ( ) ; fix_chess = arg : : argf ( ) ; } )
+ arg : : add3 ( " -embwmodel " , [ ] { with_models = ! with_models ; } )
+ arg : : add3 ( " -embwmlight " , [ ] { with_models = true ; light_models = true ; } )
+ arg : : add3 ( " -embwdig " , [ ] { arg : : shift ( ) ; draw_digger = arg : : argi ( ) ; } )
+ arg : : add3 ( " -embload " , [ ] { arg : : shift ( ) ; load_anim ( arg : : args ( ) ) ; } )
+ arg : : add3 ( " -embappend " , [ ] { arg : : shift ( ) ; append_anim ( arg : : args ( ) ) ; } )
+ arg : : add3 ( " -embsave " , [ ] { arg : : shift ( ) ; save_anim ( arg : : args ( ) ) ; } )
+ arg : : add3 ( " -embt0 " , [ ] { smoothcam : : animate_on = false ; smoothcam : : handle_animation ( 0 ) ; playermoved = false ; } )
+ arg : : add3 ( " -embt1 " , [ ] { smoothcam : : animate_on = false ; smoothcam : : handle_animation ( 1 - 1e-7 ) ; playermoved = false ; } )
+ arg : : add3 ( " -embmin " , [ ] { arg : : shift ( ) ; cells_drawn = arg : : argi ( ) ; } )
+ arg : : add3 ( " -emb-chess-moves " , [ ] { arg : : shift ( ) ; chess_moves = arg : : argi ( ) ; } )
+ arg : : add3 ( " -emb-sqd " , enable_square_diagram )
+ arg : : add3 ( " -embtrans-test " , [ ] { arg : : shift ( ) ; transition_test ( arg : : argf ( ) ) ; } )
+ arg : : add3 ( " -emb-no-floor " , [ ] { no_floor = true ; } )
+ arg : : add3 ( " -embtrans " , [ ] {
arg : : shift ( ) ; anims : : videofile = arg : : args ( ) ;
arg : : shift ( ) ; ld a = arg : : argf ( ) ;
arg : : shift ( ) ; ld b = arg : : argf ( ) ;
arg : : shift ( ) ; int t = arg : : argi ( ) ;
transition ( a , b , t ) ;
} )
+ arg : : add3 ( " -avp " , [ ] { semidirect_rendering = true ; vid . consider_shader_projection = false ; } )
+ arg : : add3 ( " -embforward " , [ ] {
arg : : shift ( ) ; int t = arg : : argi ( ) ;
arg : : shift ( ) ; anims : : videofile = arg : : args ( ) ;
arg : : shift ( ) ; ld d = arg : : argf ( ) ;
animate_forward ( d , t ) ;
} )
+ arg : : add3 ( " -emb-goforward " , [ ] {
arg : : shift ( ) ; ld d = arg : : argf ( ) ;
for ( int i = 0 ; i < 1000 ; i + + ) {
shift_view ( ztangent ( - d / 1000. ) ) ;
optimizeview ( ) ;
spinEdge ( 100 ) ;
}
} ) ;
;
auto embchess_show =
addHook_slideshows ( 100 , [ ] ( tour : : ss : : slideshow_callback cb ) {
2023-05-18 12:18:46 +00:00
cb ( XLAT ( " non-Euclidean third dimension " ) , & embchess_slides [ 0 ] , ' 3 ' ) ;
2023-05-15 00:48:38 +00:00
} ) ;
2023-05-18 12:18:46 +00:00
}
}