embeddings:: shmup fixes
This commit is contained in:
parent
d67b157904
commit
2fe39a6613
|
@ -2257,6 +2257,10 @@ EX void display_embedded_errors() {
|
||||||
dialog::addInfo(XLAT("error: currently works only in binary tiling and similar"), 0xC00000);
|
dialog::addInfo(XLAT("error: currently works only in binary tiling and similar"), 0xC00000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(shmup::on && cgi.emb->no_spin()) {
|
||||||
|
dialog::addInfo(XLAT("error: this embedding does not work in shmup"), 0xC00000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(meuclid && spatial_embedding == seCliffordTorus) {
|
if(meuclid && spatial_embedding == seCliffordTorus) {
|
||||||
rug::clifford_torus ct;
|
rug::clifford_torus ct;
|
||||||
ld h = ct.xh | ct.yh;
|
ld h = ct.xh | ct.yh;
|
||||||
|
|
|
@ -236,6 +236,7 @@ EX }
|
||||||
virtual hyperpoint logical_to_base(hyperpoint h) = 0;
|
virtual hyperpoint logical_to_base(hyperpoint h) = 0;
|
||||||
virtual ld anim_center_z() { return center_z(); }
|
virtual ld anim_center_z() { return center_z(); }
|
||||||
virtual hyperpoint anim_tile_center();
|
virtual hyperpoint anim_tile_center();
|
||||||
|
virtual void logical_fix(transmatrix&) = 0;
|
||||||
|
|
||||||
virtual bool is_euc_in_product() { return false; }
|
virtual bool is_euc_in_product() { return false; }
|
||||||
virtual bool is_product_embedding() { return false; }
|
virtual bool is_product_embedding() { return false; }
|
||||||
|
@ -380,6 +381,17 @@ struct emb_none : embedding_method {
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logical_fix(transmatrix& T) {
|
||||||
|
if(nonisotropic) {
|
||||||
|
hyperpoint h = tC0(T);
|
||||||
|
transmatrix rot = gpushxto0(h) * T;
|
||||||
|
fix_rotation(rot);
|
||||||
|
T = rgpushxto0(h) * rot;
|
||||||
|
}
|
||||||
|
else fixmatrix(T);
|
||||||
|
fixelliptic(T);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** embeddings methods that are not emb_none */
|
/** embeddings methods that are not emb_none */
|
||||||
|
@ -407,14 +419,27 @@ struct emb_actual : embedding_method {
|
||||||
h[3] = 1;
|
h[3] = 1;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logical_fix(transmatrix& T) {
|
||||||
|
hyperpoint a = T * tile_center();
|
||||||
|
hyperpoint i0 = actual_to_intermediate(a);
|
||||||
|
auto l0 = intermediate_to_logical * i0;
|
||||||
|
auto l = l0; l[2] = 0;
|
||||||
|
auto i = logical_to_intermediate * l;
|
||||||
|
auto rot0= inverse(intermediate_to_actual_translation(i0)) * T ;
|
||||||
|
auto rot = intermediate_to_logical_scaled * rot0 * logical_scaled_to_intermediate;
|
||||||
|
ld alpha = atan2(rot[0][1], rot[0][0]);
|
||||||
|
T = intermediate_to_actual_translation(i) * spin(alpha);
|
||||||
|
fixelliptic(T);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** embed in the 3D variant of the same geometry */
|
/** embed in the 3D variant of the same geometry */
|
||||||
|
|
||||||
struct emb_same_in_same : emb_actual {
|
struct emb_same_in_same : emb_actual {
|
||||||
virtual bool is_same_in_same() { return true; }
|
virtual bool is_same_in_same() { return true; }
|
||||||
transmatrix intermediate_to_actual_translation(hyperpoint i) override { return rgpushxto0(i); }
|
transmatrix intermediate_to_actual_translation(hyperpoint i) override { return rgpushxto0(logical_to_actual(i)); }
|
||||||
hyperpoint actual_to_intermediate(hyperpoint a) override { return a; }
|
hyperpoint actual_to_intermediate(hyperpoint a) override { return actual_to_logical(a); }
|
||||||
hyperpoint orthogonal_move(const hyperpoint& h, ld z) override {
|
hyperpoint orthogonal_move(const hyperpoint& h, ld z) override {
|
||||||
ld u = 1;
|
ld u = 1;
|
||||||
if(h[2]) z += asin_auto(h[2]), u /= cos_auto(asin_auto(h[2]));
|
if(h[2]) z += asin_auto(h[2]), u /= cos_auto(asin_auto(h[2]));
|
||||||
|
@ -478,6 +503,12 @@ struct emb_same_in_same : emb_actual {
|
||||||
return hpxy3(h[0] * u, h[1] * u, 0);
|
return hpxy3(h[0] * u, h[1] * u, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logical_fix(transmatrix& T) override {
|
||||||
|
// optimization
|
||||||
|
for(int i=0; i<4; i++) T[i][2] = T[2][i] = i == 2;
|
||||||
|
fixmatrix(T);
|
||||||
|
fixelliptic(T);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** embed in the product geometry */
|
/** embed in the product geometry */
|
||||||
|
@ -539,7 +570,7 @@ struct emb_sphere_in_low : emb_actual {
|
||||||
bool is_sph_in_low() override { return true; }
|
bool is_sph_in_low() override { return true; }
|
||||||
bool is_depth_limited() override { return true; }
|
bool is_depth_limited() override { return true; }
|
||||||
transmatrix intermediate_to_actual_translation(hyperpoint i) override {
|
transmatrix intermediate_to_actual_translation(hyperpoint i) override {
|
||||||
return map_relative_push(logical_to_actual(i));
|
return map_relative_push(logical_to_actual(i)) * zpush(-1);
|
||||||
}
|
}
|
||||||
hyperpoint actual_to_intermediate(hyperpoint a) override { return actual_to_logical(a); }
|
hyperpoint actual_to_intermediate(hyperpoint a) override { return actual_to_logical(a); }
|
||||||
ld center_z() { return 1; }
|
ld center_z() { return 1; }
|
||||||
|
@ -596,6 +627,12 @@ struct emb_sphere_in_low : emb_actual {
|
||||||
h[2] = z; h[3] = 1;
|
h[2] = z; h[3] = 1;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logical_fix(transmatrix& T) {
|
||||||
|
fix4(T);
|
||||||
|
fixmatrix(T);
|
||||||
|
fixelliptic(T);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** abstract class for embeddings of Euclidean plane; these embeddings are not isotropic */
|
/** abstract class for embeddings of Euclidean plane; these embeddings are not isotropic */
|
||||||
|
|
|
@ -1449,28 +1449,27 @@ EX transmatrix shift_object(transmatrix Position, const transmatrix& ori, const
|
||||||
}
|
}
|
||||||
case smEmbedded: {
|
case smEmbedded: {
|
||||||
|
|
||||||
if(cgi.emb->is_euc_in_hyp() || cgi.emb->is_sph_in_low()) {
|
// optimization -- should work without it
|
||||||
geom3::light_flip(true);
|
if(cgi.emb->is_same_in_same()) return Position * rgpushxto0(direct_exp(direction));
|
||||||
transmatrix T = rgpushxto0(direct_exp(direction));
|
|
||||||
geom3::light_flip(false);
|
if(gproduct) {
|
||||||
return Position * cgi.emb->base_to_actual(T);
|
return Position * cgi.emb->intermediate_to_actual_translation(ori * cgi.emb->logical_to_intermediate * direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cgi.emb->is_euc_in_sph()) Position = inverse(View) * Position;
|
auto P = inverse_shift(ggmatrix(cwt.at), shiftless(Position));
|
||||||
|
|
||||||
transmatrix rot = inverse(cgi.emb->map_relative_push(Position * tile_center())) * Position;
|
hyperpoint a = P * tile_center();
|
||||||
ld z = cgi.emb->center_z();
|
hyperpoint i0 = cgi.emb->actual_to_intermediate(a);
|
||||||
if(z) rot = rot * lzpush(z);
|
auto l0 = cgi.emb->intermediate_to_logical * i0;
|
||||||
transmatrix urot = unswap_spin(rot);
|
auto l = l0; l[2] = 0;
|
||||||
|
auto i = cgi.emb->logical_to_intermediate * l;
|
||||||
|
auto rot1 = inverse(cgi.emb->intermediate_to_actual_translation(i)) * P;
|
||||||
|
auto rot = cgi.emb->intermediate_to_logical_scaled * rot1 * cgi.emb->logical_scaled_to_intermediate;
|
||||||
|
|
||||||
geom3::light_flip(true);
|
auto par = cgi.emb->logical_to_intermediate * rot * direction;
|
||||||
transmatrix T = rgpushxto0(direct_exp(urot * direction));
|
if(cgi.emb->is_sph_in_low()) par = cspin180(0, 1) * par; // reason unknown
|
||||||
geom3::light_flip(false);
|
auto tra = cgi.emb->intermediate_to_actual_translation(par);
|
||||||
T = cgi.emb->base_to_actual(T);
|
return Position * inverse(rot1) * tra * rot1;
|
||||||
auto res = Position * inverse(rot) * T * rot;
|
|
||||||
|
|
||||||
if(cgi.emb->is_euc_in_sph()) res = View * res;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
default: throw hr_exception("unknown shift method in shift_object");
|
default: throw hr_exception("unknown shift method in shift_object");
|
||||||
}
|
}
|
||||||
|
|
21
hypgraph.cpp
21
hypgraph.cpp
|
@ -2025,14 +2025,9 @@ EX void adjust_eye(transmatrix& T, cell *c, ld sign) {
|
||||||
T = T * lzpush(sign * (cgi.SLEV[sl] - cgi.FLOOR - vid.eye + i));
|
T = T * lzpush(sign * (cgi.SLEV[sl] - cgi.FLOOR - vid.eye + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** achieve top-down perspective */
|
|
||||||
EX transmatrix default_spin() {
|
|
||||||
return cspin90(0, 1) * cgi.emb->intermediate_to_logical_scaled;
|
|
||||||
}
|
|
||||||
|
|
||||||
EX bool shmup_inverted() {
|
EX bool shmup_inverted() {
|
||||||
if(!embedded_plane) return false;
|
if(!embedded_plane) return false;
|
||||||
return (vid.wall_height < 0) ^ (cgi.emb->is_euc_in_nil() || cgi.emb->is_euc_in_sl2());
|
return vid.wall_height < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void centerpc(ld aspd) {
|
EX void centerpc(ld aspd) {
|
||||||
|
@ -2056,8 +2051,8 @@ EX void centerpc(ld aspd) {
|
||||||
centerover = pc->base;
|
centerover = pc->base;
|
||||||
transmatrix T = pc->at;
|
transmatrix T = pc->at;
|
||||||
|
|
||||||
if(nonisotropic) {
|
if(embedded_plane) {
|
||||||
transmatrix rot = inverse(rgpushxto0(T * C0)) * T;
|
transmatrix rot = inverse(cgi.emb->intermediate_to_actual_translation(cgi.emb->actual_to_intermediate(T * tile_center()))) * T;
|
||||||
T = T * inverse(rot);
|
T = T * inverse(rot);
|
||||||
adjust_eye(T, pc->base, +1);
|
adjust_eye(T, pc->base, +1);
|
||||||
T = T * rot;
|
T = T * rot;
|
||||||
|
@ -2069,11 +2064,13 @@ EX void centerpc(ld aspd) {
|
||||||
View = iview_inverse(T);
|
View = iview_inverse(T);
|
||||||
if(gproduct) NLP = ortho_inverse(pc->ori);
|
if(gproduct) NLP = ortho_inverse(pc->ori);
|
||||||
if(WDIM == 2) {
|
if(WDIM == 2) {
|
||||||
|
// already taken into account in gproduct
|
||||||
|
rotate_view(cgi.emb->intermediate_to_logical_scaled);
|
||||||
|
// right => upwards
|
||||||
|
rotate_view(cspin90(0, 1));
|
||||||
|
// apply playerturny
|
||||||
if(shmup_inverted()) rotate_view(cspin180(2, 1));
|
if(shmup_inverted()) rotate_view(cspin180(2, 1));
|
||||||
if(gproduct)
|
rotate_view( cspin(2, 1, -90._deg - shmup::playerturny[id]));
|
||||||
rotate_view( cspin(2, 1, -90._deg - shmup::playerturny[id]) * cspin90(0, 1));
|
|
||||||
else
|
|
||||||
rotate_view( cspin(2, 1, -90._deg - shmup::playerturny[id]) * default_spin());
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
47
shmup.cpp
47
shmup.cpp
|
@ -105,7 +105,6 @@ void monster::reset() {
|
||||||
stunoff = 0; blowoff = 0; fragoff = 0; footphase = 0;
|
stunoff = 0; blowoff = 0; fragoff = 0; footphase = 0;
|
||||||
inertia = Hypc; ori = Id; vel = 0;
|
inertia = Hypc; ori = Id; vel = 0;
|
||||||
swordangle = 0;
|
swordangle = 0;
|
||||||
if(cgip && cgi.emb && cgi.emb->is_euc_in_product()) ori = cgi.emb->intermediate_to_logical_scaled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace multi;
|
using namespace multi;
|
||||||
|
@ -185,51 +184,11 @@ cell *monster::findbase(const shiftmatrix& T, int maxsteps) {
|
||||||
else return findbaseAround(T, base, maxsteps);
|
else return findbaseAround(T, base, maxsteps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** fix the matrix, including the appropriate fixes for nonisotropic, embedded_plane, and elliptic space */
|
|
||||||
void full_fix(transmatrix& T) {
|
|
||||||
if(embedded_plane) {
|
|
||||||
if(cgi.emb->is_sph_in_low()) {
|
|
||||||
for(int i=0; i<4; i++) T[i][3] = 0, T[3][i] = 0;
|
|
||||||
T[3][3] = 1;
|
|
||||||
fixmatrix(T);
|
|
||||||
}
|
|
||||||
else if(cgi.emb->is_same_in_same()) {
|
|
||||||
for(int i=0; i<4; i++) T[i][2] = 0, T[2][i] = 0;
|
|
||||||
T[2][2] = 1;
|
|
||||||
fixmatrix(T);
|
|
||||||
}
|
|
||||||
else if(gproduct) {
|
|
||||||
fixmatrix(T);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hyperpoint h = T * tile_center();
|
|
||||||
transmatrix rot = iso_inverse(cgi.emb->map_relative_push(h)) * T;
|
|
||||||
if(cgi.emb->is_euc_in_sph()) rot = rot * lzpush(1);
|
|
||||||
fix_rotation(rot);
|
|
||||||
if(cgi.emb->is_hyp_in_solnih()) h[0] = 0;
|
|
||||||
else if(cgi.emb->is_euc_in_nil()) h[1] = 0;
|
|
||||||
|
|
||||||
T = cgi.emb->map_relative_push(h) * rot;
|
|
||||||
if(cgi.emb->is_euc_in_sph()) T = T * lzpush(-1);
|
|
||||||
fixmatrix(T);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(nonisotropic) {
|
|
||||||
hyperpoint h = tC0(T);
|
|
||||||
transmatrix rot = gpushxto0(h) * T;
|
|
||||||
fix_rotation(rot);
|
|
||||||
T = rgpushxto0(h) * rot;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fixmatrix(T);
|
|
||||||
fixelliptic(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
void monster::rebasePat(const shiftmatrix& new_pat, cell *c2) {
|
void monster::rebasePat(const shiftmatrix& new_pat, cell *c2) {
|
||||||
if(isVirtual) {
|
if(isVirtual) {
|
||||||
at = new_pat.T;
|
at = new_pat.T;
|
||||||
virtualRebase(this);
|
virtualRebase(this);
|
||||||
full_fix(at);
|
cgi.emb->logical_fix(at);
|
||||||
pat = shiftless(at);
|
pat = shiftless(at);
|
||||||
if(multi::players == 1 && this == shmup::pc[0])
|
if(multi::players == 1 && this == shmup::pc[0])
|
||||||
current_display->which_copy = back_to_view(ggmatrix(base));
|
current_display->which_copy = back_to_view(ggmatrix(base));
|
||||||
|
@ -239,7 +198,7 @@ void monster::rebasePat(const shiftmatrix& new_pat, cell *c2) {
|
||||||
at = inverse_shift(gmatrix[base], new_pat);
|
at = inverse_shift(gmatrix[base], new_pat);
|
||||||
transmatrix old_at = at;
|
transmatrix old_at = at;
|
||||||
virtualRebase(this);
|
virtualRebase(this);
|
||||||
full_fix(at);
|
cgi.emb->logical_fix(at);
|
||||||
if(base != c2) {
|
if(base != c2) {
|
||||||
if(fake::split()) println(hlog, "fake error");
|
if(fake::split()) println(hlog, "fake error");
|
||||||
else {
|
else {
|
||||||
|
@ -257,7 +216,7 @@ void monster::rebasePat(const shiftmatrix& new_pat, cell *c2) {
|
||||||
pat = new_pat;
|
pat = new_pat;
|
||||||
base = c2;
|
base = c2;
|
||||||
at = inverse_shift(gmatrix[c2], pat);
|
at = inverse_shift(gmatrix[c2], pat);
|
||||||
full_fix(at);
|
cgi.emb->logical_fix(at);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trackroute(monster *m, shiftmatrix goal, double spd) {
|
bool trackroute(monster *m, shiftmatrix goal, double spd) {
|
||||||
|
|
Loading…
Reference in New Issue