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