CudaPenalityContactForceField.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_GPU_CUDA_CUDAPENALITYCONTACTFORCEFIELD_INL
00026 #define SOFA_GPU_CUDA_CUDAPENALITYCONTACTFORCEFIELD_INL
00027 
00028 #include "CudaPenalityContactForceField.h"
00029 #include <sofa/component/forcefield/PenalityContactForceField.inl>
00030 
00031 
00032 namespace sofa
00033 {
00034 
00035 namespace gpu
00036 {
00037 
00038 namespace cuda
00039 {
00040 
00041 extern "C"
00042 {
00043 void PenalityContactForceFieldCuda3f_setContacts(unsigned int size, unsigned int nbTests, unsigned int maxPoints, const void* tests, const void* outputs, void* contacts, float d0, float stiffness, defaulttype::Mat3x3f xform);
00044 void PenalityContactForceFieldCuda3f_addForce(unsigned int size, const void* contacts, void* penetration, void* f1, const void* x1, const void* v1, void* f2, const void* x2, const void* v2);
00045 void PenalityContactForceFieldCuda3f_addDForce(unsigned int size, const void* contacts, const void* penetration, void* f1, const void* dx1, void* f2, const void* dx2, double factor);
00046 }
00047 
00048 } // namespace cuda
00049 
00050 } // namespace gpu
00051 
00052 namespace component
00053 {
00054 
00055 namespace forcefield
00056 {
00057 
00058 using namespace gpu::cuda;
00059 
00060 //template<>
00061 void PenalityContactForceField<CudaVec3fTypes>::clear(int reserve)
00062 {
00063     //prevContacts.swap(contacts); // save old contacts in prevContacts
00064     contacts.clear();
00065     pen.clear();
00066     if (reserve)
00067     {
00068         contacts.reserve(reserve);
00069         pen.reserve(reserve);
00070     }
00071 }
00072 
00073 //template<>
00074 void PenalityContactForceField<CudaVec3fTypes>::addContact(int /*m1*/, int /*m2*/, const Deriv& norm, Real dist, Real ks, Real /*mu_s*/, Real /*mu_v*/, int /*oldIndex*/)
00075 {
00076     /*
00077     int i = contacts.size();
00078     contacts.resize(i+1);
00079     Contact& c = contacts[i];
00080     c.m1 = m1;
00081     c.m2 = m2;
00082     c.norm = norm;
00083     c.dist = dist;
00084     c.ks = ks;
00085     c.mu_s = mu_s;
00086     c.mu_v = mu_v;
00087     c.pen = 0;
00088     if (oldIndex > 0 && oldIndex <= (int)prevContacts.size())
00089     {
00090        c.age = prevContacts[oldIndex-1].age+1;
00091     }
00092     else
00093     {
00094        c.age = 0;
00095     }
00096     */
00097     sofa::defaulttype::Vec4f c(norm, dist);
00098     Real fact = helper::rsqrt(ks);
00099     c *= fact;
00100     contacts.push_back(c);
00101     pen.push_back(0);
00102 }
00103 
00104 void PenalityContactForceField<CudaVec3fTypes>::setContacts(Real d0, Real stiffness, sofa::core::componentmodel::collision::GPUDetectionOutputVector* outputs, bool useDistance, defaulttype::Mat3x3f* normXForm)
00105 {
00106 #if 1
00107     int n = outputs->size();
00108     contacts.fastResize(n);
00109     pen.fastResize(n);
00110     if (!n) return;
00111     for (int i=0;i<n;i++)
00112     {
00113         const sofa::core::componentmodel::collision::GPUDetectionOutput* o = outputs->get(i);
00114         Real distance = (useDistance) ? d0 + o->distance : d0;
00115         Real ks = (distance > 1.0e-10) ? stiffness / distance : stiffness;
00116         Coord n = (normXForm)?(*normXForm)*o->normal : o->normal;
00117         defaulttype::Vec4f c(n, distance);
00118         c *= helper::rsqrt(ks);
00119         contacts[i] = c;
00120         pen[i] = 0;
00121     }
00122 #else
00123     int n = outputs->size();
00124     int nt = outputs->nbTests();
00125     int maxp = 0;
00126     for (int i=0;i<nt;i++)
00127         if (outputs->rtest(i).curSize > maxp) maxp = outputs->rtest(i).curSize;
00128     contacts.fastResize(n);
00129     pen.fastResize(n);
00130     defaulttype::Mat3x3f xform;
00131     if (normXForm) xform = *normXForm; else xform.identity();
00132     PenalityContactForceFieldCuda3f_setContacts(n, nt, maxp, outputs->tests.deviceRead(), outputs->results.deviceRead(), contacts.deviceWrite(), d0, stiffness, xform);
00133 #endif
00134 }
00135 
00136 //template<>
00137 void PenalityContactForceField<CudaVec3fTypes>::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2)
00138 {
00139     pen.resize(contacts.size());
00140     f1.resize(x1.size());
00141     f2.resize(x2.size());
00142 #if 0
00143     for (unsigned int i=0; i<contacts.size(); i++)
00144     {
00145         sofa::defaulttype::Vec4f c = contacts[i];
00146         //Coord u = x2[c.m2]-x1[c.m1];
00147         Coord u = x2[i]-x1[i];
00148         Coord norm(c[0],c[1],c[2]);
00149         //c.pen = c.dist - u*c.norm;
00150         Real p = c[3] - u*norm;
00151         pen[i] = p;
00152         if (p > 0)
00153         {
00154             //Real fN = c.ks * c.pen;
00155             Deriv force = -norm*p; //fN;
00156             f1[i]+=force;
00157             f2[i]-=force;
00158         }
00159     }
00160 #else
00161     PenalityContactForceFieldCuda3f_addForce(contacts.size(), contacts.deviceRead(), pen.deviceWrite(),
00162         f1.deviceWrite(), x1.deviceRead(), v1.deviceRead(),
00163         f2.deviceWrite(), x2.deviceRead(), v2.deviceRead());
00164 #endif
00165 }
00166 
00167 //template<>
00168 void PenalityContactForceField<CudaVec3fTypes>::addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2, double kFactor, double /*bFactor*/)
00169 {
00170     df1.resize(dx1.size());
00171     df2.resize(dx2.size());
00172 #if 0
00173     for (unsigned int i=0; i<contacts.size(); i++)
00174     {
00175         if (pen[i] > 0) // + dpen > 0)
00176         {
00177             sofa::defaulttype::Vec4f c = contacts[i];
00178             //Coord du = dx2[c.m2]-dx1[c.m1];
00179             Coord du = dx2[i]-dx1[i];
00180             Coord norm(c[0],c[1],c[2]);
00181             Real dpen = - du*norm;
00182             //if (c.pen < 0) dpen += c.pen; // start penality at distance 0
00183             //Real dfN = c.ks * dpen;
00184             Deriv dforce = -norm*(dpen*kFactor); //dfN;
00185             df1[i]+=dforce;
00186             df2[i]-=dforce;
00187         }
00188     }
00189 #else
00190     PenalityContactForceFieldCuda3f_addDForce(contacts.size(), contacts.deviceRead(), pen.deviceWrite(),
00191         df1.deviceWrite(), dx1.deviceRead(),
00192     df2.deviceWrite(), dx2.deviceRead(), kFactor);
00193 #endif
00194 }
00195 
00196 //template<> 
00197 double PenalityContactForceField<CudaVec3fTypes>::getPotentialEnergy(const VecCoord&, const VecCoord&)
00198 {
00199     cerr<<"PenalityContactForceField::getPotentialEnergy-not-implemented !!!"<<endl;
00200     return 0;
00201 }
00202 
00203 //template<>
00204 void PenalityContactForceField<CudaVec3fTypes>::draw()
00205 {
00206     if (!((this->mstate1 == this->mstate2)?getContext()->getShowForceFields():getContext()->getShowInteractionForceFields())) return;
00207     const VecCoord& p1 = *this->mstate1->getX();
00208     const VecCoord& p2 = *this->mstate2->getX();
00209     glDisable(GL_LIGHTING);
00210 
00211     glBegin(GL_LINES);
00212     for (unsigned int i=0; i<contacts.size(); i++)
00213     {
00214         sofa::defaulttype::Vec4f c = contacts[i];
00215         Coord u = p2[i]-p1[i];
00216         Coord norm(c[0],c[1],c[2]);
00217         //c.pen = c.dist - u*c.norm;
00218         Real d = c[3] - u*norm;
00219         /*if (c.age > 10) //c.spen > c.mu_s * c.ks * 0.99)
00220             if (d > 0)
00221                 glColor4f(1,0,1,1);
00222             else
00223                 glColor4f(0,1,1,1);
00224         else*/
00225             if (d > 0)
00226                 glColor4f(1,0,0,1);
00227             else
00228                 glColor4f(0,1,0,1);
00229         helper::gl::glVertexT(p1[i]); //c.m1]);
00230         helper::gl::glVertexT(p2[i]); //c.m2]);
00231     }
00232     glEnd();
00233 
00234     //if (getContext()->getShowNormals())
00235     {
00236         glColor4f(1,1,0,1);
00237         glBegin(GL_LINES);
00238         for (unsigned int i=0; i<contacts.size(); i++)
00239         {
00240             sofa::defaulttype::Vec4f c = contacts[i];
00241             Coord norm(c[0],c[1],c[2]); norm.normalize();
00242             Coord p = p1[i] - norm*0.1;
00243             helper::gl::glVertexT(p1[i]);
00244             helper::gl::glVertexT(p);
00245             p = p2[i] + norm*0.1;
00246             helper::gl::glVertexT(p2[i]);
00247             helper::gl::glVertexT(p);
00248         }
00249         glEnd();
00250     }
00251 }
00252 
00253 } // namespace forcefield
00254 
00255 } // namespace component
00256 
00257 } // namespace sofa
00258 
00259 #endif

Generated on Sun Nov 23 04:00:08 2008 for Sofa by  doxygen 1.5.7.1