Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame^] | 1 | #include "include/private/dvr/display_metrics.h" |
| 2 | #include <private/dvr/head_mount_metrics.h> |
| 3 | #include <private/dvr/identity_distortion.h> |
| 4 | #include <private/dvr/lookup_radial_distortion.h> |
| 5 | #include <private/dvr/lucid_metrics.h> |
| 6 | #include <private/dvr/types.h> |
| 7 | |
| 8 | namespace { |
| 9 | |
| 10 | // These numbers are specific to the OnePlus One and therefore |
| 11 | // temporary until we advance to the next Lucid development platform. |
| 12 | |
| 13 | // Head mount metrics for Lucid A00 |
| 14 | static const float kDefaultInterLensDistance = 0.064f; // 64mm |
| 15 | static const float kDefaultTrayToLensDistance = 0.035f; |
| 16 | static const float kDefaultVirtualEyeToScreenDistance = 0.042f; |
| 17 | static const android::dvr::HeadMountMetrics::VerticalAlignment |
| 18 | kDefaultVerticalAlignment = android::dvr::HeadMountMetrics::kCenter; |
| 19 | static const float kDefaultFovHalfAngleInsideH = 43.7f * M_PI / 180.0f; |
| 20 | static const float kDefaultFovHalfAngleOutsideH = 47.8f * M_PI / 180.0f; |
| 21 | static const float kDefaultFovHalfAngleV = 54.2f * M_PI / 180.0f; |
| 22 | |
| 23 | // Screen size in meters for Lucid (Nexus 6 display in portrait mode). |
| 24 | static const android::dvr::vec2 kScreenSizeInMeters(0.0742177f, 0.131943f); |
| 25 | |
| 26 | // Border size in meters for the OnePlus One. |
| 27 | static const float kScreenBorderSize = 0.004f; |
| 28 | |
| 29 | // Refresh rate. |
| 30 | static const float kScreenRefreshRate = 60.0f; |
| 31 | |
| 32 | // Lucid display orientation is portrait. |
| 33 | static const android::dvr::DisplayOrientation kDisplayOrientation = |
| 34 | android::dvr::DisplayOrientation::kPortrait; |
| 35 | |
| 36 | } // anonymous namespace |
| 37 | |
| 38 | namespace android { |
| 39 | namespace dvr { |
| 40 | |
| 41 | // The distortion lookup tables were generated via a raytraced lens simulation. |
| 42 | // Please see for full calculations: |
| 43 | // https://docs.google.com/a/google.com/spreadsheets/d/ |
| 44 | // 15cfHmCw5mHVOQ1rAJxMhta4q0e8zzcUDka1nRkfl7pY/edit?usp=sharing |
| 45 | LookupRadialDistortion* GetBlueDistortionLookup() { |
| 46 | // clang-format off |
| 47 | vec2 kBlueDistortionLookup[] = { |
| 48 | {0.00000000000f, 1.00000000000f}, |
| 49 | {0.01888626190f, 1.00096958278f}, |
| 50 | {0.03777223810f, 1.00133301793f}, |
| 51 | {0.05665761905f, 1.00193985168f}, |
| 52 | {0.07554214286f, 1.00279048731f}, |
| 53 | {0.09442542857f, 1.00388751781f}, |
| 54 | {0.11330704762f, 1.00523363045f}, |
| 55 | {0.13218657143f, 1.00683149424f}, |
| 56 | {0.15106340476f, 1.00868516849f}, |
| 57 | {0.16993695238f, 1.01079861126f}, |
| 58 | {0.18880640476f, 1.01317712726f}, |
| 59 | {0.20767092857f, 1.01582607321f}, |
| 60 | {0.22652945238f, 1.01875203063f}, |
| 61 | {0.24538078571f, 1.02196207850f}, |
| 62 | {0.26422352381f, 1.02546421601f}, |
| 63 | {0.28305602381f, 1.02926737969f}, |
| 64 | {0.30187640476f, 1.03338139216f}, |
| 65 | {0.32068252381f, 1.03781702504f}, |
| 66 | {0.33947190476f, 1.04258620905f}, |
| 67 | {0.35824171429f, 1.04770206653f}, |
| 68 | {0.37698869048f, 1.05317909331f}, |
| 69 | {0.39570916667f, 1.05903306635f}, |
| 70 | {0.41439900000f, 1.06528124790f}, |
| 71 | {0.43305350000f, 1.07194257391f}, |
| 72 | {0.45166738095f, 1.07903777957f}, |
| 73 | {0.47023471429f, 1.08658953759f}, |
| 74 | {0.48874897619f, 1.09462239798f}, |
| 75 | {0.50720285714f, 1.10316330018f}, |
| 76 | {0.52558835714f, 1.11224144183f}, |
| 77 | {0.54389669048f, 1.12188861421f}, |
| 78 | {0.56211826190f, 1.13213939967f}, |
| 79 | {0.58024261905f, 1.14303145047f}, |
| 80 | {0.59825847619f, 1.15460566091f}, |
| 81 | {0.61615335714f, 1.16690711338f}, |
| 82 | {0.63391345238f, 1.17998560444f}, |
| 83 | {0.65152300000f, 1.19389708987f}, |
| 84 | {0.66896328571f, 1.20870580446f}, |
| 85 | {0.68621100000f, 1.22448751087f}, |
| 86 | {0.70323578571f, 1.24133415620f}, |
| 87 | {0.71999716667f, 1.25935962776f}, |
| 88 | {0.73643969048f, 1.27870875648f}, |
| 89 | {0.75250778571f, 1.29953256670f}, |
| 90 | {0.76817614286f, 1.32193822000f}, |
| 91 | {0.78342009524f, 1.34604270338f}, |
| 92 | {0.79828314286f, 1.37185833833f}, |
| 93 | {0.81267376190f, 1.39964322604f}, |
| 94 | {0.82656559524f, 1.42955958262f}, |
| 95 | {0.83983054762f, 1.46196539657f}, |
| 96 | {0.85234333333f, 1.49724142650f}, |
| 97 | {0.86394971429f, 1.53585530271f}, |
| 98 | {0.87422461905f, 1.57881139444f}, |
| 99 | {0.88382583095f, 1.62091537826f}, |
| 100 | {0.89571361286f, 1.67610209261f}, |
| 101 | {0.90490389167f, 1.72118819668f}, |
| 102 | {0.91526452143f, 1.77496904481f}, |
| 103 | {0.92651365452f, 1.83722833673f}, |
| 104 | {0.93437489976f, 1.88337590145f}, |
| 105 | {0.94654105500f, 1.95937892848f}, |
| 106 | {0.95476685095f, 2.01469745492f}, |
| 107 | {0.96720383310f, 2.10451495481f}, |
| 108 | {0.97546726405f, 2.16904926656f}, |
| 109 | {0.98774046786f, 2.27302748020f}, |
| 110 | {0.99579206762f, 2.34720582421f}, |
| 111 | {1.00763328857f, 2.46603526105f}, |
| 112 | {1.01533118405f, 2.55049232288f}, |
| 113 | {1.02287120929f, 2.63936582235f} |
| 114 | }; |
| 115 | // clang-format on |
| 116 | return new LookupRadialDistortion( |
| 117 | kBlueDistortionLookup, sizeof(kBlueDistortionLookup) / sizeof(vec2)); |
| 118 | } |
| 119 | |
| 120 | LookupRadialDistortion* GetGreenDistortionLookup() { |
| 121 | // clang-format off |
| 122 | vec2 kGreenDistortionLookup[] = { |
| 123 | {0.00000000000f, 1.00000000000f}, |
| 124 | {0.01898883333f, 1.00000000000f}, |
| 125 | {0.03797750000f, 1.00000000000f}, |
| 126 | {0.05696585714f, 1.00000000000f}, |
| 127 | {0.07595369048f, 1.00000000000f}, |
| 128 | {0.09494078571f, 1.00000000000f}, |
| 129 | {0.11392685714f, 1.00000000000f}, |
| 130 | {0.13291157143f, 1.00000000000f}, |
| 131 | {0.15189450000f, 1.00176560670f}, |
| 132 | {0.17087511905f, 1.00384553961f}, |
| 133 | {0.18985280952f, 1.00618614484f}, |
| 134 | {0.20882680952f, 1.00879302066f}, |
| 135 | {0.22779623810f, 1.01167234096f}, |
| 136 | {0.24675997619f, 1.01483135203f}, |
| 137 | {0.26571680952f, 1.01827767641f}, |
| 138 | {0.28466519048f, 1.02202026825f}, |
| 139 | {0.30360342857f, 1.02606859705f}, |
| 140 | {0.32252950000f, 1.03043334057f}, |
| 141 | {0.34144104762f, 1.03512630376f}, |
| 142 | {0.36033538095f, 1.04016038545f}, |
| 143 | {0.37920942857f, 1.04554970984f}, |
| 144 | {0.39805966667f, 1.05130981266f}, |
| 145 | {0.41688209524f, 1.05745768999f}, |
| 146 | {0.43567214286f, 1.06401204155f}, |
| 147 | {0.45442473810f, 1.07099310305f}, |
| 148 | {0.47313411905f, 1.07842314596f}, |
| 149 | {0.49179388095f, 1.08632639514f}, |
| 150 | {0.51039692857f, 1.09472920992f}, |
| 151 | {0.52893538095f, 1.10366038032f}, |
| 152 | {0.54740061905f, 1.11315113705f}, |
| 153 | {0.56578326190f, 1.12323535769f}, |
| 154 | {0.58407300000f, 1.13395008040f}, |
| 155 | {0.60225871429f, 1.14533547370f}, |
| 156 | {0.62032809524f, 1.15743581542f}, |
| 157 | {0.63826750000f, 1.17030000749f}, |
| 158 | {0.65606135714f, 1.18398295206f}, |
| 159 | {0.67369107143f, 1.19854780583f}, |
| 160 | {0.69113350000f, 1.21406895255f}, |
| 161 | {0.70835842857f, 1.23063670464f}, |
| 162 | {0.72532545238f, 1.24836302903f}, |
| 163 | {0.74197478571f, 1.26739777609f}, |
| 164 | {0.75822164286f, 1.28793886907f}, |
| 165 | {0.77407361905f, 1.31003521318f}, |
| 166 | {0.78948523810f, 1.33383710115f}, |
| 167 | {0.80448471429f, 1.35938255065f}, |
| 168 | {0.81901733333f, 1.38686361242f}, |
| 169 | {0.83305214286f, 1.41644808409f}, |
| 170 | {0.84646438095f, 1.44848277406f}, |
| 171 | {0.85912733333f, 1.48334485259f}, |
| 172 | {0.87088369048f, 1.52149970074f}, |
| 173 | {0.88131250000f, 1.56392750036f}, |
| 174 | {0.89105132929f, 1.60552684742f}, |
| 175 | {0.90312479476f, 1.66002695068f}, |
| 176 | {0.91244067452f, 1.70458805205f}, |
| 177 | {0.92297971714f, 1.75767475825f}, |
| 178 | {0.93440940905f, 1.81916050294f}, |
| 179 | {0.94237194976f, 1.86478635937f}, |
| 180 | {0.95471202405f, 1.93989738862f}, |
| 181 | {0.96305355738f, 1.99457325750f}, |
| 182 | {0.97567372071f, 2.08333293385f}, |
| 183 | {0.98407229071f, 2.14708073108f}, |
| 184 | {0.99653762071f, 2.24981649552f}, |
| 185 | {1.00471276167f, 2.32311751786f}, |
| 186 | {1.01672394000f, 2.44057411530f}, |
| 187 | {1.02452363381f, 2.52407947994f}, |
| 188 | {1.03216732667f, 2.61194301580f} |
| 189 | }; |
| 190 | // clang-format on |
| 191 | return new LookupRadialDistortion( |
| 192 | kGreenDistortionLookup, sizeof(kGreenDistortionLookup) / sizeof(vec2)); |
| 193 | } |
| 194 | |
| 195 | LookupRadialDistortion* GetRedDistortionLookup() { |
| 196 | // clang-format off |
| 197 | vec2 kRedDistortionLookup[] = { |
| 198 | {0.00000000000f, 1.00000000000f}, |
| 199 | {0.01906776190f, 1.00000000000f}, |
| 200 | {0.03813547619f, 1.00000000000f}, |
| 201 | {0.05720304762f, 1.00000000000f}, |
| 202 | {0.07627040476f, 1.00000000000f}, |
| 203 | {0.09533740476f, 1.00000000000f}, |
| 204 | {0.11440385714f, 1.00000000000f}, |
| 205 | {0.13346952381f, 1.00000000000f}, |
| 206 | {0.15253409524f, 1.00000000000f}, |
| 207 | {0.17159714286f, 1.00000000000f}, |
| 208 | {0.19065814286f, 1.00053530030f}, |
| 209 | {0.20971645238f, 1.00310924426f}, |
| 210 | {0.22877123810f, 1.00595236192f}, |
| 211 | {0.24782154762f, 1.00907150786f}, |
| 212 | {0.26686623810f, 1.01247435420f}, |
| 213 | {0.28590388095f, 1.01616968529f}, |
| 214 | {0.30493288095f, 1.02016688932f}, |
| 215 | {0.32395133333f, 1.02447646681f}, |
| 216 | {0.34295697619f, 1.02911011406f}, |
| 217 | {0.36194726190f, 1.03408046560f}, |
| 218 | {0.38091921429f, 1.03940151599f}, |
| 219 | {0.39986942857f, 1.04508858434f}, |
| 220 | {0.41879402381f, 1.05115843585f}, |
| 221 | {0.43768857143f, 1.05762946333f}, |
| 222 | {0.45654809524f, 1.06452169646f}, |
| 223 | {0.47536695238f, 1.07185711363f}, |
| 224 | {0.49413888095f, 1.07965956927f}, |
| 225 | {0.51285690476f, 1.08795508025f}, |
| 226 | {0.53151326190f, 1.09677206014f}, |
| 227 | {0.55009952381f, 1.10614118417f}, |
| 228 | {0.56860633333f, 1.11609607621f}, |
| 229 | {0.58702361905f, 1.12667304464f}, |
| 230 | {0.60534028571f, 1.13791190276f}, |
| 231 | {0.62354421429f, 1.14985618930f}, |
| 232 | {0.64162188095f, 1.16255413653f}, |
| 233 | {0.65955780952f, 1.17605992962f}, |
| 234 | {0.67733352381f, 1.19043584317f}, |
| 235 | {0.69492602381f, 1.20575517508f}, |
| 236 | {0.71230514286f, 1.22210708787f}, |
| 237 | {0.72943057143f, 1.23960199799f}, |
| 238 | {0.74623921429f, 1.25839340501f}, |
| 239 | {0.76262400000f, 1.27871385661f}, |
| 240 | {0.77861754762f, 1.30056919119f}, |
| 241 | {0.79415866667f, 1.32413401001f}, |
| 242 | {0.80926385714f, 1.34946540639f}, |
| 243 | {0.82390640476f, 1.37670655635f}, |
| 244 | {0.83805190476f, 1.40602920817f}, |
| 245 | {0.85157807143f, 1.43777181543f}, |
| 246 | {0.86435700000f, 1.47230885729f}, |
| 247 | {0.87622914286f, 1.51010361811f}, |
| 248 | {0.88677650000f, 1.55211817236f}, |
| 249 | {0.89663317738f, 1.59330127207f}, |
| 250 | {0.90883197952f, 1.64729627820f}, |
| 251 | {0.91827594357f, 1.69138814689f}, |
| 252 | {0.92892199405f, 1.74398939784f}, |
| 253 | {0.94047261548f, 1.80490554711f}, |
| 254 | {0.94852659262f, 1.85009630648f}, |
| 255 | {0.96099790167f, 1.92451421938f}, |
| 256 | {0.96945317500f, 1.97863645920f}, |
| 257 | {0.98221554286f, 2.06656418112f}, |
| 258 | {0.99069599476f, 2.12974390154f}, |
| 259 | {1.00331392976f, 2.23149730290f}, |
| 260 | {1.01157138762f, 2.30414058939f}, |
| 261 | {1.02372409452f, 2.42049694265f}, |
| 262 | {1.03162992905f, 2.50318810924f}, |
| 263 | {1.03934762000f, 2.59027212626f} |
| 264 | }; |
| 265 | // clang-format on |
| 266 | return new LookupRadialDistortion( |
| 267 | kRedDistortionLookup, sizeof(kRedDistortionLookup) / sizeof(vec2)); |
| 268 | } |
| 269 | |
| 270 | HeadMountMetrics CreateHeadMountMetrics(const FieldOfView& l_fov, |
| 271 | const FieldOfView& r_fov) { |
| 272 | std::shared_ptr<ColorChannelDistortion> default_distortion_r( |
| 273 | GetRedDistortionLookup()); |
| 274 | std::shared_ptr<ColorChannelDistortion> default_distortion_g( |
| 275 | GetGreenDistortionLookup()); |
| 276 | std::shared_ptr<ColorChannelDistortion> default_distortion_b( |
| 277 | GetBlueDistortionLookup()); |
| 278 | |
| 279 | return HeadMountMetrics( |
| 280 | kDefaultInterLensDistance, kDefaultTrayToLensDistance, |
| 281 | kDefaultVirtualEyeToScreenDistance, kDefaultVerticalAlignment, l_fov, |
| 282 | r_fov, default_distortion_r, default_distortion_g, default_distortion_b, |
| 283 | HeadMountMetrics::EyeOrientation::kCCW0Degrees, |
| 284 | HeadMountMetrics::EyeOrientation::kCCW0Degrees, |
| 285 | kDefaultInterLensDistance / 2.0f); |
| 286 | } |
| 287 | |
| 288 | HeadMountMetrics CreateHeadMountMetrics() { |
| 289 | FieldOfView l_fov(kDefaultFovHalfAngleOutsideH, kDefaultFovHalfAngleInsideH, |
| 290 | kDefaultFovHalfAngleV, kDefaultFovHalfAngleV); |
| 291 | FieldOfView r_fov(kDefaultFovHalfAngleInsideH, kDefaultFovHalfAngleOutsideH, |
| 292 | kDefaultFovHalfAngleV, kDefaultFovHalfAngleV); |
| 293 | |
| 294 | return CreateHeadMountMetrics(l_fov, r_fov); |
| 295 | } |
| 296 | |
| 297 | DisplayMetrics CreateDisplayMetrics(vec2i screen_size) { |
| 298 | vec2 meters_per_pixel( |
| 299 | kScreenSizeInMeters[0] / static_cast<float>(screen_size[0]), |
| 300 | kScreenSizeInMeters[1] / static_cast<float>(screen_size[1])); |
| 301 | return DisplayMetrics(screen_size, meters_per_pixel, kScreenBorderSize, |
| 302 | 1000.0f / kScreenRefreshRate, kDisplayOrientation); |
| 303 | } |
| 304 | |
| 305 | HeadMountMetrics CreateUndistortedHeadMountMetrics() { |
| 306 | FieldOfView l_fov(kDefaultFovHalfAngleOutsideH, kDefaultFovHalfAngleInsideH, |
| 307 | kDefaultFovHalfAngleV, kDefaultFovHalfAngleV); |
| 308 | FieldOfView r_fov(kDefaultFovHalfAngleInsideH, kDefaultFovHalfAngleOutsideH, |
| 309 | kDefaultFovHalfAngleV, kDefaultFovHalfAngleV); |
| 310 | return CreateUndistortedHeadMountMetrics(l_fov, r_fov); |
| 311 | } |
| 312 | |
| 313 | HeadMountMetrics CreateUndistortedHeadMountMetrics(const FieldOfView& l_fov, |
| 314 | const FieldOfView& r_fov) { |
| 315 | auto distortion_all = std::make_shared<IdentityDistortion>(); |
| 316 | |
| 317 | return HeadMountMetrics(kDefaultInterLensDistance, kDefaultTrayToLensDistance, |
| 318 | kDefaultVirtualEyeToScreenDistance, |
| 319 | kDefaultVerticalAlignment, l_fov, r_fov, |
| 320 | distortion_all, distortion_all, distortion_all, |
| 321 | HeadMountMetrics::EyeOrientation::kCCW0Degrees, |
| 322 | HeadMountMetrics::EyeOrientation::kCCW0Degrees, |
| 323 | kDefaultInterLensDistance / 2.0f); |
| 324 | } |
| 325 | |
| 326 | } // namespace dvr |
| 327 | } // namespace dvr |