1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-02-08 23:20:12 +00:00

refactored the vertical movement functions

This commit is contained in:
Zeno Rogue 2022-12-06 01:04:26 +01:00
parent adfab30c62
commit bf001926c2
12 changed files with 210 additions and 181 deletions

View File

@ -96,11 +96,11 @@ void geometry_information::add_prism(ld z0, vector<hyperpoint> vh0, ld z1, vecto
} }
void geometry_information::shift_last(ld z) { void geometry_information::shift_last(ld z) {
for(int i=last->s; i<isize(hpc); i++) hpc[i] = zshift(hpc[i], z); for(int i=last->s; i<isize(hpc); i++) hpc[i] = lzpush(z) * hpc[i];
} }
void geometry_information::shift_shape(hpcshape& sh, ld z) { void geometry_information::shift_shape(hpcshape& sh, ld z) {
for(int i=sh.s; i<sh.e; i++) hpc[i] = zshift(hpc[i], z); for(int i=sh.s; i<sh.e; i++) hpc[i] = lzpush(z) * hpc[i];
} }
void geometry_information::shift_shape_orthogonally(hpcshape& sh, ld z) { void geometry_information::shift_shape_orthogonally(hpcshape& sh, ld z) {

View File

@ -714,7 +714,7 @@ void celldrawer::draw_wall() {
int hdir = 0; int hdir = 0;
for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->wall == waClosedGate) for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->wall == waClosedGate)
hdir = i; hdir = i;
shiftmatrix V2 = mscale(V, wmspatial?cgi.WALL:1) * ddspin180(c, hdir); shiftmatrix V2 = orthogonal_move_fol(V, wmspatial?cgi.WALL:1) * ddspin180(c, hdir); // to test
queuepolyat(V2, cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL); queuepolyat(V2, cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL);
starcol = 0; starcol = 0;
} }
@ -742,7 +742,7 @@ void celldrawer::draw_wall() {
if(starcol) queuepoly(V1, shThisWall, darkena(starcol, 0, 0xFF)); if(starcol) queuepoly(V1, shThisWall, darkena(starcol, 0, 0xFF));
} }
else { else {
shiftmatrix Vdepth = mscale(V1, cgi.WALL); shiftmatrix Vdepth = orthogonal_move_fol(V1, cgi.WALL);
int alpha = 0xFF; int alpha = 0xFF;
if(c->wall == waIcewall) if(c->wall == waIcewall)
alpha = 0xC0; alpha = 0xC0;
@ -790,8 +790,8 @@ void celldrawer::draw_boat() {
nospin = c->wall == waBoat && applyAnimation(c, Vboat, footphase, LAYER_BOAT); nospin = c->wall == waBoat && applyAnimation(c, Vboat, footphase, LAYER_BOAT);
if(!nospin) Vboat = face_the_player(V); if(!nospin) Vboat = face_the_player(V);
else Vboat = Vboat * cspin180(0, 2); else Vboat = Vboat * cspin180(0, 2);
queuepolyat(mscale(Vboat, cgi.scalefactor/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2); queuepolyat(orthogonal_move(Vboat, cgi.scalefactor/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2);
queuepolyat(mscale(Vboat, cgi.scalefactor/2-0.01), cgi.shBoatInner, incol, PPR::BOATLEV2); queuepolyat(orthogonal_move(Vboat, cgi.scalefactor/2-0.01), cgi.shBoatInner, incol, PPR::BOATLEV2);
return; return;
} }
@ -812,10 +812,10 @@ void celldrawer::draw_boat() {
animations[LAYER_SMALL][c].footphase = 0; animations[LAYER_SMALL][c].footphase = 0;
} }
if(wmspatial && GDIM == 2) if(wmspatial && GDIM == 2)
queuepolyat(mscale(Vboat, (cgi.LAKE+1)/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2); queuepolyat(orthogonal_move_fol(Vboat, (cgi.LAKE+1)/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2);
if(GDIM == 3) { if(GDIM == 3) {
queuepoly(mscale(Vboat, -0.004), cgi.shBoatOuter, outcol); queuepoly(orthogonal_move(Vboat, -0.004), cgi.shBoatOuter, outcol);
queuepoly(mscale(Vboat, -0.008), cgi.shBoatInner, incol); queuepoly(orthogonal_move(Vboat, -0.008), cgi.shBoatInner, incol);
} }
else { else {
queuepoly(Vboat, cgi.shBoatOuter, outcol); queuepoly(Vboat, cgi.shBoatOuter, outcol);
@ -947,7 +947,7 @@ void celldrawer::draw_halfvine() {
set_floor(cgi.shSemiFeatherFloor[0]); set_floor(cgi.shSemiFeatherFloor[0]);
int dk = 1; int dk = 1;
int vcol = winf[waVinePlant].color; int vcol = winf[waVinePlant].color;
draw_qfi(c, mscale(V2, cgi.WALL), darkena(vcol, dk, 0xFF), PPR::WALL3A); draw_qfi(c, orthogonal_move_fol(V2, cgi.WALL), darkena(vcol, dk, 0xFF), PPR::WALL3A);
escherSidewall(c, SIDE_WALL, V2, darkena(gradient(0, vcol, 0, .8, 1), dk, 0xFF)); escherSidewall(c, SIDE_WALL, V2, darkena(gradient(0, vcol, 0, .8, 1), dk, 0xFF));
queuepoly(V2, cgi.shSemiFeatherFloor[1], darkena(fcol, dk, 0xFF)); queuepoly(V2, cgi.shSemiFeatherFloor[1], darkena(fcol, dk, 0xFF));
set_floor(cgi.shFeatherFloor); set_floor(cgi.shFeatherFloor);
@ -961,7 +961,7 @@ void celldrawer::draw_halfvine() {
int vcol = winf[waVinePlant].color; int vcol = winf[waVinePlant].color;
int vcol2 = gradient(0, vcol, 0, .8, 1); int vcol2 = gradient(0, vcol, 0, .8, 1);
shiftmatrix Vdepth = mscale(V2, cgi.WALL); shiftmatrix Vdepth = orthogonal_move_fol(V2, cgi.WALL);
queuepolyat(GDIM == 2 ? Vdepth : V2, cgi.shSemiFloor[0], darkena(vcol, fd, 0xFF), PPR::WALL3A); queuepolyat(GDIM == 2 ? Vdepth : V2, cgi.shSemiFloor[0], darkena(vcol, fd, 0xFF), PPR::WALL3A);
if(!noshadow) { if(!noshadow) {
@ -1028,7 +1028,7 @@ void celldrawer::draw_mirrorwall() {
else if(wmspatial) { else if(wmspatial) {
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<layers; z++) for(int z=1; z<layers; z++)
queuepolyat(mscale(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL3+z-layers); queuepolyat(orthogonal_move_fol(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL3+z-layers);
} }
else else
queuepolyat(V2, cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL3); queuepolyat(V2, cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL3);
@ -1056,7 +1056,7 @@ void celldrawer::draw_mirrorwall() {
else if(wmspatial) { else if(wmspatial) {
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<layers; z++) for(int z=1; z<layers; z++)
queuepolyat(mscale(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL3+z-layers); queuepolyat(orthogonal_move_fol(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL3+z-layers);
} }
else else
queuepolyat(V2, cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL3); queuepolyat(V2, cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL3);
@ -1281,8 +1281,8 @@ void celldrawer::set_land_floor(const shiftmatrix& Vf) {
shiftmatrix Vbspin = Vf * bspin; shiftmatrix Vbspin = Vf * bspin;
queuepoly(Vbspin, cgi.shMercuryBridge[1], darkena(fcol, fd+1, 0xFF)); queuepoly(Vbspin, cgi.shMercuryBridge[1], darkena(fcol, fd+1, 0xFF));
if(wmspatial) { if(wmspatial) {
queuepolyat(mscale(Vbspin, cgi.LAKE), cgi.shMercuryBridge[1], darkena(gradient(0, winf[waMercury].color, 0, 0.8,1), 0, 0x80), PPR::LAKELEV); queuepolyat(orthogonal_move_fol(Vbspin, cgi.LAKE), cgi.shMercuryBridge[1], darkena(gradient(0, winf[waMercury].color, 0, 0.8,1), 0, 0x80), PPR::LAKELEV);
queuepolyat(mscale(Vbspin, cgi.BOTTOM), cgi.shMercuryBridge[1], darkena(0x202020, 0, 0xFF), PPR::LAKEBOTTOM); queuepolyat(orthogonal_move_fol(Vbspin, cgi.BOTTOM), cgi.shMercuryBridge[1], darkena(0x202020, 0, 0xFF), PPR::LAKEBOTTOM);
} }
} }
} }
@ -1377,30 +1377,30 @@ void celldrawer::draw_features() {
case waBigBush: case waBigBush:
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL);
if(detaillevel >= 1) if(detaillevel >= 1)
queuepolyat(mmscale(V, cgi.SLEV[1]) * pispin, cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); queuepolyat(at_smart_lof(V, cgi.SLEV[1]) * pispin, cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1);
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2);
queuepolyat(mmscale(V, cgi.SLEV[2]), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); queuepolyat(at_smart_lof(V, cgi.SLEV[2]), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3);
break; break;
case waSmallBush: case waSmallBush:
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL);
if(detaillevel >= 1) if(detaillevel >= 1)
queuepolyat(mmscale(V, cgi.SLEV[1]) * pispin, cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); queuepolyat(at_smart_lof(V, cgi.SLEV[1]) * pispin, cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1);
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2);
queuepolyat(mmscale(V, cgi.SLEV[2]), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); queuepolyat(at_smart_lof(V, cgi.SLEV[2]), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3);
break; break;
case waSolidBranch: case waSolidBranch:
queuepoly(GDIM == 3 ? mscale(V, cgi.BODY) : V, cgi.shSolidBranch, darkena(wcol, 0, 0xFF)); queuepoly(GDIM == 3 ? orthogonal_move_fol(V, cgi.BODY) : V, cgi.shSolidBranch, darkena(wcol, 0, 0xFF));
break; break;
case waWeakBranch: case waWeakBranch:
queuepoly(GDIM == 3 ? mscale(V, cgi.BODY) : V, cgi.shWeakBranch, darkena(wcol, 0, 0xFF)); queuepoly(GDIM == 3 ? orthogonal_move_fol(V, cgi.BODY) : V, cgi.shWeakBranch, darkena(wcol, 0, 0xFF));
break; break;
case waLadder: case waLadder:
@ -1458,7 +1458,7 @@ void celldrawer::draw_features() {
if(drawstar(c)) { if(drawstar(c)) {
aura_color = wcol; aura_color = wcol;
if(wmspatial) if(wmspatial)
queuepolyat(mscale(V, cgi.HELLSPIKE), cgi.shGiantStar[ct6], darkena(wcol, 0, 0x40), PPR::HELLSPIKE); queuepolyat(orthogonal_move_fol(V, cgi.HELLSPIKE), cgi.shGiantStar[ct6], darkena(wcol, 0, 0x40), PPR::HELLSPIKE);
else else
queuepoly(V, cgi.shGiantStar[ct6], darkena(wcol, 0, 0xFF)); queuepoly(V, cgi.shGiantStar[ct6], darkena(wcol, 0, 0xFF));
} }
@ -1543,7 +1543,7 @@ void celldrawer::draw_features() {
if(wmspatial) { if(wmspatial) {
color_t col = winf[waGlass].color; color_t col = winf[waGlass].color;
int dcol = darkena(col, 0, 0x80); int dcol = darkena(col, 0, 0x80);
shiftmatrix Vdepth = mscale(Vd, cgi.WALL); shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL);
if(GDIM == 3) if(GDIM == 3)
draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL);
else else
@ -1567,7 +1567,7 @@ void celldrawer::draw_features() {
case waArrowTrap: case waArrowTrap:
if(c->wparam >= 1) if(c->wparam >= 1)
queuepoly(mscale(V, cgi.FLOOR), cgi.shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF)); queuepoly(orthogonal_move_fol(V, cgi.FLOOR), cgi.shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF));
if(isCentralTrap(c)) arrowtraps.push_back(c); if(isCentralTrap(c)) arrowtraps.push_back(c);
break; break;
@ -1584,7 +1584,7 @@ void celldrawer::draw_features() {
draw_floorshape(c, V, cgi.shMFloor2, darkena(0x600000, 0, 0xFF)); draw_floorshape(c, V, cgi.shMFloor2, darkena(0x600000, 0, 0xFF));
} }
if(c->wparam >= 1) if(c->wparam >= 1)
queuepoly(mscale(V, cgi.FLOOR), cgi.shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF)); queuepoly(orthogonal_move_fol(V, cgi.FLOOR), cgi.shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF));
break; break;
case waGiantRug: case waGiantRug:
@ -1660,7 +1660,7 @@ void celldrawer::draw_features() {
if(wmspatial) { if(wmspatial) {
color_t col = winf[c->wall].color; color_t col = winf[c->wall].color;
int dcol = darkena(col, 0, 0xC0); int dcol = darkena(col, 0, 0xC0);
shiftmatrix Vdepth = mscale(Vd, cgi.WALL); shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL);
if(GDIM == 3) if(GDIM == 3)
draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL);
else else
@ -1912,7 +1912,7 @@ void celldrawer::check_rotations() {
ds.total += unshift(tC0(V)); ds.total += unshift(tC0(V));
ds.qty++; ds.qty++;
ds.point = normalize_flat(ds.total); ds.point = normalize_flat(ds.total);
if(prod) ds.point = zshift(ds.point, ds.depth / ds.qty); if(prod) ds.point = orthogonal_move(ds.point, ds.depth / ds.qty);
if(side == 2) for(int i=0; i<3; i++) ds.point[i] = -ds.point[i]; if(side == 2) for(int i=0; i<3; i++) ds.point[i] = -ds.point[i];
if(side == 1) ds.point = spin(-90._deg) * ds.point; if(side == 1) ds.point = spin(-90._deg) * ds.point;
} }
@ -2106,7 +2106,7 @@ void celldrawer::draw_cellstat() {
void celldrawer::draw_wall_full() { void celldrawer::draw_wall_full() {
shiftmatrix Vf0; shiftmatrix Vf0;
const shiftmatrix& Vf = (chasmg && wmspatial) ? (Vf0=mscale(V, cgi.BOTTOM)) : V; const shiftmatrix& Vf = (chasmg && wmspatial) ? (Vf0=orthogonal_move_fol(V, cgi.BOTTOM)) : V;
#if CAP_SHAPES #if CAP_SHAPES
int flooralpha = 255; int flooralpha = 255;
@ -2133,9 +2133,9 @@ void celldrawer::draw_wall_full() {
if(GDIM == 2 && (c->land != laRose || ls::any_chaos())) { if(GDIM == 2 && (c->land != laRose || ls::any_chaos())) {
int rd = rosedist(c); int rd = rosedist(c);
if(rd == 1) if(rd == 1)
draw_floorshape(c, mmscale(V, cgi.SLEV[2]), cgi.shRoseFloor, 0x80406040, PPR::LIZEYE); draw_floorshape(c, at_smart_lof(V, cgi.SLEV[2]), cgi.shRoseFloor, 0x80406040, PPR::LIZEYE);
if(rd == 2) if(rd == 2)
draw_floorshape(c, mmscale(V, cgi.SLEV[2]), cgi.shRoseFloor, 0x80406080, PPR::LIZEYE); draw_floorshape(c, at_smart_lof(V, cgi.SLEV[2]), cgi.shRoseFloor, 0x80406080, PPR::LIZEYE);
} }
if(c->wall == waChasm) { if(c->wall == waChasm) {
@ -2149,7 +2149,7 @@ void celldrawer::draw_wall_full() {
} }
if(c->land == laZebra) fd++; if(c->land == laZebra) fd++;
if(c->land == laHalloween && !wmblack) { if(c->land == laHalloween && !wmblack) {
shiftmatrix Vdepth = wmspatial ? mscale(V, cgi.BOTTOM) : V; shiftmatrix Vdepth = wmspatial ? orthogonal_move_fol(V, cgi.BOTTOM) : V;
if(GDIM == 3) if(GDIM == 3)
draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_LAKE], darkena(firecolor(0, 10), 0, 0xDF), PPR::TRANSPARENT_LAKE); draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_LAKE], darkena(firecolor(0, 10), 0, 0xDF), PPR::TRANSPARENT_LAKE);
else else
@ -2240,7 +2240,7 @@ void celldrawer::draw_wall_full() {
if(WDIM == 2 && GDIM == 3 && qfi.fshape) if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[sid], col, PPR::LAKEBOTTOM); draw_shapevec(c, V, qfi.fshape->levels[sid], col, PPR::LAKEBOTTOM);
else else
draw_qfi(c, mscale(V, cgi.BOTTOM), col, PPR::LAKEBOTTOM); draw_qfi(c, orthogonal_move_fol(V, cgi.BOTTOM), col, PPR::LAKEBOTTOM);
int fd0 = fd ? fd-1 : 0; int fd0 = fd ? fd-1 : 0;
if(WDIM == 2 && GDIM == 3 && qfi.fshape) if(WDIM == 2 && GDIM == 3 && qfi.fshape)
@ -2386,7 +2386,7 @@ void celldrawer::draw_wall_full() {
bool dbot = true; bool dbot = true;
forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) { forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) {
if(dbot) dbot = false, if(dbot) dbot = false,
draw_qfi(c, mscale(V, cgi.BOTTOM), 0x080808FF, PPR::LAKEBOTTOM); draw_qfi(c, orthogonal_move_fol(V, cgi.BOTTOM), 0x080808FF, PPR::LAKEBOTTOM);
if(placeSidewall(c, i, SIDE_BTOI, V, D(.6))) break; if(placeSidewall(c, i, SIDE_BTOI, V, D(.6))) break;
} }
#undef D #undef D
@ -2648,14 +2648,14 @@ void celldrawer::draw_gravity_particles() {
case gsNormal: case gsNormal:
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
shiftmatrix T = V * spin(i*degree*60) * xpush(cgi.crossf/3); shiftmatrix T = V * spin(i*degree*60) * xpush(cgi.crossf/3);
queueline(mmscale(T, levf(r0)) * C0, mmscale(T, levf(r1)) * C0, grav_normal_color); queueline(at_smart_lof(T, levf(r0)) * C0, at_smart_lof(T, levf(r1)) * C0, grav_normal_color);
} }
break; break;
case gsAnti: case gsAnti:
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
shiftmatrix T = V * spin(i*degree*60) * xpush(cgi.crossf/3); shiftmatrix T = V * spin(i*degree*60) * xpush(cgi.crossf/3);
queueline(mmscale(T, levf(r0)) * C0, mmscale(T, levf(r1)) * C0, antigrav_color); queueline(at_smart_lof(T, levf(r0)) * C0, at_smart_lof(T, levf(r1)) * C0, antigrav_color);
} }
break; break;
@ -2664,7 +2664,7 @@ void celldrawer::draw_gravity_particles() {
shiftmatrix T0 = V * spin(i*degree*60 + tt/60. * degree) * xpush(cgi.crossf/3); shiftmatrix T0 = V * spin(i*degree*60 + tt/60. * degree) * xpush(cgi.crossf/3);
shiftmatrix T1 = V * spin(i*degree*60 + (tt/60. + 30) * degree) * xpush(cgi.crossf/3); shiftmatrix T1 = V * spin(i*degree*60 + (tt/60. + 30) * degree) * xpush(cgi.crossf/3);
ld lv = levf(GDIM == 3 ? (i+0.5)/6 : 0.5); ld lv = levf(GDIM == 3 ? (i+0.5)/6 : 0.5);
queueline(mmscale(T0, lv) * C0, mmscale(T1, lv) * C0, levitate_color); queueline(at_smart_lof(T0, lv) * C0, at_smart_lof(T1, lv) * C0, levitate_color);
} }
break; break;
} }
@ -2792,10 +2792,10 @@ void celldrawer::draw() {
Vd = Vd =
WDIM == 3 ? V: WDIM == 3 ? V:
!wmspatial ? V : !wmspatial ? V :
sl ? mscale(V, GDIM == 3 ? cgi.SLEV[sl] - cgi.FLOOR : cgi.SLEV[sl]) : sl ? orthogonal_move_fol(V, GDIM == 3 ? cgi.SLEV[sl] - cgi.FLOOR : cgi.SLEV[sl]) :
(highwall(c) && GDIM == 2) ? mscale(V, (1+cgi.WALL)/2) : (highwall(c) && GDIM == 2) ? orthogonal_move_fol(V, (1+cgi.WALL)/2) :
#if CAP_SHAPES #if CAP_SHAPES
(chasmg==1) ? mscale(V, GDIM == 3 ? cgi.LAKE - cgi.FLOOR : cgi.LAKE) : (chasmg==1) ? orthogonal_move_fol(V, GDIM == 3 ? cgi.LAKE - cgi.FLOOR : cgi.LAKE) :
#endif #endif
V; V;
@ -2840,35 +2840,35 @@ void celldrawer::draw() {
string s1 = s0+asciichar1; string s1 = s0+asciichar1;
poly_outline = bordcolor << 8; poly_outline = bordcolor << 8;
for(int z=0; z<layers; z++) for(int z=0; z<layers; z++)
queuestrn(mscale(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), 1. - z * .5 / layers, s1, darkenedby(gradient(bordcolor, asciicol1, -layers, z, layers), darken), 1); queuestrn(orthogonal_move_fol(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), 1. - z * .5 / layers, s1, darkenedby(gradient(bordcolor, asciicol1, -layers, z, layers), darken), 1);
poly_outline = asciiborder << 8; poly_outline = asciiborder << 8;
queuestrn(mscale(V, cgi.WALL), asciicol == asciicol1 && asciichar == asciichar1 ? .5 : 1, s, darkenedby(asciicol, darken), 2); queuestrn(orthogonal_move_fol(V, cgi.WALL), asciicol == asciicol1 && asciichar == asciichar1 ? .5 : 1, s, darkenedby(asciicol, darken), 2);
} }
else if(highwall(c)) { else if(highwall(c)) {
const int layers = 1 << detaillevel; const int layers = 1 << detaillevel;
string s1 = s0+asciichar1; string s1 = s0+asciichar1;
poly_outline = bordcolor << 8; poly_outline = bordcolor << 8;
for(int z=0; z<layers; z++) for(int z=0; z<layers; z++)
queuestrn(mscale(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), 1, s1, darkenedby(gradient(bordcolor, asciicol1, -layers, z, layers), darken), 1); queuestrn(orthogonal_move_fol(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), 1, s1, darkenedby(gradient(bordcolor, asciicol1, -layers, z, layers), darken), 1);
poly_outline = asciiborder << 8; poly_outline = asciiborder << 8;
queuestrn(mscale(V, cgi.WALL), 1, s, darkenedby(asciicol, darken), 2); queuestrn(orthogonal_move_fol(V, cgi.WALL), 1, s, darkenedby(asciicol, darken), 2);
} }
else if((sl = snakelevel(c))) { else if((sl = snakelevel(c))) {
string s1 = s0+asciichar1; string s1 = s0+asciichar1;
poly_outline = bordcolor << 8; poly_outline = bordcolor << 8;
for(int z=0; z<sl*4; z++) if(z%4 == 0) for(int z=0; z<sl*4; z++) if(z%4 == 0)
queuestrn(mscale(V, zgrad0(0, cgi.slev * sl, z, sl*4)), 1, s1, darkenedby(gradient(bordcolor, asciicol1, -sl, z, sl*4), darken), 1); queuestrn(orthogonal_move_fol(V, zgrad0(0, cgi.slev * sl, z, sl*4)), 1, s1, darkenedby(gradient(bordcolor, asciicol1, -sl, z, sl*4), darken), 1);
poly_outline = asciiborder << 8; poly_outline = asciiborder << 8;
queuestrn(mscale(V, cgi.SLEV[sl]), 1, s, darkenedby(asciicol, darken), 2); queuestrn(orthogonal_move_fol(V, cgi.SLEV[sl]), 1, s, darkenedby(asciicol, darken), 2);
} }
// else if(c->wall == waChasm) { // else if(c->wall == waChasm) {
// const int layers = 1 << detaillevel; // const int layers = 1 << detaillevel;
// queuestr(mscale(V, BOTTOM), zgrad0(0, -vid.lake_bottom, z, layers)), 1, s, darkenedby(gradient(asciicol, 0, 0, z, layers+1), darken), z==0?2:1); // queuestr(orthogonal_move_fol(V, BOTTOM), zgrad0(0, -vid.lake_bottom, z, layers)), 1, s, darkenedby(gradient(asciicol, 0, 0, z, layers+1), darken), z==0?2:1);
// } // }
else if(chasmgraph(c)) { else if(chasmgraph(c)) {
string s1 = s0+asciichar1; string s1 = s0+asciichar1;
poly_outline = bordcolor << 8; poly_outline = bordcolor << 8;
queuestrn(mscale(V, cgi.BOTTOM), 1, s1, darkenedby(gradient(bordcolor, asciicol1, 0, 0.3, 1), darken), 2); queuestrn(orthogonal_move_fol(V, cgi.BOTTOM), 1, s1, darkenedby(gradient(bordcolor, asciicol1, 0, 0.3, 1), darken), 2);
poly_outline = asciiborder << 8; poly_outline = asciiborder << 8;
queuestrn(V, 1, s, darkenedby(asciicol, darken), 2); queuestrn(V, 1, s, darkenedby(asciicol, darken), 2);
} }

View File

@ -1356,7 +1356,7 @@ EX namespace dice {
h = zpush(-z) * h; h = zpush(-z) * h;
h[2] = h[3]; h[3] = 0; h[2] = h[3]; h[3] = 0;
dynamicval<eGeometry> g(geometry, orig); dynamicval<eGeometry> g(geometry, orig);
return zshift(h, geom3::scale_at_lev(z)); return orthogonal_move(h, z);
}; };
for(int d=0; d<=si; d++) { for(int d=0; d<=si; d++) {

View File

@ -379,9 +379,9 @@ void virtualRebase(cell*& base, T& at, const U& check) {
base = base->cmove(base->type-2); d += cgi.plevel; base = base->cmove(base->type-2); d += cgi.plevel;
} }
auto w = hybrid::get_where(base); auto w = hybrid::get_where(base);
at = mscale(at, -d); at = orthogonal_move(at, -d);
PIU( virtualRebase(w.first, at, check) ); PIU( virtualRebase(w.first, at, check) );
at = mscale(at, +d); at = orthogonal_move(at, +d);
base = hybrid::get_at(w.first, w.second); base = hybrid::get_at(w.first, w.second);
return; return;
} }

141
graph.cpp
View File

@ -538,6 +538,15 @@ double footfun(double d) {
EX bool ivoryz; EX bool ivoryz;
/** Change the level of V. Takes ivoryz and all geometries into account */
EX transmatrix at_smart_lof(const transmatrix& V, ld lev) {
if(!mmspatial) return V;
if(ivoryz) return mzscale(V, lev);
return orthogonal_move_fol(V, lev);
}
EX shiftmatrix at_smart_lof(const shiftmatrix& V, ld lev) { return shiftless(at_smart_lof(V.T, lev), V.shift); }
void animallegs(const shiftmatrix& V, eMonster mo, color_t col, double footphase) { void animallegs(const shiftmatrix& V, eMonster mo, color_t col, double footphase) {
#if CAP_SHAPES #if CAP_SHAPES
footphase /= SCALE; footphase /= SCALE;
@ -578,8 +587,8 @@ void animallegs(const shiftmatrix& V, eMonster mo, color_t col, double footphase
} }
#endif #endif
const shiftmatrix VL = mmscale(V, cgi.ALEG0); const shiftmatrix VL = at_smart_lof(V, cgi.ALEG0);
const shiftmatrix VAML = mmscale(V, cgi.ALEG); const shiftmatrix VAML = at_smart_lof(V, cgi.ALEG);
if(x[0]) queuepolyat(VL * xpush(rightfoot), *x[0], col, PPR::MONSTER_FOOT); if(x[0]) queuepolyat(VL * xpush(rightfoot), *x[0], col, PPR::MONSTER_FOOT);
if(x[0]) queuepolyat(VL * Mirror * xpush(leftfoot), *x[0], col, PPR::MONSTER_FOOT); if(x[0]) queuepolyat(VL * Mirror * xpush(leftfoot), *x[0], col, PPR::MONSTER_FOOT);
@ -620,28 +629,28 @@ EX void ShadowV(const shiftmatrix& V, const hpcshape& bp, PPR prio IS(PPR::MONST
#if CAP_SHAPES #if CAP_SHAPES
transmatrix otherbodyparts(const shiftmatrix& V, color_t col, eMonster who, double footphase) { transmatrix otherbodyparts(const shiftmatrix& V, color_t col, eMonster who, double footphase) {
#define VFOOT ((GDIM == 2 || hybri) ? V : mmscale(V, cgi.LEG0)) #define VFOOT ((GDIM == 2 || hybri) ? V : at_smart_lof(V, cgi.LEG0))
#define VLEG mmscale(V, cgi.LEG) #define VLEG at_smart_lof(V, cgi.LEG)
#define VGROIN mmscale(V, cgi.GROIN) #define VGROIN at_smart_lof(V, cgi.GROIN)
#define VBODY mmscale(V, cgi.BODY) #define VBODY at_smart_lof(V, cgi.BODY)
#define VBODY1 mmscale(V, cgi.BODY1) #define VBODY1 at_smart_lof(V, cgi.BODY1)
#define VBODY2 mmscale(V, cgi.BODY2) #define VBODY2 at_smart_lof(V, cgi.BODY2)
#define VBODY3 mmscale(V, cgi.BODY3) #define VBODY3 at_smart_lof(V, cgi.BODY3)
#define VNECK mmscale(V, cgi.NECK) #define VNECK at_smart_lof(V, cgi.NECK)
#define VHEAD mmscale(V, cgi.HEAD) #define VHEAD at_smart_lof(V, cgi.HEAD)
#define VHEAD1 mmscale(V, cgi.HEAD1) #define VHEAD1 at_smart_lof(V, cgi.HEAD1)
#define VHEAD2 mmscale(V, cgi.HEAD2) #define VHEAD2 at_smart_lof(V, cgi.HEAD2)
#define VHEAD3 mmscale(V, cgi.HEAD3) #define VHEAD3 at_smart_lof(V, cgi.HEAD3)
#define VALEGS V #define VALEGS V
#define VABODY mmscale(V, cgi.ABODY) #define VABODY at_smart_lof(V, cgi.ABODY)
#define VAHEAD mmscale(V, cgi.AHEAD) #define VAHEAD at_smart_lof(V, cgi.AHEAD)
#define VFISH V #define VFISH V
#define VBIRD ((GDIM == 3 || (where && bird_disruption(where))) ? (WDIM == 2 ? mmscale(V, cgi.BIRD) : V) : mmscale(V, cgi.BIRD + .05 * sintick(1000, static_cast<int>(reinterpret_cast<size_t>(where))/1000.))) #define VBIRD ((GDIM == 3 || (where && bird_disruption(where))) ? (WDIM == 2 ? at_smart_lof(V, cgi.BIRD) : V) : at_smart_lof(V, cgi.BIRD + .05 * sintick(1000, static_cast<int>(reinterpret_cast<size_t>(where))/1000.)))
#define VGHOST mmscale(V, cgi.GHOST) #define VGHOST at_smart_lof(V, cgi.GHOST)
#define VSLIMEEYE mscale(V, cgi.FLATEYE) #define VSLIMEEYE orthogonal_move_fol(V, cgi.FLATEYE)
// if(!mmspatial && !footphase && who != moSkeleton) return; // if(!mmspatial && !footphase && who != moSkeleton) return;
@ -653,19 +662,19 @@ transmatrix otherbodyparts(const shiftmatrix& V, color_t col, eMonster who, doub
// todo // todo
if(detaillevel >= 2 && GDIM == 2) { if(detaillevel >= 2 && GDIM == 2) {
shiftmatrix VL = mmscale(V, cgi.LEG1); shiftmatrix VL = at_smart_lof(V, cgi.LEG1);
queuepoly(VL * xpush(rightfoot*3/4), cgi.shHumanLeg, col); queuepoly(VL * xpush(rightfoot*3/4), cgi.shHumanLeg, col);
queuepoly(VL * Mirror * xpush(-rightfoot*3/4), cgi.shHumanLeg, col); queuepoly(VL * Mirror * xpush(-rightfoot*3/4), cgi.shHumanLeg, col);
} }
if(GDIM == 2) { if(GDIM == 2) {
shiftmatrix VL = mmscale(V, cgi.LEG); shiftmatrix VL = at_smart_lof(V, cgi.LEG);
queuepoly(VL * xpush(rightfoot/2), cgi.shHumanLeg, col); queuepoly(VL * xpush(rightfoot/2), cgi.shHumanLeg, col);
queuepoly(VL * Mirror * xpush(-rightfoot/2), cgi.shHumanLeg, col); queuepoly(VL * Mirror * xpush(-rightfoot/2), cgi.shHumanLeg, col);
} }
if(detaillevel >= 2 && GDIM == 2) { if(detaillevel >= 2 && GDIM == 2) {
shiftmatrix VL = mmscale(V, cgi.LEG3); shiftmatrix VL = at_smart_lof(V, cgi.LEG3);
queuepoly(VL * xpush(rightfoot/4), cgi.shHumanLeg, col); queuepoly(VL * xpush(rightfoot/4), cgi.shHumanLeg, col);
queuepoly(VL * Mirror * xpush(-rightfoot/4), cgi.shHumanLeg, col); queuepoly(VL * Mirror * xpush(-rightfoot/4), cgi.shHumanLeg, col);
} }
@ -707,14 +716,14 @@ transmatrix otherbodyparts(const shiftmatrix& V, color_t col, eMonster who, doub
if(GDIM == 3 || !mmspatial) return spin(rightfoot * wobble); if(GDIM == 3 || !mmspatial) return spin(rightfoot * wobble);
if(detaillevel >= 2 && who != moZombie) if(detaillevel >= 2 && who != moZombie)
queuepoly(mmscale(V, cgi.NECK1), cgi.shHumanNeck, col); queuepoly(at_smart_lof(V, cgi.NECK1), cgi.shHumanNeck, col);
if(detaillevel >= 1) { if(detaillevel >= 1) {
queuepoly(VGROIN, cgi.shHumanGroin, col); queuepoly(VGROIN, cgi.shHumanGroin, col);
if(who != moZombie) queuepoly(VNECK, cgi.shHumanNeck, col); if(who != moZombie) queuepoly(VNECK, cgi.shHumanNeck, col);
} }
if(detaillevel >= 2) { if(detaillevel >= 2) {
queuepoly(mmscale(V, cgi.GROIN1), cgi.shHumanGroin, col); queuepoly(at_smart_lof(V, cgi.GROIN1), cgi.shHumanGroin, col);
if(who != moZombie) queuepoly(mmscale(V, cgi.NECK3), cgi.shHumanNeck, col); if(who != moZombie) queuepoly(at_smart_lof(V, cgi.NECK3), cgi.shHumanNeck, col);
} }
return spin(rightfoot * wobble); return spin(rightfoot * wobble);
@ -749,7 +758,7 @@ EX color_t kind_outline(eItem it) {
EX shiftmatrix face_the_player(const shiftmatrix V) { EX shiftmatrix face_the_player(const shiftmatrix V) {
if(GDIM == 2) return V; if(GDIM == 2) return V;
if(prod) return mscale(V, cos(ptick(750)) * cgi.plevel / 16); if(prod) return orthogonal_move(V, cos(ptick(750)) * cgi.plevel / 16);
if(hybri) return V * zpush(cos(ptick(750)) * cgi.plevel / 16); if(hybri) return V * zpush(cos(ptick(750)) * cgi.plevel / 16);
transmatrix dummy; /* used only in prod anyways */ transmatrix dummy; /* used only in prod anyways */
if(nonisotropic) return shiftless(spin_towards(unshift(V), dummy, C0, 2, 0)); if(nonisotropic) return shiftless(spin_towards(unshift(V), dummy, C0, 2, 0));
@ -884,9 +893,9 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int
poly_outline = kind_outline(it); poly_outline = kind_outline(it);
shiftmatrix Vit = V; shiftmatrix Vit = V;
if(GDIM == 3 && WDIM == 2 && c && it != itBabyTortoise) Vit = mscale(V, cgi.STUFF); if(GDIM == 3 && WDIM == 2 && c && it != itBabyTortoise) Vit = orthogonal_move_fol(V, cgi.STUFF);
if(c && prod) if(c && prod)
Vit = mscale(Vit, sin(ptick(750)) * cgi.plevel / 4); Vit = orthogonal_move(Vit, sin(ptick(750)) * cgi.plevel / 4);
else if(c && sl2) else if(c && sl2)
Vit = Vit * zpush(sin(ptick(750)) * cgi.plevel / 4); Vit = Vit * zpush(sin(ptick(750)) * cgi.plevel / 4);
else else
@ -952,7 +961,7 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int
} }
if(GDIM == 3) { if(GDIM == 3) {
queue_ring(Vit, cgi.shRing, 0xFFFFFFFF, PPR::ITEM); queue_ring(Vit, cgi.shRing, 0xFFFFFFFF, PPR::ITEM);
if(WDIM == 2) V2 = mscale(V2, cgi.STUFF); if(WDIM == 2) V2 = orthogonal_move_fol(V2, cgi.STUFF);
V2 = V2 * cspin(1, 2, M_PI * sintick(100) / 39); V2 = V2 * cspin(1, 2, M_PI * sintick(100) / 39);
queuepoly(V2, cgi.shCompass3, 0xFF0000FF); queuepoly(V2, cgi.shCompass3, 0xFF0000FF);
queuepoly(V2 * pispin, cgi.shCompass3, 0x000000FF); queuepoly(V2 * pispin, cgi.shCompass3, 0x000000FF);
@ -1732,7 +1741,7 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t
case moFrog: case moPhaser: case moVaulter: { case moFrog: case moPhaser: case moVaulter: {
ShadowV(V, cgi.shFrogBody); ShadowV(V, cgi.shFrogBody);
const shiftmatrix VL = GDIM == 3 ? V : mmscale(V, cgi.ALEG0); const shiftmatrix VL = GDIM == 3 ? V : at_smart_lof(V, cgi.ALEG0);
color_t xcolor = darkena(0xFF0000, 1, 0xFF); color_t xcolor = darkena(0xFF0000, 1, 0xFF);
int alpha = (m == moPhaser ? 0xC0 : 0xFF); int alpha = (m == moPhaser ? 0xC0 : 0xFF);
if(footphase) { if(footphase) {
@ -2112,7 +2121,7 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t
ShadowV(V, cgi.shJiangShi); ShadowV(V, cgi.shJiangShi);
auto z2 = WDIM == 3 ? 0 : GDIM == 3 ? -abs(sin(footphase * TAU)) * cgi.human_height/3 : geom3::lev_to_factor(abs(sin(footphase * TAU)) * cgi.human_height); auto z2 = WDIM == 3 ? 0 : GDIM == 3 ? -abs(sin(footphase * TAU)) * cgi.human_height/3 : geom3::lev_to_factor(abs(sin(footphase * TAU)) * cgi.human_height);
auto V0 = V; auto V0 = V;
auto V = mmscale(V0, z2); auto V = at_smart_lof(V0, z2);
otherbodyparts(V, darkena(col, 0, 0xFF), m, m == moJiangshi ? 0 : footphase); otherbodyparts(V, darkena(col, 0, 0xFF), m, m == moJiangshi ? 0 : footphase);
queuepoly(VBODY, cgi.shJiangShi, darkena(col, 0, 0xFF)); queuepoly(VBODY, cgi.shJiangShi, darkena(col, 0, 0xFF));
queuepoly(VBODY1, cgi.shJiangShiDress, darkena(0x202020, 0, 0xFF)); queuepoly(VBODY1, cgi.shJiangShiDress, darkena(0x202020, 0, 0xFF));
@ -2330,8 +2339,8 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t
shiftmatrix V2 = V; shiftmatrix V2 = V;
if(m == moLancer) if(m == moLancer)
V2 = V * spin((where && where->type == 6) ? -60._deg : -90._deg ); V2 = V * spin((where && where->type == 6) ? -60._deg : -90._deg );
shiftmatrix Vh = mmscale(V2, cgi.HEAD); shiftmatrix Vh = at_smart_lof(V2, cgi.HEAD);
shiftmatrix Vb = mmscale(V2, cgi.BODY); shiftmatrix Vb = at_smart_lof(V2, cgi.BODY);
Vb = Vb * otherbodyparts(V2, darkena(col, 1, 0xFF), m, footphase); Vb = Vb * otherbodyparts(V2, darkena(col, 1, 0xFF), m, footphase);
ShadowV(V2, cgi.shPBody); ShadowV(V2, cgi.shPBody);
queuepoly(Vb, cgi.shPBody, darkena(col, 0, 0xC0)); queuepoly(Vb, cgi.shPBody, darkena(col, 0, 0xC0));
@ -2636,7 +2645,7 @@ EX bool applyAnimation(cell *c, shiftmatrix& V, double& footphase, int layer) {
auto d = product_decompose(wnow); auto d = product_decompose(wnow);
ld dist = d.first / R * aspd; ld dist = d.first / R * aspd;
if(abs(dist) > abs(d.first)) dist = -d.first; if(abs(dist) > abs(d.first)) dist = -d.first;
a.wherenow = mscale(a.wherenow, dist); a.wherenow = orthogonal_move(a.wherenow, dist);
/* signed_sqrt to prevent precision errors */ /* signed_sqrt to prevent precision errors */
aspd *= signed_sqrt(R*R - d.first * d.first) / R; aspd *= signed_sqrt(R*R - d.first * d.first) / R;
} }
@ -2831,8 +2840,8 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
queuepoly(Vb, cgi.shIBranch, (col << 8) + 0xFF); queuepoly(Vb, cgi.shIBranch, (col << 8) + 0xFF);
/* else if(c->monst < moTentacle && wormstyle == 0) { /* else if(c->monst < moTentacle && wormstyle == 0) {
ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW); ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW);
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacleX, 0xFF); queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacleX, 0xFF);
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF); queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF);
} */ } */
// else if(c->monst < moTentacle) { // else if(c->monst < moTentacle) {
// } // }
@ -2840,7 +2849,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
else if(c->monst == moDragonHead || c->monst == moDragonTail) { else if(c->monst == moDragonHead || c->monst == moDragonTail) {
char part = dragon::bodypart(c, dragon::findhead(c)); char part = dragon::bodypart(c, dragon::findhead(c));
if(part != '2') { if(part != '2') {
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shDragonSegment, darkena(col, 0, 0xFF)); queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shDragonSegment, darkena(col, 0, 0xFF));
ShadowV(Vb, cgi.shDragonSegment, PPR::GIANTSHADOW); ShadowV(Vb, cgi.shDragonSegment, PPR::GIANTSHADOW);
} }
} }
@ -2853,8 +2862,8 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
col = minf[moTentacletail].color; col = minf[moTentacletail].color;
} }
/* /*
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacleX, 0xFFFFFFFF); queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacleX, 0xFFFFFFFF);
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF); queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF);
ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW); ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW);
*/ */
bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail; bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail;
@ -2879,7 +2888,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
// shiftmatrix Vbx2 = Vnext * xpush(length2 * i / 6.0); // shiftmatrix Vbx2 = Vnext * xpush(length2 * i / 6.0);
// Vbx = Vbx * rspintox(inverse(Vbx) * Vbx2 * C0) * pispin; // Vbx = Vbx * rspintox(inverse(Vbx) * Vbx2 * C0) * pispin;
ShadowV(Vbx, sh, PPR::GIANTSHADOW); ShadowV(Vbx, sh, PPR::GIANTSHADOW);
queuepoly(mmscale(Vbx, cgi.ABODY), sh, (col0 << 8) + 0xFF); queuepoly(at_smart_lof(Vbx, cgi.ABODY), sh, (col0 << 8) + 0xFF);
} }
}); });
} }
@ -2905,21 +2914,21 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
} }
else { else {
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shILeaf[ctof(c)], darkena(col, 0, 0xFF)); queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shILeaf[ctof(c)], darkena(col, 0, 0xFF));
ShadowV(Vb, cgi.shILeaf[ctof(c)], PPR::GIANTSHADOW); ShadowV(Vb, cgi.shILeaf[ctof(c)], PPR::GIANTSHADOW);
} }
} }
else if(m == moWorm || m == moWormwait || m == moHexSnake) { else if(m == moWorm || m == moWormwait || m == moHexSnake) {
Vb = Vb * pispin; Vb = Vb * pispin;
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
shiftmatrix Vbh = mmscale(Vb, cgi.AHEAD); shiftmatrix Vbh = at_smart_lof(Vb, cgi.AHEAD);
queuepoly(Vbh, cgi.shWormHead, darkena(col, 0, 0xFF)); queuepoly(Vbh, cgi.shWormHead, darkena(col, 0, 0xFF));
queuepolyat(Vbh, cgi.shWormEyes, 0xFF, PPR::ONTENTACLE_EYES); queuepolyat(Vbh, cgi.shWormEyes, 0xFF, PPR::ONTENTACLE_EYES);
ShadowV(Vb, cgi.shWormHead, PPR::GIANTSHADOW); ShadowV(Vb, cgi.shWormHead, PPR::GIANTSHADOW);
} }
else if(m == moDragonHead) { else if(m == moDragonHead) {
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
shiftmatrix Vbh = mmscale(Vb, cgi.AHEAD); shiftmatrix Vbh = at_smart_lof(Vb, cgi.AHEAD);
ShadowV(Vb, cgi.shDragonHead, PPR::GIANTSHADOW); ShadowV(Vb, cgi.shDragonHead, PPR::GIANTSHADOW);
queuepoly(Vbh, cgi.shDragonHead, darkena(col, c->hitpoints?0:1, 0xFF)); queuepoly(Vbh, cgi.shDragonHead, darkena(col, c->hitpoints?0:1, 0xFF));
queuepolyat(Vbh/* * pispin */, cgi.shDragonEyes, 0xFF, PPR::ONTENTACLE_EYES); queuepolyat(Vbh/* * pispin */, cgi.shDragonEyes, 0xFF, PPR::ONTENTACLE_EYES);
@ -2931,7 +2940,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
else if(m == moTentacle || m == moTentaclewait || m == moTentacleEscaping) { else if(m == moTentacle || m == moTentaclewait || m == moTentacleEscaping) {
Vb = Vb * pispin; Vb = Vb * pispin;
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
shiftmatrix Vbh = mmscale(Vb, cgi.AHEAD); shiftmatrix Vbh = at_smart_lof(Vb, cgi.AHEAD);
queuepoly(Vbh, cgi.shTentHead, darkena(col, 0, 0xFF)); queuepoly(Vbh, cgi.shTentHead, darkena(col, 0, 0xFF));
ShadowV(Vb, cgi.shTentHead, PPR::GIANTSHADOW); ShadowV(Vb, cgi.shTentHead, PPR::GIANTSHADOW);
} }
@ -2952,7 +2961,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
Vb = Vb0 * ddspin180(c, nd); Vb = Vb0 * ddspin180(c, nd);
} }
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
shiftmatrix Vbb = mmscale(Vb, cgi.ABODY); shiftmatrix Vbb = at_smart_lof(Vb, cgi.ABODY);
queuepoly(Vbb, cgi.shDragonTail, darkena(col, c->hitpoints?0:1, 0xFF)); queuepoly(Vbb, cgi.shDragonTail, darkena(col, c->hitpoints?0:1, 0xFF));
ShadowV(Vb, cgi.shDragonTail, PPR::GIANTSHADOW); ShadowV(Vb, cgi.shDragonTail, PPR::GIANTSHADOW);
} }
@ -2973,7 +2982,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
Vb = Vb0 * spin((hdir0 + hdir1)/2 + M_PI); Vb = Vb0 * spin((hdir0 + hdir1)/2 + M_PI);
} }
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
shiftmatrix Vbb = mmscale(Vb, cgi.ABODY); shiftmatrix Vbb = at_smart_lof(Vb, cgi.ABODY);
if(part == 'l' || part == '2') { if(part == 'l' || part == '2') {
queuepoly(Vbb, cgi.shDragonLegs, darkena(col, c->hitpoints?0:1, 0xFF)); queuepoly(Vbb, cgi.shDragonLegs, darkena(col, c->hitpoints?0:1, 0xFF));
} }
@ -2983,7 +2992,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
else { else {
if(c->monst == moTentacletail && c->mondir == NODIR) { if(c->monst == moTentacletail && c->mondir == NODIR) {
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
queuepoly(GDIM == 3 ? mmscale(Vb, cgi.ABODY) : Vb, cgi.shWormSegment, darkena(col, 0, 0xFF)); queuepoly(GDIM == 3 ? at_smart_lof(Vb, cgi.ABODY) : Vb, cgi.shWormSegment, darkena(col, 0, 0xFF));
} }
else if(c->mondir == NODIR) { else if(c->mondir == NODIR) {
bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail; bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail;
@ -3001,7 +3010,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
Vb = Vb0 * ddspin180(c, nd); Vb = Vb0 * ddspin180(c, nd);
} }
if(c->monmirror) Vb = Vb * Mirror; if(c->monmirror) Vb = Vb * Mirror;
shiftmatrix Vbb = mmscale(Vb, cgi.ABODY) * pispin; shiftmatrix Vbb = at_smart_lof(Vb, cgi.ABODY) * pispin;
hpcshape& sh = hexsnake ? cgi.shWormTail : cgi.shSmallWormTail; hpcshape& sh = hexsnake ? cgi.shWormTail : cgi.shSmallWormTail;
queuepoly(Vbb, sh, darkena(col, 0, 0xFF)); queuepoly(Vbb, sh, darkena(col, 0, 0xFF));
ShadowV(Vb, sh, PPR::GIANTSHADOW); ShadowV(Vb, sh, PPR::GIANTSHADOW);
@ -3131,7 +3140,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
if(hypot_d(2, tC0(unshift(Vs))) > 1e-3) { if(hypot_d(2, tC0(unshift(Vs))) > 1e-3) {
Vs = Vs * rspintox(V0); Vs = Vs * rspintox(V0);
if(prod) Vs = mscale(Vs, z); if(prod) Vs = orthogonal_move(Vs, z);
} }
} }
else if(!sl2) { else if(!sl2) {
@ -3677,28 +3686,28 @@ EX void escherSidewall(cell *c, int sidepar, const shiftmatrix& V, color_t col)
if(sidepar >= SIDE_SLEV && sidepar <= SIDE_SLEV+2) { if(sidepar >= SIDE_SLEV && sidepar <= SIDE_SLEV+2) {
int sl = sidepar - SIDE_SLEV; int sl = sidepar - SIDE_SLEV;
for(int z=1; z<=4; z++) if(z == 1 || (z == 4 && detaillevel == 2)) for(int z=1; z<=4; z++) if(z == 1 || (z == 4 && detaillevel == 2))
draw_qfi(c, mscale(V, zgrad0(cgi.slev * sl, cgi.slev * (sl+1), z, 4)), col, PPR::REDWALL-4+z+4*sl); draw_qfi(c, orthogonal_move_fol(V, zgrad0(cgi.slev * sl, cgi.slev * (sl+1), z, 4)), col, PPR::REDWALL-4+z+4*sl);
} }
else if(sidepar == SIDE_WALL) { else if(sidepar == SIDE_WALL) {
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<layers; z++) for(int z=1; z<layers; z++)
draw_qfi(c, mscale(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), col, PPR::WALL3+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), col, PPR::WALL3+z-layers);
} }
else if(sidepar == SIDE_LAKE) { else if(sidepar == SIDE_LAKE) {
const int layers = 1 << (detaillevel-1); const int layers = 1 << (detaillevel-1);
if(detaillevel) for(int z=0; z<layers; z++) if(detaillevel) for(int z=0; z<layers; z++)
draw_qfi(c, mscale(V, zgrad0(-vid.lake_top, 0, z, layers)), col, PPR::FLOOR+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_top, 0, z, layers)), col, PPR::FLOOR+z-layers);
} }
else if(sidepar == SIDE_LTOB) { else if(sidepar == SIDE_LTOB) {
const int layers = 1 << (detaillevel-1); const int layers = 1 << (detaillevel-1);
if(detaillevel) for(int z=0; z<layers; z++) if(detaillevel) for(int z=0; z<layers; z++)
draw_qfi(c, mscale(V, zgrad0(-vid.lake_bottom, -vid.lake_top, z, layers)), col, PPR::INLAKEWALL+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_bottom, -vid.lake_top, z, layers)), col, PPR::INLAKEWALL+z-layers);
} }
else if(sidepar == SIDE_BTOI) { else if(sidepar == SIDE_BTOI) {
const int layers = 1 << detaillevel; const int layers = 1 << detaillevel;
draw_qfi(c, mscale(V, cgi.INFDEEP), col, PPR::MINUSINF); draw_qfi(c, orthogonal_move_fol(V, cgi.INFDEEP), col, PPR::MINUSINF);
for(int z=1; z<layers; z++) for(int z=1; z<layers; z++)
draw_qfi(c, mscale(V, zgrad0(-vid.lake_bottom, -vid.lake_top, -z, 1)), col, PPR::LAKEBOTTOM+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_bottom, -vid.lake_top, -z, 1)), col, PPR::LAKEBOTTOM+z-layers);
} }
} }
@ -4025,7 +4034,7 @@ EX int get_darkval(cell *c, int d) {
EX ld mousedist(shiftmatrix T) { EX ld mousedist(shiftmatrix T) {
if(GDIM == 2) return hdist(mouseh, tC0(T)); if(GDIM == 2) return hdist(mouseh, tC0(T));
shiftpoint T1 = tC0(mscale(T, cgi.FLOOR)); shiftpoint T1 = tC0(orthogonal_move_fol(T, cgi.FLOOR));
if(mouseaim_sensitivity) return sqhypot_d(2, T1.h) + (point_behind(T1) ? 1e10 : 0); if(mouseaim_sensitivity) return sqhypot_d(2, T1.h) + (point_behind(T1) ? 1e10 : 0);
hyperpoint h1; hyperpoint h1;
applymodel(T1, h1); applymodel(T1, h1);
@ -4546,8 +4555,8 @@ void celldrawer::draw_fallanims() {
ddalt.setcolors(); ddalt.setcolors();
int starcol = c->wall == waVinePlant ? 0x60C000 : ddalt.wcol; int starcol = c->wall == waVinePlant ? 0x60C000 : ddalt.wcol;
c->wall = w; c->wparam = p; c->wall = w; c->wparam = p;
draw_qfi(c, mscale(V, cgi.WALL), darkena(starcol, fd, 0xFF), PPR::WALL3); draw_qfi(c, orthogonal_move_fol(V, cgi.WALL), darkena(starcol, fd, 0xFF), PPR::WALL3);
queuepolyat(mscale(V, cgi.WALL), cgi.shWall[ct6], darkena(ddalt.wcol, 0, 0xFF), PPR::WALL3A); queuepolyat(orthogonal_move_fol(V, cgi.WALL), cgi.shWall[ct6], darkena(ddalt.wcol, 0, 0xFF), PPR::WALL3A);
forCellIdEx(c2, i, c) forCellIdEx(c2, i, c)
if(placeSidewall(c, i, SIDE_WALL, V, darkena(ddalt.wcol, 1, 0xFF))) break; if(placeSidewall(c, i, SIDE_WALL, V, darkena(ddalt.wcol, 1, 0xFF))) break;
} }
@ -4582,13 +4591,13 @@ EX void queuecircleat1(cell *c, const shiftmatrix& V, double rad, color_t col) {
return; return;
} }
if(spatial_graphics || GDIM == 3) { if(spatial_graphics || GDIM == 3) {
vector<shiftmatrix> corners(c->type+1); vector<hyperpoint> corners(c->type+1);
for(int i=0; i<c->type; i++) corners[i] = V * rgpushxto0(get_corner_position(c, i, 3 / rad)); for(int i=0; i<c->type; i++) corners[i] = get_corner_position(c, i, 3 / rad);
corners[c->type] = corners[0]; corners[c->type] = corners[0];
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
queueline(mscale(corners[i], cgi.FLOOR) * C0, mscale(corners[i+1], cgi.FLOOR) * C0, col, 2, PPR::SUPERLINE); queueline(V * orthogonal_move_fol(corners[i], cgi.FLOOR), V * orthogonal_move_fol(corners[i+1], cgi.FLOOR), col, 2, PPR::SUPERLINE);
queueline(mscale(corners[i], cgi.WALL) * C0, mscale(corners[i+1], cgi.WALL) * C0, col, 2, PPR::SUPERLINE); queueline(V * orthogonal_move_fol(corners[i], cgi.WALL), V * orthogonal_move_fol(corners[i+1], cgi.WALL), col, 2, PPR::SUPERLINE);
queueline(mscale(corners[i], cgi.FLOOR) * C0, mscale(corners[i], cgi.WALL) * C0, col, 2, PPR::SUPERLINE); queueline(V * orthogonal_move_fol(corners[i], cgi.FLOOR), V * orthogonal_move_fol(corners[i], cgi.WALL), col, 2, PPR::SUPERLINE);
} }
return; return;
} }
@ -4602,13 +4611,13 @@ EX void queuecircleat1(cell *c, const shiftmatrix& V, double rad, color_t col) {
queuecircle(V, rad, col); queuecircle(V, rad, col);
if(!wmspatial) return; if(!wmspatial) return;
if(highwall(c)) if(highwall(c))
queuecircle(mscale(V, cgi.WALL), rad, col); queuecircle(orthogonal_move_fol(V, cgi.WALL), rad, col);
int sl; int sl;
if((sl = snakelevel(c))) { if((sl = snakelevel(c))) {
queuecircle(mscale(V, cgi.SLEV[sl]), rad, col); queuecircle(orthogonal_move_fol(V, cgi.SLEV[sl]), rad, col);
} }
if(chasmgraph(c)) if(chasmgraph(c))
queuecircle(mscale(V, cgi.LAKE), rad, col); queuecircle(orthogonal_move_fol(V, cgi.LAKE), rad, col);
} }
EX void queuecircleat(cell *c, double rad, color_t col) { EX void queuecircleat(cell *c, double rad, color_t col) {

View File

@ -678,8 +678,6 @@ static const int MAXPLAYER = 7;
// just in case if I change my mind about when Orbs lose their power // just in case if I change my mind about when Orbs lose their power
#define ORBBASE 0 #define ORBBASE 0
#define mmscale(V, x) (mmspatial ? (ivoryz ? mzscale(V,x) : mscale(V, x)) : (V))
#define SHADOW_WALL 0x60 #define SHADOW_WALL 0x60
#define SHADOW_SL 0x18 #define SHADOW_SL 0x18
#define SHADOW_MON 0x30 #define SHADOW_MON 0x30

View File

@ -509,6 +509,7 @@ EX hyperpoint closest_to_zero(hyperpoint a, hyperpoint b) {
return (mul_b * a + mul_a * b) / (mul_a + mul_b); return (mul_b * a + mul_a * b) / (mul_a + mul_b);
} }
/** should be called get_lof */
EX ld zlevel(const hyperpoint &h) { EX ld zlevel(const hyperpoint &h) {
if(sl2) return sqrt(-intval(h, Hypc)); if(sl2) return sqrt(-intval(h, Hypc));
else if(translatable) return h[LDIM]; else if(translatable) return h[LDIM];
@ -559,7 +560,7 @@ EX hyperpoint mid(const hyperpoint& H1, const hyperpoint& H2) {
if(prod) { if(prod) {
auto d1 = product_decompose(H1); auto d1 = product_decompose(H1);
auto d2 = product_decompose(H2); auto d2 = product_decompose(H2);
return zshift(PIU( mid(d1.second, d2.second) ), (d1.first + d2.first) / 2); return orthogonal_move(PIU( mid(d1.second, d2.second) ), (d1.first + d2.first) / 2);
} }
return normalize(H1 + H2); return normalize(H1 + H2);
} }
@ -690,9 +691,9 @@ EX transmatrix euaffine(hyperpoint h) {
} }
EX transmatrix cpush(int cid, ld alpha) { EX transmatrix cpush(int cid, ld alpha) {
transmatrix T = Id;
if(prod && cid == 2) if(prod && cid == 2)
return mscale(Id, alpha); return scale_matrix(Id, exp(alpha));
transmatrix T = Id;
if(nonisotropic) if(nonisotropic)
return eupush3(cid == 0 ? alpha : 0, cid == 1 ? alpha : 0, cid == 2 ? alpha : 0); return eupush3(cid == 0 ? alpha : 0, cid == 1 ? alpha : 0, cid == 2 ? alpha : 0);
T[LDIM][LDIM] = T[cid][cid] = cos_auto(alpha); T[LDIM][LDIM] = T[cid][cid] = cos_auto(alpha);
@ -701,6 +702,10 @@ EX transmatrix cpush(int cid, ld alpha) {
return T; return T;
} }
EX transmatrix lzpush(ld z) {
return cpush(2, z);
}
EX transmatrix cmirror(int cid) { EX transmatrix cmirror(int cid) {
transmatrix T = Id; transmatrix T = Id;
T[cid][cid] = -1; T[cid][cid] = -1;
@ -719,9 +724,10 @@ EX bool eqmatrix(transmatrix A, transmatrix B, ld eps IS(.01)) {
} }
#if MAXMDIM >= 4 #if MAXMDIM >= 4
// in the 3D space, move the point h orthogonally to the (x,y) plane by z units /** in the 3D space, move the point h orthogonally to the (x,y) plane by z units */
EX hyperpoint orthogonal_move(const hyperpoint& h, ld z) { EX hyperpoint orthogonal_move(const hyperpoint& h, ld z) {
if(prod) return zshift(h, z); if(GDIM == 2) return scale_point(h, geom3::scale_at_lev(z));
if(prod) return scale_point(h, exp(z));
if(sl2) return slr::translate(h) * cpush0(2, z); if(sl2) return slr::translate(h) * cpush0(2, z);
if(!hyperbolic) return rgpushxto0(h) * cpush(2, z) * C0; if(!hyperbolic) return rgpushxto0(h) * cpush(2, z) * C0;
if(nil) return nisot::translate(h) * cpush0(2, z); if(nil) return nisot::translate(h) * cpush0(2, z);
@ -911,7 +917,7 @@ EX transmatrix ggpushxto0(const hyperpoint& H, ld co) {
return eupush(H, co); return eupush(H, co);
if(prod) { if(prod) {
auto d = product_decompose(H); auto d = product_decompose(H);
return mscale(PIU(ggpushxto0(d.second, co)), d.first * co); return scale_matrix(PIU(ggpushxto0(d.second, co)), exp(d.first * co));
} }
transmatrix res = Id; transmatrix res = Id;
if(sqhypot_d(GDIM, H) < 1e-16) return res; if(sqhypot_d(GDIM, H) < 1e-16) return res;
@ -954,9 +960,9 @@ EX void fixmatrix(transmatrix& T) {
else if(cgflags & qAFFINE) ; // affine else if(cgflags & qAFFINE) ; // affine
else if(prod) { else if(prod) {
auto z = zlevel(tC0(T)); auto z = zlevel(tC0(T));
T = mscale(T, -z); T = scale_matrix(T, exp(-z));
PIU(fixmatrix(T)); PIU(fixmatrix(T));
T = mscale(T, +z); T = scale_matrix(T, exp(+z));
} }
else if(euclid) else if(euclid)
fixmatrix_euclid(T); fixmatrix_euclid(T);
@ -1164,7 +1170,7 @@ EX transmatrix iview_inverse(transmatrix T) {
EX pair<ld, hyperpoint> product_decompose(hyperpoint h) { EX pair<ld, hyperpoint> product_decompose(hyperpoint h) {
ld z = zlevel(h); ld z = zlevel(h);
return make_pair(z, mscale(h, -z)); return make_pair(z, scale_point(h, exp(-z)));
} }
/** distance from mh and 0 */ /** distance from mh and 0 */
@ -1247,37 +1253,59 @@ EX ld hdist(const shiftpoint& h1, const shiftpoint& h2) {
return hdist(h1.h, unshift(h2, h1.shift)); return hdist(h1.h, unshift(h2, h1.shift));
} }
EX hyperpoint mscale(const hyperpoint& t, double fac) { /** like orthogonal_move but fol may be factor (in 2D graphics) or level (elsewhere) */
if(GDIM == 3 && !prod) return cpush(2, fac) * t; EX hyperpoint orthogonal_move_fol(const hyperpoint& h, double fol) {
if(prod) fac = exp(fac); if(GDIM == 2) return scale_point(h, fol);
hyperpoint res; else return orthogonal_move(h, fol);
for(int i=0; i<MXDIM; i++)
res[i] = t[i] * fac;
return res;
} }
EX shiftpoint mscale(const shiftpoint& t, double fac) { /** like orthogonal_move but fol may be factor (in 2D graphics) or level (elsewhere) */
return shiftless(mscale(t.h, fac), t.shift); EX transmatrix orthogonal_move_fol(const transmatrix& T, double fol) {
if(GDIM == 2) return scale_matrix(T, fol);
else return orthogonal_move(T, fol);
} }
EX transmatrix mscale(const transmatrix& t, double fac) { /** like orthogonal_move but fol may be factor (in 2D graphics) or level (elsewhere) */
if(GDIM == 3 && !prod) { EX shiftmatrix orthogonal_move_fol(const shiftmatrix& T, double fol) {
// if(pmodel == mdFlatten) { transmatrix u = t; u[2][LDIM] -= fac; return u; } if(GDIM == 2) return scale_matrix(T, fol);
return t * cpush(2, fac); else return orthogonal_move(T, fol);
} }
if(prod) fac = exp(fac);
/** the scaling matrix (Euclidean homogeneous scaling; also shift by log(scale) in product space */
EX transmatrix scale_matrix(const transmatrix& t, ld scale_factor) {
transmatrix res; transmatrix res;
for(int i=0; i<MXDIM; i++) { for(int i=0; i<MXDIM; i++) {
for(int j=0; j<MDIM; j++) for(int j=0; j<MDIM; j++)
res[i][j] = t[i][j] * fac; res[i][j] = t[i][j] * scale_factor;
for(int j=MDIM; j<MXDIM; j++) for(int j=MDIM; j<MXDIM; j++)
res[i][j] = t[i][j]; res[i][j] = t[i][j];
} }
return res; return res;
} }
EX shiftmatrix mscale(const shiftmatrix& t, double fac) { /** the scaling matrix (Euclidean homogeneous scaling; also shift by log(scale) in product space */
return shiftless(mscale(t.T, fac), t.shift); EX shiftmatrix scale_matrix(const shiftmatrix& t, ld scale_factor) {
return shiftless(scale_matrix(t.T, scale_factor), t.shift);
}
/** the scaling matrix (Euclidean homogeneous scaling; also shift by log(scale) in product space */
EX hyperpoint scale_point(const hyperpoint& h, ld scale_factor) {
hyperpoint res;
for(int j=0; j<MDIM; j++)
res[j] = h[j] * scale_factor;
for(int j=MDIM; j<MXDIM; j++)
res[j] = h[j];
return res;
}
EX transmatrix orthogonal_move(const transmatrix& t, double level) {
if(prod) return scale_matrix(t, exp(level));
if(GDIM == 3) return t * cpush(2, level);
return scale_matrix(t, geom3::lev_to_factor(level));
}
EX shiftmatrix orthogonal_move(const shiftmatrix& t, double level) {
return shiftless(orthogonal_move(t.T, level), t.shift);
} }
EX transmatrix xyscale(const transmatrix& t, double fac) { EX transmatrix xyscale(const transmatrix& t, double fac) {
@ -1354,13 +1382,6 @@ EX hyperpoint orthogonal_of_C0(hyperpoint h0, hyperpoint h1, hyperpoint h2) {
return normalize(h); return normalize(h);
} }
EX hyperpoint zshift(hyperpoint x, ld z) {
if(GDIM == 3 && WDIM == 2) return rgpushxto0(x) * cpush0(2, z);
else if(sl2) return mscale(x, z);
else if(prod) return mscale(x, z);
else return mscale(x, z);
}
EX hyperpoint hpxd(ld d, ld x, ld y, ld z) { EX hyperpoint hpxd(ld d, ld x, ld y, ld z) {
hyperpoint H = hpxyz(d*x, d*y, z); hyperpoint H = hpxyz(d*x, d*y, z);
H = mid(H, H); H = mid(H, H);

View File

@ -1053,7 +1053,7 @@ EX void handle() {
hyperpoint h = product_decompose(fac.h0).second; hyperpoint h = product_decompose(fac.h0).second;
h = PIU( deparabolic13(h) ); h = PIU( deparabolic13(h) );
dep[0] = h[0]; dep[0] = h[0];
return zshift(PIU(parabolic13(dep)), dec.first); return orthogonal_move(PIU(parabolic13(dep)), dec.first);
} }
#else #else
if(false) {} if(false) {}

View File

@ -3092,7 +3092,8 @@ EX namespace mapeditor {
hpcshape& sh(cgi.ushr[&ds]); hpcshape& sh(cgi.ushr[&ds]);
if(sh.s != sh.e) { if(sh.s != sh.e) {
auto& last = queuepolyat(mmscale(V, GDIM == 3 ? 0 : geom3::lev_to_factor(ds.zlevel)), sh, ds.color ? ds.color : color, prio); shiftmatrix V1 = GDIM == 3 ? V : orthogonal_move(V, ds.zlevel);
auto& last = queuepolyat(V1, sh, ds.color ? ds.color : color, prio);
if(GDIM == 3) { if(GDIM == 3) {
last.tinf = &user_triangles_texture; last.tinf = &user_triangles_texture;
last.offset_texture = ds.texture_offset; last.offset_texture = ds.texture_offset;

View File

@ -1407,14 +1407,14 @@ EX namespace hybrid {
ld lev = cgi.plevel * z / 2; ld lev = cgi.plevel * z / 2;
if(WDIM == 2) { if(WDIM == 2) {
ld zz = lerp(cgi.FLOOR, cgi.WALL, (1+z) / 2); ld zz = lerp(cgi.FLOOR, cgi.WALL, (1+z) / 2);
hyperpoint h = zshift(get_corner_position(c, i+next), zz); hyperpoint h = orthogonal_move(get_corner_position(c, i+next), zz);
return h; return h;
} }
if(prod) { if(prod) {
dynamicval<eGeometry> g(geometry, hybrid::underlying); dynamicval<eGeometry> g(geometry, hybrid::underlying);
dynamicval<geometry_information*> gc(cgip, hybrid::underlying_cgip); dynamicval<geometry_information*> gc(cgip, hybrid::underlying_cgip);
dynamicval<hrmap*> gm(currentmap, ((hrmap_hybrid*)currentmap)->underlying_map); dynamicval<hrmap*> gm(currentmap, ((hrmap_hybrid*)currentmap)->underlying_map);
return mscale(get_corner_position(c, i+next), exp(lev)); return scale_point(get_corner_position(c, i+next), exp(lev));
} }
else { else {
#if MAXMDIM >= 4 #if MAXMDIM >= 4
@ -1571,26 +1571,26 @@ EX namespace product {
struct hrmap_product : hybrid::hrmap_hybrid { struct hrmap_product : hybrid::hrmap_hybrid {
transmatrix relative_matrixc(cell *c2, cell *c1, const hyperpoint& hint) override { transmatrix relative_matrixc(cell *c2, cell *c1, const hyperpoint& hint) override {
return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, hint); }) * mscale(Id, cgi.plevel * szgmod(where[c2].second - where[c1].second, hybrid::csteps)); return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, hint); }) * cpush(2, cgi.plevel * szgmod(where[c2].second - where[c1].second, hybrid::csteps));
} }
transmatrix adj(cell *c, int i) override { transmatrix adj(cell *c, int i) override {
if(twisted && i == c->type-1 && where[c].second == hybrid::csteps-1) { if(twisted && i == c->type-1 && where[c].second == hybrid::csteps-1) {
auto b = spins[where[c].first].first; auto b = spins[where[c].first].first;
transmatrix T = mscale(Id, cgi.plevel); transmatrix T = cpush(2, cgi.plevel);
T = T * spin(TAU * b.spin / b.at->type); T = T * spin(TAU * b.spin / b.at->type);
if(b.mirrored) T = T * Mirror; if(b.mirrored) T = T * Mirror;
return T; return T;
} }
if(twisted && i == c->type-2 && where[c].second == 0) { if(twisted && i == c->type-2 && where[c].second == 0) {
auto b = spins[where[c].first].second; auto b = spins[where[c].first].second;
transmatrix T = mscale(Id, -cgi.plevel); transmatrix T = cpush(2, -cgi.plevel);
T = T * spin(TAU * b.spin / b.at->type); T = T * spin(TAU * b.spin / b.at->type);
if(b.mirrored) T = T * Mirror; if(b.mirrored) T = T * Mirror;
return T; return T;
} }
if(i == c->type-1) return mscale(Id, cgi.plevel); if(i == c->type-1) return cpush(2, cgi.plevel);
else if(i == c->type-2) return mscale(Id, -cgi.plevel); else if(i == c->type-2) return cpush(2, -cgi.plevel);
c = where[c].first; c = where[c].first;
return PIU(currentmap->adj(c, i)); return PIU(currentmap->adj(c, i));
} }
@ -1620,8 +1620,8 @@ EX namespace product {
} }
virtual transmatrix ray_iadj(cell *c, int i) override { virtual transmatrix ray_iadj(cell *c, int i) override {
if(i == c->type-2) return (mscale(Id, +cgi.plevel)); if(i == c->type-2) return (cpush(2, +cgi.plevel));
if(i == c->type-1) return (mscale(Id, -cgi.plevel)); if(i == c->type-1) return (cpush(2, -cgi.plevel));
transmatrix T; transmatrix T;
cell *cw = hybrid::get_where(c).first; cell *cw = hybrid::get_where(c).first;
hybrid::in_underlying_geometry([&] { hybrid::in_underlying_geometry([&] {
@ -1638,7 +1638,7 @@ EX namespace product {
EX hyperpoint inverse_exp(hyperpoint h) { EX hyperpoint inverse_exp(hyperpoint h) {
hyperpoint res; hyperpoint res;
res[2] = zlevel(h); res[2] = zlevel(h);
h = zshift(h, -res[2]); h = orthogonal_move(h, -res[2]);
ld r = hypot_d(2, h); ld r = hypot_d(2, h);
if(hybrid::under_class() == gcEuclid) { if(hybrid::under_class() == gcEuclid) {
res[0] = h[0]; res[0] = h[0];
@ -1664,7 +1664,7 @@ EX namespace product {
res[0] = h[0] * cd; res[0] = h[0] * cd;
res[1] = h[1] * cd; res[1] = h[1] * cd;
res[2] = cos_auto(d); res[2] = cos_auto(d);
return zshift(res, h[2]); return orthogonal_move(res, h[2]);
} }
EX bool validate_spin() { EX bool validate_spin() {

View File

@ -90,11 +90,11 @@ void geometry_information::hpcpush(hyperpoint h) {
} }
} }
void geometry_information::chasmifyPoly(double fac, double fac2, int k) { void geometry_information::chasmifyPoly(double fol, double fol2, int k) {
if(GDIM == 2) { if(GDIM == 2) {
for(int i=isize(hpc)-1; i >= last->s; i--) { for(int i=isize(hpc)-1; i >= last->s; i--) {
hpc.push_back(mscale(hpc[i], fac)); hpc.push_back(orthogonal_move_fol(hpc[i], fol));
hpc[i] = mscale(hpc[i], fac2); hpc[i] = orthogonal_move_fol(hpc[i], fol2);
} }
hpc.push_back(hpc[last->s]); hpc.push_back(hpc[last->s]);
last->flags |= POLY_ISSIDE; last->flags |= POLY_ISSIDE;
@ -111,7 +111,7 @@ void geometry_information::chasmifyPoly(double fac, double fac2, int k) {
int zf = int(x); int zf = int(x);
if(zf == isize(points)-1) zf--; if(zf == isize(points)-1) zf--;
x -= zf; x -= zf;
hpcpush(zshift(normalize(points[zf] + (points[zf+1] - points[zf]) * x), fac + (fac2-fac) * y)); hpcpush(orthogonal_move(normalize(points[zf] + (points[zf+1] - points[zf]) * x), fol + (fol2-fol) * y));
}; };
texture_order([&] (ld x, ld y) { at((1-x+y)/2, (1-x-y)/2); }); texture_order([&] (ld x, ld y) { at((1-x+y)/2, (1-x-y)/2); });
texture_order([&] (ld x, ld y) { at((1-x-y)/2, (1+x-y)/2); }); texture_order([&] (ld x, ld y) { at((1-x-y)/2, (1+x-y)/2); });
@ -958,7 +958,7 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
h = nilv::on_geodesic(center, nilv::on_geodesic(v1+center, v2+center, y / (x+y)), x + y); h = nilv::on_geodesic(center, nilv::on_geodesic(v1+center, v2+center, y / (x+y)), x + y);
if(prod) { if(prod) {
if(bt::in()) h = PIU( parabolic13(h) ); if(bt::in()) h = PIU( parabolic13(h) );
h = zshift(normalize_flat(h), center_altitude * (1-x-y) + altitudes[a] * x + altitudes[b] * y); h = orthogonal_move(normalize_flat(h), center_altitude * (1-x-y) + altitudes[a] * x + altitudes[b] * y);
hpcpush(h); return; hpcpush(h); return;
} }
hpcpush(final_coords(h)); hpcpush(final_coords(h));
@ -973,7 +973,7 @@ void geometry_information::make_wall(int id, vector<hyperpoint> vertices, vector
hyperpoint h = (vertices[a] * (STEP-y) + vertices[(a+1)%n] * y)/STEP; hyperpoint h = (vertices[a] * (STEP-y) + vertices[(a+1)%n] * y)/STEP;
if(prod) { if(prod) {
if(bt::in()) h = PIU( parabolic13(h) ); if(bt::in()) h = PIU( parabolic13(h) );
h = zshift(normalize_flat(h), (altitudes[a] * (STEP-y) + altitudes[(a+1)%n] * y) / STEP); h = orthogonal_move(normalize_flat(h), (altitudes[a] * (STEP-y) + altitudes[(a+1)%n] * y) / STEP);
hpcpush(h); hpcpush(h);
} }
else if(nil) else if(nil)

View File

@ -2983,8 +2983,8 @@ auto hooksw = addHook(hooks_swapdim, 100, [] {
shiftmatrix at_missile_level(const shiftmatrix& T) { shiftmatrix at_missile_level(const shiftmatrix& T) {
if(WDIM == 3) return T; if(WDIM == 3) return T;
if(GDIM == 3) return mscale(T, cgi.BODY); if(GDIM == 3) return orthogonal_move(T, cgi.BODY);
return mmscale(T, 1.15); return at_smart_lof(T, 1.15);
} }
bool celldrawer::draw_shmup_monster() { bool celldrawer::draw_shmup_monster() {
@ -3030,8 +3030,8 @@ bool celldrawer::draw_shmup_monster() {
queuepoly(Vboat, cgi.shBoatInner, incolor); queuepoly(Vboat, cgi.shBoatInner, incolor);
} }
if(WDIM == 3) { if(WDIM == 3) {
queuepoly(mscale(Vboat, cgi.scalefactor/2), cgi.shBoatOuter, outcolor); queuepoly(scale_matrix(Vboat, cgi.scalefactor/2), cgi.shBoatOuter, outcolor);
queuepoly(mscale(Vboat, cgi.scalefactor/2-0.01), cgi.shBoatInner, incolor); queuepoly(scale_matrix(Vboat, cgi.scalefactor/2-0.01), cgi.shBoatInner, incolor);
} }
} }