Calculate face normals from vertices

master
outfrost 2020-06-12 02:52:07 +02:00
parent d9f11e52d3
commit 91db944c53
5 changed files with 51 additions and 9 deletions

View 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,

View File

@ -31,6 +31,7 @@ struct Mesh {
struct Face {
size_t numIndices;
size_t* indices;
Vector3D* normals;
};
struct Material {

View 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 };

View 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);

View 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);
}