PBRT
|
00001 00002 // 00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 00036 #ifndef INCLUDED_IMF_ENVMAP_H 00037 #define INCLUDED_IMF_ENVMAP_H 00038 00039 //----------------------------------------------------------------------------- 00040 // 00041 // Environment maps 00042 // 00043 // Environment maps define a mapping from 3D directions to 2D 00044 // pixel space locations. Environment maps are typically used 00045 // in 3D rendering, for effects such as quickly approximating 00046 // how shiny surfaces reflect their environment. 00047 // 00048 // Environment maps can be stored in scanline-based or in tiled 00049 // OpenEXR files. The fact that an image is an environment map 00050 // is indicated by the presence of an EnvmapAttribute whose name 00051 // is "envmap". (Convenience functions to access this attribute 00052 // are defined in header file ImfStandardAttributes.h.) 00053 // The attribute's value defines the mapping from 3D directions 00054 // to 2D pixel space locations. 00055 // 00056 // This header file defines the set of possible EnvmapAttribute 00057 // values. 00058 // 00059 // For each possible EnvmapAttribute value, this header file also 00060 // defines a set of convienience functions to convert between 3D 00061 // directions and 2D pixel locations. 00062 // 00063 // Most of the convenience functions defined below require a 00064 // dataWindow parameter. For scanline-based images, and for 00065 // tiled images with level mode ONE_LEVEL, the dataWindow 00066 // parameter should be set to the image's data window, as 00067 // defined in the image header. For tiled images with level 00068 // mode MIPMAP_LEVELS or RIPMAP_LEVELS, the data window of the 00069 // image level that is being accessed should be used instead. 00070 // (See the dataWindowForLevel() methods in ImfTiledInputFile.h 00071 // and ImfTiledOutputFile.h.) 00072 // 00073 //----------------------------------------------------------------------------- 00074 00075 #include "ImathBox.h" 00076 00077 namespace Imf { 00078 00079 //-------------------------------- 00080 // Supported environment map types 00081 //-------------------------------- 00082 00083 enum Envmap 00084 { 00085 ENVMAP_LATLONG = 0, // Latitude-longitude environment map 00086 ENVMAP_CUBE = 1, // Cube map 00087 00088 NUM_ENVMAPTYPES // Number of different environment map types 00089 }; 00090 00091 00092 //------------------------------------------------------------------------- 00093 // Latitude-Longitude Map: 00094 // 00095 // The environment is projected onto the image using polar coordinates 00096 // (latitude and longitude). A pixel's x coordinate corresponds to 00097 // its longitude, and the y coordinate corresponds to its latitude. 00098 // Pixel (dataWindow.min.x, dataWindow.min.y) has latitude +pi/2 and 00099 // longitude +pi; pixel (dataWindow.max.x, dataWindow.max.y) has 00100 // latitude -pi/2 and longitude -pi. 00101 // 00102 // In 3D space, latitudes -pi/2 and +pi/2 correspond to the negative and 00103 // positive y direction. Latitude 0, longitude 0 points into positive 00104 // z direction; and latitude 0, longitude pi/2 points into positive x 00105 // direction. 00106 // 00107 // The size of the data window should be 2*N by N pixels (width by height), 00108 // where N can be any integer greater than 0. 00109 //------------------------------------------------------------------------- 00110 00111 namespace LatLongMap 00112 { 00113 //---------------------------------------------------- 00114 // Convert a 3D direction to a 2D vector whose x and y 00115 // components represent the corresponding latitude 00116 // and longitude. 00117 //---------------------------------------------------- 00118 00119 Imath::V2f latLong (const Imath::V3f &direction); 00120 00121 00122 //-------------------------------------------------------- 00123 // Convert the position of a pixel to a 2D vector whose 00124 // x and y components represent the corresponding latitude 00125 // and longitude. 00126 //-------------------------------------------------------- 00127 00128 Imath::V2f latLong (const Imath::Box2i &dataWindow, 00129 const Imath::V2f &pixelPosition); 00130 00131 00132 //------------------------------------------------------------- 00133 // Convert a 2D vector, whose x and y components represent 00134 // longitude and latitude, into a corresponding pixel position. 00135 //------------------------------------------------------------- 00136 00137 Imath::V2f pixelPosition (const Imath::Box2i &dataWindow, 00138 const Imath::V2f &latLong); 00139 00140 00141 //----------------------------------------------------- 00142 // Convert a 3D direction vector into a corresponding 00143 // pixel position. pixelPosition(dw,dir) is equivalent 00144 // to pixelPosition(dw,latLong(dw,dir)). 00145 //----------------------------------------------------- 00146 00147 Imath::V2f pixelPosition (const Imath::Box2i &dataWindow, 00148 const Imath::V3f &direction); 00149 00150 00151 //-------------------------------------------------------- 00152 // Convert the position of a pixel in a latitude-longitude 00153 // map into a corresponding 3D direction. 00154 //-------------------------------------------------------- 00155 00156 Imath::V3f direction (const Imath::Box2i &dataWindow, 00157 const Imath::V2f &pixelPosition); 00158 } 00159 00160 00161 //-------------------------------------------------------------- 00162 // Cube Map: 00163 // 00164 // The environment is projected onto the six faces of an 00165 // axis-aligned cube. The cube's faces are then arranged 00166 // in a 2D image as shown below. 00167 // 00168 // 2-----------3 00169 // / /| 00170 // / / | Y 00171 // / / | | 00172 // 6-----------7 | | 00173 // | | | | 00174 // | | | | 00175 // | 0 | 1 *------- X 00176 // | | / / 00177 // | | / / 00178 // | |/ / 00179 // 4-----------5 Z 00180 // 00181 // dataWindow.min 00182 // / 00183 // / 00184 // +-----------+ 00185 // |3 Y 7| 00186 // | | | 00187 // | | | 00188 // | ---+---Z | +X face 00189 // | | | 00190 // | | | 00191 // |1 5| 00192 // +-----------+ 00193 // |6 Y 2| 00194 // | | | 00195 // | | | 00196 // | Z---+--- | -X face 00197 // | | | 00198 // | | | 00199 // |4 0| 00200 // +-----------+ 00201 // |6 Z 7| 00202 // | | | 00203 // | | | 00204 // | ---+---X | +Y face 00205 // | | | 00206 // | | | 00207 // |2 3| 00208 // +-----------+ 00209 // |0 1| 00210 // | | | 00211 // | | | 00212 // | ---+---X | -Y face 00213 // | | | 00214 // | | | 00215 // |4 Z 5| 00216 // +-----------+ 00217 // |7 Y 6| 00218 // | | | 00219 // | | | 00220 // | X---+--- | +Z face 00221 // | | | 00222 // | | | 00223 // |5 4| 00224 // +-----------+ 00225 // |2 Y 3| 00226 // | | | 00227 // | | | 00228 // | ---+---X | -Z face 00229 // | | | 00230 // | | | 00231 // |0 1| 00232 // +-----------+ 00233 // / 00234 // / 00235 // dataWindow.max 00236 // 00237 // The size of the data window should be N by 6*N pixels 00238 // (width by height), where N can be any integer greater 00239 // than 0. 00240 // 00241 //-------------------------------------------------------------- 00242 00243 //------------------------------------ 00244 // Names for the six faces of the cube 00245 //------------------------------------ 00246 00247 enum CubeMapFace 00248 { 00249 CUBEFACE_POS_X, // +X face 00250 CUBEFACE_NEG_X, // -X face 00251 CUBEFACE_POS_Y, // +Y face 00252 CUBEFACE_NEG_Y, // -Y face 00253 CUBEFACE_POS_Z, // +Z face 00254 CUBEFACE_NEG_Z // -Z face 00255 }; 00256 00257 namespace CubeMap 00258 { 00259 //--------------------------------------------- 00260 // Width and height of a cube's face, in pixels 00261 //--------------------------------------------- 00262 00263 int sizeOfFace (const Imath::Box2i &dataWindow); 00264 00265 00266 //------------------------------------------ 00267 // Compute the region in the environment map 00268 // that is covered by the specified face. 00269 //------------------------------------------ 00270 00271 Imath::Box2i dataWindowForFace (CubeMapFace face, 00272 const Imath::Box2i &dataWindow); 00273 00274 00275 //---------------------------------------------------- 00276 // Convert the coordinates of a pixel within a face 00277 // [in the range from (0,0) to (s-1,s-1), where 00278 // s == sizeOfFace(dataWindow)] to pixel coordinates 00279 // in the environment map. 00280 //---------------------------------------------------- 00281 00282 Imath::V2f pixelPosition (CubeMapFace face, 00283 const Imath::Box2i &dataWindow, 00284 Imath::V2f positionInFace); 00285 00286 00287 //-------------------------------------------------------------- 00288 // Convert a 3D direction into a cube face, and a pixel position 00289 // within that face. 00290 // 00291 // If you have a 3D direction, dir, the following code fragment 00292 // finds the position, pos, of the corresponding pixel in an 00293 // environment map with data window dw: 00294 // 00295 // CubeMapFace f; 00296 // V2f pif, pos; 00297 // 00298 // faceAndPixelPosition (dir, dw, f, pif); 00299 // pos = pixelPosition (f, dw, pif); 00300 // 00301 //-------------------------------------------------------------- 00302 00303 void faceAndPixelPosition (const Imath::V3f &direction, 00304 const Imath::Box2i &dataWindow, 00305 CubeMapFace &face, 00306 Imath::V2f &positionInFace); 00307 00308 00309 // -------------------------------------------------------- 00310 // Given a cube face and a pixel position within that face, 00311 // compute the corresponding 3D direction. 00312 // -------------------------------------------------------- 00313 00314 Imath::V3f direction (CubeMapFace face, 00315 const Imath::Box2i &dataWindow, 00316 const Imath::V2f &positionInFace); 00317 } 00318 00319 00320 } // namespace Imf 00321 00322 #endif