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 51namespace Imath { 52 53namespace 54{ 55 56template<class T> 57bool 58normalizeOrThrow(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 79template<class T> 80bool 81normalizeOrThrow(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 103 104// Vec2<short> 105 106template <> 107short 108Vec2<short>::length () const 109{ 110 float lenF = Math<float>::sqrt (dot (*this)); 111 short lenS = (short) (lenF + 0.5f); 112 return lenS; 113} 114 115template <> 116const Vec2<short> & 117Vec2<short>::normalize () 118{ 119 normalizeOrThrow<short>(*this); 120 return *this; 121} 122 123template <> 124const Vec2<short> & 125Vec2<short>::normalizeExc () throw (Iex::MathExc) 126{ 127 if ((x == 0) && (y == 0)) 128 throw NullVecExc ("Cannot normalize null vector."); 129 130 normalizeOrThrow<short>(*this); 131 return *this; 132} 133 134template <> 135const Vec2<short> & 136Vec2<short>::normalizeNonNull () 137{ 138 normalizeOrThrow<short>(*this); 139 return *this; 140} 141 142template <> 143Vec2<short> 144Vec2<short>::normalized () const 145{ 146 Vec2<short> v(*this); 147 normalizeOrThrow<short>(v); 148 return v; 149} 150 151template <> 152Vec2<short> 153Vec2<short>::normalizedExc () const throw (Iex::MathExc) 154{ 155 if ((x == 0) && (y == 0)) 156 throw NullVecExc ("Cannot normalize null vector."); 157 158 Vec2<short> v(*this); 159 normalizeOrThrow<short>(v); 160 return v; 161} 162 163template <> 164Vec2<short> 165Vec2<short>::normalizedNonNull () const 166{ 167 Vec2<short> v(*this); 168 normalizeOrThrow<short>(v); 169 return v; 170} 171 172 173// Vec2<int> 174 175template <> 176int 177Vec2<int>::length () const 178{ 179 float lenF = Math<float>::sqrt (dot (*this)); 180 int lenI = (int) (lenF + 0.5f); 181 return lenI; 182} 183 184template <> 185const Vec2<int> & 186Vec2<int>::normalize () 187{ 188 normalizeOrThrow<int>(*this); 189 return *this; 190} 191 192template <> 193const Vec2<int> & 194Vec2<int>::normalizeExc () throw (Iex::MathExc) 195{ 196 if ((x == 0) && (y == 0)) 197 throw NullVecExc ("Cannot normalize null vector."); 198 199 normalizeOrThrow<int>(*this); 200 return *this; 201} 202 203template <> 204const Vec2<int> & 205Vec2<int>::normalizeNonNull () 206{ 207 normalizeOrThrow<int>(*this); 208 return *this; 209} 210 211template <> 212Vec2<int> 213Vec2<int>::normalized () const 214{ 215 Vec2<int> v(*this); 216 normalizeOrThrow<int>(v); 217 return v; 218} 219 220template <> 221Vec2<int> 222Vec2<int>::normalizedExc () const throw (Iex::MathExc) 223{ 224 if ((x == 0) && (y == 0)) 225 throw NullVecExc ("Cannot normalize null vector."); 226 227 Vec2<int> v(*this); 228 normalizeOrThrow<int>(v); 229 return v; 230} 231 232template <> 233Vec2<int> 234Vec2<int>::normalizedNonNull () const 235{ 236 Vec2<int> v(*this); 237 normalizeOrThrow<int>(v); 238 return v; 239} 240 241 242// Vec3<short> 243 244template <> 245short 246Vec3<short>::length () const 247{ 248 float lenF = Math<float>::sqrt (dot (*this)); 249 short lenS = (short) (lenF + 0.5f); 250 return lenS; 251} 252 253template <> 254const Vec3<short> & 255Vec3<short>::normalize () 256{ 257 normalizeOrThrow<short>(*this); 258 return *this; 259} 260 261template <> 262const Vec3<short> & 263Vec3<short>::normalizeExc () throw (Iex::MathExc) 264{ 265 if ((x == 0) && (y == 0) && (z == 0)) 266 throw NullVecExc ("Cannot normalize null vector."); 267 268 normalizeOrThrow<short>(*this); 269 return *this; 270} 271 272template <> 273const Vec3<short> & 274Vec3<short>::normalizeNonNull () 275{ 276 normalizeOrThrow<short>(*this); 277 return *this; 278} 279 280template <> 281Vec3<short> 282Vec3<short>::normalized () const 283{ 284 Vec3<short> v(*this); 285 normalizeOrThrow<short>(v); 286 return v; 287} 288 289template <> 290Vec3<short> 291Vec3<short>::normalizedExc () const throw (Iex::MathExc) 292{ 293 if ((x == 0) && (y == 0) && (z == 0)) 294 throw NullVecExc ("Cannot normalize null vector."); 295 296 Vec3<short> v(*this); 297 normalizeOrThrow<short>(v); 298 return v; 299} 300 301template <> 302Vec3<short> 303Vec3<short>::normalizedNonNull () const 304{ 305 Vec3<short> v(*this); 306 normalizeOrThrow<short>(v); 307 return v; 308} 309 310 311// Vec3<int> 312 313template <> 314int 315Vec3<int>::length () const 316{ 317 float lenF = Math<float>::sqrt (dot (*this)); 318 int lenI = (int) (lenF + 0.5f); 319 return lenI; 320} 321 322template <> 323const Vec3<int> & 324Vec3<int>::normalize () 325{ 326 normalizeOrThrow<int>(*this); 327 return *this; 328} 329 330template <> 331const Vec3<int> & 332Vec3<int>::normalizeExc () throw (Iex::MathExc) 333{ 334 if ((x == 0) && (y == 0) && (z == 0)) 335 throw NullVecExc ("Cannot normalize null vector."); 336 337 normalizeOrThrow<int>(*this); 338 return *this; 339} 340 341template <> 342const Vec3<int> & 343Vec3<int>::normalizeNonNull () 344{ 345 normalizeOrThrow<int>(*this); 346 return *this; 347} 348 349template <> 350Vec3<int> 351Vec3<int>::normalized () const 352{ 353 Vec3<int> v(*this); 354 normalizeOrThrow<int>(v); 355 return v; 356} 357 358template <> 359Vec3<int> 360Vec3<int>::normalizedExc () const throw (Iex::MathExc) 361{ 362 if ((x == 0) && (y == 0) && (z == 0)) 363 throw NullVecExc ("Cannot normalize null vector."); 364 365 Vec3<int> v(*this); 366 normalizeOrThrow<int>(v); 367 return v; 368} 369 370template <> 371Vec3<int> 372Vec3<int>::normalizedNonNull () const 373{ 374 Vec3<int> v(*this); 375 normalizeOrThrow<int>(v); 376 return v; 377} 378 379 380} // namespace Imath 381