Camera: add lock functionality

Added functionality to lock camera to an object.
Also solved the problem where the colors weren't
loading on the fragments of the initial displays
This commit is contained in:
0xdeadbeer 2023-11-10 19:42:17 +01:00
parent 0cb0461658
commit 68f6e2eeb8
4 changed files with 159 additions and 130 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ cmake-build-debug/
build/ build/
.ccls-cache/ .ccls-cache/
*.mtl *.mtl
compile_commands.json

View File

@ -12,11 +12,11 @@ Pet project simulator for interactions between matter built off of OpenGL and C.
Goals and features: Goals and features:
- [x] Law of gravitation - [x] Law of gravitation
- [x] Object tracing - [x] Object tracing
- [ ] Toggle object tracing - [x] Toggle object tracing
- [ ] Grid - [x] Grid
- [ ] Toggle Grid - [x] Toggle Grid
- [ ] Scaling up/down objects - [x] Scaling up/down objects
- [ ] Locking camera view to an object - [x] Locking camera view to an object
- [ ] File format for importing scenes - [ ] File format for importing scenes
- [ ] Collision - [ ] Collision
- [ ] Soft-bodies and structures - [ ] Soft-bodies and structures

272
gravity.c
View File

@ -1,6 +1,7 @@
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <GL/glew.h> #include <GL/glew.h>
@ -10,7 +11,7 @@
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#define MAX_PATHS 100 #define MAX_PATHS 1500
float frand48(void) { float frand48(void) {
float number = (float) rand() / (float) (RAND_MAX + 1.0); float number = (float) rand() / (float) (RAND_MAX + 1.0);
@ -22,27 +23,6 @@ float frand48(void) {
return number; return number;
} }
float fov = 80.0f; // default fov
float fov_change = 1.0f;
vec3 camera_pos = { 0.0f, 0.0f, 100.0f, };
vec3 camera_front = { 0.0f, 0.0f, -1.0f };
vec3 camera_up = { 0.0f, 1.0f, 0.0f };
float camera_yaw; // x rotation
float camera_pitch; // y rotation
float camera_sensitivity = 0.01f;
float movement_speed = 2.0f;
GLint screen_viewport[4]; // viewport: x,y,width,height
int toggle_tracing = 0; // true or false
unsigned int shader_program;
unsigned int vertex_shader;
unsigned int fragment_shader;
// shaders
const char *object_vertex_shader_location = "assets/shaders/shader.vert";
const char *object_fragment_shader_location = "assets/shaders/shader.frag";
// structs // structs
struct object { struct object {
vec4 translation_force; vec4 translation_force;
@ -74,6 +54,31 @@ struct object {
unsigned int pbo; // buffer for paths unsigned int pbo; // buffer for paths
}; };
float fov = 80.0f; // default fov
float fov_change = 1.0f;
vec3 camera_pos = { 0.0f, 0.0f, 100.0f };
vec3 camera_front = { 0.0f, 0.0f, -1.0f };
vec3 camera_up = { 0.0f, 1.0f, 0.0f };
struct object *camera_lock = NULL; // is camera locked to any object?
float camera_yaw; // x rotation
float camera_pitch; // y rotation
float camera_sensitivity = 0.01f;
float movement_speed = 2.0f;
float time_speed = 33.0f;
float time_speed_change = 1.0f;
GLint screen_viewport[4]; // viewport: x,y,width,height
int toggle_tracing = 0; // true or false
unsigned int shader_program;
unsigned int vertex_shader;
unsigned int fragment_shader;
// shaders
const char *object_vertex_shader_location = "assets/shaders/shader.vert";
const char *object_fragment_shader_location = "assets/shaders/shader.frag";
// global objects information // global objects information
struct object* objects = NULL; struct object* objects = NULL;
@ -137,7 +142,6 @@ int load_model_to_object(const char *path, struct object *obj) {
for (int mesh_index = 0; mesh_index < scene->mNumMeshes; mesh_index++) { for (int mesh_index = 0; mesh_index < scene->mNumMeshes; mesh_index++) {
struct aiMesh *mesh = scene->mMeshes[mesh_index]; struct aiMesh *mesh = scene->mMeshes[mesh_index];
fprintf(stdout, "Number of vertices in mesh %d: %d\n", mesh_index, mesh->mNumVertices);
// fetch vertices // fetch vertices
for (int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) { for (int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) {
@ -279,6 +283,8 @@ int record_path(struct object *obj) {
return 0; return 0;
} }
void display() { void display() {
mat4 view; mat4 view;
mat4 projection; mat4 projection;
@ -305,6 +311,7 @@ void display() {
view_uniform = glGetUniformLocation(shader_program, "view"); view_uniform = glGetUniformLocation(shader_program, "view");
projection_uniform = glGetUniformLocation(shader_program, "projection"); projection_uniform = glGetUniformLocation(shader_program, "projection");
translation_uniform = glGetUniformLocation(shader_program, "translation"); translation_uniform = glGetUniformLocation(shader_program, "translation");
color_uniform = glGetUniformLocation(shader_program, "color");
scale_uniform = glGetUniformLocation(shader_program, "scale"); scale_uniform = glGetUniformLocation(shader_program, "scale");
glUniformMatrix4fv(view_uniform, 1, GL_FALSE, (float *) view); glUniformMatrix4fv(view_uniform, 1, GL_FALSE, (float *) view);
@ -339,6 +346,11 @@ void display() {
glm_vec4_add(obj->position, obj->translation_force, obj->position); glm_vec4_add(obj->position, obj->translation_force, obj->position);
// follow object if camera locked
if (camera_lock == obj) {
glm_vec3_add(camera_pos, obj->translation_force, camera_pos);
}
// record path // record path
if (toggle_tracing == 1) { if (toggle_tracing == 1) {
if (record_path(obj) == -1) { if (record_path(obj) == -1) {
@ -349,6 +361,7 @@ void display() {
glm_translate(translation_matrix, obj->position); glm_translate(translation_matrix, obj->position);
glUniformMatrix4fv(translation_uniform, 1, GL_FALSE, (float *) translation_matrix); glUniformMatrix4fv(translation_uniform, 1, GL_FALSE, (float *) translation_matrix);
glUniform3fv(color_uniform, 1, (float *) obj->color); glUniform3fv(color_uniform, 1, (float *) obj->color);
glUniform1f(scale_uniform, obj->scale); glUniform1f(scale_uniform, obj->scale);
@ -365,6 +378,7 @@ void display() {
glm_mat4_identity(translation_matrix); glm_mat4_identity(translation_matrix);
glUniformMatrix4fv(translation_uniform, 1, GL_FALSE, (float *) translation_matrix); glUniformMatrix4fv(translation_uniform, 1, GL_FALSE, (float *) translation_matrix);
glUniform1f(scale_uniform, 1.0f);
glDrawArrays(GL_LINE_STRIP, 0, obj->paths_num); glDrawArrays(GL_LINE_STRIP, 0, obj->paths_num);
} }
@ -373,6 +387,93 @@ void display() {
glutPostRedisplay(); glutPostRedisplay();
} }
void setup() {
// setup default mouse position
glGetIntegerv(GL_VIEWPORT, screen_viewport);
glutWarpPointer(screen_viewport[2]/2, screen_viewport[3]/2);
for (struct object *obj = objects; obj != NULL; obj = obj->next) {
glGenVertexArrays(1, &obj->vao);
glGenVertexArrays(1, &obj->pvao);
glGenBuffers(1, &obj->vbo);
glGenBuffers(1, &obj->ebo);
glGenBuffers(1, &obj->nbo);
glGenBuffers(1, &obj->pbo);
glBindVertexArray(obj->vao);
glBindBuffer(GL_ARRAY_BUFFER,obj->vbo);
glBufferData(GL_ARRAY_BUFFER,obj->vertices_num*3*sizeof(float),obj->vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, obj->nbo);
glBufferData(GL_ARRAY_BUFFER, obj->normals_num*3*sizeof(float), obj->normals, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *) 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,obj->ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,obj->indices_num*sizeof(unsigned int),obj->indices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
glEnable(GL_DEPTH_TEST);
}
struct object *create_object(float mass, const char *model) {
struct object *new_object = (struct object *) malloc(sizeof(struct object));
if (new_object == NULL) {
return NULL;
}
new_object->mass = mass;
glm_vec4_one(new_object->position);
glm_vec4_one(new_object->rotation);
glm_vec4_zero(new_object->translation_force);
glm_vec4_zero(new_object->rotation_force);
new_object->vertices_num = 0;
new_object->indices_num = 0;
new_object->normals_num = 0;
new_object->scale = 1.0f;
new_object->vertices = NULL;
new_object->indices = NULL;
new_object->normals = NULL;
new_object->next = NULL;
new_object->paths = NULL;
new_object->paths_num = 0;
new_object->paths_max = MAX_PATHS;
glm_vec3_one(new_object->color);
// choose random color
for (int i = 0; i < 3; i++) {
new_object->color[i] = 0.5f + (fabs(frand48()) / 2);
}
if (load_model_to_object(model, new_object) == -1) {
return NULL;
}
if (objects == NULL) {
objects = new_object;
return new_object;
}
struct object *obj = objects;
while (obj->next != NULL) {
obj = obj->next;
}
obj->next = new_object;
return new_object;
}
void keyboard(unsigned char key, int x, int y) { void keyboard(unsigned char key, int x, int y) {
switch (key) { switch (key) {
case '\x1B': case '\x1B':
@ -438,6 +539,19 @@ void keyboard(unsigned char key, int x, int y) {
obj->paths = NULL; obj->paths = NULL;
} }
break; break;
case 'c':
case 'C': {
struct object *a = create_object(1000000.0f, "assets/models/sphere.obj");
float n = 0.05f;
vec4 a_pos = {frand48() * 100, frand48() * 100, -150.0f, 0.0f};
glm_vec4_add(a->position, a_pos, a->position);
//vec3 a_boost = {-10 * n, 0.0f, 0.0f};
//glm_vec3_add(a->translation_force, a_boost, a->translation_force);
setup();
break;
}
default: default:
break; break;
} }
@ -464,7 +578,7 @@ void mouse(int button, int state, int x, int y) {
} }
} }
int warped_pointer = 0; int warped_pointer = 1;
void mouse_motion(int x, int y) { void mouse_motion(int x, int y) {
if (warped_pointer == 1) { if (warped_pointer == 1) {
warped_pointer = 0; warped_pointer = 0;
@ -494,94 +608,6 @@ void mouse_motion(int x, int y) {
glm_normalize_to(view_direction, camera_front); glm_normalize_to(view_direction, camera_front);
} }
void setup() {
// setup default mouse position
glGetIntegerv(GL_VIEWPORT, screen_viewport);
glutWarpPointer(screen_viewport[2]/2, screen_viewport[3]/2);
for (struct object *obj = objects; obj != NULL; obj = obj->next) {
glGenVertexArrays(1, &obj->vao);
glGenVertexArrays(1, &obj->pvao);
glGenBuffers(1, &obj->vbo);
glGenBuffers(1, &obj->ebo);
glGenBuffers(1, &obj->nbo);
glGenBuffers(1, &obj->pbo);
glBindVertexArray(obj->vao);
glBindBuffer(GL_ARRAY_BUFFER,obj->vbo);
glBufferData(GL_ARRAY_BUFFER,obj->vertices_num*3*sizeof(float),obj->vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, obj->nbo);
glBufferData(GL_ARRAY_BUFFER, obj->normals_num*3*sizeof(float), obj->normals, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *) 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,obj->ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,obj->indices_num*sizeof(unsigned int),obj->indices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
glEnable(GL_DEPTH_TEST);
}
struct object *create_object(float mass, const char *model) {
struct object *new_object = (struct object *) malloc(sizeof(struct object));
if (new_object == NULL) {
return NULL;
}
new_object->mass = mass;
glm_vec4_one(new_object->position);
glm_vec4_one(new_object->rotation);
glm_vec4_zero(new_object->translation_force);
glm_vec4_zero(new_object->rotation_force);
new_object->vertices_num = 0;
new_object->indices_num = 0;
new_object->normals_num = 0;
new_object->scale = 1.0f;
new_object->vertices = NULL;
new_object->indices = NULL;
new_object->normals = NULL;
new_object->next = NULL;
new_object->paths = NULL;
new_object->paths_num = 0;
new_object->paths_max = MAX_PATHS;
glm_vec3_one(new_object->color);
// choose random color
for (int i = 0; i < 3; i++) {
new_object->color[i] = 0.5f + (fabs(frand48()) / 2);
}
if (load_model_to_object(model, new_object) == -1) {
return NULL;
}
if (objects == NULL) {
objects = new_object;
return new_object;
}
struct object *obj = objects;
while (obj->next != NULL) {
obj = obj->next;
}
obj->next = new_object;
return new_object;
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
srandom(time(NULL)); srandom(time(NULL));
@ -609,27 +635,29 @@ int main(int argc, char **argv) {
// objects // objects
struct object *a = create_object(1.0f, "assets/models/sphere.obj"); struct object *a = create_object(1.0f, "assets/models/sphere.obj");
struct object *b = create_object(1.0f, "assets/models/sphere.obj"); struct object *b = create_object(1000000000.0f, "assets/models/sphere.obj");
//struct object *c = create_object(1.0f, "assets/models/sphere.obj"); struct object *c = create_object(1.0f, "assets/models/sphere.obj");
float distance = -200.0f; float distance = -200.0f;
// vec4 a_pos = {0.0f, 50.0f, distance, 0.0f}; vec4 a_pos = {0.0f, 50.0f, distance, 0.0f};
// glm_vec4_add(a->position, a_pos, a->position);
vec4 a_pos = {0.0f, -40.0f, -150.0f, 0.0f};
glm_vec4_add(a->position, a_pos, a->position); glm_vec4_add(a->position, a_pos, a->position);
//vec4 a_pos = {0.0f, -0.0f, -150.0f, 0.0f};
//glm_vec4_add(a->position, a_pos, a->position);
vec4 b_pos = {0.0f, -50.0f, -150.0f, 0.0f}; vec4 b_pos = {0.0f, -75.0f, -150.0f, 0.0f};
glm_vec4_add(b->position, b_pos, b->position); glm_vec4_add(b->position, b_pos, b->position);
//vec4 c_pos = {0.0f, -20.0f, distance, 0.0f}; vec4 c_pos = {0.0f, -20.0f, distance, 0.0f};
//glm_vec4_add(c->position, c_pos, c->position); glm_vec4_add(c->position, c_pos, c->position);
float n = 0.05f; float n = 0.05f;
// vec3 a_boost = {-10*n, 0.0f, 0.0f}; vec3 b_boost = {10*n, 0.0f, 0.0f};
// glm_vec3_add(a->translation_force, a_boost, a->translation_force);
glm_vec3_add(b->translation_force, b_boost , b->translation_force);
b->scale = 2.0f; b->scale = 2.0f;
camera_lock = b;
setup(); setup();