Browse Source

Added matrix class.

angel 7 years ago
parent
commit
7840389183
7 changed files with 195 additions and 102 deletions
  1. 1 1
      include/engine.h
  2. 20 15
      include/matrix.h
  3. 0 4
      include/vector3.h
  4. 21 15
      src/engine.cpp
  5. 144 18
      src/matrix.cpp
  6. 9 7
      src/rasterizer.cpp
  7. 0 42
      src/vector.cpp

+ 1 - 1
include/engine.h

@@ -22,7 +22,7 @@ class Engine{
 
         void loadModels();
 
-        void moveModels();
+        void moveModels(int dt);
 
     private:
         WindowManager FEWindowManager;

+ 20 - 15
include/matrix.h

@@ -1,32 +1,37 @@
 #ifndef MATRIX_H
 #define MATRIX_H
 
-#include <math.h>
 #include <array>
 #include <vector3.h>
 
-class Matrix{
+struct transformParameters{
+    Vector3 position;
+    Vector3 rotation;
+    Vector3 scaling;
+};
+
+class Matrix4{
     public:
         float& operator()(size_t y, size_t x){
-            return mMatrix[y*3 + x];
+            return mMatrix[y*4 + x];
         }
+        Matrix4 operator* (Matrix4 rhs);
 
-        void makeRotX(float theta);
+        Vector3 matMultVec(Vector3 &vec, float w);
+        
+        void printMat();
 
-        Vector3 matXVec(Vector3 &vertex);
+        //Probably should be their own classes or constructors in the future
+        Matrix4 static makeTestMat();
+        Matrix4 static makeFullRotMat(float alpha, float beta, float gamma);
+        Matrix4 static makeScaleMat(float scaleX, float scaleY, float scaleZ);
+        Matrix4 static makeTranslateMat(float dx, float dy, float dz);
+        Matrix4 static modelMatrix(Vector3 position, Vector3 rotation, Vector3 scaling);
 
     private:
-        std::array<float, 9>  mMatrix{0,0,0,0,0,0,0,0,0};
+        Matrix4(){};
+        std::array<float, 16> mMatrix{};
 };
 
 
-// template<class T>
-// class Mat4 : public MatrixM<T,4,4>{
-//     public:
-//         void fullRotMat(T thetaX, T thetaY, T thetaZ);
-        
-// };
-
-
-
 #endif

+ 0 - 4
include/vector3.h

@@ -15,10 +15,6 @@ struct Vector3{
         x(std::stof(x1)), y(std::stof(y1)), z(std::stof(z1))
     {}
 
-    void rotX(float thetaX);
-    void rotY(float thetaY);
-    void rotZ(float thetaZ);
-
     void scale(float scale);
     void translate(float dx, float dy, float dz);
 };

+ 21 - 15
src/engine.cpp

@@ -1,6 +1,7 @@
 #include "engine.h"
 #include <string>
 #include <vector3.h>
+#include <matrix.h>
 
 Engine::Engine(){
 
@@ -44,10 +45,12 @@ void Engine::shutDown(){
 void Engine::mainLoop(){
     bool done = false;
     int count = 0;
+    unsigned int end = 0;
+    unsigned int start = 0;
     printf("Entered Main Loop!\n");
     
     while(!done){
-        unsigned int start = SDL_GetTicks();
+        start = SDL_GetTicks();
         ++count;
 
         //Handle all user input
@@ -56,11 +59,12 @@ void Engine::mainLoop(){
         //Update entities here in the future
         //Right now only does simple demo stuff
         //Maybe physics based in the future??
-        moveModels();
+        int dt = start - end;
+        moveModels(dt);
 
         //Perform all render calculations and update screen
         FERenderManager.render(sceneModels);
-        unsigned int end = SDL_GetTicks();
+        end = SDL_GetTicks();
         //SDL_Delay(100);
         printf("%2.1d: Loop elapsed time (ms):%d\n",count,end - start);
     }
@@ -79,22 +83,24 @@ void Engine::loadModels(){
 
 //Engine class moves stuff, for now
 //Some kind of physics module should be responsible of this in the future
-void Engine::moveModels(){
-    float thetax  = 0.001;
-    float thetay  = 0.001;
-    float thetaz  = 0.00;
-    float scale   = 0.999;
-    float dd      = 0.0;
+//Actually it should probably be moved by user input
+void Engine::moveModels(int dt){
+
+    //Creating model matrix
+    Vector3 position = Vector3(0, 0, 0);
+    Vector3 rotation = Vector3(0.01, 0.01, 0.01);
+    Vector3 scaling  = Vector3(1, 1, 1);
+    Matrix4 modelMatrix = Matrix4::modelMatrix(position, rotation, scaling);
+
+
+    //Getting vector of vertices
     Mesh * modelMesh = sceneModels->getMesh();
     int size = modelMesh->numVertices;
-    std::vector<Vector3> *   vertices = &modelMesh->vertices;
+    std::vector<Vector3> * vertices = &modelMesh->vertices;
 
+    //Applying the multiplication
     for (int i = 0;i < size; ++i){
-        (*vertices)[i].scale(scale);
-        (*vertices)[i].rotX(thetax);
-        (*vertices)[i].rotY(thetay);
-        (*vertices)[i].rotZ(thetaz);
-        (*vertices)[i].translate(dd, dd, dd);
+        (*vertices)[i] = modelMatrix.matMultVec((*vertices)[i],1);
     }
 
 }

+ 144 - 18
src/matrix.cpp

@@ -1,20 +1,146 @@
 #include "matrix.h"
+#include <math.h>
 
-//TEMPLATES ARE THE WORST
-// template<class T>
-// void Mat3::fullRotMat(T thetaX, T thetaY, T thetaZ){
-//     //We ignore the Y and Z for now
-//     Mat3
-//     Mat3 xRot = 
-// }
-
-
-// void Matrix::makeRotX(float theta){
-//     float cosine  = std::cos(theta);
-//     float sine    = std::sin(theta);
-//     mMatrix(0,1)  = 1;
-//     mMatrix(1,1)  = cosine;
-//     mMatrix(1,2)  = -sine;
-//     mMatrix(2,1)  = sine;
-//     mMatrix(2,2)  = cosine;
-// }
+Vector3 Matrix4::matMultVec(Vector3 &vec, float w){
+    Vector3 newVec(0,0,0);
+    newVec.x = vec.x*(*this)(0,0)+
+               vec.y*(*this)(0,1)+
+               vec.z*(*this)(0,2)+
+               w*(*this)(0,3);
+
+    newVec.y = vec.x*(*this)(1,0)+
+               vec.y*(*this)(1,1)+
+               vec.z*(*this)(1,2)+
+               w*(*this)(1,3);
+
+    newVec.z = vec.x*(*this)(2,0)+
+               vec.y*(*this)(2,1)+
+               vec.z*(*this)(2,2)+
+               w*(*this)(2,3);
+
+    return newVec;
+}
+
+Matrix4 Matrix4::makeFullRotMat(float alpha, float beta, float gamma){
+    Matrix4 rotMat;
+    float cosA = std::cos(alpha);
+    float sinA = std::sin(alpha);
+
+    float cosB = std::cos(beta);
+    float sinB = std::sin(beta);
+
+    float cosG = std::cos(gamma);
+    float sinG = std::sin(gamma);
+
+    //First row
+    rotMat(0,0) = cosB*cosG;
+    rotMat(0,1) = -cosA*sinG + sinA*sinB*cosG;
+    rotMat(0,2) = sinA*sinG + cosA*sinB*cosG;
+
+    //Second row
+    rotMat(1,0) = cosB*sinG;
+    rotMat(1,1) = cosA*cosG + sinA*sinB*sinG;
+    rotMat(1,2) = -sinA*cosG + cosA*sinB*sinG;
+
+    //Third row
+    rotMat(2,0) = -sinB;
+    rotMat(2,1) = sinA*cosB;
+    rotMat(2,2) = cosA*cosB;
+
+    //Fourth row
+    rotMat(3,3) = 1;
+
+    return rotMat;
+}
+
+Matrix4 Matrix4::makeScaleMat(float scaleX, float scaleY, float scaleZ){
+    Matrix4 scaleMat;
+    scaleMat(0,0) = scaleX;
+    scaleMat(1,1) = scaleY;
+    scaleMat(2,2) = scaleZ;
+    scaleMat(3,3) = 1;
+    return scaleMat;
+}
+
+Matrix4 Matrix4::makeTranslateMat(float dx, float dy, float dz){
+    Matrix4 transMat;
+    transMat(0,0) = 1;
+    transMat(1,1) = 1;
+    transMat(2,2) = 1;
+    transMat(0,3) = dx;
+    transMat(1,3) = dy;
+    transMat(2,3) = dz;
+    transMat(3,3) = 1;
+
+    return transMat;
+}
+
+Matrix4 Matrix4::makeTestMat(){
+    Matrix4 testMat;
+    int n = 4;
+    int val = 1;
+    for(int rows = 0; rows < n; ++rows){
+        for(int cols = 0; cols < n; ++cols){
+            testMat(rows,cols) = val;
+            ++val;
+        }
+    }
+    return testMat;
+}
+
+void Matrix4::printMat(){
+    int n = 4;
+    for(int rows = 0; rows < n; ++rows){
+        for(int cols = 0; cols < n; ++cols){
+            float val = (*this)(rows,cols) ;
+            printf("%f\t",val);
+        }
+        printf("\n");
+    }
+    printf("\n");
+}
+
+
+//Way too general, should probably change in the future since I think
+//I'll only need 4x4 stuff and this technically allows for any n matrix.
+//Traverse the matrix cell by cell and find the final value through a step of 
+//sub multiplications that are then added together
+Matrix4 Matrix4::operator*(Matrix4 rhs){
+    //Matrix dimensions
+    Matrix4 results;
+    int n = 4;
+
+    for(int rows = 0; rows < n; ++rows){
+        for(int cols = 0; cols < n; ++cols){
+            float total = 0;
+            //total value of multiplication with all submultiplications added together
+
+            //sub represents submultiplications in the actual matrix multiplication
+            //For a nxn matrix you have n submultiplications
+
+            for(int sub = 1; sub < n+1; ++sub ){
+                int rowLhs = rows; //row ind left matrix
+                int colLhs = sub - 1; //col ind left matrix
+
+                int rowRhs = sub -1; //row ind right matrix
+                int colRhs = cols; //col ind right matrix
+
+                total += (*this)(rowLhs,colLhs) * rhs(rowRhs,colRhs);
+                
+            }
+
+            //Setting the specific row and column to the total value of the subm-
+            //multiplications for that specifc cell of the matrix
+            results(rows,cols) = total;
+        }
+    }
+    return results;
+}
+
+Matrix4 Matrix4::modelMatrix(Vector3 pos, Vector3 rot, Vector3 scale){
+    Matrix4 rotMatrix = Matrix4::makeFullRotMat(rot.x, rot.y, rot.z);
+    Matrix4 scaleMatrix = Matrix4::makeScaleMat(scale.x, scale.y, scale.z);
+    Matrix4 translationMatrix = Matrix4::makeTranslateMat(pos.x, pos.y, pos.z);
+
+    return  translationMatrix*(rotMatrix*scaleMatrix);
+}

+ 9 - 7
src/rasterizer.cpp

@@ -49,11 +49,14 @@ void Rasterizer::drawModels(Model * models){
 }   
 
 void Rasterizer::drawLine(Vector3 vertex1, Vector3 vertex2, Uint32 color){
-        int scalingFactor = 90;
-        int x1 = (vertex1.x  * scalingFactor) + mCanvas->mWidth * 1 / 2;
-        int y1 = (-vertex1.y  * scalingFactor) + mCanvas->mHeight * 2 / 3;
-        int x2 = (vertex2.x  * scalingFactor) + mCanvas->mWidth  * 1 / 2;
-        int y2 = (-vertex2.y  * scalingFactor) + mCanvas->mHeight * 2 / 3;
+        //COMPLETE HACK, REMOVE ASAP
+        int scale = 90;
+        //BAD CODE, BAD BAD BAD
+
+        int x1 = (vertex1.x * scale ) + mCanvas->mWidth * 1 / 2;
+        int y1 = (-vertex1.y * scale ) + mCanvas->mHeight * 2 / 3;
+        int x2 = (vertex2.x * scale ) + mCanvas->mWidth  * 1 / 2;
+        int y2 = (-vertex2.y * scale ) + mCanvas->mHeight * 2 / 3;
         
         //transpose line if it is too steep
         bool steep = false;
@@ -94,9 +97,8 @@ void Rasterizer::drawLine(Vector3 vertex1, Vector3 vertex2, Uint32 color){
 void Rasterizer::setPixelColor(Uint32 color, int x, int y){
     int arrayCoordinates = convertCoordinates(x,y);
     if( ((x >= 0 ) && (y >= 0)) && ((x < mCanvas->mWidth ) && (y < mCanvas->mHeight))  ){   
-    mCanvas->mBuffer[arrayCoordinates] = color;
+        mCanvas->mBuffer[arrayCoordinates] = color;
     }
-    
 }
 
 int Rasterizer::convertCoordinates(int x, int y){

+ 0 - 42
src/vector.cpp

@@ -1,42 +0,0 @@
-#include "vector3.h"
-#include <math.h>
-
-void Vector3::rotX(float theta){
-    float cosine  = std::cos(theta);
-    float sine    = std::sin(theta);
-    float yTemp = y;
-    float zTemp = z;
-    y = yTemp*cosine + -zTemp*sine;
-    z = yTemp*sine   + zTemp*cosine;
-}   
-
-
-void Vector3::rotY(float theta){
-    float cosine  = std::cos(theta);
-    float sine    = std::sin(theta);
-    float xTemp = x;
-    float zTemp = z;
-    x = xTemp*cosine + zTemp*sine;
-    z = -xTemp*sine   + zTemp*cosine;
-}   
-
-void Vector3::rotZ(float theta){
-    float cosine  = std::cos(theta);
-    float sine    = std::sin(theta);
-    float xTemp = x;
-    float yTemp = y;
-    x = xTemp*cosine + -yTemp*sine;
-    y = xTemp*sine   + yTemp*cosine;
-}   
-
-void Vector3::scale(float scale){
-    x *= scale;
-    y *= scale;
-    z *= scale;
-}
-
-void Vector3::translate(float dx, float dy, float dz){
-    x +=dx;
-    y +=dy;
-    z +=dz;
-}