]> git.lizzy.rs Git - shadowclad.git/commitdiff
Calculate face normals from vertices
authoroutfrost <kotlet.bahn@gmail.com>
Fri, 12 Jun 2020 00:52:07 +0000 (02:52 +0200)
committeroutfrost <kotlet.bahn@gmail.com>
Fri, 12 Jun 2020 00:52:07 +0000 (02:52 +0200)
src/engine/asset.c
src/engine/asset.h
src/engine/geometry.c
src/engine/geometry.h
src/engine/render.c

index b5744aaaf32bb99b0ca4850ea3b261c90de570c6..83b3180f88d2860dd5d2f4ec72d339053aea3746 100644 (file)
@@ -13,6 +13,7 @@
 #define IMPORT_DEBUG_ 1
 
 static const struct aiScene* importScene(const char* path);
+static Vector3D triangleNormal(Vector3D v1, Vector3D v2, Vector3D v3);
 static Vector3D convertAiVector3D(struct aiVector3D vect);
 static const char* replaceFileExtension(const struct aiString path, const char* ext);
 
@@ -138,12 +139,33 @@ const Solid* importSolid(const char* path) {
                        const unsigned int numIndices = aiFace.mNumIndices;
                        
                        Face face = { .numIndices = numIndices,
-                                     .indices = malloc(numIndices * sizeof(size_t)) };
+                                     .indices = malloc(numIndices * sizeof(size_t)),
+                                     .normals = malloc(numIndices * sizeof(Vector3D)) };
                        
                        for (unsigned int i = 0; i < numIndices; ++i) {
                                face.indices[i] = aiFace.mIndices[i];
                        }
                        
+                       if (numIndices == 3) {
+                               Vector3D normal = triangleNormal(mesh.vertices[face.indices[0]],
+                                                                mesh.vertices[face.indices[1]],
+                                                                mesh.vertices[face.indices[2]]);
+                               for (size_t i = 0; i < numIndices; ++i) {
+                                       face.normals[i] = normal;
+                               }
+                       }
+                       else {
+                               if (mesh.normals) {
+                                       for (size_t i = 0; i < numIndices; ++i) {
+                                               face.normals[i] = mesh.normals[face.indices[i]];
+                                       }
+                               }
+                               else {
+                                       free(face.normals);
+                                       face.normals = NULL;
+                               }
+                       }
+                       
                        mesh.faces[faceIndex] = face;
                }
                
@@ -224,6 +246,10 @@ static const struct aiScene* importScene(const char* path) {
        return scene;
 }
 
+static Vector3D triangleNormal(Vector3D v1, Vector3D v2, Vector3D v3) {
+       return normalized(crossProduct(subtractVectors(v2, v1), subtractVectors(v3, v1)));
+}
+
 static Vector3D convertAiVector3D(struct aiVector3D vect) {
        return (Vector3D) { .x = vect.x,
                            .y = vect.y,
index 9354c47c7615faa952baf8112b03ae98da855985..21ecadbc9574225c9271883ea4a4d295b538ae46 100644 (file)
@@ -31,6 +31,7 @@ struct Mesh {
 struct Face {
        size_t numIndices;
        size_t* indices;
+       Vector3D* normals;
 };
 
 struct Material {
index 2cfb0aac767936b896d59531a70ad5555bc97f5c..311a645864adf0fa08fed6017a187574ae658372 100644 (file)
@@ -58,6 +58,20 @@ void rotate(Transform* transform, Vector3D axis, float angle) {
                *transform);
 }
 
+Vector3D addVectors(Vector3D v1, Vector3D v2){
+       return (Vector3D) { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
+}
+
+Vector3D subtractVectors(Vector3D v1, Vector3D v2) {
+       return (Vector3D) { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
+}
+
+Vector3D crossProduct(Vector3D v1, Vector3D v2) {
+       return (Vector3D) { .x = (v1.y * v2.z) - (v1.z * v2.y),
+                           .y = (v1.z * v2.x) - (v1.x * v2.z),
+                           .z = (v1.x * v2.y) - (v1.y * v2.x) };
+}
+
 Vector3D applyTransform(Transform transform, Vector3D vec) {
        GLfloat* a = (GLfloat*) &transform;
        GLfloat b[4] = { vec.x, vec.y, vec.z, 1.0f };
index ff45938aac5402d752d738c958161357975973b0..bac0ebb93de2c52ab457fff085e524eadc30a233 100644 (file)
@@ -25,6 +25,9 @@ Transform identity();
 Transform multiply(Transform t1, Transform t2);
 void translate(Transform* transform, Vector3D vec);
 void rotate(Transform* transform, Vector3D axis, float angle);
+Vector3D addVectors(Vector3D v1, Vector3D v2);
+Vector3D subtractVectors(Vector3D v1, Vector3D v2);
+Vector3D crossProduct(Vector3D v1, Vector3D v2);
 Vector3D applyTransform(Transform transform, Vector3D vec);
 Vector3D translationOf(Transform transform);
 Vector3D normalized(Vector3D vec);
index c75dc7198a2427f92dc6bfdb9e5d8269fbbadcd2..6ba5103b306be17a628b6eb67c57b58e8835f421 100644 (file)
@@ -39,7 +39,7 @@ void initRender() {
        glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05f);
        glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.005f);
        
-       glShadeModel(GL_FLAT);
+       //glShadeModel(GL_FLAT);
 }
 
 void renderFrame() {
@@ -148,14 +148,12 @@ static void drawSolid(const Solid* solid) {
                const Mesh mesh = solid->meshes[meshIndex];
                glBindTexture(GL_TEXTURE_2D,
                              solid->materials[mesh.materialIndex].textureId);
-               bool hasNormals = mesh.normals != NULL;
-               bool hasTextureCoords = mesh.textureCoords != NULL;
                
                for (size_t faceIndex = 0; faceIndex < mesh.numFaces; ++faceIndex) {
                        const Face face = mesh.faces[faceIndex];
                        
 #if RENDER_DEBUG_
-                       if (hasNormals) {
+                       if (mesh.normals) {
                                glDisable(GL_LIGHTING);
                                glDisable(GL_TEXTURE_2D);
                                glBegin(GL_LINES);
@@ -185,15 +183,15 @@ static void drawSolid(const Solid* solid) {
                        
                        for (size_t i = 0; i < face.numIndices; ++i) {
                                size_t vertIndex = face.indices[i];
-                               size_t normalIndex = face.indices[2];
-                               if (hasNormals) {
-                                       if (hasTextureCoords) {
+                               if (face.normals) {
+                                       if (mesh.textureCoords) {
                                                Vector3D coords = mesh.textureCoords[vertIndex];
                                                glTexCoord2f(coords.x, coords.y);
                                        }
-                                       Vector3D normal = mesh.normals[normalIndex];
+                                       Vector3D normal = face.normals[i];
                                        glNormal3f(normal.x, normal.y, normal.z);
                                }
+
                                Vector3D vertex = mesh.vertices[vertIndex];
                                glVertex3f(vertex.x, vertex.y, vertex.z);
                        }