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) {
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) {
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) {

View File

@ -714,7 +714,7 @@ void celldrawer::draw_wall() {
int hdir = 0;
for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->wall == waClosedGate)
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);
starcol = 0;
}
@ -742,7 +742,7 @@ void celldrawer::draw_wall() {
if(starcol) queuepoly(V1, shThisWall, darkena(starcol, 0, 0xFF));
}
else {
shiftmatrix Vdepth = mscale(V1, cgi.WALL);
shiftmatrix Vdepth = orthogonal_move_fol(V1, cgi.WALL);
int alpha = 0xFF;
if(c->wall == waIcewall)
alpha = 0xC0;
@ -790,8 +790,8 @@ void celldrawer::draw_boat() {
nospin = c->wall == waBoat && applyAnimation(c, Vboat, footphase, LAYER_BOAT);
if(!nospin) Vboat = face_the_player(V);
else Vboat = Vboat * cspin180(0, 2);
queuepolyat(mscale(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), cgi.shBoatOuter, outcol, PPR::BOATLEV2);
queuepolyat(orthogonal_move(Vboat, cgi.scalefactor/2-0.01), cgi.shBoatInner, incol, PPR::BOATLEV2);
return;
}
@ -812,10 +812,10 @@ void celldrawer::draw_boat() {
animations[LAYER_SMALL][c].footphase = 0;
}
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) {
queuepoly(mscale(Vboat, -0.004), cgi.shBoatOuter, outcol);
queuepoly(mscale(Vboat, -0.008), cgi.shBoatInner, incol);
queuepoly(orthogonal_move(Vboat, -0.004), cgi.shBoatOuter, outcol);
queuepoly(orthogonal_move(Vboat, -0.008), cgi.shBoatInner, incol);
}
else {
queuepoly(Vboat, cgi.shBoatOuter, outcol);
@ -947,7 +947,7 @@ void celldrawer::draw_halfvine() {
set_floor(cgi.shSemiFeatherFloor[0]);
int dk = 1;
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));
queuepoly(V2, cgi.shSemiFeatherFloor[1], darkena(fcol, dk, 0xFF));
set_floor(cgi.shFeatherFloor);
@ -961,7 +961,7 @@ void celldrawer::draw_halfvine() {
int vcol = winf[waVinePlant].color;
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);
if(!noshadow) {
@ -1028,7 +1028,7 @@ void celldrawer::draw_mirrorwall() {
else if(wmspatial) {
const int layers = 2 << detaillevel;
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
queuepolyat(V2, cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL3);
@ -1056,7 +1056,7 @@ void celldrawer::draw_mirrorwall() {
else if(wmspatial) {
const int layers = 2 << detaillevel;
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
queuepolyat(V2, cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL3);
@ -1281,8 +1281,8 @@ void celldrawer::set_land_floor(const shiftmatrix& Vf) {
shiftmatrix Vbspin = Vf * bspin;
queuepoly(Vbspin, cgi.shMercuryBridge[1], darkena(fcol, fd+1, 0xFF));
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(mscale(Vbspin, cgi.BOTTOM), cgi.shMercuryBridge[1], darkena(0x202020, 0, 0xFF), PPR::LAKEBOTTOM);
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(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:
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)
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)
queuepolyat(mmscale(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, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2);
queuepolyat(at_smart_lof(V, cgi.SLEV[2]), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3);
break;
case waSmallBush:
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)
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)
queuepolyat(mmscale(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, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2);
queuepolyat(at_smart_lof(V, cgi.SLEV[2]), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3);
break;
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;
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;
case waLadder:
@ -1458,7 +1458,7 @@ void celldrawer::draw_features() {
if(drawstar(c)) {
aura_color = wcol;
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
queuepoly(V, cgi.shGiantStar[ct6], darkena(wcol, 0, 0xFF));
}
@ -1543,7 +1543,7 @@ void celldrawer::draw_features() {
if(wmspatial) {
color_t col = winf[waGlass].color;
int dcol = darkena(col, 0, 0x80);
shiftmatrix Vdepth = mscale(Vd, cgi.WALL);
shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL);
if(GDIM == 3)
draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL);
else
@ -1567,7 +1567,7 @@ void celldrawer::draw_features() {
case waArrowTrap:
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);
break;
@ -1584,7 +1584,7 @@ void celldrawer::draw_features() {
draw_floorshape(c, V, cgi.shMFloor2, darkena(0x600000, 0, 0xFF));
}
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;
case waGiantRug:
@ -1660,7 +1660,7 @@ void celldrawer::draw_features() {
if(wmspatial) {
color_t col = winf[c->wall].color;
int dcol = darkena(col, 0, 0xC0);
shiftmatrix Vdepth = mscale(Vd, cgi.WALL);
shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL);
if(GDIM == 3)
draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL);
else
@ -1912,7 +1912,7 @@ void celldrawer::check_rotations() {
ds.total += unshift(tC0(V));
ds.qty++;
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 == 1) ds.point = spin(-90._deg) * ds.point;
}
@ -2106,7 +2106,7 @@ void celldrawer::draw_cellstat() {
void celldrawer::draw_wall_full() {
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
int flooralpha = 255;
@ -2133,9 +2133,9 @@ void celldrawer::draw_wall_full() {
if(GDIM == 2 && (c->land != laRose || ls::any_chaos())) {
int rd = rosedist(c);
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)
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) {
@ -2149,7 +2149,7 @@ void celldrawer::draw_wall_full() {
}
if(c->land == laZebra) fd++;
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)
draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_LAKE], darkena(firecolor(0, 10), 0, 0xDF), PPR::TRANSPARENT_LAKE);
else
@ -2240,7 +2240,7 @@ void celldrawer::draw_wall_full() {
if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[sid], col, PPR::LAKEBOTTOM);
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;
if(WDIM == 2 && GDIM == 3 && qfi.fshape)
@ -2386,7 +2386,7 @@ void celldrawer::draw_wall_full() {
bool dbot = true;
forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) {
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;
}
#undef D
@ -2648,14 +2648,14 @@ void celldrawer::draw_gravity_particles() {
case gsNormal:
for(int i=0; i<6; i++) {
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;
case gsAnti:
for(int i=0; i<6; i++) {
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;
@ -2664,7 +2664,7 @@ void celldrawer::draw_gravity_particles() {
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);
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;
}
@ -2792,10 +2792,10 @@ void celldrawer::draw() {
Vd =
WDIM == 3 ? V:
!wmspatial ? V :
sl ? mscale(V, GDIM == 3 ? cgi.SLEV[sl] - cgi.FLOOR : cgi.SLEV[sl]) :
(highwall(c) && GDIM == 2) ? mscale(V, (1+cgi.WALL)/2) :
sl ? orthogonal_move_fol(V, GDIM == 3 ? cgi.SLEV[sl] - cgi.FLOOR : cgi.SLEV[sl]) :
(highwall(c) && GDIM == 2) ? orthogonal_move_fol(V, (1+cgi.WALL)/2) :
#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
V;
@ -2840,35 +2840,35 @@ void celldrawer::draw() {
string s1 = s0+asciichar1;
poly_outline = bordcolor << 8;
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;
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)) {
const int layers = 1 << detaillevel;
string s1 = s0+asciichar1;
poly_outline = bordcolor << 8;
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;
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))) {
string s1 = s0+asciichar1;
poly_outline = bordcolor << 8;
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;
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) {
// 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)) {
string s1 = s0+asciichar1;
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;
queuestrn(V, 1, s, darkenedby(asciicol, darken), 2);
}

View File

@ -1356,7 +1356,7 @@ EX namespace dice {
h = zpush(-z) * h;
h[2] = h[3]; h[3] = 0;
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++) {

View File

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

143
graph.cpp
View File

@ -537,7 +537,16 @@ double footfun(double d) {
}
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) {
#if CAP_SHAPES
footphase /= SCALE;
@ -578,8 +587,8 @@ void animallegs(const shiftmatrix& V, eMonster mo, color_t col, double footphase
}
#endif
const shiftmatrix VL = mmscale(V, cgi.ALEG0);
const shiftmatrix VAML = mmscale(V, cgi.ALEG);
const shiftmatrix VL = at_smart_lof(V, cgi.ALEG0);
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 * 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
transmatrix otherbodyparts(const shiftmatrix& V, color_t col, eMonster who, double footphase) {
#define VFOOT ((GDIM == 2 || hybri) ? V : mmscale(V, cgi.LEG0))
#define VLEG mmscale(V, cgi.LEG)
#define VGROIN mmscale(V, cgi.GROIN)
#define VBODY mmscale(V, cgi.BODY)
#define VBODY1 mmscale(V, cgi.BODY1)
#define VBODY2 mmscale(V, cgi.BODY2)
#define VBODY3 mmscale(V, cgi.BODY3)
#define VNECK mmscale(V, cgi.NECK)
#define VHEAD mmscale(V, cgi.HEAD)
#define VHEAD1 mmscale(V, cgi.HEAD1)
#define VHEAD2 mmscale(V, cgi.HEAD2)
#define VHEAD3 mmscale(V, cgi.HEAD3)
#define VFOOT ((GDIM == 2 || hybri) ? V : at_smart_lof(V, cgi.LEG0))
#define VLEG at_smart_lof(V, cgi.LEG)
#define VGROIN at_smart_lof(V, cgi.GROIN)
#define VBODY at_smart_lof(V, cgi.BODY)
#define VBODY1 at_smart_lof(V, cgi.BODY1)
#define VBODY2 at_smart_lof(V, cgi.BODY2)
#define VBODY3 at_smart_lof(V, cgi.BODY3)
#define VNECK at_smart_lof(V, cgi.NECK)
#define VHEAD at_smart_lof(V, cgi.HEAD)
#define VHEAD1 at_smart_lof(V, cgi.HEAD1)
#define VHEAD2 at_smart_lof(V, cgi.HEAD2)
#define VHEAD3 at_smart_lof(V, cgi.HEAD3)
#define VALEGS V
#define VABODY mmscale(V, cgi.ABODY)
#define VAHEAD mmscale(V, cgi.AHEAD)
#define VABODY at_smart_lof(V, cgi.ABODY)
#define VAHEAD at_smart_lof(V, cgi.AHEAD)
#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 VGHOST mmscale(V, cgi.GHOST)
#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 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;
@ -653,19 +662,19 @@ transmatrix otherbodyparts(const shiftmatrix& V, color_t col, eMonster who, doub
// todo
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 * Mirror * xpush(-rightfoot*3/4), cgi.shHumanLeg, col);
}
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 * Mirror * xpush(-rightfoot/2), cgi.shHumanLeg, col);
}
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 * 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(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) {
queuepoly(VGROIN, cgi.shHumanGroin, col);
if(who != moZombie) queuepoly(VNECK, cgi.shHumanNeck, col);
}
if(detaillevel >= 2) {
queuepoly(mmscale(V, cgi.GROIN1), cgi.shHumanGroin, col);
if(who != moZombie) queuepoly(mmscale(V, cgi.NECK3), cgi.shHumanNeck, col);
queuepoly(at_smart_lof(V, cgi.GROIN1), cgi.shHumanGroin, col);
if(who != moZombie) queuepoly(at_smart_lof(V, cgi.NECK3), cgi.shHumanNeck, col);
}
return spin(rightfoot * wobble);
@ -749,7 +758,7 @@ EX color_t kind_outline(eItem it) {
EX shiftmatrix face_the_player(const shiftmatrix 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);
transmatrix dummy; /* used only in prod anyways */
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);
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)
Vit = mscale(Vit, sin(ptick(750)) * cgi.plevel / 4);
Vit = orthogonal_move(Vit, sin(ptick(750)) * cgi.plevel / 4);
else if(c && sl2)
Vit = Vit * zpush(sin(ptick(750)) * cgi.plevel / 4);
else
@ -952,7 +961,7 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int
}
if(GDIM == 3) {
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);
queuepoly(V2, cgi.shCompass3, 0xFF0000FF);
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: {
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);
int alpha = (m == moPhaser ? 0xC0 : 0xFF);
if(footphase) {
@ -2112,7 +2121,7 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t
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 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);
queuepoly(VBODY, cgi.shJiangShi, darkena(col, 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;
if(m == moLancer)
V2 = V * spin((where && where->type == 6) ? -60._deg : -90._deg );
shiftmatrix Vh = mmscale(V2, cgi.HEAD);
shiftmatrix Vb = mmscale(V2, cgi.BODY);
shiftmatrix Vh = at_smart_lof(V2, cgi.HEAD);
shiftmatrix Vb = at_smart_lof(V2, cgi.BODY);
Vb = Vb * otherbodyparts(V2, darkena(col, 1, 0xFF), m, footphase);
ShadowV(V2, cgi.shPBody);
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);
ld dist = d.first / R * aspd;
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 */
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);
/* else if(c->monst < moTentacle && wormstyle == 0) {
ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW);
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacleX, 0xFF);
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF);
queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacleX, 0xFF);
queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF);
} */
// 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) {
char part = dragon::bodypart(c, dragon::findhead(c));
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);
}
}
@ -2853,8 +2862,8 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col
col = minf[moTentacletail].color;
}
/*
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacleX, 0xFFFFFFFF);
queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF);
queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacleX, 0xFFFFFFFF);
queuepoly(at_smart_lof(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF);
ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW);
*/
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);
// Vbx = Vbx * rspintox(inverse(Vbx) * Vbx2 * C0) * pispin;
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 {
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);
}
}
else if(m == moWorm || m == moWormwait || m == moHexSnake) {
Vb = Vb * pispin;
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));
queuepolyat(Vbh, cgi.shWormEyes, 0xFF, PPR::ONTENTACLE_EYES);
ShadowV(Vb, cgi.shWormHead, PPR::GIANTSHADOW);
}
else if(m == moDragonHead) {
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);
queuepoly(Vbh, cgi.shDragonHead, darkena(col, c->hitpoints?0:1, 0xFF));
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) {
Vb = Vb * pispin;
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));
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);
}
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));
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);
}
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') {
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 {
if(c->monst == moTentacletail && c->mondir == NODIR) {
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) {
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);
}
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;
queuepoly(Vbb, sh, darkena(col, 0, 0xFF));
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) {
Vs = Vs * rspintox(V0);
if(prod) Vs = mscale(Vs, z);
if(prod) Vs = orthogonal_move(Vs, z);
}
}
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) {
int sl = sidepar - SIDE_SLEV;
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) {
const int layers = 2 << detaillevel;
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) {
const int layers = 1 << (detaillevel-1);
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) {
const int layers = 1 << (detaillevel-1);
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) {
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++)
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) {
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);
hyperpoint h1;
applymodel(T1, h1);
@ -4546,8 +4555,8 @@ void celldrawer::draw_fallanims() {
ddalt.setcolors();
int starcol = c->wall == waVinePlant ? 0x60C000 : ddalt.wcol;
c->wall = w; c->wparam = p;
draw_qfi(c, mscale(V, cgi.WALL), darkena(starcol, fd, 0xFF), PPR::WALL3);
queuepolyat(mscale(V, cgi.WALL), cgi.shWall[ct6], darkena(ddalt.wcol, 0, 0xFF), PPR::WALL3A);
draw_qfi(c, orthogonal_move_fol(V, cgi.WALL), darkena(starcol, fd, 0xFF), PPR::WALL3);
queuepolyat(orthogonal_move_fol(V, cgi.WALL), cgi.shWall[ct6], darkena(ddalt.wcol, 0, 0xFF), PPR::WALL3A);
forCellIdEx(c2, i, c)
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;
}
if(spatial_graphics || GDIM == 3) {
vector<shiftmatrix> corners(c->type+1);
for(int i=0; i<c->type; i++) corners[i] = V * rgpushxto0(get_corner_position(c, i, 3 / rad));
vector<hyperpoint> corners(c->type+1);
for(int i=0; i<c->type; i++) corners[i] = get_corner_position(c, i, 3 / rad);
corners[c->type] = corners[0];
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(mscale(corners[i], cgi.WALL) * C0, mscale(corners[i+1], cgi.WALL) * C0, 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+1], cgi.FLOOR), 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(V * orthogonal_move_fol(corners[i], cgi.FLOOR), V * orthogonal_move_fol(corners[i], cgi.WALL), col, 2, PPR::SUPERLINE);
}
return;
}
@ -4602,13 +4611,13 @@ EX void queuecircleat1(cell *c, const shiftmatrix& V, double rad, color_t col) {
queuecircle(V, rad, col);
if(!wmspatial) return;
if(highwall(c))
queuecircle(mscale(V, cgi.WALL), rad, col);
queuecircle(orthogonal_move_fol(V, cgi.WALL), rad, col);
int sl;
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))
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) {

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
#define ORBBASE 0
#define mmscale(V, x) (mmspatial ? (ivoryz ? mzscale(V,x) : mscale(V, x)) : (V))
#define SHADOW_WALL 0x60
#define SHADOW_SL 0x18
#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);
}
/** should be called get_lof */
EX ld zlevel(const hyperpoint &h) {
if(sl2) return sqrt(-intval(h, Hypc));
else if(translatable) return h[LDIM];
@ -559,7 +560,7 @@ EX hyperpoint mid(const hyperpoint& H1, const hyperpoint& H2) {
if(prod) {
auto d1 = product_decompose(H1);
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);
}
@ -690,9 +691,9 @@ EX transmatrix euaffine(hyperpoint h) {
}
EX transmatrix cpush(int cid, ld alpha) {
transmatrix T = Id;
if(prod && cid == 2)
return mscale(Id, alpha);
return scale_matrix(Id, exp(alpha));
transmatrix T = Id;
if(nonisotropic)
return eupush3(cid == 0 ? alpha : 0, cid == 1 ? alpha : 0, cid == 2 ? alpha : 0);
T[LDIM][LDIM] = T[cid][cid] = cos_auto(alpha);
@ -701,6 +702,10 @@ EX transmatrix cpush(int cid, ld alpha) {
return T;
}
EX transmatrix lzpush(ld z) {
return cpush(2, z);
}
EX transmatrix cmirror(int cid) {
transmatrix T = Id;
T[cid][cid] = -1;
@ -719,9 +724,10 @@ EX bool eqmatrix(transmatrix A, transmatrix B, ld eps IS(.01)) {
}
#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) {
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(!hyperbolic) return rgpushxto0(h) * cpush(2, z) * C0;
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);
if(prod) {
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;
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(prod) {
auto z = zlevel(tC0(T));
T = mscale(T, -z);
T = scale_matrix(T, exp(-z));
PIU(fixmatrix(T));
T = mscale(T, +z);
T = scale_matrix(T, exp(+z));
}
else if(euclid)
fixmatrix_euclid(T);
@ -1164,7 +1170,7 @@ EX transmatrix iview_inverse(transmatrix T) {
EX pair<ld, hyperpoint> product_decompose(hyperpoint 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 */
@ -1247,37 +1253,59 @@ EX ld hdist(const shiftpoint& h1, const shiftpoint& h2) {
return hdist(h1.h, unshift(h2, h1.shift));
}
EX hyperpoint mscale(const hyperpoint& t, double fac) {
if(GDIM == 3 && !prod) return cpush(2, fac) * t;
if(prod) fac = exp(fac);
hyperpoint res;
for(int i=0; i<MXDIM; i++)
res[i] = t[i] * fac;
return res;
/** like orthogonal_move but fol may be factor (in 2D graphics) or level (elsewhere) */
EX hyperpoint orthogonal_move_fol(const hyperpoint& h, double fol) {
if(GDIM == 2) return scale_point(h, fol);
else return orthogonal_move(h, fol);
}
EX shiftpoint mscale(const shiftpoint& t, double fac) {
return shiftless(mscale(t.h, fac), t.shift);
/** like orthogonal_move but fol may be factor (in 2D graphics) or level (elsewhere) */
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) {
if(GDIM == 3 && !prod) {
// if(pmodel == mdFlatten) { transmatrix u = t; u[2][LDIM] -= fac; return u; }
return t * cpush(2, fac);
}
if(prod) fac = exp(fac);
/** like orthogonal_move but fol may be factor (in 2D graphics) or level (elsewhere) */
EX shiftmatrix orthogonal_move_fol(const shiftmatrix& T, double fol) {
if(GDIM == 2) return scale_matrix(T, fol);
else return orthogonal_move(T, fol);
}
/** 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;
for(int i=0; i<MXDIM; i++) {
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++)
res[i][j] = t[i][j];
}
return res;
}
EX shiftmatrix mscale(const shiftmatrix& t, double fac) {
return shiftless(mscale(t.T, fac), t.shift);
/** the scaling matrix (Euclidean homogeneous scaling; also shift by log(scale) in product space */
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) {
@ -1354,13 +1382,6 @@ EX hyperpoint orthogonal_of_C0(hyperpoint h0, hyperpoint h1, hyperpoint h2) {
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) {
hyperpoint H = hpxyz(d*x, d*y, z);
H = mid(H, H);

View File

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

View File

@ -3092,7 +3092,8 @@ EX namespace mapeditor {
hpcshape& sh(cgi.ushr[&ds]);
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) {
last.tinf = &user_triangles_texture;
last.offset_texture = ds.texture_offset;

View File

@ -1407,14 +1407,14 @@ EX namespace hybrid {
ld lev = cgi.plevel * z / 2;
if(WDIM == 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;
}
if(prod) {
dynamicval<eGeometry> g(geometry, hybrid::underlying);
dynamicval<geometry_information*> gc(cgip, hybrid::underlying_cgip);
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 {
#if MAXMDIM >= 4
@ -1571,26 +1571,26 @@ EX namespace product {
struct hrmap_product : hybrid::hrmap_hybrid {
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 {
if(twisted && i == c->type-1 && where[c].second == hybrid::csteps-1) {
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);
if(b.mirrored) T = T * Mirror;
return T;
}
if(twisted && i == c->type-2 && where[c].second == 0) {
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);
if(b.mirrored) T = T * Mirror;
return T;
}
if(i == c->type-1) return mscale(Id, cgi.plevel);
else if(i == c->type-2) return mscale(Id, -cgi.plevel);
if(i == c->type-1) return cpush(2, cgi.plevel);
else if(i == c->type-2) return cpush(2, -cgi.plevel);
c = where[c].first;
return PIU(currentmap->adj(c, i));
}
@ -1620,8 +1620,8 @@ EX namespace product {
}
virtual transmatrix ray_iadj(cell *c, int i) override {
if(i == c->type-2) return (mscale(Id, +cgi.plevel));
if(i == c->type-1) return (mscale(Id, -cgi.plevel));
if(i == c->type-2) return (cpush(2, +cgi.plevel));
if(i == c->type-1) return (cpush(2, -cgi.plevel));
transmatrix T;
cell *cw = hybrid::get_where(c).first;
hybrid::in_underlying_geometry([&] {
@ -1638,7 +1638,7 @@ EX namespace product {
EX hyperpoint inverse_exp(hyperpoint h) {
hyperpoint res;
res[2] = zlevel(h);
h = zshift(h, -res[2]);
h = orthogonal_move(h, -res[2]);
ld r = hypot_d(2, h);
if(hybrid::under_class() == gcEuclid) {
res[0] = h[0];
@ -1664,7 +1664,7 @@ EX namespace product {
res[0] = h[0] * cd;
res[1] = h[1] * cd;
res[2] = cos_auto(d);
return zshift(res, h[2]);
return orthogonal_move(res, h[2]);
}
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) {
for(int i=isize(hpc)-1; i >= last->s; i--) {
hpc.push_back(mscale(hpc[i], fac));
hpc[i] = mscale(hpc[i], fac2);
hpc.push_back(orthogonal_move_fol(hpc[i], fol));
hpc[i] = orthogonal_move_fol(hpc[i], fol2);
}
hpc.push_back(hpc[last->s]);
last->flags |= POLY_ISSIDE;
@ -111,7 +111,7 @@ void geometry_information::chasmifyPoly(double fac, double fac2, int k) {
int zf = int(x);
if(zf == isize(points)-1) 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); });
@ -958,8 +958,8 @@ 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);
if(prod) {
if(bt::in()) h = PIU( parabolic13(h) );
h = zshift(normalize_flat(h), center_altitude * (1-x-y) + altitudes[a] * x + altitudes[b] * y);
hpcpush(h); return;
h = orthogonal_move(normalize_flat(h), center_altitude * (1-x-y) + altitudes[a] * x + altitudes[b] * y);
hpcpush(h); return;
}
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;
if(prod) {
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);
}
else if(nil)

View File

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