5#include "testing/testing.h"
28 const float fov = 150.0f * (
M_PI_F / 180.0f);
29 const float width = 36.0f;
30 const float height = 41.142857142857144f;
36 const float4 k_stereographic =
make_float4(-5.79e-02f, 0.0f, 9.48e-05f, -7.67e-06f);
40 const float4 k_rectilinear =
make_float4(-6.50e-02f, 0.0f, 8.32e-05f, -1.80e-06f);
42 const float4 parameters[]{k_equidistant, k_stereographic, k_rectilinear};
44 const std::pair<float, float> points[]{
56 for (
const float k0 : {0.0f, -1e-2f, -2e-2f, -5e-2f, -1e-1f}) {
57 for (
const float k2 : {0.0f, -1e-4f, 1e-4f, -2e-4f, 2e-4f}) {
58 for (
float4 k : parameters) {
60 for (std::pair<float, float>
const &pt : points) {
61 const float x = pt.first;
62 const float y = pt.second;
64 pt.first, pt.second, k0, k, fov, width, height);
66 EXPECT_NEAR(
len(direction), 1, 1
e-6) <<
"x: " <<
x << std::endl
67 <<
"y: " <<
y << std::endl
68 <<
"k0: " << k0 << std::endl
72 direction, k0, k, width, height);
74 EXPECT_NEAR(reprojection.
x,
x, 1
e-6) <<
"k0: " << k0 << std::endl
75 <<
"k1: " << k.x << std::endl
76 <<
"k2: " << k.y << std::endl
77 <<
"k3: " << k.z << std::endl
78 <<
"k4: " << k.w << std::endl;
79 EXPECT_NEAR(reprojection.
y,
y, 3
e-6) <<
"k0: " << k0 << std::endl
80 <<
"k1: " << k.x << std::endl
81 <<
"k2: " << k.y << std::endl
82 <<
"k3: " << k.z << std::endl
83 <<
"k4: " << k.w << std::endl;
96 const float width = 1.0f;
97 const float height = 1.0f;
101 const float k0 = 0.0f;
104 const float2 center{0.5f, 0.5f};
120 for (
float2 const &offset : offsets) {
123 point.x,
point.y, k0, k_equidistant, fov, width, height);
124 EXPECT_NEAR(
len(direction), 1.0, 1
e-6);
126 const float2 point_mirror = center - offset;
128 point_mirror.
x, point_mirror.
y, k0, k_equidistant, fov, width, height);
129 EXPECT_NEAR(
len(direction_mirror), 1.0, 1
e-6);
131 EXPECT_NEAR(direction.
x, +direction_mirror.
x, 1
e-6)
132 <<
"offset: (" << offset.x <<
", " << offset.y <<
")";
133 EXPECT_NEAR(direction.
y, -direction_mirror.
y, 1
e-6)
134 <<
"offset: (" << offset.x <<
", " << offset.y <<
")";
136 EXPECT_NEAR(direction.
z, -direction_mirror.
z, 1
e-6)
137 <<
"offset: (" << offset.x <<
", " << offset.y <<
")";
149 const float k0 = 0.0f;
151 const float rad60 =
M_PI_F / 3.0f;
152 const float cos60 = 0.5f;
153 const float sin60 = M_SQRT3_F / 2.0f;
155 const float rad30 =
M_PI_F / 6.0f;
156 const float cos30 = M_SQRT3_F / 2.0f;
157 const float sin30 = 0.5f;
159 const float rad45 = M_PI_4F;
160 const float cos45 = M_SQRT1_2F;
161 const float sin45 = M_SQRT1_2F;
163 const std::pair<float2, float3> tests[]{
191 for (
auto [offset, direction] : tests) {
193 for (
float const scale : {1.0f, 0.5f, 2.0f, 0.25f, 4.0f, 0.125f, 8.0f, 0.0625f, 16.0f}) {
194 const float width = 1.0f / scale;
195 const float height = 1.0f / scale;
200 sensor.
x, sensor.
y, k0, k_equidistant, fov, width, height);
202 EXPECT_NEAR(direction.x, computed.
x, 1
e-6)
203 <<
"sensor: (" << sensor.
x <<
", " << sensor.
y <<
")" << std::endl
204 <<
"scale: " << scale;
205 EXPECT_NEAR(direction.y, computed.
y, 1
e-6)
206 <<
"sensor: (" << sensor.
x <<
", " << sensor.
y <<
")" << std::endl
207 <<
"scale: " << scale;
208 EXPECT_NEAR(direction.z, computed.
z, 1
e-6)
209 <<
"sensor: (" << sensor.
x <<
", " << sensor.
y <<
")" << std::endl
210 <<
"scale: " << scale;
213 direction, k0, k_equidistant, width, height);
215 EXPECT_NEAR(sensor.
x, reprojected.
x, 1
e-6) <<
"scale: " << scale;
216 EXPECT_NEAR(sensor.
y, reprojected.
y, 1
e-6) <<
"scale: " << scale;
304 static constexpr float lens = 15.0f;
376 const float2 sensors[]{{0.5f, 0.5f},
387 for (
float const size : {36.0f, 24.0f, 6.0f *
M_PI_F}) {
388 float const width =
size;
389 float const height =
size;
391 size_t test_count = 0;
392 for (
const float2 &sensor : sensors) {
393 const float3 direction = TypeParam::sensor_to_direction(sensor, fov, width, height);
394 if (test.skip_invalid() &&
len(direction) < 0.9f) {
398 EXPECT_NEAR(
len(direction), 1.0, 1
e-6)
399 <<
"dir: (" << direction.
x <<
", " << direction.
y <<
", " << direction.
z <<
")"
401 <<
"fov: " << fov << std::endl
402 <<
"sensor: (" << sensor.x <<
", " << sensor.y <<
")" << std::endl;
403 const float2 projection = TypeParam::direction_to_sensor(direction, fov, width, height);
404 EXPECT_NEAR(sensor.x, projection.
x, test.threshold())
405 <<
"dir: (" << direction.
x <<
", " << direction.
y <<
", " << direction.
z <<
")"
407 <<
"fov: " << fov << std::endl
408 <<
"sensor: (" << sensor.x <<
", " << sensor.y <<
")" << std::endl;
409 EXPECT_NEAR(sensor.y, projection.
y, test.threshold())
410 <<
"dir: (" << direction.
x <<
", " << direction.
y <<
", " << direction.
z <<
")"
412 <<
"fov: " << fov << std::endl
413 <<
"sensor: (" << sensor.x <<
", " << sensor.y <<
")" << std::endl;
415 EXPECT_GE(test_count, 2) <<
"fov: " << fov << std::endl <<
"size: " <<
size << std::endl;
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
ccl_device float3 equiangular_cubemap_face_to_direction(float u, float v)
ccl_device float2 direction_to_fisheye(float3 dir, float fov)
ccl_device float3 fisheye_to_direction(float u, float v, float fov)
ccl_device float2 direction_to_mirrorball(float3 dir)
ccl_device float2 direction_to_equiangular_cubemap_face(float3 dir)
ccl_device float2 direction_to_fisheye_lens_polynomial(float3 dir, float coeff0, float4 coeffs, float width, float height)
CCL_NAMESPACE_BEGIN ccl_device float2 direction_to_spherical(float3 dir)
ccl_device float3 equirectangular_to_direction(float u, float v)
ccl_device float2 direction_to_equirectangular(float3 dir)
ccl_device float2 direction_to_fisheye_equisolid(float3 dir, float lens, float width, float height)
ccl_device_inline float3 fisheye_equisolid_to_direction(float u, float v, float lens, float fov, float width, float height)
ccl_device float3 spherical_to_direction(float theta, float phi)
ccl_device float3 mirrorball_to_direction(float u, float v)
ccl_device_inline float3 fisheye_lens_polynomial_to_direction(float u, float v, float coeff0, float4 coeffs, float fov, float width, float height)
#define CCL_NAMESPACE_END
CCL_NAMESPACE_BEGIN TEST(KernelCamera, FisheyeLensPolynomialRoundtrip)
Test fisheye_lens_polynomial_to_direction and its inverse direction_to_fisheye_lens_polynomial by che...
TYPED_TEST_SUITE(PanoramaProjection, MyTypes)
TYPED_TEST(PanoramaProjection, round_trip)
Test <projection>to_direction and its inverse direction_to<projection> by checking if sensor position...
::testing::Types< Spherical, Equirectangular, FisheyeEquidistant, FisheyeEquisolid, MirrorBall, EquiangularCubemapFace > MyTypes
The CommonValues struct contains information about the tests which is common across the different tes...
virtual bool skip_invalid() const
If skip_invalid returns true, invalid unprojections are ignored in the test.
virtual double threshold() const
Threshold for the reprojection error.
static float2 direction_to_sensor(float3 const &dir, float const fov, float const width, float const height)
static float3 sensor_to_direction(float2 const &sensor, float const fov, float const width, float const height)
static float3 sensor_to_direction(float2 const &sensor, float const fov, float const width, float const height)
static float2 direction_to_sensor(float3 const &dir, float const fov, float const width, float const height)
static float2 direction_to_sensor(float3 const &dir, float const fov, float const width, float const height)
static float3 sensor_to_direction(float2 const &sensor, float const fov, float const width, float const height)
static float3 sensor_to_direction(float2 const &sensor, float const fov, float const width, float const height)
static float2 direction_to_sensor(float3 const &dir, float const fov, float const width, float const height)
bool skip_invalid() const
If skip_invalid returns true, invalid unprojections are ignored in the test.
static constexpr float lens
static float3 sensor_to_direction(float2 const &sensor, float const fov, float const width, float const height)
static float2 direction_to_sensor(float3 const &dir, float const fov, float const width, float const height)
static float2 direction_to_sensor(float3 const &dir, float const fov, float const width, float const height)
static float3 sensor_to_direction(float2 const &sensor, float const fov, float const width, float const height)
VecBase< float, 4 > float4