commit 0528cfb93e932e8ceda1ac13aea4ffc37af3c977
Author: Quinta <0pietroquintavalle0@gmail.com>
Date: Fri Jul 12 03:22:10 2024 +0200
Gave up on that fucking bug for today
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ff9047e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/cmake-build-debug/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/gravity.iml b/.idea/gravity.iml
new file mode 100644
index 0000000..f08604b
--- /dev/null
+++ b/.idea/gravity.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..0b76fe5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..6ef4ed2
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..486a02a
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.28)
+project(gravity)
+
+set(CMAKE_CXX_STANDARD 17)
+
+# Find packages
+find_package(OpenGL REQUIRED)
+find_package(GLEW REQUIRED)
+find_package(glfw3 CONFIG REQUIRED)
+find_package(glm CONFIG REQUIRED)
+
+# Add executable
+add_executable(gravity
+ main.cpp
+ CelestialBody.cpp
+ Simulator.cpp
+ Renderer.cpp
+)
+
+# Include directories
+target_include_directories(gravity PRIVATE
+ ${OPENGL_INCLUDE_DIRS}
+ ${GLEW_INCLUDE_DIRS}
+)
+
+# Link libraries
+target_link_libraries(gravity PRIVATE
+ ${OPENGL_LIBRARIES}
+ GLEW::GLEW
+ glfw
+ glm::glm
+)
+
+# On some systems, you might need to explicitly link against OpenGL
+if(UNIX AND NOT APPLE)
+ target_link_libraries(gravity PRIVATE GL)
+endif()
\ No newline at end of file
diff --git a/CelestialBody.cpp b/CelestialBody.cpp
new file mode 100644
index 0000000..780bb19
--- /dev/null
+++ b/CelestialBody.cpp
@@ -0,0 +1,37 @@
+//
+// Created by 0piet on 7/12/2024.
+//
+#include "CelestialBody.h"
+#include
+#include
+
+// Helper function to convert glm::vec3 to string
+std::string vec3_to_string(const glm::vec3& v) {
+ std::stringstream ss;
+ ss << "(" << v.x << ", " << v.y << ", " << v.z << ")";
+ return ss.str();
+}
+
+CelestialBody::CelestialBody(float mass, const glm::vec3& position, const glm::vec3& velocity)
+ : mass(mass), position(position), velocity(velocity), acceleration(0.0f) {}
+
+void CelestialBody::update(float dt) {
+ if (glm::any(glm::isnan(velocity)) || glm::any(glm::isinf(velocity))) {
+ std::cout << "Warning: Invalid velocity detected: " << vec3_to_string(velocity) << std::endl;
+ velocity = glm::vec3(0.0f);
+ }
+
+ velocity += acceleration * dt;
+ position += velocity * dt;
+
+ if (glm::any(glm::isnan(position)) || glm::any(glm::isinf(position))) {
+ std::cout << "Warning: Invalid position detected: " << vec3_to_string(position) << std::endl;
+ position = glm::vec3(0.0f);
+ }
+
+ acceleration = glm::vec3(0.0f);
+}
+
+void CelestialBody::applyForce(const glm::vec3& force) {
+ acceleration += force / mass;
+}
\ No newline at end of file
diff --git a/CelestialBody.h b/CelestialBody.h
new file mode 100644
index 0000000..b81bc94
--- /dev/null
+++ b/CelestialBody.h
@@ -0,0 +1,28 @@
+//
+// Created by 0piet on 7/12/2024.
+//
+
+#ifndef GRAVITY_CELESTIALBODY_H
+#define GRAVITY_CELESTIALBODY_H
+#pragma once
+#include
+#include
+
+class CelestialBody {
+public:
+ CelestialBody(float mass, const glm::vec3& position, const glm::vec3& velocity);
+
+ void update(float dt);
+ void applyForce(const glm::vec3& force);
+
+ float getMass() const { return mass; }
+ glm::vec3 getPosition() const { return position; }
+ glm::vec3 getVelocity() const { return velocity; }
+
+private:
+ float mass;
+ glm::vec3 position;
+ glm::vec3 velocity;
+ glm::vec3 acceleration;
+};
+#endif //GRAVITY_CELESTIALBODY_H
diff --git a/Renderer.cpp b/Renderer.cpp
new file mode 100644
index 0000000..9b4a6be
--- /dev/null
+++ b/Renderer.cpp
@@ -0,0 +1,215 @@
+//
+// Created by 0piet on 7/12/2024.
+//
+#include "Renderer.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+Renderer::Renderer(int width, int height) {
+ if (!glfwInit()) {
+ throw std::runtime_error("Failed to initialize GLFW");
+ }
+
+ window = glfwCreateWindow(width, height, "3D Gravity Simulator", nullptr, nullptr);
+ if (!window) {
+ glfwTerminate();
+ throw std::runtime_error("Failed to create GLFW window");
+ }
+
+ glfwMakeContextCurrent(window);
+
+ if (glewInit() != GLEW_OK) {
+ throw std::runtime_error("Failed to initialize GLEW");
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_LIGHT0);
+ glEnable(GL_COLOR_MATERIAL);
+
+ createSphereMesh(1.0f, 20, 20);
+}
+
+Renderer::~Renderer() {
+ glDeleteVertexArrays(1, &sphereVAO);
+ glDeleteBuffers(1, &sphereVBO);
+ glDeleteBuffers(1, &sphereEBO);
+ glfwDestroyWindow(window);
+ glfwTerminate();
+}
+
+void Renderer::render(const Simulator& simulator) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glClearColor(0.0f, 0.0f, 0.1f, 1.0f);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(45.0, 1024.0 / 768.0, 1e8, 1e12);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(3e11, 2e11, 3e11, 0, 0, 0, 0, 1, 0);
+
+ drawGrid();
+
+ const auto& bodies = simulator.getBodies();
+ for (size_t i = 0; i < bodies.size(); ++i) {
+ const auto& body = bodies[i];
+ float minSize = 2e9f;
+ float scaleFactor = std::max(std::cbrt(body.getMass()) * 1e-9f, minSize);
+
+ glm::vec3 pos = body.getPosition();
+ std::cout << "Rendering body " << i << " (";
+ switch(i) {
+ case 0: std::cout << "Sun"; break;
+ case 1: std::cout << "Mercury"; break;
+ case 2: std::cout << "Venus"; break;
+ case 3: std::cout << "Earth"; break;
+ case 4: std::cout << "Mars"; break;
+ default: std::cout << "Unknown"; break;
+ }
+ std::cout << ") at position ("
+ << pos.x << ", " << pos.y << ", " << pos.z
+ << ") with scale " << scaleFactor << std::endl;
+
+ // Set color based on body index
+ switch(i) {
+ case 0: glColor3f(1.0f, 1.0f, 0.0f); break; // Sun: Yellow
+ case 1: glColor3f(0.5f, 0.5f, 0.5f); break; // Mercury: Gray
+ case 2: glColor3f(0.9f, 0.7f, 0.4f); break; // Venus: Light Orange
+ case 3: glColor3f(0.0f, 0.5f, 1.0f); break; // Earth: Blue
+ case 4: glColor3f(1.0f, 0.0f, 0.0f); break; // Mars: Red
+ default: glColor3f(1.0f, 1.0f, 1.0f); break; // White for any additional bodies
+ }
+
+ drawSphere(body.getPosition(), scaleFactor);
+ }
+}
+
+bool Renderer::shouldClose() {
+ return glfwWindowShouldClose(window);
+}
+
+void Renderer::swapBuffers() {
+ glfwSwapBuffers(window);
+ glfwPollEvents();
+}
+
+void Renderer::drawSphere(const glm::vec3& position, float radius) {
+ glPushMatrix();
+ glTranslatef(position.x, position.y, position.z);
+ glScalef(radius, radius, radius);
+
+ glBindVertexArray(sphereVAO);
+ glDrawElements(GL_TRIANGLES, sphereIndexCount, GL_UNSIGNED_INT, 0);
+ glBindVertexArray(0);
+
+ glPopMatrix();
+}
+
+void Renderer::createSphereMesh(float radius, int sectors, int stacks) {
+ std::vector vertices;
+ std::vector indices;
+
+ float x, y, z, xy;
+ float nx, ny, nz, lengthInv = 1.0f / radius;
+ float s, t;
+
+ float sectorStep = 2 * M_PI / sectors;
+ float stackStep = M_PI / stacks;
+ float sectorAngle, stackAngle;
+
+ for (int i = 0; i <= stacks; ++i) {
+ stackAngle = M_PI / 2 - i * stackStep;
+ xy = radius * cosf(stackAngle);
+ z = radius * sinf(stackAngle);
+
+ for (int j = 0; j <= sectors; ++j) {
+ sectorAngle = j * sectorStep;
+
+ x = xy * cosf(sectorAngle);
+ y = xy * sinf(sectorAngle);
+
+ nx = x * lengthInv;
+ ny = y * lengthInv;
+ nz = z * lengthInv;
+
+ vertices.push_back(x);
+ vertices.push_back(y);
+ vertices.push_back(z);
+ }
+ }
+
+ for (int i = 0; i < stacks; ++i) {
+ int k1 = i * (sectors + 1);
+ int k2 = k1 + sectors + 1;
+
+ for (int j = 0; j < sectors; ++j, ++k1, ++k2) {
+ if (i != 0) {
+ indices.push_back(k1);
+ indices.push_back(k2);
+ indices.push_back(k1 + 1);
+ }
+
+ if (i != (stacks - 1)) {
+ indices.push_back(k1 + 1);
+ indices.push_back(k2);
+ indices.push_back(k2 + 1);
+ }
+ }
+ }
+
+ glGenVertexArrays(1, &sphereVAO);
+ glGenBuffers(1, &sphereVBO);
+ glGenBuffers(1, &sphereEBO);
+
+ glBindVertexArray(sphereVAO);
+
+ glBindBuffer(GL_ARRAY_BUFFER, sphereVBO);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphereEBO);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
+
+ glBindVertexArray(0);
+
+ sphereVertexCount = vertices.size() / 3;
+ sphereIndexCount = indices.size();
+}
+
+void Renderer::drawDebugTriangle() {
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1, 1, -1, 1, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glBegin(GL_TRIANGLES);
+ glColor3f(1.0f, 0.0f, 0.0f);
+ glVertex3f(-0.5f, -0.5f, 0.0f);
+ glColor3f(0.0f, 1.0f, 0.0f);
+ glVertex3f(0.5f, -0.5f, 0.0f);
+ glColor3f(0.0f, 0.0f, 1.0f);
+ glVertex3f(0.0f, 0.5f, 0.0f);
+ glEnd();
+}
+
+void Renderer::drawGrid() {
+ glBegin(GL_LINES);
+ glColor3f(0.2f, 0.2f, 0.2f); // Gray color for the grid
+ for (float i = -5e11f; i <= 5e11f; i += 5e10f) {
+ glVertex3f(i, 0, -5e11f);
+ glVertex3f(i, 0, 5e11f);
+ glVertex3f(-5e11f, 0, i);
+ glVertex3f(5e11f, 0, i);
+ }
+ glEnd();
+}
\ No newline at end of file
diff --git a/Renderer.h b/Renderer.h
new file mode 100644
index 0000000..ce0e7c0
--- /dev/null
+++ b/Renderer.h
@@ -0,0 +1,33 @@
+//
+// Created by 0piet on 7/12/2024.
+//
+
+#ifndef GRAVITY_RENDERER_H
+#define GRAVITY_RENDERER_H
+#pragma once
+#include
+#include
+#include
+#include "Simulator.h"
+
+class Renderer {
+public:
+ Renderer(int width, int height);
+ ~Renderer();
+
+ void render(const Simulator& simulator);
+ bool shouldClose();
+ void swapBuffers();
+
+private:
+ GLFWwindow* window;
+ void drawSphere(const glm::vec3& position, float radius);
+ void createSphereMesh(float radius, int sectors, int stacks);
+ void drawDebugTriangle(); // Add this line
+
+ GLuint sphereVAO, sphereVBO, sphereEBO;
+ int sphereVertexCount, sphereIndexCount;
+
+ void drawGrid();
+};
+#endif //GRAVITY_RENDERER_H
diff --git a/Simulator.cpp b/Simulator.cpp
new file mode 100644
index 0000000..85aa34d
--- /dev/null
+++ b/Simulator.cpp
@@ -0,0 +1,54 @@
+//
+// Created by 0piet on 7/12/2024.
+//
+#include "Simulator.h"
+#include
+#include
+
+Simulator::Simulator() {}
+
+void Simulator::addBody(const CelestialBody& body) {
+ bodies.push_back(body);
+}
+
+void Simulator::update(float dt) {
+ // Calculate and apply gravitational forces
+ for (size_t i = 0; i < bodies.size(); ++i) {
+ glm::vec3 totalForce(0.0f);
+ for (size_t j = 0; j < bodies.size(); ++j) {
+ if (i != j) {
+ glm::vec3 force = calculateGravitationalForce(bodies[i], bodies[j]);
+ totalForce += force;
+ }
+ }
+ bodies[i].applyForce(totalForce);
+ }
+
+ // Update positions and velocities
+ for (auto& body : bodies) {
+ body.update(dt);
+ }
+}
+
+glm::vec3 Simulator::calculateGravitationalForce(const CelestialBody& body1, const CelestialBody& body2) {
+ glm::vec3 direction = body2.getPosition() - body1.getPosition();
+ float distance = glm::length(direction);
+
+ // Avoid division by zero and unrealistic forces at very small distances
+ if (distance < 1e9) {
+ std::cout << "Warning: Bodies too close, using minimum distance" << std::endl;
+ distance = 1e9;
+ }
+
+ // Use the actual G value
+ const float G = 6.67430e-11f;
+ float forceMagnitude = G * (body1.getMass() * body2.getMass()) / (distance * distance);
+
+ if (std::isnan(forceMagnitude) || std::isinf(forceMagnitude)) {
+ std::cout << "Warning: Invalid force magnitude calculated. Distance: " << distance
+ << ", Masses: " << body1.getMass() << ", " << body2.getMass() << std::endl;
+ return glm::vec3(0.0f);
+ }
+
+ return glm::normalize(direction) * forceMagnitude;
+}
\ No newline at end of file
diff --git a/Simulator.h b/Simulator.h
new file mode 100644
index 0000000..af9c830
--- /dev/null
+++ b/Simulator.h
@@ -0,0 +1,25 @@
+//
+// Created by 0piet on 7/12/2024.
+//
+
+#ifndef GRAVITY_SIMULATOR_H
+#define GRAVITY_SIMULATOR_H
+#pragma once
+#include
+#include "CelestialBody.h"
+
+class Simulator {
+public:
+ Simulator();
+
+ void addBody(const CelestialBody& body);
+ void update(float dt);
+ const std::vector& getBodies() const { return bodies; }
+
+private:
+ std::vector bodies;
+ const float G = 6.67430e-11f; // Gravitational constant
+
+ glm::vec3 calculateGravitationalForce(const CelestialBody& body1, const CelestialBody& body2);
+};
+#endif //GRAVITY_SIMULATOR_H
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..68d54eb
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,36 @@
+#include "Simulator.h"
+#include "Renderer.h"
+#include
+#include
+
+int main() {
+ Simulator simulator;
+ Renderer renderer(1024, 768); // Increased window size for better visibility
+
+ // Sun
+ simulator.addBody(CelestialBody(1.989e30f, glm::vec3(0, 0, 0), glm::vec3(0, 0, 0)));
+
+// Mercury
+ simulator.addBody(CelestialBody(3.285e23f, glm::vec3(57.9e9f, 0, 0), glm::vec3(0, 47.36e3f, 0)));
+
+// Venus
+ simulator.addBody(CelestialBody(4.867e24f, glm::vec3(108.2e9f, 0, 0), glm::vec3(0, 35.02e3f, 0)));
+
+// Earth
+ simulator.addBody(CelestialBody(5.972e24f, glm::vec3(149.6e9f, 0, 0), glm::vec3(0, 29.78e3f, 0)));
+
+// Mars
+ simulator.addBody(CelestialBody(6.39e23f, glm::vec3(227.9e9f, 0, 0), glm::vec3(0, 24.07e3f, 0)));
+
+ const float dt = 3600.0f; // Time step of 1 hour
+
+ while (!renderer.shouldClose()) {
+ simulator.update(dt);
+ renderer.render(simulator);
+ renderer.swapBuffers();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(16)); // Aim for roughly 60 FPS
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json
new file mode 100644
index 0000000..2599769
--- /dev/null
+++ b/vcpkg-configuration.json
@@ -0,0 +1,14 @@
+{
+ "default-registry": {
+ "kind": "git",
+ "baseline": "3f530d4827b064f5894e94a8946473d40999826e",
+ "repository": "https://github.com/microsoft/vcpkg"
+ },
+ "registries": [
+ {
+ "kind": "artifact",
+ "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip",
+ "name": "microsoft"
+ }
+ ]
+}
diff --git a/vcpkg.json b/vcpkg.json
new file mode 100644
index 0000000..d165fcb
--- /dev/null
+++ b/vcpkg.json
@@ -0,0 +1,10 @@
+{
+ "dependencies": [
+ "freeglut",
+ "glew",
+ "glm",
+ "vcpkg-cmake",
+ "opengl",
+ "glfw3"
+ ]
+}
\ No newline at end of file