mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-29 19:40:35 +00:00
drawing:: broken_projection as a separate function
This commit is contained in:
parent
f7a3a80f85
commit
5f33d6b51b
145
drawing.cpp
145
drawing.cpp
@ -1501,8 +1501,85 @@ EX namespace ods {
|
||||
#endif
|
||||
EX }
|
||||
|
||||
/** @brief render in a broken projection; return false if normal rendering is not applicable */
|
||||
bool broken_projection(dqi_poly& p0) {
|
||||
int broken_coord = models::get_broken_coord(pmodel);
|
||||
static bool in_broken = false;
|
||||
if(broken_coord && !in_broken) {
|
||||
|
||||
int zcoord = broken_coord;
|
||||
int ycoord = 3 - zcoord;
|
||||
|
||||
vector<hyperpoint> all;
|
||||
for(int i=0; i<p0.cnt; i++)
|
||||
all.push_back(p0.V.T * glhr::gltopoint((*p0.tab)[p0.offset+i]));
|
||||
int fail = 0;
|
||||
int last_fail;
|
||||
|
||||
auto break_in = [&] (hyperpoint a, hyperpoint b) {
|
||||
return a[0] * b[0] <= 0 && (a[0] * b[zcoord] - b[0] * a[zcoord]) * (a[0] - b[0]) < 0;
|
||||
};
|
||||
|
||||
for(int i=0; i<p0.cnt-1; i++)
|
||||
if(break_in(all[i], all[i+1]))
|
||||
last_fail = i, fail++;
|
||||
vector<glvertex> v;
|
||||
dqi_poly p = p0;
|
||||
p.tab = &v;
|
||||
p.offset = 0;
|
||||
p.V.T = Id;
|
||||
if(fail) {
|
||||
dynamicval<bool> ib(in_broken, true);
|
||||
ld part = ilerp(all[last_fail][0], all[last_fail+1][0], 0);
|
||||
hyperpoint initial = normalize(lerp(all[last_fail], all[last_fail+1], 1 - (1-part) * .99));
|
||||
bool have_initial = true;
|
||||
v.push_back(glhr::pointtogl(initial));
|
||||
last_fail++;
|
||||
int at = last_fail;
|
||||
do {
|
||||
v.push_back(glhr::pointtogl(all[at]));
|
||||
if(at == p0.cnt-1 && all[at] != all[0]) {
|
||||
p.cnt = isize(v); p.draw(); v.clear(); at = 0;
|
||||
have_initial = false;
|
||||
}
|
||||
int next = at+1;
|
||||
if(next == p0.cnt) next = 0;
|
||||
if(break_in(all[at], all[next])) {
|
||||
ld part = ilerp(all[at][0], all[next][0], 0);
|
||||
hyperpoint final = normalize(lerp(all[at], all[next], part * .99));
|
||||
v.push_back(glhr::pointtogl(final));
|
||||
if(have_initial) {
|
||||
int max = 4 << vid.linequality;
|
||||
if(final[0] * initial[0] > 0) {
|
||||
for(int i=1; i<=max; i++)
|
||||
v.push_back(glhr::pointtogl(lerp(final, initial, i * 1. / max)));
|
||||
}
|
||||
else {
|
||||
hyperpoint end = Hypc;
|
||||
end[ycoord] = final[ycoord] > 0 ? 1 : -1;
|
||||
for(int i=1; i<=max; i++)
|
||||
v.push_back(glhr::pointtogl(lerp(final, end, i * 1. / max)));
|
||||
for(int i=1; i<=max; i++)
|
||||
v.push_back(glhr::pointtogl(lerp(end, initial, i * 1. / max)));
|
||||
}
|
||||
}
|
||||
p.cnt = isize(v); p.draw(); v.clear();
|
||||
initial = normalize(lerp(all[at], all[next], 1 - (1-part) * .99));
|
||||
have_initial = true;
|
||||
v.push_back(glhr::pointtogl(initial));
|
||||
}
|
||||
at = next;
|
||||
}
|
||||
while(at != last_fail);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void dqi_poly::draw() {
|
||||
if(flags & POLY_DEBUG) debug_this();
|
||||
|
||||
if(debugflags & DF_VERTEX) {
|
||||
println(hlog, tie(V, offset, cnt, offset_texture, outline, linewidth, flags, intester, cache), (cell*) tinf);
|
||||
for(int i=0; i<cnt; i++) print(hlog, (*tab)[i]);
|
||||
@ -1546,73 +1623,7 @@ void dqi_poly::draw() {
|
||||
return;
|
||||
}
|
||||
|
||||
int broken_coord = models::get_broken_coord(pmodel);
|
||||
static bool in_broken = false;
|
||||
if(broken_coord && !in_broken) {
|
||||
|
||||
int zcoord = broken_coord;
|
||||
int ycoord = 3 - zcoord;
|
||||
|
||||
vector<hyperpoint> all;
|
||||
for(int i=0; i<cnt; i++)
|
||||
all.push_back(V.T * glhr::gltopoint((*tab)[offset+i]));
|
||||
int fail = 0;
|
||||
int last_fail;
|
||||
for(int i=0; i<cnt-1; i++)
|
||||
if(all[i][0] * all[i+1][0] <= 0 && (all[i][0] * all[i+1][zcoord] - all[i+1][0] * all[i][zcoord]) * (all[i][0] - all[i+1][0]) < 0)
|
||||
last_fail = i, fail++;
|
||||
vector<glvertex> v;
|
||||
dqi_poly p = *this;
|
||||
p.tab = &v;
|
||||
p.offset = 0;
|
||||
p.V.T = Id;
|
||||
if(fail) {
|
||||
dynamicval<bool> ib(in_broken, true);
|
||||
ld part = ilerp(all[last_fail][0], all[last_fail+1][0], 0);
|
||||
hyperpoint initial = normalize(lerp(all[last_fail], all[last_fail+1], 1 - (1-part) * .99));
|
||||
bool have_initial = true;
|
||||
v.push_back(glhr::pointtogl(initial));
|
||||
last_fail++;
|
||||
int at = last_fail;
|
||||
do {
|
||||
v.push_back(glhr::pointtogl(all[at]));
|
||||
if(at == cnt-1 && all[at] != all[0]) {
|
||||
p.cnt = isize(v); p.draw(); v.clear(); at = 0;
|
||||
have_initial = false;
|
||||
}
|
||||
int next = at+1;
|
||||
if(next == cnt) next = 0;
|
||||
if(all[at][0] * all[next][0] <= 0 && (all[at][0] * all[next][zcoord] - all[next][0] * all[at][zcoord]) * (all[at][0] - all[next][0]) < 0) {
|
||||
ld part = ilerp(all[at][0], all[next][0], 0);
|
||||
if(part > .999 || part < .001) { in_broken = false; return; }
|
||||
hyperpoint final = normalize(lerp(all[at], all[next], part * .99));
|
||||
v.push_back(glhr::pointtogl(final));
|
||||
if(have_initial) {
|
||||
int max = 4 << vid.linequality;
|
||||
if(final[0] * initial[0] > 0) {
|
||||
for(int i=1; i<=max; i++)
|
||||
v.push_back(glhr::pointtogl(lerp(final, initial, i * 1. / max)));
|
||||
}
|
||||
else {
|
||||
hyperpoint end = Hypc;
|
||||
end[ycoord] = final[ycoord] > 0 ? 1 : -1;
|
||||
for(int i=1; i<=max; i++)
|
||||
v.push_back(glhr::pointtogl(lerp(final, end, i * 1. / max)));
|
||||
for(int i=1; i<=max; i++)
|
||||
v.push_back(glhr::pointtogl(lerp(end, initial, i * 1. / max)));
|
||||
}
|
||||
}
|
||||
p.cnt = isize(v); p.draw(); v.clear();
|
||||
initial = normalize(lerp(all[at], all[next], 1 - (1-part) * .99));
|
||||
have_initial = true;
|
||||
v.push_back(glhr::pointtogl(initial));
|
||||
}
|
||||
at = next;
|
||||
}
|
||||
while(at != last_fail);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(broken_projection(*this)) return;
|
||||
|
||||
if(sphere && pmodel == mdTwoPoint && !in_twopoint) {
|
||||
#define MAX_PHASE 4
|
||||
|
Loading…
Reference in New Issue
Block a user