220 lines
5 KiB
C++
220 lines
5 KiB
C++
//
|
|
// Created by trotfunky on 30/09/2019.
|
|
//
|
|
|
|
#include "Model3D.h"
|
|
|
|
|
|
Model3D::Model3D() : vertex_count(0), face_count(0), texture_count(0), is_textured(false)
|
|
{}
|
|
|
|
Model3D::Model3D(const std::string& file_name) : Model3D()
|
|
{
|
|
load_ascii_off_file(file_name);
|
|
}
|
|
|
|
Model3D::~Model3D()
|
|
{
|
|
if (vertex_count > 0)
|
|
{
|
|
delete(vertices);
|
|
}
|
|
if (face_count > 0)
|
|
{
|
|
delete(faces);
|
|
}
|
|
|
|
if (is_textured && texture_count > 0)
|
|
{
|
|
delete(texture_coordinates);
|
|
delete(face_textures);
|
|
delete(normals);
|
|
}
|
|
}
|
|
|
|
void Model3D::draw_model()
|
|
{
|
|
if (is_textured)
|
|
{
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
|
glBindTexture(GL_TEXTURE_2D,texture->opengl_id[0]);
|
|
|
|
glColor4f(1.0f, 1.0f, 1.0f,1.00);
|
|
}
|
|
|
|
glPushMatrix();
|
|
|
|
glScalef(scaling.x,scaling.y,scaling.z);
|
|
glRotatef(rotation_angle,rotation_axis.x,rotation_axis.y,rotation_axis.z);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
for (uint32_t i = 0;i<face_count;i++)
|
|
{
|
|
Vec3i face = faces[i];
|
|
|
|
Vec3i face_texture;
|
|
if (is_textured)
|
|
{
|
|
face_texture = face_textures[i];
|
|
}
|
|
|
|
// FIXME : Find a better way to draw the three vertices
|
|
Vec3f vertex = vertices[face.x];
|
|
if (is_textured)
|
|
{
|
|
Vec2f vertex_texture = texture_coordinates[face_texture.x];
|
|
glTexCoord2f(vertex_texture.x,vertex_texture.y);
|
|
}
|
|
glVertex3f(vertex.x,vertex.y,vertex.z);
|
|
|
|
vertex = vertices[face.y];
|
|
if (is_textured)
|
|
{
|
|
Vec2f vertex_texture = texture_coordinates[face_texture.y];
|
|
glTexCoord2f(vertex_texture.x,vertex_texture.y);
|
|
}
|
|
glVertex3f(vertex.x,vertex.y,vertex.z);
|
|
|
|
vertex = vertices[face.z];
|
|
if (is_textured)
|
|
{
|
|
Vec2f vertex_texture = texture_coordinates[face_texture.z];
|
|
glTexCoord2f(vertex_texture.x,vertex_texture.y);
|
|
}
|
|
glVertex3f(vertex.x,vertex.y,vertex.z);
|
|
}
|
|
|
|
glEnd();
|
|
glPopMatrix();
|
|
|
|
if (is_textured)
|
|
{
|
|
glDisable(GL_ALPHA_TEST);
|
|
}
|
|
}
|
|
|
|
bool Model3D::load_ascii_off_file(const std::string& file_name)
|
|
{
|
|
std::fstream file_stream(file_name, std::ios_base::in);
|
|
if (file_stream.fail())
|
|
{
|
|
std::cerr << "Error opening " << file_name << std::endl;
|
|
return false;
|
|
}
|
|
|
|
std::string temp;
|
|
// Discard the first line (OFF Header)
|
|
std::getline(file_stream,temp);
|
|
|
|
// Ignore comments at the beginning of the file
|
|
while (file_stream.peek() == '#')
|
|
{
|
|
if (!std::getline(file_stream,temp))
|
|
{
|
|
std::cerr << "Error while parsing OFF comments in " << file_name << std::endl;
|
|
file_stream.close();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Parse count information (edge_count is can be safely ignored)
|
|
int edge_count;
|
|
file_stream >> vertex_count >> face_count >> edge_count;
|
|
|
|
vertices = new Vec3f[vertex_count];
|
|
faces = new Vec3i[face_count];
|
|
|
|
for (uint32_t i = 0;i<vertex_count;i++)
|
|
{
|
|
file_stream >> vertices[i];
|
|
}
|
|
|
|
for (uint32_t i = 0;i<face_count;i++)
|
|
{
|
|
// Check the the edge count of each face
|
|
file_stream >> edge_count;
|
|
if (edge_count != 3)
|
|
{
|
|
std::cerr << "Models must only have triangles !" << std::endl;
|
|
file_stream.close();
|
|
return false;
|
|
}
|
|
file_stream >> faces[i];
|
|
}
|
|
|
|
if (!file_stream)
|
|
{
|
|
std::cerr << "Unexpected EOF while reading model data in " << file_name << std::endl;
|
|
file_stream.close();
|
|
return false;
|
|
}
|
|
|
|
while(std::getline(file_stream,temp) && temp.find("EXT"));
|
|
|
|
file_stream >> texture_count;
|
|
|
|
if (texture_count > 0)
|
|
{
|
|
is_textured = true;
|
|
|
|
texture_coordinates = new Vec2f[texture_count];
|
|
face_textures = new Vec3i[face_count];
|
|
normals = new Vec3f[face_count];
|
|
|
|
// Parse U,V coordinates
|
|
for (uint32_t i = 0;i<texture_count;i++)
|
|
{
|
|
file_stream >> texture_coordinates[i];
|
|
}
|
|
// Assign U,V coordinates to vertices
|
|
for (uint32_t i = 0;i<face_count;i++)
|
|
{
|
|
file_stream >> face_textures[i];
|
|
}
|
|
|
|
for (uint32_t i=0;i<vertex_count;i++)
|
|
{
|
|
file_stream >> normals[i];
|
|
}
|
|
|
|
if (!file_stream)
|
|
{
|
|
std::cerr << "Error while parsing texture data in " << file_name << std::endl;
|
|
file_stream.close();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Model3D::assign_texture(Texture& new_texture)
|
|
{
|
|
if (is_textured)
|
|
{
|
|
texture = &new_texture;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void Model3D::set_scaling(float x_scale, float y_scale, float z_scale)
|
|
{
|
|
scaling.x = x_scale;
|
|
scaling.y = y_scale;
|
|
scaling.z = z_scale;
|
|
}
|
|
|
|
void Model3D::set_rotation(float angle, float x, float y, float z)
|
|
{
|
|
rotation_axis.x = x;
|
|
rotation_axis.y = y;
|
|
rotation_axis.z = z;
|
|
rotation_angle = angle;
|
|
}
|