cleaned up keep_vertical_orientation; camera rotation is now nicer if yes

This commit is contained in:
Zeno Rogue 2020-04-19 21:56:26 +02:00
parent 5d89f8ee4b
commit fc7563e388
2 changed files with 45 additions and 25 deletions

View File

@ -318,8 +318,23 @@ EX void full_rotate_camera(int dir, ld val) {
else if(rug::rug_control() && rug::in_crystal())
crystal::apply_rotation(cspin(dir, 2, val));
#endif
else if(GDIM == 3)
rotate_view(cspin(dir, 2, val)), didsomething = true;
else if(GDIM == 3) {
if(keep_vertical()) {
hyperpoint vv = vertical_vector();
ld alpha = -atan2(vv[2], vv[1]);
rotate_view(cspin(2, 1, alpha));
ld max_angle = quarter_circle - 1e-4;
if(dir == 1 && alpha + val > max_angle)
val = max_angle - alpha;
if(dir == 1 && alpha + val < -max_angle)
val = -max_angle - alpha;
rotate_view(cspin(dir, 2, val));
rotate_view(cspin(1, 2, alpha));
}
else
rotate_view(cspin(dir, 2, val));
if(!rug::rug_control()) didsomething = true;
}
else
View = cpush(dir, val) * View, playermoved = false, didsomething = true;
};

View File

@ -1252,6 +1252,24 @@ void hrmap_standard::draw() {
}
}
EX bool keep_vertical() {
if(CAP_ORIENTATION) return false;
if((WDIM == 2 || prod) && GDIM == 3 && vid.fixed_yz) return true;
if(downseek.qty) return true;
return false;
}
EX hyperpoint vertical_vector() {
auto& ds = downseek;
if((WDIM == 2 || prod) && GDIM == 3 && vid.fixed_yz)
return get_view_orientation() * ztangent(1);
else if(ds.qty && prod)
return get_view_orientation() * product::inverse_exp(ds.point);
else if(ds.qty)
return ds.point;
return C0;
}
EX void spinEdge(ld aspd) {
ld downspin = 0;
auto& ds = downseek;
@ -1272,33 +1290,20 @@ EX void spinEdge(ld aspd) {
downspin = atan2(H[1], H[0]);
downspin += vid.fixed_facing_dir * degree;
if(flipplayer) downspin += M_PI;
while(downspin < -M_PI) downspin += 2*M_PI;
while(downspin > +M_PI) downspin -= 2*M_PI;
cyclefix(downspin, 0);
aspd = (1 + 2 * abs(downspin)) * aspd;
}
else if((WDIM == 2 || prod) && GDIM == 3 && vid.fixed_yz && !CAP_ORIENTATION) {
aspd = 999999;
auto& vo = get_view_orientation();
// does not work well (also need change auto& to auto)
// if(hybri && !prod) vo = vo * inverse(nisot::translate(tC0(vo)));
if(ds.qty) {
auto sdp = ds.point;
if(prod) sdp = vo * product::inverse_exp(sdp);
if(sdp[0])
downspin = models::rotation * degree - atan2(sdp[0], sdp[1]);
else if(keep_vertical()) {
hyperpoint h = vertical_vector();
downspin = -atan2(h[0], h[1]);
if(ds.qty && GDIM == 2) {
downspin += models::rotation * degree;
}
else {
if(vo[0][2])
downspin = -atan2(vo[0][2], vo[1][2]);
if(GDIM == 2) {
cyclefix(downspin, 0);
downspin = downspin * min(ds.speed, (double)1);
}
}
else if(ds.qty) {
downspin = atan2(ds.point[1], ds.point[0]);
downspin -= M_PI/2;
downspin += models::rotation * degree;
while(downspin < -M_PI) downspin += 2*M_PI;
while(downspin > +M_PI) downspin -= 2*M_PI;
downspin = downspin * min(ds.speed, (double)1);
else aspd = 999999;
}
if(downspin > aspd) downspin = aspd;
if(downspin < -aspd) downspin = -aspd;