Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

glmesh.cpp

Go to the documentation of this file.
00001 /*
00002     Sheep - A Rigid Body Dynamics Engine
00003     Copyright (C) 2001-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of Sheep.
00007 
00008     Sheep is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     Sheep is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with Sheep; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #include "glmesh.h" // include first
00024 #include "common/math/real.h"
00025 #include "material.h"
00026 
00027 #include <algorithm>
00028 #include <cassert>
00029 
00030 using namespace sheep;
00031 using namespace std;
00032 
00033 GLMesh::SubMesh::SubMesh() :
00034     m_material(0),
00035     m_list_name(0)  // 0 is not a valid display list index
00036 {
00037     SetupRendering(IMMEDIATE_MODE);
00038 }
00039 
00040 GLMesh::SubMesh::~SubMesh() {
00041     if(m_list_name != 0)
00042         glDeleteLists(m_list_name, 1);
00043 }
00044 
00045 void GLMesh::SubMesh::SetMaterial(Material *m) {
00046     assert(m);
00047     m_material = m;
00048 }
00049 
00050 void GLMesh::SubMesh::SetupRendering(RenderingMode mode) {
00051     m_rendering_mode = mode;
00052 
00053     if(m_rendering_mode == DISPLAY_LIST) {
00054         if(m_list_name == 0)
00055             m_list_name = glGenLists(1);
00056 
00057         glNewList(m_list_name, GL_COMPILE);
00058         do_rendering();
00059         glEndList();
00060     }
00061 }
00062 
00063 void GLMesh::SubMesh::Render() const {
00064     switch(m_rendering_mode) {
00065     case IMMEDIATE_MODE:
00066         do_rendering();
00067         break;
00068     case DISPLAY_LIST:
00069         glCallList(m_list_name);
00070         break;
00071     }
00072 }
00073 
00074 void GLMesh::SubMesh::DisplayNormals() const {
00075     glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LINE_BIT);
00076 
00077     glDisable(GL_LIGHTING);
00078     glDisable(GL_TEXTURE_2D);
00079 
00080     glLineWidth(1.0f);
00081     glColor3f(1.0f, 0.0f, 0.0f);
00082 
00083     //!\todo Make normals independant of the model scale.
00084     const Real NORMAL_LENGTH = 0.6;
00085 
00086     glBegin(GL_LINES);
00087 
00088     for(unsigned int i = 0; i < m_faces.size(); ++i) {
00089         const Face &f = m_faces[i];
00090 
00091         const Vector3 &n0 = m_normals[f.m_n0];
00092         const Vector3 &n1 = m_normals[f.m_n1];
00093         const Vector3 &n2 = m_normals[f.m_n2];
00094 
00095         const Vector3 &v0 = m_vertices[f.m_v0];
00096         const Vector3 &v1 = m_vertices[f.m_v1];
00097         const Vector3 &v2 = m_vertices[f.m_v2];
00098 
00099         const Vector3 e0 = v0 + NORMAL_LENGTH * n0;
00100         const Vector3 e1 = v1 + NORMAL_LENGTH * n1;
00101         const Vector3 e2 = v2 + NORMAL_LENGTH * n2;
00102 
00103         glVertex3f(v0.m_x, v0.m_y, v0.m_z);
00104         glVertex3f(e0.m_x, e0.m_y, e0.m_z);
00105 
00106         glVertex3f(v1.m_x, v1.m_y, v1.m_z);
00107         glVertex3f(e1.m_x, e1.m_y, e1.m_z);
00108 
00109         glVertex3f(v2.m_x, v2.m_y, v2.m_z);
00110         glVertex3f(e2.m_x, e2.m_y, e2.m_z);
00111 
00112 /*      const Vector3 center = (v0 + v1 + v2) / 3;
00113         const Vector3 avg_normal = (n0 + n1 + n2).Normalized();
00114         const Vector3 end = center + NORMAL_LENGTH * avg_normal;
00115 
00116         glVertex3f(center.m_x, center.m_y, center.m_z);
00117         glVertex3f(end.m_x, end.m_y, end.m_z);*/
00118     }
00119 
00120     glEnd();
00121 
00122     glPopAttrib();
00123 }
00124 
00125 void GLMesh::SubMesh::do_rendering() const {
00126     assert(m_material);
00127 
00128     m_material->SetActive();
00129 
00130     glBegin(GL_TRIANGLES);
00131 
00132     if(m_material->GetTexture() && m_texcoords.size() > 0) {
00133         for(FaceVectorConstIt i = m_faces.begin(), e = m_faces.end(); i != e; ++i) {
00134             const Face &f = *i;
00135 
00136             // Make sure stuff is there.
00137             assert(m_vertices.size() > 0);
00138             assert(m_texcoords.size() > 0);
00139             assert(m_normals.size() > 0);
00140 
00141             // Make sure vertex indices are valid.
00142             assert(f.m_v0 >= 0 && f.m_v0 < static_cast<int>(m_vertices.size()));
00143             assert(f.m_v1 >= 0 && f.m_v1 < static_cast<int>(m_vertices.size()));
00144             assert(f.m_v2 >= 0 && f.m_v2 < static_cast<int>(m_vertices.size()));
00145 
00146             // Make sure texture coordinate indices are valid.
00147             assert(f.m_t0 >= 0 && f.m_t0 < static_cast<int>(m_texcoords.size()));
00148             assert(f.m_t1 >= 0 && f.m_t1 < static_cast<int>(m_texcoords.size()));
00149             assert(f.m_t2 >= 0 && f.m_t2 < static_cast<int>(m_texcoords.size()));
00150 
00151             // Make sure normal indices are valid.
00152             assert(f.m_n0 >= 0 && f.m_n0 < static_cast<int>(m_normals.size()));
00153             assert(f.m_n1 >= 0 && f.m_n1 < static_cast<int>(m_normals.size()));
00154             assert(f.m_n2 >= 0 && f.m_n2 < static_cast<int>(m_normals.size()));
00155 
00156             const Vector2 &t0 = m_texcoords[f.m_t0];
00157             const Vector2 &t1 = m_texcoords[f.m_t1];
00158             const Vector2 &t2 = m_texcoords[f.m_t2];
00159 
00160             const Vector3 &n0 = m_normals[f.m_n0];
00161             const Vector3 &n1 = m_normals[f.m_n1];
00162             const Vector3 &n2 = m_normals[f.m_n2];
00163 
00164             const Vector3 &v0 = m_vertices[f.m_v0];
00165             const Vector3 &v1 = m_vertices[f.m_v1];
00166             const Vector3 &v2 = m_vertices[f.m_v2];
00167 
00168             glTexCoord2f(t0.m_x, t0.m_y);
00169             glNormal3f(n0.m_x, n0.m_y, n0.m_z);
00170             glVertex3f(v0.m_x, v0.m_y, v0.m_z);
00171 
00172             glTexCoord2f(t1.m_x, t1.m_y);
00173             glNormal3f(n1.m_x, n1.m_y, n1.m_z);
00174             glVertex3f(v1.m_x, v1.m_y, v1.m_z);
00175 
00176             glTexCoord2f(t2.m_x, t2.m_y);
00177             glNormal3f(n2.m_x, n2.m_y, n2.m_z);
00178             glVertex3f(v2.m_x, v2.m_y, v2.m_z);
00179         }
00180     } else {
00181         for(FaceVectorConstIt i = m_faces.begin(), e = m_faces.end(); i != e; ++i) {
00182             const Face &f = *i;
00183 
00184             // Make sure stuff is there.
00185             assert(m_vertices.size() > 0);
00186             assert(m_normals.size() > 0);
00187 
00188             // Make sure vertex indices are valid.
00189             assert(f.m_v0 >= 0 && f.m_v0 < static_cast<int>(m_vertices.size()));
00190             assert(f.m_v1 >= 0 && f.m_v1 < static_cast<int>(m_vertices.size()));
00191             assert(f.m_v2 >= 0 && f.m_v2 < static_cast<int>(m_vertices.size()));
00192 
00193             // Make sure normal indices are valid.
00194             assert(f.m_n0 >= 0 && f.m_n0 < static_cast<int>(m_normals.size()));
00195             assert(f.m_n1 >= 0 && f.m_n1 < static_cast<int>(m_normals.size()));
00196             assert(f.m_n2 >= 0 && f.m_n2 < static_cast<int>(m_normals.size()));
00197 
00198             const Vector3 &n0 = m_normals[f.m_n0];
00199             const Vector3 &n1 = m_normals[f.m_n1];
00200             const Vector3 &n2 = m_normals[f.m_n2];
00201 
00202             const Vector3 &v0 = m_vertices[f.m_v0];
00203             const Vector3 &v1 = m_vertices[f.m_v1];
00204             const Vector3 &v2 = m_vertices[f.m_v2];
00205 
00206             glNormal3f(n0.m_x, n0.m_y, n0.m_z);
00207             glVertex3f(v0.m_x, v0.m_y, v0.m_z);
00208 
00209             glNormal3f(n1.m_x, n1.m_y, n1.m_z);
00210             glVertex3f(v1.m_x, v1.m_y, v1.m_z);
00211 
00212             glNormal3f(n2.m_x, n2.m_y, n2.m_z);
00213             glVertex3f(v2.m_x, v2.m_y, v2.m_z);
00214         }
00215     }
00216 
00217     glEnd();
00218 }
00219 
00220 GLMesh::GLMesh() :
00221     m_vertex_count(0),
00222     m_face_count(0)
00223 {
00224 }
00225 
00226 GLMesh::~GLMesh() {
00227     for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00228         delete *i;
00229     }
00230 }
00231 
00232 void GLMesh::Insert(SubMesh *m) {
00233     assert(m);
00234 
00235     m_sub_meshes.push_back(m);
00236 
00237     // Update vertex and face counters.
00238     m_vertex_count += m->m_vertices.size();
00239     m_face_count += m->m_faces.size();
00240 
00241     // Update the bounding box.
00242     for(SubMesh::Vector3VectorConstIt i = m->m_vertices.begin(),
00243         e = m->m_vertices.end(); i != e; ++i)
00244     {
00245         m_aabb.Include(*i);
00246     }
00247 }
00248 
00249 void GLMesh::FlipFaces() {
00250     for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00251         SubMesh *sub_mesh = *i;
00252 
00253         // Reverse triangles orientation.
00254         for(SubMesh::FaceVectorIt j = sub_mesh->m_faces.begin(),
00255             e = sub_mesh->m_faces.end(); j != e; ++j)
00256         {
00257             SubMesh::Face &f = *j;
00258 
00259             swap(f.m_v1, f.m_v2);
00260             swap(f.m_n1, f.m_n2);
00261             swap(f.m_t1, f.m_t2);
00262         }
00263 
00264         // Flip normals.
00265         for(SubMesh::Vector3VectorIt j = sub_mesh->m_normals.begin(),
00266             e = sub_mesh->m_normals.end(); j != e; ++j)
00267         {
00268             *j = - *j;
00269         }
00270     }
00271 }
00272 
00273 void GLMesh::SetupRendering(RenderingMode mode) {
00274     for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00275         (*i)->SetupRendering(mode);
00276     }
00277 }
00278 
00279 void GLMesh::Render() const {
00280     for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00281         (*i)->Render();
00282     }
00283 }
00284 
00285 void GLMesh::DisplayNormals() const {
00286     for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00287         (*i)->DisplayNormals();
00288     }
00289 }

Generated on Tue May 11 01:31:50 2004 for toxic by doxygen 1.3.6