/* This file is part of Nori, a simple educational ray tracer Copyright (c) 2015 by Wenzel Jakob Nori is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 as published by the Free Software Foundation. Nori is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #pragma once #include NORI_NAMESPACE_BEGIN /* =================================================================== This file contains a few templates and specializations, which provide 2/3D points, vectors, and normals over different underlying data types. Points, vectors, and normals are distinct in Nori, because they transform differently under homogeneous coordinate transformations. * =================================================================== */ /** * \brief Generic N-dimensional vector data structure based on Eigen::Matrix */ template struct TVector : public Eigen::Matrix<_Scalar, _Dimension, 1> { public: enum { Dimension = _Dimension }; typedef _Scalar Scalar; typedef Eigen::Matrix Base; typedef TVector VectorType; typedef TPoint PointType; /// Create a new vector with constant component vlaues TVector(Scalar value = (Scalar) 0) { Base::setConstant(value); } /// Create a new 2D vector (type error if \c Dimension != 2) TVector(Scalar x, Scalar y) : Base(x, y) { } /// Create a new 3D vector (type error if \c Dimension != 3) TVector(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { } /// Create a new 4D vector (type error if \c Dimension != 4) TVector(Scalar x, Scalar y, Scalar z, Scalar w) : Base(x, y, z, w) { } /// Construct a vector from MatrixBase (needed to play nice with Eigen) template TVector(const Eigen::MatrixBase& p) : Base(p) { } /// Assign a vector from MatrixBase (needed to play nice with Eigen) template TVector &operator=(const Eigen::MatrixBase& p) { this->Base::operator=(p); return *this; } /// Return a human-readable string summary std::string toString() const { std::string result; for (size_t i=0; icoeff(i)); if (i+1 < Dimension) result += ", "; } return "[" + result + "]"; } }; /** * \brief Generic N-dimensional point data structure based on Eigen::Matrix */ template struct TPoint : public Eigen::Matrix<_Scalar, _Dimension, 1> { public: enum { Dimension = _Dimension }; typedef _Scalar Scalar; typedef Eigen::Matrix Base; typedef TVector VectorType; typedef TPoint PointType; /// Create a new point with constant component vlaues TPoint(Scalar value = (Scalar) 0) { Base::setConstant(value); } /// Create a new 2D point (type error if \c Dimension != 2) TPoint(Scalar x, Scalar y) : Base(x, y) { } /// Create a new 3D point (type error if \c Dimension != 3) TPoint(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { } /// Create a new 4D point (type error if \c Dimension != 4) TPoint(Scalar x, Scalar y, Scalar z, Scalar w) : Base(x, y, z, w) { } /// Construct a point from MatrixBase (needed to play nice with Eigen) template TPoint(const Eigen::MatrixBase& p) : Base(p) { } /// Assign a point from MatrixBase (needed to play nice with Eigen) template TPoint &operator=(const Eigen::MatrixBase& p) { this->Base::operator=(p); return *this; } /// Return a human-readable string summary std::string toString() const { std::string result; for (size_t i=0; icoeff(i)); if (i+1 < Dimension) result += ", "; } return "[" + result + "]"; } }; /** * \brief 3-dimensional surface normal representation */ struct Normal3f : public Eigen::Matrix { public: enum { Dimension = 3 }; typedef float Scalar; typedef Eigen::Matrix Base; typedef TVector VectorType; typedef TPoint PointType; /// Create a new normal with constant component vlaues Normal3f(Scalar value = 0.0f) { Base::setConstant(value); } /// Create a new 3D normal Normal3f(Scalar x, Scalar y, Scalar z) : Base(x, y, z) { } /// Construct a normal from MatrixBase (needed to play nice with Eigen) template Normal3f(const Eigen::MatrixBase& p) : Base(p) { } /// Assign a normal from MatrixBase (needed to play nice with Eigen) template Normal3f &operator=(const Eigen::MatrixBase& p) { this->Base::operator=(p); return *this; } /// Return a human-readable string summary std::string toString() const { return tfm::format("[%f, %f, %f]", coeff(0), coeff(1), coeff(2)); } }; /// Complete the set {a} to an orthonormal base extern void coordinateSystem(const Vector3f &a, Vector3f &b, Vector3f &c); NORI_NAMESPACE_END