Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vector.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_CORE_VECTOR_H_)
21 #define __MITSUBA_CORE_VECTOR_H_
22 
23 #include <mitsuba/core/stream.h>
24 
26 /**
27  * \headerfile mitsuba/core/vector.h mitsuba/mitsuba.h
28  * \brief Parameterizable one-dimensional vector data structure
29  * \ingroup libcore
30  */
31 template <typename T> struct TVector1 {
32  typedef T Scalar;
34 
35  T x;
36 
37  /// Number of dimensions
38  const static int dim = 1;
39 
40  /** \brief Construct a new vector without initializing it.
41  *
42  * This construtor is useful when the vector will either not
43  * be used at all (it might be part of a larger data structure)
44  * or initialized at a later point in time. Always make sure
45  * that one of the two is the case! Otherwise your program will do
46  * computations involving uninitialized memory, which will probably
47  * lead to a difficult-to-find bug.
48  */
49 #if !defined(MTS_DEBUG_UNINITIALIZED)
50  TVector1() { }
51 #else
52  TVector1() { x = std::numeric_limits<T>::quiet_NaN(); }
53 #endif
54 
55  /// Initialize the vector with the specified value
56  TVector1(T x) : x(x) { }
57 
58  /// Initialize the vector with the components of another vector data structure
59  template <typename T1> explicit TVector1(const TVector1<T1> &v)
60  : x((T) v.x) { }
61 
62  /// Initialize the vector with the components of a point data structure
63  template <typename T1> explicit TVector1(const TPoint1<T1> &p)
64  : x((T) p.x) { }
65 
66  /// Unserialize a vector from a binary data stream
67  explicit TVector1(Stream *stream) {
68  x = stream->readElement<T>();
69  }
70 
71  /// Add two vectors and return the result
72  TVector1 operator+(const TVector1 &v) const {
73  return TVector1(x + v.x);
74  }
75 
76  /// Subtract two vectors and return the result
77  TVector1 operator-(const TVector1 &v) const {
78  return TVector1(x - v.x);
79  }
80 
81  /// Add another vector to the current one
83  x += v.x;
84  return *this;
85  }
86 
87  /// Subtract another vector from the current one
89  x -= v.x;
90  return *this;
91  }
92 
93  /// Multiply the vector by the given scalar and return the result
94  TVector1 operator*(T f) const {
95  return TVector1(x*f);
96  }
97 
98  /// Multiply the vector by the given scalar
100  x *= f;
101  return *this;
102  }
103 
104  /// Return a negated version of the vector
105  TVector1 operator-() const {
106  return TVector1(-x);
107  }
108 
109  /// Divide the vector by the given scalar and return the result
110  TVector1 operator/(T f) const {
111 #ifdef MTS_DEBUG
112  if (f == 0)
113  SLog(EWarn, "Vector1: Division by zero!");
114 #endif
115  return TVector1(x / f);
116  }
117 
118  /// Divide the vector by the given scalar
120 #ifdef MTS_DEBUG
121  if (f == 0)
122  SLog(EWarn, "Vector1: Division by zero!");
123 #endif
124  x /= f;
125  return *this;
126  }
127 
128  /// Index into the vector's components
129  T &operator[](int i) {
130  return (&x)[i];
131  }
132 
133  /// Index into the vector's components (const version)
134  T operator[](int i) const {
135  return (&x)[i];
136  }
137 
138  /// Return the squared 1-norm of this vector
139  T lengthSquared() const {
140  return x*x;
141  }
142 
143  /// Return the 1-norm of this vector
144  T length() const {
145  return std::abs(x);
146  }
147 
148  /// Return whether or not this vector is identically zero
149  bool isZero() const {
150  return x == 0;
151  }
152 
153  /// Equality test
154  bool operator==(const TVector1 &v) const {
155  return v.x == x;
156  }
157 
158  /// Inequality test
159  bool operator!=(const TVector1 &v) const {
160  return v.x != x;
161  }
162 
163  /// Serialize this vector to a binary data stream
164  void serialize(Stream *stream) const {
165  stream->writeElement<T>(x);
166  }
167 
168  /// Implicit conversion to Scalar
169  operator Scalar() const { return x; }
170 
171  /// Return a readable string representation of this vector
172  std::string toString() const {
173  std::ostringstream oss;
174  oss << "[" << x << "]";
175  return oss.str();
176  }
177 };
178 
179 template <typename T> inline TVector1<T> operator*(T f, const TVector1<T> &v) {
180  return v*f;
181 }
182 
183 template <typename T> inline T dot(const TVector1<T> &v1, const TVector1<T> &v2) {
184  return v1.x * v2.x;
185 }
186 
187 template <typename T> inline T absDot(const TVector1<T> &v1, const TVector1<T> &v2) {
188  return std::abs(dot(v1, v2));
189 }
190 
191 template <typename T> inline TVector1<T> normalize(const TVector1<T> &v) {
192  return v / v.length();
193 }
194 
195 template <typename T> inline TVector1<T> normalizeStrict(const TVector1<T> &v, const char *errMsg) {
196  Float length = v.length();
197  if (length == 0)
198  SLog(EError, "normalizeStrict(): %s", errMsg);
199  return v / length;
200 }
201 
202 template <> inline TVector1<int> TVector1<int>::operator/(int s) const {
203 #ifdef MTS_DEBUG
204  if (s == 0)
205  SLog(EWarn, "Vector1i: Division by zero!");
206 #endif
207  return TVector1(x/s);
208 }
209 
210 template <> inline TVector1<int> &TVector1<int>::operator/=(int s) {
211 #ifdef MTS_DEBUG
212  if (s == 0)
213  SLog(EWarn, "Vector1i: Division by zero!");
214 #endif
215 
216  x /= s;
217  return *this;
218 }
219 
220 namespace detail {
221 // Helper structures to define "length" as a floating point value
222 
223 template <typename T, bool IsInteger = false> struct VectorLength {
224  typedef T type;
225 };
226 
227 template <typename T> struct VectorLength<T, true> {
228  typedef Float type;
229 };
230 
231 template <> struct VectorLength<uint64_t, true> {
232  typedef double type;
233 };
234 
235 template <> struct VectorLength<int64_t, true> {
236  typedef double type;
237 };
238 
239 }
240 
241 /**
242  * \headerfile mitsuba/core/vector.h mitsuba/mitsuba.h
243  * \brief Parameterizable two-dimensional vector data structure
244  * \ingroup libcore
245  */
246 template <typename T> struct TVector2 {
247  typedef T Scalar;
250 
251  T x, y;
252 
253  /// Number of dimensions
254  const static int dim = 2;
255 
256  /** \brief Construct a new vector without initializing it.
257  *
258  * This construtor is useful when the vector will either not
259  * be used at all (it might be part of a larger data structure)
260  * or initialized at a later point in time. Always make sure
261  * that one of the two is the case! Otherwise your program will do
262  * computations involving uninitialized memory, which will probably
263  * lead to a difficult-to-find bug.
264  */
265 #if !defined(MTS_DEBUG_UNINITIALIZED)
266  TVector2() { }
267 #else
268  TVector2() { x = y = std::numeric_limits<T>::quiet_NaN(); }
269 #endif
270 
271  /// Initialize the vector with the specified X and Z components
272  TVector2(T x, T y) : x(x), y(y) { }
273 
274  /// Initialize all components of the the vector with the specified value
275  explicit TVector2(T val) : x(val), y(val) { }
276 
277  /// Initialize the vector with the components of another vector data structure
278  template <typename T2> explicit TVector2(const TVector2<T2> &v)
279  : x((T) v.x), y((T) v.y) { }
280 
281  /// Initialize the vector with the components of a point data structure
282  template <typename T2> explicit TVector2(const TPoint2<T2> &p)
283  : x((T) p.x), y((T) p.y) { }
284 
285  /// Unserialize a vector from a binary data stream
286  explicit TVector2(Stream *stream) {
287  x = stream->readElement<T>();
288  y = stream->readElement<T>();
289  }
290 
291  /// Add two vectors and return the result
292  TVector2 operator+(const TVector2 &v) const {
293  return TVector2(x + v.x, y + v.y);
294  }
295 
296  /// Subtract two vectors and return the result
297  TVector2 operator-(const TVector2 &v) const {
298  return TVector2(x - v.x, y - v.y);
299  }
300 
301  /// Add another vector to the current one
303  x += v.x; y += v.y;
304  return *this;
305  }
306 
307  /// Subtract another vector from the current one
309  x -= v.x; y -= v.y;
310  return *this;
311  }
312 
313  /// Multiply the vector by the given scalar and return the result
314  TVector2 operator*(T f) const {
315  return TVector2(x*f, y*f);
316  }
317 
318  /// Multiply the vector by the given scalar
320  x *= f; y *= f;
321  return *this;
322  }
323 
324  /// Return a negated version of the vector
325  TVector2 operator-() const {
326  return TVector2(-x, -y);
327  }
328 
329  /// Divide the vector by the given scalar and return the result
330  TVector2 operator/(T f) const {
331 #ifdef MTS_DEBUG
332  if (f == 0)
333  SLog(EWarn, "Vector2: Division by zero!");
334 #endif
335  T recip = (T) 1 / f;
336  return TVector2(x * recip, y * recip);
337  }
338 
339  /// Divide the vector by the given scalar
341 #ifdef MTS_DEBUG
342  if (f == 0)
343  SLog(EWarn, "Vector2: Division by zero!");
344 #endif
345  T recip = (T) 1 / f;
346  x *= recip; y *= recip;
347  return *this;
348  }
349 
350  /// Index into the vector's components
351  T &operator[](int i) {
352  return (&x)[i];
353  }
354 
355  /// Index into the vector's components (const version)
356  T operator[](int i) const {
357  return (&x)[i];
358  }
359 
360  /// Return the squared 2-norm of this vector
361  T lengthSquared() const {
362  return x*x + y*y;
363  }
364 
365  /// Return the 2-norm of this vector
366  LengthType length() const {
367  return (LengthType) std::sqrt((LengthType) lengthSquared());
368  }
369 
370  /// Return whether or not this vector is identically zero
371  bool isZero() const {
372  return x == 0 && y == 0;
373  }
374 
375  /// Equality test
376  bool operator==(const TVector2 &v) const {
377  return (v.x == x && v.y == y);
378  }
379 
380  /// Inequality test
381  bool operator!=(const TVector2 &v) const {
382  return v.x != x || v.y != y;
383  }
384 
385  /// Serialize this vector to a binary data stream
386  void serialize(Stream *stream) const {
387  stream->writeElement<T>(x);
388  stream->writeElement<T>(y);
389  }
390 
391  /// Return a readable string representation of this vector
392  std::string toString() const {
393  std::ostringstream oss;
394  oss << "[" << x << ", " << y << "]";
395  return oss.str();
396  }
397 };
398 
399 template <typename T> inline TVector2<T> operator*(T f, const TVector2<T> &v) {
400  return v*f;
401 }
402 
403 template <typename T> inline T dot(const TVector2<T> &v1, const TVector2<T> &v2) {
404  return v1.x * v2.x + v1.y * v2.y;
405 }
406 
407 template <typename T> inline T absDot(const TVector2<T> &v1, const TVector2<T> &v2) {
408  return std::abs(dot(v1, v2));
409 }
410 
411 template <typename T> inline T det(const TVector2<T> &v1, const TVector2<T> &v2) {
412  return v1.x * v2.y - v1.y * v2.x;
413 }
414 
415 template <typename T> inline TVector2<T> normalize(const TVector2<T> &v) {
416  return v / v.length();
417 }
418 
419 template <typename T> inline TVector2<T> normalizeStrict(const TVector2<T> &v, const char *errMsg) {
420  Float length = v.length();
421  if (length == 0)
422  SLog(EError, "normalizeStrict(): %s", errMsg);
423  return v / length;
424 }
425 
426 template <> inline TVector2<int> TVector2<int>::operator/(int s) const {
427 #ifdef MTS_DEBUG
428  if (s == 0)
429  SLog(EWarn, "Vector2i: Division by zero!");
430 #endif
431  return TVector2(x/s, y/s);
432 }
433 
434 template <> inline TVector2<int> &TVector2<int>::operator/=(int s) {
435 #ifdef MTS_DEBUG
436  if (s == 0)
437  SLog(EWarn, "Vector2i: Division by zero!");
438 #endif
439 
440  x /= s;
441  y /= s;
442  return *this;
443 }
444 
445 /**
446  * \headerfile mitsuba/core/vector.h mitsuba/mitsuba.h
447  * \brief Parameterizable three-dimensional vector data structure
448  * \ingroup libcore
449  */
450 template <typename T> struct TVector3 {
451  typedef T Scalar;
454 
455  T x, y, z;
456 
457  /// Number of dimensions
458  const static int dim = 3;
459 
460  /** \brief Construct a new vector without initializing it.
461  *
462  * This construtor is useful when the vector will either not
463  * be used at all (it might be part of a larger data structure)
464  * or initialized at a later point in time. Always make sure
465  * that one of the two is the case! Otherwise your program will do
466  * computations involving uninitialized memory, which will probably
467  * lead to a difficult-to-find bug.
468  */
469 #if !defined(MTS_DEBUG_UNINITIALIZED)
470  TVector3() { }
471 #else
472  TVector3() { x = y = z = std::numeric_limits<T>::quiet_NaN(); }
473 #endif
474 
475  /// Initialize the vector with the specified X, Y and Z components
476  TVector3(T x, T y, T z) : x(x), y(y), z(z) { }
477 
478  /// Initialize all components of the the vector with the specified value
479  explicit TVector3(T val) : x(val), y(val), z(val) { }
480 
481  /// Initialize the vector with the components of another vector data structure
482  template <typename T2> explicit TVector3(const TVector3<T2> &v)
483  : x((T) v.x), y((T) v.y), z((T) v.z) { }
484 
485  /// Initialize the vector with the components of a point data structure
486  template <typename T2> explicit TVector3(const TPoint3<T2> &p)
487  : x((T) p.x), y((T) p.y), z((T) p.z) { }
488 
489  /// Unserialize a vector from a binary data stream
490  explicit TVector3(Stream *stream) {
491  x = stream->readElement<T>();
492  y = stream->readElement<T>();
493  z = stream->readElement<T>();
494  }
495 
496  /// Add two vectors and return the result
497  TVector3 operator+(const TVector3 &v) const {
498  return TVector3(x + v.x, y + v.y, z + v.z);
499  }
500 
501  /// Subtract two vectors and return the result
502  TVector3 operator-(const TVector3 &v) const {
503  return TVector3(x - v.x, y - v.y, z - v.z);
504  }
505 
506  /// Add another vector to the current one
508  x += v.x; y += v.y; z += v.z;
509  return *this;
510  }
511 
512  /// Subtract another vector from the current one
514  x -= v.x; y -= v.y; z -= v.z;
515  return *this;
516  }
517 
518  /// Multiply the vector by the given scalar and return the result
519  TVector3 operator*(T f) const {
520  return TVector3(x*f, y*f, z*f);
521  }
522 
523  /// Multiply the vector by the given scalar
525  x *= f; y *= f; z *= f;
526  return *this;
527  }
528 
529  /// Return a negated version of the vector
530  TVector3 operator-() const {
531  return TVector3(-x, -y, -z);
532  }
533 
534  /// Divide the vector by the given scalar and return the result
535  TVector3 operator/(T f) const {
536 #ifdef MTS_DEBUG
537  if (f == 0)
538  SLog(EWarn, "Vector3: Division by zero!");
539 #endif
540  T recip = (T) 1 / f;
541  return TVector3(x * recip, y * recip, z * recip);
542  }
543 
544  /// Divide the vector by the given scalar
546 #ifdef MTS_DEBUG
547  if (f == 0)
548  SLog(EWarn, "Vector3: Division by zero!");
549 #endif
550  T recip = (T) 1 / f;
551  x *= recip; y *= recip; z *= recip;
552  return *this;
553  }
554 
555  /// Index into the vector's components
556  T &operator[](int i) {
557  return (&x)[i];
558  }
559 
560  /// Index into the vector's components (const version)
561  T operator[](int i) const {
562  return (&x)[i];
563  }
564 
565  /// Return the squared 2-norm of this vector
566  T lengthSquared() const {
567  return x*x + y*y + z*z;
568  }
569 
570  /// Return the 2-norm of this vector
571  LengthType length() const {
572  return (LengthType) std::sqrt((LengthType) lengthSquared());
573  }
574 
575  /// Return whether or not this vector is identically zero
576  bool isZero() const {
577  return x == 0 && y == 0 && z == 0;
578  }
579 
580  /// Equality test
581  bool operator==(const TVector3 &v) const {
582  return (v.x == x && v.y == y && v.z == z);
583  }
584 
585  /// Inequality test
586  bool operator!=(const TVector3 &v) const {
587  return v.x != x || v.y != y || v.z != z;
588  }
589 
590  /// Serialize this vector to a binary data stream
591  void serialize(Stream *stream) const {
592  stream->writeElement<T>(x);
593  stream->writeElement<T>(y);
594  stream->writeElement<T>(z);
595  }
596 
597  /// Return a readable string representation of this vector
598  std::string toString() const {
599  std::ostringstream oss;
600  oss << "[" << x << ", " << y << ", " << z << "]";
601  return oss.str();
602  }
603 };
604 
605 template <typename T> inline TVector3<T> operator*(T f, const TVector3<T> &v) {
606  return v*f;
607 }
608 
609 template <typename T> inline T dot(const TVector3<T> &v1, const TVector3<T> &v2) {
610  return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
611 }
612 
613 template <typename T> inline T absDot(const TVector3<T> &v1, const TVector3<T> &v2) {
614  return std::abs(dot(v1, v2));
615 }
616 
617 template <typename T> inline TVector3<T> cross(const TVector3<T> &v1, const TVector3<T> &v2) {
618  return TVector3<T>(
619  (v1.y * v2.z) - (v1.z * v2.y),
620  (v1.z * v2.x) - (v1.x * v2.z),
621  (v1.x * v2.y) - (v1.y * v2.x)
622  );
623 }
624 
625 template <typename T> inline TVector3<T> normalize(const TVector3<T> &v) {
626  return v / v.length();
627 }
628 
629 template <typename T> inline TVector3<T> normalizeStrict(const TVector3<T> &v, const char *errMsg) {
630  Float length = v.length();
631  if (length == 0)
632  SLog(EError, "normalizeStrict(): %s", errMsg);
633  return v / length;
634 }
635 
636 template <> inline TVector3<int> TVector3<int>::operator/(int s) const {
637 #ifdef MTS_DEBUG
638  if (s == 0)
639  SLog(EWarn, "Vector3i: Division by zero!");
640 #endif
641  return TVector3(x/s, y/s, z/s);
642 }
643 
644 template <> inline TVector3<int> &TVector3<int>::operator/=(int s) {
645 #ifdef MTS_DEBUG
646  if (s == 0)
647  SLog(EWarn, "Vector3i: Division by zero!");
648 #endif
649 
650  x /= s;
651  y /= s;
652  z /= s;
653  return *this;
654 }
655 
656 
657 /**
658  * \headerfile mitsuba/core/vector.h mitsuba/mitsuba.h
659  * \brief Parameterizable four-dimensional vector data structure
660  * \ingroup libcore
661  */
662 template <typename T> struct TVector4 {
663  typedef T Scalar;
666 
667  T x, y, z, w;
668 
669  /// Number of dimensions
670  const static int dim = 4;
671 
672  /** \brief Construct a new vector without initializing it.
673  *
674  * This construtor is useful when the vector will either not
675  * be used at all (it might be part of a larger data structure)
676  * or initialized at a later point in time. Always make sure
677  * that one of the two is the case! Otherwise your program will do
678  * computations involving uninitialized memory, which will probably
679  * lead to a difficult-to-find bug.
680  */
681 #if !defined(MTS_DEBUG_UNINITIALIZED)
682  TVector4() { }
683 #else
684  TVector4() { x = y = z = w = std::numeric_limits<T>::quiet_NaN(); }
685 #endif
686 
687  /// Initialize the vector with the specified X, Y and Z components
688  TVector4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) { }
689 
690  /// Initialize all components of the the vector with the specified value
691  explicit TVector4(T val) : x(val), y(val), z(val), w(val) { }
692 
693  /// Initialize the vector with the components of another vector data structure
694  template <typename T2> explicit TVector4(const TVector4<T2> &v)
695  : x((T) v.x), y((T) v.y), z((T) v.z), w((T) v.w) { }
696 
697  /// Initialize the vector with the components of a point data structure
698  template <typename T2> explicit TVector4(const TPoint4<T2> &p)
699  : x((T) p.x), y((T) p.y), z((T) p.z), w((T) p.w) { }
700 
701  /// Unserialize a vector from a binary data stream
702  explicit TVector4(Stream *stream) {
703  x = stream->readElement<T>();
704  y = stream->readElement<T>();
705  z = stream->readElement<T>();
706  w = stream->readElement<T>();
707  }
708 
709  /// Add two vectors and return the result
710  TVector4 operator+(const TVector4 &v) const {
711  return TVector4(x + v.x, y + v.y, z + v.z, w + v.w);
712  }
713 
714  /// Subtract two vectors and return the result
715  TVector4 operator-(const TVector4 &v) const {
716  return TVector4(x - v.x, y - v.y, z - v.z, w - v.w);
717  }
718 
719  /// Add another vector to the current one
721  x += v.x; y += v.y; z += v.z; w += v.w;
722  return *this;
723  }
724 
725  /// Subtract another vector from the current one
727  x -= v.x; y -= v.y; z -= v.z; w -= v.w;
728  return *this;
729  }
730 
731  /// Multiply the vector by the given scalar and return the result
732  TVector4 operator*(T f) const {
733  return TVector4(x * f, y * f, z * f, w * f);
734  }
735 
736  /// Multiply the vector by the given scalar
738  x *= f; y *= f; z *= f; w *= f;
739  return *this;
740  }
741 
742  /// Return a negated version of the vector
743  TVector4 operator-() const {
744  return TVector4(-x, -y, -z, -w);
745  }
746 
747  /// Divide the vector by the given scalar and return the result
748  TVector4 operator/(T f) const {
749 #ifdef MTS_DEBUG
750  if (f == 0)
751  SLog(EWarn, "Vector4: Division by zero!");
752 #endif
753  T recip = (T) 1 / f;
754  return TVector4(x * recip, y * recip, z * recip, w * recip);
755  }
756 
757  /// Divide the vector by the given scalar
759 #ifdef MTS_DEBUG
760  if (f == 0)
761  SLog(EWarn, "Vector4: Division by zero!");
762 #endif
763  T recip = (T) 1 / f;
764  x *= recip; y *= recip; z *= recip; w *= recip;
765  return *this;
766  }
767 
768  /// Index into the vector's components
769  T &operator[](int i) {
770  return (&x)[i];
771  }
772 
773  /// Index into the vector's components (const version)
774  T operator[](int i) const {
775  return (&x)[i];
776  }
777 
778  /// Return the squared 2-norm of this vector
779  T lengthSquared() const {
780  return x*x + y*y + z*z + w*w;
781  }
782 
783  /// Return the 2-norm of this vector
784  LengthType length() const {
785  return (LengthType) std::sqrt((LengthType) lengthSquared());
786  }
787 
788  /// Return whether or not this vector is identically zero
789  bool isZero() const {
790  return x == 0 && y == 0 && z == 0 && w == 0;
791  }
792 
793  /// Equality test
794  bool operator==(const TVector4 &v) const {
795  return (v.x == x && v.y == y && v.z == z && v.w == w);
796  }
797 
798  /// Inequality test
799  bool operator!=(const TVector4 &v) const {
800  return v.x != x || v.y != y || v.z != z || v.w != w;
801  }
802 
803  /// Serialize this vector to a binary data stream
804  void serialize(Stream *stream) const {
805  stream->writeElement<T>(x);
806  stream->writeElement<T>(y);
807  stream->writeElement<T>(z);
808  stream->writeElement<T>(w);
809  }
810 
811  /// Return a readable string representation of this vector
812  std::string toString() const {
813  std::ostringstream oss;
814  oss << "[" << x << ", " << y << ", " << z << ", " << w << "]";
815  return oss.str();
816  }
817 };
818 
819 template <typename T> inline TVector4<T> operator*(T f, const TVector4<T> &v) {
820  return v*f;
821 }
822 
823 template <typename T> inline T dot(const TVector4<T> &v1, const TVector4<T> &v2) {
824  return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
825 }
826 
827 template <typename T> inline T absDot(const TVector4<T> &v1, const TVector4<T> &v2) {
828  return std::abs(dot(v1, v2));
829 }
830 
831 template <typename T> inline TVector4<T> normalize(const TVector4<T> &v) {
832  return v / v.length();
833 }
834 
835 template <typename T> inline TVector4<T> normalizeStrict(const TVector4<T> &v, const char *errMsg) {
836  Float length = v.length();
837  if (length == 0)
838  SLog(EError, "normalizeStrict(): %s", errMsg);
839  return v / length;
840 }
841 
842 template <> inline TVector4<int> TVector4<int>::operator/(int s) const {
843 #ifdef MTS_DEBUG
844  if (s == 0)
845  SLog(EWarn, "Vector4i: Division by zero!");
846 #endif
847  return TVector4(x/s, y/s, z/s, w/s);
848 }
849 
850 template <> inline TVector4<int> &TVector4<int>::operator/=(int s) {
851 #ifdef MTS_DEBUG
852  if (s == 0)
853  SLog(EWarn, "Vector4i: Division by zero!");
854 #endif
855 
856  x /= s;
857  y /= s;
858  z /= s;
859  w /= s;
860  return *this;
861 }
862 
864 
865 #endif /* __MITSUBA_CORE_VECTOR_H_ */
TVector4(const TPoint4< T2 > &p)
Initialize the vector with the components of a point data structure.
Definition: vector.h:698
T length() const
Return the 1-norm of this vector.
Definition: vector.h:144
TVector1 & operator-=(const TVector1 &v)
Subtract another vector from the current one.
Definition: vector.h:88
T operator[](int i) const
Index into the vector&#39;s components (const version)
Definition: vector.h:561
LengthType length() const
Return the 2-norm of this vector.
Definition: vector.h:366
TVector2< int > & operator/=(int s)
Definition: vector.h:434
TVector2 operator+(const TVector2 &v) const
Add two vectors and return the result.
Definition: vector.h:292
TVector2 & operator/=(T f)
Divide the vector by the given scalar.
Definition: vector.h:340
TVector4< T > operator*(T f, const TVector4< T > &v)
Definition: vector.h:819
TVector3()
Construct a new vector without initializing it.
Definition: vector.h:470
TVector1(Stream *stream)
Unserialize a vector from a binary data stream.
Definition: vector.h:67
T readElement()
Read an element from the stream (uses partial template specialization to select a method appropriate ...
Definition: stream.h:508
std::string toString() const
Return a readable string representation of this vector.
Definition: vector.h:172
T & operator[](int i)
Index into the vector&#39;s components.
Definition: vector.h:769
T lengthSquared() const
Return the squared 2-norm of this vector.
Definition: vector.h:779
TVector2(const TVector2< T2 > &v)
Initialize the vector with the components of another vector data structure.
Definition: vector.h:278
T type
Definition: vector.h:224
TVector3 operator-() const
Return a negated version of the vector.
Definition: vector.h:530
TVector3 & operator+=(const TVector3 &v)
Add another vector to the current one.
Definition: vector.h:507
TVector1 & operator/=(T f)
Divide the vector by the given scalar.
Definition: vector.h:119
TVector4(Stream *stream)
Unserialize a vector from a binary data stream.
Definition: vector.h:702
void serialize(Stream *stream) const
Serialize this vector to a binary data stream.
Definition: vector.h:164
T dot(const TVector4< T > &v1, const TVector4< T > &v2)
Definition: vector.h:823
TVector2 operator/(T f) const
Divide the vector by the given scalar and return the result.
Definition: vector.h:330
T absDot(const TVector4< T > &v1, const TVector4< T > &v2)
Definition: vector.h:827
T y
Definition: vector.h:455
T x
Definition: vector.h:667
TPoint4< T > PointType
Definition: vector.h:664
detail::VectorLength< T, std::numeric_limits< T >::is_integer >::type LengthType
Definition: vector.h:453
TVector1< int > operator/(int s) const
Definition: vector.h:202
Parameterizable one-dimensional point data structure.
Definition: point.h:33
detail::VectorLength< T, std::numeric_limits< T >::is_integer >::type LengthType
Definition: vector.h:249
TVector3 operator-(const TVector3 &v) const
Subtract two vectors and return the result.
Definition: vector.h:502
void serialize(Stream *stream) const
Serialize this vector to a binary data stream.
Definition: vector.h:591
T Scalar
Definition: vector.h:247
TVector4< T > normalizeStrict(const TVector4< T > &v, const char *errMsg)
Definition: vector.h:835
TVector4 operator-(const TVector4 &v) const
Subtract two vectors and return the result.
Definition: vector.h:715
TVector4 operator/(T f) const
Divide the vector by the given scalar and return the result.
Definition: vector.h:748
TVector2 operator*(T f) const
Multiply the vector by the given scalar and return the result.
Definition: vector.h:314
#define SLog(level, fmt,...)
Write a Log message to the console (static version - to be used outside of classes that derive from O...
Definition: logger.h:49
TVector1()
Construct a new vector without initializing it.
Definition: vector.h:50
T z
Definition: vector.h:667
TVector3 operator/(T f) const
Divide the vector by the given scalar and return the result.
Definition: vector.h:535
TPoint1< T > PointType
Definition: vector.h:33
TVector4 & operator/=(T f)
Divide the vector by the given scalar.
Definition: vector.h:758
TVector1 operator-() const
Return a negated version of the vector.
Definition: vector.h:105
TVector3(T val)
Initialize all components of the the vector with the specified value.
Definition: vector.h:479
TVector1(const TVector1< T1 > &v)
Initialize the vector with the components of another vector data structure.
Definition: vector.h:59
T det(const TVector2< T > &v1, const TVector2< T > &v2)
Definition: vector.h:411
TVector1 operator-(const TVector1 &v) const
Subtract two vectors and return the result.
Definition: vector.h:77
TVector2 operator-(const TVector2 &v) const
Subtract two vectors and return the result.
Definition: vector.h:297
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
TVector3(T x, T y, T z)
Initialize the vector with the specified X, Y and Z components.
Definition: vector.h:476
TPoint2< T > PointType
Definition: vector.h:248
T Scalar
Definition: vector.h:663
TVector4< int > & operator/=(int s)
Definition: vector.h:850
TVector4()
Construct a new vector without initializing it.
Definition: vector.h:682
TVector3(const TPoint3< T2 > &p)
Initialize the vector with the components of a point data structure.
Definition: vector.h:486
T Scalar
Definition: vector.h:451
Float type
Definition: vector.h:228
TVector3 & operator/=(T f)
Divide the vector by the given scalar.
Definition: vector.h:545
TVector1 & operator*=(T f)
Multiply the vector by the given scalar.
Definition: vector.h:99
T x
Definition: vector.h:251
T Scalar
Definition: vector.h:32
TVector2 & operator-=(const TVector2 &v)
Subtract another vector from the current one.
Definition: vector.h:308
TVector2 operator-() const
Return a negated version of the vector.
Definition: vector.h:325
T x
Definition: vector.h:35
bool operator==(const TVector2 &v) const
Equality test.
Definition: vector.h:376
bool isZero() const
Return whether or not this vector is identically zero.
Definition: vector.h:149
void serialize(Stream *stream) const
Serialize this vector to a binary data stream.
Definition: vector.h:386
T & operator[](int i)
Index into the vector&#39;s components.
Definition: vector.h:351
Parameterizable two-dimensional point data structure.
Definition: point.h:222
TVector3 & operator*=(T f)
Multiply the vector by the given scalar.
Definition: vector.h:524
TVector1 operator/(T f) const
Divide the vector by the given scalar and return the result.
Definition: vector.h:110
T lengthSquared() const
Return the squared 1-norm of this vector.
Definition: vector.h:139
TVector3 & operator-=(const TVector3 &v)
Subtract another vector from the current one.
Definition: vector.h:513
LengthType length() const
Return the 2-norm of this vector.
Definition: vector.h:784
void serialize(Stream *stream) const
Serialize this vector to a binary data stream.
Definition: vector.h:804
bool operator==(const TVector4 &v) const
Equality test.
Definition: vector.h:794
TVector3(Stream *stream)
Unserialize a vector from a binary data stream.
Definition: vector.h:490
std::string toString() const
Return a readable string representation of this vector.
Definition: vector.h:392
T z
Definition: vector.h:455
Parameterizable one-dimensional vector data structure.
Definition: vector.h:31
TVector2()
Construct a new vector without initializing it.
Definition: vector.h:266
TVector2(T val)
Initialize all components of the the vector with the specified value.
Definition: vector.h:275
T operator[](int i) const
Index into the vector&#39;s components (const version)
Definition: vector.h:134
Parameterizable three-dimensional vector data structure.
Definition: vector.h:450
TVector1< int > & operator/=(int s)
Definition: vector.h:210
void writeElement(T value)
Write an element to the stream (uses partial template specialization to select a method appropriate t...
Definition: stream.h:512
T operator[](int i) const
Index into the vector&#39;s components (const version)
Definition: vector.h:774
TVector4 operator*(T f) const
Multiply the vector by the given scalar and return the result.
Definition: vector.h:732
LengthType length() const
Return the 2-norm of this vector.
Definition: vector.h:571
bool operator!=(const TVector3 &v) const
Inequality test.
Definition: vector.h:586
TVector1 operator+(const TVector1 &v) const
Add two vectors and return the result.
Definition: vector.h:72
Abstract seekable stream class.
Definition: stream.h:58
TVector4(T val)
Initialize all components of the the vector with the specified value.
Definition: vector.h:691
Warning message.
Definition: formatter.h:32
TVector2< int > operator/(int s) const
Definition: vector.h:426
T x
Definition: vector.h:455
Definition: vector.h:223
std::string toString() const
Return a readable string representation of this vector.
Definition: vector.h:812
bool isZero() const
Return whether or not this vector is identically zero.
Definition: vector.h:371
bool operator!=(const TVector4 &v) const
Inequality test.
Definition: vector.h:799
TVector4(const TVector4< T2 > &v)
Initialize the vector with the components of another vector data structure.
Definition: vector.h:694
T & operator[](int i)
Index into the vector&#39;s components.
Definition: vector.h:129
detail::VectorLength< T, std::numeric_limits< T >::is_integer >::type LengthType
Definition: vector.h:665
TVector2 & operator+=(const TVector2 &v)
Add another vector to the current one.
Definition: vector.h:302
TVector3 operator+(const TVector3 &v) const
Add two vectors and return the result.
Definition: vector.h:497
Definition: fwd.h:96
Error message, causes an exception to be thrown.
Definition: formatter.h:33
Parameterizable three-dimensional point data structure.
Definition: point.h:415
T y
Definition: vector.h:251
TVector4 & operator*=(T f)
Multiply the vector by the given scalar.
Definition: vector.h:737
TVector4< int > operator/(int s) const
Definition: vector.h:842
Definition: fwd.h:94
T operator[](int i) const
Index into the vector&#39;s components (const version)
Definition: vector.h:356
bool operator==(const TVector1 &v) const
Equality test.
Definition: vector.h:154
bool operator==(const TVector3 &v) const
Equality test.
Definition: vector.h:581
TVector2(Stream *stream)
Unserialize a vector from a binary data stream.
Definition: vector.h:286
Parameterizable two-dimensional vector data structure.
Definition: vector.h:246
TVector3(const TVector3< T2 > &v)
Initialize the vector with the components of another vector data structure.
Definition: vector.h:482
TVector1(const TPoint1< T1 > &p)
Initialize the vector with the components of a point data structure.
Definition: vector.h:63
TVector3 operator*(T f) const
Multiply the vector by the given scalar and return the result.
Definition: vector.h:519
Parameterizable four-dimensional vector data structure.
Definition: vector.h:662
TVector4 & operator+=(const TVector4 &v)
Add another vector to the current one.
Definition: vector.h:720
T lengthSquared() const
Return the squared 2-norm of this vector.
Definition: vector.h:566
TVector3< int > & operator/=(int s)
Definition: vector.h:644
T y
Definition: vector.h:667
TVector3< int > operator/(int s) const
Definition: vector.h:636
bool operator!=(const TVector1 &v) const
Inequality test.
Definition: vector.h:159
TVector4< T > normalize(const TVector4< T > &v)
Definition: vector.h:831
double type
Definition: vector.h:236
TVector1(T x)
Initialize the vector with the specified value.
Definition: vector.h:56
TVector1 operator*(T f) const
Multiply the vector by the given scalar and return the result.
Definition: vector.h:94
bool operator!=(const TVector2 &v) const
Inequality test.
Definition: vector.h:381
TVector3< T > cross(const TVector3< T > &v1, const TVector3< T > &v2)
Definition: vector.h:617
TVector4 operator+(const TVector4 &v) const
Add two vectors and return the result.
Definition: vector.h:710
TVector4 & operator-=(const TVector4 &v)
Subtract another vector from the current one.
Definition: vector.h:726
bool isZero() const
Return whether or not this vector is identically zero.
Definition: vector.h:789
Definition: fwd.h:97
Parameterizable four-dimensional point data structure.
Definition: point.h:612
TVector2(T x, T y)
Initialize the vector with the specified X and Z components.
Definition: vector.h:272
TVector4(T x, T y, T z, T w)
Initialize the vector with the specified X, Y and Z components.
Definition: vector.h:688
Definition: fwd.h:95
TPoint3< T > PointType
Definition: vector.h:452
TVector1 & operator+=(const TVector1 &v)
Add another vector to the current one.
Definition: vector.h:82
#define MTS_NAMESPACE_END
Definition: platform.h:138
T w
Definition: vector.h:667
T & operator[](int i)
Index into the vector&#39;s components.
Definition: vector.h:556
std::string toString() const
Return a readable string representation of this vector.
Definition: vector.h:598
bool isZero() const
Return whether or not this vector is identically zero.
Definition: vector.h:576
TVector2 & operator*=(T f)
Multiply the vector by the given scalar.
Definition: vector.h:319
TVector4 operator-() const
Return a negated version of the vector.
Definition: vector.h:743
TVector2(const TPoint2< T2 > &p)
Initialize the vector with the components of a point data structure.
Definition: vector.h:282
T lengthSquared() const
Return the squared 2-norm of this vector.
Definition: vector.h:361