vector operations and backface culling
This commit is contained in:
parent
f2c976c4c1
commit
9bb767b58f
46
assets/cube.obj
Normal file
46
assets/cube.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# Blender v2.76 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cube.mtl
|
||||
o Cube
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -0.999999
|
||||
v 0.999999 1.000000 1.000001
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
vt 1.000000 0.333333
|
||||
vt 1.000000 0.666667
|
||||
vt 0.666667 0.666667
|
||||
vt 0.666667 0.333333
|
||||
vt 0.666667 0.000000
|
||||
vt 0.000000 0.333333
|
||||
vt 0.000000 0.000000
|
||||
vt 0.333333 0.000000
|
||||
vt 0.333333 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.666667
|
||||
vt 0.333333 0.333333
|
||||
vt 0.333333 0.666667
|
||||
vt 1.000000 0.000000
|
||||
vn 0.000000 -1.000000 0.000000
|
||||
vn 0.000000 1.000000 0.000000
|
||||
vn 1.000000 0.000000 0.000000
|
||||
vn -0.000000 0.000000 1.000000
|
||||
vn -1.000000 -0.000000 -0.000000
|
||||
vn 0.000000 0.000000 -1.000000
|
||||
usemtl Material
|
||||
s off
|
||||
f 2/1/1 3/2/1 4/3/1
|
||||
f 8/1/2 7/4/2 6/5/2
|
||||
f 5/6/3 6/7/3 2/8/3
|
||||
f 6/8/4 7/5/4 3/4/4
|
||||
f 3/9/5 7/10/5 8/11/5
|
||||
f 1/12/6 4/13/6 8/11/6
|
||||
f 1/4/1 2/1/1 4/3/1
|
||||
f 5/14/2 8/1/2 6/5/2
|
||||
f 1/12/3 5/6/3 2/8/3
|
||||
f 2/12/4 6/8/4 3/4/4
|
||||
f 4/13/5 3/9/5 8/11/5
|
||||
f 5/6/6 1/12/6 8/11/6
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
triangle_t* triangles_to_render = NULL; //[N_MESH_FACES];
|
||||
|
||||
vec3_t camera_position = { .x = 0, .y = 0, .z = -5 };
|
||||
vec3_t camera_position = { 0, 0, 0 };
|
||||
|
||||
float fov_factor = 640;
|
||||
|
||||
@ -84,9 +84,9 @@ void update(void) {
|
||||
|
||||
previous_frame_time = SDL_GetTicks();
|
||||
|
||||
//mesh.rotation.y += 0.01;
|
||||
mesh.rotation.y += 0.01;
|
||||
mesh.rotation.x -= 0.01;
|
||||
//mesh.rotation.z += 0.01;
|
||||
mesh.rotation.z += 0.01;
|
||||
|
||||
triangles_to_render = NULL;
|
||||
|
||||
@ -94,25 +94,57 @@ void update(void) {
|
||||
for (int i = 0; i < num_faces; i++) {
|
||||
face_t mesh_face = mesh.faces[i];
|
||||
|
||||
vec3_t face_verticies[3];
|
||||
face_verticies[0] = mesh.vertices[mesh_face.a - 1];
|
||||
face_verticies[1] = mesh.vertices[mesh_face.b - 1];
|
||||
face_verticies[2] = mesh.vertices[mesh_face.c - 1];
|
||||
vec3_t face_vertices[3];
|
||||
face_vertices[0] = mesh.vertices[mesh_face.a - 1];
|
||||
face_vertices[1] = mesh.vertices[mesh_face.b - 1];
|
||||
face_vertices[2] = mesh.vertices[mesh_face.c - 1];
|
||||
|
||||
triangle_t projected_triangle;
|
||||
vec3_t transformed_vertices[3];
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
vec3_t transformed_vertex = face_verticies[j];
|
||||
vec3_t transformed_vertex = face_vertices[j];
|
||||
|
||||
transformed_vertex = vec3_rotate_x(transformed_vertex, mesh.rotation.x);
|
||||
transformed_vertex = vec3_rotate_y(transformed_vertex, mesh.rotation.y);
|
||||
transformed_vertex = vec3_rotate_z(transformed_vertex, mesh.rotation.z);
|
||||
|
||||
// translate away from camera in z
|
||||
transformed_vertex.z -= camera_position.z;
|
||||
transformed_vertex.z += 5;
|
||||
|
||||
// save translated vertex in the array of transformed vertices
|
||||
transformed_vertices[j] = transformed_vertex;
|
||||
}
|
||||
|
||||
// check backface culling
|
||||
vec3_t vector_a = transformed_vertices[0]; /* A */
|
||||
vec3_t vector_b = transformed_vertices[1]; /* / \ */
|
||||
vec3_t vector_c = transformed_vertices[2]; /* C---B */
|
||||
|
||||
// get the vector subtraction of B-A and C-A
|
||||
vec3_t vector_ab = vec3_subtract(vector_b, vector_a);
|
||||
vec3_t vector_ac = vec3_subtract(vector_c, vector_a);
|
||||
vec3_normalize(&vector_ab);
|
||||
vec3_normalize(&vector_ac);
|
||||
|
||||
// compute the face normal using the cross product to find perpindicular
|
||||
vec3_t normal = vec3_cross(vector_ab, vector_ac);
|
||||
vec3_normalize(&normal);
|
||||
|
||||
// find the vector between a point in the triangle and the camera origin
|
||||
vec3_t camera_ray = vec3_subtract(camera_position, vector_a);
|
||||
|
||||
// calculate how aligned the camera ray is with the face normal
|
||||
float dot_normal_camera = vec3_dot(normal, camera_ray);
|
||||
|
||||
if (dot_normal_camera < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
triangle_t projected_triangle;
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
// project the current vertex
|
||||
vec2_t projected_point = project(transformed_vertex);
|
||||
vec2_t projected_point = project(transformed_vertices[j]);
|
||||
|
||||
// scale and translate the projected points to the center of the screen
|
||||
projected_point.x += (window_width / 2);
|
||||
@ -124,6 +156,21 @@ void update(void) {
|
||||
// save the projected triangle in the array of triangles
|
||||
array_push(triangles_to_render, projected_triangle);
|
||||
|
||||
triangle_t normal_triangle;
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
// project the current vertex
|
||||
vec2_t projected_point = project(transformed_vertices[j]);
|
||||
|
||||
// scale and translate the projected points to the center of the screen
|
||||
projected_point.x += (window_width / 2);
|
||||
projected_point.y += (window_height / 2);
|
||||
|
||||
normal_triangle.points[j] = projected_point;
|
||||
}
|
||||
|
||||
array_push(triangles_to_render, normal_triangle);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -75,7 +75,7 @@ void load_file(void) {
|
||||
FILE* fp;
|
||||
char* tok;
|
||||
|
||||
fp = fopen("..\\assets\\f22.obj", "r");
|
||||
fp = fopen("..\\assets\\cube.obj", "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
@ -21,6 +21,8 @@ struct mesh_t {
|
||||
|
||||
extern mesh_t mesh;
|
||||
|
||||
void parse_face(const char* buffer, face_t* face);
|
||||
|
||||
void load_cube_mesh_data(void);
|
||||
void load_file(void);
|
||||
|
||||
|
||||
@ -25,4 +25,101 @@ vec3_t vec3_rotate_z(vec3_t v, float angle) {
|
||||
.y = v.x * sin(angle) + v.y * cos(angle),
|
||||
.z = v.z,
|
||||
};
|
||||
}
|
||||
|
||||
float vec2_length(const vec2_t vector) {
|
||||
return sqrt((vector.x * vector.x) + (vector.y * vector.y));
|
||||
}
|
||||
|
||||
vec2_t vec2_add(const vec2_t a, const vec2_t b) {
|
||||
return (vec2_t) {
|
||||
.x = a.x + b.x,
|
||||
.y = a.y + b.y,
|
||||
};
|
||||
}
|
||||
|
||||
vec2_t vec2_subtract(const vec2_t a, const vec2_t b) {
|
||||
return (vec2_t) {
|
||||
.x = a.x - b.x,
|
||||
.y = a.y - b.y,
|
||||
};
|
||||
}
|
||||
|
||||
vec2_t vec2_multiply(const vec2_t vector, float scalar) {
|
||||
return (vec2_t) {
|
||||
.x = vector.x * scalar,
|
||||
.y = vector.y * scalar,
|
||||
};
|
||||
}
|
||||
|
||||
vec2_t vec2_divide(const vec2_t vector, float scalar) {
|
||||
return (vec2_t) {
|
||||
.x = vector.x / scalar,
|
||||
.y = vector.y / scalar,
|
||||
};
|
||||
}
|
||||
|
||||
float vec2_dot(const vec2_t a, const vec2_t b) {
|
||||
return (a.x * b.x) + (a.y * b.y);
|
||||
}
|
||||
|
||||
float vec3_length(const vec3_t vector) {
|
||||
return sqrtf((vector.x * vector.x) + (vector.y * vector.y) + (vector.z * vector.z));
|
||||
}
|
||||
|
||||
void vec2_normalize(vec2_t* vertex) {
|
||||
float length = vec2_length(*vertex);
|
||||
vertex->x /= length;
|
||||
vertex->y /= length;
|
||||
}
|
||||
|
||||
vec3_t vec3_add(const vec3_t a, const vec3_t b) {
|
||||
return (vec3_t) {
|
||||
.x = a.x + b.x,
|
||||
.y = a.y + b.y,
|
||||
.z = a.z + b.z,
|
||||
};
|
||||
}
|
||||
|
||||
vec3_t vec3_subtract(const vec3_t a, const vec3_t b) {
|
||||
return (vec3_t) {
|
||||
.x = a.x - b.x,
|
||||
.y = a.y - b.y,
|
||||
.z = a.z - b.z,
|
||||
};
|
||||
}
|
||||
|
||||
vec3_t vec3_multiply(const vec3_t vector, const float scalar) {
|
||||
return (vec3_t) {
|
||||
.x = vector.x * scalar,
|
||||
.y = vector.y * scalar,
|
||||
.z = vector.z * scalar,
|
||||
};
|
||||
}
|
||||
|
||||
vec3_t vec3_divide(const vec3_t vector, const float scalar) {
|
||||
return (vec3_t) {
|
||||
.x = vector.x / scalar,
|
||||
.y = vector.y / scalar,
|
||||
.z = vector.z / scalar,
|
||||
};
|
||||
}
|
||||
|
||||
vec3_t vec3_cross(const vec3_t a, const vec3_t b) {
|
||||
return (vec3_t) {
|
||||
.x = a.y * b.z - a.z * b.y,
|
||||
.y = a.z * b.x - a.x * b.z,
|
||||
.z = a.x * b.y - a.y * b.x,
|
||||
};
|
||||
}
|
||||
|
||||
float vec3_dot(const vec3_t a, const vec3_t b) {
|
||||
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
|
||||
}
|
||||
|
||||
void vec3_normalize(vec3_t* vertex) {
|
||||
float length = vec3_length(*vertex);
|
||||
vertex->x /= length;
|
||||
vertex->y /= length;
|
||||
vertex->z /= length;
|
||||
}
|
||||
@ -19,4 +19,21 @@ vec3_t vec3_rotate_x(vec3_t v, float angle);
|
||||
vec3_t vec3_rotate_y(vec3_t v, float angle);
|
||||
vec3_t vec3_rotate_z(vec3_t v, float angle);
|
||||
|
||||
vec2_t vec2_add(const vec2_t a, const vec2_t b);
|
||||
vec2_t vec2_subtract(const vec2_t a, const vec2_t b);
|
||||
vec2_t vec2_multiply(const vec2_t vector, float scalar);
|
||||
vec2_t vec2_divide(const vec2_t vector, float scalar);
|
||||
float vec2_length(const vec2_t vector);
|
||||
float vec2_dot(const vec2_t a, const vec2_t b);
|
||||
void vec2_normalize(vec2_t* vertex);
|
||||
|
||||
vec3_t vec3_add(const vec3_t a, const vec3_t b);
|
||||
vec3_t vec3_subtract(const vec3_t a, const vec3_t b);
|
||||
vec3_t vec3_multiply(const vec3_t vector, const float scalar);
|
||||
vec3_t vec3_divide(const vec3_t vector, const float scalar);
|
||||
vec3_t vec3_cross(const vec3_t a, const vec3_t b);
|
||||
float vec3_length(const vec3_t vector);
|
||||
float vec3_dot(const vec3_t a, const vec3_t b);
|
||||
void vec3_normalize(vec3_t* vertex);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user