#include <cstdio> #include <cmath> #include <string> #include "raylib.h" #include "waterpool.hpp" const int WIDTH = 160; const int HEIGHT = 160; using PoolType = Sapphire::WaterPool<WIDTH, HEIGHT>; const int PIXELS_PER_CELL = 4; struct RenderContext { const int screenWidth = WIDTH * PIXELS_PER_CELL; const int screenHeight = HEIGHT * PIXELS_PER_CELL; float zoom = 8000.0f; // pixels per meter float xCenter = 0.05f; float yCenter = 0.00f; int xScreen(float x) const { return (screenWidth/2) + static_cast<int>(round(zoom * (x - xCenter))); } int yScreen(float y) const { return (screenHeight/2) - static_cast<int>(round(zoom * (y - yCenter))); } int scale(float r) const { return static_cast<int>(round(zoom * r)); } static Color cellColor(const Sapphire::WaterCell& cell) { using namespace Sapphire; if (cell.wet == 0.0f) return WHITE; float g = 128.0f * (cell.pos + 1.0f); if (g > 255.0f) g = 255.0f; else if (g < 0.0f) g = 0.0f; return CLITERAL(Color){0, static_cast<unsigned char>(g), 32, 255}; } void draw(const PoolType& pool) { using namespace Sapphire; for (int i = 0; i < WIDTH; ++i) { for (int j = 0; j < HEIGHT; ++j) { const WaterCell& cell = pool.getCell(i, j); Color color = cellColor(cell); DrawRectangle(i*PIXELS_PER_CELL, j*PIXELS_PER_CELL, PIXELS_PER_CELL, PIXELS_PER_CELL, color); } } } }; int main(int argc, const char *argv[]) { using namespace Sapphire; float dt = 1.0f / 48000.0f; float halflife = 0.07f; float c = 2.0f; // speed of waves in meters/second float s = 0.001f; // grid spacing in meters float k = (c*c) / (s*s); // propagation constant [second^(-2)] PoolType pool; RenderContext render; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { int r = 1 + i*i + j*j; pool.getCell(i + WIDTH/5, j + HEIGHT/2).vel = +20000.0f / r; } } // Create reflective barriers. for (int i = 30; i+10 < WIDTH; ++i) { pool.getCell(i, HEIGHT/2-7).wet = 0.0f; pool.getCell(i-13, HEIGHT/2+17).wet = 0.0f; } InitWindow(render.screenWidth, render.screenHeight, "Water Simulation by Don Cross"); SetTargetFPS(240); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(BLACK); render.draw(pool); EndDrawing(); pool.update(dt, halflife, k); } CloseWindow(); return 0; }