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#ifndef INCLUDED_IMF_ENVMAP_H
37#define INCLUDED_IMF_ENVMAP_H
38
39//-----------------------------------------------------------------------------
40//
41// Environment maps
42//
43// Environment maps define a mapping from 3D directions to 2D
44// pixel space locations. Environment maps are typically used
45// in 3D rendering, for effects such as quickly approximating
46// how shiny surfaces reflect their environment.
47//
48// Environment maps can be stored in scanline-based or in tiled
49// OpenEXR files. The fact that an image is an environment map
50// is indicated by the presence of an EnvmapAttribute whose name
51// is "envmap". (Convenience functions to access this attribute
52// are defined in header file ImfStandardAttributes.h.)
53// The attribute's value defines the mapping from 3D directions
54// to 2D pixel space locations.
55//
56// This header file defines the set of possible EnvmapAttribute
57// values.
58//
59// For each possible EnvmapAttribute value, this header file also
60// defines a set of convienience functions to convert between 3D
61// directions and 2D pixel locations.
62//
63// Most of the convenience functions defined below require a
64// dataWindow parameter. For scanline-based images, and for
65// tiled images with level mode ONE_LEVEL, the dataWindow
66// parameter should be set to the image's data window, as
67// defined in the image header. For tiled images with level
68// mode MIPMAP_LEVELS or RIPMAP_LEVELS, the data window of the
69// image level that is being accessed should be used instead.
70// (See the dataWindowForLevel() methods in ImfTiledInputFile.h
71// and ImfTiledOutputFile.h.)
72//
73//-----------------------------------------------------------------------------
74
75#include "ImathBox.h"
76#include "ImfNamespace.h"
77#include "ImfExport.h"
78
79
80OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
81
82//--------------------------------
83// Supported environment map types
84//--------------------------------
85
86enum Envmap
87{
88 ENVMAP_LATLONG = 0, // Latitude-longitude environment map
89 ENVMAP_CUBE = 1, // Cube map
90
91 NUM_ENVMAPTYPES // Number of different environment map types
92};
93
94
95//-------------------------------------------------------------------------
96// Latitude-Longitude Map:
97//
98// The environment is projected onto the image using polar coordinates
99// (latitude and longitude). A pixel's x coordinate corresponds to
100// its longitude, and the y coordinate corresponds to its latitude.
101// Pixel (dataWindow.min.x, dataWindow.min.y) has latitude +pi/2 and
102// longitude +pi; pixel (dataWindow.max.x, dataWindow.max.y) has
103// latitude -pi/2 and longitude -pi.
104//
105// In 3D space, latitudes -pi/2 and +pi/2 correspond to the negative and
106// positive y direction. Latitude 0, longitude 0 points into positive
107// z direction; and latitude 0, longitude pi/2 points into positive x
108// direction.
109//
110// The size of the data window should be 2*N by N pixels (width by height),
111// where N can be any integer greater than 0.
112//-------------------------------------------------------------------------
113
114namespace LatLongMap
115{
116 //----------------------------------------------------
117 // Convert a 3D direction to a 2D vector whose x and y
118 // components represent the corresponding latitude
119 // and longitude.
120 //----------------------------------------------------
121
122 IMF_EXPORT
123 IMATH_NAMESPACE::V2f latLong (const IMATH_NAMESPACE::V3f &direction);
124
125
126 //--------------------------------------------------------
127 // Convert the position of a pixel to a 2D vector whose
128 // x and y components represent the corresponding latitude
129 // and longitude.
130 //--------------------------------------------------------
131
132 IMF_EXPORT
133 IMATH_NAMESPACE::V2f latLong (const IMATH_NAMESPACE::Box2i &dataWindow,
134 const IMATH_NAMESPACE::V2f &pixelPosition);
135
136
137 //-------------------------------------------------------------
138 // Convert a 2D vector, whose x and y components represent
139 // longitude and latitude, into a corresponding pixel position.
140 //-------------------------------------------------------------
141
142 IMF_EXPORT
143 IMATH_NAMESPACE::V2f pixelPosition (const IMATH_NAMESPACE::Box2i &dataWindow,
144 const IMATH_NAMESPACE::V2f &latLong);
145
146
147 //-----------------------------------------------------
148 // Convert a 3D direction vector into a corresponding
149 // pixel position. pixelPosition(dw,dir) is equivalent
150 // to pixelPosition(dw,latLong(dw,dir)).
151 //-----------------------------------------------------
152
153 IMF_EXPORT
154 IMATH_NAMESPACE::V2f pixelPosition (const IMATH_NAMESPACE::Box2i &dataWindow,
155 const IMATH_NAMESPACE::V3f &direction);
156
157
158 //--------------------------------------------------------
159 // Convert the position of a pixel in a latitude-longitude
160 // map into a corresponding 3D direction.
161 //--------------------------------------------------------
162
163 IMF_EXPORT
164 IMATH_NAMESPACE::V3f direction (const IMATH_NAMESPACE::Box2i &dataWindow,
165 const IMATH_NAMESPACE::V2f &pixelPosition);
166}
167
168
169//--------------------------------------------------------------
170// Cube Map:
171//
172// The environment is projected onto the six faces of an
173// axis-aligned cube. The cube's faces are then arranged
174// in a 2D image as shown below.
175//
176// 2-----------3
177// / /|
178// / / | Y
179// / / | |
180// 6-----------7 | |
181// | | | |
182// | | | |
183// | 0 | 1 *------- X
184// | | / /
185// | | / /
186// | |/ /
187// 4-----------5 Z
188//
189// dataWindow.min
190// /
191// /
192// +-----------+
193// |3 Y 7|
194// | | |
195// | | |
196// | ---+---Z | +X face
197// | | |
198// | | |
199// |1 5|
200// +-----------+
201// |6 Y 2|
202// | | |
203// | | |
204// | Z---+--- | -X face
205// | | |
206// | | |
207// |4 0|
208// +-----------+
209// |6 Z 7|
210// | | |
211// | | |
212// | ---+---X | +Y face
213// | | |
214// | | |
215// |2 3|
216// +-----------+
217// |0 1|
218// | | |
219// | | |
220// | ---+---X | -Y face
221// | | |
222// | | |
223// |4 Z 5|
224// +-----------+
225// |7 Y 6|
226// | | |
227// | | |
228// | X---+--- | +Z face
229// | | |
230// | | |
231// |5 4|
232// +-----------+
233// |2 Y 3|
234// | | |
235// | | |
236// | ---+---X | -Z face
237// | | |
238// | | |
239// |0 1|
240// +-----------+
241// /
242// /
243// dataWindow.max
244//
245// The size of the data window should be N by 6*N pixels
246// (width by height), where N can be any integer greater
247// than 0.
248//
249//--------------------------------------------------------------
250
251//------------------------------------
252// Names for the six faces of the cube
253//------------------------------------
254
255enum CubeMapFace
256{
257 CUBEFACE_POS_X, // +X face
258 CUBEFACE_NEG_X, // -X face
259 CUBEFACE_POS_Y, // +Y face
260 CUBEFACE_NEG_Y, // -Y face
261 CUBEFACE_POS_Z, // +Z face
262 CUBEFACE_NEG_Z // -Z face
263};
264
265namespace CubeMap
266{
267 //---------------------------------------------
268 // Width and height of a cube's face, in pixels
269 //---------------------------------------------
270
271 IMF_EXPORT
272 int sizeOfFace (const IMATH_NAMESPACE::Box2i &dataWindow);
273
274
275 //------------------------------------------
276 // Compute the region in the environment map
277 // that is covered by the specified face.
278 //------------------------------------------
279
280 IMF_EXPORT
281 IMATH_NAMESPACE::Box2i dataWindowForFace (CubeMapFace face,
282 const IMATH_NAMESPACE::Box2i &dataWindow);
283
284
285 //----------------------------------------------------
286 // Convert the coordinates of a pixel within a face
287 // [in the range from (0,0) to (s-1,s-1), where
288 // s == sizeOfFace(dataWindow)] to pixel coordinates
289 // in the environment map.
290 //----------------------------------------------------
291
292 IMF_EXPORT
293 IMATH_NAMESPACE::V2f pixelPosition (CubeMapFace face,
294 const IMATH_NAMESPACE::Box2i &dataWindow,
295 IMATH_NAMESPACE::V2f positionInFace);
296
297
298 //--------------------------------------------------------------
299 // Convert a 3D direction into a cube face, and a pixel position
300 // within that face.
301 //
302 // If you have a 3D direction, dir, the following code fragment
303 // finds the position, pos, of the corresponding pixel in an
304 // environment map with data window dw:
305 //
306 // CubeMapFace f;
307 // V2f pif, pos;
308 //
309 // faceAndPixelPosition (dir, dw, f, pif);
310 // pos = pixelPosition (f, dw, pif);
311 //
312 //--------------------------------------------------------------
313
314 IMF_EXPORT
315 void faceAndPixelPosition (const IMATH_NAMESPACE::V3f &direction,
316 const IMATH_NAMESPACE::Box2i &dataWindow,
317 CubeMapFace &face,
318 IMATH_NAMESPACE::V2f &positionInFace);
319
320
321 // --------------------------------------------------------
322 // Given a cube face and a pixel position within that face,
323 // compute the corresponding 3D direction.
324 // --------------------------------------------------------
325
326 IMF_EXPORT
327 IMATH_NAMESPACE::V3f direction (CubeMapFace face,
328 const IMATH_NAMESPACE::Box2i &dataWindow,
329 const IMATH_NAMESPACE::V2f &positionInFace);
330}
331
332
333OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
334
335
336#endif
337