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