Skip to content

Commit

Permalink
made public
Browse files Browse the repository at this point in the history
  • Loading branch information
optiklab committed Apr 18, 2023
1 parent 6c7bfbc commit bc7e34b
Show file tree
Hide file tree
Showing 158 changed files with 64,754 additions and 0 deletions.
85 changes: 85 additions & 0 deletions Camera.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "Camera.h"

static camera_t camera;

void init_camera(vec3_t position, vec3_t direction)
{
camera.position = position;
camera.direction = direction;
camera.forward_velocity = vec3_new(0, 0, 0);
camera.yaw = 0.0;
camera.pitch = 0.0;
};

vec3_t get_camera_position(void)
{
return camera.position;
}

vec3_t get_camera_direction(void)
{
return camera.direction;
}

vec3_t get_camera_forward_velocity(void)
{
return camera.forward_velocity;
}

float get_camera_yaw(void)
{
return camera.yaw;
}

float get_camera_pitch(void)
{
return camera.pitch;
}

void update_camera_position(vec3_t position)
{
camera.position = position;
}

void update_camera_direction(vec3_t direction)
{
camera.direction = direction;
}

void update_camera_forward_velocity(vec3_t forward_velocity)
{
camera.forward_velocity = forward_velocity;
}

void rotate_camera_yaw(float angle)
{
camera.yaw += angle;
}

void rotate_camera_pitch(float angle)
{
camera.pitch += angle;
}

vec3_t get_camera_lookat_target(void)
{
// Initialize the target looking at the positive z-axis
vec3_t target = { 0, 0, 1 };

mat4_t camera_yaw_rotation = mat4_make_rotation_y(camera.yaw);
mat4_t camera_pitch_rotation = mat4_make_rotation_x(camera.pitch);

// Create camera rotation matrix based on yaw and pitch
mat4_t camera_rotation = mat4_identity();
camera_rotation = mat4_mul_mat4(camera_pitch_rotation, camera_rotation);
camera_rotation = mat4_mul_mat4(camera_yaw_rotation, camera_rotation);

// Update camera direction based on the rotation
vec4_t camera_direction = mat4_mul_vec4(camera_rotation, vec4_from_vec3(target));
camera.direction = vec3_from_vec4(camera_direction);

// Offset the camera position in the direction where the camera is pointing at
target = vec3_add(camera.position, camera.direction);

return target;
}
32 changes: 32 additions & 0 deletions Camera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef CAMERA_H
#define CAMERA_H

#include "Vector.h"
#include "Matrix.h"

typedef struct {
vec3_t position;
vec3_t direction;
vec3_t forward_velocity;
float yaw;
float pitch;
} camera_t;

void init_camera(vec3_t position, vec3_t direction);

vec3_t get_camera_position(void);
vec3_t get_camera_direction(void);
vec3_t get_camera_forward_velocity(void);
float get_camera_yaw(void);
float get_camera_pitch(void);

void update_camera_position(vec3_t position);
void update_camera_direction(vec3_t direction);
void update_camera_forward_velocity(vec3_t forward_velocity);

void rotate_camera_yaw(float angle);
void rotate_camera_pitch(float angle);

vec3_t get_camera_lookat_target(void);

#endif
206 changes: 206 additions & 0 deletions Clipping.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#include <math.h>
#include "Clipping.h"

#define NUM_PLANES 6
plane_t frustum_planes[NUM_PLANES];

///////////////////////////////////////////////////////////////////////////////
// Frustum planes are defined by a point and a normal vector
///////////////////////////////////////////////////////////////////////////////
// Near plane : P=(0, 0, znear), N=(0, 0, 1)
// Far plane : P=(0, 0, zfar), N=(0, 0, -1)
// Top plane : P=(0, 0, 0), N=(0, -cos(fovy/2), sin(fovy/2))
// Bottom plane : P=(0, 0, 0), N=(0, cos(fovy/2), sin(fovy/2))
// Left plane : P=(0, 0, 0), N=(cos(fovx/2), 0, sin(fovx/2))
// Right plane : P=(0, 0, 0), N=(-cos(fovx/2), 0, sin(fovx/2))
///////////////////////////////////////////////////////////////////////////////
//
// /|\
// / | |
// /\ | |
// / | |
// P*|--> <-|*| ----> +z-axis
// \ | |
// \/ | |
// \ | |
// \|/
//
///////////////////////////////////////////////////////////////////////////////
void init_frustum_planes(float fov_x, float fov_y, float z_near, float z_far)
{
float cos_half_fov_x = cos(fov_x / 2);
float sin_half_fov_x = sin(fov_x / 2);
float cos_half_fov_y = cos(fov_y / 2);
float sin_half_fov_y = sin(fov_y / 2);

frustum_planes[LEFT_FRUSTUM_PLANE].point = vec3_new(0, 0, 0);
frustum_planes[LEFT_FRUSTUM_PLANE].normal.x = cos_half_fov_x;
frustum_planes[LEFT_FRUSTUM_PLANE].normal.y = 0;
frustum_planes[LEFT_FRUSTUM_PLANE].normal.z = sin_half_fov_x;

frustum_planes[RIGHT_FRUSTUM_PLANE].point = vec3_new(0, 0, 0);
frustum_planes[RIGHT_FRUSTUM_PLANE].normal.x = -cos_half_fov_x;
frustum_planes[RIGHT_FRUSTUM_PLANE].normal.y = 0;
frustum_planes[RIGHT_FRUSTUM_PLANE].normal.z = sin_half_fov_x;

frustum_planes[TOP_FRUSTUM_PLANE].point = vec3_new(0, 0, 0);
frustum_planes[TOP_FRUSTUM_PLANE].normal.x = 0;
frustum_planes[TOP_FRUSTUM_PLANE].normal.y = -cos_half_fov_y;
frustum_planes[TOP_FRUSTUM_PLANE].normal.z = sin_half_fov_y;

frustum_planes[BOTTOM_FRUSTUM_PLANE].point = vec3_new(0, 0, 0);
frustum_planes[BOTTOM_FRUSTUM_PLANE].normal.x = 0;
frustum_planes[BOTTOM_FRUSTUM_PLANE].normal.y = cos_half_fov_y;
frustum_planes[BOTTOM_FRUSTUM_PLANE].normal.z = sin_half_fov_y;

frustum_planes[NEAR_FRUSTUM_PLANE].point = vec3_new(0, 0, z_near);
frustum_planes[NEAR_FRUSTUM_PLANE].normal.x = 0;
frustum_planes[NEAR_FRUSTUM_PLANE].normal.y = 0;
frustum_planes[NEAR_FRUSTUM_PLANE].normal.z = 1;

frustum_planes[FAR_FRUSTUM_PLANE].point = vec3_new(0, 0, z_far);
frustum_planes[FAR_FRUSTUM_PLANE].normal.x = 0;
frustum_planes[FAR_FRUSTUM_PLANE].normal.y = 0;
frustum_planes[FAR_FRUSTUM_PLANE].normal.z = -1;
}

polygon_t polygon_from_triangle(vec3_t v0, vec3_t v1, vec3_t v2, tex2_t t0, tex2_t t1, tex2_t t2)
{
polygon_t polygon = {
.vertices = { v0, v1, v2 },
.texcoords = { t0, t1, t2 },
.num_vertices = 3
};
return polygon;
}

// Static arrays are always passed by reference in C
void triangles_from_polygon(polygon_t* polygon, triangle_t triangles[], int* num_triangles)
{
for (int i = 0; i < polygon->num_vertices - 2; i++)
{
int index0 = 0;
int index1 = i + 1;
int index2 = i + 2;

triangles[i].points[0] = vec4_from_vec3(polygon->vertices[index0]);
triangles[i].points[1] = vec4_from_vec3(polygon->vertices[index1]);
triangles[i].points[2] = vec4_from_vec3(polygon->vertices[index2]);

triangles[i].texcoords[0] = polygon->texcoords[index0];
triangles[i].texcoords[1] = polygon->texcoords[index1];
triangles[i].texcoords[2] = polygon->texcoords[index2];
}
*num_triangles = polygon->num_vertices - 2;
}

// A standard function to calculate linear interpolation between A and B with factor t.
float float_lerp(float a, float b, float t)
{
return a + t * (b - a);
}

///////////////////////////////////////////////////////////////////////////////
// P2
// \ / \ /
// \/ \ /
// I1 * \ /
// / \ * I2
// P1<----*--*-> P3
// I4\/I3
///////////////////////////////////////////////////////////////////////////////
void clip_polygon_against_plane(polygon_t* polygon, int plane)
{
vec3_t plane_point = frustum_planes[plane].point;
vec3_t plane_normal = frustum_planes[plane].normal;

// Declare a static array of inside vertices that will be part of the final polygon returned via parameter
vec3_t inside_vertices[MAX_NUM_POLY_VERTICES];
tex2_t inside_texcoords[MAX_NUM_POLY_VERTICES];
int num_inside_vertices = 0;

// Start the current vertex with the first polygon vertex, and the previous with the last polygon vertex
vec3_t* current_vertex = &polygon->vertices[0];
tex2_t* current_texcoord = &polygon->texcoords[0];

// Start the previous vertex with the last polygon vertex and texture coordinates
vec3_t* previous_vertex = &polygon->vertices[polygon->num_vertices - 1];
tex2_t* previous_texcoord = &polygon->texcoords[polygon->num_vertices - 1];

// Calculate the dot product of the current and previous vertex
// to know if Current and Previous points inside or outside the plane
float current_dot = 0; //dot Q2
float previous_dot = vec3_dot(vec3_sub(*previous_vertex, plane_point), plane_normal); //dot Q1

// Loop all the polygon vertices while the current is different than the last one
while (current_vertex != &polygon->vertices[polygon->num_vertices])
{
current_dot = vec3_dot(vec3_sub(*current_vertex, plane_point), plane_normal);

// If we changed SIGN (from inside to outside or from outside to inside) then
// we need to find intersection point with the plane.
if (current_dot * previous_dot < 0)
{
// Find the interpolation factor t
float t = previous_dot / (previous_dot - current_dot);

// Calculate the intersection point I = Q1 + t(Q2-Q1)
//vec3_t intersection_point = vec3_clone(current_vertex); // I = Qc
//intersection_point = vec3_sub(intersection_point, *previous_vertex); // I = (Qc-Qp)
//intersection_point = vec3_mul(intersection_point, t); // I = t(Qc-Qp)
//intersection_point = vec3_add(intersection_point, *previous_vertex); // I = Qp + t(Qc-Qp)

// Calculate the intersection point I = Q1 + t(Q2-Q1)
vec3_t intersection_point = {
.x = float_lerp(previous_vertex->x, current_vertex->x, t),
.y = float_lerp(previous_vertex->y, current_vertex->y, t),
.z = float_lerp(previous_vertex->z, current_vertex->z, t)
};

// Use the lerp formula to get the interpolated U and V texture coordinates
tex2_t interpolated_texcoord = {
.u = float_lerp(previous_texcoord->u, current_texcoord->u, t),
.v = float_lerp(previous_texcoord->v, current_texcoord->v, t)
};

// Insert the intersection point to the list of "inside vertices"
inside_vertices[num_inside_vertices] = vec3_clone(&intersection_point);
inside_texcoords[num_inside_vertices] = tex2_clone(&interpolated_texcoord);
num_inside_vertices++;
}

// Current vertex is inside the plane
if (current_dot > 0)
{
// Insert the current vertex to the list of "inside vertices"
inside_vertices[num_inside_vertices] = vec3_clone(current_vertex);
inside_texcoords[num_inside_vertices] = tex2_clone(current_texcoord);
num_inside_vertices++;
}

// Move to the next vertex
previous_dot = current_dot;
previous_vertex = current_vertex;
previous_texcoord = current_texcoord;
current_vertex++;
current_texcoord++;
}

// At the end, copy the list of inside vertices into the destination polygon (out parameter)
for (int i = 0; i < num_inside_vertices; i++)
{
polygon->vertices[i] = vec3_clone(&inside_vertices[i]);
polygon->texcoords[i] = tex2_clone(&inside_texcoords[i]);
}
polygon->num_vertices = num_inside_vertices;
}

void clip_polygon(polygon_t* polygon)
{
clip_polygon_against_plane(polygon, LEFT_FRUSTUM_PLANE);
clip_polygon_against_plane(polygon, RIGHT_FRUSTUM_PLANE);
clip_polygon_against_plane(polygon, TOP_FRUSTUM_PLANE);
clip_polygon_against_plane(polygon, BOTTOM_FRUSTUM_PLANE);
clip_polygon_against_plane(polygon, NEAR_FRUSTUM_PLANE);
clip_polygon_against_plane(polygon, FAR_FRUSTUM_PLANE);
}
36 changes: 36 additions & 0 deletions Clipping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef CLIPPING_H
#define CLIPPING_H

#include "Triangle.h"
#include "Vector.h"

#define MAX_NUM_POLY_VERTICES 10
#define MAX_NUM_POLY_TRIANGLES 10

enum {
LEFT_FRUSTUM_PLANE,
RIGHT_FRUSTUM_PLANE,
TOP_FRUSTUM_PLANE,
BOTTOM_FRUSTUM_PLANE,
NEAR_FRUSTUM_PLANE,
FAR_FRUSTUM_PLANE
};

typedef struct {
vec3_t point;
vec3_t normal;
} plane_t;

void init_frustum_planes(float fov_x, float fov_y, float z_near, float z_far);

typedef struct {
vec3_t vertices[MAX_NUM_POLY_VERTICES];
tex2_t texcoords[MAX_NUM_POLY_VERTICES];
int num_vertices;
} polygon_t;

polygon_t polygon_from_triangle(vec3_t v0, vec3_t v1, vec3_t v2, tex2_t t0, tex2_t t1, tex2_t t2);
void triangles_from_polygon(polygon_t* polygon, triangle_t triangles[], int* num_triangles);
void clip_polygon(polygon_t* polygon);

#endif
16 changes: 16 additions & 0 deletions Dependencies/SDL2/SDL2-2.0.18/BUGS.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Bugs are now managed in the SDL issue tracker, here:

https://github.com/libsdl-org/SDL/issues

You may report bugs there, and search to see if a given issue has already
been reported, discussed, and maybe even fixed.


You may also find help at the SDL forums/mailing list:

https://discourse.libsdl.org/

Bug reports are welcome here, but we really appreciate if you use the issue
tracker, as bugs discussed on the mailing list may be forgotten or missed.

Loading

0 comments on commit bc7e34b

Please sign in to comment.