You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.3 KiB

#include <glm/geometric.hpp>
4 months ago
#include "soft_body.hpp"
4 months ago
#include "mesh.hpp"
#include "constraints.hpp"
#include "tetgen.h"
4 months ago
4 months ago
SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) {
tetgenbehavior behavior;
behavior.parse_commandline(std::string("pYa0.01Qfez").data());
tetgenio in;
in.numberofpoints = static_cast<int>(mesh->vertices.size());
in.pointlist = new REAL[mesh->vertices.size() * 3];
in.numberoffacets = static_cast<int>(mesh->faces.size());
in.facetlist = new tetgenio::facet[mesh->faces.size()];
in.numberofpointattributes = 3;
in.pointattributelist = new REAL[mesh->vertices.size() * 3];
for (size_t i = 0; i < mesh->vertices.size(); i++){
4 months ago
in.pointlist[i * 3 + 0] = mesh->vertices[i].position.x;
in.pointlist[i * 3 + 1] = mesh->vertices[i].position.y;
in.pointlist[i * 3 + 2] = mesh->vertices[i].position.z;
in.pointattributelist[i * 3 + 0] = (mesh->vertices[i].position.x + 1) / 2;
in.pointattributelist[i * 3 + 1] = (mesh->vertices[i].position.y + 1) / 2;
in.pointattributelist[i * 3 + 2] = (mesh->vertices[i].position.z + 1) / 2;
4 months ago
}
for (size_t i = 0; i < mesh->faces.size(); i++){
tetgenio::facet &f = in.facetlist[i];
tetgenio::polygon p;
p.numberofvertices = 3;
p.vertexlist = new int[3];
p.vertexlist[0] = static_cast<int>(mesh->faces[i].a);
p.vertexlist[1] = static_cast<int>(mesh->faces[i].b);
p.vertexlist[2] = static_cast<int>(mesh->faces[i].c);
f.numberofholes = 0;
f.holelist = nullptr;
f.numberofpolygons = 1;
f.polygonlist = new tetgenio::polygon[1];
f.polygonlist[0] = p;
}
tetgenio out;
tetrahedralize(&behavior, &in, &out);
vertices.reserve(out.numberofpoints);
4 months ago
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]);
float z = static_cast<float>(out.pointlist[i * 3 + 2]);
float r = static_cast<float>(out.pointattributelist[i * 3 + 0]);
float g = static_cast<float>(out.pointattributelist[i * 3 + 1]);
float b = static_cast<float>(out.pointattributelist[i * 3 + 2]);
vertices.emplace_back(Vertex({x, y, z}, {r, g, b}));
}
faces.reserve(out.numberoftrifaces);
triangles.reserve(out.numberoftrifaces);
4 months ago
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];
4 months ago
if (out.trifacemarkerlist[i] != 0)
4 months ago
faces.emplace_back(Face(a, b, c));
triangles.emplace_back(Triangle(Face(a, b, c)));
4 months ago
}
faces.shrink_to_fit();
4 months ago
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));
}
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));
}
4 months ago
}
4 months ago
void SoftBody::applyVertexOffset(const glm::vec3 &offset) {
4 months ago
for (Vertex& vertex : vertices){
vertex.position += offset;
}
}
void SoftBody::applyIndexOffset(int32_t offset) {
}