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