Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/openexr/IlmImf/ImfEnvmap.cpp
16337 views
1
///////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
4
// Digital Ltd. LLC
5
//
6
// All rights reserved.
7
//
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
10
// met:
11
// * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the following disclaimer.
13
// * Redistributions in binary form must reproduce the above
14
// copyright notice, this list of conditions and the following disclaimer
15
// in the documentation and/or other materials provided with the
16
// distribution.
17
// * Neither the name of Industrial Light & Magic nor the names of
18
// its contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
20
//
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
//
33
///////////////////////////////////////////////////////////////////////////
34
35
36
//-----------------------------------------------------------------------------
37
//
38
// Environment maps
39
//
40
//-----------------------------------------------------------------------------
41
42
#include <ImfEnvmap.h>
43
#include "ImathFun.h"
44
#include <algorithm>
45
#include <math.h>
46
47
using namespace std;
48
using namespace Imath;
49
50
namespace Imf {
51
namespace LatLongMap {
52
53
V2f
54
latLong (const V3f &dir)
55
{
56
float r = sqrt (dir.z * dir.z + dir.x * dir.x);
57
58
float latitude = (r < abs (dir.y))?
59
acos (r / dir.length()) * sign (dir.y):
60
asin (dir.y / dir.length());
61
62
float longitude = (dir.z == 0 && dir.x == 0)? 0: atan2 (dir.x, dir.z);
63
64
return V2f (latitude, longitude);
65
}
66
67
68
V2f
69
latLong (const Box2i &dataWindow, const V2f &pixelPosition)
70
{
71
float latitude, longitude;
72
73
if (dataWindow.max.y > dataWindow.min.y)
74
{
75
latitude = -M_PI *
76
((pixelPosition.y - dataWindow.min.y) /
77
(dataWindow.max.y - dataWindow.min.y) - 0.5f);
78
}
79
else
80
{
81
latitude = 0;
82
}
83
84
if (dataWindow.max.x > dataWindow.min.x)
85
{
86
longitude = -2 * M_PI *
87
((pixelPosition.x - dataWindow.min.x) /
88
(dataWindow.max.x - dataWindow.min.x) - 0.5f);
89
}
90
else
91
{
92
longitude = 0;
93
}
94
95
return V2f (latitude, longitude);
96
}
97
98
99
V2f
100
pixelPosition (const Box2i &dataWindow, const V2f &latLong)
101
{
102
float x = latLong.y / (-2 * M_PI) + 0.5f;
103
float y = latLong.x / -M_PI + 0.5f;
104
105
return V2f (x * (dataWindow.max.x - dataWindow.min.x) + dataWindow.min.x,
106
y * (dataWindow.max.y - dataWindow.min.y) + dataWindow.min.y);
107
}
108
109
110
V2f
111
pixelPosition (const Box2i &dataWindow, const V3f &direction)
112
{
113
return pixelPosition (dataWindow, latLong (direction));
114
}
115
116
117
V3f
118
direction (const Box2i &dataWindow, const V2f &pixelPosition)
119
{
120
V2f ll = latLong (dataWindow, pixelPosition);
121
122
return V3f (sin (ll.y) * cos (ll.x),
123
sin (ll.x),
124
cos (ll.y) * cos (ll.x));
125
}
126
127
} // namespace LatLongMap
128
129
130
namespace CubeMap {
131
132
int
133
sizeOfFace (const Box2i &dataWindow)
134
{
135
return min ((dataWindow.max.x - dataWindow.min.x + 1),
136
(dataWindow.max.y - dataWindow.min.y + 1) / 6);
137
}
138
139
140
Box2i
141
dataWindowForFace (CubeMapFace face, const Box2i &dataWindow)
142
{
143
int sof = sizeOfFace (dataWindow);
144
Box2i dwf;
145
146
dwf.min.x = 0;
147
dwf.min.y = int (face) * sof;
148
149
dwf.max.x = dwf.min.x + sof - 1;
150
dwf.max.y = dwf.min.y + sof - 1;
151
152
return dwf;
153
}
154
155
156
V2f
157
pixelPosition (CubeMapFace face, const Box2i &dataWindow, V2f positionInFace)
158
{
159
Box2i dwf = dataWindowForFace (face, dataWindow);
160
V2f pos (0, 0);
161
162
switch (face)
163
{
164
case CUBEFACE_POS_X:
165
166
pos.x = dwf.min.x + positionInFace.y;
167
pos.y = dwf.max.y - positionInFace.x;
168
break;
169
170
case CUBEFACE_NEG_X:
171
172
pos.x = dwf.max.x - positionInFace.y;
173
pos.y = dwf.max.y - positionInFace.x;
174
break;
175
176
case CUBEFACE_POS_Y:
177
178
pos.x = dwf.min.x + positionInFace.x;
179
pos.y = dwf.max.y - positionInFace.y;
180
break;
181
182
case CUBEFACE_NEG_Y:
183
184
pos.x = dwf.min.x + positionInFace.x;
185
pos.y = dwf.min.y + positionInFace.y;
186
break;
187
188
case CUBEFACE_POS_Z:
189
190
pos.x = dwf.max.x - positionInFace.x;
191
pos.y = dwf.max.y - positionInFace.y;
192
break;
193
194
case CUBEFACE_NEG_Z:
195
196
pos.x = dwf.min.x + positionInFace.x;
197
pos.y = dwf.max.y - positionInFace.y;
198
break;
199
}
200
201
return pos;
202
}
203
204
205
void
206
faceAndPixelPosition (const V3f &direction,
207
const Box2i &dataWindow,
208
CubeMapFace &face,
209
V2f &pif)
210
{
211
int sof = sizeOfFace (dataWindow);
212
float absx = abs (direction.x);
213
float absy = abs (direction.y);
214
float absz = abs (direction.z);
215
216
if (absx >= absy && absx >= absz)
217
{
218
if (absx == 0)
219
{
220
//
221
// Special case - direction is (0, 0, 0)
222
//
223
224
face = CUBEFACE_POS_X;
225
pif = V2f (0, 0);
226
return;
227
}
228
229
pif.x = (direction.y / absx + 1) / 2 * (sof - 1);
230
pif.y = (direction.z / absx + 1) / 2 * (sof - 1);
231
232
if (direction.x > 0)
233
face = CUBEFACE_POS_X;
234
else
235
face = CUBEFACE_NEG_X;
236
}
237
else if (absy >= absz)
238
{
239
pif.x = (direction.x / absy + 1) / 2 * (sof - 1);
240
pif.y = (direction.z / absy + 1) / 2 * (sof - 1);
241
242
if (direction.y > 0)
243
face = CUBEFACE_POS_Y;
244
else
245
face = CUBEFACE_NEG_Y;
246
}
247
else
248
{
249
pif.x = (direction.x / absz + 1) / 2 * (sof - 1);
250
pif.y = (direction.y / absz + 1) / 2 * (sof - 1);
251
252
if (direction.z > 0)
253
face = CUBEFACE_POS_Z;
254
else
255
face = CUBEFACE_NEG_Z;
256
}
257
}
258
259
260
V3f
261
direction (CubeMapFace face, const Box2i &dataWindow, const V2f &positionInFace)
262
{
263
int sof = sizeOfFace (dataWindow);
264
265
V2f pos;
266
267
if (sof > 1)
268
{
269
pos = V2f (positionInFace.x / (sof - 1) * 2 - 1,
270
positionInFace.y / (sof - 1) * 2 - 1);
271
}
272
else
273
{
274
pos = V2f (0, 0);
275
}
276
277
V3f dir (1, 0, 0);
278
279
switch (face)
280
{
281
case CUBEFACE_POS_X:
282
283
dir.x = 1;
284
dir.y = pos.x;
285
dir.z = pos.y;
286
break;
287
288
case CUBEFACE_NEG_X:
289
290
dir.x = -1;
291
dir.y = pos.x;
292
dir.z = pos.y;
293
break;
294
295
case CUBEFACE_POS_Y:
296
297
dir.x = pos.x;
298
dir.y = 1;
299
dir.z = pos.y;
300
break;
301
302
case CUBEFACE_NEG_Y:
303
304
dir.x = pos.x;
305
dir.y = -1;
306
dir.z = pos.y;
307
break;
308
309
case CUBEFACE_POS_Z:
310
311
dir.x = pos.x;
312
dir.y = pos.y;
313
dir.z = 1;
314
break;
315
316
case CUBEFACE_NEG_Z:
317
318
dir.x = pos.x;
319
dir.y = pos.y;
320
dir.z = -1;
321
break;
322
}
323
324
return dir;
325
}
326
327
} // namespace CubeMap
328
} // namespace Imf
329
330