worked on 3d models within map

adjusted grid factory
adjusted nav mesh factory
minoor changes/fixes
new helper classes
refactoring
This commit is contained in:
2018-04-03 14:55:59 +02:00
parent f3b6155157
commit 1c2081d406
25 changed files with 620 additions and 93 deletions

View File

@@ -14,7 +14,6 @@ class OBJReader {
public:
/** group vertex+normal+texture */
struct VNT {
int idxVertex;
@@ -31,15 +30,26 @@ public:
Face(VNT v1, VNT v2, VNT v3) : vnt({v1,v2,v3}) {;}
};
/** one object within the file */
struct Object {
std::string material;
std::string name;
std::vector<Face> faces;
};
/** internal data */
struct Data {
std::vector<Point3> vertices;
std::vector<Point2> texCoords;
std::vector<Point3> normals;
std::vector<Face> faces;
std::vector<std::string> materialFiles;
std::vector<Object> objects;
Object& curObj() {
if (objects.empty()) {objects.push_back(Object());}
return objects.back();
}
} data;
public:
/** ctor. use readXYZ() */
@@ -68,6 +78,24 @@ public:
private:
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
size_t end_pos = start_pos + from.length();
str.replace(start_pos, end_pos, to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
/** remove empty strings from the vector */
std::vector<std::string> nonEmpty(const std::vector<std::string>& src) {
std::vector<std::string> res;
for (const std::string& s : src) {
if (!s.empty()) {res.push_back(s);}
}
return res;
}
template<typename Out>
void split(const std::string &s, char delim, Out result) {
std::stringstream ss(s);
@@ -84,20 +112,33 @@ private:
}
/** parse one line of the .obj file */
void parseLine(const std::string& line) {
void parseLine(std::string line) {
if (line.length() < 2) {return;}
const std::vector<std::string> tokens = split(line, ' ');
// remove other linebreaks
replaceAll(line, "\r", "");
const std::vector<std::string> tokens = nonEmpty(split(line, ' '));
const std::string token = tokens.front();
if ("v" == token) {parseVertex(tokens);}
if ("vt" == token) {parseTexCoord(tokens);}
if ("vn" == token) {parseNormal(tokens);}
if ("f" == token) {parseFace(tokens);}
if ("mtllib" == token) {data.materialFiles.push_back(tokens[1]);}
if ("usemtl" == token) {data.curObj().material = tokens[1];}
if ("v" == token) {parseVertex(tokens);}
if ("vt" == token) {parseTexCoord(tokens);}
if ("vn" == token) {parseNormal(tokens);}
if ("f" == token) {parseFace(tokens);}
if ("g" == token) {newObject(tokens[1]);}
}
/** allocate a new object */
void newObject(const std::string& name) {
Object o;
o.name = name;
data.objects.push_back(o);
}
/** parse one vertex from the tokenizer */
void parseVertex(const std::vector<std::string>& t) {
const float x = std::stof(t[1]);
@@ -135,18 +176,20 @@ private:
++numVertices;
const std::string v = vtn[0];
const std::string vt = (vtn.size() > 1) ? (vtn[1]) : ("");
const std::string vn = (vtn.size() > 2) ? (vtn[2]) : ("");
//const std::string vt = t2.getToken('/', false);
//const std::string vn = t2.getToken('/', false);
// create a new vertex/normal/texture combination
VNT vnt;
vnt.idxVertex = (std::stoi(v) - 1);
//vnt.idxNormal = (vn.empty()) ? (-1) : (std::stoi(vn) - 1);
//vnt.idxTexture = (vt.empty()) ? (-1) : (std::stoi(vt) - 1);
vnt.idxNormal = (vn.empty()) ? (-1) : (std::stoi(vn) - 1);
vnt.idxTexture = (vt.empty()) ? (-1) : (std::stoi(vt) - 1);
if (vnt.idxVertex >= 0) {vnt.vertex = data.vertices[vnt.idxVertex];}
//if (vnt.idxNormal >= 0) {vnt.normal = data.normals[vnt.idxNormal];}
//if (vnt.idxTexture >= 0) {vnt.texture = data.texCoords[vnt.idxTexture];}
if (vnt.idxNormal >= 0) {vnt.normal = data.normals[vnt.idxNormal];}
if (vnt.idxTexture >= 0) {vnt.texture = data.texCoords[vnt.idxTexture];}
indices.push_back(vnt);
@@ -156,7 +199,7 @@ private:
// see: http://www.mathopenref.com/polygontriangles.html
for (int i = 1; i < (int) indices.size()-1; ++i) {
Face face(indices[0], indices[1], indices[i+1]);
data.faces.push_back(face);
data.curObj().faces.push_back(face);
}
// sanity check