1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 17:10:36 +00:00

better matrix handling

This commit is contained in:
Zeno Rogue 2020-10-26 19:17:38 +01:00
parent 4e3a611168
commit ca7210081f

View File

@ -253,6 +253,7 @@ vector<bgeometry> bgeoms = {
set_geometry(gProduct); set_geometry(gProduct);
max_piece = 5; max_piece = 5;
rotate_allowed = false; rotate_allowed = false;
well_size = 5;
}}, }},
{"torus: shear", "Nil geometry: are you sure you want this?", [] { {"torus: shear", "Nil geometry: are you sure you want this?", [] {
@ -277,6 +278,7 @@ void create_game();
void enable_bgeom() { void enable_bgeom() {
stop_game_and_switch_mode(rg::nothing); stop_game_and_switch_mode(rg::nothing);
well_size = 10;
bgeoms[bgeom].create(); bgeoms[bgeom].create();
start_game(); start_game();
create_game(); create_game();
@ -395,6 +397,23 @@ vector<cellwalker> build_from(const code_t& code, cellwalker start, int sym = 0)
return all; return all;
} }
vector<transmatrix> build_shape_matrices(const vector<cellwalker>& cells) {
vector<transmatrix> all = {Id};
all.reserve(isize(cells));
for(int i=1; i<isize(cells); i++) {
for(int j=0; j<i; j++) {
int nei = neighborId(cells[j].at, cells[i].at);
if(nei != -1) {
transmatrix T = all[j];
T = T * currentmap->adj(cells[j].at, nei);
all.push_back(T);
break;
}
}
}
return all;
}
int penalty(const vector<cellwalker>& shape, const code_t& code) { int penalty(const vector<cellwalker>& shape, const code_t& code) {
int p = 0; int p = 0;
if(prod) { if(prod) {
@ -463,7 +482,7 @@ void generate_shapes_rec(vector<cellwalker>& sofar, code_t& code, int cnt) {
} }
for(int i=0; i<isize(sofar); i++) for(int i=0; i<isize(sofar); i++)
for(int t=0; t<sofar[i].at->type; t++) { for(int t=0; t<sofar[i].at->type; t++) {
if(solnil && !among(t, 4, 5, 10, 11)) continue; if(sol && !among(t, 4, 5, 10, 11)) continue;
cellwalker ncw = add(sofar[i], t); cellwalker ncw = add(sofar[i], t);
if(listed(sofar, ncw.at)) continue; if(listed(sofar, ncw.at)) continue;
code.emplace_back(i, t); code.emplace_back(i, t);
@ -511,6 +530,7 @@ color_t hipso[] = {
color_t get_hipso(ld y) { color_t get_hipso(ld y) {
y += 12; y += 12;
if(well_size <= 5) y *= 2;
return hipso[gmod(y, 13)]; return hipso[gmod(y, 13)];
} }
@ -868,11 +888,20 @@ void create_matrices() {
current_display->all_drawn_copies[c].push_back(V); current_display->all_drawn_copies[c].push_back(V);
gmatrix[p.first] = p.second; gmatrix[p.first] = p.second;
if(id < draw_per_level) { if(id < draw_per_level) {
for(int i=0; i<c->type-2; i++) { auto go = [&] (int i) {
cell *c1 = c->cmove(i); cell *c1 = c->cmove(i);
dq::enqueue_by_matrix_c(c1, optimized_shift(V * currentmap->adj(c, i))); dq::enqueue_by_matrix_c(c1, optimized_shift(V * currentmap->adj(c, i)));
};
if(prod) {
for(int i=0; i<c->type-2; i++) go(i);
} }
} else if(sol) {
go(4); go(5); go(10); go(11);
}
else if(nil) {
go(0); go(2); go(3); go(5);
}
}
dq::drawqueue_c.pop(); dq::drawqueue_c.pop();
id++; id++;
} }
@ -880,32 +909,26 @@ void create_matrices() {
transmatrix smooth; transmatrix smooth;
void draw_wirecube_at(const transmatrix& smoo, cell *c, int zlev, color_t col) { void change_depth(shiftmatrix& V, int newlevel, int zlev) {
if(solnil) { if(solnil) {
auto lev = inverse_shift(gmatrix[at.at], gmatrix[c]); while(newlevel > zlev) zlev++, V = V * currentmap->adj(cwt.at, down_dir());
for(const shiftmatrix& V: current_display->all_drawn_copies[c]) while(newlevel < zlev) zlev--, V = V * currentmap->adj(cwt.at, up_dir());
for(int i=0; i<c->type; i++) {
queuepolyat(V * inverse(lev) * smoo * lev, cgi.shWireframe3D[i], 0, PPR::SUPERLINE).outline = col;
// queuepolyat(V * smoo, cgi.shWireframe3D[i], 0, PPR::SUPERLINE).outline = col;
}
return;
} }
else if(in_h2xe())
V = shiftless(V.T, cgi.plevel * (newlevel - zlev));
else
V = shiftless(V.T * zpush(cgi.plevel * (newlevel - zlev)));
}
void draw_wirecube_at(cell *c, const transmatrix& rel, int zlev, color_t col) {
auto where_c = get_where(c); auto where_c = get_where(c);
auto c_camera = get_at(where_c.first, zlev);
auto c_camera = get_at(where_c.first, -camera_level); for(shiftmatrix V: current_display->all_drawn_copies[c_camera]) {
change_depth(V, where_c.second, zlev);
for(const shiftmatrix& V: current_display->all_drawn_copies[c_camera]) {
shiftmatrix VA;
if(solnil)
VA = V;
else if(in_h2xe())
VA = shiftless(smoo * V.T, cgi.plevel * (where_c.second - zlev));
else
VA = shiftless(smoo * V.T * zpush(cgi.plevel * (where_c.second - zlev)));
for(int i=0; i<c->type; i++) for(int i=0; i<c->type; i++)
queuepolyat(VA, cgi.shWireframe3D[i], 0, PPR::SUPERLINE).outline = col; queuepolyat(V * rel, cgi.shWireframe3D[i], 0, PPR::SUPERLINE).outline = col;
} }
} }
@ -913,19 +936,20 @@ void draw_piece(int zlev, int id) {
sightranges[geometry] *= 100; sightranges[geometry] *= 100;
initquickqueue(); initquickqueue();
auto shape = build_from(piecelist[id].code, at); auto shape = build_from(piecelist[id].code, at);
auto matrices = build_shape_matrices(shape);
auto where_at = get_where(at.at); auto where_at = get_where(at.at);
vid.linewidth *= 3; vid.linewidth *= 3;
int mid = 0;
for(auto c: shape) { for(auto c: shape) {
auto where_c = get_where(c.at); auto where_c = get_where(c.at);
color_t levels[4] = {color_t(0xFFFFFFFFF), color_t(0xFFFF00FF), color_t(0xFF8000FF), color_t(0xFF0000FF)}; color_t levels[5] = {color_t(0xFFFFFFFFF), color_t(0xFFFF00FF), color_t(0xFF8000FF), color_t(0xFF0000FF), color_t(0xC000C0FF) };
draw_wirecube_at(smooth, c.at, zlev, levels[where_at.second-where_c.second]); draw_wirecube_at(at.at, smooth * matrices[mid++], zlev, levels[where_at.second-where_c.second]);
} }
// draw_wirecube_at(smooth, at.cpeek(), zlev, 0xFF00FFFF);
vid.linewidth /= 3; vid.linewidth /= 3;
quickqueue(); quickqueue();
@ -944,7 +968,7 @@ void draw_holes(int zlev) {
if(c1->wall) covered = true; if(c1->wall) covered = true;
else if(covered) { else if(covered) {
vid.linewidth *= 4; vid.linewidth *= 4;
draw_wirecube_at(Id, c1, zlev, (get_hipso(z) << 8) | 0xFF); draw_wirecube_at(c1, Id, zlev, (get_hipso(z) << 8) | 0xFF);
vid.linewidth /= 4; vid.linewidth /= 4;
} }
} }
@ -971,19 +995,14 @@ void draw_all_noray(int zlev) {
continue; continue;
} }
auto c_camera = get_at(lev, -camera_level); auto c_camera = get_at(lev, zlev);
for(const shiftmatrix& V: current_display->all_drawn_copies[c_camera]) { for(shiftmatrix V: current_display->all_drawn_copies[c_camera]) {
shiftmatrix VA; change_depth(V, z, zlev);
if(in_h2xe())
VA = shiftless(V.T, cgi.plevel * (-z - zlev));
else
VA = shiftless(V.T * zpush(cgi.plevel * (-z - zlev)));
forCellIdCM(c2, i, c1) forCellIdCM(c2, i, c1)
if(!c2->wall) { if(!c2->wall) {
auto &q = queuepolyat(VA, cgi.shWall3D[i], (c1->landparam << 8) | 0xFF, PPR::WALL); auto &q = queuepolyat(V, cgi.shWall3D[i], (c1->landparam << 8) | 0xFF, PPR::WALL);
if(c1->wall == waBarrier) q.color = (winf[waBarrier].color << 8) | 0xFF; if(c1->wall == waBarrier) q.color = (winf[waBarrier].color << 8) | 0xFF;
q.tinf = &floor_texture_vertices[cgi.shFloor.id]; q.tinf = &floor_texture_vertices[cgi.shFloor.id];
ensure_vertex_number(*q.tinf, q.cnt); ensure_vertex_number(*q.tinf, q.cnt);
@ -1004,7 +1023,7 @@ void draw_screen(int xstart, bool show_next) {
dynamicval<display_data> ccd(*current_display); dynamicval<display_data> ccd(*current_display);
current_display->xmax = xstart * 1. / vid.xres; current_display->xmax = xstart * 1. / vid.xres;
ray::max_cells = isize(level) * camera_level; ray::max_cells = isize(level) * (camera_level+2);
if(explore) { if(explore) {
gamescreen(0); gamescreen(0);
@ -1021,12 +1040,14 @@ void draw_screen(int xstart, bool show_next) {
rotate_view(cspin(1, 2, -90*degree)); rotate_view(cspin(1, 2, -90*degree));
shift_view(ztangent(3 * nilv::nilwidth)); shift_view(ztangent(3 * nilv::nilwidth));
rotate_view(cspin(0, 1, -90*degree)); rotate_view(cspin(0, 1, -90*degree));
anims::moved();
} }
else if(sol) { else if(sol) {
centerover = at.at; centerover = at.at;
rotate_view(cspin(1, 2, 180*degree)); rotate_view(cspin(1, 2, 180*degree));
shift_view(ztangent(1)); shift_view(ztangent(1));
rotate_view(cspin(0, 1, -90*degree)); rotate_view(cspin(0, 1, -90*degree));
anims::moved();
} }
else { else {
ld lv = -cgi.plevel * steps; ld lv = -cgi.plevel * steps;
@ -1034,27 +1055,22 @@ void draw_screen(int xstart, bool show_next) {
rotate_view(cspin(1, 2, cur_ang)); rotate_view(cspin(1, 2, cur_ang));
shift_view(ztangent(cgi.plevel * (2 + max_piece))); shift_view(ztangent(cgi.plevel * (2 + max_piece)));
centerover = ncenter; centerover = ncenter;
anims::moved();
} }
int zlev = get_z(centerover); int zlev = get_z(centerover);
if(!solnil) {
make_actual_view(); // make_actual_view();
create_matrices();
}
// anims::moved(); // anims::moved();
if(state == tsCollect) for(cell *c: to_disappear) c->landparam = rand() & 0xFFFFFF; if(state == tsCollect) for(cell *c: to_disappear) c->landparam = rand() & 0xFFFFFF;
if(state == tsFalling && !explore && !cur_ang) remove_shape(); if(state == tsFalling && !explore && !cur_ang && !lctrlclick) remove_shape();
// just_gmatrix = true; // just_gmatrix = true;
ray::want_use = use_raycaster ? 2 : 0; ray::want_use = use_raycaster ? 2 : 0;
if(solnil) { if(1) {
gamescreen(0); gamescreen(0);
} create_matrices();
else {
auto adc = std::move(current_display->all_drawn_copies);
gamescreen(0);
current_display->all_drawn_copies = std::move(adc);
} }
if(!use_raycaster) if(!use_raycaster)
@ -1155,7 +1171,7 @@ void visual_menu() {
void settings_menu() { void settings_menu() {
dialog::init("Bringris settings"); dialog::init("Bringris settings");
dialog::addItem("geometry", 'g'); dialog::addItem("alternative geometry", 'g');
dialog::add_action_push(geometry_menu); dialog::add_action_push(geometry_menu);
dialog::addItem("visuals", 's'); dialog::addItem("visuals", 's');
dialog::add_action_push(visual_menu); dialog::add_action_push(visual_menu);
@ -1213,7 +1229,6 @@ void run() {
sh = lerp(C0, sh, 1-part); sh = lerp(C0, sh, 1-part);
pView = eupush(sh); pView = eupush(sh);
smooth = inverse(pView); smooth = inverse(pView);
println(hlog, "smooth = ", tC0(smooth));
} }
else { else {
ld part = (ticks - last_adjust) * 1. / (when_t - last_adjust); ld part = (ticks - last_adjust) * 1. / (when_t - last_adjust);
@ -1223,7 +1238,8 @@ void run() {
ld alpha = atan2(Tspin*xpush0(1)); ld alpha = atan2(Tspin*xpush0(1));
pView = spin(alpha * part) * gpushxto0(direct_exp(vec*part)) * pView; pView = spin(alpha * part) * gpushxto0(direct_exp(vec*part)) * pView;
fixmatrix(pView); fixmatrix(pView);
smooth = tView * inverse(pView); smooth = inverse(pView) * cview().T;
// println(hlog, "smooth = ", smooth);
} }
last_adjust = ticks; last_adjust = ticks;