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(__TRANSFORM_H) 00020 #define __TRANSFORM_H 00021 00022 #include <nori/common.h> 00023 #include <nori/ray.h> 00024 00025 NORI_NAMESPACE_BEGIN 00026 00027 /** 00028 * \brief Homogeneous coordinate transformation 00029 * 00030 * This class stores a general homogeneous coordinate tranformation, such as 00031 * rotation, translation, uniform or non-uniform scaling, and perspective 00032 * transformations. The inverse of this transformation is also recorded 00033 * here, since it is required when transforming normal vectors. 00034 */ 00035 struct Transform { 00036 public: 00037 /// Create the identity transform 00038 Transform() : 00039 m_transform(Eigen::Matrix4f::Identity()), 00040 m_inverse(Eigen::Matrix4f::Identity()) { } 00041 00042 /// Create a new transform instance for the given matrix 00043 Transform(const Eigen::Matrix4f &trafo); 00044 00045 /// Create a new transform instance for the given matrix and its inverse 00046 Transform(const Eigen::Matrix4f &trafo, const Eigen::Matrix4f &inv) 00047 : m_transform(trafo), m_inverse(inv) { } 00048 00049 /// Return the underlying matrix 00050 inline const Eigen::Matrix4f &getMatrix() const { 00051 return m_transform; 00052 } 00053 00054 /// Return the inverse of the underlying matrix 00055 inline const Eigen::Matrix4f &getInverseMatrix() const { 00056 return m_inverse; 00057 } 00058 00059 /// Return the inverse transformation 00060 Transform inverse() const { 00061 return Transform(m_inverse, m_transform); 00062 } 00063 00064 /// Concatenate with another transform 00065 Transform operator*(const Transform &t) const; 00066 00067 /// Apply the homogeneous transformation to a 3D vector 00068 inline Vector3f operator*(const Vector3f &v) const { 00069 return m_transform.topLeftCorner<3,3>() * v; 00070 } 00071 00072 /// Apply the homogeneous transformation to a 3D normal 00073 inline Normal3f operator*(const Normal3f &n) const { 00074 return m_inverse.topLeftCorner<3, 3>().transpose() * n; 00075 } 00076 00077 /// Transform a point by an arbitrary matrix in homogeneous coordinates 00078 inline Point3f operator*(const Point3f &p) const { 00079 Vector4f result = m_transform * Vector4f(p[0], p[1], p[2], 1.0f); 00080 return result.head<3>() / result.w(); 00081 } 00082 00083 /// Apply the homogeneous transformation to a ray 00084 inline Ray3f operator&(const Ray3f &r) const { 00085 return Ray3f( 00086 operator*(r.o), 00087 operator*(r.d), 00088 r.mint, r.maxt 00089 ); 00090 } 00091 00092 /// Return a string representation 00093 QString toString() const; 00094 private: 00095 Eigen::Matrix4f m_transform; 00096 Eigen::Matrix4f m_inverse; 00097 }; 00098 00099 NORI_NAMESPACE_END 00100 00101 #endif /* __TRANSFORM_H */