Skip to content

Commit

Permalink
Merge pull request #17 from ange-yaghi/feature/I8_obj_file_writer
Browse files Browse the repository at this point in the history
[#8] : Added object file writer
  • Loading branch information
ange-yaghi committed Sep 2, 2019
2 parents 17c73ea + ef65ad9 commit 4cffbb9
Show file tree
Hide file tree
Showing 14 changed files with 19,765 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ StyleCopReport.xml
*.meta
*.obj
!demos/models/*.obj
!test/geometry/*.obj
!test/assets/geometry/*.obj
*.iobj
*.pch
*.pdb
Expand Down
18 changes: 14 additions & 4 deletions include/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@ namespace urb {
class Mesh {

This comment has been minimized.

Copy link
@chris-zeng

chris-zeng Sep 2, 2019

Is Mesh for a single triangle?

public:
struct Face {
int v1, v2, v3;
int n1, n2, n3;
int t1, t2, t3;
struct Vertex {
int v, n, t;
};

union {
struct {
int v1, n1, t1;
int v2, n2, t2;
int v3, n3, t3;
};

Vertex v[3];
};
};

public:
Expand All @@ -32,7 +42,7 @@ namespace urb {
void setTexCoord(int index, const math::Vector &t) { m_textureCoordinates[index] = t; }
int getTexCoordCount() const { return m_texCoordCount; }

Face *getFace(int index) { return &m_faces[index]; }
Face *getFace(int index) const { return &m_faces[index]; }
int getFaceCount() const { return m_faceCount; }

protected:
Expand Down
5 changes: 4 additions & 1 deletion include/mesh_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ namespace urb {
const Mesh *getMesh() const { return m_mesh; }
void setMesh(const Mesh *mesh) { m_mesh = mesh; }

math::Vector getTransformedVertex(int index);
math::Vector getTransformedVertex(int index) const;
int getVertexCount() const { return m_mesh->getVertexCount(); }

math::Vector getTransformedNormal(int index) const;
int getNormalCount() const { return m_mesh->getNormalCount(); }

This comment has been minimized.

Copy link
@chris-zeng

chris-zeng Sep 2, 2019

Perhaps it should be a Const int getNormalCount(), since the return variable should be a const as well?


protected:
const Mesh *m_mesh;

This comment has been minimized.

Copy link
@chris-zeng

chris-zeng Sep 2, 2019

And what is the difference between Mesh and Mesh instance? Is Mesh instance just a wrapper intreface for a Mesh? If so why?

};
Expand Down
10 changes: 5 additions & 5 deletions include/obj_file_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ namespace urb {
ObjFileLoader();
~ObjFileLoader();

bool loadObjFile(const char *fname);
bool loadObjFile(const std::string &fname);
bool loadObjFile(std::istream &stream);
void populateMesh(class Mesh *mesh) const;
void destroy();

unsigned int getVertexCount() const { return (unsigned int)m_vertices.size(); }
unsigned int getFaceCount() const { return (unsigned int)m_faces.size(); }
Expand All @@ -45,12 +48,9 @@ namespace urb {
ObjFace *getFace(unsigned int i) { return m_faces[i]; }
math::Vector3 *getVertex(unsigned int i) { return m_vertices[i]; }
math::Vector3 *getNormal(unsigned int i) { return m_normals[i]; }
math::Vector2 *getTexCoords(unsigned int i) { return m_texCoords[i]; }

This comment has been minimized.

Copy link
@chris-zeng

chris-zeng Sep 2, 2019

What are Vector3,2,1 ? Are there better names for theses?


void destroy();
math::Vector2 *getTexCoords(unsigned int i) { return m_texCoords[i]; }

protected:
bool loadObjFile(std::istream &stream);
bool readVertexPosition(std::stringstream &s, math::Vector3 *vertex) const;
bool readVertexNormal(std::stringstream &s, math::Vector3 *normal) const;
bool readVertexTextureCoords(std::stringstream &s, math::Vector2 *texCoords) const;
Expand Down
11 changes: 9 additions & 2 deletions include/obj_file_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "scene.h"

#include <string>
#include <fstream>
#include <ostream>

namespace urb {

Expand All @@ -14,6 +14,7 @@ namespace urb {
ObjFileWriter();
~ObjFileWriter();

void writeScene(std::ostream *stream, Scene *scene);
void writeScene(const std::string &fname, Scene *scene);

protected:
Expand All @@ -27,8 +28,14 @@ namespace urb {
void writeFace(const Mesh::Face &face);
void writeComment(const std::string &comment);

void writeIndex(int index, int offset);

protected:
std::ofstream m_outputFile;
std::ostream *m_outputStream;

int m_currentVertex;
int m_currentNormal;
int m_currentTexCoord;
};

} /* namespace urb */
Expand Down
6 changes: 6 additions & 0 deletions include/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "mesh_instance.h"

#include <vector>

namespace urb {

class Scene {
Expand All @@ -12,6 +14,10 @@ namespace urb {

int getMeshInstanceCount() const;
const MeshInstance *getMeshInstance(int index) const;
void addMeshInstance(MeshInstance *mesh);

protected:
std::vector<MeshInstance *> m_meshes;
};

} /* namespace urb */
Expand Down
1 change: 1 addition & 0 deletions project/urbanity_test/urbanity_test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<ItemGroup>
<ClCompile Include="..\..\test\fsm_test.cpp" />
<ClCompile Include="..\..\test\fsm_tests.cpp" />
<ClCompile Include="..\..\test\obj_file_tests.cpp" />
<ClCompile Include="..\..\test\pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
Expand Down
3 changes: 3 additions & 0 deletions project/urbanity_test/urbanity_test.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<ClCompile Include="..\..\test\fsm_test.cpp">
<Filter>unit\src</Filter>
</ClCompile>
<ClCompile Include="..\..\test\obj_file_tests.cpp">
<Filter>unit</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="unit">
Expand Down
7 changes: 6 additions & 1 deletion src/mesh_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ urb::MeshInstance::~MeshInstance() {
/* void */
}

urb::math::Vector urb::MeshInstance::getTransformedVertex(int index) {
urb::math::Vector urb::MeshInstance::getTransformedVertex(int index) const {
// TODO
return m_mesh->getVertex(index);
}

urb::math::Vector urb::MeshInstance::getTransformedNormal(int index) const {
// TODO
return m_mesh->getNormal(index);
}
61 changes: 55 additions & 6 deletions src/obj_file_loader.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "../include/obj_file_loader.h"

#include "../include/standard_allocator.h"
#include "../include/mesh.h"

#include <fstream>
#include <sstream>
Expand Down Expand Up @@ -47,15 +48,63 @@ urb::ObjFileLoader::~ObjFileLoader() {
// TODO: check that object is actually destroyed
}

bool urb::ObjFileLoader::loadObjFile(const char *fname) {
bool urb::ObjFileLoader::loadObjFile(const std::string &fname) {
std::ifstream inputFile(fname, std::ios::in);

if (inputFile.is_open()) {
return loadObjFile(inputFile);
if (!inputFile.is_open()) return false;

bool result = loadObjFile(inputFile);
inputFile.close();

return result;
}

void urb::ObjFileLoader::populateMesh(Mesh *mesh) const {

This comment has been minimized.

Copy link
@chris-zeng

chris-zeng Sep 2, 2019

I think I need a bit of background info on how this works.

int vertexCount = getVertexCount();
int normalCount = getNormalCount();
int texCoordCount = getTexCoordCount();
int faceCount = getFaceCount();

mesh->initialize(
vertexCount,
normalCount,
texCoordCount,
faceCount
);

for (int i = 0; i < vertexCount; i++) {
const math::Vector3 &ref = *m_vertices[i];
math::Vector v =
math::loadVector(ref.x, ref.y, ref.z);

mesh->setVertex(i, v);
}
else {
// The file could not be loaded
return false;

for (int i = 0; i < normalCount; i++) {
const math::Vector3 &ref = *m_normals[i];
math::Vector n =
math::loadVector(ref.x, ref.y, ref.z);

mesh->setNormal(i, n);
}

for (int i = 0; i < texCoordCount; i++) {
const math::Vector2 &ref = *m_texCoords[i];
math::Vector v =
math::loadVector(ref.x, ref.y);

mesh->setTexCoord(i, v);
}

for (int i = 0; i < faceCount; i++) {
const ObjFace &ref = *m_faces[i];
Mesh::Face *face = mesh->getFace(i);

for (int vi = 0; vi < 3; vi++) {
face->v[vi].v = ref.v[vi] - 1;
face->v[vi].n = ref.vn[vi] - 1;
face->v[vi].t = ref.vt[vi] - 1;
}
}
}

Expand Down
91 changes: 80 additions & 11 deletions src/obj_file_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@

#include "../include/mesh.h"

#include <fstream>

urb::ObjFileWriter::ObjFileWriter() {
// TODO
m_currentVertex = 0;
m_currentTexCoord = 0;
m_currentNormal = 0;

m_outputStream = nullptr;
}

urb::ObjFileWriter::~ObjFileWriter() {
// TODO
}

void urb::ObjFileWriter::writeScene(const std::string &fname, Scene *scene) {
m_outputFile.open(fname, std::ios::out);
if (!m_outputFile.is_open()) return;
void urb::ObjFileWriter::writeScene(std::ostream *stream, Scene *scene) {

This comment has been minimized.

Copy link
@chris-zeng

chris-zeng Sep 2, 2019

And is Scene a collection of Meshes which makes up an object?

m_outputStream = stream;

writeHeader();

Expand All @@ -22,7 +27,16 @@ void urb::ObjFileWriter::writeScene(const std::string &fname, Scene *scene) {
writeMeshInstance(meshInstance);
}

m_outputFile.close();
m_outputStream = nullptr;
}

void urb::ObjFileWriter::writeScene(const std::string &fname, Scene *scene) {
std::fstream outputFile(fname, std::ios::out);
if (!outputFile.is_open()) return;

writeScene(&outputFile, scene);

outputFile.close();
}

void urb::ObjFileWriter::writeHeader() {
Expand All @@ -31,25 +45,80 @@ void urb::ObjFileWriter::writeHeader() {
}

void urb::ObjFileWriter::writeMeshInstance(const MeshInstance *mesh) {
// TODO
int vertexCount = mesh->getVertexCount();
for (int i = 0; i < vertexCount; i++) {
writeVertex(mesh->getTransformedVertex(i));
}

int normalCount = mesh->getNormalCount();
for (int i = 0; i < normalCount; i++) {
writeNormal(mesh->getTransformedNormal(i));
}

int texCoordCount = mesh->getMesh()->getTexCoordCount();
for (int i = 0; i < texCoordCount; i++) {
writeTexCoords(mesh->getMesh()->getTexCoord(i));
}

int faceCount = mesh->getMesh()->getFaceCount();
for (int i = 0; i < faceCount; i++) {
writeFace(*mesh->getMesh()->getFace(i));
}

m_currentVertex += vertexCount;
m_currentNormal += normalCount;
m_currentTexCoord += texCoordCount;
}

void urb::ObjFileWriter::writeVertex(const math::Vector &v) {
// TODO
*m_outputStream
<< "v "
<< math::getX(v) << " "
<< math::getY(v) << " "
<< math::getZ(v)
<< std::endl;
}

void urb::ObjFileWriter::writeNormal(const math::Vector &n) {
// TODO
*m_outputStream
<< "vn "
<< math::getX(n) << " "
<< math::getY(n) << " "
<< math::getZ(n)
<< std::endl;
}

void urb::ObjFileWriter::writeTexCoords(const math::Vector &t) {
// TODO
*m_outputStream
<< "vt "
<< math::getX(t) << " "
<< math::getY(t)
<< std::endl;
}

void urb::ObjFileWriter::writeFace(const Mesh::Face &face) {
// TODO
*m_outputStream << "f ";

constexpr int VERTEX_COUNT = 3;
for (int i = 0; i < VERTEX_COUNT; i++) {
writeIndex(face.v[i].v, m_currentVertex); *m_outputStream << "/";
writeIndex(face.v[i].n, m_currentNormal); *m_outputStream << "/";
writeIndex(face.v[i].t, m_currentTexCoord);

if (i != VERTEX_COUNT - 1) {
*m_outputStream << " ";
}
}

*m_outputStream << std::endl;
}

void urb::ObjFileWriter::writeComment(const std::string &comment) {
m_outputFile << "# " << comment << "\n";
*m_outputStream << "# " << comment << "\n";
}

void urb::ObjFileWriter::writeIndex(int index, int offset) {
if (index != -1) {
*m_outputStream << (index + 1 + offset);
}
}
10 changes: 6 additions & 4 deletions src/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ urb::Scene::~Scene() {
}

int urb::Scene::getMeshInstanceCount() const {
// TODO
return 0;
return (int)m_meshes.size();
}

const urb::MeshInstance *urb::Scene::getMeshInstance(int index) const {
// TODO
return nullptr;
return m_meshes[index];
}

void urb::Scene::addMeshInstance(MeshInstance *mesh) {
m_meshes.push_back(mesh);
}
Loading

0 comments on commit 4cffbb9

Please sign in to comment.