CudaPointModel.cpp
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 #include "CudaPointModel.h"
00026 #include <sofa/core/ObjectFactory.h>
00027 #include <sofa/component/collision/CubeModel.h>
00028 #include <fstream>
00029 #include <sofa/helper/system/gl.h>
00030
00031 namespace sofa
00032 {
00033
00034 namespace gpu
00035 {
00036
00037 namespace cuda
00038 {
00039
00040 SOFA_DECL_CLASS(CudaPointModel)
00041
00042 int CudaPointModelClass = core::RegisterObject("GPU-based point collision model using CUDA")
00043 .add< CudaPointModel >()
00044 .addAlias("CudaPoint")
00045 ;
00046
00047 using namespace defaulttype;
00048
00049 CudaPointModel::CudaPointModel()
00050 : groupSize( initData( &groupSize, (int)BSIZE, "groupSize", "number of point per collision element" ) )
00051 , mstate(NULL)
00052 {
00053 }
00054
00055 void CudaPointModel::resize(int size)
00056 {
00057 this->core::CollisionModel::resize(size);
00058 }
00059
00060 void CudaPointModel::init()
00061 {
00062 this->CollisionModel::init();
00063 mstate = dynamic_cast< core::componentmodel::behavior::MechanicalState<InDataTypes>* > (getContext()->getMechanicalState());
00064
00065 if (mstate==NULL)
00066 {
00067 std::cerr << "ERROR: CudaPointModel requires a CudaVec3f Mechanical Model.\n";
00068 return;
00069 }
00070
00071 const int npoints = mstate->getX()->size();
00072 int gsize = groupSize.getValue();
00073 int nelems = (npoints + gsize-1)/gsize;
00074 resize(nelems);
00075 }
00076
00077 void CudaPointModel::draw(int index)
00078 {
00079 const int gsize = groupSize.getValue();
00080 CudaPoint t(this,index);
00081 glBegin(GL_POINTS);
00082 const VecCoord& x = *mstate->getX();
00083 int i0 = index*gsize;
00084 int n = (index==size-1) ? x.size()-i0 : gsize;
00085 for (int p=0;p<n;p++)
00086 {
00087 glVertex3fv(x[i0+p].ptr());
00088 }
00089 glEnd();
00090 }
00091
00092 void CudaPointModel::draw()
00093 {
00094 if (isActive() && getContext()->getShowCollisionModels())
00095 {
00096 if (getContext()->getShowWireFrame())
00097 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00098
00099 glDisable(GL_LIGHTING);
00100 glPointSize(3);
00101 glColor4fv(getColor4f());
00102
00103 for (int i=0;i<size;i++)
00104 {
00105 draw(i);
00106 }
00107
00108 glColor3f(1.0f, 1.0f, 1.0f);
00109 glDisable(GL_LIGHTING);
00110 glPointSize(1);
00111 if (getContext()->getShowWireFrame())
00112 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00113 }
00114 if (isActive() && getPrevious()!=NULL && getContext()->getShowBoundingCollisionModels())
00115 getPrevious()->draw();
00116 }
00117
00118 using sofa::component::collision::CubeModel;
00119
00120 void CudaPointModel::computeBoundingTree(int maxDepth)
00121 {
00122 CubeModel* cubeModel = createPrevious<CubeModel>();
00123 const int npoints = mstate->getX()->size();
00124 const int gsize = groupSize.getValue();
00125 const int nelems = (npoints + gsize-1)/gsize;
00126 bool updated = false;
00127 if (nelems != size)
00128 {
00129 resize(nelems);
00130 updated = true;
00131 }
00132 if (updated) cubeModel->resize(0);
00133 if (!isMoving() && !cubeModel->empty() && !updated) return;
00134
00135 cubeModel->resize(size);
00136 if (!empty())
00137 {
00138 const VecCoord& x = *mstate->getX();
00139 for (int i=0;i<size;i++)
00140 {
00141 int i0 = i*gsize;
00142 int n = (i==size-1) ? npoints-i0 : gsize;
00143 Vec3f bmin = x[i0];
00144 Vec3f bmax = bmin;
00145 for (int p=1;p<n;p++)
00146 {
00147 const Vec3f& xi = x[i0+p];
00148 for (int c=0;c<3;c++)
00149 {
00150 if (xi[c] < bmin[c]) bmin[c] = xi[c];
00151 else if (xi[c] > bmax[c]) bmax[c] = xi[c];
00152 }
00153 }
00154 cubeModel->setParentOf(i, bmin, bmax);
00155 }
00156 cubeModel->computeBoundingTree(maxDepth);
00157 }
00158 }
00159
00160 }
00161
00162 }
00163
00164 }