#include "BSH.h" #include #include #include "ClothSim.h" void BSH::BuidBSH( objLoader *model, int level, Cloth cloth ) { this->model=model; this->level=level; Sphere BS; //Point *P = new Point[model->vertexCount]; Point *P = new Point[cloth.particleActiveState.size()]; /////////////////////////////////////////////////////////////////////////////////////////////////////// int k,l=0; for (k=0;kvertexList[l]; P[l].x=v->e[0]; P[l].y=v->e[1]; P[l].z=v->e[2]; } l=l-3; l=l+207; } /////////////////////////////////////////////////////////////////////////////////////////////////////// /*for (int i=0;ivertexCount;i++) { obj_vector* v=model->vertexList[i]; P[i].x=v->e[0]; P[i].y=v->e[1]; P[i].z=v->e[2]; }*/ BS = MinSphere(P, model->vertexCount); root->BS->center=BS.center; root->BS->radius=BS.radius; root->pere=NULL; FaceList *faces=new FaceList; //cout<faceCount<faceCount; i++) { obj_face *o = model->faceList[i]; obj_vector* v[3]; for (int j=0;j<3;j++) {//cout<< o->vertex_index[j]<vertexList[o->vertex_index[j]];//v[] contient les indices des vertexes de la face. } /*for(int k=0;k<3;i++) for(int j=0;j<3;j++) {cout<< v[j]->e[0]<e[1]<e[2]<e[0]; sum.y+=v[j]->e[1]; sum.z+=v[j]->e[2]; } sum.x/=3; sum.y/=3; sum.z/=3; Face tri; tri.center=sum; tri.index=i; faces->push_back(tri); } if (level<=1) { faces->clear(); delete faces; return; } RecurseBuild(root,faces,2); faces->clear(); delete faces; } BSH::BSH() { root=new BSN; root->BS=new Sphere(); output=new BSHList; leaffaces= new LeafIndFaces; } void BSH::RecurseBuild( BSN *current, FaceList *faces, int l ) { float minX, maxX, minY, maxY, minZ, maxZ; float sum[3]; sum[0]=sum[1]=sum[2]=0; minX=minY=minZ=1e20; maxX=maxY=maxZ=-minX; for (int i=0;isize();i++) { Face tri=faces->at(i); sum[0]+=tri.center.x; sum[1]+=tri.center.y; sum[2]+=tri.center.z; if (tri.center.xmaxX) { maxX=tri.center.x; } if (tri.center.ymaxY) { maxY=tri.center.y; } if (tri.center.zmaxZ) { maxZ=tri.center.z; } } float span[3]; span[0]=maxX-minX; span[1]=maxY-minY; span[2]=maxZ-minZ; int axis; if (span[0]>span[1]) { if (span[0]>span[2]) { axis=0; }else{ axis=2; } }else{ if (span[1]>span[2]) { axis=1; }else{ axis=2; } } sum[axis]/=faces->size(); FaceList *leftFace=new FaceList; FaceList *rightFace=new FaceList; for (int i=0;isize();i++) { Face tri=faces->at(i); bool left=false; switch (axis) { case 0: if (sum[axis]push_back(tri); }else{ rightFace->push_back(tri); } } /************************************************************************/ /* left */ /************************************************************************/ Sphere lBS; Point *lP = new Point[leftFace->size()*3]; for (int i=0;isize();i++) { obj_face *o = model->faceList[leftFace->at(i).index]; obj_vector* v[3]; for (int j=0;j<3;j++) { v[j]=model->vertexList[o->vertex_index[j]]; } for (int j=0;j<3;j++) { lP[i*3+j].x=v[j]->e[0]; lP[i*3+j].y=v[j]->e[1]; lP[i*3+j].z=v[j]->e[2]; } } lBS = MinSphere(lP, leftFace->size()*3); current->left=new BSN; current->left->BS=new Sphere(); current->left->pere=current; current->left->BS->center=lBS.center; current->left->BS->radius=lBS.radius; if (l==level) { current->left->left=NULL; current->left->right=NULL; current->left->mesh=new TriList; for (int i=0;isize();i++) { int ind=leftFace->at(i).index; current->left->mesh->push_back(ind); } }else{ RecurseBuild(current->left,leftFace,l+1); } leftFace->clear(); delete [] lP; delete leftFace; /************************************************************************/ /* right */ /************************************************************************/ Sphere rBS; Point *rP = new Point[rightFace->size()*3]; for (int i=0;isize();i++) { obj_face *o = model->faceList[rightFace->at(i).index]; obj_vector* v[3]; for (int j=0;j<3;j++) { v[j]=model->vertexList[o->vertex_index[j]]; } for (int j=0;j<3;j++) { rP[i*3+j].x=v[j]->e[0]; rP[i*3+j].y=v[j]->e[1]; rP[i*3+j].z=v[j]->e[2]; } } rBS = MinSphere(rP, rightFace->size()*3); current->right=new BSN; current->right->BS=new Sphere(); current->right->pere=current; current->right->BS->center=rBS.center; current->right->BS->radius=rBS.radius; if (l==level) { current->right->left=NULL; current->right->right=NULL; current->right->mesh=new TriList; for (int i=0;isize();i++) { int ind=rightFace->at(i).index; current->right->mesh->push_back(ind); } }else{ RecurseBuild(current->right,rightFace,l+1); } rightFace->clear(); delete [] rP; delete rightFace; } void BSH::SearchBSH( int l ) { if (l>level) { return; } detail=l; output->clear(); RecurseSearch(root,1); } void BSH::RecurseSearch( BSN *current, int l ) { if (detail==l) { output->push_back(current); }else{ RecurseSearch(current->left,l+1); RecurseSearch(current->right,l+1); } } Vec3 BSH:: minus(const Vec3& v1, const vector3& v2) { Vec3 r; r.f[0] = v1.f[0] - v2.x; r.f[1] = v1.f[1] - v2.y; r.f[2] = v1.f[2] - v2.z; return r; } double BSH:: dotProduct(const Vec3& v1, const Vec3& v2) { return v1.f[0] * v2.f[0] + v1.f[1] * v2.f[1] + v1.f[2] * v2.f[2]; } int BSH:: distanceSquared(const vector3& v1, const Vec3& v2) { Vec3 delta = minus(v2, v1); return dotProduct(delta, delta); } bool BSH:: doesItCollide(Sphere *BS, const Vec3 center,const float radius){ int rSquared = BS->radius + radius; rSquared *= rSquared; return distanceSquared(BS->center, center) < rSquared; } void BSH:: traverse(Cloth cloth, BSN *current,const Vec3 center,const float radius,int Reslevel,float stepsize){ queue file; int i=-1; int line,col,col1; file.push(current); if(!doesItCollide(current->BS, center, radius)) return; while(!file.empty()) { BSN *node=file.front(); i++; file.pop(); if(doesItCollide(node->BS, center, radius)) { if(node->left==NULL&&node->right==NULL) { leaffaces->push_back(node->mesh); } else { if(node->left!=NULL) file.push(node->left); if(node->right!=NULL) file.push(node->right); } } else { if(i%2!=0) node->pere->left=NULL; else node->pere->right=NULL; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TriList *Refine=new TriList; TriList *Refine1=new TriList; for(int i=0;isize();i++) { for(int j=0;jat(i)->size(); j++){ Refine->push_back(cloth.Indexface[leaffaces->at(i)->at(j)]->vertex_index[0]); Refine->push_back(cloth.Indexface[leaffaces->at(i)->at(j)]->vertex_index[1]); Refine->push_back(cloth.Indexface[leaffaces->at(i)->at(j)]->vertex_index[2]); } } //here we have to build a function that delete multiple occurence of the same particle if(!Refine->empty()) { Refine1->push_back(Refine->at(0)); int ind; vector::iterator it; vector::iterator it1; for(it1=Refine->begin();it1end();it1++) { ind=*it1; for(it=Refine1->begin();itend()&&(*it)!=ind;it++); if(it>=Refine1->end()) Refine1->push_back(ind); } //for(int i=0;isize();i++) //Refine1->at(i)=Refine1->at(i)*4; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Activate the neighboring of particles on collision int l=0; for(int i=0;isize();i++){ //vector *RefinedParticles; for(l=0;lsize()&& cloth.t->at(l).index!=Refine1->at(i);l++); if(lsize()) { line=col=col1=0; int j= cloth.t->at(l).x; int k= cloth.t->at(l).y; if(k==0&&j!=0&&j!=(cloth.num_particles_height* (Reslevel+1)-Reslevel)-1) { line=5; col=9; col1=9; for(int m=0;mparticleIndex];cout<<"y1 "<particleIndex];cout<<"y2 "<particleIndex];cout<<"y3 "<particleIndex];cout<<"y4 "<particleIndex]; p2=cloth.getParticle1(x,y,col1); //p2=&cloth.particleActiveState[p2->particleIndex]; cloth.makeConstraint1(p2,p1); } if (yparticleIndex]; p3=cloth.getParticle1(x,y+1,col1); //p3=&cloth.particleActiveState[p3->particleIndex]; cloth.makeConstraint1(p2,p3);} if (xparticleIndex]; p4=cloth.getParticle1(x+1,y+1,col1); //p4=&cloth.particleActiveState[p4->particleIndex]; cloth.makeConstraint1(p2,p4);} if (xparticleIndex]; p3=cloth.getParticle1(x,y+1,col1); //p3=&cloth.particleActiveState[p3->particleIndex]; cloth.makeConstraint1(p1,p3);} } } // Connecting secondary neighbors with constraints (distance 2 and sqrt(4) in the grid) for(int x=0; xparticleIndex]; p5=cloth.getParticle1(x+2,y,col1); p5=&cloth.particleActiveState[p5->particleIndex]; p6=cloth.getParticle1(x,y+2,col1); p6=&cloth.particleActiveState[p6->particleIndex]; p7=cloth.getParticle1(x+2,y+2,col1); p7=&cloth.particleActiveState[p7->particleIndex];*/ if (xparticleIndex]; p5=cloth.getParticle1(x+2,y,col1); //p5=&cloth.particleActiveState[p5->particleIndex]; cloth.makeConstraint1(p2,p5);} if (yparticleIndex]; p6=cloth.getParticle1(x,y+2,col1); //p6=&cloth.particleActiveState[p6->particleIndex]; cloth.makeConstraint1(p2,p6);} if (xparticleIndex]; p7=cloth.getParticle1(x+2,y+2,col1); //p7=&cloth.particleActiveState[p7->particleIndex]; cloth.makeConstraint1(p2,p7);} if (xparticleIndex]; p6=cloth.getParticle1(x,y+2,col1); //p6=&cloth.particleActiveState[p6->particleIndex]; cloth.makeConstraint1(p5,p6);} } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //cout<<"taille constr after connect= "<::iterator it; cout<<"taille= "<particleIndex];cout<<"y2 "<particleIndex];cout<<"y3 "<particleIndex];cout<<"y4 "<particleIndex]; p2=cloth.getParticle1(x,y,col1); //p2=&cloth.particleActiveState[p2->particleIndex]; cloth.makeConstraint1(p2,p1); } if (yparticleIndex]; p3=cloth.getParticle1(x,y+1,col1); //p3=&cloth.particleActiveState[p3->particleIndex]; cloth.makeConstraint1(p2,p3);} if (xparticleIndex]; p4=cloth.getParticle1(x+1,y+1,col1); //p4=&cloth.particleActiveState[p4->particleIndex]; cloth.makeConstraint1(p2,p4);} if (xparticleIndex]; p3=cloth.getParticle1(x,y+1,col1); //p3=&cloth.particleActiveState[p3->particleIndex]; cloth.makeConstraint1(p1,p3);} } } // Connecting secondary neighbors with constraints (distance 2 and sqrt(4) in the grid) for(int x=0; xparticleIndex]; p5=cloth.getParticle1(x+2,y,col1); p5=&cloth.particleActiveState[p5->particleIndex]; p6=cloth.getParticle1(x,y+2,col1); p6=&cloth.particleActiveState[p6->particleIndex]; p7=cloth.getParticle1(x+2,y+2,col1); p7=&cloth.particleActiveState[p7->particleIndex];*/ /*if (xparticleIndex]; p5=cloth.getParticle1(x+2,y,col1); //p5=&cloth.particleActiveState[p5->particleIndex]; cloth.makeConstraint1(p2,p5);} if (yparticleIndex]; p6=cloth.getParticle1(x,y+2,col1); //p6=&cloth.particleActiveState[p6->particleIndex]; cloth.makeConstraint1(p2,p6);} if (xparticleIndex]; p7=cloth.getParticle1(x+2,y+2,col1); //p7=&cloth.particleActiveState[p7->particleIndex]; cloth.makeConstraint1(p2,p7);} if (xparticleIndex]; p6=cloth.getParticle1(x,y+2,col1); //p6=&cloth.particleActiveState[p6->particleIndex]; cloth.makeConstraint1(p5,p6);} } } cout<<"taille constr fin= "<