Home | History | Annotate | Download | only in Imath
      1 ///////////////////////////////////////////////////////////////////////////
      2 //
      3 // Copyright (c) 2002, 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 
     37 //----------------------------------------------------------------------------
     38 //
     39 //      Specializations of the Vec2<T> and Vec3<T> templates.
     40 //
     41 //----------------------------------------------------------------------------
     42 
     43 #include "ImathVec.h"
     44 
     45 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
     46 // suppress exception specification warnings
     47 #pragma warning(disable:4290)
     48 #endif
     49 
     50 
     51 namespace Imath {
     52 
     53 namespace
     54 {
     55 
     56 template<class T>
     57 bool
     58 normalizeOrThrow(Vec2<T> &v)
     59 {
     60     int axis = -1;
     61     for (int i = 0; i < 2; i ++)
     62     {
     63         if (v[i] != 0)
     64         {
     65             if (axis != -1)
     66             {
     67                 throw IntVecNormalizeExc ("Cannot normalize an integer "
     68                                           "vector unless it is parallel "
     69                                           "to a principal axis");
     70             }
     71             axis = i;
     72         }
     73     }
     74     v[axis] = (v[axis] > 0) ? 1 : -1;
     75     return true;
     76 }
     77 
     78 
     79 template<class T>
     80 bool
     81 normalizeOrThrow(Vec3<T> &v)
     82 {
     83     int axis = -1;
     84     for (int i = 0; i < 3; i ++)
     85     {
     86         if (v[i] != 0)
     87         {
     88             if (axis != -1)
     89             {
     90                 throw IntVecNormalizeExc ("Cannot normalize an integer "
     91                                           "vector unless it is parallel "
     92                                           "to a principal axis");
     93             }
     94             axis = i;
     95         }
     96     }
     97     v[axis] = (v[axis] > 0) ? 1 : -1;
     98     return true;
     99 }
    100 
    101 
    102 template<class T>
    103 bool
    104 normalizeOrThrow(Vec4<T> &v)
    105 {
    106     int axis = -1;
    107     for (int i = 0; i < 4; i ++)
    108     {
    109         if (v[i] != 0)
    110         {
    111             if (axis != -1)
    112             {
    113                 throw IntVecNormalizeExc ("Cannot normalize an integer "
    114                                           "vector unless it is parallel "
    115                                           "to a principal axis");
    116             }
    117             axis = i;
    118         }
    119     }
    120     v[axis] = (v[axis] > 0) ? 1 : -1;
    121     return true;
    122 }
    123 
    124 }
    125 
    126 
    127 // Vec2<short>
    128 
    129 template <>
    130 short
    131 Vec2<short>::length () const
    132 {
    133     float lenF = Math<float>::sqrt ((float)dot (*this));
    134     short lenS = (short) (lenF + 0.5f);
    135     return lenS;
    136 }
    137 
    138 template <>
    139 const Vec2<short> &
    140 Vec2<short>::normalize ()
    141 {
    142     normalizeOrThrow<short>(*this);
    143     return *this;
    144 }
    145 
    146 template <>
    147 const Vec2<short> &
    148 Vec2<short>::normalizeExc () throw (Iex::MathExc)
    149 {
    150     if ((x == 0) && (y == 0))
    151         throw NullVecExc ("Cannot normalize null vector.");
    152 
    153     normalizeOrThrow<short>(*this);
    154     return *this;
    155 }
    156 
    157 template <>
    158 const Vec2<short> &
    159 Vec2<short>::normalizeNonNull ()
    160 {
    161     normalizeOrThrow<short>(*this);
    162     return *this;
    163 }
    164 
    165 template <>
    166 Vec2<short>
    167 Vec2<short>::normalized () const
    168 {
    169     Vec2<short> v(*this);
    170     normalizeOrThrow<short>(v);
    171     return v;
    172 }
    173 
    174 template <>
    175 Vec2<short>
    176 Vec2<short>::normalizedExc () const throw (Iex::MathExc)
    177 {
    178     if ((x == 0) && (y == 0))
    179         throw NullVecExc ("Cannot normalize null vector.");
    180 
    181     Vec2<short> v(*this);
    182     normalizeOrThrow<short>(v);
    183     return v;
    184 }
    185 
    186 template <>
    187 Vec2<short>
    188 Vec2<short>::normalizedNonNull () const
    189 {
    190     Vec2<short> v(*this);
    191     normalizeOrThrow<short>(v);
    192     return v;
    193 }
    194 
    195 
    196 // Vec2<int>
    197 
    198 template <>
    199 int
    200 Vec2<int>::length () const
    201 {
    202     float lenF = Math<float>::sqrt ((float)dot (*this));
    203     int lenI = (int) (lenF + 0.5f);
    204     return lenI;
    205 }
    206 
    207 template <>
    208 const Vec2<int> &
    209 Vec2<int>::normalize ()
    210 {
    211     normalizeOrThrow<int>(*this);
    212     return *this;
    213 }
    214 
    215 template <>
    216 const Vec2<int> &
    217 Vec2<int>::normalizeExc () throw (Iex::MathExc)
    218 {
    219     if ((x == 0) && (y == 0))
    220         throw NullVecExc ("Cannot normalize null vector.");
    221 
    222     normalizeOrThrow<int>(*this);
    223     return *this;
    224 }
    225 
    226 template <>
    227 const Vec2<int> &
    228 Vec2<int>::normalizeNonNull ()
    229 {
    230     normalizeOrThrow<int>(*this);
    231     return *this;
    232 }
    233 
    234 template <>
    235 Vec2<int>
    236 Vec2<int>::normalized () const
    237 {
    238     Vec2<int> v(*this);
    239     normalizeOrThrow<int>(v);
    240     return v;
    241 }
    242 
    243 template <>
    244 Vec2<int>
    245 Vec2<int>::normalizedExc () const throw (Iex::MathExc)
    246 {
    247     if ((x == 0) && (y == 0))
    248         throw NullVecExc ("Cannot normalize null vector.");
    249 
    250     Vec2<int> v(*this);
    251     normalizeOrThrow<int>(v);
    252     return v;
    253 }
    254 
    255 template <>
    256 Vec2<int>
    257 Vec2<int>::normalizedNonNull () const
    258 {
    259     Vec2<int> v(*this);
    260     normalizeOrThrow<int>(v);
    261     return v;
    262 }
    263 
    264 
    265 // Vec3<short>
    266 
    267 template <>
    268 short
    269 Vec3<short>::length () const
    270 {
    271     float lenF = Math<float>::sqrt ((float)dot (*this));
    272     short lenS = (short) (lenF + 0.5f);
    273     return lenS;
    274 }
    275 
    276 template <>
    277 const Vec3<short> &
    278 Vec3<short>::normalize ()
    279 {
    280     normalizeOrThrow<short>(*this);
    281     return *this;
    282 }
    283 
    284 template <>
    285 const Vec3<short> &
    286 Vec3<short>::normalizeExc () throw (Iex::MathExc)
    287 {
    288     if ((x == 0) && (y == 0) && (z == 0))
    289         throw NullVecExc ("Cannot normalize null vector.");
    290 
    291     normalizeOrThrow<short>(*this);
    292     return *this;
    293 }
    294 
    295 template <>
    296 const Vec3<short> &
    297 Vec3<short>::normalizeNonNull ()
    298 {
    299     normalizeOrThrow<short>(*this);
    300     return *this;
    301 }
    302 
    303 template <>
    304 Vec3<short>
    305 Vec3<short>::normalized () const
    306 {
    307     Vec3<short> v(*this);
    308     normalizeOrThrow<short>(v);
    309     return v;
    310 }
    311 
    312 template <>
    313 Vec3<short>
    314 Vec3<short>::normalizedExc () const throw (Iex::MathExc)
    315 {
    316     if ((x == 0) && (y == 0) && (z == 0))
    317         throw NullVecExc ("Cannot normalize null vector.");
    318 
    319     Vec3<short> v(*this);
    320     normalizeOrThrow<short>(v);
    321     return v;
    322 }
    323 
    324 template <>
    325 Vec3<short>
    326 Vec3<short>::normalizedNonNull () const
    327 {
    328     Vec3<short> v(*this);
    329     normalizeOrThrow<short>(v);
    330     return v;
    331 }
    332 
    333 
    334 // Vec3<int>
    335 
    336 template <>
    337 int
    338 Vec3<int>::length () const
    339 {
    340     float lenF = Math<float>::sqrt ((float)dot (*this));
    341     int lenI = (int) (lenF + 0.5f);
    342     return lenI;
    343 }
    344 
    345 template <>
    346 const Vec3<int> &
    347 Vec3<int>::normalize ()
    348 {
    349     normalizeOrThrow<int>(*this);
    350     return *this;
    351 }
    352 
    353 template <>
    354 const Vec3<int> &
    355 Vec3<int>::normalizeExc () throw (Iex::MathExc)
    356 {
    357     if ((x == 0) && (y == 0) && (z == 0))
    358         throw NullVecExc ("Cannot normalize null vector.");
    359 
    360     normalizeOrThrow<int>(*this);
    361     return *this;
    362 }
    363 
    364 template <>
    365 const Vec3<int> &
    366 Vec3<int>::normalizeNonNull ()
    367 {
    368     normalizeOrThrow<int>(*this);
    369     return *this;
    370 }
    371 
    372 template <>
    373 Vec3<int>
    374 Vec3<int>::normalized () const
    375 {
    376     Vec3<int> v(*this);
    377     normalizeOrThrow<int>(v);
    378     return v;
    379 }
    380 
    381 template <>
    382 Vec3<int>
    383 Vec3<int>::normalizedExc () const throw (Iex::MathExc)
    384 {
    385     if ((x == 0) && (y == 0) && (z == 0))
    386         throw NullVecExc ("Cannot normalize null vector.");
    387 
    388     Vec3<int> v(*this);
    389     normalizeOrThrow<int>(v);
    390     return v;
    391 }
    392 
    393 template <>
    394 Vec3<int>
    395 Vec3<int>::normalizedNonNull () const
    396 {
    397     Vec3<int> v(*this);
    398     normalizeOrThrow<int>(v);
    399     return v;
    400 }
    401 
    402 
    403 // Vec4<short>
    404 
    405 template <>
    406 short
    407 Vec4<short>::length () const
    408 {
    409     float lenF = Math<float>::sqrt ((float)dot (*this));
    410     short lenS = (short) (lenF + 0.5f);
    411     return lenS;
    412 }
    413 
    414 template <>
    415 const Vec4<short> &
    416 Vec4<short>::normalize ()
    417 {
    418     normalizeOrThrow<short>(*this);
    419     return *this;
    420 }
    421 
    422 template <>
    423 const Vec4<short> &
    424 Vec4<short>::normalizeExc () throw (Iex::MathExc)
    425 {
    426     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
    427         throw NullVecExc ("Cannot normalize null vector.");
    428 
    429     normalizeOrThrow<short>(*this);
    430     return *this;
    431 }
    432 
    433 template <>
    434 const Vec4<short> &
    435 Vec4<short>::normalizeNonNull ()
    436 {
    437     normalizeOrThrow<short>(*this);
    438     return *this;
    439 }
    440 
    441 template <>
    442 Vec4<short>
    443 Vec4<short>::normalized () const
    444 {
    445     Vec4<short> v(*this);
    446     normalizeOrThrow<short>(v);
    447     return v;
    448 }
    449 
    450 template <>
    451 Vec4<short>
    452 Vec4<short>::normalizedExc () const throw (Iex::MathExc)
    453 {
    454     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
    455         throw NullVecExc ("Cannot normalize null vector.");
    456 
    457     Vec4<short> v(*this);
    458     normalizeOrThrow<short>(v);
    459     return v;
    460 }
    461 
    462 template <>
    463 Vec4<short>
    464 Vec4<short>::normalizedNonNull () const
    465 {
    466     Vec4<short> v(*this);
    467     normalizeOrThrow<short>(v);
    468     return v;
    469 }
    470 
    471 
    472 // Vec4<int>
    473 
    474 template <>
    475 int
    476 Vec4<int>::length () const
    477 {
    478     float lenF = Math<float>::sqrt ((float)dot (*this));
    479     int lenI = (int) (lenF + 0.5f);
    480     return lenI;
    481 }
    482 
    483 template <>
    484 const Vec4<int> &
    485 Vec4<int>::normalize ()
    486 {
    487     normalizeOrThrow<int>(*this);
    488     return *this;
    489 }
    490 
    491 template <>
    492 const Vec4<int> &
    493 Vec4<int>::normalizeExc () throw (Iex::MathExc)
    494 {
    495     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
    496         throw NullVecExc ("Cannot normalize null vector.");
    497 
    498     normalizeOrThrow<int>(*this);
    499     return *this;
    500 }
    501 
    502 template <>
    503 const Vec4<int> &
    504 Vec4<int>::normalizeNonNull ()
    505 {
    506     normalizeOrThrow<int>(*this);
    507     return *this;
    508 }
    509 
    510 template <>
    511 Vec4<int>
    512 Vec4<int>::normalized () const
    513 {
    514     Vec4<int> v(*this);
    515     normalizeOrThrow<int>(v);
    516     return v;
    517 }
    518 
    519 template <>
    520 Vec4<int>
    521 Vec4<int>::normalizedExc () const throw (Iex::MathExc)
    522 {
    523     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
    524         throw NullVecExc ("Cannot normalize null vector.");
    525 
    526     Vec4<int> v(*this);
    527     normalizeOrThrow<int>(v);
    528     return v;
    529 }
    530 
    531 template <>
    532 Vec4<int>
    533 Vec4<int>::normalizedNonNull () const
    534 {
    535     Vec4<int> v(*this);
    536     normalizeOrThrow<int>(v);
    537     return v;
    538 }
    539 
    540 } // namespace Imath
    541