diff --git a/sim/CMakeLists.txt b/sim/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2ebd04ca3698fb274934fa51755544e8f6dbe9b2 --- /dev/null +++ b/sim/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.10) + +project(main LANGUAGES C) + + +link_libraries( -lGL -lglfw -lm -ggdb -lgraphene-1.0 -g -lpthread -O2) + +add_executable(main ${PROJECT_SOURCE_DIR}/src/main.c ${PROJECT_SOURCE_DIR}/src/glad.c) +include_directories( PRIVATE include) +include_directories(PRIVATE /usr/lib64/graphene-1.0/include) #beware: not system agnostic diff --git a/sim/include/importData.h b/sim/include/importData.h new file mode 100644 index 0000000000000000000000000000000000000000..b9d0806be8a6647aa36fb404fa933f20e6f292a3 --- /dev/null +++ b/sim/include/importData.h @@ -0,0 +1,85 @@ +#ifndef SIMDATA +#define SIMDATA +typedef struct { + float x; + float y; + float z; +} Vector; + +typedef struct { + long noOfBodies; + long noOfRecords; + float *allocator; + float *traceAllocator; + char *filename; + long size; + bool run; + int speed; + bool trace; + unsigned int *indices; + unsigned int *count; + unsigned int noOfTracepoints; +} SimData; + +void importData(SimData *sim) { + + char *charptr1, *charptr2; + FILE *output = fopen(sim -> filename, "r"); + + //get the file size to make sure we have enough space to read it! + struct stat filestats; + stat(sim->filename, &filestats); + long size = filestats.st_size; //since we read line by line this is large enough! + //buffer is freed at the end of this scope + char* buffer = (char*)malloc(size); + + //random line ignore + getline(&buffer, &size, output); + printf("Vertex File opened: %s\n", buffer); + + //this line has information about the number of Record Positions + getline(&buffer, &size, output); + charptr1 = &buffer[0]; + sim->noOfRecords = strtol(charptr1, &charptr2, 0); + printf("number of Recorded Points: :%ld\n", sim -> noOfRecords); + + //this line tells us how many bodies are part of the system + getline(&buffer, &size, output); + charptr1 = &buffer[0]; + sim -> noOfBodies = strtol(charptr1, &charptr2, 0); + printf("number of Bodies:::%ld\n", sim -> noOfBodies); + + //now we can use the noOfBodies and the NoOfRecords to allocate enough memory to + //hold all the positions in memory + //pointer is owned by caller and will be freed when the program terminates + sim -> size = sim -> noOfRecords * sim -> noOfBodies*3; + sim -> allocator = malloc(size*sizeof(float)); + if (!sim->allocator) { + exit(1); + } + sim -> traceAllocator = malloc(size*sizeof(float)); + if (!sim->traceAllocator) { + exit(1); + } + charptr1 = &buffer[0]; + + for (long record = 0; record < sim->noOfRecords; record++) { + long offset = record * 3*sim -> noOfBodies; + long offset_trace = sim->noOfRecords; + + getline(&buffer, &size, output); + charptr1 = &buffer[0]; + for (long body = 0; body <sim -> noOfBodies*3; body+=3) { + sim->allocator[offset + body] = strtof(charptr1, &charptr2); + sim->allocator[offset + body+1] = strtof(charptr2, &charptr2); + sim->allocator[offset + body+2] = strtof(charptr2, &charptr2); + sim->traceAllocator[body*offset_trace +record*3] = sim->allocator[offset + body]; + sim->traceAllocator[body*offset_trace +1+record*3] = sim->allocator[offset + body+1]; + sim->traceAllocator[body*offset_trace +2+record*3] = sim->allocator[offset + body+2]; + charptr1 = charptr2; + } + + } + free(buffer); +} +#endif diff --git a/sim/include/main.h b/sim/include/main.h new file mode 100644 index 0000000000000000000000000000000000000000..3e47dd471c22664ba076fe158fe6fc7efab692e2 --- /dev/null +++ b/sim/include/main.h @@ -0,0 +1,52 @@ +#ifndef MAIN +#define MAIN + +#include "importData.h" +#include "Camera.h" + +enum textureFormat {png, jpg}; +struct texture{ + char* name; + enum textureFormat format; + bool flip; +}; + +void processInput( + GLFWwindow *window, + int key, + int scancode, + int action, + int mods +); + +void updateCamera(); +void mouse_callback(GLFWwindow* window, double xpos, double ypos); +void framebuffer_size_callback(GLFWwindow* window, int width, int height); +void compileAndAttachShaders( unsigned int Program,char vertexSource[], char fragmentSource[]); + +void loadTexture(struct texture Tex) { + + int width, height, nrChannels; + stbi_set_flip_vertically_on_load(Tex.flip); + + unsigned char* data = stbi_load(Tex.name, &width, &height, &nrChannels, 0); + if (data) { + + switch (Tex.format) { + case jpg: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + break; + case png: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + break; + } + + glGenerateMipmap(GL_TEXTURE_2D); + } else { + printf("Failed to load texture"); + exit(EXIT_FAILURE); + } + stbi_image_free(data); + +} +#endif diff --git a/sim/include/openGLProgram.h b/sim/include/openGLProgram.h new file mode 100644 index 0000000000000000000000000000000000000000..58ec78e0c730a9a96013899fbfe1540b446414eb --- /dev/null +++ b/sim/include/openGLProgram.h @@ -0,0 +1,86 @@ +#include <glad/glad.h> + +#ifndef openGLProgram +#define openGLProgram +void compileAndAttachShaders( unsigned int Program, char vertexSource[], char fragmentSource[]) { + + unsigned int vertexShader, fragmentShader; + char vertexbuffer[2024], fragmentbuffer[2024], infoLog[512]; + int success; + long charsRead; + + FILE* SourceFile = fopen(vertexSource, "r"); + if (SourceFile) { + charsRead = fread(vertexbuffer,sizeof(char), sizeof(vertexbuffer)/sizeof(char), SourceFile); + vertexbuffer[charsRead] = '\0'; + + const char* vertexptr = &vertexbuffer[0]; + + fclose(SourceFile); + if ( charsRead > 0&& charsRead < sizeof(vertexbuffer)/sizeof(char)) { + vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vertexptr, NULL); + } else { + printf("Failed to open %s as vertex Source File\n", vertexSource); + exit(EXIT_FAILURE); + } + } else { + printf("Failed to open file: %s\n", vertexSource); + exit(EXIT_FAILURE); + } + glCompileShader(vertexShader); + + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); + printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"); + printf("%s\n", infoLog); + printf("\n\n%s", vertexbuffer); + return exit(EXIT_FAILURE); + } + + + SourceFile = fopen(fragmentSource, "r"); + if (SourceFile) { + charsRead = fread(fragmentbuffer,sizeof(char), sizeof(fragmentbuffer)/sizeof(char), SourceFile); + fragmentbuffer[charsRead] = '\0'; + const char* fragmentptr = &fragmentbuffer[0]; + fclose(SourceFile); + if (charsRead > 0 && charsRead < sizeof(fragmentbuffer)/sizeof(char)) { + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fragmentptr, NULL); + } else { + printf("Failed to open %s as vertex Source File\n", fragmentSource); + exit(EXIT_FAILURE); + } + } else { + printf("Failed to open file: %s\n", fragmentSource); + exit(EXIT_FAILURE); + } + glCompileShader(fragmentShader); + + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); + printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"); + printf("%s\n", infoLog); + printf("\n\n%s", fragmentbuffer); + return exit(EXIT_FAILURE); + } + + glAttachShader(Program, vertexShader); + glAttachShader(Program, fragmentShader); + glLinkProgram(Program); + + glGetProgramiv(Program, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(Program, 512, NULL, infoLog); + printf("ERROR::GL::Program::LINKING_FAILES\n"); + printf("%s\n", infoLog); + return exit(EXIT_FAILURE); + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); +} + +#endif diff --git a/sim/shaders/fragmentshader.fs b/sim/shaders/fragmentshader.fs new file mode 100644 index 0000000000000000000000000000000000000000..614339e1838644dca8bd63f50e757f60b0c9bca3 --- /dev/null +++ b/sim/shaders/fragmentshader.fs @@ -0,0 +1,39 @@ +#version 450 core + + +out vec4 FragColor; +uniform bool Trace; + +void point(in vec2 gl_PointCoord, out vec4 FragColor) { + vec2 center = gl_PointCoord-vec2(0.5,0.5); + float radius = dot(center, center); + if (radius > 0.25) + { + gl_FragDepth = 0.999; + discard; + } if ( radius <0.13) + { + FragColor = vec4(1.0,1.0,1.0,1.0); + } else + { + float brightness = -4 * (radius-0.13) +0.8; + FragColor = vec4(brightness, brightness, brightness, 0.5); + } + +} +void trace(in vec2 gl_PointCoord, out vec4 FragColor) { + + + FragColor = vec4(0.84,0.36,0.055,1.0); + +} + +void main() +{ + gl_FragDepth = gl_FragCoord.z; + if (Trace) { + trace(gl_PointCoord, FragColor); + } else { + point(gl_PointCoord, FragColor); + } +} diff --git a/sim/shaders/gui.fs b/sim/shaders/gui.fs new file mode 100644 index 0000000000000000000000000000000000000000..cfda982046d4bbffe944ae28648e85b43c6edd19 --- /dev/null +++ b/sim/shaders/gui.fs @@ -0,0 +1,11 @@ +#version 330 core + +out vec4 FragColor; +in vec4 vertexColor; +in float depth; + + +void main() +{ + FragColor = vertexColor; +} diff --git a/sim/shaders/gui.vs b/sim/shaders/gui.vs new file mode 100644 index 0000000000000000000000000000000000000000..48517ee31605b1548a260a278aca0d2001b453de --- /dev/null +++ b/sim/shaders/gui.vs @@ -0,0 +1,14 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +out vec4 vertexColor; + +uniform mat4 view; + +void main() +{ + gl_Position = vec4(aPos, 1.0); + gl_PointSize = 30; + vertexColor = vec4(0.45,0.85,0.88,1.0); + + +} diff --git a/sim/shaders/vertexshader.vs b/sim/shaders/vertexshader.vs new file mode 100644 index 0000000000000000000000000000000000000000..798d93c270ffd4b1ff9c9924fdabba88c9774602 --- /dev/null +++ b/sim/shaders/vertexshader.vs @@ -0,0 +1,22 @@ +#version 330 core +layout (location = 1) in vec3 aPos; +//layout (location = 16) in float +//out vec4 vertexColor; + + +uniform mat4 view; +uniform mat4 proj; +uniform float worldScale; +uniform float pointScale; +void main() +{ + mat4 scaling = mat4(worldScale); + scaling[3][3] = 1.0f; + vec4 World = proj*inverse(view)*scaling*vec4(aPos, 1.0); + gl_PointSize = 1/(World.z)*pointScale; + + gl_Position = World; + //vertexColor = vec4(1,1,1,0.5); + + +} diff --git a/sim/src/main.c b/sim/src/main.c new file mode 100644 index 0000000000000000000000000000000000000000..5e956dca06f384c09dea45108fae9fbb5e739fe0 --- /dev/null +++ b/sim/src/main.c @@ -0,0 +1,440 @@ +//open gl related libraries +#include <glad/glad.h> +#include <GLFW/glfw3.h> + +//libc imports +#include <stdio.h> +#include <stdbool.h> +#include <math.h> +#include <sys/stat.h> +#include <threads.h> + +//image library for importing pictures +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +//linear algebra library +#include <graphene-1.0/graphene.h> + +//project specific files +#include "main.h" +#include "importData.h" +#include "openGLProgram.h" + + +float pause_indicator[] = { + //first triangle + + 0.90f, 0.98f, -1.0, // top right + 0.94f, 0.8f, -1.0, // bottom right + 0.90f, 0.8f, -1.0, + + 0.90f, 0.98f, -1.0, // top right + 0.94f, 0.98f, -1.0, // bottom right + 0.94f, 0.8f, -1.0, + + 0.95f, 0.98f, -1.0, // top right + 0.99f, 0.8f, -1.0, // bottom right + 0.95f, 0.8f, -1.0, + + 0.95f, 0.98f, -1.0, // top right + 0.99f, 0.98f, -1.0, // bottom right + 0.99f, 0.8f, -1.0, + + +}; + +float play_indicator[] = { + 0.9f, 1.0f, -1.0, // top right + 1.0f, 0.9f, -1.0, // bottom right + 0.9f, 0.8f, -1.0, // bottom left +}; + +unsigned int indices[] = { + 0, 1, 3, //first triangle + 1, 2, 3 //second triangle +}; + +float deltaTime = 0.0f; // Time between current frame and last frame +float lastFrame = 0.0f; +float lastX = 0, lastY = 0; + +graphene_vec3_t direction; +Camera cam; +SimData sim; +GLFWwindow *window; + + +void GLAPIENTRY +MessageCallback( GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam ) { + fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", + ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), + type, severity, message ); +} + +typedef struct { + float distance; + unsigned int index; +} TransparentPoint; + +int main(int argc, char *argv[]) { + + glfwInit(); + + char *filename = argv[1]; + + sim.filename = filename; + sim.allocator = NULL; + sim.run = false; + sim.speed = 1; + sim.noOfTracepoints = 1000; + sim.trace = false; + importData(&sim); + TransparentPoint *root = malloc(sizeof(TransparentPoint) * (sim.noOfBodies)); + if (!root) { + exit(1); + } + + + + //init glfw and configure the enum that is the state of glfw + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_SAMPLES,1); + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); + glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); + + glfwWindowHint(GLFW_DEPTH_BITS, 24); + window = glfwCreateWindow(1000,1000,"Visualize", NULL, NULL); + if (window == NULL) { + printf("Failed to create GLFW window"); + glfwTerminate(); + return -1; + } + glfwSetKeyCallback(window, processInput); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + + glfwMakeContextCurrent(window); + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + printf("failed to initialize GLAD"); + return -1; + } + + glViewport(0, 0, 1000, 1000); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glEnable ( GL_DEBUG_OUTPUT ); + glDebugMessageCallback( MessageCallback, 0 ); + + //to change things related to GL_POINT Primitive + glEnable(GL_PROGRAM_POINT_SIZE); + + + glEnable(GL_LINE_SMOOTH); + glLineWidth(3.0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + unsigned int shaderProgram; + shaderProgram = glCreateProgram(); + + //Prepare the shaders + compileAndAttachShaders( shaderProgram, "./shaders/vertexshader.vs", "./shaders/fragmentshader.fs"); + glUseProgram(shaderProgram); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + unsigned int VBO, EBO, VAO; + glGenVertexArrays(1,&VAO); + glGenBuffers(1,&EBO); + glGenBuffers(1, &VBO); + + //after binding the VAO can be used + glBindVertexArray(VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sim.size*sizeof(float), sim.allocator, GL_DYNAMIC_DRAW); + + glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(1); + unsigned int VAO_trace, VBO_trace; + glGenVertexArrays(1,&VAO_trace); + glGenBuffers(1,&VBO_trace); + + //after binding the VAO can be used + glBindVertexArray(VAO_trace); + + glBindBuffer(GL_ARRAY_BUFFER, VBO_trace); + int offset = 1; + glBufferData(GL_ARRAY_BUFFER, sim.size*sizeof(float), sim.traceAllocator, GL_DYNAMIC_DRAW); + glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE,offset *3* sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + + + float arr[16]; + graphene_matrix_t models; + graphene_vec3_t vector; + graphene_matrix_t projection_mat; + graphene_matrix_t* projection = graphene_matrix_init_perspective(&projection_mat, 45,1,0.1,10000.0); + graphene_matrix_to_float(projection, arr); + + glUniformMatrix4fv(glGetUniformLocation( shaderProgram, "proj"), 1, GL_FALSE, arr); + + int t = 0; + graphene_point3d_t point; + + graphene_vec3_t* eye =graphene_vec3_init(&cam.position, 0.0, 0.0, 3); + + CameraInit(&cam, shaderProgram); + glfwSetCursorPos(window, 0, 0); + glUniform1f(glGetUniformLocation(cam.program, "pointScale"), cam.pointScale); + + unsigned int gui; + gui = glCreateProgram(); + + compileAndAttachShaders( gui, "./shaders/gui.vs", "./shaders/gui.fs"); + glUseProgram(gui); + unsigned int VBO_play, VAO_play, VBO_pause, VAO_pause; + glGenVertexArrays(1,&VAO_play); + glGenVertexArrays(1,&VAO_pause); + glGenBuffers(1,&VBO_play); + glGenBuffers(1,&VBO_pause); + + glBindVertexArray(VAO_play); + glBindBuffer(GL_ARRAY_BUFFER,VBO_play); + glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), play_indicator, GL_STATIC_DRAW); + glVertexAttribPointer(0,3,GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindVertexArray(VAO_pause); + glBindBuffer(GL_ARRAY_BUFFER,VBO_pause); + glBufferData(GL_ARRAY_BUFFER,36*sizeof(float), pause_indicator, GL_STATIC_DRAW); + glVertexAttribPointer(0,3,GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + graphene_vec4_t zvec; + graphene_vec4_t vertex; + int trace = sim.noOfTracepoints; + while (!glfwWindowShouldClose(window) && t < sim.noOfRecords) { + //empty screen + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT); + glClearColor(0.0f,0.0f,0.0f,0.0f); + + //render bodies + glUseProgram(shaderProgram); + glfwPollEvents(); + updateCamera(); + graphene_matrix_get_row(&cam.view, 2, &zvec); + + for (int k = 0; k < sim.noOfBodies; k++) { + graphene_vec4_t *tmp = graphene_vec4_init( + &vertex, + sim.traceAllocator[t+k*sim.noOfRecords*3], + sim.traceAllocator[t+k*sim.noOfRecords*3+1], + sim.traceAllocator[t+k*sim.noOfRecords*3+2], + 1.0f); + + root[k].distance = graphene_vec4_dot(&vertex, &zvec); + root[k].index = k; + } + glBindVertexArray(VAO_trace); + glUniform1f(glGetUniformLocation(cam.program, "Trace"), 0); + for (int body = 0; body < sim.noOfBodies; body++) { + glDrawArrays(GL_POINTS, t+body*sim.noOfRecords,1); + } + int trace = sim.noOfTracepoints; + if (sim.trace == true) { + glBindVertexArray(VAO_trace); + glUniform1f(glGetUniformLocation(cam.program, "Trace"), 1); + + for (int j = 0; j <sim.noOfBodies; j++) { + glDrawArrays( + GL_LINE_STRIP, + sim.noOfRecords*j/1+ fmax(0, t-trace), + fmin(t/1, trace) + ); + } + } + + //render gui + glUseProgram(gui); + glBindVertexArray(VAO_play); + if (sim.run) { + t+= sim.speed; + glBindVertexArray(VAO_play); + + } else { + glBindVertexArray(VAO_pause); + sim.run = 0; + } + if (t == 0 && sim.speed < 0) { + sim.run = 0; + sim.speed = 1; + } + glDrawArrays(GL_TRIANGLES, 0,3+9*(1-sim.run)); + + //swap + glfwSwapBuffers(window); + } + glfwTerminate(); + free(root); + return 0; +} + +void processInput( + GLFWwindow *window, + int key, + int scancode, + int action, + int mods + ) { + + if (key ==GLFW_KEY_SPACE && action == GLFW_PRESS) { + sim.run = -1*(sim.run -1); + } + + else if (key == GLFW_KEY_COMMA && action == GLFW_PRESS) { + sim.speed -= 1; + } + else if (key == GLFW_KEY_PERIOD && action == GLFW_PRESS) { + sim.speed += 1; + } + else if (key == GLFW_KEY_C && action == GLFW_PRESS) { + sim.trace = (sim.trace-1)*-1; + } + else if (key == GLFW_KEY_M && action == GLFW_PRESS) { + sim.noOfTracepoints =(int)sim.noOfTracepoints* 2; + } + else if (key == GLFW_KEY_N && action == GLFW_PRESS) { + sim.noOfTracepoints = (int)sim.noOfTracepoints/2; + } + + +} + +void updateCamera () { + //acquire the lock to write to the fields of the Camera + float arr[16]; + double xpos, ypos; + graphene_vec3_t tmp; + + float currentFrame = glfwGetTime(); + deltaTime = currentFrame - lastFrame; + printf("Frametime : %lf\n", deltaTime); + lastFrame = currentFrame; + + float speed = cam.speed*2; + glfwGetCursorPos(window, &xpos, &ypos); + glfwSetCursorPos(window, 0,0 ); + + cam.phi += cam.sensitivity *(float)(-xpos); + cam.theta += cam.sensitivity * (float)(ypos ); + graphene_vec3_t *left = graphene_vec3_init( + &cam.left, + cos(cam.phi), + 0, + -sin(cam.phi) + ); + + graphene_vec3_cross(&cam.left, &cam.direction, &cam.up); + graphene_vec3_negate(&cam.up, &cam.up); + + + + graphene_vec3_t *direction = graphene_vec3_init( + &cam.direction, + sin(cam.phi) * cos(cam.theta), + sin(cam.theta), + cos(cam.phi) * cos(cam.theta) + + ); + + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); + + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { + graphene_vec3_scale( &cam.direction,(speed *1.2)* deltaTime, &tmp); + graphene_vec3_add(&cam.position, &tmp, &cam.position); + + + } + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { + graphene_vec3_scale( &cam.direction, (speed *1.2)* deltaTime, &tmp); + graphene_vec3_subtract(&cam.position, &tmp, &cam.position); + + } + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { + graphene_vec3_scale( &cam.left, speed * deltaTime, &tmp); + graphene_vec3_add(&cam.position, &tmp, &cam.position); + } + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { + graphene_vec3_scale(&cam.left, speed * deltaTime, &tmp); + graphene_vec3_subtract(&cam.position, &tmp, &cam.position); + } + if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) { + graphene_vec3_scale( &cam.up, speed * deltaTime, &tmp); + graphene_vec3_add(&cam.position, &tmp, &cam.position); + } + if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { + graphene_vec3_scale( &cam.up, speed * deltaTime, &tmp); + graphene_vec3_subtract(&cam.position, &tmp, &cam.position); + } + if (glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS) { + cam.pointScale *= 1.05; + glUniform1f(glGetUniformLocation(cam.program, "pointScale"), cam.pointScale); + } + if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) { + cam.pointScale /= 1.05; + glUniform1f(glGetUniformLocation(cam.program, "pointScale"), cam.pointScale); + } + if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) { + cam.speed *=1.1f; + } + if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) { + cam.speed *=0.9f; + } + if (glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) { + cam.worldScale *= 1.1f; + } + if (glfwGetKey(window, GLFW_KEY_K) == GLFW_PRESS) { + cam.worldScale /= 1.1f; + } + graphene_matrix_t worldScale; + graphene_matrix_t *worldScale_pointer = graphene_matrix_init_scale( + &worldScale, + cam.worldScale, + cam.worldScale, + cam.worldScale + ); + graphene_matrix_to_float(&worldScale, arr); + glUniform1f(glGetUniformLocation(cam.program, "worldScale"), cam.worldScale); + + + + graphene_vec3_subtract(&cam.position, &cam.direction, &tmp); + + graphene_matrix_t* view = graphene_matrix_init_look_at( + &cam.view, + &cam.position, + &tmp, + &cam.up + ); + + + graphene_matrix_to_float(&cam.view, arr); + glUniformMatrix4fv(glGetUniformLocation( cam.program, "view"), 1, GL_FALSE, arr); +} + +void framebuffer_size_callback(GLFWwindow* window, int width, int height) { + + glViewport(0,0,1800,1800); +} diff --git a/src/.gitkeep b/src/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/jupiter.c b/src/jupiter.c deleted file mode 100644 index 7cbe00aa5c19e9012139a9f4c1806224eac3d08e..0000000000000000000000000000000000000000 --- a/src/jupiter.c +++ /dev/null @@ -1,166 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#define pi 3.141592653589793 -#define solar_mass 1 -#define G (4 * pi * pi) -#define days_per_year 365.24 -#define JD 5.2 -#define VJ0 2.75535903023 - - -typedef struct { - double x[3]; - double v[3]; - double a[3]; - double mass; -} Planet; - -//Unit scaling: Mass in solar mass, distance in AU, velocity in AU/year, and constant G in AU^3/solar mass*year^2 - -Planet Planets[] = { - { - {0,0,0}, - {0,0,0}, - {0,0,0}, - solar_mass - }, - { - {JD, 0, 0}, - {0, VJ0, 0}, - {0,0,0}, - 9.54791938424326609e-04 * solar_mass - }, - { - {-JD, 0, 0}, - {0, -VJ0, 0}, - {0, 0, 0}, - 2.85885980666130812e-04 * solar_mass - } -}; -static inline double distance( const double x1[3], const double x2[3]) { - const double x = x1[0] - x2[0]; - const double y = x1[1] - x2[1]; - const double z = x1[2] - x2[2]; - - return sqrt(x*x + y*y + z*z + 0.001); - -} - -void update(int steps){ - long run = 0; - const int noOfBodies = sizeof(Planets)/sizeof(Planet); - const double dt = 0.01; - - while (run < steps) { - for (int l = 0; l < noOfBodies; l++) { - Planets[l].v[0] += 0.5 * Planets[l].a[0]* dt; - Planets[l].v[1] += 0.5 * Planets[l].a[1]* dt; - Planets[l].v[2] += 0.5 * Planets[l].a[2]* dt; - } - for (int k = 0; k < noOfBodies; k++) { - Planets[k].x[0] += dt * Planets[k].v[0]; - Planets[k].x[1] += dt * Planets[k].v[1]; - Planets[k].x[2] += dt * Planets[k].v[2]; - Planets[k].a[0] = 0; - Planets[k].a[1] = 0; - Planets[k].a[2] = 0; - } - - for (int i = 0; i < noOfBodies; i++) { - for (int j = i+1; j < noOfBodies; j++) { - double dist = distance(Planets[i].x, Planets[j].x); - double a = G/pow(dist, 3); - - Planets[i].a[0] += a * Planets[j].mass * ( Planets[j].x[0] - Planets[i].x[0] ); - Planets[i].a[1] += a * Planets[j].mass * ( Planets[j].x[1] - Planets[i].x[1] ); - Planets[i].a[2] += a * Planets[j].mass * ( Planets[j].x[2] - Planets[i].x[2] ); - Planets[j].a[0] += a * Planets[i].mass * ( Planets[i].x[0] - Planets[j].x[0] ); - Planets[j].a[1] += a * Planets[i].mass * ( Planets[i].x[1] - Planets[j].x[1] ); - Planets[j].a[2] += a * Planets[i].mass * ( Planets[i].x[2] - Planets[j].x[2] ); - } - } - - for (int m = 0; m < noOfBodies; m++) { - Planets[m].v[0] += 0.5 * Planets[m].a[0]* dt; - Planets[m].v[1] += 0.5 * Planets[m].a[1]* dt; - Planets[m].v[2] += 0.5 * Planets[m].a[2]* dt; - } - - run++;} -} - -int main() { - FILE *starting = fopen("starting.txt", "w+"); - if (starting == NULL) { - printf("HELP\n COULDNT OPEN FILE\nSIGSEVV"); - } else { - printf("Output File opened\n"); - } - const int noOfBodies = sizeof(Planets)/sizeof(Planet); - double s =0; - double ds=0.001; - - for(s=1.5; s<=3; s+=ds){ - - Planets[2].x[0]=-s*JD; - Planets[2].x[1]=0; - Planets[2].x[2]=0; - Planets[2].v[0]=0; - Planets[2].v[1]=-sqrt(1/s)*VJ0; - Planets[2].v[2]=0; - for(int i=0; i<3;i++){ - for(int k=0; k<3; k++){ - Planets[k].a[i]=0; - } - } - for(int i=0; i<3; i++){ - Planets[0].x[i]=0; - Planets[0].v[i]=0; - } - Planets[1].x[0]=JD; - Planets[1].x[1]=0; - Planets[1].x[2]=0; - Planets[1].v[0]=0; - Planets[1].v[1]=VJ0; - Planets[1].v[2]=0; - update(10000); - double r10= sqrt(Planets[2].x[1]*Planets[2].x[1]+Planets[2].x[0]*Planets[2].x[0]); - update(10000); - double r1= sqrt(Planets[2].x[1]*Planets[2].x[1]+Planets[2].x[0]*Planets[2].x[0]); - - Planets[2].x[0]=(-s*JD)-0.01; - Planets[2].x[1]=0; - Planets[2].x[2]=0; - Planets[2].v[0]=0; - Planets[2].v[1]=-sqrt(G/((s*JD)-0.01)); - Planets[2].v[2]=0; - for(int i=0; i<3;i++){ - for(int k=0; k<3; k++){ - Planets[k].a[i]=0; - } - } - for(int i=0; i<3; i++){ - Planets[0].x[i]=0; - Planets[0].v[i]=0; - } - Planets[1].x[0]=JD; - Planets[1].x[1]=0; - Planets[1].x[2]=0; - Planets[1].v[0]=0; - Planets[1].v[1]=VJ0; - Planets[1].v[2]=0; - update(10000); - double r20= sqrt(Planets[2].x[1]*Planets[2].x[1]+Planets[2].x[0]*Planets[2].x[0]); - update(10000); - double r2=sqrt(Planets[2].x[1]*Planets[2].x[1]+Planets[2].x[0]*Planets[2].x[0]); - double d0=fabs(r10-r20); - double d=fabs(r2-r1); - double l= log(d/d0); - fprintf(starting, "%lf %lf\n", r10, l); - - } - fclose(starting); -} - diff --git a/src/nbody.c b/src/nbody.c deleted file mode 100644 index 60de895d661aba1d518ab77d04bd0c3e0835dc25..0000000000000000000000000000000000000000 --- a/src/nbody.c +++ /dev/null @@ -1,186 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#define pi 3.141592653589793 -#define solar_mass 1 -#define G (4 * pi * pi) -#define days_per_year 365.24 - -//compile options gcc -O2 main.c -Wall -lm - -typedef struct { - double x[3]; - double v[3]; - double a[3]; - double mass; -} Planet; - -//Unit scaling: Mass in solar mass, distance in AU, velocity in AU/year, and constant G in AU^3/solar mass*year^2 - -Planet Planets[] = { - { - {0,0,0}, - {0,0,0}, - {0,0,0}, - solar_mass - }, - { - {4.84143144246472090e+00, - -1.16032004402742839e+00, - -1.03622044471123109e-01}, - {1.66007664274403694e-03 * days_per_year, - 7.69901118419740425e-03 * days_per_year, - -6.90460016972063023e-05 * days_per_year}, - {0,0,0}, - 9.54791938424326609e-04 * solar_mass - }, - { - {8.34336671824457987e+00, - 4.12479856412430479e+00, - -4.03523417114321381e-01}, - {-2.76742510726862411e-03 * days_per_year, - 4.99852801234917238e-03 * days_per_year, - 2.30417297573763929e-05 * days_per_year}, - 2.85885980666130812e-04 * solar_mass - }, - { - {1.28943695621391310e+01, - -1.51111514016986312e+01, - -2.23307578892655734e-01}, - {2.96460137564761618e-03 * days_per_year, - 2.37847173959480950e-03 * days_per_year, - -2.96589568540237556e-05 * days_per_year}, - 4.36624404335156298e-05 * solar_mass - }, - { - {1.53796971148509165e+01, - -2.59193146099879641e+01, - 1.79258772950371181e-01}, - {2.68067772490389322e-03 * days_per_year, - 1.62824170038242295e-03 * days_per_year, - -9.51592254519715870e-05 * days_per_year}, - 5.15138902046611451e-05 * solar_mass - } -}; - -//TODO add softening factor -static inline double distance( const double x1[3], const double x2[3]) { - const double x = x1[0] - x2[0]; - const double y = x1[1] - x2[1]; - const double z = x1[2] - x2[2]; - - return sqrt(x*x + y*y + z*z + 0.001); - -} -double energy(int n){ - double e; - int i=0, j=0, k=0; - e = 0.0; - - for(i=0; i<n; i++){ - for(k=0; k<3; k++){ - e += 0.5 * Planets[i].mass * Planets[i].v[k] * Planets[i].v[k]; - } - for(j=i+1; j < n; j++) { - double dist = distance(Planets[i].x, Planets[j].x); - e -= (G * Planets[i].mass * Planets[j].mass) / dist; - } - } - return e; -} - -static inline double radius(const double r[3]){ - const double x = r[0]; - const double y = r[1]; - const double z = r[2]; - return sqrt(x*x+y*y+z*z); -} - -static inline double velocity(const double v[3]){ - const double vx = v[0]; - const double vy = v[1]; - const double vz = v[2]; - return sqrt(vx*vx+vy*vy+vz*vz); -} - -double an_mom(int n){ - double L; - int i=0; - L=0.0; - - for(i=0; i<n; i++){ - double v = velocity(Planets[i].v); - double r = radius(Planets[i].x); - L+= Planets[i].mass * v * r; - } - return L; -} - - -int main(int argc, char * argv[]) { - - const long steps = atoi(argv[1]); - FILE *output = fopen("output.xyz", "w+"); - if (output == NULL) { - printf("HELP\n COULDNT OPEN FILE\nSIGSEVV"); //TODO stop here - } else { - printf("Output File opened\n"); - } - //this could also be done via the preprocessor - const int noOfBodies = sizeof(Planets)/sizeof(Planet); - printf("size: %d\n", noOfBodies); - const double dt = 0.01; - - printf("energy before: %.9f\n", energy(noOfBodies)); - printf("total angular momentum before: %.9f\n", an_mom(noOfBodies)); - - long run = 0; - - while (run < steps) { - if (run %(long int) 10== 0){ - fprintf(output, "%d\n%d.000\n", noOfBodies, run+1); - } - for (int l = 0; l < noOfBodies; l++) { - Planets[l].v[0] += 0.5 * Planets[l].a[0]* dt; - Planets[l].v[1] += 0.5 * Planets[l].a[1]* dt; - Planets[l].v[2] += 0.5 * Planets[l].a[2]* dt; - if (run %(long int) 10== 0) { - fprintf(output, "%d %lf %lf %lf\n", l, Planets[l].x[0], Planets[l].x[1], Planets[l].x[2]); - } - } - for (int k = 0; k < noOfBodies; k++) { - Planets[k].x[0] += dt * Planets[k].v[0]; - Planets[k].x[1] += dt * Planets[k].v[1]; - Planets[k].x[2] += dt * Planets[k].v[2]; - Planets[k].a[0] = 0; - Planets[k].a[1] = 0; - Planets[k].a[2] = 0; - } - - for (int i = 0; i < noOfBodies; i++) { - for (int j = i+1; j < noOfBodies; j++) { - double dist = distance(Planets[i].x, Planets[j].x); - double a = G/pow(dist, 3); - - Planets[i].a[0] += a * Planets[j].mass * ( Planets[j].x[0] - Planets[i].x[0] ); - Planets[i].a[1] += a * Planets[j].mass * ( Planets[j].x[1] - Planets[i].x[1] ); - Planets[i].a[2] += a * Planets[j].mass * ( Planets[j].x[2] - Planets[i].x[2] ); - Planets[j].a[0] += a * Planets[i].mass * ( Planets[i].x[0] - Planets[j].x[0] ); - Planets[j].a[1] += a * Planets[i].mass * ( Planets[i].x[1] - Planets[j].x[1] ); - Planets[j].a[2] += a * Planets[i].mass * ( Planets[i].x[2] - Planets[j].x[2] ); - } - } - - for (int m = 0; m < noOfBodies; m++) { - Planets[m].v[0] += 0.5 * Planets[m].a[0]* dt; - Planets[m].v[1] += 0.5 * Planets[m].a[1]* dt; - Planets[m].v[2] += 0.5 * Planets[m].a[2]* dt; - } - run++; - } - printf("energy after: %.9f\n", energy(noOfBodies)); - printf("total angular momentum after: %.9f\n", an_mom(noOfBodies)); - fclose(output); -} -