diff options
author | Jeff McGlynn <jwmcglynn@google.com> | 2017-11-16 17:40:22 -0800 |
---|---|---|
committer | Jeff McGlynn <jwmcglynn@google.com> | 2017-11-16 17:40:22 -0800 |
commit | d16a940067fbc191364fc1d3e2a2d907209c9320 (patch) | |
tree | f41c4b7a0660ee902ec007954d705c5659117219 /examples/obj_sticher/obj_writer.cc | |
parent | 2de00aa4ef5314cb202427175e85f1a9f9f8bd89 (diff) | |
parent | b434c2497fcb52aa1497b84aa8aeb12bb590492d (diff) | |
download | tinyobjloader-emu-34-2-release.tar.gz |
Initial merge of upstream-master.HEADmastermainemu-master-qemu-releaseemu-35-1-releaseemu-34-releaseemu-34-3-releaseemu-34-2-releaseemu-34-2-devemu-33-releaseemu-33-devemu-32-releaseemu-32-devemu-31-stable-releaseemu-31-releaseemu-30-releaseemu-3.1-releaseemu-3.0-releaseemu-29.0-releaseemu-2.8-releaseemu-2.7-releaseemu-2.6-releaseaosp-emu-30-release
Diffstat (limited to 'examples/obj_sticher/obj_writer.cc')
-rw-r--r-- | examples/obj_sticher/obj_writer.cc | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/examples/obj_sticher/obj_writer.cc b/examples/obj_sticher/obj_writer.cc new file mode 100644 index 0000000..2c8bd7b --- /dev/null +++ b/examples/obj_sticher/obj_writer.cc @@ -0,0 +1,176 @@ +// +// Simple wavefront .obj writer +// +#include "obj_writer.h" +#include <cstdio> + +static std::string GetFileBasename(const std::string& FileName) +{ + if(FileName.find_last_of(".") != std::string::npos) + return FileName.substr(0, FileName.find_last_of(".")); + return ""; +} + +bool WriteMat(const std::string& filename, const std::vector<tinyobj::material_t>& materials) { + FILE* fp = fopen(filename.c_str(), "w"); + if (!fp) { + fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str()); + return false; + } + + for (size_t i = 0; i < materials.size(); i++) { + + tinyobj::material_t mat = materials[i]; + + fprintf(fp, "newmtl %s\n", mat.name.c_str()); + fprintf(fp, "Ka %f %f %f\n", mat.ambient[0], mat.ambient[1], mat.ambient[2]); + fprintf(fp, "Kd %f %f %f\n", mat.diffuse[0], mat.diffuse[1], mat.diffuse[2]); + fprintf(fp, "Ks %f %f %f\n", mat.specular[0], mat.specular[1], mat.specular[2]); + fprintf(fp, "Kt %f %f %f\n", mat.transmittance[0], mat.specular[1], mat.specular[2]); + fprintf(fp, "Ke %f %f %f\n", mat.emission[0], mat.emission[1], mat.emission[2]); + fprintf(fp, "Ns %f\n", mat.shininess); + fprintf(fp, "Ni %f\n", mat.ior); + // @todo { texture } + } + + fclose(fp); + + return true; +} + +bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool coordTransform) { + FILE* fp = fopen(filename.c_str(), "w"); + if (!fp) { + fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str()); + return false; + } + + std::string basename = GetFileBasename(filename); + std::string material_filename = basename + ".mtl"; + + int v_offset = 0; + int vn_offset = 0; + int vt_offset = 0; + int prev_material_id = -1; + + fprintf(fp, "mtllib %s\n", material_filename.c_str()); + + for (size_t i = 0; i < shapes.size(); i++) { + + bool has_vn = false; + bool has_vt = false; + + if (shapes[i].name.empty()) { + fprintf(fp, "g Unknown\n"); + } else { + fprintf(fp, "g %s\n", shapes[i].name.c_str()); + } + + //if (!shapes[i].material.name.empty()) { + // fprintf(fp, "usemtl %s\n", shapes[i].material.name.c_str()); + //} + + // facevarying vtx + for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) { + for (int j = 0; j < 3; j++) { + int idx = shapes[i].mesh.indices[3*k+j]; + if (coordTransform) { + fprintf(fp, "v %f %f %f\n", + shapes[i].mesh.positions[3*idx+0], + shapes[i].mesh.positions[3*idx+2], + -shapes[i].mesh.positions[3*idx+1]); + } else { + fprintf(fp, "v %f %f %f\n", + shapes[i].mesh.positions[3*idx+0], + shapes[i].mesh.positions[3*idx+1], + shapes[i].mesh.positions[3*idx+2]); + } + } + } + + // facevarying normal + if (shapes[i].mesh.normals.size() > 0) { + for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) { + for (int j = 0; j < 3; j++) { + int idx = shapes[i].mesh.indices[3*k+j]; + if (coordTransform) { + fprintf(fp, "vn %f %f %f\n", + shapes[i].mesh.normals[3*idx+0], + shapes[i].mesh.normals[3*idx+2], + -shapes[i].mesh.normals[3*idx+1]); + } else { + fprintf(fp, "vn %f %f %f\n", + shapes[i].mesh.normals[3*idx+0], + shapes[i].mesh.normals[3*idx+1], + shapes[i].mesh.normals[3*idx+2]); + } + } + } + } + if (shapes[i].mesh.normals.size() > 0) has_vn = true; + + // facevarying texcoord + if (shapes[i].mesh.texcoords.size() > 0) { + for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) { + for (int j = 0; j < 3; j++) { + int idx = shapes[i].mesh.indices[3*k+j]; + fprintf(fp, "vt %f %f\n", + shapes[i].mesh.texcoords[2*idx+0], + shapes[i].mesh.texcoords[2*idx+1]); + } + } + } + if (shapes[i].mesh.texcoords.size() > 0) has_vt = true; + + // face + for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) { + + // Face index is 1-base. + //int v0 = shapes[i].mesh.indices[3*k+0] + 1 + v_offset; + //int v1 = shapes[i].mesh.indices[3*k+1] + 1 + v_offset; + //int v2 = shapes[i].mesh.indices[3*k+2] + 1 + v_offset; + int v0 = (3*k + 0) + 1 + v_offset; + int v1 = (3*k + 1) + 1 + v_offset; + int v2 = (3*k + 2) + 1 + v_offset; + + int vt0 = (3*k + 0) + 1 + vt_offset; + int vt1 = (3*k + 1) + 1 + vt_offset; + int vt2 = (3*k + 2) + 1 + vt_offset; + + int material_id = shapes[i].mesh.material_ids[k]; + if (material_id != prev_material_id) { + std::string material_name = materials[material_id].name; + fprintf(fp, "usemtl %s\n", material_name.c_str()); + prev_material_id = material_id; + } + + if (has_vn && has_vt) { + fprintf(fp, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", + v0, vt0, v0, v1, vt1, v1, v2, vt2, v2); + } else if (has_vn && !has_vt) { + fprintf(fp, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2); + } else if (!has_vn && has_vt) { + fprintf(fp, "f %d/%d %d/%d %d/%d\n", v0, v0, v1, v1, v2, v2); + } else { + fprintf(fp, "f %d %d %d\n", v0, v1, v2); + } + + } + + v_offset += shapes[i].mesh.indices.size(); + //vn_offset += shapes[i].mesh.normals.size() / 3; + vt_offset += shapes[i].mesh.texcoords.size() / 2; + + } + + fclose(fp); + + // + // Write material file + // + bool ret = WriteMat(material_filename, materials); + + return ret; +} + + |