Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

utilities.inl

Go to the documentation of this file.
00001 /*
00002     toxic - A Global Illumination Renderer
00003     Copyright (C) 2003-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of toxic.
00007 
00008     toxic is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     toxic is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with toxic; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 inline
00024 int IntSquareRoot(int n) {
00025     return static_cast<int>(sqrt(static_cast<double>(n)));
00026 }
00027 
00028 inline
00029 bool IsSquare(int n) {
00030     return sheep::sq(IntSquareRoot(n)) == n;
00031 }
00032 
00033 inline
00034 void VectorToSphericalCoords(const sheep::Vector3 &v,
00035                              sheep::Real *phi,
00036                              sheep::Real *theta)
00037 {
00038     assert(v.IsUnitLength());
00039     assert(phi);
00040     assert(theta);
00041 
00042     *phi = atan2(v.m_z, v.m_x);
00043 
00044     if(*phi < 0.0)
00045         *phi += 2.0 * sheep::PI;    //!\todo Turn the multiplication into an addition.
00046 
00047     *theta = acos(v.m_y);
00048 
00049     assert(*phi >= 0.0 && *phi <= 2.0 * sheep::PI);
00050     assert(*theta >= 0.0 && *theta <= sheep::PI);
00051 }
00052 
00053 inline
00054 sheep::Vector3 SphericalCoordsToVector(sheep::Real phi, sheep::Real theta) {
00055     const sheep::Real sin_theta = sin(theta);
00056 
00057     const sheep::Vector3 v(
00058         cos(phi) * sin_theta,
00059         cos(theta),
00060         sin(phi) * sin_theta);
00061 
00062     assert(v.IsUnitLength());
00063 
00064     return v;
00065 }
00066 
00067 inline
00068 void PackSphericalCoords(sheep::Real phi, sheep::Real theta,
00069                          sheep::uint8 *qphi, sheep::uint8 *qtheta)
00070 {
00071     assert(qphi);
00072     assert(qtheta);
00073 
00074     phi = sheep::NormalizeAngle(phi);
00075     theta = sheep::NormalizeAngle(theta);
00076 
00077     assert(phi >= 0.0 && phi <= 2.0 * sheep::PI);
00078     assert(theta >= 0.0 && theta <= sheep::PI);
00079 
00080     int qphi1 = static_cast<int>(phi * (128.0 / sheep::PI));
00081     assert(qphi1 >= 0 && qphi1 <= 256);
00082 
00083     if(qphi1 > 255)
00084         *qphi = 255;
00085     else *qphi = static_cast<sheep::uint8>(qphi1);
00086 
00087     int qtheta1 = static_cast<int>(theta * (256.0 / sheep::PI));
00088     assert(qtheta1 >= 0 && qtheta1 <= 256);
00089 
00090     if(qtheta1 > 255)
00091         *qtheta = 255;
00092     else *qtheta = static_cast<sheep::uint8>(qtheta1);
00093 }
00094 
00095 inline
00096 void UnpackSphericalCoords(sheep::uint8 qphi, sheep::uint8 qtheta,
00097                            sheep::Real *phi, sheep::Real *theta)
00098 {
00099     //!\todo Could be faster with a conversion table.
00100     *phi = qphi * (sheep::PI / 128.0);
00101     *theta = qtheta * (sheep::PI / 256.0);
00102 
00103     assert(*phi >= 0.0 && *phi <= 2.0 * sheep::PI);
00104     assert(*theta >= 0.0 && *theta <= sheep::PI);
00105 }
00106 
00107 inline
00108 void PackSphericalCoords(sheep::Real phi, sheep::Real theta,
00109                          sheep::uint8 *q)
00110 {
00111     assert(q);
00112 
00113     phi = sheep::NormalizeAngle(phi);
00114     theta = sheep::NormalizeAngle(theta);
00115 
00116     assert(phi >= 0.0 && phi <= 2.0 * sheep::PI);
00117     assert(theta >= 0.0 && theta <= sheep::PI);
00118 
00119     int qphi = static_cast<int>(phi * (8.0 / sheep::PI));
00120     assert(qphi >= 0 && qphi <= 16);
00121 
00122     if(qphi > 15)
00123         qphi = 15;
00124 
00125     int qtheta = static_cast<int>(theta * (16.0 / sheep::PI));
00126     assert(qtheta >= 0 && qtheta <= 16);
00127 
00128     if(qtheta > 15)
00129         qtheta = 15;
00130 
00131     *q = (static_cast<sheep::uint8>(qphi) << 4) + static_cast<sheep::uint8>(qtheta);
00132 }
00133 
00134 inline
00135 void UnpackSphericalCoords(sheep::uint8 q,
00136                            sheep::Real *phi, sheep::Real *theta)
00137 {
00138     //!\todo Could be faster with a conversion table.
00139     sheep::uint8 qphi = q >> 4;
00140     sheep::uint8 qtheta = q & 15;
00141 
00142     *phi = qphi * (sheep::PI / 8.0);
00143     *theta = qtheta * (sheep::PI / 16.0);
00144 
00145     assert(*phi >= 0.0 && *phi <= 2.0 * sheep::PI);
00146     assert(*theta >= 0.0 && *theta <= sheep::PI);
00147 }
00148 
00149 inline
00150 void PackDirection(const sheep::Vector3 &v,
00151                    sheep::uint8 *qphi,
00152                    sheep::uint8 *qtheta)
00153 {
00154     sheep::Real phi, theta;
00155     VectorToSphericalCoords(v, &phi, &theta);
00156     PackSphericalCoords(phi, theta, qphi, qtheta);
00157 }
00158 
00159 inline
00160 void PackDirection(const sheep::Vector3 &v, sheep::uint8 *q) {
00161     sheep::Real phi, theta;
00162     VectorToSphericalCoords(v, &phi, &theta);
00163     PackSphericalCoords(phi, theta, q);
00164 }
00165 
00166 inline
00167 sheep::Vector3 UnpackDirection(sheep::uint8 qphi, sheep::uint8 qtheta) {
00168     const sheep::Real sin_theta = ConversionTables::m_sin_theta[qtheta];
00169 
00170     const sheep::Vector3 v(
00171         ConversionTables::m_cos_phi[qphi] * sin_theta,
00172         ConversionTables::m_cos_theta[qtheta],
00173         ConversionTables::m_sin_phi[qphi] * sin_theta);
00174 
00175     assert(v.IsUnitLength());
00176 
00177     return v;
00178 }
00179 
00180 inline
00181 sheep::Vector3 UnpackDirection(sheep::uint8 q) {
00182     return ConversionTables::m_direction[q];
00183 }

Generated on Tue May 11 01:31:52 2004 for toxic by doxygen 1.3.6