Nori
|
00001 /* 00002 This file is part of Nori, a simple educational ray tracer 00003 00004 Copyright (c) 2012 by Wenzel Jakob and Steve Marschner. 00005 00006 Nori is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License Version 3 00008 as published by the Free Software Foundation. 00009 00010 Nori is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #if !defined(__VECTOR_H) 00020 #define __VECTOR_H 00021 00022 #include <nori/common.h> 00023 00024 NORI_NAMESPACE_BEGIN 00025 00026 /* =================================================================== 00027 This file contains a few templates and specializations that 00028 provide 2/3D points, vectors, and normals over different 00029 underlying data types. Points, vectors, and normals are distinct 00030 in Nori, because they transform differently under homogeneous 00031 coordinate transformations. 00032 * =================================================================== */ 00033 00034 /** 00035 * \brief Generic N-dimensional vector data structure based on Eigen::Matrix 00036 */ 00037 template <typename _Scalar, int _Dimension> struct TVector : public Eigen::Matrix<_Scalar, _Dimension, 1> { 00038 public: 00039 enum { 00040 Dimension = _Dimension 00041 }; 00042 00043 typedef _Scalar Scalar; 00044 typedef Eigen::Matrix<Scalar, Dimension, 1> Base; 00045 typedef TVector<Scalar, Dimension> VectorType; 00046 typedef TPoint<Scalar, Dimension> PointType; 00047 00048 /// Create a new vector with constant component vlaues 00049 inline TVector(Scalar value = (Scalar) 0) { setConstant(value); } 00050 00051 /// Create a new 2D vector (type error if \c Dimension != 2) 00052 inline TVector(Scalar x, Scalar y) : Base(x, y) { } 00053 00054 /// Create a new 3D vector (type error if \c Dimension != 3) 00055 inline TVector(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { } 00056 00057 /// Create a new 4D vector (type error if \c Dimension != 4) 00058 inline TVector(Scalar x, Scalar y, Scalar z, Scalar w) : Base(x, y, z, w) { } 00059 00060 /// Construct a vector from MatrixBase (needed to play nice with Eigen) 00061 template <typename Derived> inline TVector(const Eigen::MatrixBase<Derived>& p) 00062 : Base(p) { } 00063 00064 /// Assign a vector from MatrixBase (needed to play nice with Eigen) 00065 template <typename Derived> TVector &operator=(const Eigen::MatrixBase<Derived>& p) { 00066 this->Base::operator=(p); 00067 return *this; 00068 } 00069 00070 /// Return a human-readable string summary 00071 inline QString toString() const { 00072 QString result; 00073 for (size_t i=0; i<Dimension; ++i) { 00074 result += QString("%1").arg(this->coeff(i)); 00075 if (i+1 < Dimension) 00076 result += ", "; 00077 } 00078 return "[" + result + "]"; 00079 } 00080 }; 00081 00082 /** 00083 * \brief Generic N-dimensional point data structure based on Eigen::Matrix 00084 */ 00085 template <typename _Scalar, int _Dimension> struct TPoint : public Eigen::Matrix<_Scalar, _Dimension, 1> { 00086 public: 00087 enum { 00088 Dimension = _Dimension 00089 }; 00090 00091 typedef _Scalar Scalar; 00092 typedef Eigen::Matrix<Scalar, Dimension, 1> Base; 00093 typedef TVector<Scalar, Dimension> VectorType; 00094 typedef TPoint<Scalar, Dimension> PointType; 00095 00096 /// Create a new point with constant component vlaues 00097 inline TPoint(Scalar value = (Scalar) 0) { setConstant(value); } 00098 00099 /// Create a new 2D point (type error if \c Dimension != 2) 00100 inline TPoint(Scalar x, Scalar y) : Base(x, y) { } 00101 00102 /// Create a new 3D point (type error if \c Dimension != 3) 00103 inline TPoint(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { } 00104 00105 /// Create a new 4D point (type error if \c Dimension != 4) 00106 inline TPoint(Scalar x, Scalar y, Scalar z, Scalar w) : Base(x, y, z, w) { } 00107 00108 /// Construct a point from MatrixBase (needed to play nice with Eigen) 00109 template <typename Derived> inline TPoint(const Eigen::MatrixBase<Derived>& p) 00110 : Base(p) { } 00111 00112 /// Assign a point from MatrixBase (needed to play nice with Eigen) 00113 template <typename Derived> TPoint &operator=(const Eigen::MatrixBase<Derived>& p) { 00114 this->Base::operator=(p); 00115 return *this; 00116 } 00117 00118 /// Return a human-readable string summary 00119 inline QString toString() const { 00120 QString result; 00121 for (size_t i=0; i<Dimension; ++i) { 00122 result += QString("%1").arg(this->coeff(i)); 00123 if (i+1 < Dimension) 00124 result += ", "; 00125 } 00126 return "[" + result + "]"; 00127 } 00128 }; 00129 00130 /** 00131 * \brief 3-dimensional surface normal representation 00132 */ 00133 struct Normal3f : public Eigen::Matrix<float, 3, 1> { 00134 public: 00135 enum { 00136 Dimension = 3 00137 }; 00138 00139 typedef float Scalar; 00140 typedef Eigen::Matrix<Scalar, Dimension, 1> Base; 00141 typedef TVector<Scalar, Dimension> VectorType; 00142 typedef TPoint<Scalar, Dimension> PointType; 00143 00144 00145 /// Create a new normal with constant component vlaues 00146 inline Normal3f(Scalar value = 0.0f) { setConstant(value); } 00147 00148 /// Create a new 3D normal 00149 inline Normal3f(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { } 00150 00151 /// Construct a normal from MatrixBase (needed to play nice with Eigen) 00152 template <typename Derived> inline Normal3f(const Eigen::MatrixBase<Derived>& p) 00153 : Base(p) { } 00154 00155 /// Assign a normal from MatrixBase (needed to play nice with Eigen) 00156 template <typename Derived> Normal3f &operator=(const Eigen::MatrixBase<Derived>& p) { 00157 this->Base::operator=(p); 00158 return *this; 00159 } 00160 00161 /// Return a human-readable string summary 00162 inline QString toString() const { 00163 return QString("[%1, %2, %3]").arg(coeff(0)).arg(coeff(1)).arg(coeff(2)); 00164 } 00165 }; 00166 00167 /// Complete the set {a} to an orthonormal base 00168 extern void coordinateSystem(const Vector3f &a, Vector3f &b, Vector3f &c); 00169 00170 NORI_NAMESPACE_END 00171 00172 #endif /* __VECTOR_H */ 00173