TriangleOctreeModel.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #include <sofa/component/collision/TriangleModel.h>
00026 #include <sofa/component/collision/TriangleOctreeModel.h>
00027 #include <sofa/component/collision/CubeModel.h>
00028 #include <sofa/component/collision/Triangle.h>
00029 #include <sofa/core/CollisionElement.h>
00030 #include <sofa/core/ObjectFactory.h>
00031 #include <vector>
00032 #include <sofa/helper/system/thread/CTime.h>
00033 
00034 #include <cmath>
00035 #include <sofa/helper/system/gl.h>
00036 #include <sofa/helper/system/glut.h>
00037 
00038 namespace sofa
00039 {
00040 
00041   namespace component
00042   {
00043       namespace topology
00044       {
00045           typedef core::componentmodel::topology::BaseMeshTopology::Triangle    Triangle;
00046       }
00047 
00048     namespace collision
00049     {
00050 
00051       using sofa::helper::system::thread::CTime;
00052       using sofa::helper::system::thread::ctime_t;
00053 
00054 
00055   TriangleAABB::TriangleAABB (Triangle & t)
00056       {
00057         for (int i = 0; i < 3; i++)
00058           {
00059 
00060             bb[i * 2] = bb_min3 (t.p1 ()[i], t.p2 ()[i], t.p3 ()[i]);
00061             bb[(i * 2) + 1] = bb_max3 (t.p1 ()[i], t.p2 ()[i], t.p3 ()[i]);
00062             
00063         m_size =
00064           bb_max3 (fabs (bb[1] - bb[0]), fabs (bb[3] - bb[2]),
00065                    fabs (bb[5] - bb[4]));
00066         
00067 
00068       }
00069 }
00070 
00071 
00072 
00073     
00074     int TriangleOctreeModelClass =  core::RegisterObject ("collision model using a triangular mesh mapped to an Octree").add <  TriangleOctreeModel > ().addAlias ("TriangleOctree");
00075 
00076         TriangleOctreeModel::TriangleOctreeModel ()
00077       {
00078     octreeRoot = NULL;
00079     cubeSize = CUBE_SIZE;
00080       }
00081 
00082 
00083 
00084  void TriangleOctreeModel::draw ()
00085       {
00086 
00087         if (isActive () && getContext ()->getShowCollisionModels ())
00088           {
00089             if (getContext ()->getShowWireFrame ())
00090               glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00091 
00092             glEnable (GL_LIGHTING);
00093             //Enable<GL_BLEND> blending;
00094             //glLightModeli(GL  _LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00095 
00096         glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, getColor4f());
00097             static const float emissive[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
00098             static const float specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
00099             glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive);
00100             glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
00101             glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 20);
00102         if(octreeRoot)
00103               octreeRoot->draw ();
00104    
00105             glColor3f (1.0f, 1.0f, 1.0f);
00106             glDisable (GL_LIGHTING);
00107             if (getContext ()->getShowWireFrame ())
00108               glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00109           }
00110       }
00111 
00112       int TriangleOctreeModel::fillOctree (int tId, int /*d*/, Vector3 /*v*/)
00113       {
00114 
00115 
00116     Vector3 center;
00117     Triangle t (this, tId);
00118     Vector3 corner (-cubeSize, -cubeSize, -cubeSize);
00119 
00120     TriangleAABB aabb (t);
00121     double *bb = aabb.getAABB ();
00122     /*Computes the depth of the bounding box in a octree
00123 
00124      */
00125     int d1 = (int)((log10( (double) CUBE_SIZE * 2) / log10( (double)2) )/ aabb.size ());
00126     /*computes the size of the octree box that can store the bounding box */
00127     int divs = (1 << (d1));
00128     double inc = (double) (2 * CUBE_SIZE) / divs;
00129     if (bb[0] >= -CUBE_SIZE && bb[2] >= -CUBE_SIZE && bb[4] >= -CUBE_SIZE
00130         && bb[1] <= CUBE_SIZE && bb[3] <= CUBE_SIZE && bb[5] <= CUBE_SIZE)
00131       for (double x1 =
00132            (((int)((bb[0] + CUBE_SIZE) / inc)) * inc - CUBE_SIZE);
00133            x1 <= bb[1]; x1 += inc)
00134         {
00135 
00136           for (double y1 =
00137            ((int)((bb[2] + CUBE_SIZE) / inc)) * inc - CUBE_SIZE;
00138            y1 <= bb[3]; y1 += inc)
00139         {
00140 
00141 
00142           for (double z1 =
00143                ((int)((bb[4] + CUBE_SIZE) / inc)) * inc - CUBE_SIZE;
00144                z1 <= bb[5]; z1 += inc)
00145             {
00146               octreeRoot->insert (x1, y1, z1, inc, tId);
00147 
00148             }
00149         }
00150         }
00151     return 0;
00152 
00153       }
00154 void TriangleOctreeModel::computeBoundingTree(int maxDepth)
00155 {
00156     const helper::vector<topology::Triangle>& tri = *triangles;
00157     if(octreeRoot){
00158         delete octreeRoot;
00159         octreeRoot=NULL;    
00160     }
00161 
00162     CubeModel* cubeModel = createPrevious<CubeModel>();
00163      updateFromTopology();
00164     
00165     if (!isMoving() && !cubeModel->empty()) return; // No need to recompute BBox if immobile
00166         int size2=mstate->getX()->size();
00167     pNorms.resize(size2);
00168     for(int i=0;i<size2;i++){
00169         pNorms[i]=Vector3(0,0,0);
00170     }
00171     Vector3 minElem, maxElem;
00172     maxElem[0]=minElem[0]=(*mstate->getX())[0][0];
00173     maxElem[1]=minElem[1]=(*mstate->getX())[0][1];
00174     maxElem[2]=minElem[2]=(*mstate->getX())[0][2];
00175         
00176     cubeModel->resize(1);  // size = number of triangles
00177         for (int i=1;i<size;i++)
00178         {
00179         Triangle t(this,i);
00180         pNorms[tri[i][0]]+=t.n();
00181         pNorms[tri[i][1]]+=t.n();
00182         pNorms[tri[i][2]]+=t.n();
00183 const Vector3* pt[3];
00184             pt[0] = &t.p1();
00185             pt[1] = &t.p2();
00186             pt[2] = &t.p3();
00187         t.n() = cross(*pt[1]-*pt[0],*pt[2]-*pt[0]);
00188             t.n().normalize();
00189 
00190         for (int p=0;p<3;p++)
00191         {
00192         
00193 
00194         for(int c=0;c<3;c++){
00195                      if ((*pt[p])[c] > maxElem[c]) maxElem[c] = (*pt[p])[c];
00196                     if ((*pt[p])[c] < minElem[c]) minElem[c] = (*pt[p])[c];
00197                 
00198             }
00199         }
00200             
00201         }
00202 
00203                         cubeModel->setParentOf(0, minElem, maxElem); // define the bounding box of the current triangle
00204         cubeModel->computeBoundingTree(maxDepth);
00205     for(int i=0;i<size2;i++){
00206         pNorms[i].normalize();
00207     }
00208     if(!pTri.size()){
00209     /*creates the list of triangles that are associated to a point*/
00210     pTri.resize(size2);
00211         for(int i=0;i<size;i++)
00212         {
00213            pTri[tri[i][0]].push_back(i);    
00214     
00215            pTri[tri[i][1]].push_back(i);
00216            pTri[tri[i][2]].push_back(i);
00217         }
00218     }
00219 }
00220  
00221 void TriangleOctreeModel::computeContinuousBoundingTree(double/* dt*/, int maxDepth){
00222         computeBoundingTree(maxDepth);
00223 
00224     }
00225       void TriangleOctreeModel::buildOctree ()
00226       {
00227     octreeRoot = new TriangleOctree (this);
00228 
00229     /*for each triangle add it to the octree*/
00230     for (size_t i = 0; i < elems.size (); i++)
00231       {
00232 
00233         fillOctree (i);
00234 
00235       }
00236       }
00237 
00238     }               // namespace collision
00239 
00240   }             // namespace component
00241 
00242 }               // namespace sofa

Generated on Sun Nov 23 02:37:12 2008 for Sofa by  doxygen 1.5.7.1