diff options
Diffstat (limited to 'examples/callback_api/main.cc')
-rw-r--r-- | examples/callback_api/main.cc | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/examples/callback_api/main.cc b/examples/callback_api/main.cc new file mode 100644 index 0000000..a7a7422 --- /dev/null +++ b/examples/callback_api/main.cc @@ -0,0 +1,166 @@ +// +// An example of how to use callback API. +// This example is minimum and incomplete. Just showing the usage of callback +// API. +// You need to implement your own Mesh data struct constrution based on this +// example in practical. +// +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + +#include <cassert> +#include <cstdio> +#include <cstdlib> +#include <fstream> +#include <iostream> +#include <sstream> + +typedef struct { + std::vector<float> vertices; + std::vector<float> normals; + std::vector<float> texcoords; + std::vector<int> v_indices; + std::vector<int> vn_indices; + std::vector<int> vt_indices; + + std::vector<tinyobj::material_t> materials; + +} MyMesh; + +void vertex_cb(void *user_data, float x, float y, float z, float w) { + MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); + printf("v[%ld] = %f, %f, %f (w %f)\n", mesh->vertices.size() / 3, x, y, z, w); + + mesh->vertices.push_back(x); + mesh->vertices.push_back(y); + mesh->vertices.push_back(z); + // Discard w +} + +void normal_cb(void *user_data, float x, float y, float z) { + MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); + printf("vn[%ld] = %f, %f, %f\n", mesh->normals.size() / 3, x, y, z); + + mesh->normals.push_back(x); + mesh->normals.push_back(y); + mesh->normals.push_back(z); +} + +void texcoord_cb(void *user_data, float x, float y, float z) { + MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); + printf("vt[%ld] = %f, %f, %f\n", mesh->texcoords.size() / 3, x, y, z); + + mesh->texcoords.push_back(x); + mesh->texcoords.push_back(y); + mesh->texcoords.push_back(z); +} + +void index_cb(void *user_data, tinyobj::index_t *indices, int num_indices) { + // NOTE: the value of each index is raw value. + // For example, the application must manually adjust the index with offset + // (e.g. v_indices.size()) when the value is negative(whic means relative + // index). + // Also, the first index starts with 1, not 0. + // See fixIndex() function in tiny_obj_loader.h for details. + // Also, 0 is set for the index value which + // does not exist in .obj + MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); + + for (int i = 0; i < num_indices; i++) { + tinyobj::index_t idx = indices[i]; + printf("idx[%ld] = %d, %d, %d\n", mesh->v_indices.size(), idx.vertex_index, + idx.normal_index, idx.texcoord_index); + + if (idx.vertex_index != 0) { + mesh->v_indices.push_back(idx.vertex_index); + } + if (idx.normal_index != 0) { + mesh->vn_indices.push_back(idx.normal_index); + } + if (idx.texcoord_index != 0) { + mesh->vt_indices.push_back(idx.texcoord_index); + } + } +} + +void usemtl_cb(void *user_data, const char *name, int material_idx) { + MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); + if ((material_idx > -1) && (material_idx < mesh->materials.size())) { + printf("usemtl. material id = %d(name = %s)\n", material_idx, + mesh->materials[material_idx].name.c_str()); + } else { + printf("usemtl. name = %s\n", name); + } +} + +void mtllib_cb(void *user_data, const tinyobj::material_t *materials, + int num_materials) { + MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); + printf("mtllib. # of materials = %d\n", num_materials); + + for (int i = 0; i < num_materials; i++) { + mesh->materials.push_back(materials[i]); + } +} + +void group_cb(void *user_data, const char **names, int num_names) { + // MyMesh *mesh = reinterpret_cast<MyMesh*>(user_data); + printf("group : name = \n"); + + for (int i = 0; i < num_names; i++) { + printf(" %s\n", names[i]); + } +} + +void object_cb(void *user_data, const char *name) { + // MyMesh *mesh = reinterpret_cast<MyMesh*>(user_data); + printf("object : name = %s\n", name); +} + +int main(int argc, char **argv) { + tinyobj::callback_t cb; + cb.vertex_cb = vertex_cb; + cb.normal_cb = normal_cb; + cb.texcoord_cb = texcoord_cb; + cb.index_cb = index_cb; + cb.usemtl_cb = usemtl_cb; + cb.mtllib_cb = mtllib_cb; + cb.group_cb = group_cb; + cb.object_cb = object_cb; + + MyMesh mesh; + std::string err; + std::string filename = "../../models/cornell_box.obj"; + if (argc > 1) { + filename = std::string(argv[1]); + } + std::ifstream ifs(filename.c_str()); + + if (ifs.fail()) { + std::cerr << "file not found." << std::endl; + return EXIT_FAILURE; + } + + tinyobj::MaterialFileReader mtlReader("../../models/"); + + bool ret = tinyobj::LoadObjWithCallback(ifs, cb, &mesh, &mtlReader, &err); + + if (!err.empty()) { + std::cerr << err << std::endl; + } + + if (!ret) { + std::cerr << "Failed to parse .obj" << std::endl; + return EXIT_FAILURE; + } + + printf("# of vertices = %ld\n", mesh.vertices.size() / 3); + printf("# of normals = %ld\n", mesh.normals.size() / 3); + printf("# of texcoords = %ld\n", mesh.texcoords.size() / 2); + printf("# of vertex indices = %ld\n", mesh.v_indices.size()); + printf("# of normal indices = %ld\n", mesh.vn_indices.size()); + printf("# of texcoord indices = %ld\n", mesh.vt_indices.size()); + printf("# of materials = %ld\n", mesh.materials.size()); + + return EXIT_SUCCESS; +} |