283 lines
8.9 KiB
C++
283 lines
8.9 KiB
C++
#include "Object3D.h"
|
|
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <strstream>
|
|
|
|
Object3D::Object3D() = default;
|
|
|
|
Object3D::Object3D(const std::string &file_path)
|
|
{
|
|
this->loadFromOBJ(file_path);
|
|
}
|
|
|
|
bool Object3D::loadFromOBJ(const std::string& file_path)
|
|
{
|
|
std::ifstream f(file_path);
|
|
if (!f.is_open())
|
|
return false;
|
|
|
|
std::vector<float> temp_vertices;
|
|
std::vector<unsigned int> temp_indices;
|
|
std::vector<float> temp_normals;
|
|
|
|
while (!f.eof())
|
|
{
|
|
char line[128];
|
|
f.getline(line, 128);
|
|
|
|
std::string l(line);
|
|
|
|
// std::cout << "LINE: " << l << std::endl;
|
|
|
|
if (line[0] == 'f')
|
|
{
|
|
l.erase(0, 2); // Erase the "f "
|
|
size_t pos1 = 0;
|
|
std::string token1;
|
|
|
|
// Split by space
|
|
while ((pos1 = l.find(' ')) != std::string::npos)
|
|
{
|
|
token1 = l.substr(0, pos1);
|
|
int face_vert;
|
|
|
|
if (l.find("//") != std::string::npos)
|
|
{
|
|
size_t pos2 = 0;
|
|
std::string token2;
|
|
bool face = true;
|
|
|
|
while ((pos2 = token1.find("//")) != std::string::npos)
|
|
{
|
|
token2 = token1.substr(0, pos2);
|
|
// std::cout << token1 << std::endl;
|
|
|
|
if (face)
|
|
{
|
|
face_vert = std::stoi(token2) - 1;
|
|
temp_indices.push_back(face_vert);
|
|
face = false;
|
|
|
|
}
|
|
|
|
token1.erase(0, pos2 + 2);
|
|
}
|
|
|
|
// The Normal paired with the face is here
|
|
if (!face) {
|
|
// std::cout << "thisg" << std::endl;
|
|
int face_normal = std::stoi(token1) - 1;
|
|
// std::cout << "f " << face_vert + 1 << "//" << face_normal + 1 << std::endl;
|
|
|
|
bool VBO_el_found = false;
|
|
|
|
// If Vertice AND correct normal are already in VBO buffer just refernce that
|
|
for (unsigned int i = 0; i < this->VBO_buffer.size(); i += 6)
|
|
{
|
|
bool vert_equal = true;
|
|
bool normal_equal = true;
|
|
|
|
// Since each Vertice & Normal are 3 elements we need to do a little looping
|
|
for (int a = 0; a < 3; a++)
|
|
{
|
|
if (this->VBO_buffer[i + a] != temp_vertices[(face_vert * 3) + a]) {
|
|
vert_equal = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int a = 3; a < 6; a++)
|
|
{
|
|
if (this->VBO_buffer[i + a] != temp_normals[(face_normal * 3) + a - 3]) {
|
|
normal_equal = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (vert_equal && normal_equal) {
|
|
this->EBO_buffer.push_back(i / 6);
|
|
VBO_el_found = true;
|
|
}
|
|
}
|
|
|
|
// If not we need to add it to the VBO buffer
|
|
if (!VBO_el_found)
|
|
{
|
|
// Again we need to add all three elements for each
|
|
for (int a = 0; a < 3; a++)
|
|
this->VBO_buffer.push_back(temp_vertices[face_vert * 3 + a]);
|
|
|
|
|
|
for (int a = 0; a < 3; a++)
|
|
this->VBO_buffer.push_back(temp_normals[face_normal * 3 + a]);
|
|
|
|
this->EBO_buffer.push_back(this->VBO_buffer.size() / 6 - 1);
|
|
}
|
|
}
|
|
|
|
// std::cout << l << std::endl;
|
|
|
|
// temp_indices.push_back(std::stoi(token1) - 1);
|
|
|
|
}
|
|
|
|
l.erase(0, pos1 + 1);
|
|
}
|
|
|
|
// std::cout << "thing" << std::endl;
|
|
// std::cout << l << std::endl;
|
|
|
|
if (l.find("//") != std::string::npos)
|
|
{
|
|
size_t pos2 = 0;
|
|
std::string token2;
|
|
bool face = true;
|
|
int face_vert;
|
|
|
|
while ((pos2 = l.find("//")) != std::string::npos)
|
|
{
|
|
token2 = l.substr(0, pos2);
|
|
face_vert = std::stoi(token2) - 1;
|
|
|
|
|
|
if (face)
|
|
{
|
|
temp_indices.push_back(face_vert);
|
|
face = false;
|
|
}
|
|
// Else case if I want to add normals for the faces
|
|
|
|
l.erase(0, pos2 + 2);
|
|
}
|
|
|
|
// The Normal paired with the face is here
|
|
if (!face) {
|
|
// std::cout << "thisg" << std::endl;
|
|
int face_normal = std::stoi(l) - 1;
|
|
// std::cout << "f " << face_vert + 1 << "//" << face_normal + 1 << std::endl;
|
|
|
|
bool VBO_el_found = false;
|
|
|
|
// If Vertice AND correct normal are already in VBO buffer just refernce that
|
|
for (unsigned int i = 0; i < this->VBO_buffer.size(); i += 6)
|
|
{
|
|
bool vert_equal = true;
|
|
bool normal_equal = true;
|
|
|
|
// Since each Vertice & Normal are 3 elements we need to do a little looping
|
|
for (int a = 0; a < 3; a++)
|
|
{
|
|
if (this->VBO_buffer[i + a] != temp_vertices[(face_vert * 3) + a]) {
|
|
vert_equal = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int a = 3; a < 6; a++)
|
|
{
|
|
if (this->VBO_buffer[i + a] != temp_normals[(face_normal * 3) + a - 3]) {
|
|
normal_equal = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (vert_equal && normal_equal) {
|
|
this->EBO_buffer.push_back(i / 6);
|
|
VBO_el_found = true;
|
|
}
|
|
}
|
|
|
|
// If not we need to add it to the VBO buffer
|
|
if (!VBO_el_found)
|
|
{
|
|
// Again we need to add all three elements for each
|
|
for (int a = 0; a < 3; a++)
|
|
this->VBO_buffer.push_back(temp_vertices[face_vert * 3 + a]);
|
|
|
|
|
|
for (int a = 0; a < 3; a++)
|
|
this->VBO_buffer.push_back(temp_normals[face_normal * 3 + a]);
|
|
|
|
this->EBO_buffer.push_back(this->VBO_buffer.size() / 6 - 1);
|
|
}
|
|
}
|
|
|
|
// std::cout << l << std::endl;
|
|
|
|
// temp_indices.push_back(std::stoi(token1) - 1);
|
|
|
|
}
|
|
|
|
}
|
|
else if (line[0] == 'v')
|
|
{
|
|
|
|
|
|
size_t pos1 = 0;
|
|
std::string token1;
|
|
bool normal = line[1] == 'n';
|
|
|
|
if (normal)
|
|
{
|
|
l.erase(0, 3); // Get rid of the "vn "
|
|
}
|
|
else
|
|
{
|
|
l.erase(0, 2); // Get rid of the "v "
|
|
}
|
|
|
|
|
|
// Split by space
|
|
while ((pos1 = l.find(' ')) != std::string::npos)
|
|
{
|
|
token1 = l.substr(0, pos1);
|
|
|
|
if (normal)
|
|
{
|
|
temp_normals.push_back(std::stof(token1));
|
|
}
|
|
else
|
|
{
|
|
temp_vertices.push_back(std::stof(token1));
|
|
}
|
|
|
|
|
|
l.erase(0, pos1 + 1);
|
|
}
|
|
|
|
// Last point is still left after the loop
|
|
if (normal)
|
|
{
|
|
temp_normals.push_back(std::stof(l));
|
|
}
|
|
else
|
|
{
|
|
temp_vertices.push_back(std::stof(l));
|
|
}
|
|
}
|
|
}
|
|
|
|
this->vertices = temp_vertices;
|
|
this->indices = temp_indices;
|
|
this->normals = temp_normals;
|
|
|
|
return true;
|
|
}
|
|
|
|
std::vector<float> Object3D::getVBOBuffer()
|
|
{
|
|
std::vector<float> temp_VBO_buffer;
|
|
|
|
for (int i = 0; i < this->vertices.size() / 3; i++)
|
|
{
|
|
for (int a = 0; a < 3; a++)
|
|
temp_VBO_buffer.push_back(this->vertices[(i * 3) + a]);
|
|
for (int a = 0; a < 3; a++)
|
|
temp_VBO_buffer.push_back(this->normals[(i * 3) + a]);
|
|
}
|
|
|
|
return temp_VBO_buffer;
|
|
}
|
|
|