Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2010-12-02 13:07:57 +0000
committerStijn Buys <ingar@osirion.org>2010-12-02 13:07:57 +0000
commit5c949b7e6eaf0076199f803f83e37290f0c549a8 (patch)
tree1d23e29e0912f40360b8ff5fc4d18708a9f4179a
parent9eabfbf3f2642cde6615ea30c5942769071c83cf (diff)
Improved patch mesh subdivision.
-rw-r--r--src/model/mapfile.cc53
-rw-r--r--src/model/mapfile.h8
2 files changed, 47 insertions, 14 deletions
diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc
index 7775c8d..c016659 100644
--- a/src/model/mapfile.cc
+++ b/src/model/mapfile.cc
@@ -396,21 +396,46 @@ bool MapFile::read_patchdef()
// patchvertices[][] are the control points as read from the .map file
// mesh[][] is a subdivideXsubdivide quad mesh calculated for each set of 9 control points in the patch
- // TODO variable sibdivision
- const size_t subdivide = 4;
+ // binomial coefficient
const float binom[3] = {1.0f, 2.0f, 1.0f};
-
+ size_t subdivide_u = 0;
+ size_t subdivide_v = 0;
+
for (size_t r = 0; r < rows-2; r +=2 ) {
for (size_t c = 0; c < columns -2; c += 2) {
- math::Vector3f mesh[subdivide + 1][subdivide +1];
- math::Vector3f meshnormals[subdivide + 1][subdivide +1];
- math::Vector2f meshtexcoords[subdivide + 1][subdivide +1];
-
- for (size_t i = 0; i <= subdivide; i++) {
- const float u = (float) i / (float) subdivide;
- for (size_t j = 0; j <= subdivide; j++) {
- const float v = (float) j / (float) subdivide;
+ // if columns are collinear, do not subdivide in u direction
+ if (
+ collinear(patchvertices[r][c], patchvertices[r+1][c], patchvertices[r+2][c]) &&
+ collinear(patchvertices[r][c+1], patchvertices[r+1][c+1], patchvertices[r+2][c+1]) &&
+ collinear(patchvertices[r][c+2], patchvertices[r+1][c+2], patchvertices[r+2][c+2])
+ ) {
+ subdivide_u = 1;
+ } else {
+ subdivide_u = 4;
+ }
+
+
+ // if rows are collinear, do not subdivide in v direction
+ if (
+ collinear(patchvertices[r][c], patchvertices[r][c+1], patchvertices[r][c+2]) &&
+ collinear(patchvertices[r+1][c], patchvertices[r+1][c+1], patchvertices[r+1][c+2]) &&
+ collinear(patchvertices[r+2][c], patchvertices[r+2][c+1], patchvertices[r+2][c+2])
+ ) {
+ subdivide_v = 1;
+ } else {
+ subdivide_v = 4;
+ }
+
+ math::Vector3f mesh[subdivide_u + 1][subdivide_v +1];
+ math::Vector3f meshnormals[subdivide_u + 1][subdivide_v +1];
+ math::Vector2f meshtexcoords[subdivide_u + 1][subdivide_v +1];
+
+ for (size_t i = 0; i <= subdivide_u; i++) {
+ const float u = (float) i / (float) subdivide_u;
+
+ for (size_t j = 0; j <= subdivide_v; j++) {
+ const float v = (float) j / (float) subdivide_v;
math::Vector3f tan_u;
math::Vector3f tan_v;
@@ -418,7 +443,7 @@ bool MapFile::read_patchdef()
// we cheat and pull the edge points towards the middle
float un = u;
float vn = v;
- if ((i ==0) || (j==0) || (i == subdivide) || (j == subdivide)) {
+ if ((i ==0) || (j==0) || (i == subdivide_u) || (j == subdivide_v)) {
un = (u - 0.5f) * 0.95f + 0.5f;
vn = (v - 0.5f) * 0.95f + 0.5f;
}
@@ -480,8 +505,8 @@ bool MapFile::read_patchdef()
}
const math::Vector3f zero;
- for (size_t i = 0; i < subdivide; i++) {
- for (size_t j = 0; j < subdivide; j++) {
+ for (size_t i = 0; i < subdivide_u; i++) {
+ for (size_t j = 0; j < subdivide_v; j++) {
Quad *quad = new Quad(
mesh[i+1][j+1] * SCALE,
mesh[i][j+1] * SCALE,
diff --git a/src/model/mapfile.h b/src/model/mapfile.h
index a12e295..c78b56c 100644
--- a/src/model/mapfile.h
+++ b/src/model/mapfile.h
@@ -128,6 +128,14 @@ private:
inline const math::BoundingBox3f & box() const {
return map_box;
}
+
+ inline bool collinear(const math::Vector3f & a, const math::Vector3f & b, const math::Vector3f & c)
+ {
+ if ((distance(a, b) + distance(b, c)) == distance(a, c))
+ return true;
+ else
+ return false;
+ }
/// close the file
void close();