diff --git a/CGII/src/AtomicTransform.cpp b/CGII/src/AtomicTransform.cpp index 6719e43..3115041 100644 --- a/CGII/src/AtomicTransform.cpp +++ b/CGII/src/AtomicTransform.cpp @@ -102,30 +102,72 @@ float angle(const Vec3 &v1, const Vec3 &v2) return std::acos(d / (v1_length * v2_length)); } -/* -fn angle(v1 - : cgmath::Vector2) - ->f32 +float a(float rcos, float x) { - let dot = v1.x * DEFAULT_DIRECTION.x + v1.y * DEFAULT_DIRECTION.y; - - let v1_len = ((v1.x * v1.x) + (v1.y * v1.y)).sqrt(); - let v2_len = ((DEFAULT_DIRECTION.x * DEFAULT_DIRECTION.x) + (DEFAULT_DIRECTION.y * DEFAULT_DIRECTION.y)) - .sqrt(); - - let angle = (dot / (v1_len * v2_len)).acos(); - - if - v1.x < 0.0 - { - -angle - } - else - { - angle - } + return rcos + x * x * (1 - rcos); +} + +float b(float rcos, float rsin, float x, float y, float z) +{ + return -z * rsin + y * x * (1 - rcos); +} + +float c(float rcos, float rsin, float x, float y, float z) +{ + return y * rsin + z * x * (1 - rcos); +} + +float d(float rcos, float rsin, float x, float y, float z) +{ + return z * rsin + x * y * (1 - rcos); +} + +float e(float rcos, float y) +{ + return rcos + y * y * (1 - rcos); +} + +float f(float rcos, float rsin, float x, float y, float z) +{ + return -x * rsin + z * y * (1 - rcos); +} + +float g(float rcos, float rsin, float x, float y, float z) +{ + return -y * rsin + x * z * (1 - rcos); +} + +float h(float rcos, float rsin, float x, float y, float z) +{ + return x * rsin + y * z * (1 - rcos); +} + +float j(float rcos, float z) +{ + rcos + z *z *(1 - rcos); +} + +float AtomicRotationTransform::least_squares(const Vec3 &local_vector, const Vec3 &target, float r) +{ + float angler = r * PI / 180.0f; + + float rcos = cos(angler); + float rsin = sin(angler); + + float x = axis.x(); + float y = axis.y(); + float z = axis.z(); + + float xs = a(rcos, x) * local_vector.x() + b(rcos, rsin, x, y, z) * local_vector.y() + c(rcos, rsin, x, y, z) * local_vector.z(); + float ys = d(rcos, rsin, x, y, z) * local_vector.x() + e(rcos, y) * local_vector.y() + f(rcos, rsin, x, y, z) * local_vector.z(); + float zs = g(rcos, rsin, x, y, z) * local_vector.x() + h(rcos, rsin, x, y, z) * local_vector.y() + j(rcos, z); + + float x_diff = xs - target.x(); + float y_diff = ys - target.y(); + float z_diff = zs - target.z(); + + float squares = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff; } -*/ void AtomicRotationTransform::optimize_value(const Vec3 &local_vector, const Vec3 &target, bool inverse) { @@ -133,7 +175,9 @@ void AtomicRotationTransform::optimize_value(const Vec3 &local_vector, const Vec // optimize this that: target = this->calculate_matrix() * local_vector; - double result = angle(local_vector, target); + float first_guess = angle(local_vector, target); + + double result = least_squares(local_vector, target, first_guess); if (inverse) result = -result; diff --git a/CGII/src/AtomicTransform.h b/CGII/src/AtomicTransform.h index 332f0d0..1edbf8c 100644 --- a/CGII/src/AtomicTransform.h +++ b/CGII/src/AtomicTransform.h @@ -1,5 +1,5 @@ -// This source code is property of the Computer Graphics and Visualization -// chair of the TU Dresden. Do not distribute! +// This source code is property of the Computer Graphics and Visualization +// chair of the TU Dresden. Do not distribute! // Copyright (C) CGV TU Dresden - All Rights Reserved // #pragma once @@ -14,30 +14,30 @@ class Transform { -public: + public: //Calculates a matrix that represents the current transform. virtual Mat4 calculate_matrix() = 0; //Optimizes the current value, such that T * local_vector = target in a least-squares sense. - virtual void optimize_value(const Vec3& local_vector, const Vec3& target) = 0; + virtual void optimize_value(const Vec3 &local_vector, const Vec3 &target) = 0; }; class StaticTransform : public Transform { -public: - StaticTransform(const Mat4& t) : t(t) {} + public: + StaticTransform(const Mat4 &t) : t(t) {} Mat4 calculate_matrix() { return t; } - void optimize_value(const Vec3& local_vector, const Vec3& target) { } + void optimize_value(const Vec3 &local_vector, const Vec3 &target) {} -private: + private: Mat4 t; }; //Represents an arbitrary affine transform with exactly one scalar parameter class AtomicTransform : public cgv::gui::control_provider, public Transform { -public: + public: //Sets the limits of the scalar parameter void set_limits(double lower, double upper); @@ -45,24 +45,24 @@ public: const double get_upper_limit() const; //Sets the current scalar parameter. Ignore ud. - virtual void set_value(const double& value, void* ud = nullptr); + virtual void set_value(const double &value, void *ud = nullptr); //Gets the current scalar parameter. Ignore ud. - const double get_value(void* ud = nullptr) const; + const double get_value(void *ud = nullptr) const; //Calculates a matrix that represents the current transform. virtual Mat4 calculate_matrix() = 0; //Optimizes the current value, such that T * local_vector = target in a least-squares sense. - virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false) = 0; - virtual void optimize_value(const Vec3& local_vector, const Vec3& target) { optimize_value(local_vector, target, false); } + virtual void optimize_value(const Vec3 &local_vector, const Vec3 &target, bool inverse = false) = 0; + virtual void optimize_value(const Vec3 &local_vector, const Vec3 &target) { optimize_value(local_vector, target, false); } //Draws an indicator that visualizes the transform, including its limits. virtual void drawIndicator(float size) = 0; //Draws an indicator that visualizes the current scalar parameter. virtual void drawActualIndicator(float size) = 0; - std::string get_name() const; + std::string get_name() const; //Signal that is raised whenever the scalar parameter changes cgv::signal::signal changed_signal; @@ -73,7 +73,7 @@ public: //Get the order in which the transform is specified in the animation file. int get_index_in_amc() const { return index_in_amc; } -protected: + protected: double lower_limit, upper_limit; double value; std::string title; @@ -82,79 +82,82 @@ protected: class AtomicRotationTransform : public AtomicTransform { -public: + public: AtomicRotationTransform(Vec3 axis); virtual Mat4 calculate_matrix(); - virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false); + virtual void optimize_value(const Vec3 &local_vector, const Vec3 &target, bool inverse = false); virtual void drawIndicator(float size); virtual void drawActualIndicator(float size); -protected: + private: + virtual float least_squares(const Vec3 &local_vector, const Vec3 &target, float r); + + protected: Vec3 axis; }; class AtomicXRotationTransform : public AtomicRotationTransform { -public: + public: AtomicXRotationTransform() : AtomicRotationTransform(Vec3(1, 0, 0)) { title = "X-Rotation"; } }; class AtomicYRotationTransform : public AtomicRotationTransform { -public: + public: AtomicYRotationTransform() : AtomicRotationTransform(Vec3(0, 1, 0)) { title = "Y-Rotation"; } }; class AtomicZRotationTransform : public AtomicRotationTransform { -public: + public: AtomicZRotationTransform() : AtomicRotationTransform(Vec3(0, 0, 1)) { title = "Z-Rotation"; } }; class AtomicTranslationTransform : public AtomicTransform { -public: + public: AtomicTranslationTransform(int dim); virtual Mat4 calculate_matrix(); - virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false); + virtual void optimize_value(const Vec3 &local_vector, const Vec3 &target, bool inverse = false); - virtual void drawIndicator(float size) { }; - virtual void drawActualIndicator(float size) { }; + virtual void drawIndicator(float size){}; + virtual void drawActualIndicator(float size){}; -private: + private: int dim; }; class AtomicXTranslationTransform : public AtomicTranslationTransform { -public: + public: AtomicXTranslationTransform() : AtomicTranslationTransform(0) { title = "X-Translation"; } }; class AtomicYTranslationTransform : public AtomicTranslationTransform { -public: + public: AtomicYTranslationTransform() : AtomicTranslationTransform(1) { title = "Y-Translation"; } }; class AtomicZTranslationTransform : public AtomicTranslationTransform { -public: + public: AtomicZTranslationTransform() : AtomicTranslationTransform(2) { title = "Z-Translation"; } }; class InverseTransform : public Transform { -public: - InverseTransform(std::shared_ptr t) : t(t) { } + public: + InverseTransform(std::shared_ptr t) : t(t) {} Mat4 calculate_matrix() { return cgv::math::inv(t->calculate_matrix()); } - void optimize_value(const Vec3& local_vector, const Vec3& target) + void optimize_value(const Vec3 &local_vector, const Vec3 &target) { t->optimize_value(local_vector, target, true); } -private: + private: std::shared_ptr t; }; \ No newline at end of file diff --git a/framework/include/cgv/math/transformations.h b/framework/include/cgv/math/transformations.h index 0407f82..82b853d 100644 --- a/framework/include/cgv/math/transformations.h +++ b/framework/include/cgv/math/transformations.h @@ -2,265 +2,309 @@ #include "vec.h" #include "mat.h" -namespace cgv { -namespace math { - +namespace cgv +{ +namespace math +{ ///creates a 3x3 scale matrix template -const mat scale_33(const T&sx, const T &sy, const T&sz) +const mat scale_33(const T &sx, const T &sy, const T &sz) { - mat m(3,3); - m(0,0)=sx; m(0,1)= 0; m(0,2)= 0; - m(1,0)=0; m(1,1)=sy; m(1,2)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= sz; + mat m(3, 3); + m(0, 0) = sx; + m(0, 1) = 0; + m(0, 2) = 0; + m(1, 0) = 0; + m(1, 1) = sy; + m(1, 2) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = sz; return m; } ///creates a 3x3 uniform scale matrix template -const mat scale_33(const T&s) +const mat scale_33(const T &s) { - mat m(3,3); - m(0,0)=s; m(0,1)= 0; m(0,2)= 0; - m(1,0)=0; m(1,1)=s; m(1,2)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= s; + mat m(3, 3); + m(0, 0) = s; + m(0, 1) = 0; + m(0, 2) = 0; + m(1, 0) = 0; + m(1, 1) = s; + m(1, 2) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = s; return m; } - - -///creates a 3x3 rotation matrix around the x axis, the angle is in degree -template -const mat rotatex_33(const T& angle) +///creates a 3x3 rotation matrix around the x axis, the angle is in degree +template +const mat rotatex_33(const T &angle) { - T angler = angle*(T)3.14159/(T)180.0; - mat m(3,3); - m(0,0)=1; m(0,1)= 0; m(0,2)= 0; - m(1,0)=0; m(1,1)= (T)cos((double)angler); - m(1,2)= -(T)sin((double)angler); - m(2,0)=0; m(2,1)= (T)sin((double)angler); - m(2,2)= (T)cos((double)angler); - - return m; -} + T angler = angle * (T)3.14159 / (T)180.0; + mat m(3, 3); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = 0; + m(1, 0) = 0; + m(1, 1) = (T)cos((double)angler); + m(1, 2) = -(T)sin((double)angler); + m(2, 0) = 0; + m(2, 1) = (T)sin((double)angler); + m(2, 2) = (T)cos((double)angler); -///creates a 3x3 rotation matrix around the y axis, the angle is in degree -template -const mat rotatey_33(const T& angle) -{ - T angler=angle*(T)3.14159/(T)180.0; - mat m(3,3); - m(0,0)=(T)cos((double)angler); m(0,1)= 0; - m(0,2)= (T)sin((double)angler); - m(1,0)=0; m(1,1)=1; m(1,2)= 0; - m(2,0)=-(T)sin((double)angler); m(2,1)= 0; - m(2,2)= (T)cos((double)angler); - - - return m; -} - -///creates a 3x3 rotation matrix around the z axis, the angle is in degree -template -const mat rotatez_33(const T& angle) -{ - T angler=angle*(T)3.14159/(T)180.0; - mat m(3,3); - m(0,0)=(T)cos((double)angler); - m(0,1)= -(T)sin((double)angler); m(0,2)= 0; - m(1,0)=(T)sin((double)angler); - m(1,1)= (T)cos((double)angler); m(1,2)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= 1; - return m; -} - -///creates a 2x2 rotation matrix around the z axis, the angle is in degree -template -const mat rotate_22(const T& angle) -{ - T angler=angle*(T)3.14159/(T)180.0; - mat m(2,2); - m(0,0)=(T)cos((double)angler); - m(0,1)= -(T)sin((double)angler); - m(1,0)=(T)sin((double)angler); - m(1,1)= (T)cos((double)angler); - return m; -} - -template -const mat rotate_33(const T &dirx, const T &diry, const T&dirz, - const T& angle) -{ - - T angler = angle*(T)3.14159/(T)180.0; - mat m(3,3); - T rcos = cos(angler); - T rsin = sin(angler); - m(0,0)= rcos + dirx*dirx*((T)1-rcos); - m(0,1)= -dirz*rsin + diry*dirx*((T)1-rcos); - m(0,2)= diry*rsin + dirz*dirx*((T)1-rcos); - - - m(1,0)= dirz*rsin + dirx*diry*((T)1-rcos); - m(1,1)= rcos + diry*diry*((T)1-rcos); - m(1,2)= -dirx*rsin + dirz*diry*((T)1-rcos); - - - m(2,0)= -diry*rsin + dirx*dirz*((T)1-rcos); - m(2,1)= dirx*rsin + diry*dirz*((T)1-rcos); - m(2,2)= rcos + dirz*dirz*((T)1-rcos); - - return m; } - -///creates a 3x3 euler rotation matrix from yaw, pitch and roll given in degree -template -const mat rotate_euler_33(const T& yaw, const T& pitch,const T& roll) +///creates a 3x3 rotation matrix around the y axis, the angle is in degree +template +const mat rotatey_33(const T &angle) { - T yawd= (T)(yaw*3.14159/180.0); - T pitchd=(T)(pitch*3.14159/180.0); - T rolld=(T)(roll*3.14159/180.0); - T cosy =(T) cos(yawd); - T siny =(T) sin(yawd); - T cosp =(T) cos(pitchd); - T sinp =(T) sin(pitchd); - T cosr =(T) cos(rolld); - T sinr =(T) sin(rolld); - mat m(3,3); - - m(0,0) = cosr*cosy - sinr*sinp*siny; - m(0,1) = -sinr*cosp; - m(0,2) = cosr*siny + sinr*sinp*cosy; - + T angler = angle * (T)3.14159 / (T)180.0; + mat m(3, 3); + m(0, 0) = (T)cos((double)angler); + m(0, 1) = 0; + m(0, 2) = (T)sin((double)angler); + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = 0; + m(2, 0) = -(T)sin((double)angler); + m(2, 1) = 0; + m(2, 2) = (T)cos((double)angler); - m(1,0) = sinr*cosy + cosr*sinp*siny; - m(1,1) = cosr*cosp; - m(1,2) = sinr*siny - cosr*sinp*cosy; - + return m; +} - m(2,0) = -cosp*siny; - m(2,1) = sinp; - m(2,2) = cosp*cosy; - +///creates a 3x3 rotation matrix around the z axis, the angle is in degree +template +const mat rotatez_33(const T &angle) +{ + T angler = angle * (T)3.14159 / (T)180.0; + mat m(3, 3); + m(0, 0) = (T)cos((double)angler); + m(0, 1) = -(T)sin((double)angler); + m(0, 2) = 0; + m(1, 0) = (T)sin((double)angler); + m(1, 1) = (T)cos((double)angler); + m(1, 2) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = 1; + return m; +} - - return m; +///creates a 2x2 rotation matrix around the z axis, the angle is in degree +template +const mat rotate_22(const T &angle) +{ + T angler = angle * (T)3.14159 / (T)180.0; + mat m(2, 2); + m(0, 0) = (T)cos((double)angler); + m(0, 1) = -(T)sin((double)angler); + m(1, 0) = (T)sin((double)angler); + m(1, 1) = (T)cos((double)angler); + return m; } template -const mat star(const vec& v) +const mat rotate_33(const T &dirx, const T &diry, const T &dirz, + const T &angle) { - mat m(3,3); - - m(0,0) = 0; - m(0,1) = -v(2); - m(0,2) = v(1); - - m(1,0) = v(2); - m(1,1) = 0; - m(1,2) = -v(0); - + T angler = angle * (T)3.14159 / (T)180.0; + mat m(3, 3); + T rcos = cos(angler); + T rsin = sin(angler); + m(0, 0) = rcos + dirx * dirx * ((T)1 - rcos); + m(0, 1) = -dirz * rsin + diry * dirx * ((T)1 - rcos); + m(0, 2) = diry * rsin + dirz * dirx * ((T)1 - rcos); - m(2,0) = -v(1); - m(2,1) = v(0); - m(2,2) = 0; - + m(1, 0) = dirz * rsin + dirx * diry * ((T)1 - rcos); + m(1, 1) = rcos + diry * diry * ((T)1 - rcos); + m(1, 2) = -dirx * rsin + dirz * diry * ((T)1 - rcos); + + m(2, 0) = -diry * rsin + dirx * dirz * ((T)1 - rcos); + m(2, 1) = dirx * rsin + diry * dirz * ((T)1 - rcos); + m(2, 2) = rcos + dirz * dirz * ((T)1 - rcos); + + return m; +} + +///creates a 3x3 euler rotation matrix from yaw, pitch and roll given in degree +template +const mat rotate_euler_33(const T &yaw, const T &pitch, const T &roll) +{ + T yawd = (T)(yaw * 3.14159 / 180.0); + T pitchd = (T)(pitch * 3.14159 / 180.0); + T rolld = (T)(roll * 3.14159 / 180.0); + T cosy = (T)cos(yawd); + T siny = (T)sin(yawd); + T cosp = (T)cos(pitchd); + T sinp = (T)sin(pitchd); + T cosr = (T)cos(rolld); + T sinr = (T)sin(rolld); + mat m(3, 3); + + m(0, 0) = cosr * cosy - sinr * sinp * siny; + m(0, 1) = -sinr * cosp; + m(0, 2) = cosr * siny + sinr * sinp * cosy; + + m(1, 0) = sinr * cosy + cosr * sinp * siny; + m(1, 1) = cosr * cosp; + m(1, 2) = sinr * siny - cosr * sinp * cosy; + + m(2, 0) = -cosp * siny; + m(2, 1) = sinp; + m(2, 2) = cosp * cosy; + + return m; +} + +template +const mat star(const vec &v) +{ + mat m(3, 3); + + m(0, 0) = 0; + m(0, 1) = -v(2); + m(0, 2) = v(1); + + m(1, 0) = v(2); + m(1, 1) = 0; + m(1, 2) = -v(0); + + m(2, 0) = -v(1); + m(2, 1) = v(0); + m(2, 2) = 0; return m; } ///creates a 3x3 rotation matrix from a rodrigues vector -template -const mat rotate_rodrigues_33(const vec& r) +template +const mat rotate_rodrigues_33(const vec &r) { T theta = length(r); - if(theta == 0) + if (theta == 0) return identity(3); - vec rn = r/theta; + vec rn = r / theta; T cos_theta = cos(theta); T sin_theta = sin(theta); - - return cos_theta*identity(3) + ((T)1-cos_theta)*dyad(rn,rn) + sin_theta*star(rn); + + return cos_theta * identity(3) + ((T)1 - cos_theta) * dyad(rn, rn) + sin_theta * star(rn); } -template -const mat rotate_rodrigues_33(const T&rx, const T& ry, const T&rz) +template +const mat rotate_rodrigues_33(const T &rx, const T &ry, const T &rz) { vec r(3); r(0) = rx; r(1) = ry; r(2) = rz; - + return rotate_rodrigues_33(r); } - ///creates a homogen 3x3 shear matrix with given shears shx in x direction, and shy in y direction -template +template const mat shearxy_33(const T &shx, const T ­) { - mat m(3,3); - m(0,0)=1; m(0,1)= 0; m(0,2)= shx; - m(1,0)=0; m(1,1)= 1; m(1,2)= shy; - m(2,0)=0; m(2,1)= 0; m(2,2)= 1; - + mat m(3, 3); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = shx; + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = shy; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = 1; + return m; } - ///creates a homogen 3x3 shear matrix with given shears shx in x direction, and shy in y direction -template -const mat shearxz_33(const T&shx, const T&shz) +template +const mat shearxz_33(const T &shx, const T &shz) { - mat m(3,3); - m(0,0)=1; m(0,1)= shx; m(0,2)= 0; - m(1,0)=0; m(1,1)= 1; m(1,2)= 0; - m(2,0)=0; m(2,1)= shz; m(2,2)= 1; + mat m(3, 3); + m(0, 0) = 1; + m(0, 1) = shx; + m(0, 2) = 0; + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = 0; + m(2, 0) = 0; + m(2, 1) = shz; + m(2, 2) = 1; return m; } ///creates a homogen 3x3 shear matrix with given shears shy in y direction, and shz in z direction -template -const mat shearyz_33(const T­, const T&shz) +template +const mat shearyz_33(const T ­, const T &shz) { - mat m(3,3); - m(0,0)=1; m(0,1)= 0; m(0,2)= 0; - m(1,0)=shy; m(1,1)= 1; m(1,2)= 0; - m(2,0)=shz; m(2,1)= 0; m(2,2)= 1; - + mat m(3, 3); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = 0; + m(1, 0) = shy; + m(1, 1) = 1; + m(1, 2) = 0; + m(2, 0) = shz; + m(2, 1) = 0; + m(2, 2) = 1; + return m; } - -///creates a homogen 3x3 shear matrix -template +///creates a homogen 3x3 shear matrix +template const mat shear_33(const T &syx, const T &szx, - const T &sxy, const T &szy, - const T &sxz, const T &syz) + const T &sxy, const T &szy, + const T &sxz, const T &syz) { - mat m(3,3); - m(0,0)=1; m(0,1)= syx; m(0,2)= szx; - m(1,0)=sxy; m(1,1)= 1; m(1,2)= szy; - m(2,0)=sxz; m(2,1)= syz; m(2,2)= 1; - + mat m(3, 3); + m(0, 0) = 1; + m(0, 1) = syx; + m(0, 2) = szx; + m(1, 0) = sxy; + m(1, 1) = 1; + m(1, 2) = szy; + m(2, 0) = sxz; + m(2, 1) = syz; + m(2, 2) = 1; + return m; } ///creates a 4x4 translation matrix template -const mat translate_44(const T&x, const T &y, const T&z) +const mat translate_44(const T &x, const T &y, const T &z) { - mat m(4,4); - m(0,0)=1; m(0,1)= 0; m(0,2)= 0; m(0,3)= x; - m(1,0)=0; m(1,1)= 1; m(1,2)= 0; m(1,3)= y; - m(2,0)=0; m(2,1)= 0; m(2,2)= 1; m(2,3)= z; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = x; + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = 0; + m(1, 3) = y; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = 1; + m(2, 3) = z; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } @@ -268,442 +312,619 @@ const mat translate_44(const T&x, const T &y, const T&z) template const mat translate_44(const vec &v) { - mat m(4,4); - m(0,0)=1; m(0,1)= 0; m(0,2)= 0; m(0,3)= v(0); - m(1,0)=0; m(1,1)= 1; m(1,2)= 0; m(1,3)= v(1); - m(2,0)=0; m(2,1)= 0; m(2,2)= 1; m(2,3)= v(2); - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = v(0); + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = 0; + m(1, 3) = v(1); + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = 1; + m(2, 3) = v(2); + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } ///creates a 4x4 scale matrix template -const mat scale_44(const T&sx, const T &sy, const T&sz) +const mat scale_44(const T &sx, const T &sy, const T &sz) { - mat m(4,4); - m(0,0)=sx; m(0,1)= 0; m(0,2)= 0; m(0,3)= 0; - m(1,0)=0; m(1,1)=sy; m(1,2)= 0; m(1,3)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= sz; m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = sx; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = sy; + m(1, 2) = 0; + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = sz; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } -template +template const mat scale_44(const cgv::math::vec s) { assert(s.size() == 3); - return scale_44(s(0),s(1),s(2)); + return scale_44(s(0), s(1), s(2)); } ///creates a 4x4 uniform scale matrix template -const mat scale_44(const T&s) +const mat scale_44(const T &s) { - mat m(4,4); - m(0,0)=s; m(0,1)= 0; m(0,2)= 0; m(0,3)= 0; - m(1,0)=0; m(1,1)=s; m(1,2)= 0; m(1,3)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= s; m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = s; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = s; + m(1, 2) = 0; + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = s; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } - - -///creates a 4x4 rotation matrix around the x axis, the angle is in degree -template -const mat rotatex_44(const T& angle) +///creates a 4x4 rotation matrix around the x axis, the angle is in degree +template +const mat rotatex_44(const T &angle) { - T angler = angle*(T)3.14159/(T)180.0; - mat m(4,4); - m(0,0)=1; m(0,1)= 0; m(0,2)= 0; m(0,3)= 0; - m(1,0)=0; m(1,1)= (T)cos((double)angler); - m(1,2)= -(T)sin((double)angler); m(1,3)= 0; - m(2,0)=0; m(2,1)= (T)sin((double)angler); - m(2,2)= (T)cos((double)angler); m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; - return m; + T angler = angle * (T)3.14159 / (T)180.0; + mat m(4, 4); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = (T)cos((double)angler); + m(1, 2) = -(T)sin((double)angler); + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = (T)sin((double)angler); + m(2, 2) = (T)cos((double)angler); + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + return m; } -///creates a 4x4 rotation matrix around the y axis, the angle is in degree -template -const mat rotatey_44(const T& angle) +///creates a 4x4 rotation matrix around the y axis, the angle is in degree +template +const mat rotatey_44(const T &angle) { - T angler=angle*(T)3.14159/(T)180.0; - mat m(4,4); - m(0,0)=(T)cos((double)angler); m(0,1)= 0; - m(0,2)= (T)sin((double)angler); m(0,3)= 0; - m(1,0)=0; m(1,1)=1; m(1,2)= 0; m(1,3)= 0; - m(2,0)=-(T)sin((double)angler); m(2,1)= 0; - m(2,2)= (T)cos((double)angler); m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; - return m; + T angler = angle * (T)3.14159 / (T)180.0; + mat m(4, 4); + m(0, 0) = (T)cos((double)angler); + m(0, 1) = 0; + m(0, 2) = (T)sin((double)angler); + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = 0; + m(1, 3) = 0; + m(2, 0) = -(T)sin((double)angler); + m(2, 1) = 0; + m(2, 2) = (T)cos((double)angler); + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + return m; } -///creates a 4x4 rotation matrix around the z axis, the angle is in degree -template -const mat rotatez_44(const T& angle) +///creates a 4x4 rotation matrix around the z axis, the angle is in degree +template +const mat rotatez_44(const T &angle) { - T angler=angle*(T)3.14159/(T)180.0; - mat m(4,4); - m(0,0)=(T)cos((double)angler); - m(0,1)= -(T)sin((double)angler); m(0,2)= 0; m(0,3)= 0; - m(1,0)=(T)sin((double)angler); - m(1,1)= (T)cos((double)angler); m(1,2)= 0; m(1,3)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= 1; m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; - return m; + T angler = angle * (T)3.14159 / (T)180.0; + mat m(4, 4); + m(0, 0) = (T)cos((double)angler); + m(0, 1) = -(T)sin((double)angler); + m(0, 2) = 0; + m(0, 3) = 0; + m(1, 0) = (T)sin((double)angler); + m(1, 1) = (T)cos((double)angler); + m(1, 2) = 0; + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = 1; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + return m; } - -template -const mat rotate_44(const T &dirx, const T &diry, const T&dirz, - const T& angle) +template +const mat rotate_44(const T &dirx, const T &diry, const T &dirz, + const T &angle) { - - T angler = angle*(T)3.14159/(T)180.0; - mat m(4,4); + + T angler = angle * (T)3.14159 / (T)180.0; + mat m(4, 4); T rcos = cos(angler); T rsin = sin(angler); - m(0,0)= rcos + dirx*dirx*((T)1-rcos); - m(0,1)= -dirz*rsin + diry*dirx*((T)1-rcos); - m(0,2)= diry*rsin + dirz*dirx*((T)1-rcos); - + m(0, 0) = rcos + dirx * dirx * ((T)1 - rcos); + m(0, 1) = -dirz * rsin + diry * dirx * ((T)1 - rcos); + m(0, 2) = diry * rsin + dirz * dirx * ((T)1 - rcos); - m(1,0)= dirz*rsin + dirx*diry*((T)1-rcos); - m(1,1)= rcos + diry*diry*((T)1-rcos); - m(1,2)= -dirx*rsin + dirz*diry*((T)1-rcos); - + m(1, 0) = dirz * rsin + dirx * diry * ((T)1 - rcos); + m(1, 1) = rcos + diry * diry * ((T)1 - rcos); + m(1, 2) = -dirx * rsin + dirz * diry * ((T)1 - rcos); - m(2,0)= -diry*rsin + dirx*dirz*((T)1-rcos); - m(2,1)= dirx*rsin + diry*dirz*((T)1-rcos); - m(2,2)= rcos + dirz*dirz*((T)1-rcos); - - m(3,0)= (T)0; - m(3,1)= (T)0; - m(3,2)= (T)0; - m(0,3)= (T)0; - m(1,3)= (T)0; - m(2,3)= (T)0; - m(3,3)= (T)1; + m(2, 0) = -diry * rsin + dirx * dirz * ((T)1 - rcos); + m(2, 1) = dirx * rsin + diry * dirz * ((T)1 - rcos); + m(2, 2) = rcos + dirz * dirz * ((T)1 - rcos); + + m(3, 0) = (T)0; + m(3, 1) = (T)0; + m(3, 2) = (T)0; + m(0, 3) = (T)0; + m(1, 3) = (T)0; + m(2, 3) = (T)0; + m(3, 3) = (T)1; return m; } - -template -const mat rotate_33(const cgv::math::vec& dir, const T& angle) +template +const mat rotate_33(const cgv::math::vec &dir, const T &angle) { - + assert(dir.size() == 3); - cgv::math::vec vdir =dir; + cgv::math::vec vdir = dir; vdir.normalize(); - return rotate_33(vdir(0),vdir(1),vdir(2), angle); + return rotate_33(vdir(0), vdir(1), vdir(2), angle); } -template -const mat rotate_44(const cgv::math::vec& dir, const T& angle) +template +const mat rotate_44(const cgv::math::vec &dir, const T &angle) { - + assert(dir.size() == 3); - cgv::math::vec vdir =dir; + cgv::math::vec vdir = dir; vdir.normalize(); - return rotate_44(vdir(0),vdir(1),vdir(2), angle); + return rotate_44(vdir(0), vdir(1), vdir(2), angle); } - -///creates a 4x4 euler rotation matrix from yaw, pitch and roll given in degree -template -const mat rotate_euler_44(const T& yaw, const T& pitch,const T& roll) +///creates a 4x4 euler rotation matrix from yaw, pitch and roll given in degree +template +const mat rotate_euler_44(const T &yaw, const T &pitch, const T &roll) { - T yawd= yaw*3.14159/180.0; - T pitchd=pitch*3.14159/180.0; - T rolld=roll*3.14159/180.0; - T cosy =(T) cos(yawd); - T siny =(T) sin(yawd); - T cosp =(T) cos(pitchd); - T sinp =(T) sin(pitchd); - T cosr =(T) cos(rolld); - T sinr =(T) sin(rolld); - mat m(4,4); - - m(0,0) = cosr*cosy - sinr*sinp*siny; - m(0,1) = -sinr*cosp; - m(0,2) = cosr*siny + sinr*sinp*cosy; - m(0,3) = 0; + T yawd = yaw * 3.14159 / 180.0; + T pitchd = pitch * 3.14159 / 180.0; + T rolld = roll * 3.14159 / 180.0; + T cosy = (T)cos(yawd); + T siny = (T)sin(yawd); + T cosp = (T)cos(pitchd); + T sinp = (T)sin(pitchd); + T cosr = (T)cos(rolld); + T sinr = (T)sin(rolld); + mat m(4, 4); - m(1,0) = sinr*cosy + cosr*sinp*siny; - m(1,1) = cosr*cosp; - m(1,2) = sinr*siny - cosr*sinp*cosy; - m(1,3) = 0; + m(0, 0) = cosr * cosy - sinr * sinp * siny; + m(0, 1) = -sinr * cosp; + m(0, 2) = cosr * siny + sinr * sinp * cosy; + m(0, 3) = 0; - m(2,0) = -cosp*siny; - m(2,1) = sinp; - m(2,2) = cosp*cosy; - m(2,3) = 0; + m(1, 0) = sinr * cosy + cosr * sinp * siny; + m(1, 1) = cosr * cosp; + m(1, 2) = sinr * siny - cosr * sinp * cosy; + m(1, 3) = 0; - m(3,0) = m(3,1)= m(3,2) =0; - m(3,3) = 1; - return m; + m(2, 0) = -cosp * siny; + m(2, 1) = sinp; + m(2, 2) = cosp * cosy; + m(2, 3) = 0; + + m(3, 0) = m(3, 1) = m(3, 2) = 0; + m(3, 3) = 1; + return m; } - ///creates a homogen 4x4 shear matrix with given shears shx in x direction, and shy in y direction -template +template const mat shearxy_44(const T &shx, const T ­) { - mat m(4,4); - m(0,0)=1; m(0,1)= 0; m(0,2)= shx; m(0,3)= 0; - m(1,0)=0; m(1,1)= 1; m(1,2)= shy; m(1,3)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= 1; m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = shx; + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = shy; + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = 1; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } - ///creates a homogen 4x4 shear matrix with given shears shx in x direction, and shy in y direction -template -const mat shearxz_44(const T&shx, const T&shz) +template +const mat shearxz_44(const T &shx, const T &shz) { - mat m(4,4); - m(0,0)=1; m(0,1)= shx; m(0,2)= 0; m(0,3)= 0; - m(1,0)=0; m(1,1)= 1; m(1,2)= 0; m(1,3)= 0; - m(2,0)=0; m(2,1)= shz; m(2,2)= 1; m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = 1; + m(0, 1) = shx; + m(0, 2) = 0; + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = 1; + m(1, 2) = 0; + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = shz; + m(2, 2) = 1; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } ///creates a homogen 4x4 shear matrix with given shears shy in y direction, and shz in z direction -template -const mat shearyz_44(const T­, const T&shz) +template +const mat shearyz_44(const T ­, const T &shz) { - mat m(4,4); - m(0,0)=1; m(0,1)= 0; m(0,2)= 0; m(0,3)= 0; - m(1,0)=shy; m(1,1)= 1; m(1,2)= 0; m(1,3)= 0; - m(2,0)=shz; m(2,1)= 0; m(2,2)= 1; m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = 1; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = 0; + m(1, 0) = shy; + m(1, 1) = 1; + m(1, 2) = 0; + m(1, 3) = 0; + m(2, 0) = shz; + m(2, 1) = 0; + m(2, 2) = 1; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } - -///creates a homogen 4x4 shear matrix -template +///creates a homogen 4x4 shear matrix +template const mat shear_44(const T &syx, const T &szx, - const T &sxy, const T &szy, - const T &sxz, const T &syz) + const T &sxy, const T &szy, + const T &sxz, const T &syz) { - mat m(4,4); - m(0,0)=1; m(0,1)= syx; m(0,2)= szx; m(0,3)= 0; - m(1,0)=sxy; m(1,1)= 1; m(1,2)= szy; m(1,3)= 0; - m(2,0)=sxz; m(2,1)= syz; m(2,2)= 1; m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + mat m(4, 4); + m(0, 0) = 1; + m(0, 1) = syx; + m(0, 2) = szx; + m(0, 3) = 0; + m(1, 0) = sxy; + m(1, 1) = 1; + m(1, 2) = szy; + m(1, 3) = 0; + m(2, 0) = sxz; + m(2, 1) = syz; + m(2, 2) = 1; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; return m; } - - - - ///creates a perspective transformation matrix in the same way as gluPerspective does -template -const mat perspective_44(const T& fovy, const T&aspect, const T& znear, - const T& zfar) -{ - T fovyr = (T)(fovy*3.14159/180.0); - T f = (T)(cos(fovyr/2.0f)/sin(fovyr/2.0f)); - mat m(4,4); - m(0,0)=f/aspect; m(0,1)= 0; m(0,2)= 0; m(0,3)= 0; - m(1,0)=0; m(1,1)= f; m(1,2)= 0; m(1,3)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= (zfar+znear)/(znear-zfar); - m(2,3)= (2*zfar*znear)/(znear-zfar); - m(3,0)=0; m(3,1)= 0; m(3,2)= -1; m(3,3)= 0; - return m; -} - -///creates a viewport transformation matrix template -mat viewport_44(const T& xoff, const T yoff, const T& width, - const T& height) +const mat perspective_44(const T &fovy, const T &aspect, const T &znear, + const T &zfar) { - mat m(4,4); - T a = width/(T)2.0; - T b = height/(T)2.0; - m(0,0)=a; m(0,1)= 0; m(0,2)= 0; m(0,3)= xoff+(T)0.5; - m(1,0)=0; m(1,1)= b; m(1,2)= 0; m(1,3)= yoff+(T)0.5; - m(2,0)=0; m(2,1)= 0; m(2,2)= (T)0.5; m(2,3)=(T)0.5 ; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + T fovyr = (T)(fovy * 3.14159 / 180.0); + T f = (T)(cos(fovyr / 2.0f) / sin(fovyr / 2.0f)); + mat m(4, 4); + m(0, 0) = f / aspect; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = f; + m(1, 2) = 0; + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = (zfar + znear) / (znear - zfar); + m(2, 3) = (2 * zfar * znear) / (znear - zfar); + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = -1; + m(3, 3) = 0; return m; } +///creates a viewport transformation matrix +template +mat viewport_44(const T &xoff, const T yoff, const T &width, + const T &height) +{ + mat m(4, 4); + T a = width / (T)2.0; + T b = height / (T)2.0; + m(0, 0) = a; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = xoff + (T)0.5; + m(1, 0) = 0; + m(1, 1) = b; + m(1, 2) = 0; + m(1, 3) = yoff + (T)0.5; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = (T)0.5; + m(2, 3) = (T)0.5; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + return m; +} ///creates a look at transformation matrix in the same way as gluLookAt does -template +template const mat look_at_44(const T &eyex, const T &eyey, const T &eyez, - const T& centerx, const T& centery, const T& centerz, - const T& upx, const T& upy, const T& upz) + const T ¢erx, const T ¢ery, const T ¢erz, + const T &upx, const T &upy, const T &upz) { - vec center(centerx,centery,centerz); - vec eye(eyex,eyey,eyez); - vec up(upx,upy,upz); + vec center(centerx, centery, centerz); + vec eye(eyex, eyey, eyez); + vec up(upx, upy, upz); - vec f = normalize(center-eye); - up=normalize(up); - vec s = normalize(cross(f,up)); - vec u = normalize(cross(s,f)); + vec f = normalize(center - eye); + up = normalize(up); + vec s = normalize(cross(f, up)); + vec u = normalize(cross(s, f)); - mat m(4,4); - m(0,0)=s(0); m(0,1)=s(1) ; m(0,2)= s(2); m(0,3)= 0; - m(1,0)=u(0); m(1,1)=u(1) ; m(1,2)= u(2); m(1,3)= 0; - m(2,0)=-f(0); m(2,1)= -f(1); m(2,2)= -f(2); m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; - m = m*translate_44(-eyex,-eyey,-eyez); + mat m(4, 4); + m(0, 0) = s(0); + m(0, 1) = s(1); + m(0, 2) = s(2); + m(0, 3) = 0; + m(1, 0) = u(0); + m(1, 1) = u(1); + m(1, 2) = u(2); + m(1, 3) = 0; + m(2, 0) = -f(0); + m(2, 1) = -f(1); + m(2, 2) = -f(2); + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + m = m * translate_44(-eyex, -eyey, -eyez); return m; } -template +template const mat look_at_44(vec eye, vec center, vec up) { - - vec f = normalize(center-eye); - up=normalize(up); - vec s = normalize(cross(f,up)); - vec u = normalize(cross(s,f)); + vec f = normalize(center - eye); + up = normalize(up); + vec s = normalize(cross(f, up)); + vec u = normalize(cross(s, f)); - mat m(4,4); - m(0,0)=s(0); m(0,1)=s(1) ; m(0,2)= s(2); m(0,3)= 0; - m(1,0)=u(0); m(1,1)=u(1) ; m(1,2)= u(2); m(1,3)= 0; - m(2,0)=-f(0); m(2,1)= -f(1); m(2,2)= -f(2); m(2,3)= 0; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; - m = m*translate_44(-eye); + mat m(4, 4); + m(0, 0) = s(0); + m(0, 1) = s(1); + m(0, 2) = s(2); + m(0, 3) = 0; + m(1, 0) = u(0); + m(1, 1) = u(1); + m(1, 2) = u(2); + m(1, 3) = 0; + m(2, 0) = -f(0); + m(2, 1) = -f(1); + m(2, 2) = -f(2); + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + m = m * translate_44(-eye); return m; } ///creates a frustrum projection matrix in the same way as glFrustum does -template -const mat frustrum_44(const T& left, const T&right, - const T& bottom, const T& top, - const T& znear, const T& zfar) +template +const mat frustrum_44(const T &left, const T &right, + const T &bottom, const T &top, + const T &znear, const T &zfar) { - T e = 2*znear/(right - left); - T f = 2*znear/(top-bottom); - T A = (right +left)/(right -left); - T B = (top+bottom)/(top-bottom); - T C = -(zfar + znear)/(zfar-znear); - T D = -(2*zfar*znear)/(zfar-znear); - mat m(4,4); - m(0,0)=e; m(0,1)= 0; m(0,2)= A; m(0,3)= 0; - m(1,0)=0; m(1,1)= f; m(1,2)= B; m(1,3)= 0; - m(2,0)=0; m(2,1)= 0; m(2,2)= C; m(2,3)= D; - m(3,0)=0; m(3,1)= 0; m(3,2)= -1; m(3,3)= 0; - return m; -} - -///creates an orthographic projection matrix in the same way as glOrtho does -template -const mat ortho_44(const T& left, const T&right, - const T& bottom, const T& top, - const T& znear, const T& zfar) -{ - T a = 2/(right - left); - T b = 2/(top-bottom); - T c = -2/(zfar-znear); - T tx = (right+left)/(right-left); - T ty = (top+bottom)/(top-bottom); - T tz = (zfar+znear)/(zfar-znear); - mat m(4,4); - m(0,0)=a; m(0,1)= 0; m(0,2)= 0; m(0,3)= -tx; - m(1,0)=0; m(1,1)= b; m(1,2)= 0; m(1,3)= -ty; - m(2,0)=0; m(2,1)= 0; m(2,2)= c; m(2,3)= -tz; - m(3,0)=0; m(3,1)= 0; m(3,2)= 0; m(3,3)= 1; + T e = 2 * znear / (right - left); + T f = 2 * znear / (top - bottom); + T A = (right + left) / (right - left); + T B = (top + bottom) / (top - bottom); + T C = -(zfar + znear) / (zfar - znear); + T D = -(2 * zfar * znear) / (zfar - znear); + mat m(4, 4); + m(0, 0) = e; + m(0, 1) = 0; + m(0, 2) = A; + m(0, 3) = 0; + m(1, 0) = 0; + m(1, 1) = f; + m(1, 2) = B; + m(1, 3) = 0; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = C; + m(2, 3) = D; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = -1; + m(3, 3) = 0; return m; } +///creates an orthographic projection matrix in the same way as glOrtho does +template +const mat ortho_44(const T &left, const T &right, + const T &bottom, const T &top, + const T &znear, const T &zfar) +{ + T a = 2 / (right - left); + T b = 2 / (top - bottom); + T c = -2 / (zfar - znear); + T tx = (right + left) / (right - left); + T ty = (top + bottom) / (top - bottom); + T tz = (zfar + znear) / (zfar - znear); + mat m(4, 4); + m(0, 0) = a; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = -tx; + m(1, 0) = 0; + m(1, 1) = b; + m(1, 2) = 0; + m(1, 3) = -ty; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = c; + m(2, 3) = -tz; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + return m; +} ///creates an orthographic projection matrix in the same way as glOrtho2d does -template -const mat ortho2d_44(const T& left, const T&right, - const T& bottom, const T& top) +template +const mat ortho2d_44(const T &left, const T &right, + const T &bottom, const T &top) { - return ortho_44(left,right,bottom,top,(T)-1.0,(T)1.0); + return ortho_44(left, right, bottom, top, (T)-1.0, (T)1.0); } +///creates a picking matrix like gluPickMatrix with pixel (0,0) in the lower left corner if flipy=false +template +const mat pick_44(const T &x, const T &y, const T &width, const T &height, int viewport[4], const mat &modelviewproj, bool flipy = true) +{ + mat m(4, 4); + T sx, sy; + T tx, ty; + sx = viewport[2] / width; + sy = viewport[3] / height; + tx = (T)(viewport[2] + 2.0 * (viewport[0] - x)) / width; + if (flipy) + ty = (T)(viewport[3] + 2.0 * (viewport[1] - (viewport[3] - y))) / height; + else + ty = (T)(viewport[3] + 2.0 * (viewport[1] - y)) / height; -///creates a picking matrix like gluPickMatrix with pixel (0,0) in the lower left corner if flipy=false -template -const mat pick_44(const T& x,const T& y,const T& width, const T& height,int viewport[4],const mat &modelviewproj, bool flipy=true) -{ - mat m(4,4); - T sx, sy; - T tx, ty; - sx = viewport[2] / width; - sy = viewport[3] / height; - tx = (T)(viewport[2] + 2.0 * (viewport[0] - x)) / width; - if(flipy) - ty = (T)(viewport[3] + 2.0 * (viewport[1] - (viewport[3]-y))) / height; - else - ty = (T)(viewport[3] + 2.0 * (viewport[1] - y)) / height; - - m(0,0) = sx; m(0,1) = 0; m(0,2) = 0; m(0,3) = tx; - m(1,0) = 0; m(1,1) = sy; m(1,2) = 0; m(1,3) = ty; - m(2,0) = 0; m(2,1) = 0; m(2,2) = 1; m(2,3) = 0; - m(3,0) = 0; m(3,1) = 0; m(3,2) = 0; m(3,3) = 1; - return m*modelviewproj; -} + m(0, 0) = sx; + m(0, 1) = 0; + m(0, 2) = 0; + m(0, 3) = tx; + m(1, 0) = 0; + m(1, 1) = sy; + m(1, 2) = 0; + m(1, 3) = ty; + m(2, 0) = 0; + m(2, 1) = 0; + m(2, 2) = 1; + m(2, 3) = 0; + m(3, 0) = 0; + m(3, 1) = 0; + m(3, 2) = 0; + m(3, 3) = 1; + return m * modelviewproj; +} //extract rotation angles from combined rotation matrix -template -void decompose_R_2_RxRyRz(const mat& R33,T &angle_x, T& angle_y, T& angle_z) -{ - - angle_y = asin( R33(0,2)); /* Calculate Y-axis angle */ - T C = cos( angle_y ); - T trx,atry; - angle_y *= (T)(180/3.14159); - if ( std::abs( C ) > (T)0.005 ) /* Gimbal lock? */ - { - trx = R33(2,2) / C; /* No, so get X-axis angle */ - atry = -R33(1,2) / C; - angle_x = atan2( atry, trx ) * (T)(180/3.14159); - trx = R33(0,0) / C; /* Get Z-axis angle */ - atry = -R33(0,1) / C; - angle_z = atan2( atry, trx ) * (T)(180/3.14159); - } - else /* Gimbal lock has occurred */ - { - angle_x = 0; /* Set X-axis angle to zero */ - trx = R33(1,1); /* And calculate Z-axis angle */ - atry = R33(1,0); - angle_z = atan2( atry, trx ) * (T)(180/3.14159); - } - - /* return only positive angles in [0,360] */ - if (angle_x < 0) angle_x += (T)360; - if (angle_y < 0) angle_y += (T)360; - if (angle_z < 0) angle_z += (T)360; - //std::cout << angle_x << " "<< angle_y << " " < +void decompose_R_2_RxRyRz(const mat &R33, T &angle_x, T &angle_y, T &angle_z) +{ + + angle_y = asin(R33(0, 2)); /* Calculate Y-axis angle */ + T C = cos(angle_y); + T trx, atry; + angle_y *= (T)(180 / 3.14159); + if (std::abs(C) > (T)0.005) /* Gimbal lock? */ + { + trx = R33(2, 2) / C; /* No, so get X-axis angle */ + atry = -R33(1, 2) / C; + angle_x = atan2(atry, trx) * (T)(180 / 3.14159); + trx = R33(0, 0) / C; /* Get Z-axis angle */ + atry = -R33(0, 1) / C; + angle_z = atan2(atry, trx) * (T)(180 / 3.14159); + } + else /* Gimbal lock has occurred */ + { + angle_x = 0; /* Set X-axis angle to zero */ + trx = R33(1, 1); /* And calculate Z-axis angle */ + atry = R33(1, 0); + angle_z = atan2(atry, trx) * (T)(180 / 3.14159); + } + + /* return only positive angles in [0,360] */ + if (angle_x < 0) + angle_x += (T)360; + if (angle_y < 0) + angle_y += (T)360; + if (angle_z < 0) + angle_z += (T)360; + //std::cout << angle_x << " "<< angle_y << " " < -const mat extract_frustrum_planes(const mat& modelviewprojection) +const mat extract_frustrum_planes(const mat &modelviewprojection) { - mat frustrum_planes(4,6); - - frustrum_planes.set_col(0,modelviewprojection.row(3)-modelviewprojection.row(0));//right - frustrum_planes.set_col(1,modelviewprojection.row(3)+modelviewprojection.row(0));//left - frustrum_planes.set_col(2,modelviewprojection.row(3)-modelviewprojection.row(1));//top - frustrum_planes.set_col(3,modelviewprojection.row(3)+modelviewprojection.row(1));//bottom - frustrum_planes.set_col(4,modelviewprojection.row(3)-modelviewprojection.row(2));//far - frustrum_planes.set_col(5,modelviewprojection.row(3)+modelviewprojection.row(2));//near - - // Normalize all planes - for(unsigned i=0;i<6;i++) - frustrum_planes.set_col(i,frustrum_planes.col(i)/length(frustrum_planes.col(i).sub_vec(0,3))); - return frustrum_planes; + mat frustrum_planes(4, 6); + frustrum_planes.set_col(0, modelviewprojection.row(3) - modelviewprojection.row(0)); //right + frustrum_planes.set_col(1, modelviewprojection.row(3) + modelviewprojection.row(0)); //left + frustrum_planes.set_col(2, modelviewprojection.row(3) - modelviewprojection.row(1)); //top + frustrum_planes.set_col(3, modelviewprojection.row(3) + modelviewprojection.row(1)); //bottom + frustrum_planes.set_col(4, modelviewprojection.row(3) - modelviewprojection.row(2)); //far + frustrum_planes.set_col(5, modelviewprojection.row(3) + modelviewprojection.row(2)); //near + + // Normalize all planes + for (unsigned i = 0; i < 6; i++) + frustrum_planes.set_col(i, frustrum_planes.col(i) / length(frustrum_planes.col(i).sub_vec(0, 3))); + return frustrum_planes; } -} -} - - +} // namespace math +} // namespace cgv