Skip to content

Commit

Permalink
Removed in/out parameters from math (#1029)
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy committed Aug 20, 2020
1 parent 862708d commit f5cb7f3
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 49 deletions.
7 changes: 4 additions & 3 deletions apps/yimageview/yimageview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void draw_widgets(gui_window* win, app_states* apps, const gui_input& input) {
std::to_string(app->source.height()));
draw_slider(win, "zoom", app->glparams.scale, 0.1, 10);
draw_checkbox(win, "fit", app->glparams.fit);
auto ij = get_image_coords(input.mouse_pos, app->glparams.center,
auto ij = image_coords(input.mouse_pos, app->glparams.center,
app->glparams.scale, app->source.imsize());
draw_dragger(win, "mouse", ij);
auto img_pixel = zero4f, display_pixel = zero4f;
Expand Down Expand Up @@ -267,8 +267,9 @@ void draw(gui_window* win, app_states* apps, const gui_input& input) {
set_image(app->glimage, app->display, false, false);
app->glupdated = false;
}
update_imview(app->glparams.center, app->glparams.scale,
app->display.imsize(), app->glparams.window, app->glparams.fit);
std::tie(app->glparams.center, app->glparams.scale) = camera_imview(
app->glparams.center, app->glparams.scale, app->display.imsize(),
app->glparams.window, app->glparams.fit);
draw_image(app->glimage, app->glparams);
}

Expand Down
7 changes: 4 additions & 3 deletions apps/yimageviews/yimageviews.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ int main(int argc, const char* argv[]) {
init_image(app->glimage);
set_image(app->glimage, app->display, false, false);
}
update_imview(app->glparams.center, app->glparams.scale,
app->display.imsize(), app->glparams.window, app->glparams.fit);
std::tie(app->glparams.center, app->glparams.scale) = camera_imview(
app->glparams.center, app->glparams.scale, app->display.imsize(),
app->glparams.window, app->glparams.fit);
draw_image(app->glimage, app->glparams);
};
callbacks.widgets_cb = [app](gui_window* win, const gui_input& input) {
Expand Down Expand Up @@ -137,7 +138,7 @@ int main(int argc, const char* argv[]) {
if (begin_header(win, "inspect")) {
draw_slider(win, "zoom", app->glparams.scale, 0.1, 10);
draw_checkbox(win, "fit", app->glparams.fit);
auto ij = get_image_coords(input.mouse_pos, app->glparams.center,
auto ij = image_coords(input.mouse_pos, app->glparams.center,
app->glparams.scale, app->source.imsize());
draw_dragger(win, "mouse", ij);
auto img_pixel = zero4f, display_pixel = zero4f;
Expand Down
11 changes: 6 additions & 5 deletions apps/ysceneitrace/ysceneitrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ void draw_widgets(gui_window* win, app_states* apps, const gui_input& input) {
if (draw_button(win, "print stats")) {
for (auto stat : scene_stats(app->ioscene)) print_info(stat);
}
auto ij = get_image_coords(input.mouse_pos, app->glparams.center,
auto ij = image_coords(input.mouse_pos, app->glparams.center,
app->glparams.scale, app->render.imsize());
draw_dragger(win, "mouse", ij);
if (ij.x >= 0 && ij.x < app->render.width() && ij.y >= 0 &&
Expand Down Expand Up @@ -692,8 +692,9 @@ void draw(gui_window* win, app_states* apps, const gui_input& input) {
app->glparams.framebuffer = input.framebuffer_viewport;
if (!is_initialized(app->glimage)) init_image(app->glimage);
if (!app->render_counter) set_image(app->glimage, app->display, false, false);
update_imview(app->glparams.center, app->glparams.scale,
app->display.imsize(), app->glparams.window, app->glparams.fit);
std::tie(app->glparams.center, app->glparams.scale) = camera_imview(
app->glparams.center, app->glparams.scale, app->display.imsize(),
app->glparams.window, app->glparams.fit);
draw_image(app->glimage, app->glparams);
app->render_counter++;
if (app->render_counter > 10) app->render_counter = 0;
Expand Down Expand Up @@ -792,7 +793,7 @@ int main(int argc, const char* argv[]) {
200.0f;
pan.x = -pan.x;
stop_display(app);
update_turntable(
std::tie(app->iocamera->frame, app->iocamera->focus) = camera_turntable(
app->iocamera->frame, app->iocamera->focus, rotate, dolly, pan);
set_frame(app->camera, app->iocamera->frame);
set_lens(app->camera, app->iocamera->lens, app->iocamera->aspect,
Expand All @@ -804,7 +805,7 @@ int main(int argc, const char* argv[]) {
// selection
if ((input.mouse_left || input.mouse_right) && input.modifier_alt &&
!input.widgets_active) {
auto ij = get_image_coords(input.mouse_pos, app->glparams.center,
auto ij = image_coords(input.mouse_pos, app->glparams.center,
app->glparams.scale, app->render.imsize());
if (ij.x >= 0 && ij.x < app->render.width() && ij.y >= 0 &&
ij.y < app->render.height()) {
Expand Down
9 changes: 5 additions & 4 deletions apps/ysceneitraces/ysceneitraces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,9 @@ int main(int argc, const char* argv[]) {
set_image(app->glimage, app->display, false, false);
app->glparams.window = input.window_size;
app->glparams.framebuffer = input.framebuffer_viewport;
update_imview(app->glparams.center, app->glparams.scale,
app->display.imsize(), app->glparams.window, app->glparams.fit);
std::tie(app->glparams.center, app->glparams.scale) = camera_imview(
app->glparams.center, app->glparams.scale, app->display.imsize(),
app->glparams.window, app->glparams.fit);
draw_image(app->glimage, app->glparams);
app->render_counter++;
if (app->render_counter > 10) app->render_counter = 0;
Expand Down Expand Up @@ -371,8 +372,8 @@ int main(int argc, const char* argv[]) {
if (input.mouse_left && input.modifier_shift)
pan = (input.mouse_pos - input.mouse_last) * app->camera->focus /
200.0f;
pan.x = -pan.x;
update_turntable(
pan.x = -pan.x;
std::tie(app->camera->frame, app->camera->focus) = camera_turntable(
app->camera->frame, app->camera->focus, rotate, dolly, pan);
reset_display(app);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/ysceneview/ysceneview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ int main(int argc, const char* argv[]) {
dolly = (input.mouse_pos.x - input.mouse_last.x) / 100.0f;
if (input.mouse_left && input.modifier_shift)
pan = (input.mouse_pos - input.mouse_last) / 100.0f;
update_turntable(
std::tie(app->iocamera->frame, app->iocamera->focus) = camera_turntable(
app->iocamera->frame, app->iocamera->focus, rotate, dolly, pan);
set_frame(app->glcamera, app->iocamera->frame);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/ysceneviews/ysceneviews.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ int main(int argc, const char* argv[]) {
dolly = (input.mouse_pos.x - input.mouse_last.x) / 100.0f;
if (input.mouse_left && input.modifier_shift)
pan = (input.mouse_pos - input.mouse_last) / 100.0f;
update_turntable(
std::tie(app->iocamera->frame, app->iocamera->focus) = camera_turntable(
app->iocamera->frame, app->iocamera->focus, rotate, dolly, pan);
set_frame(app->glcamera, app->iocamera->frame);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/yshapeview/yshapeview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ int main(int argc, const char* argv[]) {
dolly = (input.mouse_pos.x - input.mouse_last.x) / 100.0f;
if (input.mouse_left && input.modifier_shift)
pan = (input.mouse_pos - input.mouse_last) / 100.0f;
update_turntable(
std::tie(app->glcamera->frame, app->glcamera->focus) = camera_turntable(
app->glcamera->frame, app->glcamera->focus, rotate, dolly, pan);
}
};
Expand Down
197 changes: 166 additions & 31 deletions libs/yocto/yocto_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -1062,24 +1062,24 @@ namespace yocto {

// Computes the image uv coordinates corresponding to the view parameters.
// Returns negative coordinates if out of the image.
inline vec2i get_image_coords(const vec2f& mouse_pos, const vec2f& center,
inline vec2i image_coords(const vec2f& mouse_pos, const vec2f& center,
float scale, const vec2i& txt_size);

// Center image and autofit.
inline void update_imview(vec2f& center, float& scale, const vec2i& imsize,
const vec2i& winsize, bool zoom_to_fit);
// Center image and autofit. Returns center and scale.
inline pair<vec2f, float> camera_imview(const vec2f& center, float scale,
const vec2i& imsize, const vec2i& winsize, bool zoom_to_fit);

// Turntable for UI navigation.
inline void update_turntable(vec3f& from, vec3f& to, vec3f& up,
// Turntable for UI navigation. Returns from and to.
inline pair<vec3f, vec3f> camera_turntable(const vec3f& from, const vec3f& to,
const vec3f& up, const vec2f& rotate, float dolly, const vec2f& pan);

// Turntable for UI navigation. Returns frame and focus.
inline pair<frame3f, float> camera_turntable(const frame3f& frame, float focus,
const vec2f& rotate, float dolly, const vec2f& pan);

// Turntable for UI navigation.
inline void update_turntable(frame3f& frame, float& focus, const vec2f& rotate,
float dolly, const vec2f& pan);

// FPS camera for UI navigation for a frame parametrization.
inline void update_fpscam(
frame3f& frame, const vec3f& transl, const vec2f& rotate);
// FPS camera for UI navigation for a frame parametrization. Returns frame.
inline frame3f camera_fpscam(
const frame3f& frame, const vec3f& transl, const vec2f& rotate);

// Generate a ray from a camera
inline ray3f camera_ray(
Expand All @@ -1089,6 +1089,27 @@ inline ray3f camera_ray(
inline ray3f camera_ray(const frame3f& frame, float lens, float aspect,
float film, const vec2f& image_uv);

// Computes the image uv coordinates corresponding to the view parameters.
// Returns negative coordinates if out of the image.
[[deprecated]] inline vec2i get_image_coords(const vec2f& mouse_pos,
const vec2f& center, float scale, const vec2i& txt_size);

// Center image and autofit.
[[deprecated]] inline void update_imview(vec2f& center, float& scale,
const vec2i& imsize, const vec2i& winsize, bool zoom_to_fit);

// Turntable for UI navigation.
[[deprecated]] inline void update_turntable(vec3f& from, vec3f& to,
const vec3f& up, const vec2f& rotate, float dolly, const vec2f& pan);

// Turntable for UI navigation.
[[deprecated]] inline void update_turntable(frame3f& frame, float& focus,
const vec2f& rotate, float dolly, const vec2f& pan);

// FPS camera for UI navigation for a frame parametrization.
[[deprecated]] inline void update_fpscam(
frame3f& frame, const vec3f& transl, const vec2f& rotate);

} // namespace yocto

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -2590,28 +2611,32 @@ namespace yocto {

// Computes the image uv coordinates corresponding to the view parameters.
// Returns negative coordinates if out of the image.
inline vec2i get_image_coords(const vec2f& mouse_pos, const vec2f& center,
inline vec2i image_coords(const vec2f& mouse_pos, const vec2f& center,
float scale, const vec2i& txt_size) {
auto xyf = (mouse_pos - center) / scale;
return vec2i{(int)round(xyf.x + txt_size.x / 2.0f),
(int)round(xyf.y + txt_size.y / 2.0f)};
}

// Center image and autofit.
inline void update_imview(vec2f& center, float& scale, const vec2i& imsize,
const vec2i& winsize, bool zoom_to_fit) {
// Center image and autofit. Returns center and scale.
inline pair<vec2f, float> camera_imview(const vec2f& center, float scale,
const vec2i& imsize, const vec2i& winsize, bool zoom_to_fit) {
if (zoom_to_fit) {
scale = min(winsize.x / (float)imsize.x, winsize.y / (float)imsize.y);
center = {(float)winsize.x / 2, (float)winsize.y / 2};
return {{(float)winsize.x / 2, (float)winsize.y / 2},
min(winsize.x / (float)imsize.x, winsize.y / (float)imsize.y)};
} else {
if (winsize.x >= imsize.x * scale) center.x = winsize.x / 2;
if (winsize.y >= imsize.y * scale) center.y = winsize.y / 2;
return {{(winsize.x >= imsize.x * scale) ? winsize.x / 2 : center.x,
(winsize.y >= imsize.y * scale) ? winsize.y / 2 : center.y},
scale};
}
}

// Turntable for UI navigation.
inline void update_turntable(vec3f& from, vec3f& to, vec3f& up,
const vec2f& rotate, float dolly, const vec2f& pan) {
// Turntable for UI navigation. Returns from and to.
inline pair<vec3f, vec3f> camera_turntable(const vec3f& from_, const vec3f& to_,
const vec3f& up, const vec2f& rotate, float dolly, const vec2f& pan) {
// copy values
auto from = from_, to = to_;

// rotate if necessary
if (rotate != zero2f) {
auto z = normalize(to - from);
Expand Down Expand Up @@ -2642,11 +2667,17 @@ inline void update_turntable(vec3f& from, vec3f& to, vec3f& up,
from += t;
to += t;
}

// done
return {from, to};
}

// Turntable for UI navigation.
inline void update_turntable(frame3f& frame, float& focus, const vec2f& rotate,
float dolly, const vec2f& pan) {
// Turntable for UI navigation. Returns frame and focus.
inline pair<frame3f, float> camera_turntable(const frame3f& frame_, float focus,
const vec2f& rotate, float dolly, const vec2f& pan) {
// copy values
auto frame = frame_;

// rotate if necessary
if (rotate != zero2f) {
auto phi = atan2(frame.z.z, frame.z.x) + rotate.x;
Expand All @@ -2671,11 +2702,14 @@ inline void update_turntable(frame3f& frame, float& focus, const vec2f& rotate,
if (pan != zero2f) {
frame.o += frame.x * pan.x + frame.y * pan.y;
}

// done
return {frame, focus};
}

// FPS camera for UI navigation for a frame parametrization.
inline void update_fpscam(
frame3f& frame, const vec3f& transl, const vec2f& rotate) {
// FPS camera for UI navigation for a frame parametrization. Returns frame.
inline frame3f camera_fpscam(
const frame3f& frame, const vec3f& transl, const vec2f& rotate) {
// https://gamedev.stackexchange.com/questions/30644/how-to-keep-my-quaternion-using-fps-camera-from-tilting-and-messing-up
auto y = vec3f{0, 1, 0};
auto z = orthonormalize(frame.z, y);
Expand All @@ -2686,7 +2720,7 @@ inline void update_fpscam(
rotation_frame(vec3f{0, 1, 0}, rotate.x);
auto pos = frame.o + transl.x * x + transl.y * y + transl.z * z;

frame = {rot.x, rot.y, rot.z, pos};
return {rot.x, rot.y, rot.z, pos};
}

// Generate a ray from a camera
Expand Down Expand Up @@ -2715,6 +2749,107 @@ inline ray3f camera_ray(const frame3f& frame, float lens, float aspect,
return ray;
}

// Computes the image uv coordinates corresponding to the view parameters.
// Returns negative coordinates if out of the image.
inline vec2i get_image_coords(const vec2f& mouse_pos, const vec2f& center,
float scale, const vec2i& txt_size) {
auto xyf = (mouse_pos - center) / scale;
return vec2i{(int)round(xyf.x + txt_size.x / 2.0f),
(int)round(xyf.y + txt_size.y / 2.0f)};
}

// Center image and autofit.
inline void update_imview(vec2f& center, float& scale, const vec2i& imsize,
const vec2i& winsize, bool zoom_to_fit) {
if (zoom_to_fit) {
scale = min(winsize.x / (float)imsize.x, winsize.y / (float)imsize.y);
center = {(float)winsize.x / 2, (float)winsize.y / 2};
} else {
if (winsize.x >= imsize.x * scale) center.x = winsize.x / 2;
if (winsize.y >= imsize.y * scale) center.y = winsize.y / 2;
}
}

// Turntable for UI navigation.
inline void update_turntable(vec3f& from, vec3f& to, vec3f& up,
const vec2f& rotate, float dolly, const vec2f& pan) {
// rotate if necessary
if (rotate != zero2f) {
auto z = normalize(to - from);
auto lz = length(to - from);
auto phi = atan2(z.z, z.x) + rotate.x;
auto theta = acos(z.y) + rotate.y;
theta = clamp(theta, 0.001f, pif - 0.001f);
auto nz = vec3f{sin(theta) * cos(phi) * lz, cos(theta) * lz,
sin(theta) * sin(phi) * lz};
from = to - nz;
}

// dolly if necessary
if (dolly != 0) {
auto z = normalize(to - from);
auto lz = max(0.001f, length(to - from) * (1 + dolly));
z *= lz;
from = to - z;
}

// pan if necessary
if (pan != zero2f) {
auto z = normalize(to - from);
auto x = normalize(cross(up, z));
auto y = normalize(cross(z, x));
auto t = vec3f{pan.x * x.x + pan.y * y.x, pan.x * x.y + pan.y * y.y,
pan.x * x.z + pan.y * y.z};
from += t;
to += t;
}
}

// Turntable for UI navigation.
inline void update_turntable(frame3f& frame, float& focus, const vec2f& rotate,
float dolly, const vec2f& pan) {
// rotate if necessary
if (rotate != zero2f) {
auto phi = atan2(frame.z.z, frame.z.x) + rotate.x;
auto theta = acos(frame.z.y) + rotate.y;
theta = clamp(theta, 0.001f, pif - 0.001f);
auto new_z = vec3f{
sin(theta) * cos(phi), cos(theta), sin(theta) * sin(phi)};
auto new_center = frame.o - frame.z * focus;
auto new_o = new_center + new_z * focus;
frame = lookat_frame(new_o, new_center, {0, 1, 0});
focus = length(new_o - new_center);
}

// pan if necessary
if (dolly != 0) {
auto c = frame.o - frame.z * focus;
focus = max(focus * (1 + dolly), 0.001f);
frame.o = c + frame.z * focus;
}

// pan if necessary
if (pan != zero2f) {
frame.o += frame.x * pan.x + frame.y * pan.y;
}
}

// FPS camera for UI navigation for a frame parametrization.
inline void update_fpscam(
frame3f& frame, const vec3f& transl, const vec2f& rotate) {
// https://gamedev.stackexchange.com/questions/30644/how-to-keep-my-quaternion-using-fps-camera-from-tilting-and-messing-up
auto y = vec3f{0, 1, 0};
auto z = orthonormalize(frame.z, y);
auto x = cross(y, z);

auto rot = rotation_frame(vec3f{1, 0, 0}, rotate.y) *
frame3f{frame.x, frame.y, frame.z, vec3f{0, 0, 0}} *
rotation_frame(vec3f{0, 1, 0}, rotate.x);
auto pos = frame.o + transl.x * x + transl.y * y + transl.z * z;

frame = {rot.x, rot.y, rot.z, pos};
}

} // namespace yocto

#endif

0 comments on commit f5cb7f3

Please sign in to comment.