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;
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) {
case mdPerspective: {
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);
break;
}
if(prod) {
ret = H;
break;
}
if(pmodel == mdHyperboloid) {
ld& topz = models::top_z;
if(H[2] > topz) {
@ -754,7 +767,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
break;
case mdEquidistant: case mdEquiarea: case mdEquivolume: {
if(nonisotropic) {
if(nonisotropic || prod) {
ret = lp_apply(inverse_exp(H, iTable, false));
ret[3] = 1;
break;

View File

@ -159,6 +159,8 @@ EX namespace models {
EX ld spiral_cone = 360;
EX ld spiral_cone_rad;
EX bool ring_not_spiral;
EX ld product_z_scale = 1;
EX void configure() {
ld ball = -vid.ballangle * degree;
@ -198,7 +200,11 @@ EX namespace models {
}
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(nonisotropic) return among(pm, mdDisk, mdPerspective, mdHorocyclic, mdGeodesic, mdEquidistant, mdFisheye);
if(pm == mdGeodesic && !sol) return false;
@ -220,11 +226,18 @@ EX namespace models {
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;
EX string get_model_name(eModel m) {
if(m == mdDisk && GDIM == 3 && (hyperbolic || nonisotropic)) return XLAT("ball model/Gans");
if(m == mdPerspective && prod) return XLAT("native perspective");
if(prod) return PIU(get_model_name(m));
if(nonisotropic) {
if(m == mdHorocyclic && !sol) return XLAT("simple model: projection");
if(m == mdPerspective) return XLAT("simple model: perspective");
@ -630,6 +643,14 @@ EX namespace models {
dialog::addSelItem(XLAT("vertical stretch"), fts(vid.stretch), 's');
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');
bool shaderside_projection = get_shader_flags() & SF_DIRECT;

View File

@ -1167,7 +1167,7 @@ EX namespace product {
EX void drawcell_stack(cellwalker cw, transmatrix V) {
cell *c = cw.at;
if(sphere) gmatrix[c] = V; /* some computations need gmatrix0 for underlying geometry */
bool s = sphere;
bool s = sphere || pmodel != mdPerspective;
hybrid::in_actual([&] {
cell *c0 = hybrid::get_at(c, hybrid::current_view_level);
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) {
shader_flags |= SF_PIXELS;
}
else if(pmodel == mdDisk && MDIM == 3 && !spherespecial) {
else if(pmodel == mdDisk && MDIM == 3 && !spherespecial && !prod) {
shader_flags |= SF_DIRECT;
}
else if(glhr::noshaders) {
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";
vsh += "uniform mediump float uAlpha;";
shader_flags |= SF_DIRECT | SF_BOX;
@ -197,7 +197,7 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
break;
}
}
else if(geometry == gProduct && !hybrid::over_sphere()) {
else if(geometry == gProduct && !hybrid::over_sphere() && pmodel == mdPerspective) {
shader_flags |= SF_PERS3 | SF_DIRECT;
coordinator +=
"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)";
treset = true;
}
else if(geometry == gProduct && hybrid::over_sphere()) {
else if(geometry == gProduct && hybrid::over_sphere() && pmodel == mdPerspective) {
shader_flags |= SF_PERS3 | SF_DIRECT;
distfun = "length(t.xyz)", treset = true;
}