123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- #ifndef __OOPLESS_PARSER__
- #define __OOPLESS_PARSER__
- #include "planes.h"
- #include "worldspawn.h"
- #include <string>
- #include <vector>
- #include <fstream>
- #include <queue>
- #include "EntityConverter.hpp"
- bool is_ebrush(const std::vector<std::string> &);
- std::vector<std::string> extract_brush(const std::vector<std::string> &);
- struct TBrush override_textures(struct TBrush, const char*);
- bool write(const struct TBrush &,
- std::ofstream &,
- void (*f) (std::stringstream &, const std::vector<TPlanePoints> &));
- void write(const std::vector<std::string> &,
- std::ofstream &,
- void (*f) (std::stringstream &, const std::vector<TPlanePoints> &),
- EntityConverter &);
- bool convertmap(std::stringstream &,
- const char * const,
- void (*f) (std::stringstream &, const std::vector<TPlanePoints> &),
- std::vector<std::vector<std::string> > &);
- #define KEYWORD_ENTITY "entity"
- #define KEYWORD_BRUSH "brush"
- #define KEYWORD_VERTICES "vertices"
- #define KEYWORD_FACES "faces"
- #define KEYWORD_GLOBAL "global"
- #define KEYWORD_PREFAB "prefab"
- template <class STREAMOBJ>
- std::vector<std::string> get_entity(STREAMOBJ &f) {
- using namespace std;
- vector<string> output;
- string line;
- unsigned int pos = f.tellg();
- while (getline(f, line)) {
- // stop when
- // entity or a prefab keyword
- // brush keyword and the entity is not of the type teleporter or jumppad.
- if ((line.find(KEYWORD_ENTITY) != string::npos ||
- line.find(KEYWORD_PREFAB) != string::npos) || (
- line.find(KEYWORD_BRUSH) != string::npos && !is_ebrush(output))) {
- f.seekg(pos);
- break;
- } else {
- output.push_back(line);
- }
- pos = f.tellg();
- }
- return output;
- }
- template <class STREAMOBJ>
- std::vector<Eigen::Vector3f> parse_vertices(STREAMOBJ &f) {
- using namespace std;
- #define FIRSTCH(x) x[0]
- vector<Eigen::Vector3f> output;
- string line;
- unsigned int pos = f.tellg();
- while(getline(f, line)) {
- if (line.find(KEYWORD_FACES) != string::npos ||
- line.find(KEYWORD_BRUSH) != string::npos ||
- line.find(KEYWORD_ENTITY) != string::npos ||
- line.find(KEYWORD_PREFAB) != string::npos) {
- f.seekg(pos);
- return output;
- } else {
- Eigen::Vector3f v;
- stringstream ss(line);
- string vdata;
- unsigned int i = 0;
- while (ss >> vdata) {
- if (isdigit(FIRSTCH(vdata)) || FIRSTCH(vdata) == '-') {
- double dvalue = stod(vdata);
- v[i] = (float)dvalue;
- }
- // note: this prevents the index growing out of vector capacity
- // alternatively can throw an exception when that happens instead
- // to make it clear that an illegal line has been hit.
- i = (i + 1) % 3;
- }
- output.push_back(v);
- }
- pos = f.tellg();
- }
- return output;
- }
- template <class STREAMOBJ>
- std::vector<struct TFace> parse_face(STREAMOBJ &f) {
- using namespace std;
- #define FIRSTCH(x) x[0]
- #define SECONDCH(x) x[1]
- // it is possible for the next line to be unrelated to faces
- // so it is needed to reset the stream prior to reading
- // the new label, e.g '\tbrush'.
- vector<struct TFace> output;
- string line;
- unsigned int pos = f.tellg();
- while(getline(f, line)) {
- if (line.find(KEYWORD_VERTICES) != string::npos ||
- line.find(KEYWORD_BRUSH) != string::npos ||
- line.find(KEYWORD_ENTITY) != string::npos ||
- line.find(KEYWORD_PREFAB) != string::npos ||
- line.find(KEYWORD_GLOBAL) != string::npos) {
- f.seekg(pos);
- return output;
- } else {
- struct TFace x;
- float *f = &x.m_fXOffset;;
- stringstream ss(line);
- string fdata;
- bool hex = false;
- unsigned int i = 0;
- while (ss >> fdata) {
- if (i < 5) {
- if (isdigit(FIRSTCH(fdata)) || FIRSTCH(fdata) == '-') {
- double dvalue = stod(fdata);
- *f = (float)dvalue;
- f++;
- }
- // note: if there is a non-digit in the first 5 fields
- // then it qualifies as an illegal line.
- } else if (4 < i && i < 8) {
- x.m_Indices.push_back(stoi(fdata));
- } else if (8 <= i) {
- if (!hex && fdata.length() > 1) {
- if (SECONDCH(fdata) == 'x') {
- // this is the unidentified hex digit.
- // out of range for stoi
- x.hex = fdata;
- hex = true;
- }
- } else if (!hex) {
- x.m_Indices.push_back(stoi(fdata));
- } else if (hex) {
- x.m_Material = fdata;
- } else {
- ;
- }
- }
- i++;
- } // end, per field iteration
- output.push_back(x);
- } // end else case, if line did not contain other keywords
- pos = f.tellg();
- } // end, per line iteration
- // the odd case when the map file ends with a face indent.
- return output;
- }
- template <class STREAMOBJ>
- struct TBrush parse_brush(STREAMOBJ &f) {
- using namespace std;
- struct TBrush output;
- string l;
- getline(f, l);
- if (l.find(KEYWORD_VERTICES) != string::npos) {
- output.m_Vertices = parse_vertices<STREAMOBJ>(f);
- }
- getline(f, l);
- if (l.find(KEYWORD_FACES) != string::npos) {
- output.m_Faces = parse_face<STREAMOBJ>(f);
- }
- return output;
- }
- template <class ISTR>
- void parse_prefab(ISTR &f,
- std::ofstream &out,
- void (*b) (std::stringstream &, const std::vector<TPlanePoints> &),
- std::vector<std::vector<std::string> > &entities) {
- using namespace std;
- string l;
- getline(f, l);
- if (l.find(KEYWORD_BRUSH) != string::npos) {
- write(parse_brush<ISTR>(f), out, b);
- } else if (l.find(KEYWORD_ENTITY) != string::npos) {
- entities.push_back(get_entity<ISTR>(f));
- }
- }
- #endif
|