SphereModel.inl
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_COMPONENT_COLLISION_SPHEREMODEL_INL
00026 #define SOFA_COMPONENT_COLLISION_SPHEREMODEL_INL
00027
00028 #include <sofa/component/collision/SphereModel.h>
00029 #include <sofa/helper/io/SphereLoader.h>
00030 #include <sofa/component/collision/CubeModel.h>
00031 #include <sofa/helper/system/FileRepository.h>
00032 #include <sofa/helper/system/gl.h>
00033 #include <sofa/helper/system/glut.h>
00034
00035 namespace sofa
00036 {
00037
00038 namespace component
00039 {
00040
00041 namespace collision
00042 {
00043
00044 template<class TDataTypes>
00045 TSphereModel<TDataTypes>::TSphereModel()
00046 : radius(initData(&radius, "listRadius","Radius of each sphere")),
00047 defaultRadius(initData(&defaultRadius,(SReal)(1.0), "radius","Default Radius"))
00048 {
00049 if (radius.getValue().size() == 0)
00050 {
00051 resize(getSize());
00052 for(unsigned int i=0;i<this->radius.getValue().size();i++) setRadius(i, -1);
00053 }
00054 }
00055
00056
00057 template<class TDataTypes>
00058 TSphereModel<TDataTypes>::TSphereModel(SReal r)
00059 : radius(initData(&radius, "listRadius","Radius of each sphere")),
00060 defaultRadius(initData(&defaultRadius, r,"radius","Default Radius"))
00061 {
00062 resize(getSize());
00063 for(unsigned int i=0;i<this->radius.getValue().size();i++) setRadius(i, r);
00064 }
00065
00066 template<class TDataTypes>
00067 void TSphereModel<TDataTypes>::init()
00068 {
00069 Inherit::init();
00070 for(unsigned int i=0;i<this->radius.getValue().size();i++)
00071 if (getRadius(i)==-1) setRadius(i,defaultRadius.getValue());
00072 }
00073
00074 template<class TDataTypes>
00075 void TSphereModel<TDataTypes>::resize(int size)
00076 {
00077 this->component::MechanicalObject<InDataTypes>::resize(size);
00078 this->core::CollisionModel::resize(size);
00079 if ((int)radius.getValue().size() < size)
00080 {
00081 radius.beginEdit()->reserve(size);
00082 while ((int)radius.getValue().size() < size)
00083 radius.beginEdit()->push_back(defaultRadius.getValue());
00084 }
00085 else
00086 {
00087 radius.beginEdit()->resize(size);
00088 }
00089 }
00090
00091 template<class TDataTypes>
00092 int TSphereModel<TDataTypes>::addSphere(const Vector3& pos, SReal radius)
00093 {
00094 int i = size;
00095 resize(i+1);
00096 setSphere(i, pos, radius);
00097 return i;
00098 }
00099
00100 template<class TDataTypes>
00101 void TSphereModel<TDataTypes>::setSphere(int i, const Vector3& pos, SReal r)
00102 {
00103 if ((unsigned)i >= (unsigned) size) return;
00104 (*this->getX())[i] = pos;
00105 setRadius(i,r);
00106 }
00107
00108 template<class TDataTypes>
00109 class TSphereModel<TDataTypes>::Loader : public helper::io::SphereLoader
00110 {
00111 public:
00112 TSphereModel<TDataTypes>* dest;
00113 Loader(TSphereModel<TDataTypes>* dest) : dest(dest) { }
00114 void addSphere(SReal x, SReal y, SReal z, SReal r)
00115 {
00116 dest->addSphere(Vector3(x,y,z),r);
00117 }
00118 };
00119
00120 template<class TDataTypes>
00121 bool TSphereModel<TDataTypes>::load(const char* filename)
00122 {
00123 this->resize(0);
00124 std::string sphereFilename(filename);
00125 if (!sofa::helper::system::DataRepository.findFile (sphereFilename))
00126 logWarning(std::string("Sphere File \"") + filename +std::string("\" not found"));
00127 Loader loader(this);
00128 return loader.load(filename);
00129
00130
00131 }
00132
00133 template<class TDataTypes>
00134 void TSphereModel<TDataTypes>::applyScale(SReal s)
00135 {
00136 Inherit::applyScale(s);
00137
00138 for (int i=0;i<size;i++) setRadius(i, getRadius(i)*s);
00139 }
00140
00141 template<class TDataTypes>
00142 void TSphereModel<TDataTypes>::draw(int index)
00143 {
00144 const typename TDataTypes::VecCoord& x = *(((const TSphereModel<TDataTypes>*)this)->getX());
00145 Vector3 p = x[index];
00146 glPushMatrix();
00147 glTranslated(p[0], p[1], p[2]);
00148
00149 glutSolidSphere(getRadius(index), 32,16);
00150 glPopMatrix();
00151 }
00152
00153 template<class TDataTypes>
00154 void TSphereModel<TDataTypes>::draw()
00155 {
00156 if (getContext()->getShowCollisionModels())
00157 {
00158 glEnable(GL_LIGHTING);
00159 glEnable(GL_COLOR_MATERIAL);
00160
00161 glColor4fv(getColor4f());
00162 for (int i=0;i<size;i++)
00163 {
00164 draw(i);
00165 }
00166 glDisable(GL_LIGHTING);
00167 glDisable(GL_COLOR_MATERIAL);
00168 }
00169 if (getPrevious()!=NULL && getContext()->getShowBoundingCollisionModels())
00170 getPrevious()->draw();
00171 }
00172
00173 template<class TDataTypes>
00174 void TSphereModel<TDataTypes>::computeBoundingTree(int maxDepth)
00175 {
00176 CubeModel* cubeModel = createPrevious<CubeModel>();
00177 if (!isMoving() && !cubeModel->empty()) return;
00178
00179 Vector3 minElem, maxElem;
00180
00181 cubeModel->resize(size);
00182 if (!empty())
00183 {
00184 const typename TDataTypes::VecCoord& x = *(((const TSphereModel<TDataTypes>*)this)->getX());
00185 for (int i=0;i<size;i++)
00186 {
00187 SReal r = getRadius(i);
00188 for (int c=0;c<3;c++)
00189 {
00190 minElem[c] = x[i][c] - r;
00191 maxElem[c] = x[i][c] + r;
00192 }
00193 cubeModel->setParentOf(i, minElem, maxElem);
00194 }
00195 cubeModel->computeBoundingTree(maxDepth);
00196 }
00197 }
00198
00199 template<class TDataTypes>
00200 void TSphereModel<TDataTypes>::computeContinuousBoundingTree(double dt, int maxDepth)
00201 {
00202 CubeModel* cubeModel = createPrevious<CubeModel>();
00203 if (!isMoving() && !cubeModel->empty()) return;
00204
00205 Vector3 minElem, maxElem;
00206
00207 cubeModel->resize(this->size);
00208 if (!empty())
00209 {
00210 const typename TDataTypes::VecCoord& x = *this->getX();
00211 const typename TDataTypes::VecDeriv& v = *this->getV();
00212 for (int i=0;i<this->size;i++)
00213 {
00214 SReal r = getRadius(i);
00215 for (int c=0;c<3;c++)
00216 {
00217 if (v[i][c] < 0)
00218 {
00219 minElem[c] = x[i][c] + v[i][c]*dt - r;
00220 maxElem[c] = x[i][c] + r;
00221 }
00222 else
00223 {
00224 minElem[c] = x[i][c] - r;
00225 maxElem[c] = x[i][c] + v[i][c]*dt + r;
00226 }
00227 }
00228 cubeModel->setParentOf(i, minElem, maxElem);
00229 }
00230 cubeModel->computeBoundingTree(maxDepth);
00231 }
00232 }
00233
00234 }
00235
00236 }
00237
00238 }
00239
00240 #endif