OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ViewerEye.cpp
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 // Internal Includes
26 #include <osvr/Client/ViewerEye.h>
29 #include <osvr/Util/EigenInterop.h>
32 
33 // Library/third-party includes
34 // - none
35 
36 // Standard includes
37 // - none
38 
39 namespace osvr {
40 namespace client {
41  Eigen::Isometry3d ViewerEye::getPoseIsometry() const {
42  OSVR_TimeValue timestamp;
43  OSVR_Pose3 pose;
44  bool hasState = m_pose->getState<OSVR_PoseReport>(timestamp, pose);
45  if (!hasState) {
46  throw NoPoseYet();
47  }
48  Eigen::Isometry3d transformedPose =
49  util::fromPose(pose) * Eigen::Translation3d(m_offset) *
50  Eigen::AngleAxisd(util::getRadians(m_opticalAxisOffsetY),
51  Eigen::Vector3d::UnitY());
52  return transformedPose;
53  }
54  OSVR_Pose3 ViewerEye::getPose() const {
55  Eigen::Isometry3d transformedPose = getPoseIsometry();
56  OSVR_Pose3 pose;
57  util::toPose(transformedPose, pose);
58  return pose;
59  }
60 
61  bool ViewerEye::hasPose() const {
62  return m_pose->hasStateForReportType<OSVR_PoseReport>();
63  }
64 
65  Eigen::Matrix4d ViewerEye::getView() const {
66  Eigen::Isometry3d transformedPose = getPoseIsometry();
67  return transformedPose.inverse().matrix();
68  }
69 
70  util::Rectd ViewerEye::m_getRect(double near, double /*far*/ = 100) const {
71  util::Rectd rect(m_unitBounds);
72  // Scale the in-plane positions based on the near plane to put
73  // the virtual viewing window on the near plane with the eye at the
74  // origin.
75  rect *= near;
76 
78  // (such as the Oculus DK2) by shifting the boundaries.
79 
80  // Incorporate pitch_tilt (degrees, positive is downwards)
81  // We assume that this results in a shearing of the image that leaves
82  // the plane of the screen the same.
83  if (m_pitchTilt != 0) {
85  }
86 
88  // we will have something to put into every pixel once the
89  // predistortion has been applied around the center of projection).
90 
93 
94  // See if we need to rotate 180 degrees about Z.
95  //
96  // If so, do so by swapping each pair of edges, producing an upside-down
97  // projection. We do this after all of the above shifts, producing an
98  // image that matches but which is upside down.
99  //
100  // NOTE: This would adjust the distortion center of projection, but it
101  // is assumed that we're doing this to make scan-out circuitry behave
102  // rather than to change where the actual pixel location of the center
103  // of projection is.
104  if (m_rot180) {
105  std::swap(rect[util::Rectd::LEFT], rect[util::Rectd::RIGHT]);
106  std::swap(rect[util::Rectd::TOP], rect[util::Rectd::BOTTOM]);
107  }
108 
109 #if 0
110  // Make sure that things won't blow up in the math below.
111  if ((nearClip <= 0) || (farClip <= 0) || (nearClip == farClip) ||
112  (left == right) || (top == bottom)) {
113  return false;
114  }
115 #endif
116 
120 
121  return rect;
122  }
123 
124  Eigen::Matrix4d ViewerEye::getProjection(double near, double far) const {
125 
126  return util::createProjectionMatrix(m_getRect(near, far), near, far);
127  }
128 
129  Eigen::Matrix4d
130  ViewerEye::getProjection(double near, double far,
131  OSVR_MatrixConventions flags) const {
133  using F = osvr::util::detail::CompactMatrixFlags;
135 
136  auto rect = m_getRect(near, far);
137 
138  C compactFlags(flags);
139  Eigen::Matrix4d ret;
140  switch (compactFlags.getValue()) {
141  case C::ComputeBits<>::value:
142  ret = util::parameterizedCreateProjectionMatrix<>(rect, near, far);
143  break;
144  case C::ComputeBits<F::NeedsTranspose>::value:
145  ret = util::parameterizedCreateProjectionMatrix<>(rect, near, far)
146  .transpose();
147  break;
148 
149  case C::ComputeBits<F::LeftHandInput>::value:
151  opts::LeftHandedInput>(rect, near, far);
152  break;
153  case C::ComputeBits<F::LeftHandInput, F::NeedsTranspose>::value:
155  opts::LeftHandedInput>(rect, near, far)
156  .transpose();
157  break;
158 
159  case C::ComputeBits<F::UnsignedZ>::value:
161  opts::ZOutputUnsigned>(rect, near, far);
162  break;
163  case C::ComputeBits<F::UnsignedZ, F::NeedsTranspose>::value:
165  opts::ZOutputUnsigned>(rect, near, far)
166  .transpose();
167  break;
168 
169  case C::ComputeBits<F::LeftHandInput, F::UnsignedZ>::value:
171  opts::LeftHandedInput | opts::ZOutputUnsigned>(rect, near, far);
172  break;
173  case C::ComputeBits<F::LeftHandInput, F::UnsignedZ,
174  F::NeedsTranspose>::value:
176  opts::LeftHandedInput | opts::ZOutputUnsigned>(rect, near,
177  far)
178  .transpose();
179  break;
180  }
181 
182  return ret;
183  }
184 
185  util::Rectd ViewerEye::getRect() const { return m_getRect(1.0); }
186 
187  ViewerEye::ViewerEye(
188  OSVR_ClientContext ctx, Eigen::Vector3d const &offset,
189  const char path[], Viewport &&viewport, util::Rectd &&unitBounds,
190  bool rot180, double pitchTilt,
191  boost::optional<OSVR_RadialDistortionParameters> radDistortParams,
192  OSVR_DisplayInputCount displayInputIdx, util::Angle opticalAxisOffsetY)
193  : m_pose(ctx, path), m_offset(offset), m_viewport(viewport),
194  m_unitBounds(unitBounds), m_rot180(rot180), m_pitchTilt(pitchTilt),
195  m_radDistortParams(radDistortParams),
196  m_displayInputIdx(displayInputIdx),
197  m_opticalAxisOffsetY(opticalAxisOffsetY) {}
198 
199 } // namespace client
200 } // namespace osvr
AngleRadiansd Angle
Default angle type.
Definition: Angles.h:63
Header.
void toPose(Eigen::Isometry3d const &xform, OSVR_Pose3 &pose)
Turn an Eigen::Isometry3d (transform) into an OSVR_Pose3.
Definition: EigenInterop.h:93
Eigen::Matrix4d parameterizedCreateProjectionMatrix(Rectd const &bounds, double near, double far)
Takes in points at the near clipping plane, as well as the near and far clipping planes. Result matrix maps [l, r] and [b, t] to [-1, 1], and [n, f] to [-1, 1] or [0, 1] depending on presence/absence of ZOutputUnsigned flag bit, taking in right- or left-handed input also as configured.
Eigen::Isometry3d fromPose(OSVR_Pose3 const &pose)
Turn an OSVR_Pose3 into an Eigen::Transform.
Definition: EigenInterop.h:81
util::Rectd getRect() const
Gets clipping planes for a given surface.
Definition: ViewerEye.cpp:185
uint16_t OSVR_MatrixConventions
Type for passing matrix convention flags.
Header containing a typelist of all special report types.
Eigen::Matrix4d createProjectionMatrix(Rectd const &bounds, double near, double far)
Takes in points at the near clipping plane, as well as the near and far clipping planes. Result matrix maps [l, r] and [b, t] to [-1, 1], and [n, f] to [-1, 1] (should be configurable)
Eigen::Matrix4d getProjection(double near, double far) const
Gets a matrix that takes in row vectors in a right-handed system and outputs signed Z...
Definition: ViewerEye.cpp:124
uint8_t OSVR_DisplayInputCount
A count or index for a display input in a display config.
A structure defining a 3D (6DOF) rigid body pose: translation and rotation.
Definition: Pose3C.h:54
Header for interoperation between the Eigen math library, the internal mini math library, and VRPN's quatlib.
Y getRadians(AngleGeneric< System, Y > const angle)
Get the raw scalar value of your angle in radians.
Definition: Angles.h:67
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
Report type for a pose (position and orientation) callback on a tracker interface.