blob: 690c326ffbb4af6ee38377040b53a0cfd8d46023 [file] [log] [blame]
#include "include/private/dvr/display_metrics.h"
#include <private/dvr/head_mount_metrics.h>
#include <private/dvr/identity_distortion.h>
#include <private/dvr/lookup_radial_distortion.h>
#include <private/dvr/lucid_metrics.h>
#include <private/dvr/types.h>
namespace {
// These numbers are specific to the OnePlus One and therefore
// temporary until we advance to the next Lucid development platform.
// Head mount metrics for Lucid A00
static const float kDefaultInterLensDistance = 0.064f; // 64mm
static const float kDefaultTrayToLensDistance = 0.035f;
static const float kDefaultVirtualEyeToScreenDistance = 0.042f;
static const android::dvr::HeadMountMetrics::VerticalAlignment
kDefaultVerticalAlignment = android::dvr::HeadMountMetrics::kCenter;
static const float kDefaultFovHalfAngleInsideH = 43.7f * M_PI / 180.0f;
static const float kDefaultFovHalfAngleOutsideH = 47.8f * M_PI / 180.0f;
static const float kDefaultFovHalfAngleV = 54.2f * M_PI / 180.0f;
// Screen size in meters for Lucid (Nexus 6 display in portrait mode).
static const android::dvr::vec2 kScreenSizeInMeters(0.0742177f, 0.131943f);
// Border size in meters for the OnePlus One.
static const float kScreenBorderSize = 0.004f;
// Refresh rate.
static const float kScreenRefreshRate = 60.0f;
// Lucid display orientation is portrait.
static const android::dvr::DisplayOrientation kDisplayOrientation =
android::dvr::DisplayOrientation::kPortrait;
} // anonymous namespace
namespace android {
namespace dvr {
// The distortion lookup tables were generated via a raytraced lens simulation.
// Please see for full calculations:
// https://docs.google.com/a/google.com/spreadsheets/d/
// 15cfHmCw5mHVOQ1rAJxMhta4q0e8zzcUDka1nRkfl7pY/edit?usp=sharing
LookupRadialDistortion* GetBlueDistortionLookup() {
// clang-format off
vec2 kBlueDistortionLookup[] = {
{0.00000000000f, 1.00000000000f},
{0.01888626190f, 1.00096958278f},
{0.03777223810f, 1.00133301793f},
{0.05665761905f, 1.00193985168f},
{0.07554214286f, 1.00279048731f},
{0.09442542857f, 1.00388751781f},
{0.11330704762f, 1.00523363045f},
{0.13218657143f, 1.00683149424f},
{0.15106340476f, 1.00868516849f},
{0.16993695238f, 1.01079861126f},
{0.18880640476f, 1.01317712726f},
{0.20767092857f, 1.01582607321f},
{0.22652945238f, 1.01875203063f},
{0.24538078571f, 1.02196207850f},
{0.26422352381f, 1.02546421601f},
{0.28305602381f, 1.02926737969f},
{0.30187640476f, 1.03338139216f},
{0.32068252381f, 1.03781702504f},
{0.33947190476f, 1.04258620905f},
{0.35824171429f, 1.04770206653f},
{0.37698869048f, 1.05317909331f},
{0.39570916667f, 1.05903306635f},
{0.41439900000f, 1.06528124790f},
{0.43305350000f, 1.07194257391f},
{0.45166738095f, 1.07903777957f},
{0.47023471429f, 1.08658953759f},
{0.48874897619f, 1.09462239798f},
{0.50720285714f, 1.10316330018f},
{0.52558835714f, 1.11224144183f},
{0.54389669048f, 1.12188861421f},
{0.56211826190f, 1.13213939967f},
{0.58024261905f, 1.14303145047f},
{0.59825847619f, 1.15460566091f},
{0.61615335714f, 1.16690711338f},
{0.63391345238f, 1.17998560444f},
{0.65152300000f, 1.19389708987f},
{0.66896328571f, 1.20870580446f},
{0.68621100000f, 1.22448751087f},
{0.70323578571f, 1.24133415620f},
{0.71999716667f, 1.25935962776f},
{0.73643969048f, 1.27870875648f},
{0.75250778571f, 1.29953256670f},
{0.76817614286f, 1.32193822000f},
{0.78342009524f, 1.34604270338f},
{0.79828314286f, 1.37185833833f},
{0.81267376190f, 1.39964322604f},
{0.82656559524f, 1.42955958262f},
{0.83983054762f, 1.46196539657f},
{0.85234333333f, 1.49724142650f},
{0.86394971429f, 1.53585530271f},
{0.87422461905f, 1.57881139444f},
{0.88382583095f, 1.62091537826f},
{0.89571361286f, 1.67610209261f},
{0.90490389167f, 1.72118819668f},
{0.91526452143f, 1.77496904481f},
{0.92651365452f, 1.83722833673f},
{0.93437489976f, 1.88337590145f},
{0.94654105500f, 1.95937892848f},
{0.95476685095f, 2.01469745492f},
{0.96720383310f, 2.10451495481f},
{0.97546726405f, 2.16904926656f},
{0.98774046786f, 2.27302748020f},
{0.99579206762f, 2.34720582421f},
{1.00763328857f, 2.46603526105f},
{1.01533118405f, 2.55049232288f},
{1.02287120929f, 2.63936582235f}
};
// clang-format on
return new LookupRadialDistortion(
kBlueDistortionLookup, sizeof(kBlueDistortionLookup) / sizeof(vec2));
}
LookupRadialDistortion* GetGreenDistortionLookup() {
// clang-format off
vec2 kGreenDistortionLookup[] = {
{0.00000000000f, 1.00000000000f},
{0.01898883333f, 1.00000000000f},
{0.03797750000f, 1.00000000000f},
{0.05696585714f, 1.00000000000f},
{0.07595369048f, 1.00000000000f},
{0.09494078571f, 1.00000000000f},
{0.11392685714f, 1.00000000000f},
{0.13291157143f, 1.00000000000f},
{0.15189450000f, 1.00176560670f},
{0.17087511905f, 1.00384553961f},
{0.18985280952f, 1.00618614484f},
{0.20882680952f, 1.00879302066f},
{0.22779623810f, 1.01167234096f},
{0.24675997619f, 1.01483135203f},
{0.26571680952f, 1.01827767641f},
{0.28466519048f, 1.02202026825f},
{0.30360342857f, 1.02606859705f},
{0.32252950000f, 1.03043334057f},
{0.34144104762f, 1.03512630376f},
{0.36033538095f, 1.04016038545f},
{0.37920942857f, 1.04554970984f},
{0.39805966667f, 1.05130981266f},
{0.41688209524f, 1.05745768999f},
{0.43567214286f, 1.06401204155f},
{0.45442473810f, 1.07099310305f},
{0.47313411905f, 1.07842314596f},
{0.49179388095f, 1.08632639514f},
{0.51039692857f, 1.09472920992f},
{0.52893538095f, 1.10366038032f},
{0.54740061905f, 1.11315113705f},
{0.56578326190f, 1.12323535769f},
{0.58407300000f, 1.13395008040f},
{0.60225871429f, 1.14533547370f},
{0.62032809524f, 1.15743581542f},
{0.63826750000f, 1.17030000749f},
{0.65606135714f, 1.18398295206f},
{0.67369107143f, 1.19854780583f},
{0.69113350000f, 1.21406895255f},
{0.70835842857f, 1.23063670464f},
{0.72532545238f, 1.24836302903f},
{0.74197478571f, 1.26739777609f},
{0.75822164286f, 1.28793886907f},
{0.77407361905f, 1.31003521318f},
{0.78948523810f, 1.33383710115f},
{0.80448471429f, 1.35938255065f},
{0.81901733333f, 1.38686361242f},
{0.83305214286f, 1.41644808409f},
{0.84646438095f, 1.44848277406f},
{0.85912733333f, 1.48334485259f},
{0.87088369048f, 1.52149970074f},
{0.88131250000f, 1.56392750036f},
{0.89105132929f, 1.60552684742f},
{0.90312479476f, 1.66002695068f},
{0.91244067452f, 1.70458805205f},
{0.92297971714f, 1.75767475825f},
{0.93440940905f, 1.81916050294f},
{0.94237194976f, 1.86478635937f},
{0.95471202405f, 1.93989738862f},
{0.96305355738f, 1.99457325750f},
{0.97567372071f, 2.08333293385f},
{0.98407229071f, 2.14708073108f},
{0.99653762071f, 2.24981649552f},
{1.00471276167f, 2.32311751786f},
{1.01672394000f, 2.44057411530f},
{1.02452363381f, 2.52407947994f},
{1.03216732667f, 2.61194301580f}
};
// clang-format on
return new LookupRadialDistortion(
kGreenDistortionLookup, sizeof(kGreenDistortionLookup) / sizeof(vec2));
}
LookupRadialDistortion* GetRedDistortionLookup() {
// clang-format off
vec2 kRedDistortionLookup[] = {
{0.00000000000f, 1.00000000000f},
{0.01906776190f, 1.00000000000f},
{0.03813547619f, 1.00000000000f},
{0.05720304762f, 1.00000000000f},
{0.07627040476f, 1.00000000000f},
{0.09533740476f, 1.00000000000f},
{0.11440385714f, 1.00000000000f},
{0.13346952381f, 1.00000000000f},
{0.15253409524f, 1.00000000000f},
{0.17159714286f, 1.00000000000f},
{0.19065814286f, 1.00053530030f},
{0.20971645238f, 1.00310924426f},
{0.22877123810f, 1.00595236192f},
{0.24782154762f, 1.00907150786f},
{0.26686623810f, 1.01247435420f},
{0.28590388095f, 1.01616968529f},
{0.30493288095f, 1.02016688932f},
{0.32395133333f, 1.02447646681f},
{0.34295697619f, 1.02911011406f},
{0.36194726190f, 1.03408046560f},
{0.38091921429f, 1.03940151599f},
{0.39986942857f, 1.04508858434f},
{0.41879402381f, 1.05115843585f},
{0.43768857143f, 1.05762946333f},
{0.45654809524f, 1.06452169646f},
{0.47536695238f, 1.07185711363f},
{0.49413888095f, 1.07965956927f},
{0.51285690476f, 1.08795508025f},
{0.53151326190f, 1.09677206014f},
{0.55009952381f, 1.10614118417f},
{0.56860633333f, 1.11609607621f},
{0.58702361905f, 1.12667304464f},
{0.60534028571f, 1.13791190276f},
{0.62354421429f, 1.14985618930f},
{0.64162188095f, 1.16255413653f},
{0.65955780952f, 1.17605992962f},
{0.67733352381f, 1.19043584317f},
{0.69492602381f, 1.20575517508f},
{0.71230514286f, 1.22210708787f},
{0.72943057143f, 1.23960199799f},
{0.74623921429f, 1.25839340501f},
{0.76262400000f, 1.27871385661f},
{0.77861754762f, 1.30056919119f},
{0.79415866667f, 1.32413401001f},
{0.80926385714f, 1.34946540639f},
{0.82390640476f, 1.37670655635f},
{0.83805190476f, 1.40602920817f},
{0.85157807143f, 1.43777181543f},
{0.86435700000f, 1.47230885729f},
{0.87622914286f, 1.51010361811f},
{0.88677650000f, 1.55211817236f},
{0.89663317738f, 1.59330127207f},
{0.90883197952f, 1.64729627820f},
{0.91827594357f, 1.69138814689f},
{0.92892199405f, 1.74398939784f},
{0.94047261548f, 1.80490554711f},
{0.94852659262f, 1.85009630648f},
{0.96099790167f, 1.92451421938f},
{0.96945317500f, 1.97863645920f},
{0.98221554286f, 2.06656418112f},
{0.99069599476f, 2.12974390154f},
{1.00331392976f, 2.23149730290f},
{1.01157138762f, 2.30414058939f},
{1.02372409452f, 2.42049694265f},
{1.03162992905f, 2.50318810924f},
{1.03934762000f, 2.59027212626f}
};
// clang-format on
return new LookupRadialDistortion(
kRedDistortionLookup, sizeof(kRedDistortionLookup) / sizeof(vec2));
}
HeadMountMetrics CreateHeadMountMetrics(const FieldOfView& l_fov,
const FieldOfView& r_fov) {
std::shared_ptr<ColorChannelDistortion> default_distortion_r(
GetRedDistortionLookup());
std::shared_ptr<ColorChannelDistortion> default_distortion_g(
GetGreenDistortionLookup());
std::shared_ptr<ColorChannelDistortion> default_distortion_b(
GetBlueDistortionLookup());
return HeadMountMetrics(
kDefaultInterLensDistance, kDefaultTrayToLensDistance,
kDefaultVirtualEyeToScreenDistance, kDefaultVerticalAlignment, l_fov,
r_fov, default_distortion_r, default_distortion_g, default_distortion_b,
HeadMountMetrics::EyeOrientation::kCCW0Degrees,
HeadMountMetrics::EyeOrientation::kCCW0Degrees,
kDefaultInterLensDistance / 2.0f);
}
HeadMountMetrics CreateHeadMountMetrics() {
FieldOfView l_fov(kDefaultFovHalfAngleOutsideH, kDefaultFovHalfAngleInsideH,
kDefaultFovHalfAngleV, kDefaultFovHalfAngleV);
FieldOfView r_fov(kDefaultFovHalfAngleInsideH, kDefaultFovHalfAngleOutsideH,
kDefaultFovHalfAngleV, kDefaultFovHalfAngleV);
return CreateHeadMountMetrics(l_fov, r_fov);
}
DisplayMetrics CreateDisplayMetrics(vec2i screen_size) {
vec2 meters_per_pixel(
kScreenSizeInMeters[0] / static_cast<float>(screen_size[0]),
kScreenSizeInMeters[1] / static_cast<float>(screen_size[1]));
return DisplayMetrics(screen_size, meters_per_pixel, kScreenBorderSize,
1000.0f / kScreenRefreshRate, kDisplayOrientation);
}
HeadMountMetrics CreateUndistortedHeadMountMetrics() {
FieldOfView l_fov(kDefaultFovHalfAngleOutsideH, kDefaultFovHalfAngleInsideH,
kDefaultFovHalfAngleV, kDefaultFovHalfAngleV);
FieldOfView r_fov(kDefaultFovHalfAngleInsideH, kDefaultFovHalfAngleOutsideH,
kDefaultFovHalfAngleV, kDefaultFovHalfAngleV);
return CreateUndistortedHeadMountMetrics(l_fov, r_fov);
}
HeadMountMetrics CreateUndistortedHeadMountMetrics(const FieldOfView& l_fov,
const FieldOfView& r_fov) {
auto distortion_all = std::make_shared<IdentityDistortion>();
return HeadMountMetrics(kDefaultInterLensDistance, kDefaultTrayToLensDistance,
kDefaultVirtualEyeToScreenDistance,
kDefaultVerticalAlignment, l_fov, r_fov,
distortion_all, distortion_all, distortion_all,
HeadMountMetrics::EyeOrientation::kCCW0Degrees,
HeadMountMetrics::EyeOrientation::kCCW0Degrees,
kDefaultInterLensDistance / 2.0f);
}
} // namespace dvr
} // namespace dvr