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

Element.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     TEDDY - General graphics application library
00004     Copyright (C) 1999-2002  Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2.1 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     $Id: Element.cpp,v 1.6 2002/02/16 12:41:39 tksuoran Exp $
00022 */
00023 
00024 
00025 #include "Teddy/Maths/Matrix.h"
00026 #include "Teddy/Models/Element.h"
00027 #include "Teddy/Models/GeometryIterator.h"
00028 #include "Teddy/Models/Vertex.h"
00029 #include "Teddy/SysSupport/Messages.h"
00030 #include <algorithm>
00031 using namespace std;
00032 using namespace Teddy::Maths;
00033 using namespace Teddy::SysSupport;
00034 
00035 
00036 namespace Teddy  {
00037 namespace Models {
00038 
00039 
00040 const unsigned long Element::EL_HAS_ELEMENT_NORMAL = (1L<< 0L);
00041 const unsigned long Element::EL_USE_ELEMENT_NORMAL = (1L<< 1L);
00042 const unsigned long Element::EL_USE_VERTEX_NORMALS = (1L<< 2L);
00043 
00044 const unsigned long Element::VX_HAS_PARENT         = (1L<< 3L);
00045 const unsigned long Element::VX_HAS_VERTEX         = (1L<< 4L);
00046 const unsigned long Element::VX_HAS_NORMAL         = (1L<< 5L);
00047 const unsigned long Element::VX_HAS_COLOR          = (1L<< 6L);
00048 const unsigned long Element::VX_HAS_TEXTURE        = (1L<< 7L);
00049 
00050 const unsigned long Element::VX_USE_THIS_VERTEX    = (1L<< 8L);
00051 const unsigned long Element::VX_USE_THIS_NORMAL    = (1L<< 9L);
00052 const unsigned long Element::VX_USE_THIS_COLOR     = (1L<<10L);
00053 const unsigned long Element::VX_USE_THIS_TEXTURE   = (1L<<11L);
00054 
00055 const unsigned long Element::VX_USE_PARENT_VERTEX  = (1L<<12L);
00056 const unsigned long Element::VX_USE_PARENT_NORMAL  = (1L<<13L);
00057 const unsigned long Element::VX_USE_PARENT_COLOR   = (1L<<14L);
00058 const unsigned long Element::VX_USE_PARENT_TEXTURE = (1L<<15L);
00059 
00060 const unsigned long Element::VX_TRAVERSAL_VISITED  = (1L<<16L);
00061 
00062 const unsigned long Element::VX_USE_PARENT_ALL     = 
00063     Element::VX_USE_PARENT_VERTEX  | 
00064     Element::VX_USE_PARENT_NORMAL  | 
00065     Element::VX_USE_PARENT_COLOR   |
00066     Element::VX_USE_PARENT_TEXTURE;
00067 ;
00068 
00069 
00070 Element::Element( unsigned long options )
00071 :
00072 Options( options ),
00073 normal ( 0, 1, 0 )
00074 {
00075 }
00076 
00077 
00079 /*virtual*/ Element::~Element(){
00080 }
00081 
00082 
00084 /*virtual*/ void Element::debug(){
00085 }
00086 
00087 
00089 /*virtual*/ void Element::add( Vertex *v ){
00090     vertices.push_front( v );
00091     //v->addFace( this );
00092 }
00093 
00094 
00096 /*virtual*/ void Element::add( const float x, const float y, const float z ){
00097     Vertex *v = new Vertex(x,y,z);
00098     vertices.push_front( v );
00099     //v->addFace( this );
00100 }
00101 
00102 
00104 /*virtual*/ void Element::append( Vertex *v ){
00105     vertices.push_back( v );
00106     //v->addFace( this );
00107 }
00108 
00109 
00111 /*virtual*/ void Element::append( const float x, const float y, const float z ){
00112     Vertex *v = new Vertex(x,y,z);
00113     vertices.push_back( v );
00114     //v->addFace( this );
00115 }
00116 
00117 
00119 void Element::setNormal( const Vector &normal ){
00120     enable( EL_HAS_ELEMENT_NORMAL );
00121     this->normal = normal;
00122 }
00123 void Element::setNormal( const float x, const float y, const float z ){
00124     enable( EL_HAS_ELEMENT_NORMAL );
00125     normal = Vector( x, y, z );
00126 }
00127 
00128 
00130 const Vector &Element::getNormal() const {
00131     return normal;
00132 }
00133 
00134 
00136 bool Element::contains( const Vertex *v ) const {
00137     if(  find( vertices.begin(), vertices.end(), v ) != vertices.end()  )
00138     {
00139         return true;
00140     }else{
00141         return false;
00142     }
00143 }
00144 
00145 
00150 /*virtual*/ void Element::reverse(){
00151     vertices.reverse();
00152 }
00153 
00154 
00160 /*virtual*/ void Element::makeNormal(){
00161     list<Vertex*>::iterator v_i1 = vertices.begin();
00162     list<Vertex*>::iterator v_i2 = v_i1;
00163 
00164     if( vertices.size()<3 ){
00165         dmsg( M_WARN,
00166             "Element does not have enough vertices for normal calculation (%d vertices found)",
00167             vertices.size()
00168         );
00169         normal = Vector(0,1,0);
00170         return;
00171     }
00172 
00173     float len;
00174 
00175     //  This loop makes sure that we use proper vertices to
00176     //  get face normal calculated correctly. If we would blindly
00177     //  take three first vertices, they might be on a straight
00178     //  line, which is not good for normal calculation
00179     int max_count = vertices.size() * 3;
00180     v_i1++;
00181     if( v_i1 == vertices.end() ) v_i1 = vertices.begin();
00182     v_i1++;
00183     if( v_i1 == vertices.end() ) v_i1 = vertices.begin();
00184     do{
00185         max_count--;
00186         if( max_count <=0 ){
00187             dmsg( M_WARN, "Element had not good vertices for normal calculation" );
00188             normal = Vector(0,1,0);
00189             return;
00190         }
00191         v_i2 = v_i1++;
00192         if( v_i1 == vertices.end() ) v_i1 = vertices.begin();
00193 
00194         if( v_i2 == vertices.end() ) v_i2 = vertices.begin();
00195         Vector a  = (*v_i2++)->getVertex();
00196 
00197         if( v_i2 == vertices.end() ) v_i2 = vertices.begin();
00198         Vector b  = (*v_i2++)->getVertex();
00199 
00200         if( v_i2 == vertices.end() ) v_i2 = vertices.begin(); 
00201         Vector c  = (*v_i2++)->getVertex();
00202 
00203         Vector ac = a-c; ac.normalize();
00204         Vector ab = a-b; ab.normalize();
00205         if( (ac | ab) > 1 - 2*FLT_EPSILON ){
00206             //dmsg( M_WARN, "Trying next vertex-triplet for normal" );
00207             continue;
00208         }
00209         normal    = ac^ab;
00210         normal.normalize();
00211         len = normal.magnitude();
00212     }while( len < 0.9f || len > 1.1f );
00213 
00214     enable( EL_HAS_ELEMENT_NORMAL | EL_USE_ELEMENT_NORMAL );
00215 }
00216 
00217 
00218 /*virtual*/ void Element::makeConvexNormal(){
00219     makeNormal();
00220     list<Vertex*>::iterator v_it = vertices.begin();
00221 
00222     Vector a  = (*v_it)->getVertex();
00223     double dp = a | normal;
00224 
00225     if( dp < 0 ){
00226         reverse   ();
00227         makeNormal();
00228     }
00229 }
00230 
00231 
00233 /*virtual*/ void Element::smooth( float max_smoothing_angle ){
00234 }
00235 
00236 
00238 #if defined( TEDDY_INCLUDE_COLDET )
00239 /*virtual*/ int Element::addToCollisionModel( Teddy::ColDet::CollisionModel3D *collision_model ){
00240     return 0;
00241 }
00242 #endif
00243 
00244 
00245 void Element::clearTraversal(){
00246     list<Vertex*>::const_iterator v_it = vertices.begin();
00247     while( v_it != vertices.end() ){
00248         Vertex *vertex  = *v_it;
00249         vertex->disable( VX_TRAVERSAL_VISITED );
00250         v_it++;
00251     }
00252 }
00253 
00254 
00255 double Element::getMaxVector() const {
00256     double max_len = 0;
00257     list<Vertex*>::const_iterator v_it = vertices.begin();
00258     while( v_it != vertices.end() ){
00259         Vertex *vertex = *v_it;
00260         double  len    = vertex->getVertex().magnitude();
00261         if( len > max_len ){
00262             max_len = len;
00263         }
00264         v_it++;
00265     }
00266     return max_len;
00267 }
00268 
00269 
00273 /*virtual*/ void Element::transformVertices( const Matrix &m, const Matrix &normal_matrix, const bool rev ){
00274     list<Vertex*>::iterator v_it = vertices.begin();
00275     while( v_it != vertices.end() ){
00276         Vertex *vertex  = *v_it;
00277         if( vertex->isDisabled(VX_TRAVERSAL_VISITED) ){
00278             vertex->enable   ( VX_TRAVERSAL_VISITED );
00279             vertex->transform( m, normal_matrix );
00280         }
00281         v_it++;
00282     }
00283     if( rev == true ){
00284         reverse();
00285     }
00286     if( isEnabled(EL_HAS_ELEMENT_NORMAL) ){
00287         normal = normal_matrix * normal;
00288         normal.normalize();
00289     }
00290 }
00291 
00292 
00293 #if 0
00294 //  CSG; default for Elements, override if not equal
00295 /*virtual*/ unsigned long Element::countCSGFaceElements(){
00296     return 1;
00297 }
00298 
00299 
00300 //  CSG; default for Elements, override if not equal
00301 /*virtual*/ unsigned long Element::countCSGVertexElements(){
00302     return vertices.size();
00303 }
00304 
00305 
00306 /*virtual*/ void Element::initCSGFace( GeometryIterator *gi ){
00307     gi->face_v_it = vertices.begin();
00308     gi->face_data = 0;
00309 }
00310 
00311 
00312 /*virtual*/ void Element::initCSGVertex( GeometryIterator *gi ){
00313     gi->vertex_v_it = vertices.begin();
00314     gi->vertex_data = 0;
00315 }
00316 
00317 
00318 /*virtual*/ bool Element::stepCSGVertex( GeometryIterator *gi ){
00319     gi->vertex_data++;
00320     gi->vertex_v_it++;
00321     if( gi->vertex_v_it == vertices.end() ){
00322         return false;
00323     }else{
00324         return true;
00325     }
00326 }
00327 
00328 
00329 /*virtual*/ void Element::fillCSGVertex( GeometryIterator *gi, CSG_IVertex *vertex ){
00330     Vertex *vx = *(gi->vertex_v_it);
00331     Vector &v  = vx->getVertex();
00332     vertex->position[0] = v[0];
00333     vertex->position[1] = v[1];
00334     vertex->position[2] = v[2];
00335 }
00336 
00337 
00338 /*virtual*/ bool stepCSGFace( GeometryIterator *gi ){
00339     return false;
00340 }
00341 
00342 
00343 /*virtual*/ void fillCSGFace( GeometryIterator *gi, CSG_IFace *face ){
00344     return;
00345 }
00346 #endif
00347 
00348 
00349 };  //  namespace Models
00350 };  //  namespace Teddy
00351