Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/math/vector3f.h7
-rw-r--r--src/model/mapfile.cc191
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()