GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
20 / 20
100.0%
Branches:
6 / 12
50.0%
Functions:
20 / 20
100.0%

scene/schema/camera.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file camera.h
3 /// @brief UsdGeomCamera: a view's projection, lens and exposure.
4 ///
5 /// References:
6 /// - Pixar, UsdGeomCamera, https://openusd.org/release/api/class_usd_geom_camera.html
7 #pragma once
8
9 #include "ernie/scene/schema/geom.h"
10
11 // clang-format off
12 // Lens lengths are metres, whatever a USD stage's scale: USD's tenths of a scene unit are
13 // converted on import and export.
14 #define ERNIE_LENS_LENGTH(X, Name, usdName, fallback, text) \
15 X(double, Name, usdName, fallback, text ", metres.", ERNIE_NONNEGATIVE("Lens"))
16
17 #define ERNIE_CAMERA_ATTRIBUTES(X) \
18 X(std::string, Projection, "projection", "perspective", "How it projects the scene.", \
19 .group = "Lens", .options = {"perspective", "orthographic"}) \
20 ERNIE_LENS_LENGTH(X, HorizontalAperture, "horizontalAperture", 0.020955, "Film width") \
21 ERNIE_LENS_LENGTH(X, VerticalAperture, "verticalAperture", 0.0152908, "Film height") \
22 X(double, HorizontalApertureOffset, "horizontalApertureOffset", 0.0, \
23 "The film's offset from the lens axis along x, metres.", .group = "Lens", .finite = true) \
24 X(double, VerticalApertureOffset, "verticalApertureOffset", 0.0, \
25 "The film's offset from the lens axis along y, metres.", .group = "Lens", .finite = true) \
26 ERNIE_LENS_LENGTH(X, FocalLength, "focalLength", 0.05, "The lens's focal length") \
27 X(glm::dvec2, ClippingRange, "clippingRange", glm::dvec2(1.0, 1000000.0), \
28 "Near and far distances in metres.", .group = "Lens", .lower = Above(0.0)) \
29 X(Tensor, ClippingPlanes, "clippingPlanes", Tensor(), \
30 "(n, 4) planes (a, b, c, d) keeping points where a x + b y + c z + d >= 0.", \
31 .group = "Lens", .components = 4) \
32 X(double, FStop, "fStop", 0.0, "The lens's f-number; 0 for a pinhole, all in focus.", \
33 .group = "Lens", .lower = AtLeast(0.0)) \
34 X(double, FocusDistance, "focusDistance", 0.0, "Metres to the plane in focus.", \
35 .group = "Lens", .lower = AtLeast(0.0)) \
36 X(std::string, StereoRole, "stereoRole", "mono", "Which eye it is.", .group = "Lens", \
37 .options = {"mono", "left", "right"}) \
38 X(double, ShutterOpen, "shutter:open", 0.0, "Frames from the time code the shutter opens.", \
39 .group = "Shutter") \
40 X(double, ShutterClose, "shutter:close", 0.0, "Frames from the time code it closes.", \
41 .group = "Shutter") \
42 X(double, Exposure, "exposure", 0.0, "Stops of exposure added to the image.", \
43 .group = "Exposure", .finite = true) \
44 X(double, ExposureIso, "exposure:iso", 100.0, "The sensor's ISO speed.", .group = "Exposure", \
45 .lower = Above(0.0)) \
46 X(double, ExposureTime, "exposure:time", 1.0, "Seconds of exposure.", .group = "Exposure", \
47 .lower = AtLeast(0.0)) \
48 X(double, ExposureFStop, "exposure:fStop", 1.0, "The f-number exposure is computed with.", \
49 .group = "Exposure", .lower = Above(0.0)) \
50 X(double, ExposureResponsivity, "exposure:responsivity", 1.0, "The sensor's responsivity.", \
51 .group = "Exposure", .lower = AtLeast(0.0)) \
52 X(std::string, ExposureMode, "ernie:exposure:mode", "manual", \
53 "auto keys the image to middle grey from the metered scene, after the settings above.", \
54 .group = "Exposure", .options = {"manual", "auto"}) \
55 X(double, ExposureAdaptation, "ernie:exposure:adaptation", 0.0, \
56 "Frames auto exposure takes to cover 63% of a change; 0 at once.", .group = "Exposure", \
57 .lower = AtLeast(0.0)) \
58 X(int, ShutterSamples, "ernie:shutter:samples", 8, "Sub-frames rendered across the shutter.", \
59 .group = "Shutter", .lower = AtLeast(1.0)) \
60 X(double, ShutterRolling, "ernie:shutter:rolling", 0.0, \
61 "Frames between the top row's exposure and the bottom row's; 0 global.", .group = "Shutter", \
62 .lower = AtLeast(0.0)) \
63 X(std::string, Scan, "ernie:camera:scan", "frame", \
64 "pushbroom: a line scanner whose rows run from the last frame's pose to this one's.", \
65 .group = "Shutter", .options = {"frame", "pushbroom"}) \
66 X(double, PushbroomLineOffset, "ernie:pushbroom:lineOffset", 0.0, \
67 "Metres from the principal point to the pushbroom's detector line.", \
68 .group = "Shutter", .finite = true)
69
70 #define ERNIE_LENS_API_ATTRIBUTES(X) \
71 X(std::string, LensProjection, "ernie:lens:projection", "perspective", \
72 "Rectilinear, or a Kannala-Brandt fisheye.", .group = "Lens", \
73 .options = {"perspective", "fisheye"}) \
74 X(std::vector<float>, LensDistortion, "ernie:lens:distortion", std::vector<float>{}, \
75 "Brown-Conrady k1 k2 k3 p1 p2; missing ones are 0.", .group = "Lens") \
76 X(std::vector<float>, LensFisheye, "ernie:lens:fisheye", std::vector<float>{}, \
77 "Kannala-Brandt k1 k2 k3 k4 of a fisheye; none is equidistant.", .group = "Lens") \
78 X(bool, LensVignetting, "ernie:lens:vignetting", false, "Natural falloff off axis.", \
79 .group = "Lens") \
80 X(double, LensTransmission, "ernie:lens:transmission", 1.0, "The fraction of light passed.", \
81 ERNIE_FRACTION("Lens")) \
82 X(std::vector<float>, LensChromaticScale, "ernie:lens:chromatic:scale", std::vector<float>{}, \
83 "(nm, scale) pairs: lateral colour, the image's scale per wavelength.", .group = "Lens") \
84 X(std::vector<float>, LensChromaticFocus, "ernie:lens:chromatic:focus", std::vector<float>{}, \
85 "(nm, metres) pairs: axial colour, the focal length's shift per wavelength.", \
86 .group = "Lens") \
87 X(Tensor, LensRays, "ernie:lens:rays", Tensor(), \
88 "float32 (rows, columns, 3) unit directions every rays step pixels, in place of the " \
89 "projection and distortion.", \
90 .group = "Lens", .ranks = {3}) \
91 X(int, LensRaysStep, "ernie:lens:raysStep", 8, "Pixels between the lens's rays.", \
92 .group = "Lens", .lower = AtLeast(1.0))
93
94 #define ERNIE_POLARIZER_API_ATTRIBUTES(X) \
95 X(std::string, PolarizerType, "ernie:polarizer:type", "linear", \
96 "linear in front of the lens, or a mosaic of 90, 45 / 135, 0 degree polarizers over 2 x 2 " \
97 "pixels, as a polarization sensor's.", \
98 .group = "Polarizer", .options = {"linear", "mosaic"}) \
99 X(double, PolarizerAngle, "ernie:polarizer:angle", 0.0, \
100 "Degrees from the image's +x towards +y to a linear polarizer's axis.", .group = "Polarizer", \
101 .finite = true) \
102 X(double, PolarizerExtinction, "ernie:polarizer:extinction", 1000.0, \
103 "Light passed along the axis over light passed across it.", .group = "Polarizer", \
104 .lower = AtLeast(1.0)) \
105 X(double, PolarizerTransmission, "ernie:polarizer:transmission", 0.85, \
106 "The fraction of light polarized along the axis passed.", ERNIE_FRACTION("Polarizer"))
107
108 #define ERNIE_SENSOR_QE(X, Name, usdName, channel) \
109 X(std::vector<float>, Name, usdName, std::vector<float>{}, \
110 "(nm, electrons per photon) pairs of the " channel "; unset keeps the generic curve.", \
111 .group = "Sensor")
112
113 #define ERNIE_SENSOR_API_ATTRIBUTES(X) \
114 X(glm::dvec2, SpectralRange, "ernie:spectral:range", glm::dvec2(380.0, 780.0), \
115 "Wavelengths in nm the sensor responds to; its products sample them in bands.", \
116 .group = "Sensor", .lower = Above(0.0)) \
117 X(std::string, SensorType, "ernie:sensor:type", "rgb", "A colour or a mono sensor.", \
118 .group = "Sensor", .options = {"rgb", "mono"}) \
119 X(bool, SensorNoise, "ernie:sensor:noise", true, "Whether it adds the noise below.", \
120 .group = "Sensor") \
121 X(double, SensorFullWell, "ernie:sensor:fullWell", 20000.0, "Electrons a pixel holds.", \
122 .group = "Sensor", .lower = Above(0.0)) \
123 X(double, SensorReadNoise, "ernie:sensor:readNoise", 3.0, "Electrons, standard deviation.", \
124 .group = "Sensor", .lower = AtLeast(0.0)) \
125 X(double, SensorDarkCurrent, "ernie:sensor:darkCurrent", 0.1, "Electrons per second.", \
126 .group = "Sensor", .lower = AtLeast(0.0)) \
127 X(double, SensorPrnu, "ernie:sensor:prnu", 0.005, \
128 "Standard deviation of each pixel's relative gain.", .group = "Sensor", \
129 .lower = AtLeast(0.0)) \
130 X(double, SensorDsnu, "ernie:sensor:dsnu", 0.5, \
131 "Electrons, standard deviation of each pixel's offset.", .group = "Sensor", \
132 .lower = AtLeast(0.0)) \
133 X(double, SensorElectronsPerDn, "ernie:sensor:electronsPerDn", 0.0, \
134 "At ISO 100; 0 for the full well over the bit depth's range.", .group = "Sensor", \
135 .lower = AtLeast(0.0)) \
136 X(int, SensorBitDepth, "ernie:sensor:bitDepth", 12, \
137 "Bits of each digital number the sensor's ADC makes, such as 8, 12 or 16.", \
138 .group = "Sensor", .lower = AtLeast(1.0), .upper = AtMost(32.0)) \
139 X(double, SensorBlackLevel, "ernie:sensor:blackLevel", 0.0, "DN added to every pixel.", \
140 .group = "Sensor", .lower = AtLeast(0.0)) \
141 X(double, SensorPixelPitch, "ernie:sensor:pixelPitch", 5.0, \
142 "Micrometres, of orthographic cameras.", .group = "Sensor", .lower = Above(0.0)) \
143 X(int, SensorSeed, "ernie:sensor:seed", 0, "The seed of the sensor's noise.", \
144 .group = "Sensor") \
145 ERNIE_SENSOR_QE(X, SensorQeR, "ernie:sensor:qe:r", "red channel") \
146 ERNIE_SENSOR_QE(X, SensorQeG, "ernie:sensor:qe:g", "green channel") \
147 ERNIE_SENSOR_QE(X, SensorQeB, "ernie:sensor:qe:b", "blue channel") \
148 ERNIE_SENSOR_QE(X, SensorQeMono, "ernie:sensor:qe:mono", "mono channel")
149 // clang-format on
150
151 namespace ernie {
152
153 24 ERNIE_CONCRETE_SCHEMA(Camera, Xformable, ERNIE_CAMERA_ATTRIBUTES,
154 "A view looking down -z, y up, with a lens and film.");
155
2/4
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
4 ERNIE_API_SCHEMA(ErnieLensAPI, ERNIE_LENS_API_ATTRIBUTES,
156 "A camera's lens beyond USD's: fisheyes, distortion, vignetting and chromatic "
157 "aberration.");
158
2/4
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
4 ERNIE_API_SCHEMA(ErniePolarizerAPI, ERNIE_POLARIZER_API_ATTRIBUTES,
159 "A polarizer in front of a camera's lens, or a polarization sensor's mosaic.");
160
2/4
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
8 ERNIE_API_SCHEMA(ErnieSensorAPI, ERNIE_SENSOR_API_ATTRIBUTES,
161 "A camera's sensor: its spectral range, noise, ADC and quantum efficiency; its "
162 "products set how finely the range is sampled.");
163
164 } // namespace ernie
165