1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
/**
* Inverse mapping function that hold all the transform stack logic.
* For a pixel coordinates in the given input space, compute the pixel coordinates in output space
*/
__device__ float3 FUNCTION_NAME_4(mapInputToCameraSphere,
fromInputToSphere,
inverseDistortionMetersTransform,
inverseRadialPixelsTransform)(float2 uv,
const float2 inputScale,
const vsDistortion distortion,
const float2 centerShift) const_member {
/** Shift of principal point (Wrt image center)*/
uv -= centerShift;
/** Undistort point in pixel space*/
uv = inverseRadialPixelsTransform(uv, distortion);
RETURN_3D_IF_INVALID_INVERSE_2D(uv)
/* To meter space */
uv /= inputScale;
/* Undistort point in meter space*/
uv = inverseDistortionMetersTransform(uv, distortion);
RETURN_3D_IF_INVALID_INVERSE_2D(uv)
/* From input space to spherical space */
float3 pt = fromInputToSphere(uv);
return pt;
}
__device__ float3 FUNCTION_NAME_4(tracePointToRigSphere,
fromInputToSphere,
inverseDistortionMetersTransform,
inverseRadialPixelsTransform)(float3 pt,
const vsfloat3x4 poseInverse,
const float rigSphereRadius) const_member {
// Have translation?
#ifndef GPU_CL_ARGS_WORKAROUND
if (poseInverse.values[0][3] != 0.0f ||
poseInverse.values[1][3] != 0.0f ||
poseInverse.values[2][3] != 0.0f) {
#else
if (poseInverse.s3 != 0.0f ||
poseInverse.s7 != 0.0f ||
poseInverse.sb != 0.0f) {
#endif
/* Camera center in spherical (rig) space */
const float3 camcenterpt = transformSphere(make_float3(0.f, 0.f, 0.f), poseInverse);
/* Set refpt to reference sphere scale by ray-tracing it, finding lambda > 0 such as norm(camcenterpt + lambda * (pt
* - camcenterpt)) == rigSphereRadius */
const float3 ray = pt - camcenterpt;
/* lambda is root of lambda^2.ray^T.ray + 2 * lambda * center^T.ray + center^T.center - rigSphereRadius^2 */
const float a = dot(ray, ray);
const float b = 2 * dot(camcenterpt, ray);
const float c = dot(camcenterpt, camcenterpt) - rigSphereRadius * rigSphereRadius;
const float d = b * b - 4 * a * c;
// TODODEPTH investigate why this triggers in sphere sweep, re-enable
// assert(d >= 0.f /* if failing, it is likely that radius is smaller than getInputMinimumRigSphereRadius() */);
const float lambda = (d >= 0.f) ? (-b + sqrtf_vs(d)) / (2 * a) : 1.f;
pt = camcenterpt + lambda * ray;
}
// TODODEPTH investigate why this triggers in sphere sweep, re-enable
// assert(
// std::abs(length(pt) - rigSphereRadius) < 1e-3f ||
// (pt.x == INVALID_INVERSE_DISTORTION && pt.y == INVALID_INVERSE_DISTORTION && pt.z == INVALID_INVERSE_DISTORTION));
return pt;
}
__device__ float3 FUNCTION_NAME_4(mapInputToRigSpherical,
fromInputToSphere,
inverseDistortionMetersTransform,
inverseRadialPixelsTransform)(float2 uv,
const vsfloat3x4 poseInverse,
const float rigSphereRadius,
const float2 inputScale,
const vsDistortion distortion,
const float2 centerShift) const_member {
float3 pt = FUNCTION_NAME_4(mapInputToCameraSphere, fromInputToSphere, inverseDistortionMetersTransform,
inverseRadialPixelsTransform)(uv, inputScale, distortion, centerShift);
RETURN_3D_IF_INVALID_INVERSE_3D(pt)
/** Transform camera to rig */
pt = transformSphere(pt, poseInverse);
pt = FUNCTION_NAME_4(tracePointToRigSphere, fromInputToSphere, inverseDistortionMetersTransform,
inverseRadialPixelsTransform)(pt, poseInverse, rigSphereRadius);
return pt;
}
__device__ float2 FUNCTION_NAME_4(mapInputToPanorama,
fromInputToSphere,
inverseDistortionMetersTransform,
inverseRadialPixelsTransform)(float2 uv,
const float2 panoScale,
const vsfloat3x4 poseInverse,
const float rigSphereRadius,
const float2 inputScale,
const vsDistortion distortion,
const float2 centerShift) const_member {
const float3 pt = FUNCTION_NAME_4(mapInputToRigSpherical, fromInputToSphere, inverseDistortionMetersTransform,
inverseRadialPixelsTransform)(uv, poseInverse, rigSphereRadius, inputScale,
distortion, centerShift);
RETURN_2D_IF_INVALID_INVERSE_3D(pt)
/** From spherical to output space */
uv = fromSphereToOutput(pt);
/** From output space to normalized space */
uv *= panoScale;
return uv;
}