SphereModel.inl

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 #ifndef SOFA_COMPONENT_COLLISION_SPHEREMODEL_INL
00026 #define SOFA_COMPONENT_COLLISION_SPHEREMODEL_INL
00027 
00028 #include <sofa/component/collision/SphereModel.h>
00029 #include <sofa/helper/io/SphereLoader.h>
00030 #include <sofa/component/collision/CubeModel.h>
00031 #include <sofa/helper/system/FileRepository.h>
00032 #include <sofa/helper/system/gl.h>
00033 #include <sofa/helper/system/glut.h>
00034 
00035 namespace sofa
00036 {
00037 
00038 namespace component
00039 {
00040 
00041 namespace collision
00042 {
00043 
00044 template<class TDataTypes>
00045 TSphereModel<TDataTypes>::TSphereModel()
00046 : radius(initData(&radius, "listRadius","Radius of each sphere")), 
00047   defaultRadius(initData(&defaultRadius,(SReal)(1.0), "radius","Default Radius"))
00048 {
00049   if (radius.getValue().size() == 0)
00050   {
00051     resize(getSize()); // make sure the CollisionModel and the MechanicalObject have the same size
00052     for(unsigned int i=0;i<this->radius.getValue().size();i++) setRadius(i, -1);
00053   }
00054 }
00055 
00056 
00057 template<class TDataTypes>
00058 TSphereModel<TDataTypes>::TSphereModel(SReal r)
00059   : radius(initData(&radius, "listRadius","Radius of each sphere")), 
00060     defaultRadius(initData(&defaultRadius, r,"radius","Default Radius"))
00061 {
00062     resize(getSize()); // make sure the CollisionModel and the MechanicalObject have the same size
00063     for(unsigned int i=0;i<this->radius.getValue().size();i++) setRadius(i, r);
00064 }
00065 
00066 template<class TDataTypes>
00067 void TSphereModel<TDataTypes>::init()
00068 {
00069     Inherit::init();
00070     for(unsigned int i=0;i<this->radius.getValue().size();i++)
00071       if (getRadius(i)==-1) setRadius(i,defaultRadius.getValue());
00072 }
00073 
00074 template<class TDataTypes>
00075 void TSphereModel<TDataTypes>::resize(int size)
00076 {
00077     this->component::MechanicalObject<InDataTypes>::resize(size);
00078     this->core::CollisionModel::resize(size);
00079     if ((int)radius.getValue().size() < size)
00080     {
00081         radius.beginEdit()->reserve(size);
00082         while ((int)radius.getValue().size() < size)
00083             radius.beginEdit()->push_back(defaultRadius.getValue());
00084     }
00085     else
00086     {
00087         radius.beginEdit()->resize(size);
00088     }
00089 }
00090 
00091 template<class TDataTypes>
00092 int TSphereModel<TDataTypes>::addSphere(const Vector3& pos, SReal radius)
00093 {
00094     int i = size;
00095     resize(i+1);
00096     setSphere(i, pos, radius);
00097     return i;
00098 }
00099 
00100 template<class TDataTypes>
00101 void TSphereModel<TDataTypes>::setSphere(int i, const Vector3& pos, SReal r)
00102 {
00103     if ((unsigned)i >= (unsigned) size) return;
00104     (*this->getX())[i] = pos;
00105     setRadius(i,r);
00106 }
00107 
00108 template<class TDataTypes>
00109 class TSphereModel<TDataTypes>::Loader : public helper::io::SphereLoader
00110 {
00111 public:
00112     TSphereModel<TDataTypes>* dest;
00113     Loader(TSphereModel<TDataTypes>* dest) : dest(dest) { }
00114     void addSphere(SReal x, SReal y, SReal z, SReal r)
00115     {
00116         dest->addSphere(Vector3(x,y,z),r);
00117     }
00118 };
00119 
00120 template<class TDataTypes>
00121 bool TSphereModel<TDataTypes>::load(const char* filename)
00122 {
00123         this->resize(0);
00124         std::string sphereFilename(filename);       
00125         if (!sofa::helper::system::DataRepository.findFile (sphereFilename))                 
00126           logWarning(std::string("Sphere File \"") + filename +std::string("\" not found")); 
00127      Loader loader(this);
00128      return loader.load(filename);
00129         
00130         
00131 }
00132 
00133 template<class TDataTypes>
00134 void TSphereModel<TDataTypes>::applyScale(SReal s)
00135 {
00136     Inherit::applyScale(s);
00137     //std::cout << "Applying scale " << s << " to " << size << " spheres" << std::endl;
00138     for (int i=0;i<size;i++) setRadius(i, getRadius(i)*s);
00139 }
00140 
00141 template<class TDataTypes>
00142 void TSphereModel<TDataTypes>::draw(int index)
00143 {
00144     const typename TDataTypes::VecCoord& x = *(((const TSphereModel<TDataTypes>*)this)->getX());
00145     Vector3 p = x[index];
00146     glPushMatrix();
00147     glTranslated(p[0], p[1], p[2]);
00148     //glutSolidSphere(radius[index], 8, 4);
00149     glutSolidSphere(getRadius(index), 32,16);
00150     glPopMatrix();
00151 }
00152 
00153 template<class TDataTypes>
00154 void TSphereModel<TDataTypes>::draw()
00155 {
00156     if (getContext()->getShowCollisionModels())
00157     {
00158         glEnable(GL_LIGHTING);
00159         glEnable(GL_COLOR_MATERIAL);
00160         //glDisable(GL_LIGHTING);
00161         glColor4fv(getColor4f());
00162         for (int i=0;i<size;i++)
00163         {
00164             draw(i);
00165         }
00166         glDisable(GL_LIGHTING);
00167         glDisable(GL_COLOR_MATERIAL);
00168     }
00169     if (getPrevious()!=NULL && getContext()->getShowBoundingCollisionModels())
00170         getPrevious()->draw();
00171 }
00172 
00173 template<class TDataTypes>
00174 void TSphereModel<TDataTypes>::computeBoundingTree(int maxDepth)
00175 {
00176     CubeModel* cubeModel = createPrevious<CubeModel>();
00177     if (!isMoving() && !cubeModel->empty()) return; // No need to recompute BBox if immobile
00178     
00179     Vector3 minElem, maxElem;
00180 
00181     cubeModel->resize(size);
00182     if (!empty())
00183     {
00184         const typename TDataTypes::VecCoord& x = *(((const TSphereModel<TDataTypes>*)this)->getX());
00185         for (int i=0;i<size;i++)
00186         {
00187             SReal r = getRadius(i);
00188             for (int c=0;c<3;c++)
00189             {
00190                 minElem[c] = x[i][c] - r;
00191                 maxElem[c] = x[i][c] + r;
00192             }
00193             cubeModel->setParentOf(i, minElem, maxElem);
00194         }
00195         cubeModel->computeBoundingTree(maxDepth);
00196     }
00197 }
00198 
00199 template<class TDataTypes>
00200 void TSphereModel<TDataTypes>::computeContinuousBoundingTree(double dt, int maxDepth)
00201 {
00202     CubeModel* cubeModel = createPrevious<CubeModel>();
00203     if (!isMoving() && !cubeModel->empty()) return; // No need to recompute BBox if immobile
00204     
00205     Vector3 minElem, maxElem;
00206 
00207     cubeModel->resize(this->size);
00208     if (!empty())
00209     {
00210         const typename TDataTypes::VecCoord& x = *this->getX();
00211         const typename TDataTypes::VecDeriv& v = *this->getV();
00212         for (int i=0;i<this->size;i++)
00213         {
00214             SReal r = getRadius(i);
00215             for (int c=0;c<3;c++)
00216             {
00217                 if (v[i][c] < 0)
00218                 {
00219                     minElem[c] = x[i][c] + v[i][c]*dt - r;
00220                     maxElem[c] = x[i][c]           + r;
00221                 }
00222                 else
00223                 {
00224                     minElem[c] = x[i][c]           - r;
00225                     maxElem[c] = x[i][c] + v[i][c]*dt + r;
00226                 }
00227             }
00228             cubeModel->setParentOf(i, minElem, maxElem);
00229         }
00230         cubeModel->computeBoundingTree(maxDepth);
00231     }
00232 }
00233 
00234 } // namespace collision
00235 
00236 } // namespace component
00237 
00238 } // namespace sofa
00239 
00240 #endif

Generated on Sun Nov 23 02:35:24 2008 for Sofa by  doxygen 1.5.7.1