|
|
@ -44,23 +44,91 @@ Simulation::Simulation() { |
|
|
|
vmaFreeStatsString(Instance::instance->allocator, stats); |
|
|
|
vmaFreeStatsString(Instance::instance->allocator, stats); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Simulation::createMeshBuffers() { |
|
|
|
|
|
|
|
Mesh sphere("models/sphere_high.ply"); |
|
|
|
|
|
|
|
Mesh bunny("models/bunny_high.ply"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto body = std::make_unique<SoftBody>(&sphere, 0.3f); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 3; i++){ |
|
|
|
|
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
|
|
|
|
copy->applyVertexOffset({i * 2, 0, 0}); |
|
|
|
|
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
body = std::make_unique<SoftBody>(&bunny, 0.3f); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 3; i++){ |
|
|
|
|
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
|
|
|
|
copy->applyVertexOffset({i * 2, 2, 0}); |
|
|
|
|
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<Vertex> vertices; |
|
|
|
|
|
|
|
vector<Edge> edges; |
|
|
|
|
|
|
|
vector<Triangle> triangles; |
|
|
|
|
|
|
|
vector<Face> faces; |
|
|
|
|
|
|
|
vector<Tetrahedron> tetrahedra; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (std::unique_ptr<SoftBody> &softBody : softBodies){ |
|
|
|
|
|
|
|
softBody->firstIndex = faces.size() * 3; |
|
|
|
|
|
|
|
softBody->vertexOffset = static_cast<int32_t>(vertices.size()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t off = softBody->vertexOffset; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto &edge : softBody->edges){ |
|
|
|
|
|
|
|
edge.a += off; |
|
|
|
|
|
|
|
edge.b += off; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto &face : softBody->faces){ |
|
|
|
|
|
|
|
face.a += off; |
|
|
|
|
|
|
|
face.b += off; |
|
|
|
|
|
|
|
face.c += off; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto &tetrahedron : softBody->tetrahedra){ |
|
|
|
|
|
|
|
tetrahedron.a += off; |
|
|
|
|
|
|
|
tetrahedron.b += off; |
|
|
|
|
|
|
|
tetrahedron.c += off; |
|
|
|
|
|
|
|
tetrahedron.d += off; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices.insert(vertices.end(), softBody->vertices.begin(), softBody->vertices.end()); |
|
|
|
|
|
|
|
edges.insert(edges.end(), softBody->edges.begin(), softBody->edges.end()); |
|
|
|
|
|
|
|
triangles.insert(triangles.end(), softBody->triangles.begin(), softBody->triangles.end()); |
|
|
|
|
|
|
|
faces.insert(faces.end(), softBody->faces.begin(), softBody->faces.end()); |
|
|
|
|
|
|
|
tetrahedra.insert(tetrahedra.end(), softBody->tetrahedra.begin(), softBody->tetrahedra.end()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimulationBuffer : public Buffer { |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
SimulationBuffer(void* data, VkDeviceSize size, VkBufferUsageFlags additionalUsageFlags=0) |
|
|
|
|
|
|
|
: Buffer(size, data, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | additionalUsageFlags, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0) {} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertexBuffer = make_unique<SimulationBuffer>(vertices.data(), vertices.size() * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
|
|
|
|
|
|
|
faceBuffer = make_unique<SimulationBuffer>(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
|
|
|
|
|
|
|
edgeBuffer = make_unique<SimulationBuffer>(edges.data(), edges.size() * sizeof(Edge)); |
|
|
|
|
|
|
|
triangleBuffer = make_unique<SimulationBuffer>(triangles.data(), triangles.size() * sizeof(Triangle)); |
|
|
|
|
|
|
|
tetrahedronBuffer = make_unique<SimulationBuffer>(tetrahedra.data(), tetrahedra.size() * sizeof(Tetrahedron)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Simulation::recordDrawCommands() { |
|
|
|
void Simulation::recordDrawCommands() { |
|
|
|
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer; |
|
|
|
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer; |
|
|
|
|
|
|
|
|
|
|
|
VkBuffer buffers[] = {vertexBuffer->handle}; |
|
|
|
VkBuffer buffers[] = {vertexBuffer->handle}; |
|
|
|
VkDeviceSize offsets[] = {0}; |
|
|
|
VkDeviceSize offsets[] = {0}; |
|
|
|
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets); |
|
|
|
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets); |
|
|
|
|
|
|
|
vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32); |
|
|
|
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); |
|
|
|
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); |
|
|
|
|
|
|
|
|
|
|
|
for (const auto &softBody : softBodies){ |
|
|
|
for (const auto &softBody : softBodies){ |
|
|
|
vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, sizeof(uint32_t) * softBody->firstIndex, VK_INDEX_TYPE_UINT32); |
|
|
|
vkCmdDrawIndexed(cmdBuffer, softBody->faces.size() * 3, 1, softBody->firstIndex, 0, 0); |
|
|
|
vkCmdDrawIndexed(cmdBuffer, softBody->faces.size() * 3, 1, 0, 0, 0); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
// vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0);
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
#define BlOCK_SIZE 16 |
|
|
|
#define BlOCK_SIZE 32 |
|
|
|
|
|
|
|
|
|
|
|
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ |
|
|
|
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ |
|
|
|
return (threads - 1) / blockSize + 1; |
|
|
|
return (threads - 1) / blockSize + 1; |
|
|
@ -121,65 +189,6 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); |
|
|
|
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Simulation::~Simulation() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Simulation::createMeshBuffers() { |
|
|
|
|
|
|
|
Mesh sphere("models/sphere_high.ply"); |
|
|
|
|
|
|
|
Mesh bunny("models/bunny_high.ply"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto body = std::make_unique<SoftBody>(&sphere, 0.3f); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 5; i++){ |
|
|
|
|
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
|
|
|
|
copy->applyOffset({i * 2, 0, 0}); |
|
|
|
|
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
body = std::make_unique<SoftBody>(&bunny, 0.3f); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 5; i++){ |
|
|
|
|
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
|
|
|
|
copy->applyOffset({i * 2, 2, 0}); |
|
|
|
|
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<Vertex> vertices; |
|
|
|
|
|
|
|
vector<Edge> edges; |
|
|
|
|
|
|
|
vector<Triangle> triangles; |
|
|
|
|
|
|
|
vector<Face> faces; |
|
|
|
|
|
|
|
vector<Tetrahedron> tetrahedra; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const std::unique_ptr<SoftBody> &softBody : softBodies){ |
|
|
|
|
|
|
|
softBody->firstIndex = faces.size() * 3; |
|
|
|
|
|
|
|
softBody->vertexOffset = static_cast<int32_t>(vertices.size()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices.insert(vertices.end(), softBody->vertices.begin(), softBody->vertices.end()); |
|
|
|
|
|
|
|
edges.insert(edges.end(), softBody->edges.begin(), softBody->edges.end()); |
|
|
|
|
|
|
|
triangles.insert(triangles.end(), softBody->triangles.begin(), softBody->triangles.end()); |
|
|
|
|
|
|
|
faces.insert(faces.end(), softBody->faces.begin(), softBody->faces.end()); |
|
|
|
|
|
|
|
tetrahedra.insert(tetrahedra.end(), softBody->tetrahedra.begin(), softBody->tetrahedra.end()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto face = faces.begin() + softBody->firstIndex / 3; face != faces.end(); face++){ |
|
|
|
|
|
|
|
face->a += softBody->vertexOffset; |
|
|
|
|
|
|
|
face->b += softBody->vertexOffset; |
|
|
|
|
|
|
|
face->c += softBody->vertexOffset; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimulationBuffer : public Buffer { |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
SimulationBuffer(void* data, VkDeviceSize size, VkBufferUsageFlags additionalUsageFlags=0) |
|
|
|
|
|
|
|
: Buffer(size, data, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | additionalUsageFlags, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0) {} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertexBuffer = make_unique<SimulationBuffer>(vertices.data(), vertices.size() * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
|
|
|
|
|
|
|
faceBuffer = make_unique<SimulationBuffer>(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
|
|
|
|
|
|
|
edgeBuffer = make_unique<SimulationBuffer>(edges.data(), edges.size() * sizeof(Edge)); |
|
|
|
|
|
|
|
triangleBuffer = make_unique<SimulationBuffer>(triangles.data(), triangles.size() * sizeof(Triangle)); |
|
|
|
|
|
|
|
tetrahedronBuffer = make_unique<SimulationBuffer>(tetrahedra.data(), tetrahedra.size() * sizeof(Tetrahedron)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Simulation::createComputePipelines() { |
|
|
|
void Simulation::createComputePipelines() { |
|
|
|
vector<VkDescriptorSetLayout> layouts; |
|
|
|
vector<VkDescriptorSetLayout> layouts; |
|
|
|
vector<VkPushConstantRange> pushRanges; |
|
|
|
vector<VkPushConstantRange> pushRanges; |
|
|
@ -208,3 +217,6 @@ void Simulation::createComputePipelines() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Simulation::~Simulation() = default; |
|
|
|