From a92dc36d721806f8613a7aa531eca89162de504a Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Fri, 26 Nov 2010 14:12:53 +0000 Subject: Read .map patch definitions into model quads (without triangulation) --- src/math/vector3f.h | 7 ++ src/model/mapfile.cc | 191 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 178 insertions(+), 20 deletions(-) diff --git a/src/math/vector3f.h b/src/math/vector3f.h index a7437aa..7cd533d 100644 --- a/src/math/vector3f.h +++ b/src/math/vector3f.h @@ -225,6 +225,13 @@ inline btVector3 to_btVector3(const math::Vector3f & v) return btVector3(v[0], v[1], v[2]); } +/// calculate the normal of a plane defined by three vertices +inline const Vector3f normal(const Vector3f & first, const Vector3f & second, const Vector3f & third) { + Vector3f r = crossproduct(second - first, third - first); + r.normalize(); + return r; +} + } // namespace math #endif // __INCLUDED_MATH_VECTOR3F_H__ diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index 84fd108..deb22a5 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -215,43 +215,194 @@ bool MapFile::read_patchdef() { char data[1024]; memset(data, 0, sizeof(data)); - size_t count = 0; + size_t columns = 0; + size_t rows = 0; + std::string materialname; // first line: texture name - if (!mapfile_ifs.getline(data, 1023)) + if (!mapfile_ifs.getline(data, 1023)) { return false; - else + } else { line_number++; + + std::istringstream linestream(data); + if (!(linestream >> materialname)) { + return false; + } + } // second line: "( a b c d e )" - if (!mapfile_ifs.getline(data, 1023)) + // "( rows columns unknown unknown unknown )" + + if (!mapfile_ifs.getline(data, 1023)) { return false; - else + } else { line_number++; - - // third line: "(" - if (!mapfile_ifs.getline(data, 1023)) + + std::istringstream linestream(data); + std::string word; + + if (!(linestream >> word)) + return false; + + if (word.compare("(") != 0) + return false; + + if (!(linestream >> rows >> columns)) + return false; + } + + // leading line: "(" + if (!mapfile_ifs.getline(data, 1023)) { return false; - else + } else { line_number++; + + std::istringstream linestream(data); + std::string word; + + if (!(linestream >> word)) + return false; + + if (word.compare("(") != 0) + return false; + } - while (mapfile_ifs.getline(data, 1023)) { + // patch definitions: + // 'column' is the number of lines to be read + // each line has 'row' vertices + + // sanity check + if ((columns < 2) || (rows < 2) || (columns >= 1024) || (rows >= 1024)) { + return false; + } + + math::Vector3f patchvertices[rows][columns]; + + // read rows + for (size_t r = 0; r < rows; r++) { + if(!mapfile_ifs.getline(data, 1023)) { + return false; + } line_number++; - + std::istringstream linestream(data); - std::string firstword; - - if (linestream >> firstword) { - if (firstword.compare(")") == 0) { - //con_debug << " patchDef2 with " << count << " lines" << std::endl; - return true; - } else { - count ++; + std::string word; + + if (!(linestream >> word)) { + //con_debug << " Error reading row begin" << std::endl; + return false; + } + + if (word.compare("(") != 0) { + //con_debug << " Error reading row begin: word contains '" << word << "'" << std::endl; + return false; + } + + // read columns + for (size_t c = 0; c < columns; c++) { + float x, y, z, tx, ty; + + //con_debug << " Reading patch row " << r << " column " << c << std::endl; + + if (!(linestream >> word)) { + return false; + } + if (word.compare("(") != 0) { + //con_debug << " Error reading column begin: word contains '" << word << "'" << std::endl; + return false; + } + + if (!(linestream >> x >> y >> z >> tx >> ty)) { + //con_debug << " Error reading column data" << std::endl; + return false; + } + + if (!(linestream >> word)) { + //con_debug << " Error reading column end" << std::endl; + return false; + } + if (word.compare(")") != 0) { + //con_debug << " Error reading column end: word contains '" << word << "'" << std::endl; + return false; } + + patchvertices[r][c].assign(x, y, z); + } + + if (!(linestream >> word)) { + //con_debug << " Error reading row end" << std::endl; + return false; + } + if (word.compare(")") != 0) { + //con_debug << " Error reading row end: word contains '" << word << "'" << std::endl; + return false; + } + + } + + // trailing line: ")" + if(!mapfile_ifs.getline(data, 1023)) { + return false; + } else { + line_number++; + + std::istringstream linestream(data); + std::string word; + + if (!(linestream >> word)) { + //con_debug << "Error reading trialing line ')'" << std::endl; + return false; + } + + if (word.compare(")") != 0) { + //con_debug << "No trialing line ')'" << std::endl; + return false; + } + } + + // find the material for this patch + Material *material = Material::find("textures/" + materialname); + if (!material) { + material = new Material("textures/" + materialname); + Material::add(material); + material->set_texture(material->name()); + } + + // find the primitives for the current material, + // allocate a new one if necessary + Primitives *primitives = 0; + + Materials::iterator mit = map_materials.find(material); + if (mit == map_materials.end()) { + primitives = new Primitives(material); + map_materials[material] = primitives; + } else { + primitives = (*mit).second; + } + + // ignore materials with the 'Ignore' flag set + if ((material->flags() & Material::Ignore) == Material::Ignore) { + return true; + } + + // load patch data into the model geometry + // TODO triangulate, assign texture coordinates + for (size_t r = 0; r < rows-1; r++) { + for (size_t c = 0; c < columns -1; c++) { + Quad *quad = new Quad( + patchvertices[r][c] * SCALE, + patchvertices[r][c+1] * SCALE, + patchvertices[r+1][c+1] * SCALE, + patchvertices[r+1][c] * SCALE, + math::normal(patchvertices[r][c], patchvertices[r][c+1], patchvertices[r+1][c+1]) + ); + primitives->add_quad(quad); } } - return false; + //con_debug << " patchDef2 with " << columns << " columns " << rows << " rows" << std::endl; + return true; } bool MapFile::getline() -- cgit v1.2.3