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/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..052dc70 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.30) +project(VoxelSim) + +set(CMAKE_CXX_STANDARD 23) + +add_executable(VoxelSim main.cpp + simulation.cpp + simulation.h) diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..918249f --- /dev/null +++ b/main.cpp @@ -0,0 +1,54 @@ +#include +#include +#include "simulation.h" + +void printGrid(simulation::SimulationGrid* grid) +{ + std::cout << std::string(grid->x_max+2, '_') << std::endl; + for (unsigned char y = grid->y_max; y > 0; y--) + { + std::cout << "|"; + for (unsigned char x = 0; x < grid->x_max; x++) + { + unsigned int offset = simulation::getCellOffset(x, y-1, 0, grid); + unsigned int material = grid->cells[offset]; + switch (material) + { + case simulation::VACUUM: + std::cout << " "; + break; + case simulation::WATER: + std::cout << "~"; + break; + default: + std::cout << "?"; + } + } + std::cout << "|" << std::endl; + } + std::cout << std::string(grid->x_max+2, '_') << std::endl; +} + +int main() +{ + unsigned char xMax = 50; + unsigned char yMax = 20; + unsigned char zMax = 1; + size_t bufferSizeInBytes = sizeof(unsigned int) * xMax * yMax * zMax; + auto inCells = static_cast(std::malloc(bufferSizeInBytes)); + std::memset(inCells, 0, bufferSizeInBytes); + auto outCells = static_cast(std::malloc(bufferSizeInBytes)); + simulation::SimulationGrid inGrid = { + inCells, xMax, yMax, zMax + }; + simulation::SimulationGrid outGrid = { + outCells, xMax, yMax, zMax + }; + + step(0, &inGrid, &outGrid); + + printGrid(&outGrid); + std::free(inCells); + std::free(outCells); + return 0; +} diff --git a/simulation.cpp b/simulation.cpp new file mode 100644 index 0000000..3dd8fad --- /dev/null +++ b/simulation.cpp @@ -0,0 +1,51 @@ +#include "simulation.h" + +namespace simulation +{ + unsigned int getCellOffset( + unsigned char x, + unsigned char y, + unsigned char z, + SimulationGrid* grid) + { + if (x < grid->x_max && y < grid->y_max && z < grid->z_max) + { + unsigned int offset = x + y * grid->x_max + z * (grid->y_max * grid->x_max); + return offset; + } + return -1; + } + + void step( + double millisecondsSinceLastStep, + SimulationGrid* input, + SimulationGrid* output) + { + for (unsigned char x = 0; x < input->x_max; x++) + { + for (unsigned char y = 0; y < input->y_max; y++) + { + for (unsigned char z = 0; z < input->z_max; z++) + { + unsigned int offset = getCellOffset(x, y, z, input); + unsigned int material = input->cells[offset]; + switch (material) + { + case WATER: + if (y > 0) + { + unsigned int downOffset = getCellOffset(x, y - 1, z, input); + // Flow down if cell is empty + if (output->cells[downOffset] == 0) + { + output->cells[downOffset] = material; + } + } + default: + output->cells[offset] = material; + } + } + } + } + } +} diff --git a/simulation.h b/simulation.h new file mode 100644 index 0000000..5303ba3 --- /dev/null +++ b/simulation.h @@ -0,0 +1,37 @@ +// +// Created by johan on 2025-01-25. +// + +#ifndef SIMULATION_H +#define SIMULATION_H +namespace simulation +{ + enum Fluid + { + VACUUM = 0, + WATER, + MERCURY + }; + + struct SimulationGrid + { + unsigned int* cells; + unsigned char x_max; + unsigned char y_max; + unsigned char z_max; + }; + + void step( + double millisecondsSinceLastStep, + SimulationGrid* input, + SimulationGrid* output); + + unsigned int getCellOffset( + unsigned char x, + unsigned char y, + unsigned char z, + SimulationGrid* grid); + +} + +#endif //SIMULATION_H