TriangleOctreeModel.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 <sofa/component/collision/TriangleModel.h>
00026 #include <sofa/component/collision/TriangleOctreeModel.h>
00027 #include <sofa/component/collision/CubeModel.h>
00028 #include <sofa/component/collision/Triangle.h>
00029 #include <sofa/core/CollisionElement.h>
00030 #include <sofa/core/ObjectFactory.h>
00031 #include <vector>
00032 #include <sofa/helper/system/thread/CTime.h>
00033
00034 #include <cmath>
00035 #include <sofa/helper/system/gl.h>
00036 #include <sofa/helper/system/glut.h>
00037
00038 namespace sofa
00039 {
00040
00041 namespace component
00042 {
00043 namespace topology
00044 {
00045 typedef core::componentmodel::topology::BaseMeshTopology::Triangle Triangle;
00046 }
00047
00048 namespace collision
00049 {
00050
00051 using sofa::helper::system::thread::CTime;
00052 using sofa::helper::system::thread::ctime_t;
00053
00054
00055 TriangleAABB::TriangleAABB (Triangle & t)
00056 {
00057 for (int i = 0; i < 3; i++)
00058 {
00059
00060 bb[i * 2] = bb_min3 (t.p1 ()[i], t.p2 ()[i], t.p3 ()[i]);
00061 bb[(i * 2) + 1] = bb_max3 (t.p1 ()[i], t.p2 ()[i], t.p3 ()[i]);
00062
00063 m_size =
00064 bb_max3 (fabs (bb[1] - bb[0]), fabs (bb[3] - bb[2]),
00065 fabs (bb[5] - bb[4]));
00066
00067
00068 }
00069 }
00070
00071
00072
00073
00074 int TriangleOctreeModelClass = core::RegisterObject ("collision model using a triangular mesh mapped to an Octree").add < TriangleOctreeModel > ().addAlias ("TriangleOctree");
00075
00076 TriangleOctreeModel::TriangleOctreeModel ()
00077 {
00078 octreeRoot = NULL;
00079 cubeSize = CUBE_SIZE;
00080 }
00081
00082
00083
00084 void TriangleOctreeModel::draw ()
00085 {
00086
00087 if (isActive () && getContext ()->getShowCollisionModels ())
00088 {
00089 if (getContext ()->getShowWireFrame ())
00090 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00091
00092 glEnable (GL_LIGHTING);
00093
00094
00095
00096 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, getColor4f());
00097 static const float emissive[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
00098 static const float specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
00099 glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive);
00100 glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
00101 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 20);
00102 if(octreeRoot)
00103 octreeRoot->draw ();
00104
00105 glColor3f (1.0f, 1.0f, 1.0f);
00106 glDisable (GL_LIGHTING);
00107 if (getContext ()->getShowWireFrame ())
00108 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00109 }
00110 }
00111
00112 int TriangleOctreeModel::fillOctree (int tId, int , Vector3 )
00113 {
00114
00115
00116 Vector3 center;
00117 Triangle t (this, tId);
00118 Vector3 corner (-cubeSize, -cubeSize, -cubeSize);
00119
00120 TriangleAABB aabb (t);
00121 double *bb = aabb.getAABB ();
00122
00123
00124
00125 int d1 = (int)((log10( (double) CUBE_SIZE * 2) / log10( (double)2) )/ aabb.size ());
00126
00127 int divs = (1 << (d1));
00128 double inc = (double) (2 * CUBE_SIZE) / divs;
00129 if (bb[0] >= -CUBE_SIZE && bb[2] >= -CUBE_SIZE && bb[4] >= -CUBE_SIZE
00130 && bb[1] <= CUBE_SIZE && bb[3] <= CUBE_SIZE && bb[5] <= CUBE_SIZE)
00131 for (double x1 =
00132 (((int)((bb[0] + CUBE_SIZE) / inc)) * inc - CUBE_SIZE);
00133 x1 <= bb[1]; x1 += inc)
00134 {
00135
00136 for (double y1 =
00137 ((int)((bb[2] + CUBE_SIZE) / inc)) * inc - CUBE_SIZE;
00138 y1 <= bb[3]; y1 += inc)
00139 {
00140
00141
00142 for (double z1 =
00143 ((int)((bb[4] + CUBE_SIZE) / inc)) * inc - CUBE_SIZE;
00144 z1 <= bb[5]; z1 += inc)
00145 {
00146 octreeRoot->insert (x1, y1, z1, inc, tId);
00147
00148 }
00149 }
00150 }
00151 return 0;
00152
00153 }
00154 void TriangleOctreeModel::computeBoundingTree(int maxDepth)
00155 {
00156 const helper::vector<topology::Triangle>& tri = *triangles;
00157 if(octreeRoot){
00158 delete octreeRoot;
00159 octreeRoot=NULL;
00160 }
00161
00162 CubeModel* cubeModel = createPrevious<CubeModel>();
00163 updateFromTopology();
00164
00165 if (!isMoving() && !cubeModel->empty()) return;
00166 int size2=mstate->getX()->size();
00167 pNorms.resize(size2);
00168 for(int i=0;i<size2;i++){
00169 pNorms[i]=Vector3(0,0,0);
00170 }
00171 Vector3 minElem, maxElem;
00172 maxElem[0]=minElem[0]=(*mstate->getX())[0][0];
00173 maxElem[1]=minElem[1]=(*mstate->getX())[0][1];
00174 maxElem[2]=minElem[2]=(*mstate->getX())[0][2];
00175
00176 cubeModel->resize(1);
00177 for (int i=1;i<size;i++)
00178 {
00179 Triangle t(this,i);
00180 pNorms[tri[i][0]]+=t.n();
00181 pNorms[tri[i][1]]+=t.n();
00182 pNorms[tri[i][2]]+=t.n();
00183 const Vector3* pt[3];
00184 pt[0] = &t.p1();
00185 pt[1] = &t.p2();
00186 pt[2] = &t.p3();
00187 t.n() = cross(*pt[1]-*pt[0],*pt[2]-*pt[0]);
00188 t.n().normalize();
00189
00190 for (int p=0;p<3;p++)
00191 {
00192
00193
00194 for(int c=0;c<3;c++){
00195 if ((*pt[p])[c] > maxElem[c]) maxElem[c] = (*pt[p])[c];
00196 if ((*pt[p])[c] < minElem[c]) minElem[c] = (*pt[p])[c];
00197
00198 }
00199 }
00200
00201 }
00202
00203 cubeModel->setParentOf(0, minElem, maxElem);
00204 cubeModel->computeBoundingTree(maxDepth);
00205 for(int i=0;i<size2;i++){
00206 pNorms[i].normalize();
00207 }
00208 if(!pTri.size()){
00209
00210 pTri.resize(size2);
00211 for(int i=0;i<size;i++)
00212 {
00213 pTri[tri[i][0]].push_back(i);
00214
00215 pTri[tri[i][1]].push_back(i);
00216 pTri[tri[i][2]].push_back(i);
00217 }
00218 }
00219 }
00220
00221 void TriangleOctreeModel::computeContinuousBoundingTree(double, int maxDepth){
00222 computeBoundingTree(maxDepth);
00223
00224 }
00225 void TriangleOctreeModel::buildOctree ()
00226 {
00227 octreeRoot = new TriangleOctree (this);
00228
00229
00230 for (size_t i = 0; i < elems.size (); i++)
00231 {
00232
00233 fillOctree (i);
00234
00235 }
00236 }
00237
00238 }
00239
00240 }
00241
00242 }