@@ -23,6 +23,7 @@ THE SOFTWARE.
2323*/
2424
2525//
26+ // version 1.1.0 : Support parsing vertex color(#144)
2627// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138)
2728// version 1.0.7 : Support multiple tex options(#126)
2829// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124)
@@ -230,6 +231,7 @@ typedef struct {
230231 std::vector<real_t > vertices; // 'v'
231232 std::vector<real_t > normals; // 'vn'
232233 std::vector<real_t > texcoords; // 'vt'
234+ std::vector<real_t > colors; // extension: vertex colors
233235} attrib_t ;
234236
235237typedef struct callback_t_ {
@@ -602,6 +604,19 @@ static inline real_t parseReal(const char **token, double default_value = 0.0) {
602604 return f;
603605}
604606
607+ static inline bool parseReal (const char **token, real_t *out) {
608+ (*token) += strspn ((*token), " \t " );
609+ const char *end = (*token) + strcspn ((*token), " \t\r " );
610+ double val;
611+ bool ret = tryParseDouble ((*token), end, &val);
612+ if (ret) {
613+ real_t f = static_cast <real_t >(val);
614+ (*out) = f;
615+ }
616+ (*token) = end;
617+ return ret;
618+ }
619+
605620static inline void parseReal2 (real_t *x, real_t *y, const char **token,
606621 const double default_x = 0.0 ,
607622 const double default_y = 0.0 ) {
@@ -629,6 +644,23 @@ static inline void parseV(real_t *x, real_t *y, real_t *z, real_t *w,
629644 (*w) = parseReal (token, default_w);
630645}
631646
647+ // Extension: parse vertex with colors(6 items)
648+ static inline bool parseVertexWithColor (real_t *x, real_t *y, real_t *z, real_t *r,
649+ real_t *g, real_t *b,
650+ const char **token, const double default_x = 0.0 ,
651+ const double default_y = 0.0 ,
652+ const double default_z = 0.0 ) {
653+ (*x) = parseReal (token, default_x);
654+ (*y) = parseReal (token, default_y);
655+ (*z) = parseReal (token, default_z);
656+
657+ (*r) = parseReal (token, 1.0 );
658+ (*g) = parseReal (token, 1.0 );
659+ (*b) = parseReal (token, 1.0 );
660+
661+ return true ;
662+ }
663+
632664static inline bool parseOnOff (const char **token, bool default_value = true ) {
633665 (*token) += strspn ((*token), " \t " );
634666 const char *end = (*token) + strcspn ((*token), " \t\r " );
@@ -1421,6 +1453,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
14211453 attrib->vertices .clear ();
14221454 attrib->normals .clear ();
14231455 attrib->texcoords .clear ();
1456+ attrib->colors .clear ();
14241457 shapes->clear ();
14251458
14261459 std::stringstream errss;
@@ -1453,6 +1486,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
14531486 std::vector<real_t > v;
14541487 std::vector<real_t > vn;
14551488 std::vector<real_t > vt;
1489+ std::vector<real_t > vc;
14561490 std::vector<tag_t > tags;
14571491 std::vector<std::vector<vertex_index> > faceGroup;
14581492 std::string name;
@@ -1495,10 +1529,15 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
14951529 if (token[0 ] == ' v' && IS_SPACE ((token[1 ]))) {
14961530 token += 2 ;
14971531 real_t x, y, z;
1498- parseReal3 (&x, &y, &z, &token);
1532+ real_t r, g, b;
1533+ parseVertexWithColor (&x, &y, &z, &r, &g, &b, &token);
14991534 v.push_back (x);
15001535 v.push_back (y);
15011536 v.push_back (z);
1537+
1538+ vc.push_back (r);
1539+ vc.push_back (g);
1540+ vc.push_back (b);
15021541 continue ;
15031542 }
15041543
@@ -1733,6 +1772,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
17331772 attrib->vertices .swap (v);
17341773 attrib->normals .swap (vn);
17351774 attrib->texcoords .swap (vt);
1775+ attrib->colors .swap (vc);
17361776
17371777 return true ;
17381778}
@@ -1785,6 +1825,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
17851825 // vertex
17861826 if (token[0 ] == ' v' && IS_SPACE ((token[1 ]))) {
17871827 token += 2 ;
1828+ // TODO(syoyo): Support parsing vertex color extension.
17881829 real_t x, y, z, w; // w is optional. default = 1.0
17891830 parseV (&x, &y, &z, &w, &token);
17901831 if (callback.vertex_cb ) {
0 commit comments