1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-27 02:20:36 +00:00

refactored animation, and should now work in every embedded

This commit is contained in:
Zeno Rogue 2023-01-08 03:09:40 +01:00
parent 5dcddc9365
commit 6259815f7f
2 changed files with 21 additions and 41 deletions

View File

@ -2617,30 +2617,12 @@ EX bool applyAnimation(cell *c, shiftmatrix& V, double& footphase, int layer) {
ld aspd = td / 1000.0 * exp(vid.mspeed); ld aspd = td / 1000.0 * exp(vid.mspeed);
ld R; ld R;
again: again:
auto TC0 = tile_center();
if(sl2) {
a.wherenow = slr::translate(tC0(a.wherenow));
hyperpoint h = tC0(iso_inverse(a.wherenow));
hyperpoint ie = slr::get_inverse_exp(shiftless(h));
auto R = hypot_d(3, ie);
aspd *= (1+R+(shmup::on?1:0));
if(R < aspd || std::isnan(R) || std::isnan(aspd) || R > 10) {
animations[layer].erase(c);
return false;
}
a.wherenow = nisot::parallel_transport(a.wherenow, tangent_length(h, aspd));
a.footphase += a.attacking == 2 ? -aspd : aspd;
// todo attack animation, rotate correctly
footphase = a.footphase;
V = V * a.wherenow;
a.ltick = ticks;
return true;
}
if(among(a.attacking, 1, 3)) if(among(a.attacking, 1, 3))
R = hdist(tC0(a.attackat), tC0(a.wherenow)); R = hdist(a.attackat * TC0, a.wherenow * TC0);
else else
R = hdist0(tC0(a.wherenow)); R = hdist(a.wherenow * TC0, TC0);
aspd *= (1+R+(shmup::on?1:0)); aspd *= (1+R+(shmup::on?1:0));
if(a.attacking == 3 && aspd > R) aspd = R; if(a.attacking == 3 && aspd > R) aspd = R;
@ -2651,22 +2633,20 @@ EX bool applyAnimation(cell *c, shiftmatrix& V, double& footphase, int layer) {
return false; return false;
} }
else { else {
transmatrix T = inverse(a.wherenow);
if(moved_center()) T = lzpush(-1) * T;
hyperpoint wnow; hyperpoint wnow;
if(a.attacking == 1 || a.attacking == 3) if(a.attacking == 1 || a.attacking == 3)
wnow = tC0(z_inverse(a.wherenow) * a.attackat); wnow = T * a.attackat * TC0;
else else
wnow = tC0(z_inverse(a.wherenow)); wnow = T * TC0;
shift_v_towards(T, shiftless(wnow), aspd, shift_method(smaAnimation));
if(moved_center()) T = lzpush(1) * T;
a.wherenow = inverse(T);
fixmatrix(a.wherenow);
if(gproduct) {
auto d = product_decompose(wnow);
ld dist = d.first / R * aspd;
if(abs(dist) > abs(d.first)) dist = -d.first;
a.wherenow = orthogonal_move(a.wherenow, dist);
/* signed_sqrt to prevent precision errors */
aspd *= signed_sqrt(R*R - d.first * d.first) / R;
}
a.wherenow = a.wherenow * rspintox(wnow);
a.wherenow = a.wherenow * xpush(aspd);
if(cgflags & qAFFINE) { if(cgflags & qAFFINE) {
transmatrix T = a.wherenow; transmatrix T = a.wherenow;
fixmatrix_euclid(T); fixmatrix_euclid(T);
@ -2675,15 +2655,15 @@ EX bool applyAnimation(cell *c, shiftmatrix& V, double& footphase, int layer) {
a.wherenow[i] = lerp(a.wherenow[i], Id[i], aspd / R); a.wherenow[i] = lerp(a.wherenow[i], Id[i], aspd / R);
a.wherenow = T * a.wherenow; a.wherenow = T * a.wherenow;
} }
fixmatrix(a.wherenow);
a.footphase += a.attacking == 2 ? -aspd : aspd; a.footphase += a.attacking == 2 ? -aspd : aspd;
if(a.attacking == 3 && aspd >= R) { if(a.attacking == 3 && aspd >= R) {
a.footphase = 0; a.footphase = 0;
hyperpoint h1 = a.wherenow * C0; hyperpoint h1 = a.wherenow * C0;
a.wherenow = rgpushxto0(h1) * rspintox(h1); a.wherenow = rgpushxto0(h1) * lrspintox(h1);
} }
footphase = a.footphase; footphase = a.footphase;
V = V * a.wherenow; V = V * a.wherenow * lrspintox(wnow);
if(a.mirrored) V = V * lmirror(); if(a.mirrored) V = V * lmirror();
if(a.attacking == 2) V = V * lpispin(); if(a.attacking == 2) V = V * lpispin();
a.ltick = ticks; a.ltick = ticks;
@ -6055,8 +6035,8 @@ EX void animateAttackOrHug(const movei& m, int layer, int phase, ld ratio, ld de
bool newanim = !animations[layer].count(m.s); bool newanim = !animations[layer].count(m.s);
animation& a = animations[layer][m.s]; animation& a = animations[layer][m.s];
a.attacking = phase; a.attacking = phase;
if(phase == 3) println(hlog, "distance = ", hdist0(T * C0)); auto TC0 = tile_center();
a.attackat = lrspintox(tC0(iso_inverse(T))) * lxpush(hdist0(T*C0) * ratio + delta); a.attackat = lrspintox(iso_inverse(T) * TC0) * lxpush(hdist(TC0, T*TC0) * ratio + delta);
if(newanim) a.wherenow = Id, a.ltick = ticks, a.footphase = 0; if(newanim) a.wherenow = Id, a.ltick = ticks, a.footphase = 0;
} }

View File

@ -1767,14 +1767,14 @@ EX ld xcross(ld x1, ld y1, ld x2, ld y2) { return x1 + (x2 - x1) * y1 / (y1 - y2
#if HDR #if HDR
enum eShiftMethod { smProduct, smIsotropic, smEmbedded, smLie, smGeodesic, smESL2 }; enum eShiftMethod { smProduct, smIsotropic, smEmbedded, smLie, smGeodesic, smESL2 };
enum eEmbeddedShiftMethodChoice { smcNone, smcBoth, smcAuto }; enum eEmbeddedShiftMethodChoice { smcNone, smcBoth, smcAuto };
enum eShiftMethodApplication { smaManualCamera, smaAutocenter, smaObject, smaWallRadar }; enum eShiftMethodApplication { smaManualCamera, smaAutocenter, smaObject, smaWallRadar, smaAnimation };
#endif #endif
EX eEmbeddedShiftMethodChoice embedded_shift_method_choice = smcBoth; EX eEmbeddedShiftMethodChoice embedded_shift_method_choice = smcBoth;
EX bool use_embedded_shift(eShiftMethodApplication sma) { EX bool use_embedded_shift(eShiftMethodApplication sma) {
switch(sma) { switch(sma) {
case smaAutocenter: return embedded_shift_method_choice != smcNone; case smaAutocenter: case smaAnimation: return embedded_shift_method_choice != smcNone;
case smaManualCamera: return embedded_shift_method_choice == smcBoth; case smaManualCamera: return embedded_shift_method_choice == smcBoth;
case smaObject: return true; case smaObject: return true;
case smaWallRadar: return among(pmodel, mdLiePerspective, mdLieOrthogonal); case smaWallRadar: return among(pmodel, mdLiePerspective, mdLieOrthogonal);