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 
77 namespace Imf {
78 
79 //--------------------------------
80 // Supported environment map types
81 //--------------------------------
82 
83 enum Envmap
84 {
85     ENVMAP_LATLONG = 0,		// Latitude-longitude environment map
86     ENVMAP_CUBE = 1,		// Cube map
87 
88     NUM_ENVMAPTYPES		// Number of different environment map types
89 };
90 
91 
92 //-------------------------------------------------------------------------
93 // Latitude-Longitude Map:
94 //
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.
101 //
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
105 // direction.
106 //
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 //-------------------------------------------------------------------------
110 
111 namespace LatLongMap
112 {
113     //----------------------------------------------------
114     // Convert a 3D direction to a 2D vector whose x and y
115     // components represent the corresponding latitude
116     // and longitude.
117     //----------------------------------------------------
118 
119     Imath::V2f		latLong (const Imath::V3f &direction);
120 
121 
122     //--------------------------------------------------------
123     // Convert the position of a pixel to a 2D vector whose
124     // x and y components represent the corresponding latitude
125     // and longitude.
126     //--------------------------------------------------------
127 
128     Imath::V2f		latLong (const Imath::Box2i &dataWindow,
129                  const Imath::V2f &pixelPosition);
130 
131 
132     //-------------------------------------------------------------
133     // Convert a 2D vector, whose x and y components represent
134     // longitude and latitude, into a corresponding pixel position.
135     //-------------------------------------------------------------
136 
137     Imath::V2f		pixelPosition (const Imath::Box2i &dataWindow,
138                        const Imath::V2f &latLong);
139 
140 
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     //-----------------------------------------------------
146 
147     Imath::V2f		pixelPosition (const Imath::Box2i &dataWindow,
148                        const Imath::V3f &direction);
149 
150 
151     //--------------------------------------------------------
152     // Convert the position of a pixel in a latitude-longitude
153     // map into a corresponding 3D direction.
154     //--------------------------------------------------------
155 
156     Imath::V3f		direction (const Imath::Box2i &dataWindow,
157                    const Imath::V2f &pixelPosition);
158 }
159 
160 
161 //--------------------------------------------------------------
162 // Cube Map:
163 //
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.
167 //
168 //          2-----------3
169 //         /           /|
170 //        /           / |       Y
171 //       /           /  |       |
172 //      6-----------7   |       |
173 //      |           |   |       |
174 //      |           |   |       |
175 //      |   0       |   1       *------- X
176 //      |           |  /       /
177 //      |           | /       /
178 //      |           |/       /
179 //      4-----------5       Z
180 //
181 //   dataWindow.min
182 //        /
183 //       /
184 //      +-----------+
185 //      |3    Y    7|
186 //      |     |     |
187 //      |     |     |
188 //      |  ---+---Z |  +X face
189 //      |     |     |
190 //      |     |     |
191 //      |1         5|
192 //      +-----------+
193 //      |6    Y    2|
194 //      |     |     |
195 //      |     |     |
196 //      | Z---+---  |  -X face
197 //      |     |     |
198 //      |     |     |
199 //      |4         0|
200 //      +-----------+
201 //      |6    Z    7|
202 //      |     |     |
203 //      |     |     |
204 //      |  ---+---X |  +Y face
205 //      |     |     |
206 //      |     |     |
207 //      |2         3|
208 //      +-----------+
209 //      |0         1|
210 //      |     |     |
211 //      |     |     |
212 //      |  ---+---X |  -Y face
213 //      |     |     |
214 //      |     |     |
215 //      |4    Z    5|
216 //      +-----------+
217 //      |7    Y    6|
218 //      |     |     |
219 //      |     |     |
220 //      | X---+---  |  +Z face
221 //      |     |     |
222 //      |     |     |
223 //      |5         4|
224 //      +-----------+
225 //      |2    Y    3|
226 //      |     |     |
227 //      |     |     |
228 //      |  ---+---X |  -Z face
229 //      |     |     |
230 //      |     |     |
231 //      |0         1|
232 //      +-----------+
233 //                 /
234 //                /
235 //          dataWindow.max
236 //
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
239 // than 0.
240 //
241 //--------------------------------------------------------------
242 
243 //------------------------------------
244 // Names for the six faces of the cube
245 //------------------------------------
246 
247 enum CubeMapFace
248 {
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
255 };
256 
257 namespace CubeMap
258 {
259     //---------------------------------------------
260     // Width and height of a cube's face, in pixels
261     //---------------------------------------------
262 
263     int			sizeOfFace (const Imath::Box2i &dataWindow);
264 
265 
266     //------------------------------------------
267     // Compute the region in the environment map
268     // that is covered by the specified face.
269     //------------------------------------------
270 
271     Imath::Box2i	dataWindowForFace (CubeMapFace face,
272                        const Imath::Box2i &dataWindow);
273 
274 
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     //----------------------------------------------------
281 
282     Imath::V2f		pixelPosition (CubeMapFace face,
283                        const Imath::Box2i &dataWindow,
284                        Imath::V2f positionInFace);
285 
286 
287     //--------------------------------------------------------------
288     // Convert a 3D direction into a cube face, and a pixel position
289     // within that face.
290     //
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:
294     //
295     // CubeMapFace f;
296     // V2f pif, pos;
297     //
298     // faceAndPixelPosition (dir, dw, f, pif);
299     // pos = pixelPosition (f, dw, pif);
300     //
301     //--------------------------------------------------------------
302 
303     void		faceAndPixelPosition (const Imath::V3f &direction,
304                           const Imath::Box2i &dataWindow,
305                           CubeMapFace &face,
306                           Imath::V2f &positionInFace);
307 
308 
309     // --------------------------------------------------------
310     // Given a cube face and a pixel position within that face,
311     // compute the corresponding 3D direction.
312     // --------------------------------------------------------
313 
314     Imath::V3f		direction (CubeMapFace face,
315                    const Imath::Box2i &dataWindow,
316                    const Imath::V2f &positionInFace);
317 }
318 
319 
320 } // namespace Imf
321 
322 #endif
323