CudaCollisionDetection.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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 }
00157
00158 }
00159
00160 }
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
00190
00191
00192
00193
00194
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
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* ) {}
00228
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
00244
00245 protected:
00246
00247
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
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
00278
00279 protected:
00280
00281
00282 };
00283
00284 struct Entry
00285 {
00286 int index;
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 }
00305
00306 }
00307
00308 }
00309
00310 #endif