multi:: two-focus projections
This commit is contained in:
parent
a6cbedc944
commit
6d554d6b2e
38
graph.cpp
38
graph.cpp
|
@ -4918,6 +4918,21 @@ EX transmatrix Viewbase;
|
||||||
|
|
||||||
EX bool no_wall_rendering;
|
EX bool no_wall_rendering;
|
||||||
|
|
||||||
|
EX bool set_multi = false;
|
||||||
|
EX hyperpoint multi_point;
|
||||||
|
|
||||||
|
EX void center_multiplayer_map(const vector<hyperpoint>& hs) {
|
||||||
|
hyperpoint h = Hypc;
|
||||||
|
for(auto h1: hs) h += h1;
|
||||||
|
h /= isize(hs);
|
||||||
|
h = normalize(h);
|
||||||
|
cwtV = shiftless(rgpushxto0(h));
|
||||||
|
if(isize(hs) == 2) {
|
||||||
|
set_multi = true;
|
||||||
|
multi_point = hs[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EX void drawthemap() {
|
EX void drawthemap() {
|
||||||
check_cgi();
|
check_cgi();
|
||||||
cgi.require_shapes();
|
cgi.require_shapes();
|
||||||
|
@ -5032,6 +5047,7 @@ EX void drawthemap() {
|
||||||
drawFlashes();
|
drawFlashes();
|
||||||
|
|
||||||
mapeditor::draw_dtshapes();
|
mapeditor::draw_dtshapes();
|
||||||
|
set_multi = false;
|
||||||
|
|
||||||
if(multi::players > 1 && !shmup::on) {
|
if(multi::players > 1 && !shmup::on) {
|
||||||
if(multi::split_screen)
|
if(multi::split_screen)
|
||||||
|
@ -5039,13 +5055,10 @@ EX void drawthemap() {
|
||||||
else if(multi::centerplayer != -1)
|
else if(multi::centerplayer != -1)
|
||||||
cwtV = multi::whereis[multi::centerplayer];
|
cwtV = multi::whereis[multi::centerplayer];
|
||||||
else {
|
else {
|
||||||
hyperpoint h = Hypc;
|
vector<hyperpoint> pts;
|
||||||
for(int p=0; p<multi::players; p++) if(multi::playerActive(p)) {
|
for(int p=0; p<multi::players; p++) if(multi::playerActive(p))
|
||||||
hyperpoint h1 = unshift(tC0(multi::whereis[p]));
|
pts.push_back(unshift(tC0(multi::whereis[p])));
|
||||||
h += h1;
|
center_multiplayer_map(pts);
|
||||||
}
|
|
||||||
h = mid(h, h);
|
|
||||||
cwtV = shiftless(rgpushxto0(h));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5057,13 +5070,10 @@ EX void drawthemap() {
|
||||||
else if(multi::centerplayer != -1)
|
else if(multi::centerplayer != -1)
|
||||||
cwtV = shmup::pc[multi::centerplayer]->pat;
|
cwtV = shmup::pc[multi::centerplayer]->pat;
|
||||||
else {
|
else {
|
||||||
hyperpoint h = Hypc;
|
vector<hyperpoint> pts;
|
||||||
for(int p=0; p<multi::players; p++) {
|
for(int p=0; p<multi::players; p++)
|
||||||
hyperpoint h1 = unshift(tC0(shmup::pc[p]->pat));
|
pts.push_back(unshift(tC0(shmup::pc[p]->pat)));
|
||||||
h += h1;
|
center_multiplayer_map(pts);
|
||||||
}
|
|
||||||
h = mid(h, h);
|
|
||||||
cwtV = shiftless(rgpushxto0(h));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
hyper.h
2
hyper.h
|
@ -266,6 +266,7 @@ struct projection_configuration {
|
||||||
ld depth_scaling;
|
ld depth_scaling;
|
||||||
ld hyperboloid_scaling;
|
ld hyperboloid_scaling;
|
||||||
ld vr_angle, vr_zshift, vr_scale_factor;
|
ld vr_angle, vr_zshift, vr_scale_factor;
|
||||||
|
bool dualfocus_autoscale;
|
||||||
|
|
||||||
int back_and_front; /* 0 = do not, 1 = do, 2 = only back */
|
int back_and_front; /* 0 = do not, 1 = do, 2 = only back */
|
||||||
|
|
||||||
|
@ -289,6 +290,7 @@ struct projection_configuration {
|
||||||
vr_zshift = 0;
|
vr_zshift = 0;
|
||||||
vr_scale_factor = 1;
|
vr_scale_factor = 1;
|
||||||
back_and_front = 0;
|
back_and_front = 0;
|
||||||
|
dualfocus_autoscale = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
21
hypgraph.cpp
21
hypgraph.cpp
|
@ -947,6 +947,9 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) {
|
||||||
|
|
||||||
if(pmodel == mdJoukowskyInverted) {
|
if(pmodel == mdJoukowskyInverted) {
|
||||||
ld r2 = sqhypot_d(2, ret);
|
ld r2 = sqhypot_d(2, ret);
|
||||||
|
if(pconf.dualfocus_autoscale)
|
||||||
|
ret *= (1-pconf.model_transition) / 2;
|
||||||
|
|
||||||
ret[0] = ret[0] / r2;
|
ret[0] = ret[0] / r2;
|
||||||
ret[1] = -ret[1] / r2;
|
ret[1] = -ret[1] / r2;
|
||||||
move_y_to_z(ret, yz);
|
move_y_to_z(ret, yz);
|
||||||
|
@ -1315,11 +1318,18 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case mdPanini: {
|
case mdPanini: {
|
||||||
|
find_zlev(H);
|
||||||
|
models::apply_orientation_yz(H[1], H[2]);
|
||||||
|
models::apply_orientation(H[0], H[1]);
|
||||||
|
|
||||||
ld proh = sqrt(H[2]*H[2] + curvature() * H[0] * H[0]);
|
ld proh = sqrt(H[2]*H[2] + curvature() * H[0] * H[0]);
|
||||||
H /= proh;
|
H /= proh;
|
||||||
H /= (H[2] + pconf.alpha);
|
H /= (H[2] + pconf.alpha);
|
||||||
ret = H;
|
ret = H;
|
||||||
ret[2] = 0; ret[3] = 1;
|
ret[2] = 0; ret[3] = 1;
|
||||||
|
|
||||||
|
models::apply_orientation(ret[1], ret[0]);
|
||||||
|
models::apply_orientation_yz(ret[2], ret[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1998,6 +2008,17 @@ EX void centerpc(ld aspd) {
|
||||||
spinEdge(aspd);
|
spinEdge(aspd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(set_multi && multi::two_focus) {
|
||||||
|
pconf.model_orientation = atan2(multi_point) / degree;
|
||||||
|
auto& d = pconf.twopoint_param;
|
||||||
|
d = hdist0(multi_point);
|
||||||
|
if(among(pmodel, mdJoukowsky, mdJoukowskyInverted)) {
|
||||||
|
pconf.model_orientation += 90;
|
||||||
|
pconf.model_transition = sinh(d) / (1 + cosh(d));
|
||||||
|
pconf.dualfocus_autoscale = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ors::rerotate(W); ors::rerotate(cwtV.T); ors::rerotate(View);
|
ors::rerotate(W); ors::rerotate(cwtV.T); ors::rerotate(View);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -600,6 +600,9 @@ EX namespace models {
|
||||||
|
|
||||||
if(among(vpmodel, mdJoukowsky, mdJoukowskyInverted, mdSpiral) && GDIM == 2)
|
if(among(vpmodel, mdJoukowsky, mdJoukowskyInverted, mdSpiral) && GDIM == 2)
|
||||||
add_edit(vpconf.skiprope);
|
add_edit(vpconf.skiprope);
|
||||||
|
|
||||||
|
if(vpmodel == mdJoukowskyInverted)
|
||||||
|
add_edit(vpconf.dualfocus_autoscale);
|
||||||
|
|
||||||
if(vpmodel == mdHemisphere && euclid)
|
if(vpmodel == mdHemisphere && euclid)
|
||||||
add_edit(vpconf.euclid_to_sphere);
|
add_edit(vpconf.euclid_to_sphere);
|
||||||
|
@ -1024,6 +1027,9 @@ EX namespace models {
|
||||||
|
|
||||||
param_f(p.skiprope, sp+"mobius", 0)
|
param_f(p.skiprope, sp+"mobius", 0)
|
||||||
-> editable(0, 360, 15, "Möbius transformations", "", 'S')->unit = "°";
|
-> editable(0, 360, 15, "Möbius transformations", "", 'S')->unit = "°";
|
||||||
|
|
||||||
|
param_b(p.dualfocus_autoscale, sp+"dualfocus_autoscale", 0)
|
||||||
|
-> editable("autoscale dual focus", 'A');
|
||||||
|
|
||||||
addsaver(p.formula, sp+"formula");
|
addsaver(p.formula, sp+"formula");
|
||||||
addsaverenum(p.basic_model, sp+"basic model");
|
addsaverenum(p.basic_model, sp+"basic model");
|
||||||
|
|
15
multi.cpp
15
multi.cpp
|
@ -32,6 +32,7 @@ EX namespace multi {
|
||||||
EX bool pvp_mode;
|
EX bool pvp_mode;
|
||||||
EX bool friendly_fire = true;
|
EX bool friendly_fire = true;
|
||||||
EX bool self_hits;
|
EX bool self_hits;
|
||||||
|
EX bool two_focus;
|
||||||
|
|
||||||
EX int players = 1;
|
EX int players = 1;
|
||||||
EX cellwalker player[MAXPLAYER];
|
EX cellwalker player[MAXPLAYER];
|
||||||
|
@ -518,6 +519,7 @@ EX void showConfigureMultiplayer() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_edit(self_hits);
|
||||||
if(multi::players > 1) {
|
if(multi::players > 1) {
|
||||||
dialog::addItem(XLAT("reset per-player statistics"), 'r');
|
dialog::addItem(XLAT("reset per-player statistics"), 'r');
|
||||||
dialog::add_action([] {
|
dialog::add_action([] {
|
||||||
|
@ -531,7 +533,6 @@ EX void showConfigureMultiplayer() {
|
||||||
if(shmup::on && !racing::on) {
|
if(shmup::on && !racing::on) {
|
||||||
add_edit(pvp_mode);
|
add_edit(pvp_mode);
|
||||||
add_edit(friendly_fire);
|
add_edit(friendly_fire);
|
||||||
add_edit(self_hits);
|
|
||||||
if(pvp_mode)
|
if(pvp_mode)
|
||||||
dialog::addInfo(XLAT("PvP grants infinite lives -- achievements disabled"));
|
dialog::addInfo(XLAT("PvP grants infinite lives -- achievements disabled"));
|
||||||
else if(friendly_fire)
|
else if(friendly_fire)
|
||||||
|
@ -539,10 +540,16 @@ EX void showConfigureMultiplayer() {
|
||||||
else
|
else
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
dialog::addInfo(XLAT("PvP available only in shmup"));
|
dialog::addInfo(XLAT("PvP available only in shmup"));
|
||||||
|
dialog::addBreak(400);
|
||||||
|
}
|
||||||
|
if(multi::players == 2 && !split_screen)
|
||||||
|
add_edit(two_focus);
|
||||||
|
else
|
||||||
|
dialog::addBreak(100);
|
||||||
}
|
}
|
||||||
else dialog::addBreak(200);
|
else dialog::addBreak(600);
|
||||||
|
|
||||||
dialog::addBack();
|
dialog::addBack();
|
||||||
dialog::display();
|
dialog::display();
|
||||||
|
@ -720,6 +727,8 @@ EX void initConfig() {
|
||||||
->editable("friendly fire", 'f');
|
->editable("friendly fire", 'f');
|
||||||
param_b(multi::self_hits, "self_hits", false)
|
param_b(multi::self_hits, "self_hits", false)
|
||||||
->editable("self hits", 'h');
|
->editable("self hits", 'h');
|
||||||
|
param_b(multi::two_focus, "two_focus", false)
|
||||||
|
->editable("auto-adjust two-focus projections", 'f');
|
||||||
addsaver(alwaysuse, "use configured keys");
|
addsaver(alwaysuse, "use configured keys");
|
||||||
// unfortunately we cannot use key names here because SDL is not yet initialized
|
// unfortunately we cannot use key names here because SDL is not yet initialized
|
||||||
for(int i=0; i<512; i++)
|
for(int i=0; i<512; i++)
|
||||||
|
|
Loading…
Reference in New Issue