# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/Geometry.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include <vlGraphics/Geometry.hpp>
    00033 #include <vlGraphics/OpenGLContext.hpp>
    00034 #include <vlGraphics/DoubleVertexRemover.hpp>
    00035 #include <cmath>
    00036
    00037 using namespace vl;
    00038
    00039 //-----------------------------------------------------------------------------
    00040 // Geometry
    00041 //-----------------------------------------------------------------------------
    00042 Geometry::Geometry()
    00043 {
    00044   VL_DEBUG_SET_OBJECT_NAME()
    00045   mVertexAttribArrays.setAutomaticDelete(false);
    00046   mTexCoordArrays.setAutomaticDelete(false);
    00047   mDrawCalls.setAutomaticDelete(false);
    00048   mColor = vl::white;
    00049   mSecondaryColor = vl::white;
    00050   mNormal = fvec3(0,0,1);
    00051 }
    00052 //-----------------------------------------------------------------------------
    00053 Geometry::~Geometry()
    00054 {
    00055 }
    00056 //-----------------------------------------------------------------------------
    00057 void Geometry::computeBounds_Implementation()
    00058 {
    00059   const ArrayAbstract* coords = vertexArray();
    00060   if (!coords && vertexAttribInfo(0))
    00061     coords = vertexAttribInfo(0)->data();
    00062
    00063   AABB aabb;
    00064
    00065   for(int i=0; i<drawCalls()->size(); ++i)
    00066   {
    00067     for(IndexIterator iit = drawCalls()->at(i)->indexIterator(); !iit.isEnd(); iit.next())
    00068     {
    00069       aabb += coords->vectorAsVec3( iit.index() );
    00070     }
    00071   }
    00072
    00073   Real radius = 0, r = 0;
    00074   vec3 center = aabb.center();
    00075   for(int i=0; i<drawCalls()->size(); ++i)
    00076   {
    00077     for(IndexIterator iit = drawCalls()->at(i)->indexIterator(); !iit.isEnd(); iit.next())
    00078     {
    00079       r = (coords->vectorAsVec3(iit.index()) - center).lengthSquared();
    00080       if (r > radius)
    00081         radius = r;
    00082     }
    00083   }
    00084
    00085   setBoundingBox( aabb );
    00086   setBoundingSphere( Sphere(center, radius) );
    00087 }
    00088 //-----------------------------------------------------------------------------
    00089 ref<Geometry> Geometry::deepCopy() const
    00090 {
    00091   ref<Geometry> geom = new Geometry;
    00092   deepCopy(geom.get());
    00093   return geom;
    00094 }
    00095 //-----------------------------------------------------------------------------
    00096 void Geometry::deepCopy(Geometry* geom) const
    00097 {
    00098   // copy the base class Renderable
    00099   geom->Renderable::operator=(*this);
    00100   // copy Geometry
    00101   geom->mVertexArray         = mVertexArray         ? mVertexArray->clone().get()         : NULL;
    00102   geom->mNormalArray         = mNormalArray         ? mNormalArray->clone().get()         : NULL;
    00103   geom->mColorArray          = mColorArray          ? mColorArray->clone().get()          : NULL;
    00104   geom->mSecondaryColorArray = mSecondaryColorArray ? mSecondaryColorArray->clone().get() : NULL;
    00105   geom->mFogCoordArray       = mFogCoordArray       ? mFogCoordArray->clone().get()       : NULL;
    00106   geom->mTexCoordArrays.resize(mTexCoordArrays.size());
    00107   for(int i=0; i<mTexCoordArrays.size(); ++i)
    00108     geom->mTexCoordArrays[i] = new TextureArray(mTexCoordArrays[i]->mTextureUnit, mTexCoordArrays[i]->mTexCoordArray ? mTexCoordArrays[i]->mTexCoordArray->clone().get() : NULL);
    00109   // custom arrays
    00110   geom->mVertexAttribArrays.resize(mVertexAttribArrays.size());
    00111   for(int i=0; i<mVertexAttribArrays.size(); ++i)
    00112   {
    00113     geom->mVertexAttribArrays[i] = new VertexAttribInfo;
    00114     geom->mVertexAttribArrays[i]->setNormalize( mVertexAttribArrays[i]->normalize() );
    00115     geom->mVertexAttribArrays[i]->setDataBehavior( mVertexAttribArrays[i]->dataBehavior() );
    00116     geom->mVertexAttribArrays[i]->setAttribIndex( mVertexAttribArrays[i]->attribIndex() );
    00117     geom->mVertexAttribArrays[i]->setData( geom->mVertexAttribArrays[i]->data() ? geom->mVertexAttribArrays[i]->data()->clone().get() : NULL );
    00118   }
    00119   // primitives
    00120   for(int i=0; i<mDrawCalls.size(); ++i)
    00121     geom->mDrawCalls.push_back( mDrawCalls[i]->clone().get() );
    00122   geom->mColor = mColor;
    00123   geom->mSecondaryColor = mSecondaryColor;
    00124   geom->mNormal = mNormal;
    00125 }
    00126 //-----------------------------------------------------------------------------
    00127 Geometry& Geometry::operator=(const Geometry& other)
    00128 {
    00129   // copy the base class Renderable
    00130   Renderable::operator=(*this);
    00131   // copy Geometry attributes
    00132   mVertexArray = other.mVertexArray;
    00133   mNormalArray = other.mNormalArray;
    00134   mColorArray = other.mColorArray;
    00135   mSecondaryColorArray = other.mSecondaryColorArray;
    00136   mFogCoordArray = other.mFogCoordArray;
    00137   mTexCoordArrays = other.mTexCoordArrays;
    00138   mVertexAttribArrays = other.mVertexAttribArrays;
    00139   mColor = other.mColor;
    00140   mSecondaryColor = other.mSecondaryColor;
    00141   mNormal = other.mNormal;
    00142   mDrawCalls = other.mDrawCalls;
    00143   return *this;
    00144 }
    00145 //-----------------------------------------------------------------------------
    00146 ref<Geometry> Geometry::shallowCopy()
    00147 {
    00148   ref<Geometry> geom = new Geometry;
    00149   geom->operator=(*this);
    00150   return geom;
    00151 }
    00152 //-----------------------------------------------------------------------------
    00153 void Geometry::shallowCopy(Geometry* geom)
    00154 {
    00155   geom->operator=(*this);
    00156 }
    00157 //-----------------------------------------------------------------------------
    00158 void Geometry::setVertexArray(ArrayAbstract* data)
    00159 {
    00160   // if one of this checks fail read the OpenGL Programmers Guide or the Reference Manual
    00161   // to see what "size" and "type" are allowed for glVertexPointer
    00162   VL_CHECK( !data || (data->glSize() >=2 && data->glSize()<=4) )
    00163
    00164   mVertexArray = data;
    00165 }
    00166 //-----------------------------------------------------------------------------
    00167 void Geometry::setNormalArray(ArrayAbstract* data)
    00168 {
    00169   // if one of this checks fail read the OpenGL Programmers Guide or the Reference Manual
    00170   // to see what "size" and "type" are allowed for glNormalPointer
    00171   VL_CHECK( !data || data->glSize() == 3 )
    00172   VL_CHECK( !data || (data->glType() == GL_BYTE||
    00173                       data->glType() == GL_SHORT ||
    00174                       data->glType() == GL_INT ||
    00175                       data->glType() == GL_FLOAT ||
    00176                       data->glType() == GL_DOUBLE) );
    00177
    00178   mNormalArray = data;
    00179 }
    00180 //-----------------------------------------------------------------------------
    00181 void Geometry::setColorArray(ArrayAbstract* data)
    00182 {
    00183   // if one of this checks fail read the OpenGL Programmers Guide or the Reference Manual
    00184   // to see what "size" and "type" are allowed for glColorPointer
    00185   VL_CHECK( !data || (data->glSize() >=3 && data->glSize()<=4) )
    00186   VL_CHECK( !data || (data->glType() == GL_BYTE ||
    00187                       data->glType() == GL_SHORT ||
    00188                       data->glType() == GL_INT ||
    00189                       data->glType() == GL_UNSIGNED_BYTE ||
    00190                       data->glType() == GL_UNSIGNED_SHORT ||
    00191                       data->glType() == GL_UNSIGNED_INT ||
    00192                       data->glType() == GL_FLOAT ||
    00193                       data->glType() == GL_DOUBLE) );
    00194
    00195   mColorArray = data;
    00196 }
    00197 //-----------------------------------------------------------------------------
    00198 void Geometry::setSecondaryColorArray(ArrayAbstract* data)
    00199 {
    00200   // if one of this checks fail read the OpenGL Programmers Guide or the Reference Manual
    00201   // to see what "size" and "type" are allowed for glSecondaryColorPointer
    00202   VL_CHECK( !data || (data->glSize() >=3 && data->glSize()<=4) )
    00203   VL_CHECK( !data || (data->glType() == GL_BYTE ||
    00204                       data->glType() == GL_SHORT ||
    00205                       data->glType() == GL_INT ||
    00206                       data->glType() == GL_UNSIGNED_BYTE ||
    00207                       data->glType() == GL_UNSIGNED_SHORT ||
    00208                       data->glType() == GL_UNSIGNED_INT ||
    00209                       data->glType() == GL_FLOAT ||
    00210                       data->glType() == GL_DOUBLE) );
    00211
    00212   mSecondaryColorArray = data;
    00213 }
    00214 //-----------------------------------------------------------------------------
    00215 void Geometry::setFogCoordArray(ArrayAbstract* data)
    00216 {
    00217   // if one of this checks fail read the OpenGL Programmers Guide or the Reference Manual
    00218   // to see what "size" and "type" are allowed for glFogCoordPointer
    00219   VL_CHECK( !data || (data->glSize() == 1) )
    00220   VL_CHECK( !data || (data->glType() == GL_FLOAT || data->glType() == GL_DOUBLE) );
    00221
    00222   mFogCoordArray = data;
    00223 }
    00224 //-----------------------------------------------------------------------------
    00225 void Geometry::setTexCoordArray(int tex_unit, ArrayAbstract* data)
    00226 {
    00227   // if one of this checks fail read the OpenGL Programmers Guide or the Reference Manual
    00228   // to see what "size" and "type" are allowed for glTexCoordPointer
    00229   VL_CHECK( !data || (data->glSize() == 1 || data->glSize() == 2 || data->glSize() == 3 || data->glSize() == 4) )
    00230   VL_CHECK( !data || (data->glType() == GL_FLOAT  ||
    00231                       data->glType() == GL_DOUBLE ||
    00232                       data->glType() == GL_SHORT  ||
    00233                       data->glType() == GL_INT) );
    00234
    00235   VL_CHECK(tex_unit<VL_MAX_TEXTURE_UNITS);
    00236
    00237   for(int i=0; i<mTexCoordArrays.size(); ++i)
    00238   {
    00239     if (mTexCoordArrays.at(i)->mTextureUnit == tex_unit)
    00240     {
    00241       if (data)
    00242         mTexCoordArrays.at(i)->mTexCoordArray = data;
    00243       else
    00244         mTexCoordArrays.erase(i,1); // removes if NULL
    00245       return;
    00246     }
    00247   }
    00248   if (data)
    00249     mTexCoordArrays.push_back(new TextureArray(tex_unit,data));
    00250 }
    00251 //-----------------------------------------------------------------------------
    00252 void Geometry::clearArrays(bool clear_draw_calls)
    00253 {
    00254   mVertexArray = NULL;
    00255   mNormalArray = NULL;
    00256   mColorArray = NULL;
    00257   mSecondaryColorArray = NULL;
    00258   mFogCoordArray = NULL;
    00259   mTexCoordArrays.clear();
    00260   mVertexAttribArrays.clear();
    00261   if (clear_draw_calls)
    00262     mDrawCalls.clear();
    00263 }
    00264 //-----------------------------------------------------------------------------
    00265 bool Geometry::flipNormals()
    00266 {
    00267   if (normalArray())
    00268   {
    00269     ArrayFloat3* norm3f = dynamic_cast<ArrayFloat3*>(normalArray());
    00270     if (norm3f)
    00271     {
    00272       for(size_t i=0; i<norm3f->size(); ++i)
    00273       {
    00274         norm3f->at(i) = -norm3f->at(i);
    00275       }
    00276       return true;
    00277     }
    00278   }
    00279   return false;
    00280 }
    00281 //-----------------------------------------------------------------------------
    00282 void Geometry::toGenericVertexAttribs()
    00283 {
    00284   vertexAttribArrays()->clear();
    00285   int index = 0;
    00286
    00287   if (vertexArray())
    00288   {
    00289     setVertexAttribArray(index++, vertexArray());
    00290     setVertexArray(NULL);
    00291   }
    00292
    00293   if (normalArray())
    00294   {
    00295     setVertexAttribArray(index++, normalArray());
    00296     setNormalArray(NULL);
    00297   }
    00298
    00299   if (colorArray())
    00300   {
    00301     setVertexAttribArray(index++, colorArray());
    00302     setColorArray(NULL);
    00303   }
    00304
    00305   for(int i=0; i<mTexCoordArrays.size(); i++)
    00306     setVertexAttribArray( index++, mTexCoordArrays[i]->mTexCoordArray.get() );
    00307   mTexCoordArrays.clear();
    00308
    00309   if (secondaryColorArray())
    00310   {
    00311     setVertexAttribArray(index++, secondaryColorArray());
    00312     setSecondaryColorArray(NULL);
    00313   }
    00314
    00315   if (fogCoordArray())
    00316   {
    00317     setVertexAttribArray(index++, fogCoordArray());
    00318     setFogCoordArray(NULL);
    00319   }
    00320 }
    00321 //-----------------------------------------------------------------------------
    00322 void Geometry::computeNormals(bool verbose)
    00323 {
    00324   ArrayAbstract* posarr = vertexArray() ? vertexArray() : vertexAttrib(0);
    00325   if (!posarr || posarr->size() == 0)
    00326   {
    00327     Log::warning("Geometry::computeNormals() not performed: no vertex coordinate array present!\n");
    00328     return;
    00329   }
    00330
    00331   ref<ArrayFloat3> norm3f = new ArrayFloat3;
    00332   norm3f->resize( posarr->size() );
    00333   setNormalArray( norm3f.get() );
    00334
    00335   // zero the normals
    00336   for(int i=0; i<(int)posarr->size(); ++i)
    00337     (*norm3f)[i] = 0;
    00338
    00339   // iterate all draw calls
    00340   for(int prim=0; prim<(int)drawCalls()->size(); prim++)
    00341   {
    00342     // iterate all triangles, if present
    00343     for(TriangleIterator trit = mDrawCalls[prim]->triangleIterator(); !trit.isEnd(); trit.next())
    00344     {
    00345       size_t a = trit.a();
    00346       size_t b = trit.b();
    00347       size_t c = trit.c();
    00348
    00349       if (verbose)
    00350       if (a == b || b == c || c == a)
    00351       {
    00352         Log::warning( Say("Geometry::computeNormals(): skipping degenerate triangle %n %n %n\n") << a << b << c );
    00353         continue;
    00354       }
    00355
    00356       VL_CHECK( a < posarr->size() )
    00357       VL_CHECK( b < posarr->size() )
    00358       VL_CHECK( c < posarr->size() )
    00359
    00360       vec3 n, v0, v1, v2;
    00361
    00362       v0 = posarr->vectorAsVec4(a).xyz();
    00363       v1 = posarr->vectorAsVec4(b).xyz();
    00364       v2 = posarr->vectorAsVec4(c).xyz();
    00365
    00366       if (verbose)
    00367       if (v0 == v1 || v1 == v2 || v2 == v0)
    00368       {
    00369         Log::warning("Geometry::computeNormals(): skipping degenerate triangle (same vertex coodinate).\n");
    00370         continue;
    00371       }
    00372
    00373       v1 -= v0;
    00374       v2 -= v0;
    00375
    00376       n = cross(v1, v2);
    00377       n.normalize();
    00378       if (verbose)
    00379       if ( fabs(1.0f - n.length()) > 0.1f )
    00380       {
    00381         Log::warning("Geometry::computeNormals(): skipping degenerate triangle (normalization failed).\n");
    00382         continue;
    00383       }
    00384
    00385       (*norm3f)[a] += (fvec3)n;
    00386       (*norm3f)[b] += (fvec3)n;
    00387       (*norm3f)[c] += (fvec3)n;
    00388     }
    00389   }
    00390
    00391   // normalize the normals
    00392   for(int i=0; i<(int)norm3f->size(); ++i)
    00393     (*norm3f)[i].normalize();
    00394 }
    00395 //-----------------------------------------------------------------------------
    00396 void Geometry::deleteVBOs()
    00397 {
    00398   if (!(GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0))
    00399     return;
    00400
    00401   for(int i=0; i<(int)drawCalls()->size(); ++i)
    00402     drawCalls()->at(i)->deleteVBOs();
    00403
    00404   if (mVertexArray)
    00405     mVertexArray->gpuBuffer()->deleteGLBufferObject();
    00406
    00407   if (mNormalArray)
    00408     mNormalArray->gpuBuffer()->deleteGLBufferObject();
    00409
    00410   if (mColorArray)
    00411     mColorArray->gpuBuffer()->deleteGLBufferObject();
    00412
    00413   if (mSecondaryColorArray)
    00414     mSecondaryColorArray->gpuBuffer()->deleteGLBufferObject();
    00415
    00416   if (mFogCoordArray)
    00417     mFogCoordArray->gpuBuffer()->deleteGLBufferObject();
    00418
    00419   for (int i=0; i<mTexCoordArrays.size(); ++i)
    00420     mTexCoordArrays[i]->mTexCoordArray->gpuBuffer()->deleteGLBufferObject();
    00421
    00422   for(int i=0; i<vertexAttribArrays()->size(); ++i)
    00423     if ( vertexAttribArrays()->at(i)->data() )
    00424       vertexAttribArrays()->at(i)->data()->gpuBuffer()->deleteGLBufferObject();
    00425 }
    00426 //-----------------------------------------------------------------------------
    00427 void Geometry::updateVBOs(bool discard_local_data, bool force_update)
    00428 {
    00429   setVBODirty(false);
    00430
    00431   if (!(GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0))
    00432     return;
    00433
    00434   if ( mVertexArray && (mVertexArray->isVBODirty() || force_update) )
    00435     mVertexArray->updateVBO(discard_local_data);
    00436
    00437   if ( mNormalArray && (mNormalArray->isVBODirty() || force_update) )
    00438     mNormalArray->updateVBO(discard_local_data);
    00439
    00440   if ( mColorArray && (mColorArray->isVBODirty() || force_update) )
    00441     mColorArray->updateVBO(discard_local_data);
    00442
    00443   if ( mSecondaryColorArray && (mSecondaryColorArray->isVBODirty() || force_update) )
    00444     mSecondaryColorArray->updateVBO(discard_local_data);
    00445
    00446   if ( mFogCoordArray && (mFogCoordArray->isVBODirty() || force_update) )
    00447     mFogCoordArray->updateVBO(discard_local_data);
    00448
    00449   for(int i=0; i<mTexCoordArrays.size(); ++i)
    00450   {
    00451     if ( mTexCoordArrays[i]->mTexCoordArray->isVBODirty() || force_update )
    00452       mTexCoordArrays[i]->mTexCoordArray->updateVBO(discard_local_data);
    00453   }
    00454
    00455   for(int i=0; i<vertexAttribArrays()->size(); ++i)
    00456     if ( vertexAttribArrays()->at(i)->data() )
    00457       vertexAttribArrays()->at(i)->data()->updateVBO(discard_local_data);
    00458
    00459   for(int i=0; i<drawCalls()->size(); ++i)
    00460     drawCalls()->at(i)->updateVBOs(discard_local_data, force_update);
    00461 }
    00462 //-----------------------------------------------------------------------------
    00463 void Geometry::render_Implementation(const Actor*, const Shader*, const Camera*, OpenGLContext* gl_context) const
    00464 {
    00465   VL_CHECK_OGL()
    00466
    00467   // set default normal, color and secondary colors
    00468
    00469   if (gl_context->isCompatible())
    00470   {
    00471     if (!normalArray())
    00472       glNormal3fv(mNormal.ptr());
    00473
    00474     if (!colorArray())
    00475       glColor4fv(mColor.ptr());
    00476
    00477     if (!secondaryColorArray() && GLEW_VERSION_1_4)
    00478       glSecondaryColor3fv(mSecondaryColor.ptr());
    00479   }
    00480
    00481   // bind Vertex Attrib Set
    00482
    00483   bool vbo_on = (GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0) && vboEnabled() && !isDisplayListEnabled();
    00484   gl_context->bindVAS(this, vbo_on, false);
    00485
    00486   // actual draw
    00487
    00488   for(int i=0; i<(int)drawCalls()->size(); i++)
    00489     if (drawCalls()->at(i)->isEnabled())
    00490       drawCalls()->at(i)->render( vbo_on );
    00491
    00492   VL_CHECK_OGL()
    00493 }
    00494 //-----------------------------------------------------------------------------
    00495 void Geometry::transform(const mat4& m, bool normalize)
    00496 {
    00497   ArrayAbstract* posarr = vertexArray() ? vertexArray() : vertexAttrib(0);
    00498   if (posarr)
    00499     posarr->transform(m);
    00500
    00501   if (normalArray())
    00502   {
    00503     mat4 nmat = m.as3x3().getInverse().transpose();
    00504     normalArray()->transform(nmat);
    00505     if (normalize)
    00506       normalArray()->normalize();
    00507   }
    00508 }
    00509 //-----------------------------------------------------------------------------
    00510 void Geometry::setVertexAttribArray(const VertexAttribInfo& info)
    00511 {
    00512   for(int i=0; i<vertexAttribArrays()->size(); ++i)
    00513   {
    00514     VL_CHECK(vertexAttribArrays()->at(i))
    00515     if (vertexAttribArrays()->at(i)->attribIndex() == info.attribIndex())
    00516     {
    00517       *vertexAttribArrays()->at(i) = info;
    00518       return;
    00519     }
    00520   }
    00521   mVertexAttribArrays.push_back( new VertexAttribInfo(info) );
    00522 }
    00523 //-----------------------------------------------------------------------------
    00524 const ArrayAbstract* Geometry::vertexAttrib(unsigned int name) const
    00525 {
    00526   const VertexAttribInfo* attrib_info = vertexAttribInfo(name);
    00527   if (attrib_info)
    00528     return attrib_info->data();
    00529   else
    00530     return NULL;
    00531 }
    00532 //-----------------------------------------------------------------------------
    00533 ArrayAbstract* Geometry::vertexAttrib(unsigned int name)
    00534 {
    00535   VertexAttribInfo* attrib_info = vertexAttribInfo(name);
    00536   if (attrib_info)
    00537     return attrib_info->data();
    00538   else
    00539     return NULL;
    00540 }
    00541 //-----------------------------------------------------------------------------
    00542 const VertexAttribInfo* Geometry::vertexAttribInfo(unsigned int name) const
    00543 {
    00544   for(int i=0; i<vertexAttribArrays()->size(); ++i)
    00545     if (vertexAttribArrays()->at(i)->attribIndex() == name)
    00546       return vertexAttribArrays()->at(i);
    00547   return NULL;
    00548 }
    00549 //-----------------------------------------------------------------------------
    00550 VertexAttribInfo* Geometry::vertexAttribInfo(unsigned int name)
    00551 {
    00552   for(int i=0; i<vertexAttribArrays()->size(); ++i)
    00553     if (vertexAttribArrays()->at(i)->attribIndex() == name)
    00554       return vertexAttribArrays()->at(i);
    00555   return NULL;
    00556 }
    00557 //-----------------------------------------------------------------------------
    00558 ref<VertexAttribInfo> Geometry::eraseVertexAttrib(unsigned int name)
    00559 {
    00560   ref<VertexAttribInfo> vai;
    00561   for(int i=0; i<vertexAttribArrays()->size(); ++i)
    00562   {
    00563     if (vertexAttribArrays()->at(i)->attribIndex() == name)
    00564     {
    00565       vai = vertexAttribArrays()->at(i);
    00566       vertexAttribArrays()->eraseAt(i);
    00567       return vai;
    00568     }
    00569   }
    00570   return NULL;
    00571 }
    00572 //-----------------------------------------------------------------------------
    00573 void Geometry::mergeTriangleStrips()
    00574 {
    00575   std::vector< ref<DrawElementsUInt> > de;
    00576   std::vector<size_t> indices;
    00577
    00578   // collect DrawElementsUInt
    00579   for(int i=drawCalls()->size(); i--; )
    00580   {
    00581     ref<DrawElementsUInt> de_uint = dynamic_cast<DrawElementsUInt*>( drawCalls()->at(i) );
    00582     if (de_uint && de_uint->primitiveType() == PT_TRIANGLE_STRIP)
    00583     {
    00584       de.push_back(de_uint);
    00585       drawCalls()->erase(i,1);
    00586     }
    00587   }
    00588
    00589   // generate new strip
    00590   indices.reserve( vertexArray()->size()*2 );
    00591   for(size_t i=0; i<de.size(); ++i)
    00592   {
    00593     if (!de[i]->indices()->size())
    00594       continue;
    00595     for(size_t j=0; j<de[i]->indices()->size(); ++j)
    00596       indices.push_back(de[i]->indices()->at(j));
    00597     // odd -> even
    00598     if ( de[i]->indices()->size() % 2 )
    00599       indices.push_back(indices.back());
    00600     // concatenate next strip inserting degenerate triangles
    00601     if ( i != de.size()-1 )
    00602     {
    00603       indices.push_back(indices.back());
    00604       indices.push_back(de[i+1]->indices()->at(0));
    00605       indices.push_back(de[i+1]->indices()->at(0));
    00606       indices.push_back(de[i+1]->indices()->at(1));
    00607     }
    00608   }
    00609
    00610   if (indices.size())
    00611   {
    00612     ref<DrawElementsUInt> draw_elems = new DrawElementsUInt(PT_TRIANGLE_STRIP);
    00613     draw_elems->indices()->resize(indices.size());
    00614     memcpy(draw_elems->indices()->ptr(), &indices[0], sizeof(unsigned int)*indices.size());
    00615     drawCalls()->push_back(draw_elems.get());
    00616   }
    00617 }
    00618 //-----------------------------------------------------------------------------
    00619 void Geometry::regenerateVertices(const std::vector<size_t>& map_new_to_old)
    00620 {
    00621   VertexMapper mapper;
    00622
    00623   if (vertexArray())
    00624     setVertexArray( mapper.regenerate( vertexArray(), map_new_to_old ).get() );
    00625
    00626   if (normalArray())
    00627     setNormalArray( mapper.regenerate( normalArray(), map_new_to_old ).get() );
    00628
    00629   if (colorArray())
    00630     setColorArray( mapper.regenerate( colorArray(), map_new_to_old ).get() );
    00631
    00632   if (secondaryColorArray())
    00633     setSecondaryColorArray( mapper.regenerate( secondaryColorArray(), map_new_to_old ).get() );
    00634
    00635   if (fogCoordArray())
    00636     setFogCoordArray( mapper.regenerate( fogCoordArray(), map_new_to_old ).get() );
    00637
    00638   for(int itex=0; itex<VL_MAX_TEXTURE_UNITS; ++itex)
    00639     if (texCoordArray(itex))
    00640       setTexCoordArray( itex, mapper.regenerate( texCoordArray(itex), map_new_to_old ).get() );
    00641
    00642   for(int i=0; i<vertexAttribArrays()->size(); ++i)
    00643     vertexAttribArrays()->at(i)->setData( mapper.regenerate(vertexAttribArrays()->at(i)->data(), map_new_to_old ).get() );
    00644 }
    00645 //-----------------------------------------------------------------------------
    00646 void Geometry::convertDrawCallToDrawArrays()
    00647 {
    00648   // generate mapping
    00649   std::vector<size_t> map_new_to_old;
    00650   map_new_to_old.reserve( vertexArray()->size() * 3 );
    00651
    00652   for(int i=drawCalls()->size(); i--; )
    00653   {
    00654     int start = (int)map_new_to_old.size();
    00655     for(IndexIterator it=drawCalls()->at(i)->indexIterator(); !it.isEnd(); it.next())
    00656       map_new_to_old.push_back(it.index());
    00657     int count = (int)map_new_to_old.size() - start;
    00658
    00659     // substitute with DrawArrays
    00660     ref<DrawArrays> da = new vl::DrawArrays( drawCalls()->at(i)->primitiveType(), start, count, drawCalls()->at(i)->instances() );
    00661     drawCalls()->erase(i,1);
    00662     drawCalls()->push_back(da.get());
    00663   }
    00664
    00665   regenerateVertices(map_new_to_old);
    00666 }
    00667 //-----------------------------------------------------------------------------
    00668 bool Geometry::sortVertices()
    00669 {
    00670   // works only if the primitive types are all DrawElements
    00671   std::vector< ref<DrawElementsUInt> >   de_uint;
    00672
    00673   // collect DrawElements
    00674   for(int i=0; i<drawCalls()->size(); ++i)
    00675   {
    00676     DrawElementsUInt*   dei = dynamic_cast<DrawElementsUInt*>(drawCalls()->at(i));
    00677     DrawElementsUShort* des = dynamic_cast<DrawElementsUShort*>(drawCalls()->at(i));
    00678     DrawElementsUByte*  deb = dynamic_cast<DrawElementsUByte*>(drawCalls()->at(i));
    00679     if (dei)
    00680       de_uint.push_back(dei);
    00681     else
    00682     if(des)
    00683     {
    00684       dei = new DrawElementsUInt(des->primitiveType(), des->instances());
    00685       de_uint.push_back(dei);
    00686       dei->indices()->resize( des->indices()->size() );
    00687       for(unsigned int j=0; j<des->indices()->size(); ++j)
    00688         dei->indices()->at(j) = des->indices()->at(j);
    00689     }
    00690     else
    00691     if(deb)
    00692     {
    00693       dei = new DrawElementsUInt(deb->primitiveType(), deb->instances());
    00694       de_uint.push_back(dei);
    00695       dei->indices()->resize( deb->indices()->size() );
    00696       for(unsigned int j=0; j<deb->indices()->size(); ++j)
    00697         dei->indices()->at(j) = deb->indices()->at(j);
    00698     }
    00699     else
    00700       return false;
    00701   }
    00702
    00703   drawCalls()->clear();
    00704
    00705   // generate mapping
    00706   std::vector<size_t> map_new_to_old;
    00707   map_new_to_old.resize( vertexArray()->size() );
    00708   memset(&map_new_to_old[0], 0xFF, map_new_to_old.size()*sizeof(map_new_to_old[0]));
    00709
    00710   std::vector<size_t> map_old_to_new;
    00711   map_old_to_new.resize( vertexArray()->size() );
    00712   memset(&map_old_to_new[0], 0xFF, map_old_to_new.size()*sizeof(map_old_to_new[0]));
    00713
    00714   std::vector<size_t> used;
    00715   used.resize( vertexArray()->size() );
    00716   memset(&used[0], 0, used.size()*sizeof(used[0]));
    00717
    00718   size_t index = 0;
    00719   for(int i=(int)de_uint.size(); i--; )
    00720   {
    00721     for(size_t idx=0; idx<de_uint[i]->indices()->size(); ++idx)
    00722       if (!used[de_uint[i]->indices()->at(idx)])
    00723       {
    00724         map_new_to_old[index] = de_uint[i]->indices()->at(idx);
    00725         map_old_to_new[de_uint[i]->indices()->at(idx)] = index;
    00726         index++;
    00727         used[de_uint[i]->indices()->at(idx)] = 1;
    00728       }
    00729   }
    00730
    00731   regenerateVertices(map_new_to_old);
    00732
    00733   // remap DrawElements
    00734   for(size_t i=0; i<de_uint.size(); ++i)
    00735   {
    00736     drawCalls()->push_back(de_uint[i].get());
    00737     for(size_t j=0; j<de_uint[i]->indices()->size(); ++j)
    00738     {
    00739       de_uint[i]->indices()->at(j) = (GLuint)map_old_to_new[de_uint[i]->indices()->at(j)];
    00740     }
    00741   }
    00742
    00743   return true;
    00744 }
    00745 //-----------------------------------------------------------------------------
    00746 void Geometry::colorizePrimitives()
    00747 {
    00748   ref<ArrayFloat4> col = new vl::ArrayFloat4;
    00749   col->resize( vertexArray()->size() );
    00750   setColorArray( col.get() );
    00751
    00752   for(int i=0; i<drawCalls()->size(); ++i)
    00753   {
    00754     fvec4 c;
    00755     c.r() = rand()%100 / 99.0f;
    00756     c.g() = rand()%100 / 99.0f;
    00757     c.b() = rand()%100 / 99.0f;
    00758     c.a() = 1.0f;
    00759
    00760     for(IndexIterator it=drawCalls()->at(i)->indexIterator(); !it.isEnd(); it.next())
    00761       col->at( it.index() ) = c;
    00762   }
    00763 }
    00764 //-----------------------------------------------------------------------------
    00765 void Geometry::computeTangentSpace(
    00766   size_t vert_count,
    00767   const fvec3 *vertex,
    00768   const fvec3* normal,
    00769   const fvec2 *texcoord,
    00770   const DrawCall* prim,
    00771   fvec3 *tangent,
    00772   fvec3 *bitangent )
    00773 {
    00774   std::vector<fvec3> tan1;
    00775   std::vector<fvec3> tan2;
    00776   tan1.resize(vert_count);
    00777   tan2.resize(vert_count);
    00778
    00779   for ( TriangleIterator trit = prim->triangleIterator(); !trit.isEnd(); trit.next() )
    00780   {
    00781     unsigned int tri[] = { trit.a(), trit.b(), trit.c() };
    00782
    00783     VL_CHECK(tri[0] < vert_count );
    00784     VL_CHECK(tri[1] < vert_count );
    00785     VL_CHECK(tri[2] < vert_count );
    00786
    00787     const fvec3& v1 = vertex[tri[0]];
    00788     const fvec3& v2 = vertex[tri[1]];
    00789     const fvec3& v3 = vertex[tri[2]];
    00790
    00791     const fvec2& w1 = texcoord[tri[0]];
    00792     const fvec2& w2 = texcoord[tri[1]];
    00793     const fvec2& w3 = texcoord[tri[2]];
    00794
    00795     float x1 = v2.x() - v1.x();
    00796     float x2 = v3.x() - v1.x();
    00797     float y1 = v2.y() - v1.y();
    00798     float y2 = v3.y() - v1.y();
    00799     float z1 = v2.z() - v1.z();
    00800     float z2 = v3.z() - v1.z();
    00801
    00802     float s1 = w2.x() - w1.x();
    00803     float s2 = w3.x() - w1.x();
    00804     float t1 = w2.y() - w1.y();
    00805     float t2 = w3.y() - w1.y();
    00806
    00807     float r = 1.0F / (s1 * t2 - s2 * t1);
    00808     fvec3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
    00809     fvec3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
    00810
    00811     tan1[tri[0]] += sdir;
    00812     tan1[tri[1]] += sdir;
    00813     tan1[tri[2]] += sdir;
    00814
    00815     tan2[tri[0]] += tdir;
    00816     tan2[tri[1]] += tdir;
    00817     tan2[tri[2]] += tdir;
    00818   }
    00819
    00820   for ( size_t a = 0; a < vert_count; a++)
    00821   {
    00822     const fvec3& n = normal[a];
    00823     const fvec3& t = tan1[a];
    00824
    00825     // Gram-Schmidt orthogonalize
    00826     tangent[a] = (t - n * dot(n, t)).normalize();
    00827
    00828     if ( bitangent )
    00829     {
    00830       // Calculate handedness
    00831       float w = (dot(cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;
    00832       bitangent[a] = cross( n, tangent[a] ) * w;
    00833     }
    00834   }
    00835 }
    00836 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:23.
Permission is granted to use this page to write and publish articles regarding Visualization Library.