Trying to add fluid simulation
This commit is contained in:
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,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"
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user