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 77namespace Imf { 78 79//-------------------------------- 80// Supported environment map types 81//-------------------------------- 82 83enum 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 111namespace 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 247enum 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 257namespace 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