OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
DisplayDescriptorSchema1.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
28 #include <osvr/Util/Verbosity.h>
29 
30 // Library/third-party includes
31 #include <boost/units/io.hpp>
32 #include <boost/assert.hpp>
33 
34 // Standard includes
35 #include <sstream>
36 
37 namespace osvr {
38 namespace client {
39  namespace display_schema_1 {
41  static const double DEFAULT_IPD_METERS = 0.063; // 63mm
42 
43  DisplayDescriptor::DisplayDescriptor() {
44  // do nothing
45  }
46 
47  DisplayDescriptor::DisplayDescriptor(
48  const std::string &display_description) {
49  parse(display_description);
50  }
51 
52  void DisplayDescriptor::parse(const std::string &display_description) {
53  auto root = common::jsonParse(display_description);
54  auto const &hmd = root["hmd"];
55  {
56  auto const &fov = hmd["field_of_view"];
57  // Field of view
58  m_monocularHorizontalFOV = util::Angle(
59  fov["monocular_horizontal"].asDouble() * util::degrees);
60  m_monocularVerticalFOV = util::Angle(
61  fov["monocular_vertical"].asDouble() * util::degrees);
62  m_overlapPercent =
63  fov.get("overlap_percent", 100).asDouble() / 100.0;
64  m_pitchTilt = util::Angle(fov.get("pitch_tilt", 0).asDouble() *
65  util::degrees);
66  }
67  {
68  auto const &devprops = hmd["device"];
69  // Device properties
70  m_vendor = devprops["vendor"].asString();
71  m_model = devprops["model"].asString();
72  m_version = devprops["Version"].asString();
73  m_note = devprops["Note"].asString();
74  }
75  {
76  auto const &resolutions = hmd["resolutions"];
77  if (resolutions.isNull()) {
78  OSVR_DEV_VERBOSE(
79  "DisplayDescriptor::parse(): ERROR: Couldn't "
80  "find resolutions array!");
81  throw DisplayDescriptorParseException(
82  "Couldn't find resolutions array.");
83  }
84 
85  for (auto const &resolution : resolutions) {
86  m_processResolution(resolution);
87  }
88 
89  if (m_resolutions.empty()) {
90  // We couldn't find any appropriate resolution entries
91  OSVR_DEV_VERBOSE(
92  "DisplayDescriptor::parse(): ERROR: Couldn't "
93  "find any appropriate resolutions.");
94  return;
95  }
96  }
97 
98  {
99  auto const &rendering = hmd["rendering"];
100  m_rightRoll = rendering.get("right_roll", 0).asDouble();
101  m_leftRoll = rendering.get("left_roll", 0).asDouble();
102  }
103  {
104  auto const &distortion = hmd["distortion"];
105  m_distort.k1_red = distortion.get("k1_red", 0).asDouble();
106  m_distort.k1_green = distortion.get("k1_green", 0).asDouble();
107  m_distort.k1_blue = distortion.get("k1_blue", 0).asDouble();
108  }
109  {
110  auto const &eyes = hmd["eyes"];
111  if (eyes.isNull()) {
112  OSVR_DEV_VERBOSE("DisplayDescriptor::parse(): ERROR: "
113  "Couldn't find eyes array!");
114  throw DisplayDescriptorParseException(
115  "Couldn't find eyes array.");
116  }
117  for (auto const &eye : eyes) {
118  EyeInfo e;
119  e.m_CenterProjX = eye.get("center_proj_x", 0.5).asDouble();
120  e.m_CenterProjY = eye.get("center_proj_y", 0.5).asDouble();
121  if (eye.isMember("rotate_180")) {
122  auto const& rot = eye["rotate_180"];
123  if (rot.isBool()) {
124  e.m_rotate180 = rot.asBool();
125  } else {
126  e.m_rotate180 = (rot.asInt() != 0);
127  }
128  }
129  m_eyes.push_back(e);
130  }
131  }
132  }
133 
135  std::ostringstream os;
136  bool needSpace = false;
137  if (!m_vendor.empty()) {
138  os << m_vendor;
139  needSpace = true;
140  }
141 
142  if (!m_model.empty()) {
143  if (needSpace) {
144  os << " ";
145  }
146  os << m_model;
147  needSpace = true;
148  }
149 
150  if (!m_version.empty()) {
151  if (needSpace) {
152  os << " ";
153  }
154  os << "(Version " << m_version << ")";
155  needSpace = true;
156  }
157 
158  if (!m_note.empty()) {
159  if (needSpace) {
160  os << " ";
161  }
162  os << "[Display descriptor note: " << m_note << "]";
163  }
164  return os.str();
165  }
166 
167  void
168  DisplayDescriptor::m_processResolution(Json::Value const &resolution) {
169  // if there is more than 1 input, display descriptor right now
170  // specifies one resolution value for both inputs. that may be
171  // changed in the future
172  Resolution res;
173  res.video_inputs = resolution.get("video_inputs", 1).asInt();
174 
175  // Window bounds
176  res.width = resolution["width"].asInt();
177  res.height = resolution["height"].asInt();
178 
179  // Display mode - Default to horiz side by side unless we have
180  // multiple video inputs, then default to full screen (? seems
181  // logical but not strictly what the json schema specifies)
182  res.display_mode =
183  (res.video_inputs > 1 ? FULL_SCREEN : HORIZONTAL_SIDE_BY_SIDE);
184 
185  auto const &display_mode = resolution["display_mode"];
186  if (display_mode.isString()) {
187  const std::string display_mode_str = display_mode.asString();
188  if ("horz_side_by_side" == display_mode_str) {
189  res.display_mode = HORIZONTAL_SIDE_BY_SIDE;
190  } else if ("vert_side_by_side" == display_mode_str) {
191  res.display_mode = VERTICAL_SIDE_BY_SIDE;
192  } else if ("full_screen" == display_mode_str) {
193  res.display_mode = FULL_SCREEN;
194  } else {
195  OSVR_DEV_VERBOSE("DisplayDescriptor::parse(): WARNING: "
196  "Unknown display mode string: "
197  << display_mode_str << " (using default)");
198  }
199  }
200 
201  m_resolutions.push_back(res);
202  }
203 
204  void DisplayDescriptor::print() const {
205  std::cout << "Monocular horizontal FOV: "
206  << m_monocularHorizontalFOV << std::endl;
207  std::cout << "Monocular vertical FOV: " << m_monocularVerticalFOV
208  << std::endl;
209  std::cout << "Overlap percent: " << m_overlapPercent << "%"
210  << std::endl;
211  std::cout << "Pitch tilt: " << m_pitchTilt << std::endl;
212  std::cout << "Resolution: " << activeResolution().width << " x "
213  << activeResolution().height << std::endl;
214  std::cout << "Video inputs: " << activeResolution().video_inputs
215  << std::endl;
216  std::cout << "Display mode: " << activeResolution().display_mode
217  << std::endl;
218  std::cout << "Right roll: " << m_rightRoll << std::endl;
219  std::cout << "Left roll: " << m_leftRoll << std::endl;
220  std::cout << "Number of eyes: " << m_eyes.size() << std::endl;
221  for (std::vector<EyeInfo>::size_type i = 0; i < m_eyes.size();
222  ++i) {
223  std::cout << "Eye " << i << ": " << std::endl;
224  m_eyes[i].print();
225  }
226  }
227 
228  std::string DisplayDescriptor::getVendor() const { return m_vendor; }
229 
230  std::string DisplayDescriptor::getModel() const { return m_model; }
231 
232  std::string DisplayDescriptor::getVersion() const { return m_version; }
233 
234  std::string DisplayDescriptor::getNote() const { return m_note; }
235 
236  int DisplayDescriptor::getNumDisplays() const {
237  if (m_eyes.size() < 2) {
238  return 1;
239  }
240  // OK, so two eyes now.
241  if (activeResolution().display_mode == DisplayMode::FULL_SCREEN) {
242  BOOST_ASSERT(activeResolution().video_inputs == 2);
243  return 2;
244  }
245  return 1;
246  }
247 
248  int DisplayDescriptor::getDisplayTop() const { return 0; }
249 
250  int DisplayDescriptor::getDisplayLeft() const { return 0; }
251 
252  int DisplayDescriptor::getDisplayWidth() const {
253  return activeResolution().width;
254  }
255 
256  int DisplayDescriptor::getDisplayHeight() const {
257  return activeResolution().height;
258  }
259 
260  DisplayDescriptor::DisplayMode
261  DisplayDescriptor::getDisplayMode() const {
262  return activeResolution().display_mode;
263  }
264 
265  util::Angle DisplayDescriptor::getVerticalFOV() const {
266  return m_monocularVerticalFOV;
267  }
268 
269  util::Angle DisplayDescriptor::getHorizontalFOV() const {
270  return m_monocularHorizontalFOV;
271  }
272 
273  double DisplayDescriptor::getOverlapPercent() const {
274  return m_overlapPercent;
275  }
276 
277  util::Angle DisplayDescriptor::getPitchTilt() const {
278  return m_pitchTilt;
279  }
280 
281  double DisplayDescriptor::getIPDMeters() const {
282  return DEFAULT_IPD_METERS;
283  }
284 
285  std::vector<DisplayDescriptor::EyeInfo> const &
286  DisplayDescriptor::getEyes() const {
287  return m_eyes;
288  }
289 
290  void DisplayDescriptor::EyeInfo::print() const {
291  std::cout << "Center of projection (X): " << m_CenterProjX
292  << std::endl;
293  std::cout << "Center of projection (Y): " << m_CenterProjY
294  << std::endl;
295  std::cout << "Rotate by 180: " << std::boolalpha << m_rotate180
296  << std::endl;
297  }
298 
299  } // namespace display_schema_1
300 } // namespace client
301 } // namespace osvr
AngleRadiansd Angle
Default angle type.
Definition: Angles.h:63
std::string getVendor() const
Read the property information.
Header containing wrappers for some common jsoncpp operations.
Internal, configured header file for verbosity macros.
std::string getHumanReadableDescription() const
Returns a human-readable description of the device being used, assembled from properties.
Json::Value jsonParse(std::string const &str)
Parses a string as JSON, returning a null value if parsing fails.
Definition: JSONHelpers.h:42