prepare graph color

feature/softbody-runtime-control
Benjamin Kraft 4 months ago
parent 1c322260c4
commit c462321a41
  1. 3
      include/soft_body.hpp
  2. 2
      shaders/normal.comp
  3. 13
      shaders/pbd.comp
  4. 138
      src/simulation.cpp
  5. 33
      src/soft_body.cpp

@ -30,7 +30,8 @@ public:
vector<Face> faces;
vector<Tetrahedron> tetrahedra;
void applyOffset(const glm::vec3& offset);
void applyVertexOffset(const glm::vec3& offset);
void applyIndexOffset(int32_t offset);
SoftBody& operator =(const SoftBody& other) = delete;
private:

@ -1,6 +1,6 @@
#version 450
layout (local_size_x = 16) in;
layout (local_size_x = 32) in;
struct Vertex {
vec3 position;

@ -1,6 +1,6 @@
#version 450
layout (local_size_x = 16) in;
layout (local_size_x = 32) in;
struct Vertex {
vec3 position;
@ -8,10 +8,21 @@ struct Vertex {
vec3 normal;
};
struct Edge {
uint a;
uint b;
};
layout (std430, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[];
};
layout (std430, set = 0, binding = 2) buffer EdgeBuffer {
Edge edges[];
};
layout (std140, set = 0, binding = 5) uniform Sizes {
uint vertexCount;
uint faceCount;

@ -44,23 +44,91 @@ Simulation::Simulation() {
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() {
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer;
VkBuffer buffers[] = {vertexBuffer->handle};
VkDeviceSize offsets[] = {0};
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);
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, 0, 0, 0);
vkCmdDrawIndexed(cmdBuffer, softBody->faces.size() * 3, 1, softBody->firstIndex, 0, 0);
}
// vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0);
}
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
#define BlOCK_SIZE 16
#define BlOCK_SIZE 32
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){
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);
}
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() {
vector<VkDescriptorSetLayout> layouts;
vector<VkPushConstantRange> pushRanges;
@ -208,3 +217,6 @@ void Simulation::createComputePipelines() {
}
}
Simulation::~Simulation() = default;

@ -1,14 +1,10 @@
#include <glm/geometric.hpp>
#include "soft_body.hpp"
#include "mesh.hpp"
#include "constraints.hpp"
#include "tetgen.h"
SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) {
edges.push_back(Edge(0, 1, 10));
triangles.push_back(Triangle(Face(0, 1, 2), 40));
tetrahedra.push_back(Tetrahedron(0, 1, 2, 3, 50));
tetgenbehavior behavior;
behavior.parse_commandline(std::string("pYa0.01Qfez").data());
@ -49,7 +45,7 @@ SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) {
tetgenio out;
tetrahedralize(&behavior, &in, &out);
vertices.reserve(out.numberofpoints / 3);
vertices.reserve(out.numberofpoints);
for (size_t i = 0; i < out.numberofpoints; i++){
float x = static_cast<float>(out.pointlist[i * 3 + 0]);
float y = static_cast<float>(out.pointlist[i * 3 + 1]);
@ -61,19 +57,42 @@ SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) {
}
faces.reserve(out.numberoftrifaces);
triangles.reserve(out.numberoftrifaces);
for (size_t i = 0; i < out.numberoftrifaces; i++){
uint32_t a = out.trifacelist[i * 3 + 0];
uint32_t b = out.trifacelist[i * 3 + 1];
uint32_t c = out.trifacelist[i * 3 + 2];
if (out.trifacemarkerlist[i] != 0)
faces.emplace_back(Face(a, b, c));
triangles.emplace_back(Triangle(Face(a, b, c)));
}
faces.shrink_to_fit();
edges.reserve(out.numberofedges);
for (size_t i = 0; i < out.numberofedges; i++) {
uint32_t a = out.edgelist[i * 2 + 0];
uint32_t b = out.edgelist[i * 2 + 1];
float length = glm::length(vertices[a].position - vertices[b].position);
edges.emplace_back(Edge(a, b, length));
}
void SoftBody::applyOffset(const glm::vec3 &offset) {
tetrahedra.reserve(out.numberoftetrahedra);
for (size_t i = 0; i < out.numberoftetrahedra; i++){
uint32_t a = out.tetrahedronlist[i * 4 + 0];
uint32_t b = out.tetrahedronlist[i * 4 + 1];
uint32_t c = out.tetrahedronlist[i * 4 + 2];
uint32_t d = out.tetrahedronlist[i * 4 + 3];
tetrahedra.emplace_back(Tetrahedron(a, b, c, d));
}
}
void SoftBody::applyVertexOffset(const glm::vec3 &offset) {
for (Vertex& vertex : vertices){
vertex.position += offset;
}
}
void SoftBody::applyIndexOffset(int32_t offset) {
}

Loading…
Cancel
Save