From 4d1b23606ed58737db9ea4423f1ad0f3d1db2782 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 28 Nov 2010 17:36:07 +0000 Subject: Improved patch mesh surface normals. --- src/model/mapfile.cc | 114 ++++++++++++++++++++++++++++++++++++++++----------- src/model/quad.cc | 3 +- src/model/quad.h | 6 --- 3 files changed, 92 insertions(+), 31 deletions(-) (limited to 'src/model') diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index 76a75a9..bf41cb4 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -27,8 +27,8 @@ const float MIN_DELTA = 10e-10; // from radiant tools/quake3/q3map2/map.c math::Vector3f texture_baseaxis[18] = { - // normal texture plane - math::Vector3f(0, 0, 1), math::Vector3f(1, 0, 0), math::Vector3f(0, -1, 0), // floor + // normal texture plane + math::Vector3f(0, 0, 1), math::Vector3f(1, 0, 0), math::Vector3f(0, -1, 0), // floor math::Vector3f(0, 0, -1), math::Vector3f(1, 0, 0), math::Vector3f(0, -1, 0), // ceiling math::Vector3f(1, 0, 0), math::Vector3f(0, 1, 0), math::Vector3f(0, 0, -1), // west wall math::Vector3f(-1, 0, 0), math::Vector3f(0, 1, 0), math::Vector3f(0, 0, -1), // east wall @@ -328,7 +328,6 @@ bool MapFile::read_patchdef() } patchvertices[r][c].assign(x, y, z); - patchvertices[r][c] *= SCALE; } if (!(linestream >> word)) { @@ -388,42 +387,111 @@ bool MapFile::read_patchdef() } // load patch data into the model geometry - // the patch is a set of quadratic B-splines with m = n =2 + // the patch is a set of quadratic B-splines with m = n = 2 + // see http://en.wikipedia.org/wiki/Bézier_surface + // http://www.cc.gatech.edu/classes/AY2002/cs4451_spring/groups/group3/index.html#bpatches2 + // + // 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 texture coordinates, normals // TODO variable sibdivision const size_t subdivide = 4; - const float binom[3] = {1, 2, 1}; + const float binom[3] = {1.0f, 2.0f, 1.0f}; 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::Vector3f patchnormals[3][3]; + + patchnormals[0][0].assign(math::normal(patchvertices[r+0][c+0], patchvertices[r+1][c+0], patchvertices[r+0][c+1])); + patchnormals[0][2].assign(math::normal(patchvertices[r+0][c+2], patchvertices[r+0][c+1], patchvertices[r+1][c+2])); + patchnormals[2][2].assign(math::normal(patchvertices[r+2][c+2], patchvertices[r+1][c+2], patchvertices[r+2][c+1])); + patchnormals[2][0].assign(math::normal(patchvertices[r+2][c+0], patchvertices[r+2][c+1], patchvertices[r+1][c+0])); + + patchnormals[0][1].assign(patchnormals[0][0] + patchnormals[0][2]); + patchnormals[0][1] *= 0.5f; + patchnormals[0][1].normalize(); + + patchnormals[2][1].assign(patchnormals[2][0] + patchnormals[2][2]); + patchnormals[2][1] *= 0.5f; + patchnormals[2][1].normalize(); + + patchnormals[1][0].assign(patchnormals[0][0] + patchnormals[2][0]); + patchnormals[1][0] *= 0.5f; + patchnormals[1][0].normalize(); + + patchnormals[1][2].assign(patchnormals[0][2] + patchnormals[2][2]); + patchnormals[1][2] *= 0.5f; + patchnormals[1][2].normalize(); + + patchnormals[1][1].assign(patchnormals[0][1] + patchnormals[2][1] + patchnormals[1][0] + patchnormals[1][2]); + patchnormals[1][1] *= 0.25f; + patchnormals[1][1].normalize(); 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; + //math::Vector3f tan_u; + //math::Vector3f tan_v; for (size_t mi = 0; mi < 3; mi++) { for (size_t mj = 0; mj < 3; mj++) { mesh[i][j] += patchvertices[r+mi][c+mj] * - binom[mi] * pow (u,mi) * pow(1.0f - u, 2-mi) * - binom[mj] * pow (v,mj) * pow(1.0f - v, 2-mj); + binom[mi] * powf (u, (float) mi) * powf(1.0f - u, 2.0f - (float) mi) * + binom[mj] * powf (v, (float) mj) * powf(1.0f - v, 2.0f - (float) mj); + + meshnormals[i][j] += + patchnormals[mi][mj] * + binom[mi] * powf (u, (float) mi) * powf(1.0f - u, 2.0f - (float) mi) * + binom[mj] * powf (v, (float) mj) * powf(1.0f - v, 2.0f - (float) mj); + /* + tan_u += + patchvertices[r+mi][c+mj] * + binom[mi] * ( + ((float) mi) * powf(u, (float) mi - 1.0f) * powf(1.0f - u, 2.0f - (float) mi) + + ((float) mi - 2.0f) * powf(u, (float) mi) * powf(1.0f - u, 1.0f - (float) mi) + ) * + binom[mj] * powf (v, (float) mj) * powf(1.0f - v, 2.0f - (float) mj); + + tan_v += + patchvertices[r+mi][c+mj] * + binom[mi] * powf (u, (float) mi) * powf(1.0f - u, 2.0f - (float) mi) * + binom[mj] * ( + ((float) mj) * powf(v, (float) mj - 1.0f) * powf(1.0f - v, 2.0f - (float) mj) + + ((float) mj - 2.0f) * powf(v, (float) mj) * powf(1.0f - v, 1.0f - (float) mj) + ); + */ } } - } + + //meshnormals[i][j].assign(math::crossproduct(tan_u, tan_v)); + meshnormals[i][j].normalize(); + class_box.expand(mesh[i][j] * SCALE); + } } - + + const math::Vector3f zero; for (size_t i = 0; i < subdivide; i++) { for (size_t j = 0; j < subdivide; j++) { Quad *quad = new Quad( - mesh[i+1][j+1], - mesh[i][j+1], - mesh[i][j], - mesh[i+1][j], - math::normal(mesh[i][j+1], mesh[i][j], mesh[i+1][j+1]) + mesh[i+1][j+1] * SCALE, + mesh[i][j+1] * SCALE, + mesh[i][j] * SCALE, + mesh[i+1][j] * SCALE, + zero ); + + quad->n0().assign(meshnormals[i+1][j+1]); + quad->n1().assign(meshnormals[i][j+1]); + quad->n2().assign(meshnormals[i][j]); + quad->n3().assign(meshnormals[i+1][j]); + primitives->add_quad(quad); } } @@ -811,7 +879,7 @@ void MapFile::make_brushface(Face *face) primitives = (*mit).second; } - // scale vertices and calculate the bounding box + // add vertices to the bounding box for (std::vector::iterator it = vl.begin(); it != vl.end(); it++) { class_box.expand(*(*it) * SCALE); } @@ -1103,10 +1171,10 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t Quad *quad = (*quad_it); if (!quad->detail()) { size_t count = 0; - count += fragment->add_vertex(quad->v0() - translation, quad->normal(), quad->t0(), false); - count += fragment->add_vertex(quad->v1() - translation, quad->normal(), quad->t1(), false); - count += fragment->add_vertex(quad->v2() - translation, quad->normal(), quad->t2(), false); - count += fragment->add_vertex(quad->v3() - translation, quad->normal(), quad->t3(), false); + count += fragment->add_vertex(quad->v0() - translation, quad->n0(), quad->t0(), false); + count += fragment->add_vertex(quad->v1() - translation, quad->n1(), quad->t1(), false); + count += fragment->add_vertex(quad->v2() - translation, quad->n2(), quad->t2(), false); + count += fragment->add_vertex(quad->v3() - translation, quad->n3(), quad->t3(), false); if (count == 4) { model->model_quad_count++; } @@ -1118,10 +1186,10 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t Quad *quad = (*quad_it); if (quad->detail()) { size_t count = 0; - count += fragment->add_vertex(quad->v0() - translation, quad->normal(), quad->t0(), false); - count += fragment->add_vertex(quad->v1() - translation, quad->normal(), quad->t1(), false); - count += fragment->add_vertex(quad->v2() - translation, quad->normal(), quad->t2(), false); - count += fragment->add_vertex(quad->v3() - translation, quad->normal(), quad->t3(), false); + count += fragment->add_vertex(quad->v0() - translation, quad->n0(), quad->t0(), true); + count += fragment->add_vertex(quad->v1() - translation, quad->n1(), quad->t1(), true); + count += fragment->add_vertex(quad->v2() - translation, quad->n2(), quad->t2(), true); + count += fragment->add_vertex(quad->v3() - translation, quad->n3(), quad->t3(), true); if (count == 4) { model->model_quad_count++; model->model_quad_detail_count++; diff --git a/src/model/quad.cc b/src/model/quad.cc index 0830fe7..29aff34 100644 --- a/src/model/quad.cc +++ b/src/model/quad.cc @@ -17,8 +17,7 @@ Quad::Quad(const math::Vector3f &v0, const math::Vector3f &v1, const math::Vect quad_v2(v2), quad_n2(normal), quad_v3(v3), - quad_n3(normal), - quad_normal(normal) + quad_n3(normal) { quad_detail = detail; } diff --git a/src/model/quad.h b/src/model/quad.h index b7dd7af..4609cea 100644 --- a/src/model/quad.h +++ b/src/model/quad.h @@ -90,11 +90,6 @@ public: return quad_detail; } - /// face normal - inline math::Vector3f &normal() { - return quad_normal; - } - private: math::Vector3f quad_v0; @@ -113,7 +108,6 @@ private: math::Vector3f quad_n3; math::Vector2f quad_t3; - math::Vector3f quad_normal; bool quad_detail; }; -- cgit v1.2.3