CudaCollisionDetection.h

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_CUDACOLLISIONDETECTION_H
00026 #define SOFA_GPU_CUDA_CUDACOLLISIONDETECTION_H
00027 
00028 #include <sofa/core/componentmodel/collision/DetectionOutput.h>
00029 #include <sofa/component/collision/BruteForceDetection.h>
00030 #include <sofa/gpu/cuda/CudaDistanceGridCollisionModel.h>
00031 #include <sofa/gpu/cuda/CudaSphereModel.h>
00032 #include <sofa/gpu/cuda/CudaPointModel.h>
00033 
00034 
00035 namespace sofa
00036 {
00037 
00038 namespace core
00039 {
00040 
00041 namespace componentmodel
00042 {
00043 
00044 namespace collision
00045 {
00046 
00047 using defaulttype::Vec3f;
00048 
00061 struct GPUDetectionOutput
00062 {
00063     int p1;
00064     Vec3f p2;
00065     union {
00066         float distance;
00067         int i2;
00068     };
00069     Vec3f normal;
00070 };
00071 
00075 class GPUDetectionOutputVector : public DetectionOutputVector
00076 {
00077 public:
00078     sofa::gpu::cuda::CudaVector<GPUDetectionOutput> results;
00079     struct TestEntry
00080     {
00081         int firstIndex; 
00082         int maxSize; 
00083         int curSize; 
00084         int newIndex; 
00085         std::pair<int,int> elems; 
00086         TestEntry() : firstIndex(0), maxSize(0), curSize(0), newIndex(0), elems(std::make_pair(0,0)) {}
00087     };
00088     sofa::gpu::cuda::CudaVector< TestEntry > tests;
00089 
00090     ~GPUDetectionOutputVector()
00091     {
00092     }
00093 
00094     unsigned int size() const
00095     {
00096         if (results.empty()) return 0;
00097         int s = 0;
00098         for (unsigned int i=0;i<tests.size();i++)
00099             s += tests[i].curSize;
00100         return s;
00101     }
00102 
00103     void clear()
00104     {
00105         results.clear();
00106         tests.clear();
00107     }
00108 
00109     unsigned int nbTests() { return tests.size(); }
00110 
00111     const TestEntry& rtest(int i) { return tests[i]; }
00112     TestEntry& wtest(int i) { return tests[i]; }
00113 
00114     int addTest(std::pair<int,int> elems, int maxSize)
00115     {
00116         int t = tests.size();
00117         TestEntry e;
00118         e.elems = elems;
00119         e.firstIndex = results.size();
00120         e.maxSize = maxSize;
00121         e.curSize = 0;
00122         e.newIndex = 0;
00123         results.fastResize(e.firstIndex+maxSize);
00124         tests.push_back(e);
00125         return t;
00126     }
00127 
00128     const GPUDetectionOutput* get(int i)
00129     {
00130         unsigned int t=0;
00131         while(t<nbTests() && rtest(t).newIndex > i) ++t;
00132         if (t<nbTests())
00133             return &(results[rtest(t).firstIndex + (i-rtest(t).newIndex)]);
00134         else
00135             return NULL;
00136     }
00137 };
00138 
00139 
00140 
00141 template<>
00142 class TDetectionOutputVector<sofa::gpu::cuda::CudaRigidDistanceGridCollisionModel,sofa::gpu::cuda::CudaRigidDistanceGridCollisionModel> : public GPUDetectionOutputVector
00143 {
00144 };
00145 
00146 template<>
00147 class TDetectionOutputVector<sofa::gpu::cuda::CudaSphereModel,sofa::gpu::cuda::CudaRigidDistanceGridCollisionModel> : public GPUDetectionOutputVector
00148 {
00149 };
00150 
00151 template<>
00152 class TDetectionOutputVector<sofa::gpu::cuda::CudaPointModel,sofa::gpu::cuda::CudaRigidDistanceGridCollisionModel> : public GPUDetectionOutputVector
00153 {
00154 };
00155 
00156 } // namespace collision
00157 
00158 } // namespace componentmodel
00159 
00160 } // namespace core
00161 
00162 namespace gpu
00163 {
00164 
00165 namespace cuda
00166 {
00167 
00168 
00169 
00170 class CudaCollisionDetection : public sofa::component::collision::BruteForceDetection
00171 {
00172 public:
00173     typedef sofa::component::collision::BruteForceDetection Inherit;
00174     struct GPUTest
00175     {
00176         void* result;
00177         const void* points;
00178         const void* radius;
00179         const void* grid;
00180         Mat3x3f rotation;
00181         Vec3f translation;
00182         float margin;
00183         int nbPoints;
00184         int gridnx, gridny, gridnz;
00185         Vec3f gridbbmin, gridbbmax;
00186         Vec3f gridp0, gridinvdp;
00187     };
00188 
00189     /*struct GPUContact
00190     {
00191         int p1;
00192         Vec3f p2;
00193         float distance;
00194         Vec3f normal;
00195     };*/
00196     typedef sofa::core::componentmodel::collision::GPUDetectionOutput GPUContact;
00197     typedef sofa::core::componentmodel::collision::GPUDetectionOutputVector GPUOutputVector;
00198 
00199     CudaVector<GPUTest> gputests;
00200     CudaVector<int> gpuresults; 
00201 
00202     typedef sofa::core::componentmodel::collision::DetectionOutputVector DetectionOutputVector;
00203 
00204     class Test
00205     {
00206     public:
00207         GPUOutputVector results;
00208         Test() {}
00209         virtual ~Test()
00210         {
00211         }
00212         virtual bool useGPU()=0;
00214         virtual int init()=0;
00216         virtual void fillInfo(GPUTest* tests)=0;
00218         //virtual void fillContacts(DetectionOutputVector& contacts, const int* nresults)=0;
00219     };
00220 
00221     class CPUTest : public Test
00222     {
00223     public:
00224         CPUTest() {}
00225         bool useGPU() { return false; }
00226         int init() { return 0; }
00227         void fillInfo(GPUTest* /*tests*/) {}
00228         //void fillContacts(DetectionOutputVector& /*contacts*/, const int* /*nresults*/) {}
00229     };
00230 
00231     class RigidRigidTest : public Test
00232     {
00233     public:
00234         CudaRigidDistanceGridCollisionModel* model1;
00235         CudaRigidDistanceGridCollisionModel* model2;
00236         RigidRigidTest(CudaRigidDistanceGridCollisionModel* model1, CudaRigidDistanceGridCollisionModel* model2);
00237         bool useGPU() { return true; }
00239         virtual int init();
00241         virtual void fillInfo(GPUTest* tests);
00243         //void fillContacts(DetectionOutputVector& contacts, const int* nresults);
00244 
00245     protected:
00246         //void fillInfo(GPUTest& test, CudaVector<GPUContact>& gpucontacts, CudaRigidDistanceGridCollisionElement elem1, CudaRigidDistanceGridCollisionElement elem2);
00247         //void fillContacts(DetectionOutputVector& contacts, int nresults, CudaVector<GPUContact>& gpucontacts, CudaRigidDistanceGridCollisionElement e1, CudaRigidDistanceGridCollisionElement e2, bool invert);
00248     };
00249 
00250     class SphereRigidTest : public Test
00251     {
00252     public:
00253         CudaSphereModel* model1;
00254         CudaRigidDistanceGridCollisionModel* model2;
00255         SphereRigidTest(CudaSphereModel* model1, CudaRigidDistanceGridCollisionModel* model2);
00256         bool useGPU() { return true; }
00258         virtual int init();
00260         virtual void fillInfo(GPUTest* tests);
00262         //void fillContacts(DetectionOutputVector& contacts, const int* nresults);
00263     };
00264 
00265     class PointRigidTest : public Test
00266     {
00267     public:
00268         CudaPointModel* model1;
00269         CudaRigidDistanceGridCollisionModel* model2;
00270         PointRigidTest(CudaPointModel* model1, CudaRigidDistanceGridCollisionModel* model2);
00271         bool useGPU() { return true; }
00273         virtual int init();
00275         virtual void fillInfo(GPUTest* tests);
00277         //void fillContacts(DetectionOutputVector& contacts, const int* nresults);
00278 
00279     protected:
00280         //void fillInfo(GPUTest& test, CudaVector<GPUContact>& gpucontacts, CudaRigidDistanceGridCollisionElement elem1, CudaRigidDistanceGridCollisionElement elem2);
00281         //void fillContacts(DetectionOutputVector& contacts, int nresults, CudaVector<GPUContact>& gpucontacts, CudaRigidDistanceGridCollisionElement e1, CudaRigidDistanceGridCollisionElement e2, bool invert);
00282     };
00283 
00284     struct Entry
00285     {
00286         int index; // negative if not active
00287         Test* test;
00288         Entry() : index(-1), test(NULL) {}
00289         ~Entry() { if (test!=NULL) delete test; }
00290     };
00291 
00292     typedef std::map< std::pair<core::CollisionModel*, core::CollisionModel*>, Entry > TestMap;
00293 
00294     TestMap tests;
00295 
00296     virtual void beginNarrowPhase();
00297     virtual void addCollisionPair (const std::pair<core::CollisionModel*, core::CollisionModel*>& cmPair);
00298     virtual void endNarrowPhase();
00299 
00300 protected:
00301     Test* createTest(core::CollisionModel* model1, core::CollisionModel* model2);
00302 };
00303 
00304 } // namespace cuda
00305 
00306 } // namespace gpu
00307 
00308 } // namespace sofa
00309 
00310 #endif

Generated on Sun Nov 23 03:57:23 2008 for Sofa by  doxygen 1.5.7.1