1+ //
2+ // An example of how to use callback API.
3+ // This example is minimum and incomplete. Just showing the usage of callback
4+ // API.
5+ // You need to implement your own Mesh data struct constrution based on this
6+ // example in practical.
7+ //
18#define TINYOBJLOADER_IMPLEMENTATION
29#include " tiny_obj_loader.h"
310
11+ #include < cassert>
412#include < cstdio>
513#include < cstdlib>
6- #include < cassert >
14+ #include < fstream >
715#include < iostream>
816#include < sstream>
9- #include < fstream>
1017
11- typedef struct
12- {
18+ typedef struct {
1319 std::vector<float > vertices;
1420 std::vector<float > normals;
1521 std::vector<float > texcoords;
16- std::vector<int > v_indices;
17- std::vector<int > vn_indices;
18- std::vector<int > vt_indices;
22+ std::vector<int > v_indices;
23+ std::vector<int > vn_indices;
24+ std::vector<int > vt_indices;
1925
2026 std::vector<tinyobj::material_t > materials;
2127
2228} MyMesh;
2329
24- void vertex_cb (void *user_data, float x, float y, float z)
25- {
26- MyMesh *mesh = reinterpret_cast <MyMesh*>(user_data);
30+ void vertex_cb (void *user_data, float x, float y, float z) {
31+ MyMesh *mesh = reinterpret_cast <MyMesh *>(user_data);
2732 printf (" v[%ld] = %f, %f, %f\n " , mesh->vertices .size () / 3 , x, y, z);
2833
2934 mesh->vertices .push_back (x);
3035 mesh->vertices .push_back (y);
3136 mesh->vertices .push_back (z);
3237}
3338
34- void normal_cb (void *user_data, float x, float y, float z)
35- {
36- MyMesh *mesh = reinterpret_cast <MyMesh*>(user_data);
39+ void normal_cb (void *user_data, float x, float y, float z) {
40+ MyMesh *mesh = reinterpret_cast <MyMesh *>(user_data);
3741 printf (" vn[%ld] = %f, %f, %f\n " , mesh->normals .size () / 3 , x, y, z);
3842
3943 mesh->normals .push_back (x);
4044 mesh->normals .push_back (y);
4145 mesh->normals .push_back (z);
4246}
4347
44- void texcoord_cb (void *user_data, float x, float y)
45- {
46- MyMesh *mesh = reinterpret_cast <MyMesh*>(user_data);
48+ void texcoord_cb (void *user_data, float x, float y) {
49+ MyMesh *mesh = reinterpret_cast <MyMesh *>(user_data);
4750 printf (" vt[%ld] = %f, %f\n " , mesh->texcoords .size () / 2 , x, y);
4851
4952 mesh->texcoords .push_back (x);
5053 mesh->texcoords .push_back (y);
5154}
5255
53- void index_cb (void *user_data, int v_idx, int vn_idx, int vt_idx)
54- {
55- // NOTE: the value of each index is raw value.
56+ void index_cb (void *user_data, tinyobj::index_t *indices, int num_indices) {
57+ // NOTE: the value of each index is raw value.
5658 // For example, the application must manually adjust the index with offset
57- // (e.g. v_indices.size()) when the value is negative(relative index).
59+ // (e.g. v_indices.size()) when the value is negative(whic means relative
60+ // index).
61+ // Also, the first index starts with 1, not 0.
5862 // See fixIndex() function in tiny_obj_loader.h for details.
59- // Also, -2147483648(0x80000000) is set for the index value which does not exist in .obj
60- MyMesh *mesh = reinterpret_cast <MyMesh*>(user_data);
61- printf (" idx[%ld] = %d, %d, %d\n " , mesh->v_indices .size (), v_idx, vn_idx, vt_idx);
62-
63- if (v_idx != 0x80000000 ) {
64- mesh->v_indices .push_back (v_idx);
65- }
66- if (vn_idx != 0x80000000 ) {
67- mesh->vn_indices .push_back (vn_idx);
68- }
69- if (vt_idx != 0x80000000 ) {
70- mesh->vt_indices .push_back (vt_idx);
63+ // Also, -2147483648(0x80000000 = -INT_MAX) is set for the index value which
64+ // does not exist in .obj
65+ MyMesh *mesh = reinterpret_cast <MyMesh *>(user_data);
66+
67+ for (int i = 0 ; i < num_indices; i++) {
68+ tinyobj::index_t idx = indices[i];
69+ printf (" idx[%ld] = %d, %d, %d\n " , mesh->v_indices .size (), idx.vertex_index ,
70+ idx.normal_index , idx.texcoord_index );
71+
72+ if (idx.vertex_index != 0x80000000 ) {
73+ mesh->v_indices .push_back (idx.vertex_index );
74+ }
75+ if (idx.normal_index != 0x80000000 ) {
76+ mesh->vn_indices .push_back (idx.normal_index );
77+ }
78+ if (idx.texcoord_index != 0x80000000 ) {
79+ mesh->vt_indices .push_back (idx.texcoord_index );
80+ }
7181 }
7282}
7383
74- void usemtl_cb (void *user_data, const char * name, int material_idx)
75- {
76- MyMesh *mesh = reinterpret_cast <MyMesh*>(user_data);
84+ void usemtl_cb (void *user_data, const char *name, int material_idx) {
85+ MyMesh *mesh = reinterpret_cast <MyMesh *>(user_data);
7786 if ((material_idx > -1 ) && (material_idx < mesh->materials .size ())) {
78- printf (" usemtl. material id = %d(name = %s)\n " , material_idx, mesh->materials [material_idx].name .c_str ());
87+ printf (" usemtl. material id = %d(name = %s)\n " , material_idx,
88+ mesh->materials [material_idx].name .c_str ());
7989 } else {
8090 printf (" usemtl. name = %s\n " , name);
8191 }
8292}
8393
84- void mtllib_cb (void *user_data, const tinyobj::material_t *materials, int num_materials)
85- {
86- MyMesh *mesh = reinterpret_cast <MyMesh*>(user_data);
94+ void mtllib_cb (void *user_data, const tinyobj::material_t *materials,
95+ int num_materials) {
96+ MyMesh *mesh = reinterpret_cast <MyMesh *>(user_data);
8797 printf (" mtllib. # of materials = %d\n " , num_materials);
8898
8999 for (int i = 0 ; i < num_materials; i++) {
90100 mesh->materials .push_back (materials[i]);
91101 }
92102}
93103
94- void group_cb (void *user_data, const char **names, int num_names)
95- {
96- // MyMesh *mesh = reinterpret_cast<MyMesh*>(user_data);
104+ void group_cb (void *user_data, const char **names, int num_names) {
105+ // MyMesh *mesh = reinterpret_cast<MyMesh*>(user_data);
97106 printf (" group : name = \n " );
98107
99108 for (int i = 0 ; i < num_names; i++) {
100109 printf (" %s\n " , names[i]);
101110 }
102111}
103112
104- void object_cb (void *user_data, const char *name)
105- {
106- // MyMesh *mesh = reinterpret_cast<MyMesh*>(user_data);
113+ void object_cb (void *user_data, const char *name) {
114+ // MyMesh *mesh = reinterpret_cast<MyMesh*>(user_data);
107115 printf (" object : name = %s\n " , name);
108-
109116}
110117
111- int
112- main (int argc, char ** argv)
113- {
118+ int main (int argc, char **argv) {
114119 tinyobj::callback_t cb;
115120 cb.vertex_cb = vertex_cb;
116121 cb.normal_cb = normal_cb;
@@ -131,7 +136,7 @@ main(int argc, char** argv)
131136 }
132137
133138 tinyobj::MaterialFileReader mtlReader (" ../../models/" );
134-
139+
135140 bool ret = tinyobj::LoadObjWithCallback (&mesh, cb, &err, &ifs, &mtlReader);
136141
137142 if (!err.empty ()) {
0 commit comments