mirror of
https://github.com/eliasstepanik/FluidSimulation.git
synced 2026-01-19 01:18:28 +00:00
qwe
This commit is contained in:
commit
04597e5d29
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
/packages/
|
||||||
|
riderModule.iml
|
||||||
|
/_ReSharper.Caches/
|
||||||
16
PixelEngine.sln
Normal file
16
PixelEngine.sln
Normal file
@ -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
|
||||||
25
PixelEngine/.dockerignore
Normal file
25
PixelEngine/.dockerignore
Normal file
@ -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
|
||||||
18
PixelEngine/Dockerfile
Normal file
18
PixelEngine/Dockerfile
Normal file
@ -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"]
|
||||||
264
PixelEngine/Fluid.cs
Normal file
264
PixelEngine/Fluid.cs
Normal file
@ -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)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
16
PixelEngine/PixelEngine.csproj
Normal file
16
PixelEngine/PixelEngine.csproj
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Raylib-CsLo" Version="4.2.0.3" />
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
94
PixelEngine/Program.cs
Normal file
94
PixelEngine/Program.cs
Normal file
@ -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();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user