Browse Source

Added view transformation matrix.

angel 7 years ago
parent
commit
9f22b0090a
9 changed files with 190 additions and 51 deletions
  1. 14 4
      include/matrix.h
  2. 4 2
      include/model.h
  3. 12 2
      include/vector3.h
  4. 19 16
      src/engine.cpp
  5. 60 7
      src/matrix.cpp
  6. 16 4
      src/model.cpp
  7. 18 11
      src/rasterizer.cpp
  8. 5 5
      src/renderManager.cpp
  9. 42 0
      src/vector.cpp

+ 14 - 4
include/matrix.h

@@ -4,8 +4,9 @@
 #include <array>
 #include <array>
 #include <vector3.h>
 #include <vector3.h>
 
 
-struct transformParameters{
-    Vector3 position;
+struct TransformParameters{
+    TransformParameters() :scaling(Vector3(1,1,1)) {};
+    Vector3 translation;
     Vector3 rotation;
     Vector3 rotation;
     Vector3 scaling;
     Vector3 scaling;
 };
 };
@@ -15,7 +16,7 @@ class Matrix4{
         float& operator()(size_t y, size_t x){
         float& operator()(size_t y, size_t x){
             return mMatrix[y*4 + x];
             return mMatrix[y*4 + x];
         }
         }
-        Matrix4 operator* (Matrix4 rhs);
+        Matrix4 operator* (Matrix4 &rhs);
 
 
         Vector3 matMultVec(Vector3 &vec, float w);
         Vector3 matMultVec(Vector3 &vec, float w);
         
         
@@ -26,7 +27,16 @@ class Matrix4{
         Matrix4 static makeFullRotMat(float alpha, float beta, float gamma);
         Matrix4 static makeFullRotMat(float alpha, float beta, float gamma);
         Matrix4 static makeScaleMat(float scaleX, float scaleY, float scaleZ);
         Matrix4 static makeScaleMat(float scaleX, float scaleY, float scaleZ);
         Matrix4 static makeTranslateMat(float dx, float dy, float dz);
         Matrix4 static makeTranslateMat(float dx, float dy, float dz);
-        Matrix4 static modelMatrix(Vector3 position, Vector3 rotation, Vector3 scaling);
+
+        //Builds a matrix that rotates, scakes abd translates all in one
+        Matrix4 static transformMatrix(TransformParameters transform);
+
+        //Camera transformation matrix (the world from the camera's eyes)
+        Matrix4 static lookAt(Vector3& position, Vector3& target, Vector3& temp);
+
+        //2D to 3D projection matrix
+        Matrix4 static makeProjectionMatrix(float fov, float far, float near);
+
 
 
     private:
     private:
         Matrix4(){};
         Matrix4(){};

+ 4 - 2
include/model.h

@@ -3,6 +3,7 @@
 
 
 #include "mesh.h"
 #include "mesh.h"
 #include "string"
 #include "string"
+#include <matrix.h>
 
 
 class Model{
 class Model{
 
 
@@ -10,11 +11,12 @@ class Model{
         Model(std::string path); 
         Model(std::string path); 
         void describeMesh();
         void describeMesh();
         Mesh *getMesh();
         Mesh *getMesh();
+        void initPosition(TransformParameters initPos);
 
 
     private:
     private:
         void buildMesh(std::string path);
         void buildMesh(std::string path);
-        void getVertices(std::ifstream &fileHandle);
-        void getFaces(std::ifstream &fileHandle);
+        void loadVertices(std::ifstream &fileHandle);
+        void loadFaces(std::ifstream &fileHandle);
         Mesh mMesh;
         Mesh mMesh;
 };
 };
 
 

+ 12 - 2
include/vector3.h

@@ -11,12 +11,22 @@ struct Vector3{
     Vector3(float x1, float y1, float z1) : x(x1), y(y1), z(z1)
     Vector3(float x1, float y1, float z1) : x(x1), y(y1), z(z1)
     {}
     {}
 
 
+    Vector3(){};
+
     Vector3(std::string x1, std::string y1, std::string z1):
     Vector3(std::string x1, std::string y1, std::string z1):
         x(std::stof(x1)), y(std::stof(y1)), z(std::stof(z1))
         x(std::stof(x1)), y(std::stof(y1)), z(std::stof(z1))
     {}
     {}
 
 
-    void scale(float scale);
-    void translate(float dx, float dy, float dz);
+    Vector3 operator-(Vector3 &rhs);
+
+    Vector3&  normalized();
+
+    float length();
+
+    Vector3 crossProduct(Vector3 &rhs);
+
+    float   dotProduct(Vector3 &rhs);
+
 };
 };
 
 
 #endif
 #endif

+ 19 - 16
src/engine.cpp

@@ -2,13 +2,12 @@
 #include <string>
 #include <string>
 #include <vector3.h>
 #include <vector3.h>
 #include <matrix.h>
 #include <matrix.h>
+#include <math.h>
 
 
 Engine::Engine(){
 Engine::Engine(){
-
 }
 }
 
 
 Engine::~Engine(){
 Engine::~Engine(){
-    
 }
 }
 
 
 bool Engine::startUp(){
 bool Engine::startUp(){
@@ -77,30 +76,34 @@ void Engine::loadModels(){
     std::string path = "../models/teapot.obj";
     std::string path = "../models/teapot.obj";
     sceneModels = new Model(path);
     sceneModels = new Model(path);
 
 
+    //We also initialize the model position here position here
+    TransformParameters initParameters;
+    initParameters.scaling = Vector3(90, 90, 90);
+    initParameters.rotation = Vector3(0,0,0);
+    initParameters.translation = Vector3(0, 0, 0);
+
+    sceneModels->initPosition(initParameters);
+
     //sceneModels->describeMesh();
     //sceneModels->describeMesh();
 }
 }
 
 
-
 //Engine class moves stuff, for now
 //Engine class moves stuff, for now
 //Some kind of physics module should be responsible of this in the future
 //Some kind of physics module should be responsible of this in the future
 //Actually it should probably be moved by user input
 //Actually it should probably be moved by user input
 void Engine::moveModels(int dt){
 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);
+    //Creating view matrix
+    
 
 
 
 
-    //Getting vector of vertices
-    Mesh * modelMesh = sceneModels->getMesh();
-    int size = modelMesh->numVertices;
-    std::vector<Vector3> * vertices = &modelMesh->vertices;
+    // //Getting vector of vertices
+    // Mesh * modelMesh = sceneModels->getMesh();
+    // int size = modelMesh->numVertices;
+    // std::vector<Vector3> * vertices = &modelMesh->vertices;
 
 
-    //Applying the multiplication
-    for (int i = 0;i < size; ++i){
-        (*vertices)[i] = modelMatrix.matMultVec((*vertices)[i],1);
-    }
+    // //Applying the multiplication
+    // for (int i = 0;i < size; ++i){
+    //     (*vertices)[i] = viewMatrix.matMultVec((*vertices)[i],1);
+    // }
 
 
 }
 }

+ 60 - 7
src/matrix.cpp

@@ -100,12 +100,11 @@ void Matrix4::printMat(){
     printf("\n");
     printf("\n");
 }
 }
 
 
-
 //Way too general, should probably change in the future since I think
 //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.
 //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 
 //Traverse the matrix cell by cell and find the final value through a step of 
 //sub multiplications that are then added together
 //sub multiplications that are then added together
-Matrix4 Matrix4::operator*(Matrix4 rhs){
+Matrix4 Matrix4::operator*(Matrix4 &rhs){
     //Matrix dimensions
     //Matrix dimensions
     Matrix4 results;
     Matrix4 results;
     int n = 4;
     int n = 4;
@@ -137,10 +136,64 @@ Matrix4 Matrix4::operator*(Matrix4 rhs){
     return results;
     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);
+Matrix4 Matrix4::transformMatrix(TransformParameters transform){
+    Matrix4 rotMatrix = Matrix4::makeFullRotMat(transform.rotation.x,
+                         transform.rotation.y, transform.rotation.z);
+    Matrix4 scaleMatrix = Matrix4::makeScaleMat(transform.scaling.x,
+                         transform.scaling.y, transform.scaling.z);
+    Matrix4 translationMatrix = Matrix4::makeTranslateMat(transform.translation.x,
+                         transform.translation.y, transform.translation.z);
+    Matrix4 temp = (rotMatrix*scaleMatrix);
+    return  translationMatrix*(temp);
+}
+
+Matrix4 Matrix4::makeProjectionMatrix(float fov, float far, float near){
+    Matrix4 projectionMat;
+    //float scale   = 1 / tan( (fov/2) * (M_PI / 180) );
+    //float zScale1 = 
+
+    projectionMat(0,0) = 1;
+    projectionMat(1,1) = 1;
+    projectionMat(2,2) = -1;
+    projectionMat(3,2) = -1;
+
+}
+
+Matrix4 Matrix4::lookAt(Vector3& position, Vector3& target, Vector3& temp){
+
+    Vector3 forward = (position - target).normalized();
+    Vector3 side    = forward.crossProduct(temp.normalized());
+    Vector3 up      = forward.crossProduct(side);
+
+    //We will now build the inverse transform from the world position to the camera
+    //The idea is that we don't care where the camera is, we only care about what
+    //transformation would put the origin at the camera world space position
+    //With the z axis behind the camera.
+    //I bet you this will be really confusing in a couple of weeks
+    Matrix4 worldToCam;
+    
+    
+    //First row
+    worldToCam(0,0) = side.x;
+    worldToCam(0,1) = side.y;
+    worldToCam(0,2) = side.z;
+    worldToCam(0,3) = -side.dotProduct(position);
+
+
+    //First row
+    worldToCam(1,0) = up.x;
+    worldToCam(1,1) = up.y;
+    worldToCam(1,2) = up.z;
+    worldToCam(1,3) = -up.dotProduct(position);
+
+    //First row
+    worldToCam(2,0) = forward.x;
+    worldToCam(2,1) = forward.y;
+    worldToCam(2,2) = forward.z;
+    worldToCam(2,3) = -forward.dotProduct(position);
+
+    //Fourth row
+    worldToCam(3,3) = 1;
 
 
-    return  translationMatrix*(rotMatrix*scaleMatrix);
+    return worldToCam;
 }
 }

+ 16 - 4
src/model.cpp

@@ -4,6 +4,7 @@
 #include <fstream>
 #include <fstream>
 #include <sstream>
 #include <sstream>
 #include "vector3.h"
 #include "vector3.h"
+#include "matrix.h"
 
 
 Model::Model(std::string path){
 Model::Model(std::string path){
     buildMesh(path);
     buildMesh(path);
@@ -30,16 +31,16 @@ void Model::buildMesh(std::string path){
     file.open(path.c_str());
     file.open(path.c_str());
 
 
     //Get vertices into mesh
     //Get vertices into mesh
-    getVertices(file);
+    loadVertices(file);
 
 
     //Get faces
     //Get faces
-    getFaces(file);
+    loadFaces(file);
 
 
     //Close file after reading
     //Close file after reading
     file.close();
     file.close();
 }
 }
 
 
-void Model::getFaces(std::ifstream &file){
+void Model::loadFaces(std::ifstream &file){
     std::string line, f, x ,y ,z;
     std::string line, f, x ,y ,z;
     while(!file.eof()){
     while(!file.eof()){
         
         
@@ -57,7 +58,7 @@ void Model::getFaces(std::ifstream &file){
     file.seekg(0, file.beg);
     file.seekg(0, file.beg);
 }
 }
 
 
-void Model::getVertices(std::ifstream &file){
+void Model::loadVertices(std::ifstream &file){
     std::string line, v, x ,y ,z;
     std::string line, v, x ,y ,z;
     while(!file.eof()){
     while(!file.eof()){
         std::getline(file,line);
         std::getline(file,line);
@@ -72,4 +73,15 @@ void Model::getVertices(std::ifstream &file){
     mMesh.numVertices = mMesh.vertices.size();
     mMesh.numVertices = mMesh.vertices.size();
     file.clear();
     file.clear();
     file.seekg(0, file.beg);
     file.seekg(0, file.beg);
+}
+
+void Model::initPosition(TransformParameters initVals){
+    Matrix4 modelMatrix = Matrix4::transformMatrix(initVals);
+    int size = mMesh.numVertices;
+    std::vector<Vector3> * vertices = &mMesh.vertices;
+
+    //Applying the multiplication
+    for (int i = 0;i < size; ++i){
+        (*vertices)[i] = modelMatrix.matMultVec((*vertices)[i],1);
+    }
 }
 }

+ 18 - 11
src/rasterizer.cpp

@@ -37,10 +37,20 @@ void Rasterizer::drawModels(Model * models){
     Mesh * modelMesh = models->getMesh();
     Mesh * modelMesh = models->getMesh();
     std::vector<Vector3> * faces = &modelMesh->faces;
     std::vector<Vector3> * faces = &modelMesh->faces;
     std::vector<Vector3> * vertices = &modelMesh->vertices;
     std::vector<Vector3> * vertices = &modelMesh->vertices;
+
+    float t = static_cast<float>(SDL_GetTicks());
+    float radius = 10;
+    float camX   = std::sin(t/4000) * radius;
+    float camZ   = std::cos(t/4000) * radius;
+    Vector3 pos(camX, 0, camZ);
+    Vector3 tar;
+    Vector3 v(0,1,0);
+    Matrix4 viewMatrix = Matrix4::lookAt(pos,tar,v);
+
     for (Vector3 f : *faces ){
     for (Vector3 f : *faces ){
-        Vector3 v1 = (*vertices)[f.x-1];
-        Vector3 v2 = (*vertices)[f.y-1];
-        Vector3 v3 = (*vertices)[f.z-1];
+        Vector3 v1 = viewMatrix.matMultVec((*vertices)[f.x-1],1); //-1 because .obj file starts face count
+        Vector3 v2 = viewMatrix.matMultVec((*vertices)[f.y-1],1); // from 1. Should probably fix this 
+        Vector3 v3 = viewMatrix.matMultVec((*vertices)[f.z-1],1); // At some point
         drawLine(v1, v2, red);
         drawLine(v1, v2, red);
         drawLine(v2, v3, green);
         drawLine(v2, v3, green);
         drawLine(v1, v3, blue);
         drawLine(v1, v3, blue);
@@ -49,14 +59,11 @@ void Rasterizer::drawModels(Model * models){
 }   
 }   
 
 
 void Rasterizer::drawLine(Vector3 vertex1, Vector3 vertex2, Uint32 color){
 void Rasterizer::drawLine(Vector3 vertex1, Vector3 vertex2, Uint32 color){
-        //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;
+
+        int x1 = (vertex1.x ) + mCanvas->mWidth * 1 / 2;
+        int y1 = (-vertex1.y ) + mCanvas->mHeight * 2 / 3;
+        int x2 = (vertex2.x  ) + mCanvas->mWidth  * 1 / 2;
+        int y2 = (-vertex2.y ) + mCanvas->mHeight * 2 / 3;
         
         
         //transpose line if it is too steep
         //transpose line if it is too steep
         bool steep = false;
         bool steep = false;

+ 5 - 5
src/renderManager.cpp

@@ -71,18 +71,18 @@ void RenderManager::render(Model *models){
 
 
     //Clear Screen back to black
     //Clear Screen back to black
     clearScreen();
     clearScreen();
-
+    
     //Perform any modifications we want on the pixels
     //Perform any modifications we want on the pixels
     raster->drawModels(models);
     raster->drawModels(models);
 
 
-    //Apply the pixel change to the texture
-    screenTexture.updateTexture(mainCanvas->mBuffer);
-
-    //Switch screen texture with back texture and re-draw
+    //Apply the pixel changes and redraw
     updateScreen();
     updateScreen();
 }
 }
 
 
 void RenderManager::updateScreen(){
 void RenderManager::updateScreen(){
+    
+    screenTexture.updateTexture(mainCanvas->mBuffer);
+
     //Render texture to screen
     //Render texture to screen
     screenTexture.renderToScreen(mainRenderer);
     screenTexture.renderToScreen(mainRenderer);
 
 

+ 42 - 0
src/vector.cpp

@@ -0,0 +1,42 @@
+#include "vector3.h"
+#include "math.h"
+
+Vector3 Vector3::operator-(Vector3 &rhs){
+    return Vector3(this->x - rhs.x,
+                   this->y - rhs.y,
+                   this->z - rhs.z
+    );
+}
+
+Vector3& Vector3::normalized(){
+    float len = this->length();
+    if(len > 0){
+        float factor = 1 / len;
+        this->x*= factor;
+        this->y*= factor;
+        this->z*= factor;
+    }
+    else{
+        //Deal with this at some point!
+        printf("Your vector is all zeros!!\n");
+    }
+    return *this;
+}     
+
+Vector3 Vector3::crossProduct(Vector3 &rhs){
+    Vector3 temp;
+    temp.x = (this->y)*rhs.z - (this->z)*rhs.y;
+    temp.y = (this->x)*rhs.z - (this->z)*rhs.x;
+    temp.z = (this->x)*rhs.y - (this->y)*rhs.x;
+    return temp;
+}
+
+float Vector3::dotProduct(Vector3 &rhs){
+    return (this->x)*rhs.x + (this->y)*rhs.y + (this->z)*rhs.z;
+}
+
+float Vector3::length(){
+    return std::sqrt((this->x * this->x) +
+                     (this->y * this->y) +
+                     (this->z * this->z));
+}