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