Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2017-04-12 20:55:42 +0300
committerJulian Eisel <eiseljulian@gmail.com>2017-04-12 20:55:42 +0300
commita993466b22434138b88aa46f1ab3392c2b1e1b9f (patch)
treed14837cb9d730f21383947fdda72c877d46d7e0d
parenta21130f737b65a7f96cd4b501349149bbf76e3fa (diff)
Fix projection matrices not taking focal length of HMD into account
-rw-r--r--intern/ghost/GHOST_C-api.h2
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp22
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c36
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h4
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c21
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_device.c13
7 files changed, 87 insertions, 12 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 1eeb0fda3e8..6c705253732 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -949,6 +949,8 @@ extern float GHOST_HMDgetLensHorizontalSeparation(void);
extern float GHOST_HMDgetProjectionZNear(void);
extern float GHOST_HMDgetProjectionZFar(void);
extern float GHOST_HMDgetScreenHorizontalSize(void);
+extern float GHOST_HMDgetLeftEyeFOV(void);
+extern float GHOST_HMDgetRightEyeFOV(void);
extern void GHOST_HMDgetLeftModelviewMatrix(float r_mat[4][4]);
extern void GHOST_HMDgetRightModelviewMatrix(float r_mat[4][4]);
extern void* GHOST_HMDgetDistortionParameters(void);
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 28b1bbcd50d..5f5bfc17f09 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -1074,6 +1074,28 @@ float GHOST_HMDgetScreenHorizontalSize()
#endif
}
+float GHOST_HMDgetLeftEyeFOV()
+{
+#ifdef WITH_OPENHMD
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ GHOST_OpenHMDManager *ohmd = system->getOpenHMDManager();
+ return ohmd->getLeftEyeFOV();
+#else
+ return -1.0f;
+#endif
+}
+
+float GHOST_HMDgetRightEyeFOV()
+{
+#ifdef WITH_OPENHMD
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ GHOST_OpenHMDManager *ohmd = system->getOpenHMDManager();
+ return ohmd->getRightEyeFOV();
+#else
+ return -1.0f;
+#endif
+}
+
#ifndef WITH_OPENHMD
static void ghost_UnitMat(float r_mat[4][4])
{
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 9eacbebc047..38e9248704c 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -3766,7 +3766,7 @@ bool view3d_is_hmd_view_mirror(const wmWindowManager *wm, const View3D *v3d, con
}
static void view3d_hmd_calc_projection_matrix_from_device(
- ARegion *region, View3D *v3d,
+ ARegion *region, View3D *v3d, const RegionView3D *rv3d,
const rcti *viewplane_rect, enum HMDViewMatrixType mat_type,
float r_projectionmat[4][4])
{
@@ -3775,16 +3775,39 @@ static void view3d_hmd_calc_projection_matrix_from_device(
* * For selecting, viewplane_rect has to be used for view-plane clipping.
* * OpenHMD doesn't allow us to set custom screen dimensions, it always uses device ones. */
+ rctf viewplane;
+ CameraParams params;
+
+ const bool is_left = mat_type == HMD_MATRIX_LEFT_EYE;
const float v3d_znear = v3d->near;
const float v3d_zfar = v3d->far;
+ const float v3d_lens = v3d->lens;
const float hmd_znear = WM_device_HMD_projection_z_near_get();
const float hmd_zfar = WM_device_HMD_projection_z_far_get();
+ const float hmd_fov = WM_device_HMD_FOV_get(is_left);
+ const int winx = region->winx;
+ const int winy = region->winy;
+
v3d->near = hmd_znear;
v3d->far = hmd_zfar;
+ v3d->lens = fov_to_focallength(hmd_fov, DEFAULT_SENSOR_WIDTH);
+
+ /* from ED_view3d_viewplane_get, but we override zoom */
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_view3d(&params, v3d, rv3d);
+ params.zoom = 1.0f;
+ BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
+ viewplane = params.viewplane;
+
+ if (viewplane_rect) {
+ /* picking/selecting */
+ view3d_winmatrix_viewplane_adjust_for_rect(&viewplane, viewplane_rect, winx, winy, &viewplane);
+ }
- view3d_winmatrix_set(region, v3d, viewplane_rect);
- glGetFloatv(GL_PROJECTION_MATRIX, (float *)r_projectionmat);
+ BLI_assert(params.clipsta == hmd_znear && params.clipend == hmd_zfar);
+ perspective_m4(r_projectionmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax,
+ params.clipsta, params.clipend);
if (mat_type != HMD_MATRIX_CENTER) {
/* calculate lens offset in [-1, 1] range to apply onto projection matrix.
@@ -3795,11 +3818,12 @@ static void view3d_hmd_calc_projection_matrix_from_device(
/* apply lens separation (IPD is applied onto modelview matrix) */
BLI_assert(IN_RANGE_INCL(proj_offset, -1.0f, 1.0f));
- translate_m4(r_projectionmat, (mat_type == HMD_MATRIX_LEFT_EYE) ? proj_offset : -proj_offset, 0, 0);
+ translate_m4(r_projectionmat, is_left ? proj_offset : -proj_offset, 0, 0);
}
v3d->near = v3d_znear;
v3d->far = v3d_zfar;
+ v3d->lens = v3d_lens;
}
static void view3d_hmd_calc_modelview_matrix_from_device(
@@ -3854,10 +3878,10 @@ static void view3d_hmd_get_matrices(
}
else if (use_device_rot) {
view3d_hmd_calc_modelview_matrix_from_device(v3d, rv3d, mat_type, r_modelviewmat);
- view3d_hmd_calc_projection_matrix_from_device(region, v3d, viewplane_rect, mat_type, r_projectionmat);
+ view3d_hmd_calc_projection_matrix_from_device(region, v3d, rv3d, viewplane_rect, mat_type, r_projectionmat);
}
else {
- view3d_hmd_calc_projection_matrix_from_device(region, v3d, viewplane_rect, mat_type, r_projectionmat);
+ view3d_hmd_calc_projection_matrix_from_device(region, v3d, rv3d, viewplane_rect, mat_type, r_projectionmat);
copy_m4_m4(r_modelviewmat, rv3d->viewmat);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 62f5d7bcbbe..d7a17a92f0a 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -261,6 +261,10 @@ void ED_view3d_smooth_view_force_finish(
void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect);
void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d);
+void view3d_winmatrix_viewplane_adjust_for_rect(
+ const rctf *viewplane, const rcti *rect,
+ float winx, float winy,
+ rctf *r_viewplane);
void fly_modal_keymap(struct wmKeyConfig *keyconf);
void walk_modal_keymap(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 7ed6a6f3be1..8108e9c402d 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -928,12 +928,7 @@ void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect)
#endif
if (rect) { /* picking */
- rctf r;
- r.xmin = viewplane.xmin + (BLI_rctf_size_x(&viewplane) * (rect->xmin / (float)ar->winx));
- r.ymin = viewplane.ymin + (BLI_rctf_size_y(&viewplane) * (rect->ymin / (float)ar->winy));
- r.xmax = viewplane.xmin + (BLI_rctf_size_x(&viewplane) * (rect->xmax / (float)ar->winx));
- r.ymax = viewplane.ymin + (BLI_rctf_size_y(&viewplane) * (rect->ymax / (float)ar->winy));
- viewplane = r;
+ view3d_winmatrix_viewplane_adjust_for_rect(&viewplane, rect, ar->winx, ar->winy, &viewplane);
}
if (is_ortho) {
@@ -947,6 +942,20 @@ void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect)
glGetFloatv(GL_PROJECTION_MATRIX, (float *)rv3d->winmat);
}
+void view3d_winmatrix_viewplane_adjust_for_rect(
+ const rctf *viewplane, const rcti *rect,
+ float winx, float winy,
+ rctf *r_viewplane)
+{
+ /* allow passing same pointer for viewplane and r_viewplane */
+ rctf viewplane_local = *viewplane;
+
+ r_viewplane->xmin = viewplane_local.xmin + (BLI_rctf_size_x(&viewplane_local) * (rect->xmin / winx));
+ r_viewplane->ymin = viewplane_local.ymin + (BLI_rctf_size_y(&viewplane_local) * (rect->ymin / winy));
+ r_viewplane->xmax = viewplane_local.xmin + (BLI_rctf_size_x(&viewplane_local) * (rect->xmax / winx));
+ r_viewplane->ymax = viewplane_local.ymin + (BLI_rctf_size_y(&viewplane_local) * (rect->ymax / winy));
+}
+
static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
{
float bmat[4][4];
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 88a76b6736d..fb564f3c223 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -544,6 +544,7 @@ float WM_device_HMD_screen_horizontal_size_get(void);
/* Utils */
void WM_device_HMD_state_set(const int device, const bool enable);
void WM_device_HMD_modelview_matrix_get(const bool is_left, float r_modelviewmat[4][4]) ATTR_NONNULL();
+float WM_device_HMD_FOV_get(const bool is_left);
void *WM_device_HMD_distortion_parameters_get(void);
#endif /* WITH_INPUT_HMD */
diff --git a/source/blender/windowmanager/intern/wm_device.c b/source/blender/windowmanager/intern/wm_device.c
index 98d6ab25210..73f866bc7c1 100644
--- a/source/blender/windowmanager/intern/wm_device.c
+++ b/source/blender/windowmanager/intern/wm_device.c
@@ -143,6 +143,19 @@ void WM_device_HMD_modelview_matrix_get(const bool is_left, float r_modelviewmat
}
}
+float WM_device_HMD_FOV_get(const bool is_left)
+{
+ if (U.hmd_settings.device == -1) {
+ return -1.0f;
+ }
+ else if (is_left) {
+ return GHOST_HMDgetLeftEyeFOV();
+ }
+ else {
+ return GHOST_HMDgetRightEyeFOV();
+ }
+}
+
void* WM_device_HMD_distortion_parameters_get(void)
{
return GHOST_HMDgetDistortionParameters();