ray:: now works with Binary4 product

This commit is contained in:
Zeno Rogue 2021-10-07 21:44:29 +02:00
parent 83da34d6ac
commit 569c968a41
3 changed files with 89 additions and 28 deletions

View File

@ -604,6 +604,7 @@ EX namespace bt {
/** \brief by what factor do the lengths expand after moving one level in hr::bt::expansion_coordinate() */ /** \brief by what factor do the lengths expand after moving one level in hr::bt::expansion_coordinate() */
EX ld expansion() { EX ld expansion() {
if(WDIM == 2) return area_expansion_rate(); if(WDIM == 2) return area_expansion_rate();
else if(prod) return PIU( area_expansion_rate() );
else return sqrt(area_expansion_rate()); else return sqrt(area_expansion_rate());
} }

View File

@ -772,10 +772,11 @@ hyperpoint ray_kleinize(hyperpoint h, int id, ld pz) {
if(hyperbolic && bt::in()) { if(hyperbolic && bt::in()) {
// ld co = vid.binary_width / log(2) / 4; // ld co = vid.binary_width / log(2) / 4;
// hyperpoint res = point31(h[2]*log(2)/2, h[0]*co, h[1]*co); // hyperpoint res = point31(h[2]*log(2)/2, h[0]*co, h[1]*co);
return deparabolic13(bt::bt_to_minkowski(h)); return deparabolic13(final_coords(h));
} }
#endif #endif
if(prod) { if(prod) {
if(bt::in()) return point3(h[0], h[1], pz);
return point3(h[0]/h[2], h[1]/h[2], pz); return point3(h[0]/h[2], h[1]/h[2], pz);
} }
return kleinize(h); return kleinize(h);

View File

@ -81,6 +81,10 @@ EX bool is_stepbased() {
return nonisotropic || stretch::in() || is_eyes(); return nonisotropic || stretch::in() || is_eyes();
} }
EX bool horos() {
return (hyperbolic || in_h2xe()) && bt::in();
}
ld& maxstep_current() { ld& maxstep_current() {
if(sn::in() || stretch::in()) return maxstep_sol; if(sn::in() || stretch::in()) return maxstep_sol;
#if CAP_VR #if CAP_VR
@ -332,8 +336,9 @@ struct raygen {
void emit_iterate(int gid1); void emit_iterate(int gid1);
void create(); void create();
string f_xpush() { return hyperbolic ? "xpush_h" : "xpush_s"; } string f_xpush() { return hyperbolic ? "xpush_h3" : "xpush_s3"; }
string f_len() { return hyperbolic ? "len_h" : (sphere && rotspace) ? "len_sr" : sl2 ? "len_sl2" : sphere ? "len_s" : "len_x"; } string f_len() { return hyperbolic ? "len_h3" : (sphere && rotspace) ? "len_sr" : sl2 ? "len_sl2" : sphere ? "len_s3" : "len_x"; }
string f_len_prod() { return in_h2xe() ? "len_h2" : in_s2xe() ? "len_s2" : "len_e2"; }
void add_functions(); void add_functions();
}; };
@ -352,7 +357,10 @@ void raygen::compute_which_and_dist(int flat1, int flat2) {
fmain += fmain +=
" if(which == -1) {\n"; " if(which == -1) {\n";
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : ((WDIM == 2 || is_subcube_based(variation) || intra::in) && !bt::in()) ? "sides" : its(flat2))+"; i++) {\n"; if(in_h2xe() && bt::in())
fmain += "for(int i=2; i<=4; i++) if(i == 2 || i == 4) {";
else
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : ((WDIM == 2 || is_subcube_based(variation) || intra::in) && !bt::in()) ? "sides" : its(flat2))+"; i++) {\n";
fmain += " mediump mat4 m = " + getM("walloffset+i") + ";\n"; fmain += " mediump mat4 m = " + getM("walloffset+i") + ";\n";
@ -416,14 +424,16 @@ void raygen::compute_which_and_dist(int flat1, int flat2) {
// 20: get to horosphere +uBLevel (take smaller root) // 20: get to horosphere +uBLevel (take smaller root)
// 21: get to horosphere -uBLevel (take larger root) // 21: get to horosphere -uBLevel (take larger root)
if(hyperbolic && bt::in()) { if(horos()) {
string push = hyperbolic ? "xpush_h3" : "xpush_h2";
string w = hyperbolic ? "w" : "z";
fmain += fmain +=
"for(int i=20; i<22; i++) {\n" "for(int i=20; i<22; i++) {\n"
"mediump float sgn = i == 20 ? -1. : 1.;\n" "mediump float sgn = i == 20 ? -1. : 1.;\n"
"mediump vec4 zpos = xpush_h(uBLevel*sgn) * position;\n" "mediump vec4 zpos = "+push+"(uBLevel*sgn) * position;\n"
"mediump vec4 ztan = xpush_h(uBLevel*sgn) * tangent;\n" "mediump vec4 ztan = "+push+"(uBLevel*sgn) * tangent;\n"
"mediump float Mp = zpos.w - zpos.x;\n" "mediump float Mp = zpos."+w+" - zpos.x;\n"
"mediump float Mt = ztan.w - ztan.x;\n" "mediump float Mt = ztan."+w+" - ztan.x;\n"
"mediump float a = (Mp*Mp-Mt*Mt);\n" "mediump float a = (Mp*Mp-Mt*Mt);\n"
"mediump float b = Mp/a;\n" "mediump float b = Mp/a;\n"
"mediump float c = (1.+Mt*Mt) / a;\n" "mediump float c = (1.+Mt*Mt) / a;\n"
@ -432,8 +442,10 @@ void raygen::compute_which_and_dist(int flat1, int flat2) {
"mediump float zsgn = (Mt > 0. ? -sgn : sgn);\n" "mediump float zsgn = (Mt > 0. ? -sgn : sgn);\n"
"mediump float u = sqrt(b*b-c)*zsgn + b;\n" "mediump float u = sqrt(b*b-c)*zsgn + b;\n"
"mediump float v = -(Mp*u-1.) / Mt;\n" "mediump float v = -(Mp*u-1.) / Mt;\n"
"mediump float d = asinh(v);\n" "mediump float d = asinh(v);\n";
"if(d < 0. && abs(log(position.w*position.w-position.x*position.x)) < uBLevel) continue;\n" if(prod) fmain += "d /= xspeed;\n";
fmain +=
"if(d < 0. && abs(log(position."+w+"*position."+w+"-position.x*position.x)) < uBLevel) continue;\n"
"if(d < dist) { dist = d; which = i; }\n" "if(d < dist) { dist = d; which = i; }\n"
"}\n"; "}\n";
} }
@ -922,17 +934,27 @@ void raygen::move_forward() {
void raygen::apply_reflect(int flat1, int flat2) { void raygen::apply_reflect(int flat1, int flat2) {
if(prod) fmain += "if(reflect && which >= sides-2) { zspeed = -zspeed; continue; }\n"; if(prod) fmain += "if(reflect && which >= sides-2) { zspeed = -zspeed; continue; }\n";
if(hyperbolic && bt::in()) fmain += if(horos()) {
"if(reflect && (which < "+its(flat1)+" || which >= "+its(flat2)+")) {\n" fmain +=
"if(reflect && (which < "+its(flat1)+" || which >= "+its(flat2)+")) {\n";
if(hyperbolic) fmain +=
" mediump float x = -log(position.w - position.x);\n" " mediump float x = -log(position.w - position.x);\n"
" mediump vec4 xtan = xpush_h(-x) * tangent;\n" " mediump vec4 xtan = xpush_h3(-x) * tangent;\n"
" mediump float diag = (position.y*position.y+position.z*position.z)/2.;\n" " mediump float diag = (position.y*position.y+position.z*position.z)/2.;\n"
" mediump vec4 normal = vec4(1.-diag, -position.y, -position.z, -diag);\n" " mediump vec4 normal = vec4(1.-diag, -position.y, -position.z, -diag);\n"
" mediump float mdot = dot(xtan.xyz, normal.xyz) - xtan.w * normal.w;\n" " mediump float mdot = dot(xtan.xyz, normal.xyz) - xtan.w * normal.w;\n";
else fmain +=
" mediump float x = -log(position.z - position.x);\n"
" mediump vec4 xtan = xpush_h2(-x) * tangent;\n"
" mediump float diag = position.y*position.y/2.;\n"
" mediump vec4 normal = vec4(1.-diag, -position.y, -diag, 0.);\n"
" mediump float mdot = dot(xtan.xy, normal.xy) - xtan.w * normal.w;\n";
fmain +=
" xtan = xtan - normal * mdot * 2.;\n" " xtan = xtan - normal * mdot * 2.;\n"
" tangent = xpush_h(x) * xtan;\n" " tangent = xpush_h(x) * xtan;\n"
" continue;\n" " continue;\n"
" }\n"; " }\n";
}
if(asonov) { if(asonov) {
fmain += fmain +=
" if(reflect) {\n" " if(reflect) {\n"
@ -1149,7 +1171,7 @@ void raygen::emit_iterate(int gid1) {
if(prod || rotspace) flat2 -= 2; if(prod || rotspace) flat2 -= 2;
#if CAP_BT #if CAP_BT
if(hyperbolic && bt::in()) { if(horos()) {
if(intra::in) if(intra::in)
fmain += "mediump float uBLevel = " + to_glsl(log(bt::expansion()) / 2) + ";\n"; fmain += "mediump float uBLevel = " + to_glsl(log(bt::expansion()) / 2) + ";\n";
else else
@ -1200,22 +1222,30 @@ void raygen::emit_iterate(int gid1) {
"tangent /= sqrt(dot(tangent.xy, tangent.xy) - tangent.z*tangent.z);\n"; "tangent /= sqrt(dot(tangent.xy, tangent.xy) - tangent.z*tangent.z);\n";
} }
if(hyperbolic && bt::in()) { if(horos()) {
string w20, w21;
if(in_h2xe() && hybrid::underlying == gBinary4) {
w21 = " for(int i=0; i<2; i++) {\n";
w20 = "int i=3; {\n";
}
else {
w20 = " for(int i="+its(flat2)+"; i<"+its(S7)+"; i++) {\n";
w21 = "for(int i=0; i<"+its(flat1)+"; i++) {\n";
}
fmain += fmain +=
"if(which == 20) {\n" "if(which == 20) {\n"
" mediump float best = 999.;\n" " mediump float best = 999.;\n"
" for(int i="+its(flat2)+"; i<"+its(S7)+"; i++) {\n" +w20+
" mediump float cand = "+f_len()+"(" + getM("i") + " * position);\n" " mediump float cand = "+f_len_prod()+"(" + getM("i") + " * position);\n"
" if(cand < best) { best = cand; which = i; }\n" " if(cand < best) { best = cand; which = i; }\n"
" }\n" " }\n"
"}\n" "}\n"
"if(which == 21) {\n" "if(which == 21) {\n"
"mediump float best = 999.;\n" "mediump float best = 999.;\n"
"for(int i=0; i<"+its(flat1)+"; i++) {\n" +w21+
" mediump float cand = "+f_len()+"(" + getM("i") + " * position);\n" " mediump float cand = "+f_len_prod()+"(" + getM("i") + " * position);\n"
" if(cand < best) { best = cand; which = i; }\n" " if(cand < best) { best = cand; which = i; }\n"
" }\n" " }\n"
// "gl_FragColor = vec4(.5 + .5 * sin((go+dist)*100.), 1, float(which)/3., 1); return;\n"
"}\n"; "}\n";
} }
@ -1264,8 +1294,12 @@ void raygen::emit_iterate(int gid1) {
"pos.xyz = pos.zxy;\n"; "pos.xyz = pos.zxy;\n";
else if(hyperbolic || sphere) fmain += else if(hyperbolic || sphere) fmain +=
"pos /= pos.w;\n"; "pos /= pos.w;\n";
else if(prod && bt::in()) fmain +=
"pos.xy = deparabolic12(pos).xy;\n"
"pos.z = -pos.w; pos.w = 0.;\n"
;
else if(prod) fmain += else if(prod) fmain +=
"pos = vec4(pos.x/pos.z, pos.y/pos.z, pos.w, 0);\n"; "pos = vec4(pos.x/pos.z, pos.y/pos.z, -pos.w, 0);\n";
fmain += fmain +=
" mediump vec2 inface = map_texture(pos, which+walloffset);\n" " mediump vec2 inface = map_texture(pos, which+walloffset);\n"
" mediump vec3 tmap = texture2D(tTextureMap, u).rgb;\n" " mediump vec3 tmap = texture2D(tTextureMap, u).rgb;\n"
@ -1440,18 +1474,27 @@ void enable_raycaster() {
void raygen::add_functions() { void raygen::add_functions() {
add_if("xpush_h", add_if("xpush_h3",
"mediump mat4 xpush_h(float x) { return mat4(" "mediump mat4 xpush_h3(float x) { return mat4("
"cosh(x), 0., 0., sinh(x),\n" "cosh(x), 0., 0., sinh(x),\n"
"0., 1., 0., 0.,\n" "0., 1., 0., 0.,\n"
"0., 0., 1., 0.,\n" "0., 0., 1., 0.,\n"
"sinh(x), 0., 0., cosh(x)" "sinh(x), 0., 0., cosh(x)"
");}\n"); ");}\n");
add_if("xpush_h2",
"mediump mat4 xpush_h2(float x) { return mat4("
"cosh(x), 0., sinh(x), 0.,\n"
"0., 1., 0., 0.,\n"
"sinh(x), 0., cosh(x), 0.,\n"
"0., 0., 0., 1."
");}\n");
add_if("xpush_s", add_if("xpush_s",
"mediump mat4 xpush(float x) { return mat4(" "mediump mat4 xpush_s(float x) { return mat4("
"cos(x), 0., 0., sin(x),\n" "cos(x), 0., 0., sin(x),\n"
"0., 1., 0., 0.,\n" "0., 1., 0., 0.,\n"
"0., 0., 1., 0.,\n" "0., 0., 1., 0.,\n"
@ -1492,6 +1535,19 @@ void raygen::add_functions() {
" return res;\n" " return res;\n"
" }\n\n"); " }\n\n");
add_if("deparabolic12",
"mediump vec4 deparabolic12(mediump vec4 h) {\n"
" h /= (1. + h.z);\n"
" h[0] -= 1.;\n"
" h /= h.x*h.x + h.y*h.y;\n"
" h[0] += .5;\n"
" mediump vec4 res;\n"
" res.x = (log(2.) + log(-h.x));\n"
" res.y = h.y * 2.;\n"
" res.w = 1.;\n"
" return res;\n"
" }\n\n");
add_if("enparabolic13", add_if("enparabolic13",
"mediump vec4 enparabolic13(mediump vec4 h) {\n" "mediump vec4 enparabolic13(mediump vec4 h) {\n"
" mediump vec4 res;\n" " mediump vec4 res;\n"
@ -1577,11 +1633,14 @@ void raygen::add_functions() {
add_if("len_rotspace", "mediump float len_rotspace(vec4 h) { return 1. - h[3]; }\n"); add_if("len_rotspace", "mediump float len_rotspace(vec4 h) { return 1. - h[3]; }\n");
add_if("len_h", " mediump float len_h(mediump vec4 x) { return x[3]; }\n"); add_if("len_h3", " mediump float len_h3(mediump vec4 x) { return x[3]; }\n");
add_if("len_sr", " mediump float len_sr(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y-x.z*x.z-x.w*x.w; }\n"); add_if("len_sr", " mediump float len_sr(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y-x.z*x.z-x.w*x.w; }\n");
add_if("len_sl2"," mediump float len_sl2(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y; }\n"); add_if("len_sl2"," mediump float len_sl2(mediump vec4 x) { return 1.+x.x*x.x+x.y*x.y; }\n");
add_if("len_s", " mediump float len_s(mediump vec4 x) { return 1.-x[3]; }\n"); add_if("len_s3", " mediump float len_s3(mediump vec4 x) { return 1.-x[3]; }\n");
add_if("len_x", " mediump float len_x(mediump vec4 x) { return length(x.xyz); }\n"); add_if("len_x", " mediump float len_x(mediump vec4 x) { return length(x.xyz); }\n");
add_if("len_h2", " mediump float len_h2(mediump vec4 x) { return x[2]; }\n");
add_if("len_s2", " mediump float len_s2(mediump vec4 x) { return 1.-x[2]; }\n");
add_if("len_e2", " mediump float len_e2(mediump vec4 x) { return length(x.xy); }\n");
} }
void raygen::create() { void raygen::create() {