/////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas // Digital Ltd. LLC // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Industrial Light & Magic nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////// #ifndef INCLUDED_IMF_ENVMAP_H #define INCLUDED_IMF_ENVMAP_H //----------------------------------------------------------------------------- // // Environment maps // // Environment maps define a mapping from 3D directions to 2D // pixel space locations. Environment maps are typically used // in 3D rendering, for effects such as quickly approximating // how shiny surfaces reflect their environment. // // Environment maps can be stored in scanline-based or in tiled // OpenEXR files. The fact that an image is an environment map // is indicated by the presence of an EnvmapAttribute whose name // is "envmap". (Convenience functions to access this attribute // are defined in header file ImfStandardAttributes.h.) // The attribute's value defines the mapping from 3D directions // to 2D pixel space locations. // // This header file defines the set of possible EnvmapAttribute // values. // // For each possible EnvmapAttribute value, this header file also // defines a set of convienience functions to convert between 3D // directions and 2D pixel locations. // // Most of the convenience functions defined below require a // dataWindow parameter. For scanline-based images, and for // tiled images with level mode ONE_LEVEL, the dataWindow // parameter should be set to the image's data window, as // defined in the image header. For tiled images with level // mode MIPMAP_LEVELS or RIPMAP_LEVELS, the data window of the // image level that is being accessed should be used instead. // (See the dataWindowForLevel() methods in ImfTiledInputFile.h // and ImfTiledOutputFile.h.) // //----------------------------------------------------------------------------- #include namespace Imf { //-------------------------------- // Supported environment map types //-------------------------------- enum Envmap { ENVMAP_LATLONG = 0, // Latitude-longitude environment map ENVMAP_CUBE = 1, // Cube map NUM_ENVMAPTYPES // Number of different environment map types }; //------------------------------------------------------------------------- // Latitude-Longitude Map: // // The environment is projected onto the image using polar coordinates // (latitude and longitude). A pixel's x coordinate corresponds to // its longitude, and the y coordinate corresponds to its latitude. // Pixel (dataWindow.min.x, dataWindow.min.y) has latitude +pi/2 and // longitude +pi; pixel (dataWindow.max.x, dataWindow.max.y) has // latitude -pi/2 and longitude -pi. // // In 3D space, latitudes -pi/2 and +pi/2 correspond to the negative and // positive y direction. Latitude 0, longitude 0 points into positive // z direction; and latitude 0, longitude pi/2 points into positive x // direction. // // The size of the data window should be 2*N by N pixels (width by height), // where N can be any integer greater than 0. //------------------------------------------------------------------------- namespace LatLongMap { //---------------------------------------------------- // Convert a 3D direction to a 2D vector whose x and y // components represent the corresponding latitude // and longitude. //---------------------------------------------------- Imath::V2f latLong (const Imath::V3f &direction); //-------------------------------------------------------- // Convert the position of a pixel to a 2D vector whose // x and y components represent the corresponding latitude // and longitude. //-------------------------------------------------------- Imath::V2f latLong (const Imath::Box2i &dataWindow, const Imath::V2f &pixelPosition); //------------------------------------------------------------- // Convert a 2D vector, whose x and y components represent // longitude and latitude, into a corresponding pixel position. //------------------------------------------------------------- Imath::V2f pixelPosition (const Imath::Box2i &dataWindow, const Imath::V2f &latLong); //----------------------------------------------------- // Convert a 3D direction vector into a corresponding // pixel position. pixelPosition(dw,dir) is equivalent // to pixelPosition(dw,latLong(dw,dir)). //----------------------------------------------------- Imath::V2f pixelPosition (const Imath::Box2i &dataWindow, const Imath::V3f &direction); //-------------------------------------------------------- // Convert the position of a pixel in a latitude-longitude // map into a corresponding 3D direction. //-------------------------------------------------------- Imath::V3f direction (const Imath::Box2i &dataWindow, const Imath::V2f &pixelPosition); } //-------------------------------------------------------------- // Cube Map: // // The environment is projected onto the six faces of an // axis-aligned cube. The cube's faces are then arranged // in a 2D image as shown below. // // 2-----------3 // / /| // / / | Y // / / | | // 6-----------7 | | // | | | | // | | | | // | 0 | 1 *------- X // | | / / // | | / / // | |/ / // 4-----------5 Z // // dataWindow.min // / // / // +-----------+ // |3 Y 7| // | | | // | | | // | ---+---Z | +X face // | | | // | | | // |1 5| // +-----------+ // |6 Y 2| // | | | // | | | // | Z---+--- | -X face // | | | // | | | // |4 0| // +-----------+ // |6 Z 7| // | | | // | | | // | ---+---X | +Y face // | | | // | | | // |2 3| // +-----------+ // |0 1| // | | | // | | | // | ---+---X | -Y face // | | | // | | | // |4 Z 5| // +-----------+ // |7 Y 6| // | | | // | | | // | X---+--- | +Z face // | | | // | | | // |5 4| // +-----------+ // |2 Y 3| // | | | // | | | // | ---+---X | -Z face // | | | // | | | // |0 1| // +-----------+ // / // / // dataWindow.max // // The size of the data window should be N by 6*N pixels // (width by height), where N can be any integer greater // than 0. // //-------------------------------------------------------------- //------------------------------------ // Names for the six faces of the cube //------------------------------------ enum CubeMapFace { CUBEFACE_POS_X, // +X face CUBEFACE_NEG_X, // -X face CUBEFACE_POS_Y, // +Y face CUBEFACE_NEG_Y, // -Y face CUBEFACE_POS_Z, // +Z face CUBEFACE_NEG_Z, // -Z face }; namespace CubeMap { //--------------------------------------------- // Width and height of a cube's face, in pixels //--------------------------------------------- int sizeOfFace (const Imath::Box2i &dataWindow); //------------------------------------------ // Compute the region in the environment map // that is covered by the specified face. //------------------------------------------ Imath::Box2i dataWindowForFace (CubeMapFace face, const Imath::Box2i &dataWindow); //---------------------------------------------------- // Convert the coordinates of a pixel within a face // [in the range from (0,0) to (s-1,s-1), where // s == sizeOfFace(dataWindow)] to pixel coordinates // in the environment map. //---------------------------------------------------- Imath::V2f pixelPosition (CubeMapFace face, const Imath::Box2i &dataWindow, Imath::V2f positionInFace); //-------------------------------------------------------------- // Convert a 3D direction into a cube face, and a pixel position // within that face. // // If you have a 3D direction, dir, the following code fragment // finds the position, pos, of the corresponding pixel in an // environment map with data window dw: // // CubeMapFace f; // V2f pif, pos; // // faceAndPixelPosition (dir, dw, f, pif); // pos = pixelPosition (f, dw, pif); // //-------------------------------------------------------------- void faceAndPixelPosition (const Imath::V3f &direction, const Imath::Box2i &dataWindow, CubeMapFace &face, Imath::V2f &positionInFace); // -------------------------------------------------------- // Given a cube face and a pixel position within that face, // compute the corresponding 3D direction. // -------------------------------------------------------- Imath::V3f direction (CubeMapFace face, const Imath::Box2i &dataWindow, const Imath::V2f &positionInFace); } } // namespace Imf #endif