From 04597e5d29f36a6558e907aafa2925cef142a14b Mon Sep 17 00:00:00 2001 From: Elias Stepanik <40958815+eliasstepanik@users.noreply.github.com> Date: Mon, 24 Oct 2022 21:04:05 +0200 Subject: [PATCH] qwe --- .gitignore | 5 + PixelEngine.sln | 16 ++ PixelEngine/.dockerignore | 25 ++++ PixelEngine/Dockerfile | 18 +++ PixelEngine/Fluid.cs | 264 +++++++++++++++++++++++++++++++++ PixelEngine/PixelEngine.csproj | 16 ++ PixelEngine/Program.cs | 94 ++++++++++++ 7 files changed, 438 insertions(+) create mode 100644 .gitignore create mode 100644 PixelEngine.sln create mode 100644 PixelEngine/.dockerignore create mode 100644 PixelEngine/Dockerfile create mode 100644 PixelEngine/Fluid.cs create mode 100644 PixelEngine/PixelEngine.csproj create mode 100644 PixelEngine/Program.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..add57be --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +/packages/ +riderModule.iml +/_ReSharper.Caches/ \ No newline at end of file diff --git a/PixelEngine.sln b/PixelEngine.sln new file mode 100644 index 0000000..d6a7ec7 --- /dev/null +++ b/PixelEngine.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixelEngine", "PixelEngine\PixelEngine.csproj", "{D0BBE489-D751-4A90-8B07-0B8830F96FFA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D0BBE489-D751-4A90-8B07-0B8830F96FFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0BBE489-D751-4A90-8B07-0B8830F96FFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0BBE489-D751-4A90-8B07-0B8830F96FFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0BBE489-D751-4A90-8B07-0B8830F96FFA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/PixelEngine/.dockerignore b/PixelEngine/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/PixelEngine/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/PixelEngine/Dockerfile b/PixelEngine/Dockerfile new file mode 100644 index 0000000..766c370 --- /dev/null +++ b/PixelEngine/Dockerfile @@ -0,0 +1,18 @@ +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["PixelEngine/PixelEngine.csproj", "PixelEngine/"] +RUN dotnet restore "PixelEngine/PixelEngine.csproj" +COPY . . +WORKDIR "/src/PixelEngine" +RUN dotnet build "PixelEngine.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "PixelEngine.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "PixelEngine.dll"] diff --git a/PixelEngine/Fluid.cs b/PixelEngine/Fluid.cs new file mode 100644 index 0000000..91e3a62 --- /dev/null +++ b/PixelEngine/Fluid.cs @@ -0,0 +1,264 @@ +using Raylib_CsLo; +using static Raylib_CsLo.RayMath; + +namespace PixelEngine; + +public class Fluid +{ + public int size { get; set; } + public int scale { get; set; } + public int iter { get; set; } + + public float dt { get; set; } + public float diff { get; set; } + public float visc { get; set; } + + public float[] s { get; set; } + public float[] density { get; set; } + + public float[] Vx { get; set; } + public float[] Vy { get; set; } + + public float[] Vx0 { get; set; } + public float[] Vy0 { get; set; } + + + public Fluid(float dt, float diffusion, float viscosity, int N, int iter, int scale) { + + this.size = N; + this.iter = iter; + this.dt = dt; + this.diff = diffusion; + this.visc = viscosity; + this.scale = scale; + + this.s = new float[N*N]; + this.density = new float[N*N]; + + this.Vx = new float[N*N]; + this.Vy = new float[N*N]; + + this.Vx0 = new float[N*N]; + this.Vy0 = new float[N*N]; + } + + public void step() { + int N = this.size; + float visc = this.visc; + float diff = this.diff; + float dt = this.dt; + float[] Vx = this.Vx; + float[] Vy = this.Vy; + float[] Vx0 = this.Vx0; + float[] Vy0 = this.Vy0; + float[] s = this.s; + float[] density = this.density; + + diffuse(1, Vx0, Vx, visc, dt); + diffuse(2, Vy0, Vy, visc, dt); + + project(Vx0, Vy0, Vx, Vy); + + advect(1, Vx, Vx0, Vx0, Vy0, dt); + advect(2, Vy, Vy0, Vx0, Vy0, dt); + + project(Vx, Vy, Vx0, Vy0); + + diffuse(0, s, density, diff, dt); + advect(0, density, s, Vx, Vy, dt); + } + + + void fadeD() { + for (int i = 0; i < this.density.Length; i++) { + float d = density[i]; + density[i] = Clamp(d-0.02f, 0, 255); + } + } + + public void renderD() { + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + int x = i * scale; + int y = j * scale; + float d = this.density[IX(i, j)]; + + Color color = new Color(/*((d + 50) % 255)*/100,255,0,(int)d * 2); + Raylib.DrawRectangle(x, y, scale, scale, color); + } + } + } + + + public int IX(int x, int y) + { + var X = Clamp(x, 0, size - 1); + var Y = Clamp(y, 0, size - 1); + return X + Y * size; + } + + float Clamp( float value, float min, float max ) + { + return (value < min) ? min : (value > max) ? max : value; + } + int Clamp( int value, int min, int max ) + { + return (value < min) ? min : (value > max) ? max : value; + } + + + public void addDensity(int x, int y, float amount) { + int index = IX(x, y); + this.density[index] += amount; + } + + public void reduceDensity(int x, int y, float amount) { + + for (int i = -10; i < 10; i++) + { + for (int j = -10; j < 10; j++) + { + int index = IX(x + i, y + j); + + if (this.density[index] - amount < 0) + { + this.density[index] = 0; + } + else + { + this.density[index] -= amount; + } + } + } + + + + + /*var amtX = Raylib.GetMouseX(); + var amtY = Raylib.GetMouseY(); + + addVelocity(amtX / scale, amtY / scale, amtX * 2, amtY * 2);*/ + } + + public void addVelocity(int x, int y, float amountX, float amountY) { + int index = IX(x, y); + this.Vx[index] += amountX; + this.Vy[index] += amountY; + } + + + void diffuse (int b, float[] x, float[] x0, float diff, float dt) { + float a = dt * diff * (size - 2) * (size - 2); + lin_solve(b, x, x0, a, 1 + 4 * a); + } + void lin_solve(int b, float[] x, float[] x0, float a, float c) { + float cRecip = 1.0f / c; + for (int k = 0; k < iter; k++) { + for (int j = 1; j < size - 1; j++) { + for (int i = 1; i < size - 1; i++) { + x[IX(i, j)] = + (x0[IX(i, j)] + + a*( x[IX(i+1, j)] + +x[IX(i-1, j)] + +x[IX(i, j+1)] + +x[IX(i, j-1)] + )) * cRecip; + } + } + + set_bnd(b, x); + } + } + void project(float[] velocX, float[] velocY, float[] p, float[] div) { + for (int j = 1; j < size - 1; j++) { + for (int i = 1; i < size - 1; i++) { + div[IX(i, j)] = -0.5f*( + velocX[IX(i+1, j)] + -velocX[IX(i-1, j)] + +velocY[IX(i, j+1)] + -velocY[IX(i, j-1)] + )/size; + p[IX(i, j)] = 0; + } + } + + set_bnd(0, div); + set_bnd(0, p); + lin_solve(0, p, div, 1, 4); + + for (int j = 1; j < size - 1; j++) { + for (int i = 1; i < size - 1; i++) { + velocX[IX(i, j)] -= 0.5f * ( p[IX(i+1, j)] + -p[IX(i-1, j)]) * size; + velocY[IX(i, j)] -= 0.5f * ( p[IX(i, j+1)] + -p[IX(i, j-1)]) * size; + } + } + set_bnd(1, velocX); + set_bnd(2, velocY); + } + void advect(int b, float[] d, float[] d0, float[] velocX, float[] velocY, float dt) { + float i0, i1, j0, j1; + + float dtx = dt * (size - 2); + float dty = dt * (size - 2); + + float s0, s1, t0, t1; + float tmp1, tmp2, x, y; + + float Nfloat = size; + float ifloat, jfloat; + int i, j; + + for (j = 1, jfloat = 1; j < size - 1; j++, jfloat++) { + for (i = 1, ifloat = 1; i < size - 1; i++, ifloat++) { + tmp1 = dtx * velocX[IX(i, j)]; + tmp2 = dty * velocY[IX(i, j)]; + x = ifloat - tmp1; + y = jfloat - tmp2; + + if (x < 0.5f) x = 0.5f; + if (x > Nfloat + 0.5f) x = Nfloat + 0.5f; + i0 = RayMath.floorf(x); + i1 = i0 + 1.0f; + if (y < 0.5f) y = 0.5f; + if (y > Nfloat + 0.5f) y = Nfloat + 0.5f; + j0 = RayMath.floorf(y); + j1 = j0 + 1.0f; + + s1 = x - i0; + s0 = 1.0f - s1; + t1 = y - j0; + t0 = 1.0f - t1; + + int i0i = (int)i0; + int i1i = (int)i1; + int j0i = (int)j0; + int j1i = (int)j1; + + // DOUBLE CHECK THIS!!! + d[IX(i, j)] = + s0 * (t0 * d0[IX(i0i, j0i)] + t1 * d0[IX(i0i, j1i)]) + + s1 * (t0 * d0[IX(i1i, j0i)] + t1 * d0[IX(i1i, j1i)]); + } + } + + set_bnd(b, d); + } + void set_bnd(int b, float[] x) { + for (int i = 1; i < size - 1; i++) { + x[IX(i, 0 )] = b == 2 ? -x[IX(i, 1 )] : x[IX(i, 1 )]; + x[IX(i, size-1)] = b == 2 ? -x[IX(i, size-2)] : x[IX(i, size-2)]; + } + for (int j = 1; j < size - 1; j++) { + x[IX(0, j)] = b == 1 ? -x[IX(1, j)] : x[IX(1, j)]; + x[IX(size-1, j)] = b == 1 ? -x[IX(size-2, j)] : x[IX(size-2, j)]; + } + + x[IX(0, 0)] = 0.5f * (x[IX(1, 0)] + x[IX(0, 1)]); + x[IX(0, size-1)] = 0.5f * (x[IX(1, size-1)] + x[IX(0, size-2)]); + x[IX(size-1, 0)] = 0.5f * (x[IX(size-2, 0)] + x[IX(size-1, 1)]); + x[IX(size-1, size-1)] = 0.5f * (x[IX(size-2, size-1)] + x[IX(size-1, size-2)]); + } + +} \ No newline at end of file diff --git a/PixelEngine/PixelEngine.csproj b/PixelEngine/PixelEngine.csproj new file mode 100644 index 0000000..d17f885 --- /dev/null +++ b/PixelEngine/PixelEngine.csproj @@ -0,0 +1,16 @@ + + + + Exe + net6.0 + enable + enable + Linux + + + + + + + + diff --git a/PixelEngine/Program.cs b/PixelEngine/Program.cs new file mode 100644 index 0000000..8a9ee31 --- /dev/null +++ b/PixelEngine/Program.cs @@ -0,0 +1,94 @@ +using System.Drawing; +using System.Numerics; +using System.Security.Cryptography.X509Certificates; +using static Raylib_CsLo.Raylib; +using static Raylib_CsLo.RayMath; +using static Raylib_CsLo.RayGui; +using System.Drawing; +using PixelEngine; +using Raylib_CsLo; + + +/*var c = new CircleAndClock(); +c.Run();*/ +var N = 64; +var Scale = 10; +var Iter = 10; +float t = 0; + +Fluid fluid; + +fluid = new Fluid(0.2f, 0, 0.0000001f, N, Iter, Scale); +InitWindow(N * Scale, N * Scale, "Raylib_CsLo"); +SetTargetFPS(60); +Random rd = new Random(); + + +var pMouseX = GetMouseX(); +var pMouseY = GetMouseY(); + + +while (!WindowShouldClose()) +{ + BeginDrawing(); + ClearBackground(BLACK); + DrawFPS(10,10); + + /*int cx = (int)0.5*N/Scale; + int cy = (int)0.5*N/Scale; + for (int i = -1; i <= 1; i++) { + for (int j = -1; j <= 1; j++) { + fluid.addDensity(cx+i, cy+j, rd.Next(50, 150)); + } + }*/ + /*for (int i = 0; i < 2; i++) { + float angle = noise(t) * TWO_PI * 2; + PVector v = PVector.fromAngle(angle); + v.mult(0.2); + t += 0.01; + fluid.addVelocity(cx, cy, v.x, v.y ); + }*/ + + + /*fluid.step(); + fluid.renderD();*/ + + + if (IsMouseButtonDown(MouseButton.MOUSE_BUTTON_LEFT)) + fluid.addDensity((int)GetMouseX() / Scale, (int)GetMouseY() / Scale, 100); + else if (IsMouseButtonDown(MouseButton.MOUSE_BUTTON_RIGHT)) + { + fluid.reduceDensity((int)GetMouseX() / Scale, (int)GetMouseY() / Scale, 100); + + + //TODO: Suction for Density Reduction + /*var amtX = GetMouseX() - pMouseX; + var amtY = GetMouseY() - pMouseY; + + fluid.addVelocity((int)GetMouseX() / Scale, (int)GetMouseY() / Scale, amtX, amtY);*/ + } + + + + fluid.addDensity(N - 3, 3, 200); + fluid.addVelocity(N - 3 , 3, -10f, -10f); + + + /*if (GetMouseX() != pMouseX || GetMouseY() != pMouseY) + { + + var amtX = GetMouseX() - pMouseX; + var amtY = GetMouseY() - pMouseY; + + fluid.addVelocity((int)GetMouseX() / Scale, (int)GetMouseY() / Scale, amtX, amtY); + }*/ + + pMouseX = GetMouseX(); + pMouseY = GetMouseY(); + + fluid.step(); + fluid.renderD(); + + + EndDrawing(); +}