diff options
Diffstat (limited to '')
-rw-r--r-- | dev/MinGfx/src/matrix4.h | 520 |
1 files changed, 260 insertions, 260 deletions
diff --git a/dev/MinGfx/src/matrix4.h b/dev/MinGfx/src/matrix4.h index 4abf29f..337f8bd 100644 --- a/dev/MinGfx/src/matrix4.h +++ b/dev/MinGfx/src/matrix4.h @@ -1,260 +1,260 @@ -/* - This file is part of the MinGfx Project. - - Copyright (c) 2017,2018 Regents of the University of Minnesota. - All Rights Reserved. - - Original Author(s) of this File: - Dan Keefe, 2017, University of Minnesota - - Author(s) of Significant Updates/Modifications to the File: - ... - */ - -#ifndef SRC_MATRIX4_H_ -#define SRC_MATRIX4_H_ - -#include <iostream> - -#include "point3.h" -#include "vector3.h" -#include "ray.h" - - -namespace mingfx { - - -/** A 4x4 transformation matrix stored internally as an array of floats in - column-major order so as to be compatible with OpenGL. Examples: - ~~~ - // constructing various matrices: - Matrix4 T = Matrix4::Translation(Vector3(1,0,0)); - Matrix4 S = Matrix4::Scale(Vector3(2,2,2)); - Matrix4 R = Matrix4::RotateX(GfxMath::toRadians(45.0)); - - // compose matrices together by multiplication - Matrix4 M = T * R * S; - Matrix4 Minv = M.Inverse(); - - // transforming points, vectors, etc. - Point3 p1(1,1,1); - Point3 p2 = M * p1; - - Vector3 v1(1,1,1); - Vector3 v2 = M * v1; - - Ray r1(p1, v1); - Ray r2 = M * r1; - ~~~ - */ -class Matrix4 { -public: - - /// The default constructor creates an identity matrix: - Matrix4(); - - /// Constructs a matrix given from an array of 16 floats in OpenGL matrix format - /// (i.e., column major). - Matrix4(const float* a); - - /// Constructs a matrix given from a vector of 16 floats in OpenGL matrix format - /// (i.e., column major). - Matrix4(const std::vector<float> &a); - - /// Copy constructor - Matrix4(const Matrix4& m2); - - /// Destructor - virtual ~Matrix4(); - - /// Check for "equality", taking floating point imprecision into account - bool operator==(const Matrix4& m2) const; - - /// Check for "inequality", taking floating point imprecision into account - bool operator!=(const Matrix4& m2) const; - - /// Matrix assignment operator - Matrix4& operator=(const Matrix4& m2); - - - /// Returns a pointer to the raw data array used to store the matrix. This - /// is a 1D array of 16-elements stored in column-major order. - const float * value_ptr() const; - - /// Accesses the ith element of the raw data array used to store the matrix. - /// This is a 1D array of 16-elements stored in column-major order. - float operator[](const int i) const; - - /// Accesses the ith element of the raw data array used to store the matrix. - /// This is a 1D array of 16-elements stored in column-major order. - float& operator[](const int i); - - /// Access an individual element of the array using the syntax: - /// Matrix4 mat; float row1col2 = mat(1,2); - float operator()(const int row, const int col) const; - - /// Access an individual element of the array using the syntax: - /// Matrix4 mat; mat(1,2) = 1.0; - float& operator()(const int row, const int col); - - - /// Returns the c-th column of the matrix as a Vector type, e.g.,: - /// Vector3 xAxis = mat.getColumnAsVector3(0); - /// Vector3 yAxis = mat.getColumnAsVector3(1); - /// Vector3 zAxis = mat.getColumnAsVector3(2); - Vector3 ColumnToVector3(int c) const; - - /// Returns the c-th column of the matrix as a Vector type, e.g.,: - /// Point3 pos = mat.getColumnAsPoint3(3); - Point3 ColumnToPoint3(int c) const; - - std::vector<float> ToVector() const; - - - // --- Static Constructors for Special Matrices --- - - /** Returns a matrix constructed from individual elements passed in row major - order so that the matrix looks "correct" on the screen as you write this - constructor on 4 lines of code as below. Note the that internally the - matrix constructed will be stored in a 16 element column major array to - be consistent with OpenGL. - */ - static Matrix4 FromRowMajorElements( - const float r1c1, const float r1c2, const float r1c3, const float r1c4, - const float r2c1, const float r2c2, const float r2c3, const float r2c4, - const float r3c1, const float r3c2, const float r3c3, const float r3c4, - const float r4c1, const float r4c2, const float r4c3, const float r4c4 - ); - - // --- Model Transformations --- - - /// Returns the scale matrix described by the vector - static Matrix4 Scale(const Vector3 &v); - - /// Returns the translation matrix described by the vector - static Matrix4 Translation(const Vector3 &v); - - /// Returns the rotation matrix about the x axis by the specified angle - static Matrix4 RotationX(const float radians); - - /// Returns the rotation matrix about the y axis by the specified angle - static Matrix4 RotationY(const float radians); - - /// Returns the rotation matrix about the z axis by the specified angle - static Matrix4 RotationZ(const float radians); - - /// Returns the rotation matrix around the vector v placed at point p, rotate by angle a - static Matrix4 Rotation(const Point3 &p, const Vector3 &v, const float a); - - /// Creates a transformation matrix that maps a coordinate space, *a*, defined - /// one point, *a_p*, and two vectors, *a_v1* and *a_v2*, to a new coordinate - /// space, *b*, also defined by one point, *b_p*, and two vectors, *b_v1* and - /// *b_v2*. The transformation will thus include both some rotation and some - /// translation. Pseudocode example of aligning a billboard defined in the - /// XY plane with a normal in the +Z direction and that rotates around the Y - /// axis with a camera: - /// ~~~ - /// // define a coordiante space for a canonical billboard geometry defined - /// // right at the origin. - /// Point3 a_p = Point3(0,0,0); // billboard's initial base position - /// Vector3 a_v1 = Vector3(0,1,0); // billboard's initial up direction - /// Vector3 a_v2 = Vector3(0,0,1); // billboard's initial normal direction - /// - /// // define a coordinate space for where we want this billboard to go and - /// // the direction it should be facing - /// Point3 b_p = desired_base_pos; // new position for the billboard - /// Vector3 b_v1 = Vector3(0,1,0); // +Y is still up, doesn't change - /// Vector3 b_v2 = (camera.eye() - desired_base_pos); // the normal should point toward the camera - /// b_v2[1] = 0.0; // with 0 change in Y so the billboard does not tilt - /// b_v2.Normalize(); // convert to a unit vector - /// - /// Matrix4 billboard_model_matrix = Matrix4::Align(a_p, a_v1, a_v2, b_p, b_v1, b_v2); - /// ~~~ - static Matrix4 Align(const Point3 &a_p, const Vector3 &a_v1, const Vector3 &a_v2, - const Point3 &b_p, const Vector3 &b_v1, const Vector3 &b_v2); - - - // --- View Matrices --- - - /** Returns a view matrix that centers the camera at the 'eye' position and - orients it to look at the desired 'target' point with the top of the - screen pointed as closely as possible in the direction of the 'up' vector. - */ - static Matrix4 LookAt(Point3 eye, Point3 target, Vector3 up); - - // --- Projection Matrices --- - - /// Returns a perspective projection matrix equivalent to the one gluPerspective - /// creates. - static Matrix4 Perspective(float fov_y_in_degrees, float aspect_ratio, float near_plane_dist, float far_plane_dist); - - /// Returns a projection matrix equivalent the one glFrustum creates - static Matrix4 Frustum(float left, float right, float bottom, float top, float near_plane_dist, float far_plane_dist); - - // --- Inverse, Transposeand Other General Matrix Functions --- - - /// Returns the inverse of the 4x4 matrix if it is nonsingular. If it is - /// singular, then returns the identity matrix. - Matrix4 Inverse() const; - - /** Returns an orthonormal version of the matrix, i.e., guarantees that the - rotational component of the matrix is built from column vectors that are - all unit vectors and orthogonal to each other. - */ - Matrix4 Orthonormal() const; - - /// Returns the transpose of the matrix - Matrix4 Transpose() const; - - /// Returns the determinant of the 3x3 matrix formed by excluding the specified - /// row and column from the 4x4 matrix. - float SubDeterminant(int exclude_row, int exclude_col) const; - - /// Returns the cofactor matrix. - Matrix4 Cofactor() const; - - /// Returns the determinant of the 4x4 matrix - float Determinant() const; - - - -private: - float m[16]; -}; - - - -// ---------- Operator Overloads for Working with Points, Vectors, & Matrices ---------- - - -// --- Matrix multiplication for Points, Vectors, & Matrices --- - -/// Multiply matrix and scalar, returns the new matrix -Matrix4 operator*(const Matrix4& m, const float& s); - -/// Multiply matrix and scalar, returns the new matrix -Matrix4 operator*(const float& s, const Matrix4& m); - -/// Multiply matrix and point, returns the new point -Point3 operator*(const Matrix4& m, const Point3& p); - -/// Multiply matrix and vector, returns the new vector -Vector3 operator*(const Matrix4& m, const Vector3& v); - -/// Multiply two matrices, returns the result -Matrix4 operator*(const Matrix4& m1, const Matrix4& m2); - - - -/// Multiply matrix and the point and vector portions of the ray, returns the new ray -Ray operator*(const Matrix4& m, const Ray& r); - -// --- Stream operators --- - -std::ostream & operator<< ( std::ostream &os, const Matrix4 &m); -std::istream & operator>> ( std::istream &is, Matrix4 &m); - - -} // end namespace - -#endif +/*
+ This file is part of the MinGfx Project.
+
+ Copyright (c) 2017,2018 Regents of the University of Minnesota.
+ All Rights Reserved.
+
+ Original Author(s) of this File:
+ Dan Keefe, 2017, University of Minnesota
+
+ Author(s) of Significant Updates/Modifications to the File:
+ ...
+ */
+
+#ifndef SRC_MATRIX4_H_
+#define SRC_MATRIX4_H_
+
+#include <iostream>
+
+#include "point3.h"
+#include "vector3.h"
+#include "ray.h"
+
+
+namespace mingfx {
+
+
+/** A 4x4 transformation matrix stored internally as an array of floats in
+ column-major order so as to be compatible with OpenGL. Examples:
+ ~~~
+ // constructing various matrices:
+ Matrix4 T = Matrix4::Translation(Vector3(1,0,0));
+ Matrix4 S = Matrix4::Scale(Vector3(2,2,2));
+ Matrix4 R = Matrix4::RotateX(GfxMath::toRadians(45.0));
+
+ // compose matrices together by multiplication
+ Matrix4 M = T * R * S;
+ Matrix4 Minv = M.Inverse();
+
+ // transforming points, vectors, etc.
+ Point3 p1(1,1,1);
+ Point3 p2 = M * p1;
+
+ Vector3 v1(1,1,1);
+ Vector3 v2 = M * v1;
+
+ Ray r1(p1, v1);
+ Ray r2 = M * r1;
+ ~~~
+ */
+class Matrix4 {
+public:
+
+ /// The default constructor creates an identity matrix:
+ Matrix4();
+
+ /// Constructs a matrix given from an array of 16 floats in OpenGL matrix format
+ /// (i.e., column major).
+ Matrix4(const float* a);
+
+ /// Constructs a matrix given from a vector of 16 floats in OpenGL matrix format
+ /// (i.e., column major).
+ Matrix4(const std::vector<float> &a);
+
+ /// Copy constructor
+ Matrix4(const Matrix4& m2);
+
+ /// Destructor
+ virtual ~Matrix4();
+
+ /// Check for "equality", taking floating point imprecision into account
+ bool operator==(const Matrix4& m2) const;
+
+ /// Check for "inequality", taking floating point imprecision into account
+ bool operator!=(const Matrix4& m2) const;
+
+ /// Matrix assignment operator
+ Matrix4& operator=(const Matrix4& m2);
+
+
+ /// Returns a pointer to the raw data array used to store the matrix. This
+ /// is a 1D array of 16-elements stored in column-major order.
+ const float * value_ptr() const;
+
+ /// Accesses the ith element of the raw data array used to store the matrix.
+ /// This is a 1D array of 16-elements stored in column-major order.
+ float operator[](const int i) const;
+
+ /// Accesses the ith element of the raw data array used to store the matrix.
+ /// This is a 1D array of 16-elements stored in column-major order.
+ float& operator[](const int i);
+
+ /// Access an individual element of the array using the syntax:
+ /// Matrix4 mat; float row1col2 = mat(1,2);
+ float operator()(const int row, const int col) const;
+
+ /// Access an individual element of the array using the syntax:
+ /// Matrix4 mat; mat(1,2) = 1.0;
+ float& operator()(const int row, const int col);
+
+
+ /// Returns the c-th column of the matrix as a Vector type, e.g.,:
+ /// Vector3 xAxis = mat.getColumnAsVector3(0);
+ /// Vector3 yAxis = mat.getColumnAsVector3(1);
+ /// Vector3 zAxis = mat.getColumnAsVector3(2);
+ Vector3 ColumnToVector3(int c) const;
+
+ /// Returns the c-th column of the matrix as a Vector type, e.g.,:
+ /// Point3 pos = mat.getColumnAsPoint3(3);
+ Point3 ColumnToPoint3(int c) const;
+
+ std::vector<float> ToVector() const;
+
+
+ // --- Static Constructors for Special Matrices ---
+
+ /** Returns a matrix constructed from individual elements passed in row major
+ order so that the matrix looks "correct" on the screen as you write this
+ constructor on 4 lines of code as below. Note the that internally the
+ matrix constructed will be stored in a 16 element column major array to
+ be consistent with OpenGL.
+ */
+ static Matrix4 FromRowMajorElements(
+ const float r1c1, const float r1c2, const float r1c3, const float r1c4,
+ const float r2c1, const float r2c2, const float r2c3, const float r2c4,
+ const float r3c1, const float r3c2, const float r3c3, const float r3c4,
+ const float r4c1, const float r4c2, const float r4c3, const float r4c4
+ );
+
+ // --- Model Transformations ---
+
+ /// Returns the scale matrix described by the vector
+ static Matrix4 Scale(const Vector3 &v);
+
+ /// Returns the translation matrix described by the vector
+ static Matrix4 Translation(const Vector3 &v);
+
+ /// Returns the rotation matrix about the x axis by the specified angle
+ static Matrix4 RotationX(const float radians);
+
+ /// Returns the rotation matrix about the y axis by the specified angle
+ static Matrix4 RotationY(const float radians);
+
+ /// Returns the rotation matrix about the z axis by the specified angle
+ static Matrix4 RotationZ(const float radians);
+
+ /// Returns the rotation matrix around the vector v placed at point p, rotate by angle a
+ static Matrix4 Rotation(const Point3 &p, const Vector3 &v, const float a);
+
+ /// Creates a transformation matrix that maps a coordinate space, *a*, defined
+ /// one point, *a_p*, and two vectors, *a_v1* and *a_v2*, to a new coordinate
+ /// space, *b*, also defined by one point, *b_p*, and two vectors, *b_v1* and
+ /// *b_v2*. The transformation will thus include both some rotation and some
+ /// translation. Pseudocode example of aligning a billboard defined in the
+ /// XY plane with a normal in the +Z direction and that rotates around the Y
+ /// axis with a camera:
+ /// ~~~
+ /// // define a coordiante space for a canonical billboard geometry defined
+ /// // right at the origin.
+ /// Point3 a_p = Point3(0,0,0); // billboard's initial base position
+ /// Vector3 a_v1 = Vector3(0,1,0); // billboard's initial up direction
+ /// Vector3 a_v2 = Vector3(0,0,1); // billboard's initial normal direction
+ ///
+ /// // define a coordinate space for where we want this billboard to go and
+ /// // the direction it should be facing
+ /// Point3 b_p = desired_base_pos; // new position for the billboard
+ /// Vector3 b_v1 = Vector3(0,1,0); // +Y is still up, doesn't change
+ /// Vector3 b_v2 = (camera.eye() - desired_base_pos); // the normal should point toward the camera
+ /// b_v2[1] = 0.0; // with 0 change in Y so the billboard does not tilt
+ /// b_v2.Normalize(); // convert to a unit vector
+ ///
+ /// Matrix4 billboard_model_matrix = Matrix4::Align(a_p, a_v1, a_v2, b_p, b_v1, b_v2);
+ /// ~~~
+ static Matrix4 Align(const Point3 &a_p, const Vector3 &a_v1, const Vector3 &a_v2,
+ const Point3 &b_p, const Vector3 &b_v1, const Vector3 &b_v2);
+
+
+ // --- View Matrices ---
+
+ /** Returns a view matrix that centers the camera at the 'eye' position and
+ orients it to look at the desired 'target' point with the top of the
+ screen pointed as closely as possible in the direction of the 'up' vector.
+ */
+ static Matrix4 LookAt(Point3 eye, Point3 target, Vector3 up);
+
+ // --- Projection Matrices ---
+
+ /// Returns a perspective projection matrix equivalent to the one gluPerspective
+ /// creates.
+ static Matrix4 Perspective(float fov_y_in_degrees, float aspect_ratio, float near_plane_dist, float far_plane_dist);
+
+ /// Returns a projection matrix equivalent the one glFrustum creates
+ static Matrix4 Frustum(float left, float right, float bottom, float top, float near_plane_dist, float far_plane_dist);
+
+ // --- Inverse, Transposeand Other General Matrix Functions ---
+
+ /// Returns the inverse of the 4x4 matrix if it is nonsingular. If it is
+ /// singular, then returns the identity matrix.
+ Matrix4 Inverse() const;
+
+ /** Returns an orthonormal version of the matrix, i.e., guarantees that the
+ rotational component of the matrix is built from column vectors that are
+ all unit vectors and orthogonal to each other.
+ */
+ Matrix4 Orthonormal() const;
+
+ /// Returns the transpose of the matrix
+ Matrix4 Transpose() const;
+
+ /// Returns the determinant of the 3x3 matrix formed by excluding the specified
+ /// row and column from the 4x4 matrix.
+ float SubDeterminant(int exclude_row, int exclude_col) const;
+
+ /// Returns the cofactor matrix.
+ Matrix4 Cofactor() const;
+
+ /// Returns the determinant of the 4x4 matrix
+ float Determinant() const;
+
+
+
+private:
+ float m[16];
+};
+
+
+
+// ---------- Operator Overloads for Working with Points, Vectors, & Matrices ----------
+
+
+// --- Matrix multiplication for Points, Vectors, & Matrices ---
+
+/// Multiply matrix and scalar, returns the new matrix
+Matrix4 operator*(const Matrix4& m, const float& s);
+
+/// Multiply matrix and scalar, returns the new matrix
+Matrix4 operator*(const float& s, const Matrix4& m);
+
+/// Multiply matrix and point, returns the new point
+Point3 operator*(const Matrix4& m, const Point3& p);
+
+/// Multiply matrix and vector, returns the new vector
+Vector3 operator*(const Matrix4& m, const Vector3& v);
+
+/// Multiply two matrices, returns the result
+Matrix4 operator*(const Matrix4& m1, const Matrix4& m2);
+
+
+
+/// Multiply matrix and the point and vector portions of the ray, returns the new ray
+Ray operator*(const Matrix4& m, const Ray& r);
+
+// --- Stream operators ---
+
+std::ostream & operator<< ( std::ostream &os, const Matrix4 &m);
+std::istream & operator>> ( std::istream &is, Matrix4 &m);
+
+
+} // end namespace
+
+#endif
|