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_CUDAUNIFORMMASS_INL
00026 #define SOFA_GPU_CUDA_CUDAUNIFORMMASS_INL
00027
00028 #include "CudaUniformMass.h"
00029 #include <sofa/component/mass/UniformMass.inl>
00030 #include <sofa/helper/gl/Axis.h>
00031
00032 namespace sofa
00033 {
00034
00035 namespace gpu
00036 {
00037
00038 namespace cuda
00039 {
00040
00041 extern "C"
00042 {
00043 void UniformMassCuda3f_addMDx(unsigned int size, float mass, void* res, const void* dx);
00044 void UniformMassCuda3f_accFromF(unsigned int size, float mass, void* a, const void* f);
00045 void UniformMassCuda3f_addForce(unsigned int size, const float *mg, void* f);
00046
00047 void UniformMassCuda3f1_addMDx(unsigned int size, float mass, void* res, const void* dx);
00048 void UniformMassCuda3f1_accFromF(unsigned int size, float mass, void* a, const void* f);
00049 void UniformMassCuda3f1_addForce(unsigned int size, const float *mg, void* f);
00050
00051 }
00052
00053 }
00054
00055 }
00056
00057 namespace component
00058 {
00059
00060 namespace mass
00061 {
00062
00063 using namespace gpu::cuda;
00064
00065
00066 template <>
00067 void UniformMass<CudaVec3fTypes, float>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00068 {
00069 UniformMassCuda3f_addMDx(dx.size(), (float)(mass.getValue()*factor), res.deviceWrite(), dx.deviceRead());
00070 }
00071
00072 template <>
00073 void UniformMass<CudaVec3fTypes, float>::accFromF(VecDeriv& a, const VecDeriv& f)
00074 {
00075 UniformMassCuda3f_accFromF(f.size(), mass.getValue(), a.deviceWrite(), f.deviceRead());
00076 }
00077
00078 template <>
00079 void UniformMass<CudaVec3fTypes, float>::addForce(VecDeriv& f, const VecCoord&, const VecDeriv&)
00080 {
00081
00082 Vec3d g ( this->getContext()->getLocalGravity() );
00083 Deriv theGravity;
00084 DataTypes::set( theGravity, g[0], g[1], g[2]);
00085 Deriv mg = theGravity * mass.getValue();
00086 UniformMassCuda3f_addForce(f.size(), mg.ptr(), f.deviceWrite());
00087 }
00088
00089 template <>
00090 bool UniformMass<gpu::cuda::CudaVec3fTypes, float>::addBBox(double* minBBox, double* maxBBox)
00091 {
00092 const VecCoord& x = *this->mstate->getX();
00093
00094 for (unsigned int i=0; i<x.size(); i++)
00095 {
00096
00097 const Coord& p = x.getCached(i);
00098 for (int c=0;c<3;c++)
00099 {
00100 if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
00101 if (p[c] < minBBox[c]) minBBox[c] = p[c];
00102 }
00103 }
00104 return true;
00105 }
00106
00107 template <>
00108 void UniformMass<CudaVec3f1Types, float>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00109 {
00110 UniformMassCuda3f1_addMDx(dx.size(), (float)(mass.getValue()*factor), res.deviceWrite(), dx.deviceRead());
00111 }
00112
00113 template <>
00114 void UniformMass<CudaVec3f1Types, float>::accFromF(VecDeriv& a, const VecDeriv& f)
00115 {
00116 UniformMassCuda3f1_accFromF(f.size(), mass.getValue(), a.deviceWrite(), f.deviceRead());
00117 }
00118
00119 template <>
00120 void UniformMass<CudaVec3f1Types, float>::addForce(VecDeriv& f, const VecCoord&, const VecDeriv&)
00121 {
00122
00123 Vec3d g ( this->getContext()->getLocalGravity() );
00124 Deriv theGravity;
00125 DataTypes::set( theGravity, g[0], g[1], g[2]);
00126 Deriv mg = theGravity * mass.getValue();
00127 UniformMassCuda3f1_addForce(f.size(), mg.ptr(), f.deviceWrite());
00128 }
00129
00130 template <>
00131 bool UniformMass<gpu::cuda::CudaVec3f1Types, float>::addBBox(double* minBBox, double* maxBBox)
00132 {
00133 const VecCoord& x = *this->mstate->getX();
00134
00135 for (unsigned int i=0; i<x.size(); i++)
00136 {
00137
00138 const Coord& p = x.getCached(i);
00139 for (int c=0;c<3;c++)
00140 {
00141 if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
00142 if (p[c] < minBBox[c]) minBBox[c] = p[c];
00143 }
00144 }
00145 return true;
00146 }
00147
00148 template <>
00149 double UniformMass<gpu::cuda::CudaRigid3fTypes,sofa::defaulttype::Rigid3fMass>::getPotentialEnergy( const VecCoord& x )
00150 {
00151 double e = 0;
00152
00153 Vec3d g ( this->getContext()->getLocalGravity() );
00154 for (unsigned int i=0;i<x.size();i++)
00155 {
00156 e += g*mass.getValue().mass*x[i].getCenter();
00157 }
00158 return e;
00159 }
00160
00161 template <>
00162 double UniformMass<gpu::cuda::CudaRigid3fTypes,sofa::defaulttype::Rigid3fMass>::getElementMass(unsigned int )
00163 {
00164 return (double)(mass.getValue().mass);
00165 }
00166
00167 template <>
00168 void UniformMass<gpu::cuda::CudaRigid3fTypes, Rigid3fMass>::draw()
00169 {
00170 if (!getContext()->getShowBehaviorModels())
00171 return;
00172 const VecCoord& x = *mstate->getX();
00173 defaulttype::Vec3d len;
00174
00175
00176
00177
00178
00179
00180
00181
00182 double m00 = mass.getValue().inertiaMatrix[0][0];
00183 double m11 = mass.getValue().inertiaMatrix[1][1];
00184 double m22 = mass.getValue().inertiaMatrix[2][2];
00185 len[0] = sqrt(m11+m22-m00);
00186 len[1] = sqrt(m00+m22-m11);
00187 len[2] = sqrt(m00+m11-m22);
00188
00189 for (unsigned int i=0; i<x.size(); i++)
00190 {
00191 helper::gl::Axis::draw(x[i].getCenter(), x[i].getOrientation(), len);
00192 }
00193 }
00194
00195
00196
00197 }
00198
00199 }
00200
00201 }
00202
00203 #endif