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 #include "CudaDistanceGridCollisionModel.h"
00026 #include "CudaSphereModel.h"
00027 #include "CudaPointModel.h"
00028 #include <sofa/component/collision/NewProximityIntersection.inl>
00029 #include <sofa/component/collision/DiscreteIntersection.inl>
00030 #include <sofa/component/collision/RayPickInteractor.inl>
00031 #include <sofa/component/collision/RayContact.h>
00032 #include "CudaContactMapper.h"
00033 #include <sofa/component/collision/BarycentricPenalityContact.inl>
00034 #include <sofa/component/collision/BarycentricContactMapper.inl>
00035 #include <sofa/component/forcefield/PenalityContactForceField.h>
00036 #include "CudaPenalityContactForceField.h"
00037 #include "CudaSpringForceField.h"
00038 #include <sofa/component/forcefield/VectorSpringForceField.h>
00039 #include <fstream>
00040 #include <sofa/helper/system/gl.h>
00041 #include <sofa/helper/Factory.inl>
00042
00043 namespace sofa
00044 {
00045
00046 namespace component
00047 {
00048
00049 namespace collision
00050 {
00051
00052 using namespace sofa::gpu::cuda;
00053
00054 template <>
00055 void BarycentricPenalityContact<CudaPointModel,CudaRigidDistanceGridCollisionModel,CudaVec3fTypes>::setDetectionOutputs(OutputVector* o)
00056 {
00057 TOutputVector& outputs = *static_cast<TOutputVector*>(o);
00058
00059 if (ff==NULL)
00060 {
00061 MechanicalState1* mstate1 = mapper1.createMapping("contactPointsCUDA");
00062 MechanicalState2* mstate2 = mapper2.createMapping("contactPointsCUDA");
00063 ff = new ResponseForceField(mstate1,mstate2);ff->setName( getName());
00064 }
00065
00066 mapper1.setPoints1(&outputs);
00067 mapper2.setPoints2(&outputs);
00068 const double d0 = intersectionMethod->getContactDistance() + model1->getProximity() + model2->getProximity();
00069 #if 0
00070 int insize = outputs.size();
00071 int size = insize;
00072 ff->clear(size);
00073
00074 for (int i=0; i<insize; i++)
00075 {
00076 int index = i;
00077 if (index < 0) continue;
00078
00079
00080
00081
00082
00083 int index1 = index;
00084 int index2 = index;
00086
00088
00089 double distance = d0 + outputs.get(i)->distance;
00090 double stiffness = (model1->getContactStiffness(0) * model1->getContactStiffness(0))/distance;
00091 double mu_v = (model1->getContactFriction(0) + model1->getContactFriction(0));
00092 ff->addContact(index1, index2, outputs.get(i)->normal, (float)distance, (float)stiffness, (float)mu_v, (float)mu_v, index);
00093 }
00094 #else
00095 double distance = d0;
00096 double stiffness = (model1->getContactStiffness(0) * model1->getContactStiffness(0));
00097 ff->setContacts((float)distance, (float)stiffness, &outputs, true);
00098 #endif
00099
00100 mapper1.update();
00101 mapper2.update();
00102 }
00103
00104 template <>
00105 void BarycentricPenalityContact<CudaSphereModel,CudaRigidDistanceGridCollisionModel,CudaVec3fTypes>::setDetectionOutputs(OutputVector* o)
00106 {
00107 TOutputVector& outputs = *static_cast<TOutputVector*>(o);
00108
00109 if (ff==NULL)
00110 {
00111 MechanicalState1* mstate1 = mapper1.createMapping("contactPointsCUDA");
00112 MechanicalState2* mstate2 = mapper2.createMapping("contactPointsCUDA");
00113 ff = new ResponseForceField(mstate1,mstate2); ff->setName( getName());
00114 }
00115
00116 mapper1.setPoints1(&outputs);
00117 mapper2.setPoints2(&outputs);
00118 const double d0 = intersectionMethod->getContactDistance() + model1->getProximity() + model2->getProximity();
00119 #if 0
00120 int insize = outputs.size();
00121 int size = insize;
00122 ff->clear(size);
00123
00124 for (int i=0; i<insize; i++)
00125 {
00126 int index = i;
00127 if (index < 0) continue;
00128
00129
00130
00131
00132
00133 int index1 = index;
00134 int index2 = index;
00136
00138
00139 double distance = d0 + outputs.get(i)->distance;
00140 double stiffness = (model1->getContactStiffness(0) * model1->getContactStiffness(0))/distance;
00141 double mu_v = (model1->getContactFriction(0) + model1->getContactFriction(0));
00142 ff->addContact(index1, index2, outputs.get(i)->normal, (float)distance, (float)stiffness, (float)mu_v, (float)mu_v, index);
00143 }
00144 #else
00145 double distance = d0;
00146 double stiffness = (model1->getContactStiffness(0) * model1->getContactStiffness(0));
00147 ff->setContacts((float)distance, (float)stiffness, &outputs, true);
00148 #endif
00149
00150 mapper1.update();
00151 mapper2.update();
00152 }
00153
00154
00155 ContactMapperCreator< ContactMapper<CudaSphereModel, CudaVec3fTypes> > CudaSphereCudaContactMapperClass("default",true);
00156
00157 template<>
00158 void DefaultPickingManager<CudaVec3fTypes,forcefield::StiffSpringForceField<CudaVec3fTypes> >::addContact(forcefield::StiffSpringForceField<CudaVec3fTypes>* ff, int index1, int index2, double stiffness, double mu_v, double length, const Vector3& , const Vector3& )
00159 {
00160 ff->addSpring(index1, index2, stiffness, mu_v, length);
00161 }
00162
00163 template class DefaultPickingManager< CudaVec3fTypes, forcefield::StiffSpringForceField<CudaVec3fTypes> >;
00164
00165
00166 helper::Creator<BasePickingManager::PickingManagerFactory, DefaultPickingManager< CudaVec3fTypes, forcefield::StiffSpringForceField<CudaVec3fTypes> > > PickingVectorSpringCudaClass ("VectorSpringCUDA",true);
00167
00168 }
00169
00170
00171 }
00172
00173
00174 namespace gpu
00175 {
00176
00177 namespace cuda
00178 {
00179
00180 SOFA_DECL_CLASS(CudaCollision)
00181
00182 using namespace sofa::component::collision;
00183
00184 class CudaProximityIntersection : public sofa::component::collision::NewProximityIntersection
00185 {
00186 public:
00187
00188 virtual void init()
00189 {
00190 sofa::component::collision::NewProximityIntersection::init();
00191 intersectors.add<RayModel, CudaSphereModel, DiscreteIntersection>(this);
00192
00193 intersectors.add<CudaSphereModel, CudaSphereModel, DiscreteIntersection>(this);
00194
00195 intersectors.add<TriangleModel, CudaSphereModel, CudaProximityIntersection>(this);
00196 }
00197
00198 };
00199
00200
00201 int CudaProximityIntersectionClass = core::RegisterObject("GPGPU Proximity Intersection based on CUDA")
00202 .add< CudaProximityIntersection >()
00203 ;
00204
00205 sofa::helper::Creator<core::componentmodel::collision::Contact::Factory, component::collision::RayContact<CudaSphereModel> > RayCudaSphereContactClass("ray",true);
00206
00207
00208
00209 sofa::helper::Creator<sofa::core::componentmodel::collision::Contact::Factory, sofa::component::collision::BarycentricPenalityContact<CudaPointModel, CudaRigidDistanceGridCollisionModel,CudaVec3fTypes> > CudaPointCudaDistanceGridContactClass("default", true);
00210 sofa::helper::Creator<sofa::core::componentmodel::collision::Contact::Factory, sofa::component::collision::BarycentricPenalityContact<CudaSphereModel, CudaRigidDistanceGridCollisionModel,CudaVec3fTypes> > CudaSphereCudaDistanceGridContactClass("default", true);
00211
00212
00213
00214
00215
00216
00217 }
00218
00219 }
00220
00221 }