1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-25 09:30:35 +00:00

product:: product projections

This commit is contained in:
Zeno Rogue 2019-11-09 13:14:42 +01:00
parent 6dfec2140e
commit cc9e03ddb8
4 changed files with 41 additions and 7 deletions

View File

@ -315,6 +315,15 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
hyperpoint H_orig = H; hyperpoint H_orig = H;
if(models::product_model()) {
ld zlev = zlevel(H);
H /= exp(zlev);
hybrid::in_underlying_geometry([&] { applymodel(H, ret); });
ret[2] = zlev * models::product_z_scale;
ret = nisot::local_perspective * ret;
return;
}
switch(pmodel) { switch(pmodel) {
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;
@ -509,6 +518,10 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
ret = lp_apply(H); ret = lp_apply(H);
break; break;
} }
if(prod) {
ret = H;
break;
}
if(pmodel == mdHyperboloid) { if(pmodel == mdHyperboloid) {
ld& topz = models::top_z; ld& topz = models::top_z;
if(H[2] > topz) { if(H[2] > topz) {
@ -754,7 +767,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
break; break;
case mdEquidistant: case mdEquiarea: case mdEquivolume: { case mdEquidistant: case mdEquiarea: case mdEquivolume: {
if(nonisotropic) { if(nonisotropic || prod) {
ret = lp_apply(inverse_exp(H, iTable, false)); ret = lp_apply(inverse_exp(H, iTable, false));
ret[3] = 1; ret[3] = 1;
break; break;

View File

@ -160,6 +160,8 @@ EX namespace models {
EX ld spiral_cone_rad; EX ld spiral_cone_rad;
EX bool ring_not_spiral; EX bool ring_not_spiral;
EX ld product_z_scale = 1;
EX void configure() { EX void configure() {
ld ball = -vid.ballangle * degree; ld ball = -vid.ballangle * degree;
cos_ball = cos(ball), sin_ball = sin(ball); cos_ball = cos(ball), sin_ball = sin(ball);
@ -198,7 +200,11 @@ EX namespace models {
} }
EX bool model_available(eModel pm) { EX bool model_available(eModel pm) {
if(prod) return pm == mdPerspective; if(prod) {
if(pm == mdPerspective) return true;
if(among(pm, mdBall, mdHemisphere)) return false;
return PIU(model_available(pm));
}
if(sl2) return pm == mdGeodesic; if(sl2) return pm == mdGeodesic;
if(nonisotropic) return among(pm, mdDisk, mdPerspective, mdHorocyclic, mdGeodesic, mdEquidistant, mdFisheye); if(nonisotropic) return among(pm, mdDisk, mdPerspective, mdHorocyclic, mdGeodesic, mdEquidistant, mdFisheye);
if(pm == mdGeodesic && !sol) return false; if(pm == mdGeodesic && !sol) return false;
@ -220,11 +226,18 @@ EX namespace models {
return among(pmodel, mdJoukowsky, mdJoukowskyInverted, mdBand) && GDIM == 2; return among(pmodel, mdJoukowsky, mdJoukowskyInverted, mdBand) && GDIM == 2;
} }
EX bool product_model() {
if(!prod) return false;
if(among(pmodel, mdPerspective, mdHyperboloid, mdEquidistant)) return false;
return true;
}
int editpos = 0; int editpos = 0;
EX string get_model_name(eModel m) { EX string get_model_name(eModel m) {
if(m == mdDisk && GDIM == 3 && (hyperbolic || nonisotropic)) return XLAT("ball model/Gans"); if(m == mdDisk && GDIM == 3 && (hyperbolic || nonisotropic)) return XLAT("ball model/Gans");
if(m == mdPerspective && prod) return XLAT("native perspective"); if(m == mdPerspective && prod) return XLAT("native perspective");
if(prod) return PIU(get_model_name(m));
if(nonisotropic) { if(nonisotropic) {
if(m == mdHorocyclic && !sol) return XLAT("simple model: projection"); if(m == mdHorocyclic && !sol) return XLAT("simple model: projection");
if(m == mdPerspective) return XLAT("simple model: perspective"); if(m == mdPerspective) return XLAT("simple model: perspective");
@ -631,6 +644,14 @@ EX namespace models {
dialog::addSelItem(XLAT("vertical stretch"), fts(vid.stretch), 's'); dialog::addSelItem(XLAT("vertical stretch"), fts(vid.stretch), 's');
dialog::add_action(edit_stretch); dialog::add_action(edit_stretch);
if(product_model()) {
dialog::addSelItem(XLAT("product Z stretch"), fts(product_z_scale), 'Z');
dialog::add_action([] {
dialog::editNumber(product_z_scale, 0.1, 10, 0.1, 1, XLAT("product Z stretch"), "");
dialog::scaleLog();
});
}
dialog::addBoolItem(XLAT("use GPU to compute projections"), vid.consider_shader_projection, 'G'); dialog::addBoolItem(XLAT("use GPU to compute projections"), vid.consider_shader_projection, 'G');
bool shaderside_projection = get_shader_flags() & SF_DIRECT; bool shaderside_projection = get_shader_flags() & SF_DIRECT;
if(vid.consider_shader_projection && !shaderside_projection) if(vid.consider_shader_projection && !shaderside_projection)

View File

@ -1167,7 +1167,7 @@ EX namespace product {
EX void drawcell_stack(cellwalker cw, transmatrix V) { EX void drawcell_stack(cellwalker cw, transmatrix V) {
cell *c = cw.at; cell *c = cw.at;
if(sphere) gmatrix[c] = V; /* some computations need gmatrix0 for underlying geometry */ if(sphere) gmatrix[c] = V; /* some computations need gmatrix0 for underlying geometry */
bool s = sphere; bool s = sphere || pmodel != mdPerspective;
hybrid::in_actual([&] { hybrid::in_actual([&] {
cell *c0 = hybrid::get_at(c, hybrid::current_view_level); cell *c0 = hybrid::get_at(c, hybrid::current_view_level);
cwall_offset = hybrid::wall_offset(c0); cwall_offset = hybrid::wall_offset(c0);

View File

@ -117,13 +117,13 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
else if(!vid.consider_shader_projection) { else if(!vid.consider_shader_projection) {
shader_flags |= SF_PIXELS; shader_flags |= SF_PIXELS;
} }
else if(pmodel == mdDisk && MDIM == 3 && !spherespecial) { else if(pmodel == mdDisk && MDIM == 3 && !spherespecial && !prod) {
shader_flags |= SF_DIRECT; shader_flags |= SF_DIRECT;
} }
else if(glhr::noshaders) { else if(glhr::noshaders) {
shader_flags |= SF_PIXELS; shader_flags |= SF_PIXELS;
} }
else if(pmodel == mdDisk && GDIM == 3 && !spherespecial && !nonisotropic) { else if(pmodel == mdDisk && GDIM == 3 && !spherespecial && !nonisotropic && !prod) {
coordinator += "t /= (t[3] + uAlpha);\n"; coordinator += "t /= (t[3] + uAlpha);\n";
vsh += "uniform mediump float uAlpha;"; vsh += "uniform mediump float uAlpha;";
shader_flags |= SF_DIRECT | SF_BOX; shader_flags |= SF_DIRECT | SF_BOX;
@ -197,7 +197,7 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
break; break;
} }
} }
else if(geometry == gProduct && !hybrid::over_sphere()) { else if(geometry == gProduct && !hybrid::over_sphere() && pmodel == mdPerspective) {
shader_flags |= SF_PERS3 | SF_DIRECT; shader_flags |= SF_PERS3 | SF_DIRECT;
coordinator += coordinator +=
"float z = log(t[2] * t[2] - t[0] * t[0] - t[1] * t[1]) / 2.;\n" "float z = log(t[2] * t[2] - t[0] * t[0] - t[1] * t[1]) / 2.;\n"
@ -209,7 +209,7 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
distfun = "sqrt(z*z+d*d)"; distfun = "sqrt(z*z+d*d)";
treset = true; treset = true;
} }
else if(geometry == gProduct && hybrid::over_sphere()) { else if(geometry == gProduct && hybrid::over_sphere() && pmodel == mdPerspective) {
shader_flags |= SF_PERS3 | SF_DIRECT; shader_flags |= SF_PERS3 | SF_DIRECT;
distfun = "length(t.xyz)", treset = true; distfun = "length(t.xyz)", treset = true;
} }