summaryrefslogtreecommitdiff
path: root/wave-sim/src/graphics/shape.cpp
diff options
context:
space:
mode:
authorSebastian Park <SebPark03@gmail.com>2024-04-10 02:51:43 -0400
committerSebastian Park <SebPark03@gmail.com>2024-04-10 02:51:43 -0400
commit0b0629450e2553b2f890094290528b565d607e38 (patch)
tree16d34a6123f3e50153b5fcd6466de5057cc960a0 /wave-sim/src/graphics/shape.cpp
parentad313dcf57437ec0d40dddbce622a11c2bc2bc23 (diff)
parent47cd8a592ecad52c1b01f27d23476c0a5afeb7f1 (diff)
Merge branch 'shaders'
Diffstat (limited to 'wave-sim/src/graphics/shape.cpp')
-rw-r--r--wave-sim/src/graphics/shape.cpp337
1 files changed, 337 insertions, 0 deletions
diff --git a/wave-sim/src/graphics/shape.cpp b/wave-sim/src/graphics/shape.cpp
new file mode 100644
index 0000000..e59e009
--- /dev/null
+++ b/wave-sim/src/graphics/shape.cpp
@@ -0,0 +1,337 @@
+#include "shape.h"
+
+#include <iostream>
+
+#include "graphics/shader.h"
+
+using namespace Eigen;
+
+Shape::Shape()
+ : m_tetVao(-1),
+ m_numSurfaceVertices(),
+ m_verticesSize(),
+ m_modelMatrix(Eigen::Matrix4f::Identity()),
+ m_wireframe(false)
+{
+}
+
+//void Shape::init(const std::vector<Eigen::Vector3d> &vertices, const std::vector<Eigen::Vector3d> &normals, const std::vector<Eigen::Vector3i> &triangles)
+//{
+// if(vertices.size() != normals.size()) {
+// std::cerr << "Vertices and normals are not the same size" << std::endl;
+// return;
+// }
+// glGenBuffers(1, &m_surfaceVbo);
+// glGenBuffers(1, &m_surfaceIbo);
+// glGenVertexArrays(1, &m_surfaceVao);
+
+// glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo);
+// glBufferData(GL_ARRAY_BUFFER, sizeof(double) * vertices.size() * 3 * 2, nullptr, GL_DYNAMIC_DRAW);
+// glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(double) * vertices.size() * 3, static_cast<const void *>(vertices.data()));
+// glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * vertices.size() * 3, sizeof(double) * vertices.size() * 3, static_cast<const void *>(normals.data()));
+// glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceIbo);
+// glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 3 * triangles.size(), static_cast<const void *>(triangles.data()), GL_STATIC_DRAW);
+// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+// glBindVertexArray(m_surfaceVao);
+// glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo);
+// glEnableVertexAttribArray(0);
+// glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, static_cast<GLvoid *>(0));
+// glEnableVertexAttribArray(1);
+// glVertexAttribPointer(1, 3, GL_DOUBLE, GL_FALSE, 0, reinterpret_cast<GLvoid *>(sizeof(double) * vertices.size() * 3));
+// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceIbo);
+// glBindVertexArray(0);
+// glBindBuffer(GL_ARRAY_BUFFER, 0);
+// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+// m_numSurfaceVertices = triangles.size() * 3;
+// m_verticesSize = vertices.size();
+// m_faces = triangles;
+//}
+
+void Shape::init(const std::vector<Eigen::Vector3d> &vertices, const std::vector<Eigen::Vector3i> &triangles)
+{
+ std::vector<Eigen::Vector3d> verts;
+ std::vector<Eigen::Vector3d> normals;
+ std::vector<Eigen::Vector3i> faces;
+ std::vector<Eigen::Vector3d> forces;
+ verts.reserve(triangles.size() * 3);
+ normals.reserve(triangles.size() * 3);
+ for(auto& f : triangles) {
+ auto& v1 = vertices[f[0]];
+ auto& v2 = vertices[f[1]];
+ auto& v3 = vertices[f[2]];
+ auto& e1 = v2 - v1;
+ auto& e2 = v3 - v1;
+ auto n = e1.cross(e2);
+ int s = verts.size();
+ faces.push_back(Eigen::Vector3i(s, s + 1, s + 2));
+ normals.push_back(n);
+ normals.push_back(n);
+ normals.push_back(n);
+ verts.push_back(v1);
+ verts.push_back(v2);
+ verts.push_back(v3);
+ forces.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
+ forces.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
+ forces.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
+ }
+ glGenBuffers(1, &m_surfaceVbo);
+ glGenBuffers(1, &m_surfaceIbo);
+ glGenVertexArrays(1, &m_surfaceVao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(double) * verts.size() * 3 * 3, nullptr, GL_DYNAMIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(double) * verts.size() * 3, static_cast<const void *>(verts.data()));
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * verts.size() * 3, sizeof(double) * verts.size() * 3, static_cast<const void *>(normals.data()));
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * verts.size() * 3 * 2, sizeof(double) * verts.size() * 3, static_cast<const void *>(forces.data()));
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceIbo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 3 * faces.size(), static_cast<const void *>(faces.data()), GL_STATIC_DRAW);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glBindVertexArray(m_surfaceVao);
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, static_cast<GLvoid *>(0));
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 3, GL_DOUBLE, GL_FALSE, 0, reinterpret_cast<GLvoid *>(sizeof(double) * verts.size() * 3));
+ glEnableVertexAttribArray(2);
+ glVertexAttribPointer(2, 3, GL_DOUBLE, GL_FALSE, 0, reinterpret_cast<GLvoid *>(sizeof(double) * verts.size() * 3 * 2));
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceIbo);
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ m_numSurfaceVertices = faces.size() * 3;
+ m_verticesSize = vertices.size();
+ m_faces = triangles;
+
+ if (vertices.size() > 4) { //shape
+ m_red = 0.93;
+ m_green = 0.8;
+ m_blue = 1.f;
+ m_alpha = 1.f;
+ } else { //ground
+ m_red = 1;
+ m_green = 1;
+ m_blue = 1;
+ m_alpha = 1.f;
+ }
+ m_force = 0;
+// m_red = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
+// m_blue = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
+// m_green = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
+// m_alpha = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
+}
+
+void Shape::setColor(float r, float g, float b) {
+ m_red = r;
+ m_green = g;
+ m_blue = b;
+}
+
+void Shape::init(const std::vector<Eigen::Vector3d> &vertices, const std::vector<Eigen::Vector3i> &triangles, const std::vector<Eigen::Vector4i> &tetIndices)
+{
+ init(vertices, triangles);
+
+ std::vector<Eigen::Vector2i> lines;
+ for(Vector4i tet : tetIndices) {
+ lines.emplace_back(tet[0], tet[1]);
+ lines.emplace_back(tet[0], tet[2]);
+ lines.emplace_back(tet[0], tet[3]);
+ lines.emplace_back(tet[1], tet[2]);
+ lines.emplace_back(tet[1], tet[3]);
+ lines.emplace_back(tet[2], tet[3]);
+ }
+ glGenBuffers(1, &m_tetVbo);
+ glGenBuffers(1, &m_tetIbo);
+ glGenVertexArrays(1, &m_tetVao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_tetVbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(double) * vertices.size() * 3, vertices.data(), GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_tetIbo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 2 * lines.size(), static_cast<const void *>(lines.data()), GL_STATIC_DRAW);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glBindVertexArray(m_tetVao);
+ glBindBuffer(GL_ARRAY_BUFFER, m_tetVbo);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, static_cast<GLvoid *>(0));
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_tetIbo);
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ m_numTetVertices = lines.size() * 2;
+}
+
+void Shape::setVertices(const std::vector<Eigen::Vector3d> &vertices)
+{
+ if(vertices.size() != m_verticesSize) {
+ std::cerr << "You can't set vertices to a vector that is a different length that what shape was inited with" << std::endl;
+ return;
+ }
+ std::vector<Eigen::Vector3d> verts;
+ std::vector<Eigen::Vector3d> normals;
+ std::vector<Eigen::Vector3d> forces;
+ verts.reserve(m_faces.size() * 3);
+ normals.reserve(m_faces.size() * 3);
+ for(auto& f : m_faces) {
+ auto& v1 = vertices[f[0]];
+ auto& v2 = vertices[f[1]];
+ auto& v3 = vertices[f[2]];
+ auto& e1 = v2 - v1;
+ auto& e2 = v3 - v1;
+ auto n = e1.cross(e2);
+ normals.push_back(n);
+ normals.push_back(n);
+ normals.push_back(n);
+ verts.push_back(v1);
+ verts.push_back(v2);
+ verts.push_back(v3);
+ forces.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
+ forces.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
+ forces.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(double) * verts.size() * 3, static_cast<const void *>(verts.data()));
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * verts.size() * 3, sizeof(double) * verts.size() * 3, static_cast<const void *>(normals.data()));
+ if(m_tetVao != static_cast<GLuint>(-1)) {
+ glBindBuffer(GL_ARRAY_BUFFER, m_tetVbo);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(double) * vertices.size() * 3, static_cast<const void *>(vertices.data()));
+ }
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * vertices.size() * 3 * 2, sizeof(double) * vertices.size() * 3 * 2, static_cast<const void *>(forces.data()));
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void Shape::setVerticesF(const std::vector<Eigen::Vector3d> &vertices, const std::vector<Eigen::Vector3d> &forces) {
+ if(vertices.size() != m_verticesSize) {
+ std::cerr << "You can't set vertices to a vector that is a different length that what shape was inited with" << std::endl;
+ return;
+ }
+ if(vertices.size() != forces.size()) {
+ std::cerr << "Vertices and forces are not the same size" << std::endl;
+ return;
+ }
+ std::vector<Eigen::Vector3d> verts;
+ std::vector<Eigen::Vector3d> normals;
+ std::vector<Eigen::Vector3d> glForces;
+ verts.reserve(m_faces.size() * 3);
+ normals.reserve(m_faces.size() * 3);
+ glForces.reserve(m_faces.size() * 3);
+
+ double maxForceNorm = 500;
+ for(auto& f : m_faces) {
+ auto& v1 = vertices[f[0]];
+ auto& v2 = vertices[f[1]];
+ auto& v3 = vertices[f[2]];
+// auto& f1 = forces[f[0]].normalized();
+// auto& f2 = forces[f[1]].normalized();
+// auto& f3 = forces[f[2]].normalized();
+ auto& f1 = forces[f[0]];
+ auto& f2 = forces[f[1]];
+ auto& f3 = forces[f[2]];
+ maxForceNorm = std::max(f1.norm(), maxForceNorm);
+ maxForceNorm = std::max(f2.norm(), maxForceNorm);
+ maxForceNorm = std::max(f3.norm(), maxForceNorm);
+ auto& e1 = v2 - v1;
+ auto& e2 = v3 - v1;
+ auto n = e1.cross(e2);
+ normals.push_back(n);
+ normals.push_back(n);
+ normals.push_back(n);
+ verts.push_back(v1);
+ verts.push_back(v2);
+ verts.push_back(v3);
+ glForces.push_back(f1);
+ glForces.push_back(f2);
+ glForces.push_back(f3); // Cool effect if it's v1, v2, v3 instead
+ }
+// std::cout << maxForceNorm << std::endl;
+ for(Eigen::Vector3d &f : glForces) {
+ f /= maxForceNorm;
+ f = f.cwiseAbs();
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(double) * verts.size() * 3, static_cast<const void *>(verts.data()));
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * verts.size() * 3, sizeof(double) * verts.size() * 3, static_cast<const void *>(normals.data()));
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * verts.size() * 3 * 2, sizeof(double) * verts.size() * 3, static_cast<const void *>(glForces.data()));
+ if(m_tetVao != static_cast<GLuint>(-1)) {
+ glBindBuffer(GL_ARRAY_BUFFER, m_tetVbo);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(double) * vertices.size() * 3, static_cast<const void *>(vertices.data()));
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void Shape::setModelMatrix(const Eigen::Affine3f &model)
+{
+ m_modelMatrix = model.matrix();
+}
+
+void Shape::toggleWireframe()
+{
+ m_wireframe = !m_wireframe;
+}
+
+void Shape::toggleForce() {
+ m_force = std::abs(m_force - 1);
+}
+
+void Shape::setVertices(const std::vector<Eigen::Vector3d> &vertices, const std::vector<Eigen::Vector3d> &normals)
+{
+ std::vector<Eigen::Vector3d> forces;
+ if(vertices.size() != normals.size()) {
+ std::cerr << "Vertices and normals are not the same size" << std::endl;
+ return;
+ }
+ if(vertices.size() != m_verticesSize) {
+ std::cerr << "You can't set vertices to a vector that is a different length that what shape was inited with" << std::endl;
+ return;
+ }
+ for(Eigen::Vector3d v : vertices) {
+ forces.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(double) * vertices.size() * 3, static_cast<const void *>(vertices.data()));
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * vertices.size() * 3, sizeof(double) * vertices.size() * 3, static_cast<const void *>(normals.data()));
+ glBufferSubData(GL_ARRAY_BUFFER, sizeof(double) * vertices.size() * 3 * 2, sizeof(double) * vertices.size() * 3, static_cast<const void *>(forces.data()));
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void Shape::draw(Shader *shader)
+{
+ Eigen::Matrix3f m3 = m_modelMatrix.topLeftCorner(3, 3);
+ Eigen::Matrix3f inverseTransposeModel = m3.inverse().transpose();
+
+ if(m_wireframe && m_tetVao != static_cast<GLuint>(-1)) {
+ shader->setUniform("wire", 1);
+ shader->setUniform("model", m_modelMatrix);
+ shader->setUniform("inverseTransposeModel", inverseTransposeModel);
+ shader->setUniform("red", 1);
+ shader->setUniform("green", 1);
+ shader->setUniform("blue", 1);
+ shader->setUniform("alpha", 1);
+ shader->setUniform("displayForce", m_force);
+ glBindVertexArray(m_tetVao);
+ glDrawElements(GL_LINES, m_numTetVertices, GL_UNSIGNED_INT, reinterpret_cast<GLvoid *>(0));
+ glBindVertexArray(0);
+ } else {
+ shader->setUniform("wire", 0);
+ shader->setUniform("model", m_modelMatrix);
+ shader->setUniform("inverseTransposeModel", inverseTransposeModel);
+ shader->setUniform("red", m_red);
+ shader->setUniform("green", m_green);
+ shader->setUniform("blue", m_blue);
+ shader->setUniform("alpha", m_alpha);
+ shader->setUniform("displayForce", m_force);
+ glBindVertexArray(m_surfaceVao);
+ glDrawElements(GL_TRIANGLES, m_numSurfaceVertices, GL_UNSIGNED_INT, reinterpret_cast<GLvoid *>(0));
+ glBindVertexArray(0);
+ }
+}