Trying to add fluid simulation

This commit is contained in:
2026-04-12 20:49:02 +02:00
parent 056589a6f9
commit ac317a3829
65 changed files with 2708 additions and 371 deletions
+3
View File
@@ -1,6 +1,8 @@
target_sources(Engine
PRIVATE
EventManager.h
FluidScene.h
FluidScene.cpp
LightEnvironment.h
LightEnvironment.cpp
Util.h
@@ -11,6 +13,7 @@ target_sources(Engine
PUBLIC FILE_SET HEADERS
FILES
EventManager.h
FluidScene.h
LightEnvironment.h
Util.h
Scene.h)
+173
View File
@@ -0,0 +1,173 @@
#include "FluidScene.h"
#include "Graphics/Enums.h"
using namespace Seele;
FluidScene::FluidScene(Gfx::PGraphics graphics) : graphics(graphics) {}
FluidScene::~FluidScene() {}
void FluidScene::updateFluidData(uint32 entityID, const Component::Transform& transform, const Component::FluidGrid& grid) {
if (!fluidDataMap.contains(entityID)) {
auto& data = fluidDataMap[entityID];
uint64 totalCells = (uint64)grid.gridSize.x * grid.gridSize.y * grid.gridSize.z;
uint64 bufferSize = totalCells * sizeof(float);
Array<float> initialDensity(bufferSize / sizeof(float));
Array<float> initialVelocityX(bufferSize / sizeof(float));
Array<float> initialVelocityY(bufferSize / sizeof(float));
Array<float> initialVelocityZ(bufferSize / sizeof(float));
Array<float> initialPhi(bufferSize / sizeof(float));
// Initialize level set to positive (outside) everywhere
float halfGridX = static_cast<float>(grid.gridSize.x) * 0.5f;
float halfGridY = static_cast<float>(grid.gridSize.y) * 0.5f;
float radius = static_cast<float>(grid.gridSize.x) * 0.2f;
// Place sphere center in the lower portion of the grid
float cx = halfGridX;
float cy = halfGridY;
float cz = static_cast<float>(grid.gridSize.z) * 0.3f;
for (uint32 z = 1; z < grid.gridSize.z - 1; ++z) {
for (uint32 y = 1; y < grid.gridSize.y - 1; ++y) {
for (uint32 x = 1; x < grid.gridSize.x - 1; ++x) {
uint32 idx = x + grid.gridSize.x * y + grid.gridSize.x * grid.gridSize.y * z;
float dx = static_cast<float>(x) - cx;
float dy = static_cast<float>(y) - cy;
float dz = static_cast<float>(z) - cz;
float dist = std::sqrt(dx * dx + dy * dy + dz * dz);
initialPhi[idx] = dist - radius;
if (dist < radius) {
initialDensity[idx] = 1.0f;
// Give an initial upward velocity to kick the simulation
initialVelocityZ[idx] = 5.0f;
}
}
}
}
data.phiBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "PhiBuffer",
});
data.phi0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
.data = (uint8*)initialPhi.data(),
},
.name = "Phi0Buffer",
});
data.densityBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "DensityBuffer",
});
data.density0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
.data = (uint8*)initialDensity.data(),
},
.name = "Density0Buffer",
});
data.scratchBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "ScratchBuffer",
});
data.velocityXNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "VelocityXNextBuffer",
});
data.velocityYNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "VelocityYNextBuffer",
});
data.velocityZNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "VelocityZNextBuffer",
});
data.velocityXBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "VelocityXBuffer",
});
data.velocityYBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "VelocityYBuffer",
});
data.velocityZBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
},
.name = "VelocityZBuffer",
});
data.velocityX0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
.data = (uint8*)initialVelocityX.data(),
},
.name = "VelocityX0Buffer",
});
data.velocityY0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
.data = (uint8*)initialVelocityY.data(),
},
.name = "VelocityY0Buffer",
});
data.velocityZ0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData =
{
.size = bufferSize,
.data = (uint8*)initialVelocityZ.data(),
},
.name = "VelocityZ0Buffer",
});
data.vertexBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.name = "VertexBuffer",
});
data.normalBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.name = "NormalBuffer",
});
data.indexBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.name = "IndexBuffer",
});
data.surfaceCountBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = 4 * sizeof(uint32),
},
.usage = Gfx::SE_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
.name = "SurfaceCountBuffer",
});
}
auto& data = fluidDataMap[entityID];
data.transform = transform.transform;
data.cellSize = grid.cellSize;
data.viscosity = grid.viscosity;
data.diffusion = grid.diffusion;
data.gridSize = grid.gridSize;
}
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include "Component/FluidGrid.h"
#include "Component/Transform.h"
#include "Containers/Array.h"
#include "Containers/Map.h"
#include "Graphics/Buffer.h"
#include "Graphics/Graphics.h"
#include "Graphics/Shader.h"
#include "Math/Transform.h"
#include "Math/Vector.h"
#include "MinimalEngine.h"
namespace Seele {
class FluidScene {
public:
FluidScene(Gfx::PGraphics graphics);
virtual ~FluidScene();
struct FluidData {
Math::Transform transform;
float cellSize;
float viscosity;
float diffusion;
UVector gridSize;
Gfx::OShaderBuffer phiBuffer;
Gfx::OShaderBuffer phi0Buffer;
Gfx::OShaderBuffer densityBuffer;
Gfx::OShaderBuffer density0Buffer;
Gfx::OShaderBuffer scratchBuffer;
Gfx::OShaderBuffer velocityXNextBuffer;
Gfx::OShaderBuffer velocityYNextBuffer;
Gfx::OShaderBuffer velocityZNextBuffer;
Gfx::OShaderBuffer velocityXBuffer;
Gfx::OShaderBuffer velocityYBuffer;
Gfx::OShaderBuffer velocityZBuffer;
Gfx::OShaderBuffer velocityX0Buffer;
Gfx::OShaderBuffer velocityY0Buffer;
Gfx::OShaderBuffer velocityZ0Buffer;
Gfx::OShaderBuffer vertexBuffer;
Gfx::OShaderBuffer normalBuffer;
Gfx::OShaderBuffer indexBuffer;
Gfx::OShaderBuffer surfaceCountBuffer;
uint32 frameCounter = 0;
constexpr uint getVertexBufferSize() {
// Max 5 triangles per cell, 3 vertices per triangle
return gridSize.x * gridSize.y * gridSize.z * 15;
}
constexpr uint getIndexBufferSize() { return gridSize.x * gridSize.y * gridSize.z * 15; }
};
void updateFluidData(uint32 entityID, const Component::Transform& transform, const Component::FluidGrid& grid);
const Map<uint32, FluidData>& getFluidDataMap() const { return fluidDataMap; }
private:
Gfx::PGraphics graphics;
Map<uint32, FluidData> fluidDataMap;
};
DEFINE_REF(FluidScene)
} // namespace Seele
+1 -1
View File
@@ -1,7 +1,7 @@
#include "LightEnvironment.h"
#include "Asset/AssetRegistry.h"
#include "Asset/EnvironmentMapAsset.h"
#include "Graphics/Descriptor.h"
#include "Asset/EnvironmentMapAsset.h"
#include "Graphics/Enums.h"
#include "Graphics/Graphics.h"
+2 -10
View File
@@ -1,22 +1,14 @@
#include "Scene.h"
#include "Actor/PointLightActor.h"
#include "Asset/MaterialAsset.h"
#include "Asset/TextureAsset.h"
#include "Component/DirectionalLight.h"
#include "Component/Mesh.h"
#include "Component/PointLight.h"
#include "Component/Transform.h"
#include "Graphics/Graphics.h"
#include "Graphics/Mesh.h"
#include "Graphics/StaticMeshVertexData.h"
using namespace Seele;
Scene::Scene(Gfx::PGraphics graphics)
: graphics(graphics), lightEnv(new LightEnvironment(graphics)), physics(registry) {}
: graphics(graphics), lightEnv(new LightEnvironment(graphics)), fluidScene(new FluidScene(graphics)), physics(registry) {}
Scene::~Scene() {}
void Scene::bakeLighting() {}
void Scene::update(float deltaTime) { physics.update(deltaTime); }
+3 -3
View File
@@ -1,12 +1,10 @@
#pragma once
#include "MinimalEngine.h"
#include "Component/Skybox.h"
#include "Graphics/Graphics.h"
#include "LightEnvironment.h"
#include "Physics/PhysicsSystem.h"
#include "FluidScene.h"
#include <entt/entt.hpp>
#include <iostream>
namespace Seele {
DECLARE_REF(Material)
@@ -33,12 +31,14 @@ class Scene {
template <typename Component> auto constructCallback() { return registry.on_construct<Component>(); }
template <typename Component> auto destroyCallback() { return registry.on_destroy<Component>(); }
PLightEnvironment getLightEnvironment() { return lightEnv; }
PFluidScene getFluidScene() { return fluidScene; }
Gfx::PGraphics getGraphics() const { return graphics; }
entt::registry registry;
private:
Gfx::PGraphics graphics;
OLightEnvironment lightEnv;
OFluidScene fluidScene;
PhysicsSystem physics;
Array<Gfx::OTexture2D> lightMaps;
};