https://github.com/sueda/eol-cloth
Revision 2323d9f6471bbf5dc63979216a3ed3c97ff3538a authored by Weidner on 13 July 2018, 15:37:58 UTC, committed by Weidner on 13 July 2018, 15:37:58 UTC
1 parent db932cf
Tip revision: 2323d9f6471bbf5dc63979216a3ed3c97ff3538a authored by Weidner on 13 July 2018, 15:37:58 UTC
Solver solving using old deform grad method. Still some bugs, but going to clean up force filling
Solver solving using old deform grad method. Still some bugs, but going to clean up force filling
Tip revision: 2323d9f
Shape.cpp
#include "Shape.h"
#include <iostream>
#ifdef EOLC_ONLINE
#include "online/GLSL.h"
#include "online/Program.h"
#endif // EOLC_ONLINE
#define TINYOBJLOADER_IMPLEMENTATION
#include "tiny_obj_loader.h"
using namespace std;
Shape::Shape() :
posBufID(0),
norBufID(0),
texBufID(0)
{
}
Shape::~Shape()
{
}
void Shape::loadMesh(const string &meshName)
{
// Load geometry
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
string errStr;
bool rc = tinyobj::LoadObj(&attrib, &shapes, &materials, &errStr, meshName.c_str());
if(!rc) {
cerr << errStr << endl;
} else {
// Some OBJ files have different indices for vertex positions, normals,
// and texture coordinates. For example, a cube corner vertex may have
// three different normals. Here, we are going to duplicate all such
// vertices.
// Loop over shapes
for(size_t s = 0; s < shapes.size(); s++) {
// Loop over faces (polygons)
size_t index_offset = 0;
for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
size_t fv = shapes[s].mesh.num_face_vertices[f];
// Loop over vertices in the face.
for(size_t v = 0; v < fv; v++) {
// access to vertex
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
posBuf.push_back(attrib.vertices[3*idx.vertex_index+0]);
posBuf.push_back(attrib.vertices[3*idx.vertex_index+1]);
posBuf.push_back(attrib.vertices[3*idx.vertex_index+2]);
if(!attrib.normals.empty()) {
norBuf.push_back(attrib.normals[3*idx.normal_index+0]);
norBuf.push_back(attrib.normals[3*idx.normal_index+1]);
norBuf.push_back(attrib.normals[3*idx.normal_index+2]);
}
if(!attrib.texcoords.empty()) {
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+0]);
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+1]);
}
}
index_offset += fv;
// per-face material (IGNORE)
shapes[s].mesh.material_ids[f];
}
}
}
}
#ifdef EOLC_ONLINE
void Shape::init()
{
// Send the position array to the GPU
glGenBuffers(1, &posBufID);
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW);
// Send the normal array to the GPU
if(!norBuf.empty()) {
glGenBuffers(1, &norBufID);
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
glBufferData(GL_ARRAY_BUFFER, norBuf.size()*sizeof(float), &norBuf[0], GL_STATIC_DRAW);
}
// Send the texture array to the GPU
if(!texBuf.empty()) {
glGenBuffers(1, &texBufID);
glBindBuffer(GL_ARRAY_BUFFER, texBufID);
glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW);
}
// Unbind the arrays
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLSL::checkError(GET_FILE_LINE);
}
void Shape::draw(const shared_ptr<Program> prog) const
{
GLSL::checkError(GET_FILE_LINE);
// Bind position buffer
int h_pos = prog->getAttribute("aPos");
glEnableVertexAttribArray(h_pos);
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
glVertexAttribPointer(h_pos, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
// Bind normal buffer
int h_nor = prog->getAttribute("aNor");
if(h_nor != -1 && norBufID != 0) {
glEnableVertexAttribArray(h_nor);
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
glVertexAttribPointer(h_nor, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
}
// Bind texcoords buffer
//int h_tex = prog->getAttribute("aTex");
//if(h_tex != -1 && texBufID != 0) {
// glEnableVertexAttribArray(h_tex);
// glBindBuffer(GL_ARRAY_BUFFER, texBufID);
// glVertexAttribPointer(h_tex, 2, GL_FLOAT, GL_FALSE, 0, (const void *)0);
//}
// Draw
int count = posBuf.size()/3; // number of indices to be rendered
glDrawArrays(GL_TRIANGLES, 0, count);
// Disable and unbind
//if(h_tex != -1) {
// glDisableVertexAttribArray(h_tex);
//}
if(h_nor != -1) {
glDisableVertexAttribArray(h_nor);
}
glDisableVertexAttribArray(h_pos);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLSL::checkError(GET_FILE_LINE);
}
#endif // EOLC_ONLINE
void Shape::exportBrender(const Eigen::Matrix4d &E, std::ofstream& outfile) const {
//Make transformation conversions
// //multiply E by each p(x,y,z) where p is point in shape
//vertex positions
for (int i = 0; i < posBuf.size(); i = i + 3) {
Eigen::Vector4d pos(posBuf[i], posBuf[i + 1], posBuf[i + 2], 1.0); //double check if it should be zero or 1
// apply transformation
Eigen::Vector4d trans_pos = E * pos;
char vert[50];
//sprintf(vert, "v %f %f %f\n", posBuf[i], posBuf[i + 1], posBuf[i + 2]);
sprintf(vert, "v %f %f %f\n", trans_pos(0), trans_pos(1), trans_pos(2));
outfile << vert;
}
//texture coordinates
for (int i = 0; i < texBuf.size(); i = i + 2) {
char vtex[50];
sprintf(vtex, "vt %f %f\n", texBuf[i], texBuf[i + 1]);
outfile << vtex;
}
//normal vectors
for (int i = 0; i < norBuf.size(); i = i + 3) {
Eigen::Vector4d nor(norBuf[i], norBuf[i + 1], norBuf[i + 2], 0.0);
// apply transformation
Eigen::Vector4d trans_nor = E * nor;
char norm[50];
sprintf(norm, "vn %f %f %f\n", trans_nor(0), trans_nor(1), trans_nor(2));
outfile << norm;
}
//face
//f vertex/texture/normal1 vertex/texture/normal2 vertex/texture/normal3
// posbuf holds all vertices. each face has 3 vertices.
for (int i = 1; i < (posBuf.size() / 3); i = i + 3) {
char face[50];
int f1, f2, f3;
f1 = i;
f2 = i + 1;
f3 = i + 2;
sprintf(face, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", f1, f1, f1, f2, f2, f2, f3, f3, f3);
outfile << face;
}
}
Computing file changes ...