From a30ae7d0fb13b9a00a17e621463c186fb6ac5ada Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 6 Jan 2010 06:12:58 +0100 Subject: Optimized triangle normal handling --- src/Collision.cpp | 2 +- src/Level.cpp | 18 +++++++----------- src/MathUtil.h | 2 +- src/Renderer.cpp | 2 +- src/Triangle.h | 33 ++++++++++++++++++++++----------- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/Collision.cpp b/src/Collision.cpp index 21ef083..81bc89d 100644 --- a/src/Collision.cpp +++ b/src/Collision.cpp @@ -136,7 +136,7 @@ bool Collision::test(const Triangle &t, const vmml::vec3f &m, float r, const vmm float d; - vmml::vec3f triangleNormal = t.computeNormal(); + vmml::vec3f triangleNormal = t.getNormal(); if(test(t, MathUtil::Ray(m - r*triangleNormal, move), &d) && d > -MathUtil::EPSILON) { if(d < 1) { if(distance) diff --git a/src/Level.cpp b/src/Level.cpp index 9b2aa78..c6ba915 100644 --- a/src/Level.cpp +++ b/src/Level.cpp @@ -172,13 +172,13 @@ TriangleRecord Level::loadWall(xmlNodePtr wallNode) { if(++vertexNum > 2) break; - wall.getTriangle().setVertex(vertexNum, loadVector(node)); + wall.getTriangle().setVertex(vertexNum, loadVector(node), false); } else if(!xmlStrcmp(node->name, (xmlChar*)"normal")) { if(vertexNum < 0) continue; - wall.getTriangle().setNormal(vertexNum, loadVector(node)); + wall.getTriangle().setVertexNormal(vertexNum, loadVector(node)); } else if(!xmlStrcmp(node->name, (xmlChar*)"texcoords")) { if(vertexNum < 0) continue; @@ -197,18 +197,14 @@ TriangleRecord Level::loadWall(xmlNodePtr wallNode) { } } - vmml::vec3f normal = wall.getTriangle().computeNormal(); + wall.getTriangle().updateNormal(); + vmml::vec3f normal = wall.getTriangle().getNormal(); - if(normal.squared_length() > 0) { - normal.normalize(); - - for(int i = 0; i < 3; ++i) { - if(wall.getTriangle().getNormal(i).squared_length() == 0) - wall.getTriangle().setNormal(i, normal); - } + for(int i = 0; i < 3; ++i) { + if(wall.getTriangle().getVertexNormal(i).squared_length() == 0) + wall.getTriangle().setVertexNormal(i, normal); } - return wall; } diff --git a/src/MathUtil.h b/src/MathUtil.h index 3f7ba90..639336a 100644 --- a/src/MathUtil.h +++ b/src/MathUtil.h @@ -51,7 +51,7 @@ class MathUtil { class Plane { public: Plane(const vmml::vec3f &n = vmml::vec3f::ZERO, float d0 = 0) : normal(n), d(d0) {} - Plane(const Triangle &t) : normal(t.computeNormal()), d(t.getVertex(0).dot(normal)) {} + Plane(const Triangle &t) : normal(t.getNormal()), d(t.getVertex(0).dot(normal)) {} bool contains(const vmml::vec3f &v) const { return (fabsf(normal.dot(v) - d) < EPSILON); diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 5d86565..512883d 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -53,7 +53,7 @@ void Renderer::renderTriangle(const Triangle &t) { for(int i = 0; i < 3; ++i) { glTexCoord2fv(t.getTexCoords(i).array); - glNormal3fv(t.getNormal(i).array); + glNormal3fv(t.getVertexNormal(i).array); glVertex3fv(t.getVertex(i).array); } } diff --git a/src/Triangle.h b/src/Triangle.h index 2b34c3f..e13574c 100644 --- a/src/Triangle.h +++ b/src/Triangle.h @@ -30,30 +30,44 @@ class Triangle { Triangle() : color(vmml::vec4f::ONE), texture(0) { vertices[0] = vertices[1] = vertices[2] = vmml::vec3f::ZERO; normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO; + normal = vmml::vec3f::ZERO; texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO; } - Triangle(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &v3, const vmml::vec4f &color0) : color(color0), texture(0) { + Triangle(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &v3, const vmml::vec4f &color0, bool update = true) : color(color0), texture(0) { vertices[0] = v1; vertices[1] = v2; vertices[2] = v3; normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO; texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO; + + if(update) + updateNormal(); + else + normal = vmml::vec3f::ZERO; } const vmml::vec3f& getVertex(int i) const {return vertices[i];} - vmml::vec3f& getVertex(int i) {return vertices[i];} - void setVertex(int i, vmml::vec3f v) { + void setVertex(int i, vmml::vec3f v, bool update = true) { vertices[i] = v; + + if(update) + updateNormal(); + } + + void updateNormal() { + normal = vertices[0].compute_normal(vertices[1], vertices[2]); } - const vmml::vec3f& getNormal(int i) const {return normals[i];} - vmml::vec3f& getNormal(int i) {return normals[i];} - void setNormal(int i, vmml::vec3f n) { + const vmml::vec3f& getVertexNormal(int i) const {return normals[i];} + vmml::vec3f& getVertexNormal(int i) {return normals[i];} + void setVertexNormal(int i, vmml::vec3f n) { normals[i] = n; } + const vmml::vec3f& getNormal() const {return normal;} + const vmml::vec2f& getTexCoords(int i) const {return texcoords[i];} vmml::vec2f& getTexCoords(int i) {return texcoords[i];} void setTexCoords(int i, vmml::vec2f t) { @@ -73,12 +87,8 @@ class Triangle { color = c; } - vmml::vec3f computeNormal() const { - return vertices[0].compute_normal(vertices[1], vertices[2]); - } - bool isDegenerate() const { - return (computeNormal().squared_length() == 0); + return (normal.squared_length() == 0); } void transform(const vmml::mat4f &matrix) { @@ -94,6 +104,7 @@ class Triangle { private: vmml::vec3f vertices[3]; vmml::vec3f normals[3]; + vmml::vec3f normal; vmml::vec2f texcoords[3]; vmml::vec4f color; unsigned texture; -- cgit v1.2.3