mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-28 11:00:34 +00:00
intra:: walking mode
This commit is contained in:
parent
cfaa52cf42
commit
94d660cc43
@ -2013,6 +2013,8 @@ EX void optimizeview() {
|
||||
fixmatrix(View);
|
||||
callhooks(hooks_postoptimize);
|
||||
|
||||
walking::handle();
|
||||
|
||||
if(is_boundary(centerover))
|
||||
centerover = c, View = oView;
|
||||
else
|
||||
|
199
intra.cpp
199
intra.cpp
@ -541,11 +541,9 @@ EX const connection_data* through_portal() {
|
||||
|
||||
EX void check_portal_movement() {
|
||||
auto p = through_portal();
|
||||
ld c = camera_speed;
|
||||
|
||||
if(p) {
|
||||
ld eps = 1e-5;
|
||||
c /= p->id1.scale;
|
||||
anims::cycle_length /= p->id1.scale;
|
||||
ld ss = pow(eps, -2);
|
||||
|
||||
array<hyperpoint, 4> ds; /* camera, forward, upward */
|
||||
@ -605,9 +603,16 @@ EX void check_portal_movement() {
|
||||
println(hlog, "goal: at = ", xds[0], " det = ", dsdet(xds), " bt = ", bt::minkowski_to_bt(xds[0]));
|
||||
}
|
||||
|
||||
c *= p->id2.scale;
|
||||
anims::cycle_length *= p->id2.scale;
|
||||
camera_speed = c;
|
||||
ld scale = p->id2.scale / p->id1.scale;
|
||||
|
||||
camera_speed *= scale;
|
||||
anims::cycle_length *= scale;
|
||||
#if CAP_VR
|
||||
absolute_units_in_meters *= scale;
|
||||
#endif
|
||||
if(walking::eye_level != -1) walking::eye_level *= scale;
|
||||
|
||||
walking::floor_dir = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -691,6 +696,8 @@ void show_portals() {
|
||||
}
|
||||
}
|
||||
|
||||
walking::add_options();
|
||||
|
||||
dialog::display();
|
||||
}
|
||||
|
||||
@ -790,8 +797,182 @@ auto hooks1 =
|
||||
arg::shift(); int i = arg::argi(); be_ratio_edge(i);
|
||||
})
|
||||
+ arg::add3("-debug-portal", [] { arg::shift(); debug_portal = arg::argi(); });
|
||||
|
||||
|
||||
#endif
|
||||
EX }
|
||||
}
|
||||
|
||||
EX namespace walking {
|
||||
|
||||
EX bool on;
|
||||
|
||||
EX bool auto_eyelevel;
|
||||
|
||||
EX int floor_dir = -1;
|
||||
EX cell *on_floor_of = nullptr;
|
||||
EX ld eye_level = 0.2174492;
|
||||
EX ld eye_angle = 0;
|
||||
EX ld eye_angle_scale = 1;
|
||||
|
||||
map<cell*, int> recorded_floor_dir;
|
||||
|
||||
int ticks_end, ticks_last;
|
||||
|
||||
EX set<color_t> colors_of_floors;
|
||||
|
||||
EX bool isFloor(cell *c) {
|
||||
if(!isWall(c)) return false;
|
||||
return colors_of_floors.count(c->landparam);
|
||||
}
|
||||
|
||||
EX void handle() {
|
||||
if(!on) return;
|
||||
|
||||
if(floor_dir == -1 || on_floor_of != centerover) {
|
||||
vector<int> choices;
|
||||
for(int i=0; i<centerover->type; i++)
|
||||
if(isFloor(centerover->cmove(i)))
|
||||
choices.push_back(i);
|
||||
|
||||
if(sol && isize(choices) == 2) choices.pop_back();
|
||||
|
||||
if(isize(choices) == 1) {
|
||||
on_floor_of = centerover;
|
||||
floor_dir = choices[0];
|
||||
println(hlog, "set floor_dir to ", floor_dir);
|
||||
}
|
||||
else {
|
||||
println(hlog, "there are ", isize(choices), " choices for floor_dir");
|
||||
if(!on_floor_of) return;
|
||||
}
|
||||
}
|
||||
|
||||
struct face {
|
||||
hyperpoint h0, hx, hy;
|
||||
};
|
||||
|
||||
transmatrix ToOld = currentmap->relative_matrix(on_floor_of, centerover, C0);
|
||||
auto& csh = currentmap->get_cellshape(on_floor_of);
|
||||
face f;
|
||||
f.h0 = ToOld * csh.faces_local[floor_dir][0];
|
||||
f.hx = ToOld * csh.faces_local[floor_dir][1];
|
||||
f.hy = ToOld * csh.faces_local[floor_dir][2];
|
||||
|
||||
auto find_nearest = [&] (const face& fac, hyperpoint at) {
|
||||
if(sol) { at[2] = fac.h0[2]; return at; }
|
||||
else if(sphere && false) {
|
||||
hyperpoint h =
|
||||
project_on_triangle(csh.faces_local[floor_dir][0], csh.faces_local[floor_dir][1], csh.faces_local[floor_dir][2]);
|
||||
transmatrix T = rspintox(h);
|
||||
T = T * MirrorX;
|
||||
transmatrix M = ToOld * T * xpush(-2*hdist0(h)) * spintox(h);
|
||||
return mid(at, M * at);
|
||||
}
|
||||
else if(prod && bt::in()) {
|
||||
auto dec = product_decompose(at);
|
||||
hyperpoint dep = PIU( deparabolic13(dec.second) );
|
||||
hyperpoint h = product_decompose(fac.h0).second;
|
||||
h = PIU( deparabolic13(h) );
|
||||
dep[0] = h[0];
|
||||
return zshift(PIU(parabolic13(dep)), dec.first);
|
||||
}
|
||||
else {
|
||||
transmatrix M = ray::mirrorize(currentmap->ray_iadj(on_floor_of, floor_dir));
|
||||
M = ToOld * M * inverse(ToOld);
|
||||
return mid(at, M * at);
|
||||
}
|
||||
};
|
||||
|
||||
hyperpoint at = tC0(inverse(View));
|
||||
if(invalid_point(at)) {
|
||||
println(hlog, "at is invalid!");
|
||||
on = false;
|
||||
return;
|
||||
}
|
||||
|
||||
auto wallpt = find_nearest(f, at);
|
||||
|
||||
if(on_floor_of == centerover)
|
||||
recorded_floor_dir[centerover] = floor_dir;
|
||||
|
||||
ld view_eps = 1e-5;
|
||||
|
||||
if(eye_angle) rotate_view(cspin(1, 2, -eye_angle * degree));
|
||||
hyperpoint front = inverse(get_shift_view_of(ctangent(2, -view_eps), View)) * C0;
|
||||
hyperpoint up = inverse(get_shift_view_of(ctangent(1, +view_eps), View)) * C0;
|
||||
|
||||
auto fwallpt = find_nearest(f, front);
|
||||
|
||||
transmatrix T = nonisotropic ? nisot::translate(wallpt, -1) : gpushxto0(wallpt);
|
||||
hyperpoint dx = inverse_exp(shiftless(T * at));
|
||||
|
||||
transmatrix Tf = nonisotropic ? nisot::translate(fwallpt, -1) : gpushxto0(fwallpt);
|
||||
hyperpoint dxf = inverse_exp(shiftless(Tf * front));
|
||||
|
||||
if(eye_level == -1) eye_level = hypot_d(3, dx);
|
||||
|
||||
auto smooth = [&] (hyperpoint h1, hyperpoint h2) {
|
||||
if(ticks < ticks_end) {
|
||||
ld last_t = ilerp(ticks_end-1000, ticks_end, ticks_last);
|
||||
ld curr_t = ilerp(ticks_end-1000, ticks_end, ticks);
|
||||
last_t = last_t * last_t * (3-2*last_t);
|
||||
curr_t = curr_t * curr_t * (3-2*curr_t);
|
||||
ld t = ilerp(last_t, 1, curr_t);
|
||||
return lerp(h1, h2, t);
|
||||
}
|
||||
return h2;
|
||||
};
|
||||
|
||||
auto oView = View;
|
||||
set_view(
|
||||
smooth(at, inverse(T) * direct_exp(dx / hypot_d(3, dx) * eye_level)),
|
||||
smooth(front, inverse(Tf) * direct_exp(dxf / hypot_d(3, dxf) * eye_level)),
|
||||
smooth(up, inverse(T) * direct_exp(dx / hypot_d(3, dx) * (eye_level + view_eps)))
|
||||
);
|
||||
if(eye_angle) rotate_view(cspin(1, 2, eye_angle * degree));
|
||||
playermoved = false;
|
||||
|
||||
auto nat = tC0(inverse(View));
|
||||
if(invalid_point(nat)) {
|
||||
println(hlog, "at is invalid after fixing!");
|
||||
View = oView;
|
||||
return;
|
||||
}
|
||||
|
||||
ticks_last = ticks;
|
||||
}
|
||||
|
||||
EX void add_options() {
|
||||
dialog::addBoolItem("walking mode", on, 'w');
|
||||
dialog::add_action([] {
|
||||
on = !on;
|
||||
if(on && auto_eyelevel) eye_level = -1;
|
||||
floor_dir = -1;
|
||||
on_floor_of = nullptr;
|
||||
ticks_last = ticks;
|
||||
ticks_end = ticks + 1000;
|
||||
});
|
||||
add_edit(eye_level);
|
||||
add_edit(eye_angle);
|
||||
}
|
||||
|
||||
auto a = addHook(hooks_configfile, 100, [] {
|
||||
param_b(auto_eyelevel, "auto_eyelevel")
|
||||
-> editable("keep eye level when walking enabled", 'L');
|
||||
param_f(eye_level, "eye_level")
|
||||
-> editable(0, 5, .1, "walking eye level",
|
||||
"Distance from the floor to the eye in the walking mode, in absolute units. In VR this is adjusted automatically.",
|
||||
'e')
|
||||
->set_extra([] { add_edit(auto_eyelevel); });
|
||||
param_f(eye_angle, "eye_angle")
|
||||
-> editable(-90, 90, 15, "walking eye angle",
|
||||
"0 = looking forward, 90 = looking upward. In VR this is adjusted automatically.",
|
||||
'k')
|
||||
->set_extra([] { add_edit(eye_angle_scale); });
|
||||
param_f(eye_angle_scale, "eye_angle_scale")
|
||||
-> editable(-2, 0, 2, "eye angle scale",
|
||||
"1 = the angle can be changed with keyboard or mouse movements, 0 = the angle is fixed",
|
||||
'k');
|
||||
})
|
||||
+ addHook(hooks_clearmemory, 40, [] { recorded_floor_dir.clear(); on_floor_of = nullptr; floor_dir = -1; });
|
||||
|
||||
EX }
|
||||
}
|
||||
|
@ -2066,7 +2066,7 @@ void uniform2(GLint id, array<float, 2> fl) {
|
||||
|
||||
color_t color_out_of_range = 0x0F0800FF;
|
||||
|
||||
transmatrix get_ms(cell *c, int a, bool mirror) {
|
||||
EX transmatrix get_ms(cell *c, int a, bool mirror) {
|
||||
int z = a ? 1 : -1;
|
||||
|
||||
if(c->type == 3) {
|
||||
@ -2096,7 +2096,7 @@ transmatrix get_ms(cell *c, int a, bool mirror) {
|
||||
|
||||
int nesting;
|
||||
|
||||
transmatrix mirrorize(transmatrix T) {
|
||||
EX transmatrix mirrorize(transmatrix T) {
|
||||
T = inverse(T);
|
||||
hyperpoint h = tC0(T);
|
||||
ld d = hdist0(h);
|
||||
|
Loading…
Reference in New Issue
Block a user