Support parsing w element of vertex coordinate, and also third element of texture coordinates. Fixes #88.

This commit is contained in:
Syoyo Fujita
2016-07-27 16:16:51 +09:00
parent d496d8eab6
commit 75e64cd47a
2 changed files with 32 additions and 20 deletions

View File

@@ -27,13 +27,14 @@ typedef struct {
} MyMesh; } MyMesh;
void vertex_cb(void *user_data, float x, float y, float z) { void vertex_cb(void *user_data, float x, float y, float z, float w) {
MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data);
printf("v[%ld] = %f, %f, %f\n", mesh->vertices.size() / 3, x, y, z); 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(x);
mesh->vertices.push_back(y); mesh->vertices.push_back(y);
mesh->vertices.push_back(z); mesh->vertices.push_back(z);
// Discard w
} }
void normal_cb(void *user_data, float x, float y, float z) { void normal_cb(void *user_data, float x, float y, float z) {
@@ -45,12 +46,13 @@ void normal_cb(void *user_data, float x, float y, float z) {
mesh->normals.push_back(z); mesh->normals.push_back(z);
} }
void texcoord_cb(void *user_data, float x, float y) { void texcoord_cb(void *user_data, float x, float y, float z) {
MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data); MyMesh *mesh = reinterpret_cast<MyMesh *>(user_data);
printf("vt[%ld] = %f, %f\n", mesh->texcoords.size() / 2, x, y); printf("vt[%ld] = %f, %f, %f\n", mesh->texcoords.size() / 3, x, y, z);
mesh->texcoords.push_back(x); mesh->texcoords.push_back(x);
mesh->texcoords.push_back(y); mesh->texcoords.push_back(y);
mesh->texcoords.push_back(z);
} }
void index_cb(void *user_data, tinyobj::index_t *indices, int num_indices) { void index_cb(void *user_data, tinyobj::index_t *indices, int num_indices) {
@@ -128,7 +130,11 @@ int main(int argc, char **argv) {
MyMesh mesh; MyMesh mesh;
std::string err; std::string err;
std::ifstream ifs("../../models/cornell_box.obj"); std::string filename = "../../models/cornell_box.obj";
if (argc > 1) {
filename = std::string(argv[1]);
}
std::ifstream ifs(filename.c_str());
if (ifs.fail()) { if (ifs.fail()) {
std::cerr << "file not found." << std::endl; std::cerr << "file not found." << std::endl;

View File

@@ -148,9 +148,12 @@ typedef struct {
} attrib_t; } attrib_t;
typedef struct callback_t_ { typedef struct callback_t_ {
void (*vertex_cb)(void *user_data, float x, float y, float z); // W is optional and set to 1 if there is no `w` item in `v` line
void (*vertex_cb)(void *user_data, float x, float y, float z, float w);
void (*normal_cb)(void *user_data, float x, float y, float z); void (*normal_cb)(void *user_data, float x, float y, float z);
void (*texcoord_cb)(void *user_data, float x, float y);
// y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in `vt` line.
void (*texcoord_cb)(void *user_data, float x, float y, float z);
// called per 'f' line. num_indices is the number of face indices(e.g. 3 for // called per 'f' line. num_indices is the number of face indices(e.g. 3 for
// triangle, 4 for quad) // triangle, 4 for quad)
@@ -443,18 +446,13 @@ fail:
return false; return false;
} }
static inline float parseFloat(const char **token) { static inline float parseFloat(const char **token, double default_value = 0.0) {
(*token) += strspn((*token), " \t"); (*token) += strspn((*token), " \t");
#ifdef TINY_OBJ_LOADER_OLD_FLOAT_PARSER
float f = static_cast<float>(atof(*token));
(*token) += strcspn((*token), " \t\r");
#else
const char *end = (*token) + strcspn((*token), " \t\r"); const char *end = (*token) + strcspn((*token), " \t\r");
double val = 0.0; double val = default_value;
tryParseDouble((*token), end, &val); tryParseDouble((*token), end, &val);
float f = static_cast<float>(val); float f = static_cast<float>(val);
(*token) = end; (*token) = end;
#endif
return f; return f;
} }
@@ -470,6 +468,14 @@ static inline void parseFloat3(float *x, float *y, float *z,
(*z) = parseFloat(token); (*z) = parseFloat(token);
} }
static inline void parseV(float *x, float *y, float *z, float *w,
const char **token) {
(*x) = parseFloat(token);
(*y) = parseFloat(token);
(*z) = parseFloat(token);
(*w) = parseFloat(token, 1.0);
}
static tag_sizes parseTagTriple(const char **token) { static tag_sizes parseTagTriple(const char **token) {
tag_sizes ts; tag_sizes ts;
@@ -1348,10 +1354,10 @@ bool LoadObjWithCallback(void *user_data, const callback_t &callback,
// vertex // vertex
if (token[0] == 'v' && IS_SPACE((token[1]))) { if (token[0] == 'v' && IS_SPACE((token[1]))) {
token += 2; token += 2;
float x, y, z; float x, y, z, w; // w is optional. default = 1.0
parseFloat3(&x, &y, &z, &token); parseV(&x, &y, &z, &w, &token);
if (callback.vertex_cb) { if (callback.vertex_cb) {
callback.vertex_cb(user_data, x, y, z); callback.vertex_cb(user_data, x, y, z, w);
} }
continue; continue;
} }
@@ -1370,10 +1376,10 @@ bool LoadObjWithCallback(void *user_data, const callback_t &callback,
// texcoord // texcoord
if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) {
token += 3; token += 3;
float x, y; float x, y, z; // y and z are optional. default = 0.0
parseFloat2(&x, &y, &token); parseFloat3(&x, &y, &z, &token);
if (callback.texcoord_cb) { if (callback.texcoord_cb) {
callback.texcoord_cb(user_data, x, y); callback.texcoord_cb(user_data, x, y, z);
} }
continue; continue;
} }