| 128 | |
| 129 | template <typename T> |
| 130 | Expected<void> parseTextCoordinate( const std::string_view& str, Vector3<T>& v, Vector3<T>* n, Color* c ) |
| 131 | { |
| 132 | using namespace boost::spirit::x3; |
| 133 | |
| 134 | int vi = 0; |
| 135 | const auto coord = [&] ( auto& ctx ) { v[vi++] = _attr( ctx ); }; |
| 136 | int ni = 0; |
| 137 | const auto normal = [&] ( auto& ctx ) { if ( n ) ( *n )[ni++] = _attr( ctx ); }; |
| 138 | int ci = 0; |
| 139 | const auto color = [&] ( auto& ctx ) { if ( c ) ( *c )[ci++] = uint8_t( _attr( ctx ) ); }; |
| 140 | |
| 141 | const auto spaceRule = ( ascii::space | ',' | ';' ); |
| 142 | const auto coordRule = ( floatT[coord] >> floatT[coord] >> floatT[coord] ); |
| 143 | const auto normalRule = ( floatT[normal] >> floatT[normal] >> floatT[normal] ); |
| 144 | const auto colorRule = ( floatT[color] >> floatT[color] >> floatT[color] ); |
| 145 | |
| 146 | bool r; |
| 147 | if ( c != nullptr ) |
| 148 | { |
| 149 | r = phrase_parse( |
| 150 | str.begin(), |
| 151 | str.end(), |
| 152 | ( coordRule >> -( normalRule >> -colorRule ) ), |
| 153 | spaceRule |
| 154 | ); |
| 155 | } |
| 156 | else if ( n != nullptr ) |
| 157 | { |
| 158 | r = phrase_parse( |
| 159 | str.begin(), |
| 160 | str.end(), |
| 161 | ( coordRule >> -normalRule ), |
| 162 | spaceRule |
| 163 | ); |
| 164 | } |
| 165 | else |
| 166 | { |
| 167 | r = phrase_parse( |
| 168 | str.begin(), |
| 169 | str.end(), |
| 170 | coordRule, |
| 171 | spaceRule |
| 172 | ); |
| 173 | } |
| 174 | if ( !r ) |
| 175 | return unexpected( "Failed to parse coord" ); |
| 176 | |
| 177 | // explicitly set alpha value if color is present |
| 178 | if ( c != nullptr && ci == 3 ) |
| 179 | c->a = 255; |
| 180 | |
| 181 | return {}; |
| 182 | } |
| 183 | |
| 184 | template <typename T> |
| 185 | Expected<void> parseObjCoordinate( const std::string_view& str, Vector3<T>& v, Vector3<T>* c ) |
no test coverage detected