1 ///////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6 // All rights reserved.
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
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
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.
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.
33 ///////////////////////////////////////////////////////////////////////////
36 #ifndef INCLUDED_IMF_ENVMAP_H
37 #define INCLUDED_IMF_ENVMAP_H
39 //-----------------------------------------------------------------------------
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.
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.
56 // This header file defines the set of possible EnvmapAttribute
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.
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.)
73 //-----------------------------------------------------------------------------
79 //--------------------------------
80 // Supported environment map types
81 //--------------------------------
85 ENVMAP_LATLONG = 0, // Latitude-longitude environment map
86 ENVMAP_CUBE = 1, // Cube map
88 NUM_ENVMAPTYPES // Number of different environment map types
92 //-------------------------------------------------------------------------
93 // Latitude-Longitude Map:
95 // The environment is projected onto the image using polar coordinates
96 // (latitude and longitude). A pixel's x coordinate corresponds to
97 // its longitude, and the y coordinate corresponds to its latitude.
98 // Pixel (dataWindow.min.x, dataWindow.min.y) has latitude +pi/2 and
99 // longitude +pi; pixel (dataWindow.max.x, dataWindow.max.y) has
100 // latitude -pi/2 and longitude -pi.
102 // In 3D space, latitudes -pi/2 and +pi/2 correspond to the negative and
103 // positive y direction. Latitude 0, longitude 0 points into positive
104 // z direction; and latitude 0, longitude pi/2 points into positive x
107 // The size of the data window should be 2*N by N pixels (width by height),
108 // where N can be any integer greater than 0.
109 //-------------------------------------------------------------------------
113 //----------------------------------------------------
114 // Convert a 3D direction to a 2D vector whose x and y
115 // components represent the corresponding latitude
117 //----------------------------------------------------
119 Imath::V2f latLong (const Imath::V3f &direction);
122 //--------------------------------------------------------
123 // Convert the position of a pixel to a 2D vector whose
124 // x and y components represent the corresponding latitude
126 //--------------------------------------------------------
128 Imath::V2f latLong (const Imath::Box2i &dataWindow,
129 const Imath::V2f &pixelPosition);
132 //-------------------------------------------------------------
133 // Convert a 2D vector, whose x and y components represent
134 // longitude and latitude, into a corresponding pixel position.
135 //-------------------------------------------------------------
137 Imath::V2f pixelPosition (const Imath::Box2i &dataWindow,
138 const Imath::V2f &latLong);
141 //-----------------------------------------------------
142 // Convert a 3D direction vector into a corresponding
143 // pixel position. pixelPosition(dw,dir) is equivalent
144 // to pixelPosition(dw,latLong(dw,dir)).
145 //-----------------------------------------------------
147 Imath::V2f pixelPosition (const Imath::Box2i &dataWindow,
148 const Imath::V3f &direction);
151 //--------------------------------------------------------
152 // Convert the position of a pixel in a latitude-longitude
153 // map into a corresponding 3D direction.
154 //--------------------------------------------------------
156 Imath::V3f direction (const Imath::Box2i &dataWindow,
157 const Imath::V2f &pixelPosition);
161 //--------------------------------------------------------------
164 // The environment is projected onto the six faces of an
165 // axis-aligned cube. The cube's faces are then arranged
166 // in a 2D image as shown below.
175 // | 0 | 1 *------- X
188 // | ---+---Z | +X face
196 // | Z---+--- | -X face
204 // | ---+---X | +Y face
212 // | ---+---X | -Y face
220 // | X---+--- | +Z face
228 // | ---+---X | -Z face
237 // The size of the data window should be N by 6*N pixels
238 // (width by height), where N can be any integer greater
241 //--------------------------------------------------------------
243 //------------------------------------
244 // Names for the six faces of the cube
245 //------------------------------------
249 CUBEFACE_POS_X, // +X face
250 CUBEFACE_NEG_X, // -X face
251 CUBEFACE_POS_Y, // +Y face
252 CUBEFACE_NEG_Y, // -Y face
253 CUBEFACE_POS_Z, // +Z face
254 CUBEFACE_NEG_Z, // -Z face
259 //---------------------------------------------
260 // Width and height of a cube's face, in pixels
261 //---------------------------------------------
263 int sizeOfFace (const Imath::Box2i &dataWindow);
266 //------------------------------------------
267 // Compute the region in the environment map
268 // that is covered by the specified face.
269 //------------------------------------------
271 Imath::Box2i dataWindowForFace (CubeMapFace face,
272 const Imath::Box2i &dataWindow);
275 //----------------------------------------------------
276 // Convert the coordinates of a pixel within a face
277 // [in the range from (0,0) to (s-1,s-1), where
278 // s == sizeOfFace(dataWindow)] to pixel coordinates
279 // in the environment map.
280 //----------------------------------------------------
282 Imath::V2f pixelPosition (CubeMapFace face,
283 const Imath::Box2i &dataWindow,
284 Imath::V2f positionInFace);
287 //--------------------------------------------------------------
288 // Convert a 3D direction into a cube face, and a pixel position
291 // If you have a 3D direction, dir, the following code fragment
292 // finds the position, pos, of the corresponding pixel in an
293 // environment map with data window dw:
298 // faceAndPixelPosition (dir, dw, f, pif);
299 // pos = pixelPosition (f, dw, pif);
301 //--------------------------------------------------------------
303 void faceAndPixelPosition (const Imath::V3f &direction,
304 const Imath::Box2i &dataWindow,
306 Imath::V2f &positionInFace);
309 // --------------------------------------------------------
310 // Given a cube face and a pixel position within that face,
311 // compute the corresponding 3D direction.
312 // --------------------------------------------------------
314 Imath::V3f direction (CubeMapFace face,
315 const Imath::Box2i &dataWindow,
316 const Imath::V2f &positionInFace);