mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-01 21:10: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
|
#endif
|
||||||
EX }
|
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() {
|
void dqi_poly::draw() {
|
||||||
if(flags & POLY_DEBUG) debug_this();
|
if(flags & POLY_DEBUG) debug_this();
|
||||||
|
|
||||||
if(debugflags & DF_VERTEX) {
|
if(debugflags & DF_VERTEX) {
|
||||||
println(hlog, tie(V, offset, cnt, offset_texture, outline, linewidth, flags, intester, cache), (cell*) tinf);
|
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]);
|
for(int i=0; i<cnt; i++) print(hlog, (*tab)[i]);
|
||||||
@ -1546,73 +1623,7 @@ void dqi_poly::draw() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int broken_coord = models::get_broken_coord(pmodel);
|
if(broken_projection(*this)) return;
|
||||||
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(sphere && pmodel == mdTwoPoint && !in_twopoint) {
|
if(sphere && pmodel == mdTwoPoint && !in_twopoint) {
|
||||||
#define MAX_PHASE 4
|
#define MAX_PHASE 4
|
||||||
|
Loading…
Reference in New Issue
Block a user