cd.c
Go to the documentation of this file.
1 #include "cd.h"
2 
3 #include "defines.h"
4 #include "algebra.h"
5 #include "error.h"
6 
55 void StoreCollisionInfoInt(FILE *f,char *fname,unsigned int objectID,
56  Tmechanism *m,unsigned int nc,TCollisionInfo *c);
57 
70 void PrintCollisionInfoInt(THTransform *tl,Tmechanism *m,unsigned int nc,TCollisionInfo *c);
71 
72 #ifdef _HAVE_SOLID
73 
86  DT_Bool CDCallBack(void *client_data,void *obj1,void *obj2,const DT_CollData *cd);
87 
104  DT_Bool CDCallBackInfo(void *client_data,void *obj1,void *obj2,const DT_CollData *cd);
105 
118  DT_ShapeHandle AddShape2Solid(Tpolyhedron *p);
119 
133  boolean SolidCorrection(THTransform *t,Tpolyhedron *p);
134 
152  void InitSolidCD(boolean parallel,Tmechanism *m,Tenvironment *e,
153  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
154  TsolidCD *s);
155 
168  boolean CheckCollisionSolid(boolean all,THTransform *tl,TsolidCD *s);
169 
177  void DeleteSolidCD(TsolidCD *s);
178 #endif
179 
180 #ifdef _HAVE_VCOLLIDE
181 
194  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
195  TvcollideCD *vc);
196 
197 
209 
217  void DeleteVcollideCD(TvcollideCD *vc);
218 
219 #endif
220 
221 #ifdef _HAVE_PQP
222 
234  void InitPQPCD(Tmechanism *m,Tenvironment *e,
235  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
236  TpqpCD *p);
237 
248  boolean CheckCollisionPQP(THTransform *tl,TpqpCD *p);
249 
257  void DeletePQPCD(TpqpCD *p);
258 
259 #endif
260 
261 
262 #if _HAVE_FCL
263 
273  void DefineFCLObject(Tpolyhedron *shape,TfclCD *p);
274 
286  void InitFCLCD(Tmechanism *m,Tenvironment *e,
287  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
288  TfclCD *p);
289 
302  boolean CheckCollisionFCL(boolean all,THTransform *tl,TfclCD *p);
303 
319  boolean CheckContCollisionFCL(THTransform *tl,THTransform *tlPrev,TfclCD *p);
320 
328  void DeleteFCLCD(TfclCD *p);
329 
330 #endif
331 
332 #if _HAVE_BULLET
333 
344  void DefineBulletObject(boolean fixed,Tpolyhedron *shape,TBulletCD *p);
345 
358  void InitBulletCD(Tmechanism *m,Tenvironment *e,
359  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
360  boolean cont,TBulletCD *p);
361 
374  boolean CheckCollisionBullet(boolean all,THTransform *tl,TBulletCD *p);
375 
391  boolean CheckContCollisionBullet(THTransform *tl,THTransform *tlPrev,TBulletCD *p);
392 
400  void DeleteBulletCD(TBulletCD *p);
401 
402 #endif
403 
404 #ifdef _HAVE_RIGIDCLL
405 
421  boolean ObstaclesCollideLikeGround(unsigned int nl,unsigned int no,boolean **checkCollisionsLL,boolean **checkCollisionsLO);
422 
434  void InitRigidCLLCD(Tmechanism *m,Tenvironment *e,
435  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
436  TrigidCLLCD *r);
437 
448  boolean CheckCollisionRigidCLL(THTransform *tl,TrigidCLLCD *r);
449 
457  void DeleteRigidCLLCD(TrigidCLLCD *r);
458 
459 #endif
460 
461 
462 #ifdef _HAVE_SOLID
463 
464  DT_Bool CDCallBackInfo(void *client_data,void *obj1,void *obj2,
465  const DT_CollData *cd)
466  {
467  TsolidCD *s;
468 
469  s=(TsolidCD *)client_data;
470 
471  if ((s->simple)||(s->collision=NULL))
472  /* in simple collision detection mode. Stop as soon as a collision is
473  detected, without collecing information about the collisions. */
474  return(DT_DONE);
475  else
476  {
477  unsigned int id1,id2,k;
478 
479  if (s->nc==s->mc)
480  {
482  }
483 
484  id1=*((unsigned int*)obj1);
485  id2=*((unsigned int*)obj2);
486 
487  if (s->object[id1].linkID==NO_UINT)
488  {
489  /* the first object is a body in the environment */
490  s->collision[s->nc].isLink1=FALSE;
491  s->collision[s->nc].id1=s->object[id1].bodyID;
492  HTransformIdentity(&(s->collision[s->nc].t1));
493  }
494  else
495  {
496  s->collision[s->nc].isLink1=TRUE;
497  s->collision[s->nc].id1=s->object[id1].linkID;
498  HTransformCopy(&(s->collision[s->nc].t1),&(s->object[id1].t));
499  }
500 
501  if (s->object[id2].linkID==NO_UINT)
502  {
503  /* the second object is a body in the environment */
504  s->collision[s->nc].isLink2=FALSE;
505  s->collision[s->nc].id2=s->object[id2].bodyID;
506  HTransformIdentity(&(s->collision[s->nc].t2));
507  }
508  else
509  {
510  s->collision[s->nc].isLink2=TRUE;
511  s->collision[s->nc].id2=s->object[id2].linkID;
512  HTransformCopy(&(s->collision[s->nc].t2),&(s->object[id2].t));
513  }
514 
515  for(k=0;k<3;k++)
516  {
517  s->collision[s->nc].point[k]=cd->point2[k];
518  s->collision[s->nc].normal[k]=cd->normal[k];
519  }
520  /* Just in case ;) */
521  Normalize(3,s->collision[s->nc].normal);
522 
523  s->nc++;
524 
525  /* The transforms are computed after the detection */
526  return DT_CONTINUE;
527  }
528  }
529 
530  DT_ShapeHandle AddShape2Solid(Tpolyhedron *p)
531  {
532  unsigned int i,j,k,n;
533  unsigned int nv,nf;
534  double **v;
535  unsigned int *nvf,**fv;
536  DT_ShapeHandle s=0;
537  DT_Scalar ps[3];
538  double rad;
539 
541  Error("DECOR shapes can not be included into collision detection");
542 
543  /* hidden shapes are added to the collision detection, although they
544  are not displayed */
545  /*
546  IMPORTANT: The following block can not be executed in parallel. SOLID stores all
547  the shapes in the same pool of shapes, which can not be updated
548  concurrently.
549  */
550  #pragma omp critical
551  {
552  switch(GetPolyhedronType(p))
553  {
554  case OFF:
555  case LINE:
556  GetOFFInfo(&nv,&v,&nf,&nvf,&fv,p);
557 
558  s=DT_NewComplexShape(NULL);
559  for(i=0;i<nf;i++)
560  {
561  DT_Begin();
562  for(j=0;j<nvf[i];j++)
563  {
564  n=fv[i][j];
565  for(k=0;k<3;k++)
566  ps[k]=(DT_Scalar)v[n][k];
567  DT_Vertex(ps);
568  }
569  DT_End();
570  }
571  DT_EndComplexShape();
572  break;
573  case CYLINDER:
574  /* Define a unitary cylinder along the Y axis CENTERED at the origin */
575  rad=GetPolyhedronRadius(p);
576  s=DT_NewCylinder((DT_Scalar)rad,1.0f);
577  break;
578  case SPHERE:
579  rad=GetPolyhedronRadius(p);
580  s=DT_NewSphere((DT_Scalar)rad);
581  break;
582  case SEGMENTS:
583  Error("Segment-based structures can not be included in collision detection");
584  break;
585  }
586  }
587  return(s);
588  }
589 
591  {
592  THTransform t2;
593  double c[3],p1[3],p2[3];
594 
596  Error("DECOR shapes can not be included into collision detection");
597 
598  switch(GetPolyhedronType(p))
599  {
600  case OFF:
601  case LINE:
603  break;
604  case CYLINDER:
605  /* The transforms below have to be interpreted from last to first */
606 
607  /* rotate the unitary cylinder along the X positive axis to an
608  arbitrary position (this includes scaling to the appropiate lenght
609  since we defined it with lenght 1) */
610 
613 
614  HTransformX2Vect(1,1,p1,p2,t);
615  /* rotate to align the cylinder with the X axis */
616  HTransformRz2(-1,0,&t2);
617  HTransformProduct(t,&t2,t);
618  /* move the unitary cylinder to the positive Y axis */
619  HTransformTy(0.5,&t2);
620  HTransformProduct(t,&t2,t);
621  break;
622  case SPHERE:
623  GetPolyhedronCenter(c,p);
624  HTransformTxyz(c[0],c[1],c[2],t);
625  break;
626  case SEGMENTS:
627  Error("Segment-based structures can not be included in collision detection");
628  break;
629  }
630  return(!(HTransformIsIdentity(t)));
631  }
632 
633  void InitSolidCD(boolean parallel,Tmechanism *m,Tenvironment *e,
634  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
635  TsolidCD *s)
636  {
637  unsigned int i,j;
638  unsigned int lID,bID,oID,lID1,lID2;
639  unsigned int nB;
640  Tlink *l;
641  Tpolyhedron *shape;
642  double matrix[16];
643  unsigned int np,nl,no;
644 
645  nl=GetMechanismNLinks(m);
647  np=GetMechanismNBodies(m)+no;
648 
649  /* Create the shapes */
650 
651  /* np is always larger (or equal) than the number of part that can actually
652  collide. */
653  NEW(s->object,np,TsolidObj);
654 
655  /* Generate the shapes */
656  s->np=0;
657  for(lID=0;lID<nl;lID++)
658  {
659  if (LinkCanCollide(lID,nl,no,checkCollisionsLL,checkCollisionsLO))
660  {
661  l=GetMechanismLink(lID,m);
662  nB=LinkNBodies(l);
663 
664  for(bID=0;bID<nB;bID++)
665  {
666  if (GetLinkBodyStatus(bID,l)!=DECOR_SHAPE)
667  {
668  s->object[s->np].id=s->np;
669  s->object[s->np].linkID=lID;
670  s->object[s->np].bodyID=bID;
671 
672  shape=GetLinkBody(bID,l);
673  s->object[s->np].shape=AddShape2Solid(shape);
674 
675  s->object[s->np].correction=SolidCorrection(&(s->object[s->np].tc),shape);
676 
677  s->np++;
678  }
679  }
680  }
681  }
682 
683  for(oID=0;oID<no;oID++)
684  {
685  if ((ObstacleCanCollide(oID,nl,checkCollisionsLO))&&
687  {
688  s->object[s->np].id=s->np;
689  s->object[s->np].linkID=NO_UINT;
690  s->object[s->np].bodyID=oID;
691 
692  shape=GetObstacleShape(oID,e);
693  s->object[s->np].shape=AddShape2Solid(shape);
694 
695  s->object[s->np].correction=SolidCorrection(&(s->object[s->np].tc),shape);
696 
697  s->np++;
698  }
699  }
700 
701  /* Serialize the access to the internal SOLID structuers */
702  #pragma omp critical
703  {
704  s->scene=DT_CreateScene();
705  s->respTable=DT_CreateRespTable();
706 
707  for(i=0;i<s->np;i++)
708  {
709  s->object[i].handler=DT_CreateObject((void*)&(s->object[i].id),s->object[i].shape);
710  DT_AddObject(s->scene,s->object[i].handler);
711  s->object[i].respClass=DT_GenResponseClass(s->respTable);
712  DT_SetResponseClass(s->respTable,s->object[i].handler,s->object[i].respClass);
713  }
714  }
715 
716  s->simple=TRUE; /* default mode check for first collision only */
717 
718  for (i=0;i<s->np;i++)
719  {
720  lID=s->object[i].linkID;
721  if (lID!=NO_UINT)
722  {
723  /* shape 'i' is part of a link */
724  for (j=i+1;j<s->np;j++)
725  {
726  /* partj 'j' can be a link or an obstacle */
727  lID=s->object[j].linkID;
728  if (lID==NO_UINT)
729  {
730  /*link-obstacle intersection*/
731  lID=s->object[i].linkID;
732  oID=s->object[j].bodyID;
733  if (checkCollisionsLO[lID][oID])
734  {
735  DT_AddPairResponse(s->respTable,
736  s->object[i].respClass,s->object[j].respClass,
737  &CDCallBackInfo,(parallel?DT_SIMPLE_RESPONSE:DT_DEPTH_RESPONSE),s);
738  }
739  }
740  else
741  {
742  /*link-link intesection*/
743  lID1=s->object[i].linkID;
744  lID2=s->object[j].linkID;
745  if (checkCollisionsLL[lID1][lID2])
746  {
747  DT_AddPairResponse(s->respTable,
748  s->object[i].respClass,s->object[j].respClass,
749  &CDCallBackInfo,(parallel?DT_SIMPLE_RESPONSE:DT_DEPTH_RESPONSE),s);
750  }
751  }
752  }
753  }
754  }
755 
756  /* Reset the collision information (only actually used if s->simple is FALSE) */
757  s->nc=0;
758  if (parallel)
759  {
760  s->mc=0;
761  s->collision=NULL;
762  }
763  else
764  {
765  s->mc=10;
767  }
768 
769  /* For the obstacle the pre-computed correction is used only once
770  (they do not move) and we do it now*/
771  for(i=0;i<s->np;i++)
772  {
773  lID=s->object[i].linkID;
774  if ((lID==NO_UINT)&&(s->object[i].correction))
775  {
776  HTransform2GLMatrix(matrix,&(s->object[i].tc));
777  DT_SetMatrixd(s->object[i].handler,matrix);
778  }
779  /* Set a default value for all parts (mobile or not) */
780  HTransformIdentity(&(s->object[i].t));
781  }
782  }
783 
784  boolean CheckCollisionSolid(boolean all,THTransform *tl,TsolidCD *s)
785  {
786  unsigned int i;
787  double m[16];
788  THTransform t;
789  unsigned int lID;
790 
791  /* This is the only function where we actually move
792  checking for collisions. This is the place where we
793  reset the collision information before checking. */
794 
795  for(i=0;i<s->np;i++)
796  {
797  lID=s->object[i].linkID;
798  if (lID!=NO_UINT)
799  {
800  /* Keep the transform before the correction. */
801  HTransformCopy(&(s->object[i].t),&(tl[lID]));
802  /*this part can move -> move it !*/
803  if (s->object[i].correction)
804  {
805  HTransformProduct(&(tl[lID]),&(s->object[i].tc),&t);
806  HTransform2GLMatrix(m,&t);
807  }
808  else
809  HTransform2GLMatrix(m,&(tl[lID]));
810 
811  /* Here send the transform to SOLID */
812  DT_SetMatrixd(s->object[i].handler,m);
813  }
814  }
815 
816  /* set the work mode */
817  s->simple=((!all)||(s->collision==NULL));
818 
819  /* Reset the number of collisions detected so far (only used if all=TRUE). */
820  s->nc=0;
821 
822  /* Test */
823  return(DT_Test(s->scene,s->respTable)>0);
824  }
825 
827  {
828  #pragma omp critical
829  {
830  unsigned int i;
831 
832  for(i=0;i<s->np;i++)
833  {
834  DT_RemoveObject(s->scene,s->object[i].handler);
835  DT_DestroyObject(s->object[i].handler);
836  DT_DeleteShape(s->object[i].shape);
837  HTransformDelete(&(s->object[i].t));
838  HTransformDelete(&(s->object[i].tc));
839  }
840 
841  DT_DestroyRespTable(s->respTable);
842  DT_DestroyScene(s->scene);
843  }
844  free(s->object);
845  if (s->collision!=NULL)
846  free(s->collision);
847  }
848 #endif
849 
850 #ifdef _HAVE_VCOLLIDE
851 
853  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
854  TvcollideCD *vc)
855  {
856  unsigned int i,j,lID1,lID2,bID2,np,nl,no,nB,lID,bID,oID;
857  double **v;
858  unsigned int nv,nf,*nvf,**fv;
859  Tpolyhedron *shape;
860  Tlink *l;
861 
862  vc->vc=InitVcollide();
863 
864  nl=GetMechanismNLinks(m);
866  np=GetMechanismNBodies(m)+no;
867 
868  /* Create the shapes */
869 
870  /* np is always larger (or equal) than the number of part that can actually
871  collide. */
872  NEW(vc->bodyID,np,unsigned int);
873  NEW(vc->linkID,np,unsigned int);
874  NEW(vc->vcID,np,unsigned int);
875 
876  /* Generate the shapes */
877  vc->np=0;
878  for(lID=0;lID<nl;lID++)
879  {
880  if (LinkCanCollide(lID,nl,no,checkCollisionsLL,checkCollisionsLO))
881  {
882  l=GetMechanismLink(lID,m);
883  nB=LinkNBodies(l);
884 
885  for(bID=0;bID<nB;bID++)
886  {
887  if (GetLinkBodyStatus(bID,l)!=DECOR_SHAPE)
888  {
889  vc->linkID[vc->np]=lID;
890  vc->bodyID[vc->np]=bID;
891 
892  shape=GetLinkBody(bID,l);
893  GetOFFInfo(&nv,&v,&nf,&nvf,&fv,shape);
894  vc->vcID[vc->np]=AddPolyhedron2Vcollide(v,nf,nvf,fv,vc->vc);
895 
896  vc->np++;
897  }
898  }
899  }
900  }
901 
902  for(oID=0;oID<no;oID++)
903  {
904  if ((ObstacleCanCollide(oID,nl,checkCollisionsLO))&&
906  {
907  vc->linkID[vc->np]=NO_UINT;
908  vc->bodyID[vc->np]=oID;
909 
910  shape=GetObstacleShape(oID,e);
911  GetOFFInfo(&nv,&v,&nf,&nvf,&fv,shape);
912  vc->vcID[vc->np]=AddPolyhedron2Vcollide(v,nf,nvf,fv,vc->vc);
913 
914  vc->np++;
915  }
916  }
917 
918  /* Now define the possible collisions */
919  for(i=0;i<vc->np;i++)
920  {
921  lID1=vc->linkID[i];
922  if (lID1!=NO_UINT) /* if link1 is an obstacle, skip */
923  {
924  for(j=i+1;j<vc->np;j++)
925  {
926  lID2=vc->linkID[j];
927  if (lID2!=NO_UINT)
928  {
929  /* link-link */
930  if (checkCollisionsLL[lID1][lID2])
931  ActivateCollisionsVcollide(vc->vcID[i],vc->vcID[j],vc->vc);
932  else
933  DeactivateCollisionsVcollide(vc->vcID[i],vc->vcID[j],vc->vc);
934  }
935  else
936  {
937  /* link-obstacle */
938  bID2=vc->bodyID[j];
939  if (checkCollisionsLO[lID1][bID2])
940  ActivateCollisionsVcollide(vc->vcID[i],vc->vcID[j],vc->vc);
941  else
942  DeactivateCollisionsVcollide(vc->vcID[i],vc->vcID[j],vc->vc);
943  }
944  }
945  }
946  }
947  }
948 
950  {
951  unsigned int i,lID;
952 
953  /* move */
954  for(i=0;i<vc->np;i++)
955  {
956  lID=vc->linkID[i];
957  if (lID!=NO_UINT) /* if link is an obstacle, do not move */
958  MoveVcollideObject(vc->vcID[i],&(tl[lID]),vc->vc);
959  }
960 
961  /* and check */
962  return(VcollideTest(vc->vc));
963  }
964 
966  {
967  unsigned int i;
968 
969  for(i=0;i<vc->np;i++)
970  DeleteVcollideObject(vc->vcID[i],vc->vc);
971 
972  DeleteVcollide(vc->vc);
973 
974  free(vc->vcID);
975  free(vc->linkID);
976  free(vc->bodyID);
977  }
978 
979 #endif
980 
981 #ifdef _HAVE_PQP
982 
984  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
985  TpqpCD *p)
986  {
987  unsigned int i,j,lID1,lID2,bID2,np,nl,no,nB,lID,bID,oID;
988  double **v;
989  unsigned int nv,nf,*nvf,**fv;
990  Tpolyhedron *shape;
991  Tlink *l;
992 
993  nl=GetMechanismNLinks(m);
995  np=GetMechanismNBodies(m)+no;
996 
997  /* np is always larger (or equal) than the number of part that can actually
998  collide. */
999  NEW(p->bodyID,np,unsigned int);
1000  NEW(p->linkID,np,unsigned int);
1001  NEW(p->model,np,Tpqp *);
1002 
1003  /* Generate the shapes */
1004  p->np=0;
1005  for(lID=0;lID<nl;lID++)
1006  {
1007  if (LinkCanCollide(lID,nl,no,checkCollisionsLL,checkCollisionsLO))
1008  {
1009  l=GetMechanismLink(lID,m);
1010  nB=LinkNBodies(l);
1011 
1012  for(bID=0;bID<nB;bID++)
1013  {
1014  if (GetLinkBodyStatus(bID,l)!=DECOR_SHAPE)
1015  {
1016  p->linkID[p->np]=lID;
1017  p->bodyID[p->np]=bID;
1018 
1019  shape=GetLinkBody(bID,l);
1020  GetOFFInfo(&nv,&v,&nf,&nvf,&fv,shape);
1021  p->model[p->np]=DefinePQPModel(v,nf,nvf,fv);
1022 
1023  p->np++;
1024  }
1025  }
1026  }
1027  }
1028 
1029  for(oID=0;oID<no;oID++)
1030  {
1031  if ((ObstacleCanCollide(oID,nl,checkCollisionsLO))&&
1033  {
1034  p->linkID[p->np]=NO_UINT;
1035  p->bodyID[p->np]=oID;
1036 
1037  shape=GetObstacleShape(oID,e);
1038  GetOFFInfo(&nv,&v,&nf,&nvf,&fv,shape);
1039  p->model[p->np]=DefinePQPModel(v,nf,nvf,fv);
1040 
1041  p->np++;
1042  }
1043  }
1044 
1045  /* Now define the possible collisions */
1046 
1047  NEW(p->p1,p->np*(p->np-1),unsigned int);
1048  NEW(p->p2,p->np*(p->np-1),unsigned int);
1049  p->nPairs=0;
1050  for(i=0;i<p->np;i++)
1051  {
1052  lID1=p->linkID[i];
1053  if (lID1!=NO_UINT) /* if link1 is an obstacle, skip */
1054  {
1055  for(j=i+1;j<p->np;j++)
1056  {
1057  lID2=p->linkID[j];
1058  if (lID2!=NO_UINT)
1059  {
1060  /* link-link */
1061  if (checkCollisionsLL[lID1][lID2])
1062  {
1063  p->p1[p->nPairs]=i;
1064  p->p2[p->nPairs]=j;
1065  p->nPairs++;
1066  }
1067  }
1068  else
1069  {
1070  /* link-obstacle */
1071  bID2=p->bodyID[j];
1072  if (checkCollisionsLO[lID1][bID2])
1073  {
1074  p->p1[p->nPairs]=i;
1075  p->p2[p->nPairs]=j;
1076  p->nPairs++;
1077  }
1078  }
1079  }
1080  }
1081  }
1082  }
1083 
1085  {
1086  boolean collision;
1087  unsigned int n,i,j,l1,l2;
1088  THTransform *t1,*t2;
1089 
1090  n=0;
1091  collision=FALSE;
1092  while((!collision)&&(n<p->nPairs))
1093  {
1094  i=p->p1[n];
1095  j=p->p2[n];
1096 
1097  l1=p->linkID[i];
1098  l2=p->linkID[j];
1099 
1100  if (l1!=NO_UINT)
1101  t1=&(tl[l1]);
1102  else
1103  t1=NULL;
1104 
1105  if (l2!=NO_UINT)
1106  t2=&(tl[l2]);
1107  else
1108  t2=NULL;
1109 
1110  collision=PQPTest(t1,p->model[i],t2,p->model[j]);
1111 
1112  n++;
1113  }
1114  return(collision);
1115  }
1116 
1118  {
1119  unsigned int i;
1120 
1121  for(i=0;i<p->np;i++)
1122  DeletePQPModel(p->model[i]);
1123 
1124  free(p->model);
1125  free(p->linkID);
1126  free(p->bodyID);
1127  free(p->p1);
1128  free(p->p2);
1129  }
1130 
1131 #endif
1132 
1133 #if _HAVE_FCL
1134 
1135  void DefineFCLObject(Tpolyhedron *shape,TfclCD *p)
1136  {
1137  double p1[3],p2[3],r,l;
1138  double **v;
1139  unsigned int nv,nf,*nvf,**fv;
1140  THTransform t1,t2;
1141  TFCLObject *obj;
1142 
1143  obj=&(p->object[p->np]);
1144 
1145  switch(GetPolyhedronType(shape))
1146  {
1147  case SPHERE:
1148  r=GetPolyhedronRadius(shape);
1149  obj->model=DefineFCLSphere(r);
1150  GetPolyhedronCenter(p1,shape);
1151  HTransformTxyz(p1[0],p1[1],p1[2],&(obj->tc));
1152 
1153  /* Set the type */
1154  obj->type=FCL_SPHERE;
1155  break;
1156 
1157  case CYLINDER:
1158  /* vector with unit length along the Z axis (zero centered) */
1159  r=GetPolyhedronRadius(shape);
1160  GetPolyhedronDefiningPoint(0,p1,shape);
1161  GetPolyhedronDefiningPoint(1,p2,shape);
1162  SubtractVector(3,p2,p1); /* p2=p2-p1 */
1163  l=Norm(3,p2);
1164  obj->model=DefineFCLCylinder(r,l);
1165 
1166  /* define the correction: apply from end to top */
1167  /* the transforms must be proper rigid transforms (do not use
1168  scale/deformation) */
1169  /* Move the x-aligned cylinder to an arbitrary position (3) */
1170  SumVectorScale(3,p1,1.0/l,p2,p2);
1171  HTransformX2Vect(1,1,p1,p2,&t1);
1172  /* rotate to align the cylinder with the X axis (2) */
1173  HTransformRy2(1,0,&t2);
1174  HTransformProduct(&t1,&t2,&t1);
1175  /* move the cylinder to the positive Z axis (1) */
1176  HTransformTz(0.5*l,&t2);
1177  HTransformProduct(&t1,&t2,&(obj->tc));
1178 
1179  /* Set the type */
1180  obj->type=FCL_CYLINDER;
1181  break;
1182 
1183  default:
1184  /* The soup of triangles is defined and works for any body */
1185  GetOFFInfo(&nv,&v,&nf,&nvf,&fv,shape);
1186  obj->model=DefineFCLMesh(nv,v,nf,nvf,fv);
1187  HTransformIdentity(&(obj->tc));
1188 
1189  /* Set the type */
1190  obj->type=FCL_MESH;
1191  }
1192  }
1193 
1194  void InitFCLCD(Tmechanism *m,Tenvironment *e,
1195  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
1196  TfclCD *p)
1197  {
1198  unsigned int i,j,k,lID1,lID2,bID2,np,nl,no,nB,lID,bID,oID;
1199  Tpolyhedron *shape;
1200  Tlink *l;
1201 
1202  nl=GetMechanismNLinks(m);
1204  np=GetMechanismNBodies(m)+no;
1205 
1206  /* np is always larger (or equal) than the number of part that can actually
1207  collide. */
1208  NEW(p->object,np,TFCLObject);
1209 
1210  /* Generate the shapes */
1211  p->np=0;
1212  for(lID=0;lID<nl;lID++)
1213  {
1214  if (LinkCanCollide(lID,nl,no,checkCollisionsLL,checkCollisionsLO))
1215  {
1216  l=GetMechanismLink(lID,m);
1217  nB=LinkNBodies(l);
1218 
1219  for(bID=0;bID<nB;bID++)
1220  {
1221  if (GetLinkBodyStatus(bID,l)!=DECOR_SHAPE)
1222  {
1223  p->object[p->np].linkID=lID;
1224  p->object[p->np].bodyID=bID;
1225 
1226  shape=GetLinkBody(bID,l);
1227  DefineFCLObject(shape,p);
1228  p->np++;
1229  }
1230  }
1231  }
1232  }
1233  k=p->np; /* mobile parts */
1234  for(oID=0;oID<no;oID++)
1235  {
1236  if ((ObstacleCanCollide(oID,nl,checkCollisionsLO))&&
1238  {
1239  p->object[p->np].linkID=NO_UINT;
1240  p->object[p->np].bodyID=oID;
1241 
1242  shape=GetObstacleShape(oID,e);
1243  DefineFCLObject(shape,p);
1244  p->np++;
1245  }
1246  }
1247 
1248  /* Now define the possible collisions */
1249  k=k*(p->np-1); /* k=k*(k-1)+k*(p->np-k) link-link link-obs */
1250  NEW(p->p1,k,unsigned int);
1251  NEW(p->p2,k,unsigned int);
1252 
1253  p->nPairs=0;
1254  for(i=0;i<p->np;i++)
1255  {
1256  lID1=p->object[i].linkID;
1257  if (lID1!=NO_UINT) /* if object is an obstacle, skip */
1258  {
1259  for(j=i+1;j<p->np;j++)
1260  {
1261  lID2=p->object[j].linkID;
1262  if (lID2!=NO_UINT)
1263  {
1264  /* link-link */
1265  if (checkCollisionsLL[lID1][lID2])
1266  {
1267  p->p1[p->nPairs]=i;
1268  p->p2[p->nPairs]=j;
1269  p->nPairs++;
1270  }
1271  }
1272  else
1273  {
1274  /* link-obstacle */
1275  bID2=p->object[j].bodyID;
1276  if (checkCollisionsLO[lID1][bID2])
1277  {
1278  p->p1[p->nPairs]=i;
1279  p->p2[p->nPairs]=j;
1280  p->nPairs++;
1281  }
1282  }
1283  }
1284  }
1285  }
1286 
1287  p->nc=0;
1288  p->mc=10;
1289  NEW(p->collision,p->mc,TCollisionInfo);
1290 
1291  /* set the default transform for each part */
1292  for(i=0;i<p->np;i++)
1293  HTransformCopy(&(p->object[i].t),&(p->object[i].tc));
1294  }
1295 
1296  boolean CheckCollisionFCL(boolean all,THTransform *tl,TfclCD *p)
1297  {
1298  boolean collision,done,newCollision;
1299  unsigned int i,j,lID;
1300  signed int n;
1301  double point[3],normal[3];
1302  TFCLObject *obj1,*obj2;
1303 
1304  /* Precompute the transforms for each part */
1305  for(i=0;i<p->np;i++)
1306  {
1307  lID=p->object[i].linkID;
1308  /* the transforms for static objecs are already pre-computed */
1309  if (lID!=NO_UINT)
1310  {
1311  if (p->object[i].type==FCL_MESH) /* meshes have no offset */
1312  HTransformCopy(&(p->object[i].t),&(tl[lID]));
1313  else
1314  HTransformProduct(&(tl[lID]),&(p->object[i].tc),&(p->object[i].t));
1315  }
1316  }
1317 
1318  p->nc=0; /* Reset the collision information. Will be updated probably. */
1319  n=0;
1320  collision=FALSE;
1321  done=FALSE;
1322  while((!done)&&(n<p->nPairs))
1323  {
1324  i=p->p1[n];
1325  j=p->p2[n];
1326  obj1=&(p->object[i]);
1327  obj2=&(p->object[j]);
1328 
1329  newCollision=FCLTest(all,
1330  obj1->model,&(obj1->t),
1331  obj2->model,&(obj2->t),
1332  point,normal);
1333 
1334  if ((all)&&(newCollision))
1335  {
1336  unsigned int l1,l2,k;
1337  TCollisionInfo *col;
1338 
1339  /* collect the collision results */
1340  if (p->nc==p->mc)
1341  {
1342  MEM_DUP(p->collision,p->mc,TCollisionInfo);
1343  }
1344 
1345  col=&(p->collision[p->nc]);
1346 
1347  l1=obj1->linkID;
1348  if (l1==NO_UINT)
1349  {
1350  col->isLink1=FALSE;
1351  col->id1=obj1->bodyID;
1352  }
1353  else
1354  {
1355  col->isLink1=TRUE;
1356  col->id1=l1;
1357  }
1358 
1359  l2=obj2->linkID;
1360  if (l2==NO_UINT)
1361  {
1362  col->isLink2=FALSE;
1363  col->id2=obj2->bodyID;
1364  }
1365  else
1366  {
1367  col->isLink2=TRUE;
1368  col->id2=l2;
1369  }
1370 
1371  for(k=0;k<3;k++)
1372  {
1373  col->point[k]=point[k];
1374  col->normal[k]=normal[k];
1375  }
1376  /* Just in case ;) */
1377  Normalize(3,col->normal);
1378 
1379  /* Store the transforms as given by the user */
1380  if (col->isLink1)
1381  HTransformCopy(&(col->t1),&(tl[col->id1]));
1382  else
1383  HTransformIdentity(&(col->t1));
1384 
1385  if (col->isLink2)
1386  HTransformCopy(&(col->t2),&(tl[col->id2]));
1387  else
1388  HTransformIdentity(&(col->t2));
1389 
1390  p->nc++;
1391  }
1392 
1393  collision=((collision)||(newCollision));
1394 
1395  done=((!all)&&(newCollision));
1396 
1397  n++;
1398  }
1399  return(collision);
1400  }
1401 
1402  boolean CheckContCollisionFCL(THTransform *tl,THTransform *tlPrev,TfclCD *p)
1403  {
1404  if (tlPrev==NULL)
1405  return(CheckCollisionFCL(FALSE,tl,p));
1406  else
1407  {
1408  boolean collision;
1409  unsigned int n,i,j,lID;
1410  THTransform *tp;
1411  TFCLObject *obj1,*obj2;
1412 
1413  /* Precompute the transform */
1414  NEW(tp,p->np,THTransform);
1415 
1416  /* Precompute the transforms for each part */
1417  for(i=0;i<p->np;i++)
1418  {
1419  obj1=&(p->object[i]);
1420 
1421  lID=obj1->linkID;
1422 
1423  if (lID!=NO_UINT)
1424  {
1425  if (obj1->type==FCL_MESH)
1426  {
1427  HTransformCopy(&(obj1->t),&(tl[lID]));
1428  HTransformCopy(&(tp[i]),&(tlPrev[lID]));
1429  }
1430  else
1431  {
1432  HTransformProduct(&(tl[lID]),&(obj1->tc),&(obj1->t));
1433  HTransformProduct(&(tlPrev[lID]),&(obj1->tc),&(tp[i]));
1434  }
1435  }
1436  else
1437  HTransformCopy(&(tp[i]),&(obj1->tc)); /* static object -> copy the offset, if any */
1438  }
1439 
1440 
1441  p->nc=0; /* Reset the collision information. Not updated here. */
1442  n=0;
1443  collision=FALSE;
1444  while((!collision)&&(n<p->nPairs))
1445  {
1446  i=p->p1[n];
1447  j=p->p2[n];
1448  obj1=&(p->object[i]);
1449  obj2=&(p->object[j]);
1450 
1451  collision=FCLCTest(obj1->model,&(tp[i]),&(obj1->t),
1452  obj2->model,&(tp[j]),&(obj2->t));
1453 
1454  n++;
1455  }
1456 
1457  /* release the allocated memory */
1458  free(tp);
1459 
1460  return(collision);
1461  }
1462  }
1463 
1464  void DeleteFCLCD(TfclCD *p)
1465  {
1466  unsigned int i;
1467 
1468  for(i=0;i<p->np;i++)
1469  DeleteFCLObject(p->object[i].model);
1470 
1471  free(p->object);
1472  free(p->p1);
1473  free(p->p2);
1474  free(p->collision);
1475  }
1476 
1477 #endif
1478 
1479 #ifdef _HAVE_BULLET
1480 
1481  void DefineBulletObject(boolean fixed,Tpolyhedron *shape,TBulletCD *p)
1482  {
1483  double p1[3],p2[3],r,l;
1484  double **v;
1485  unsigned int nv,nf,*nvf,**fv;
1486  THTransform t1,t2;
1487  TBulletObject *obj;
1488 
1489  obj=&(p->object[p->np]);
1490 
1491  switch(GetPolyhedronType(shape))
1492  {
1493  case SPHERE:
1494  r=GetPolyhedronRadius(shape);
1495  obj->model=DefineBulletSphere(fixed,r);
1496  GetPolyhedronCenter(p1,shape);
1497  HTransformTxyz(p1[0],p1[1],p1[2],&(obj->tc));
1498 
1499  /* Set the type */
1500  obj->type=BULLET_SPHERE;
1501  break;
1502 
1503  case CYLINDER:
1504  /* vector with unit length along the X axis (zero centered) */
1505  r=GetPolyhedronRadius(shape);
1506  GetPolyhedronDefiningPoint(0,p1,shape);
1507  GetPolyhedronDefiningPoint(1,p2,shape);
1508  SubtractVector(3,p2,p1); /* p2=p2-p1 */
1509  l=Norm(3,p2);
1510  obj->model=DefineBulletCylinder(fixed,r,l);
1511 
1512  /* define the correction: apply from end to top */
1513  /* the transforms must be proper rigid transforms (do not use
1514  scale/deformation) */
1515  /* Move the x-aligned cylinder to an arbitrary position (3) */
1516  SumVectorScale(3,p1,1.0/l,p2,p2);
1517  HTransformX2Vect(1,1,p1,p2,&t1);
1518 
1519  /* move the cylinder to the positive X axis (1) */
1520  HTransformTx(0.5*l,&t2);
1521  HTransformProduct(&t1,&t2,&(obj->tc));
1522 
1523  /* Set the type */
1524  obj->type=BULLET_CYLINDER;
1525  break;
1526 
1527  default:
1528  /* The soup of triangles is defined and works for any body */
1529  GetOFFInfo(&nv,&v,&nf,&nvf,&fv,shape);
1530  obj->model=DefineBulletMesh(fixed,nv,v,nf,nvf,fv);
1531  HTransformIdentity(&(obj->tc));
1532 
1533  /* Set the type */
1534  obj->type=BULLET_MESH;
1535  }
1536  }
1537 
1538  void InitBulletCD(Tmechanism *m,Tenvironment *e,
1539  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
1540  boolean cont,TBulletCD *p)
1541  {
1542  unsigned int i,j,k,lID1,lID2,bID2,np,nl,no,nB,lID,bID,oID;
1543  Tpolyhedron *shape;
1544  Tlink *l;
1545 
1546  nl=GetMechanismNLinks(m);
1548  np=GetMechanismNBodies(m)+no;
1549 
1550  /* np is always larger (or equal) than the number of part that can actually
1551  collide. */
1552  NEW(p->object,np,TBulletObject);
1553 
1554  /* Generate the shapes */
1555  p->np=0;
1556  for(lID=0;lID<nl;lID++)
1557  {
1558  if (LinkCanCollide(lID,nl,no,checkCollisionsLL,checkCollisionsLO))
1559  {
1560  l=GetMechanismLink(lID,m);
1561  nB=LinkNBodies(l);
1562 
1563  for(bID=0;bID<nB;bID++)
1564  {
1565  if (GetLinkBodyStatus(bID,l)!=DECOR_SHAPE)
1566  {
1567  p->object[p->np].linkID=lID;
1568  p->object[p->np].bodyID=bID;
1569 
1570  shape=GetLinkBody(bID,l);
1571  DefineBulletObject(IsGroundLink(lID),shape,p);
1572  p->np++;
1573  }
1574  }
1575  }
1576  }
1577  k=p->np; /* mobile parts */
1578  for(oID=0;oID<no;oID++)
1579  {
1580  if ((ObstacleCanCollide(oID,nl,checkCollisionsLO))&&
1582  {
1583  p->object[p->np].linkID=NO_UINT;
1584  p->object[p->np].bodyID=oID;
1585 
1586  shape=GetObstacleShape(oID,e);
1587  DefineBulletObject(TRUE,shape,p);
1588  p->np++;
1589  }
1590  }
1591 
1592  /* Now define the possible collisions */
1593  k=k*(p->np-1); /* k=k*(k-1)+k*(p->np-k) link-link link-obs */
1594  NEW(p->p1,k,unsigned int);
1595  NEW(p->p2,k,unsigned int);
1596 
1597  p->nPairs=0;
1598  for(i=0;i<p->np;i++)
1599  {
1600  lID1=p->object[i].linkID;
1601  if (lID1!=NO_UINT) /* if object is an obstacle, skip */
1602  {
1603  for(j=i+1;j<p->np;j++)
1604  {
1605  lID2=p->object[j].linkID;
1606  if (lID2!=NO_UINT)
1607  {
1608  /* link-link */
1609  if (checkCollisionsLL[lID1][lID2])
1610  {
1611  p->p1[p->nPairs]=i;
1612  p->p2[p->nPairs]=j;
1613  p->nPairs++;
1614  }
1615  }
1616  else
1617  {
1618  /* link-obstacle */
1619  bID2=p->object[j].bodyID;
1620  if (checkCollisionsLO[lID1][bID2])
1621  {
1622  p->p1[p->nPairs]=i;
1623  p->p2[p->nPairs]=j;
1624  p->nPairs++;
1625  }
1626  }
1627  }
1628  }
1629  }
1630 
1631  p->nc=0;
1632  p->mc=10;
1633  NEW(p->collision,p->mc,TCollisionInfo);
1634 
1635  /* set the default transform for each part */
1636  for(i=0;i<p->np;i++)
1637  HTransformCopy(&(p->object[i].t),&(p->object[i].tc));
1638 
1639  /* Initialize the bullet world structure */
1640  p->bulletWorld=InitBulletWorld(cont);
1641  }
1642 
1643  boolean CheckCollisionBullet(boolean all,THTransform *tl,TBulletCD *p)
1644  {
1645  boolean collision,done,newCollision;
1646  unsigned int i,j,lID;
1647  signed int n;
1648  double point[3],normal[3];
1649  TBulletObject *obj1,*obj2;
1650 
1651  /* Precompute the transforms for each part */
1652  for(i=0;i<p->np;i++)
1653  {
1654  lID=p->object[i].linkID;
1655  /* the transforms for static objecs are already pre-computed */
1656  if (lID!=NO_UINT)
1657  {
1658  if (p->object[i].type==BULLET_MESH) /* meshes have no offset */
1659  HTransformCopy(&(p->object[i].t),&(tl[lID]));
1660  else
1661  HTransformProduct(&(tl[lID]),&(p->object[i].tc),&(p->object[i].t));
1662  }
1663  }
1664 
1665  p->nc=0; /* Reset the collision information. Will be updated probably. */
1666  n=0;
1667  collision=FALSE;
1668  done=FALSE;
1669  while((!done)&&(n<p->nPairs))
1670  {
1671  i=p->p1[n];
1672  j=p->p2[n];
1673  obj1=&(p->object[i]);
1674  obj2=&(p->object[j]);
1675 
1676  newCollision=BulletTest(all,
1677  obj1->model,&(obj1->t),
1678  obj2->model,&(obj2->t),
1679  point,normal,p->bulletWorld);
1680 
1681  if ((all)&&(newCollision))
1682  {
1683  unsigned int l1,l2,k;
1684  TCollisionInfo *col;
1685 
1686  /* collect the collision results */
1687  if (p->nc==p->mc)
1688  {
1689  MEM_DUP(p->collision,p->mc,TCollisionInfo);
1690  }
1691 
1692  col=&(p->collision[p->nc]);
1693 
1694  l1=obj1->linkID;
1695  if (l1==NO_UINT)
1696  {
1697  col->isLink1=FALSE;
1698  col->id1=obj1->bodyID;
1699  }
1700  else
1701  {
1702  col->isLink1=TRUE;
1703  col->id1=l1;
1704  }
1705 
1706  l2=obj2->linkID;
1707  if (l2==NO_UINT)
1708  {
1709  col->isLink2=FALSE;
1710  col->id2=obj2->bodyID;
1711  }
1712  else
1713  {
1714  col->isLink2=TRUE;
1715  col->id2=l2;
1716  }
1717 
1718  for(k=0;k<3;k++)
1719  {
1720  col->point[k]=point[k];
1721  col->normal[k]=normal[k];
1722  }
1723  /* Just in case ;) */
1724  Normalize(3,col->normal);
1725 
1726  /* Store the transforms as given by the user */
1727  if (col->isLink1)
1728  HTransformCopy(&(col->t1),&(tl[col->id1]));
1729  else
1730  HTransformIdentity(&(col->t1));
1731 
1732  if (col->isLink2)
1733  HTransformCopy(&(col->t2),&(tl[col->id2]));
1734  else
1735  HTransformIdentity(&(col->t2));
1736 
1737  p->nc++;
1738  }
1739 
1740  collision=((collision)||(newCollision));
1741 
1742  done=((!all)&&(newCollision));
1743 
1744  n++;
1745  }
1746  return(collision);
1747  }
1748 
1749  boolean CheckContCollisionBullet(THTransform *tl,THTransform *tlPrev,TBulletCD *p)
1750  {
1751  if (tlPrev==NULL)
1752  return(CheckCollisionBullet(FALSE,tl,p));
1753  else
1754  {
1755  boolean collision;
1756  unsigned int n,i,j,lID;
1757  THTransform *tp;
1758  TBulletObject *obj1,*obj2;
1759 
1760  /* Precompute the transform */
1761  NEW(tp,p->np,THTransform);
1762 
1763  /* Precompute the transforms for each part */
1764  for(i=0;i<p->np;i++)
1765  {
1766  obj1=&(p->object[i]);
1767 
1768  lID=obj1->linkID;
1769 
1770  if (lID!=NO_UINT)
1771  {
1772  if (obj1->type==BULLET_MESH)
1773  {
1774  HTransformCopy(&(obj1->t),&(tl[lID]));
1775  HTransformCopy(&(tp[i]),&(tlPrev[lID]));
1776  }
1777  else
1778  {
1779  HTransformProduct(&(tl[lID]),&(obj1->tc),&(obj1->t));
1780  HTransformProduct(&(tlPrev[lID]),&(obj1->tc),&(tp[i]));
1781  }
1782  }
1783  else
1784  HTransformCopy(&(tp[i]),&(obj1->tc)); /* static object -> copy the offset, if any */
1785  }
1786 
1787 
1788  p->nc=0; /* Reset the collision information. Not updated here. */
1789  n=0;
1790  collision=FALSE;
1791  while((!collision)&&(n<p->nPairs))
1792  {
1793  i=p->p1[n];
1794  j=p->p2[n];
1795  obj1=&(p->object[i]);
1796  obj2=&(p->object[j]);
1797 
1798  collision=BulletCTest(obj1->model,&(tp[i]),&(obj1->t),
1799  obj2->model,&(tp[j]),&(obj2->t),p->bulletWorld);
1800 
1801  n++;
1802  }
1803 
1804  /* release the allocated memory */
1805  free(tp);
1806 
1807  return(collision);
1808  }
1809  }
1810 
1811  void DeleteBulletCD(TBulletCD *p)
1812  {
1813  unsigned int i;
1814 
1815  for(i=0;i<p->np;i++)
1816  DeleteBulletObject(p->object[i].model);
1817 
1818  free(p->object);
1819  free(p->p1);
1820  free(p->p2);
1821  free(p->collision);
1822 
1823  DeleteBulletWorld(p->bulletWorld);
1824  }
1825 #endif
1826 
1827 #ifdef _HAVE_RIGIDCLL
1828 
1829  boolean ObstaclesCollideLikeGround(unsigned int nl,unsigned int no,boolean **checkCollisionsLL,boolean **checkCollisionsLO)
1830  {
1831  unsigned int i,j;
1832  boolean same;
1833 
1834  same=TRUE;
1835  for(i=0;((same)&&(i<no));i++)
1836  {
1837  for(j=0;((same)&&(j<nl));j++)
1838  same=(checkCollisionsLO[j][i]==checkCollisionsLL[j][0]);
1839  }
1840  return(same);
1841  }
1842 
1843 
1844  void InitRigidCLLCD(Tmechanism *m,Tenvironment *e,
1845  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
1846  TrigidCLLCD *r)
1847  {
1848  unsigned int lID1,lID2,np,no,npl,nB,lID,bID,oID,atomID;
1849  double *center,rad;
1850  Tpolyhedron *shape;
1851  Tlink *l;
1852  boolean obsLikeGround,added;
1853 
1854  r->r=InitRigidCLL();
1855 
1856  r->nl=GetMechanismNLinks(m);
1858 
1859  /* Create the shapes */
1860  NEW(center,3,double);
1861  NEW(r->objID,r->nl+no,unsigned int);
1862 
1863  /* Generate the shapes */
1864  np=0;
1865  atomID=0;
1866  for(lID=0;lID<r->nl;lID++)
1867  {
1868  if (LinkCanCollide(lID,r->nl,no,checkCollisionsLL,checkCollisionsLO))
1869  {
1870  l=GetMechanismLink(lID,m);
1871 
1872  if (!IsGroundLink(lID))
1873  r->objID[lID]=StartRigidCLLObject(r->r);
1874  else
1875  r->objID[lID]=0;
1876  added=FALSE;
1877 
1878  nB=LinkNBodies(l);
1879 
1880  for(bID=0;bID<nB;bID++)
1881  {
1882  if (GetLinkBodyStatus(bID,l)!=DECOR_SHAPE)
1883  {
1884  shape=GetLinkBody(bID,l);
1885  if (GetPolyhedronType(shape)!=SPHERE)
1886  Error("The RigidCLL collision engine can only be used on spheres");
1887 
1888  GetPolyhedronCenter(center,shape);
1889  rad=GetPolyhedronRadius(shape);
1890 
1891  if (IsGroundLink(lID))
1892  AddFixedSphere2RigidCLL(atomID,center,rad,r->r);
1893  else
1894  AddMobileSphere2RigidCLL(atomID,center,rad,r->r);
1895  atomID++;
1896  added=TRUE;
1897  }
1898  }
1899 
1900  if (!added)
1901  Error("Empty link in InitRigidCLL");
1902 
1903  if (!IsGroundLink(lID))
1904  CloseRigidCLLObject(r->r);
1905  np++;
1906  }
1907  else
1908  r->objID[lID]=NO_UINT;
1909  }
1910  npl=np;
1911 
1912  /* molecular problems typically do not have 'environment' we
1913  treat them as rigids that will not move (will move with
1914  the identity transform).
1915  If we ever have 'environment' it will be composed by
1916  a list of spheres, each acting as a single rigid.*/
1917  if (ObstaclesCollideLikeGround(r->nl,no,checkCollisionsLL,checkCollisionsLO))
1918  {
1919  /* Add the obstacle spheres to the ground link (in case we have obstacles
1920  this will be the most usual case). */
1921  obsLikeGround=TRUE;
1922  for(oID=0;oID<no;oID++)
1923  {
1924  if (GetObstacleShapeStatus(oID,e)!=DECOR_SHAPE)
1925  {
1926  shape=GetObstacleShape(oID,e);
1927 
1928  if (GetPolyhedronType(shape)!=SPHERE)
1929  Error("The RigidCLL collision engine can only be used on spheres");
1930 
1931  GetPolyhedronCenter(center,shape);
1932  rad=GetPolyhedronRadius(shape);
1933 
1934  AddFixedSphere2RigidCLL(atomID,center,rad,r->r);
1935  atomID++;
1936  }
1937  }
1938  }
1939  else
1940  {
1941  /* add the obstacles spheres individually */
1942  obsLikeGround=FALSE;
1943  for(oID=0;oID<no;oID++)
1944  {
1945  if ((ObstacleCanCollide(oID,r->nl,checkCollisionsLO))&&
1947  {
1948  shape=GetObstacleShape(oID,e);
1949 
1950  if (GetPolyhedronType(shape)!=SPHERE)
1951  Error("The RigidCLL collision engine can only be used on spheres");
1952 
1953  r->objID[r->nl+oID]=StartRigidCLLObject(r->r);
1954 
1955  GetPolyhedronCenter(center,shape);
1956  rad=GetPolyhedronRadius(shape);
1957 
1958  AddMobileSphere2RigidCLL(atomID,center,rad,r->r);
1959  atomID++;
1960 
1961  CloseRigidCLLObject(r->r);
1962  np++;
1963  }
1964  }
1965  }
1966 
1967  /* init the space for the transforms */
1968  NEW(r->t,np,THTransform);
1969  /* the ground link does not move */
1970  HTransformIdentity(&(r->t[0]));
1971  /* The obstacles will never move */
1972  if (!obsLikeGround)
1973  {
1974  for(no=npl;no<np;no++)
1975  HTransformIdentity(&(r->t[no]));
1976  }
1977 
1978  /* Now define the possible collisions */
1979  for(lID1=0;lID1<r->nl;lID1++)
1980  {
1981  for(lID2=lID1+1;lID2<r->nl;lID2++)
1982  {
1983  if (checkCollisionsLL[lID1][lID2])
1984  ActivateCollisionsRigidCLL(r->objID[lID1],r->objID[lID2],r->r);
1985  else
1986  DeactivateCollisionsRigidCLL(r->objID[lID1],r->objID[lID2],r->r);
1987  }
1988  if (!obsLikeGround)
1989  {
1990  for(oID=0;oID<no;oID++)
1991  {
1992  if (checkCollisionsLO[lID1][oID])
1993  ActivateCollisionsRigidCLL(r->objID[lID1],r->objID[r->nl+oID],r->r);
1994  else
1995  DeactivateCollisionsRigidCLL(r->objID[lID1],r->objID[r->nl+oID],r->r);
1996  }
1997  }
1998  }
1999  free(center);
2000  }
2001 
2002  boolean CheckCollisionRigidCLL(THTransform *tl,TrigidCLLCD *r)
2003  {
2004  unsigned int i;
2005 
2006  for(i=0;i<r->nl;i++)
2007  {
2008  if (r->objID[i]!=NO_UINT)
2009  HTransformCopy(&(r->t[r->objID[i]]),&(tl[i]));
2010  }
2011 
2012  return(MoveAndCheckRigidCLL(r->t,r->r));
2013  }
2014 
2015  void DeleteRigidCLLCD(TrigidCLLCD *r)
2016  {
2017  DeleteRigidCLL(r->r);
2018  free(r->t);
2019  free(r->objID);
2020  }
2021 
2022 #endif
2023 
2024 
2025 /************************************************************************************************/
2026 /* Private functions: generic functions on arrays of detected collisions. Only some engines
2027  are able to generate such arrays (SOLID and FCL) */
2028 
2029 void StoreCollisionInfoInt(FILE *f,char *fname,unsigned int objectID,Tmechanism *m,unsigned int nc,TCollisionInfo *c)
2030 {
2031  if (nc>0)
2032  {
2033  unsigned int i,j;
2034  unsigned int lID1,lID2;
2035  boolean isLink1,isLink2;
2036  THTransform *t1,*t2;
2037  char *ln1,*ln2;
2038  char *wname="world";
2039 
2040  fprintf(f,"fname='%s';\n\n",fname);
2041  for(i=0;i<nc;i++)
2042  {
2043  /* We are only interested on collisions with respect to the manipulated object (which actually is a link) */
2044  if ((objectID==NO_UINT)||
2045  ((c[i].isLink1)&&(c[i].id1==objectID))||
2046  ((c[i].isLink2)&&(c[i].id2==objectID)))
2047  {
2048  j=i+1; /* printed indices start at 1 */
2049 
2050  if ((objectID==NO_UINT)||((c[i].isLink1)&&(c[i].id1==objectID)))
2051  {
2052  isLink1=c[i].isLink1;
2053  isLink2=c[i].isLink2;
2054  lID1=c[i].id1;
2055  lID2=c[i].id2;
2056  t1=&(c[i].t1);
2057  t2=&(c[i].t2);
2058  }
2059  else
2060  {
2061  isLink1=c[i].isLink2;
2062  isLink2=c[i].isLink1;
2063  lID1=c[i].id2;
2064  lID2=c[i].id1;
2065  t1=&(c[i].t2);
2066  t2=&(c[i].t1);
2067  }
2068 
2069  ln1=(isLink1?GetLinkName(GetMechanismLink(lID1,m)):wname);
2070  ln2=(isLink2?GetLinkName(GetMechanismLink(lID2,m)):wname);
2071 
2072  fprintf(f,"p_%u=[%.16f %.16f %.16f 1]';\n\n",j,c[i].point[0],c[i].point[1],c[i].point[2]);
2073 
2074  fprintf(f,"T1_%u=[",j);
2075  HTransformPrint(f,t1);
2076  fprintf(f,"];\nlname1_%u='%s';\n\n",j,ln1);
2077 
2078  fprintf(f,"T2_%u=[",j);
2079  HTransformPrint(f,t2);
2080  fprintf(f,"];\nlname2_%u='%s';\n\n\n\n",j,ln2);
2081  }
2082  }
2083  for(i=0;i<nc;i++)
2084  {
2085  j=i+1;
2086  fprintf(f,"GenerateContactEqs(%u,fname,p_%u,lname1_%u,T1_%u,lname2_%u,T2_%u);\n",j,j,j,j,j,j);
2087  }
2088  fprintf(f,"\n\n\nexit\n");
2089  }
2090 }
2091 
2092 
2094 {
2095  char *ln1,*ln2;
2096  char *wname="world";
2097  unsigned int i;
2098  double p1[3],p2[3];
2099  THTransform t1,t2;
2100 
2101  /* if we stored any the collision information */
2102  for(i=0;i<nc;i++)
2103  {
2104  ln1=(c[i].isLink1?GetLinkName(GetMechanismLink(c[i].id1,m)):wname);
2105  ln2=(c[i].isLink2?GetLinkName(GetMechanismLink(c[i].id2,m)):wname);
2106 
2107  /* Transform the contact point given in global coordinates to local
2108  coordinates of the two involved bodies*/
2109  HTransformInverse(&(c[i].t1),&t1);
2110  HTransformApply(c[i].point,p1,&t1);
2111 
2112  HTransformInverse(&(c[i].t2),&t2);
2113  HTransformApply(c[i].point,p2,&t2);
2114 
2115  fprintf(stderr," - %s and %s collide at (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",
2116  ln1,ln2,p1[0],p1[1],p1[2],p2[0],p2[1],p2[2]);
2117 
2118  HTransformDelete(&t1);
2119  HTransformDelete(&t2);
2120  }
2121 }
2122 
2123 /************************************************************************************************/
2124 
2125 
2126 void InitCD(unsigned int engine,boolean parallel,
2127  Tmechanism *m,Tenvironment *e,
2128  boolean **checkCollisionsLL,boolean **checkCollisionsLO,
2129  TworldCD *cd)
2130 {
2131  cd->solid=NULL;
2132  cd->vcollide=NULL;
2133  cd->pqp=NULL;
2134  cd->fcl=NULL;
2135  cd->rigidCLL=NULL;
2136 
2137  switch(engine)
2138  {
2139  case SOLID:
2140  #ifdef _HAVE_SOLID
2141  NEW(cd->solid,1,TsolidCD);
2142  InitSolidCD(parallel,m,e,checkCollisionsLL,checkCollisionsLO,cd->solid);
2143  cd->engine=SOLID;
2144  #else
2145  Error("SOLID collision detection engine is not available");
2146  #endif
2147  break;
2148 
2149  case VCOLLIDE:
2150  #ifdef _HAVE_VCOLLIDE
2151  NEW(cd->vcollide,1,TvcollideCD);
2152  InitVcollideCD(m,e,checkCollisionsLL,checkCollisionsLO,cd->vcollide);
2153  cd->engine=VCOLLIDE;
2154  #else
2155  Error("VCOLLIDE collision detection engine is not available");
2156  #endif
2157  break;
2158 
2159  case PQP:
2160  #ifdef _HAVE_PQP
2161  NEW(cd->pqp,1,TpqpCD);
2162  InitPQPCD(m,e,checkCollisionsLL,checkCollisionsLO,cd->pqp);
2163  cd->engine=PQP;
2164  #else
2165  Error("PQP collision detection engine is not available");
2166  #endif
2167  break;
2168 
2169  case FCL:
2170  case C_FCL:
2171  #ifdef _HAVE_FCL
2172  NEW(cd->fcl,1,TfclCD);
2173  InitFCLCD(m,e,checkCollisionsLL,checkCollisionsLO,cd->fcl);
2174  cd->engine=engine;
2175  #else
2176  Error("FCL collision detection engine is not available");
2177  #endif
2178  break;
2179 
2180  case BULLET:
2181  case C_BULLET:
2182  #ifdef _HAVE_BULLET
2183  NEW(cd->bullet,1,TBulletCD);
2184  InitBulletCD(m,e,checkCollisionsLL,checkCollisionsLO,(engine==C_BULLET),cd->bullet);
2185  cd->engine=engine;
2186  #else
2187  Error("BULLET collision detection engine is not available");
2188  #endif
2189  break;
2190 
2191  case RIGIDCLL:
2192  #ifdef _HAVE_RIGIDCLL
2193  NEW(cd->rigidCLL,1,TrigidCLLCD);
2194  InitRigidCLLCD(m,e,checkCollisionsLL,checkCollisionsLO,cd->rigidCLL);
2195  cd->engine=RIGIDCLL;
2196  #else
2197  Error("RigidCLL collision detection engine is not available");
2198  #endif
2199  break;
2200 
2201  case NOCD:
2202  break;
2203 
2204  default:
2205  Error("Undefined collision detection engine");
2206  }
2207 }
2208 
2209 boolean LinkCanCollide(unsigned int l,unsigned int nl,unsigned int no,
2210  boolean **checkCollisionsLL,boolean **checkCollisionsLO)
2211 {
2212  unsigned int i;
2213  boolean found;
2214 
2215  found=FALSE;
2216  i=0;
2217  while((!found)&&(i<nl))
2218  {
2219  found=checkCollisionsLL[l][i];
2220  i++;
2221  }
2222  i=0;
2223  while((!found)&&(i<no))
2224  {
2225  found=checkCollisionsLO[l][i];
2226  i++;
2227  }
2228  return(found);
2229 }
2230 
2231 boolean ObstacleCanCollide(unsigned int o,unsigned int nl,boolean **checkCollisionsLO)
2232 {
2233  unsigned int i;
2234  boolean found;
2235 
2236  found=FALSE;
2237  i=0;
2238  while((!found)&&(i<nl))
2239  {
2240  found=checkCollisionsLO[i][o];
2241  i++;
2242  }
2243  return(found);
2244 }
2245 
2246 unsigned int GetCDEngine(TworldCD *cd)
2247 {
2248  return(cd->engine);
2249 }
2250 
2251 boolean CheckCollision(boolean all,THTransform *tl,THTransform *tlPrev,TworldCD *cd)
2252 {
2253  boolean collision=FALSE;
2254 
2255  switch (cd->engine)
2256  {
2257  case SOLID:
2258  #ifdef _HAVE_SOLID
2259  collision=CheckCollisionSolid(all,tl,cd->solid);
2260  #else
2261  Error("SOLID collision detection engine is not available");
2262  #endif
2263  break;
2264 
2265  case VCOLLIDE:
2266  #ifdef _HAVE_VCOLLIDE
2267  /* flag 'all' is not honored */
2268  collision=CheckCollisionVcollide(tl,cd->vcollide);
2269  #else
2270  Error("VCOLLIDE collision detection engine is not available");
2271  #endif
2272  break;
2273 
2274  case PQP:
2275  #ifdef _HAVE_PQP
2276  /* flag 'all' is not honored */
2277  collision=CheckCollisionPQP(tl,cd->pqp);
2278  #else
2279  Error("PQP collision detection engine is not available");
2280  #endif
2281  break;
2282 
2283  case FCL:
2284  #ifdef _HAVE_FCL
2285  collision=CheckCollisionFCL(all,tl,cd->fcl);
2286  #else
2287  Error("FCL collision detection engine is not available");
2288  #endif
2289  break;
2290 
2291  case C_FCL:
2292  #ifdef _HAVE_FCL
2293  collision=CheckContCollisionFCL(tl,tlPrev,cd->fcl);
2294  #else
2295  Error("FCL collision detection engine is not available");
2296  #endif
2297  break;
2298 
2299  case BULLET:
2300  #ifdef _HAVE_BULLET
2301  collision=CheckCollisionBullet(all,tl,cd->bullet);
2302  #else
2303  Error("BULLET collision detection engine is not available");
2304  #endif
2305  break;
2306 
2307  case C_BULLET:
2308  #ifdef _HAVE_BULLET
2309  collision=CheckContCollisionBullet(tl,tlPrev,cd->bullet);
2310  #else
2311  Error("BULLET collision detection engine is not available");
2312  #endif
2313  break;
2314 
2315  case RIGIDCLL:
2316  #ifdef _HAVE_RIGIDCLL
2317  /* flag 'all' is not honored */
2318  collision=CheckCollisionRigidCLL(tl,cd->rigidCLL);
2319  #else
2320  Error("RigidCLL collision detection engine is not available");
2321  #endif
2322  break;
2323 
2324  case NOCD:
2325  break;
2326 
2327  default:
2328  Error("Undefined collision detection engine");
2329  }
2330 
2331  return(collision);
2332 }
2333 
2334 void StoreCollisionInfo(FILE *f,char *fname,unsigned int objectID,Tmechanism *m,TworldCD *cd)
2335 {
2336  switch (cd->engine)
2337  {
2338  case SOLID:
2339  #ifdef _HAVE_SOLID
2340  StoreCollisionInfoInt(f,fname,objectID,m,cd->solid->nc,cd->solid->collision);
2341  #else
2342  Error("SOLID collision detection engine is not available");
2343  #endif
2344  break;
2345  case FCL:
2346  #ifdef _HAVE_FCL
2347  StoreCollisionInfoInt(f,fname,objectID,m,cd->fcl->nc,cd->fcl->collision);
2348  #else
2349  Error("FCL collision detection engine is not available");
2350  #endif
2351  break;
2352  case BULLET:
2353  #ifdef _HAVE_BULLET
2354  StoreCollisionInfoInt(f,fname,objectID,m,cd->bullet->nc,cd->bullet->collision);
2355  #else
2356  Error("Bullet collision detection engine is not available");
2357  #endif
2358  break;
2359  }
2360 }
2361 
2363 {
2364  switch (cd->engine)
2365  {
2366  case SOLID:
2367  #ifdef _HAVE_SOLID
2368  PrintCollisionInfoInt(tl,m,cd->solid->nc,cd->solid->collision);
2369  #else
2370  Error("SOLID collision detection engine is not available");
2371  #endif
2372  break;
2373  case FCL:
2374  #ifdef _HAVE_FCL
2375  PrintCollisionInfoInt(tl,m,cd->fcl->nc,cd->fcl->collision);
2376  #else
2377  Error("FCL collision detection engine is not available");
2378  #endif
2379  break;
2380  case BULLET:
2381  #ifdef _HAVE_BULLET
2382  PrintCollisionInfoInt(tl,m,cd->bullet->nc,cd->bullet->collision);
2383  #else
2384  Error("Bullet collision detection engine is not available");
2385  #endif
2386  break;
2387  }
2388 }
2389 
2390 
2392 {
2393  switch (cd->engine)
2394  {
2395  case SOLID:
2396  #ifdef _HAVE_SOLID
2397  DeleteSolidCD(cd->solid);
2398  free(cd->solid);
2399  #endif
2400  cd->solid=NULL;
2401  break;
2402 
2403  case VCOLLIDE:
2404  #ifdef _HAVE_VCOLLIDE
2406  free(cd->vcollide);
2407  #endif
2408  cd->vcollide=NULL;
2409  break;
2410 
2411  case PQP:
2412  #ifdef _HAVE_PQP
2413  DeletePQPCD(cd->pqp);
2414  free(cd->pqp);
2415  #endif
2416  cd->pqp=NULL;
2417  break;
2418 
2419  case FCL:
2420  case C_FCL:
2421  #ifdef _HAVE_FCL
2422  DeleteFCLCD(cd->fcl);
2423  free(cd->fcl);
2424  #endif
2425  cd->fcl=NULL;
2426  break;
2427 
2428  case BULLET:
2429  case C_BULLET:
2430  #ifdef _HAVE_BULLET
2431  DeleteBulletCD(cd->bullet);
2432  free(cd->bullet);
2433  #endif
2434  cd->bullet=NULL;
2435  break;
2436 
2437  case RIGIDCLL:
2438  #ifdef _HAVE_RIGIDCLL
2439  DeleteRigidCLLCD(cd->rigidCLL);
2440  free(cd->rigidCLL);
2441  #endif
2442  cd->rigidCLL=NULL;
2443  break;
2444 
2445  case NOCD:
2446  break;
2447 
2448  default:
2449  Error("Undefined collision detection engine (d)");
2450  }
2451 }
2452 
TsolidCD * solid
Definition: cd.h:262
boolean SolidCorrection(THTransform *t, Tpolyhedron *p)
Returns a transform that corrects the position of a polyhedron.
Definition: cd.c:590
unsigned int id2
Definition: cd.h:65
double GetPolyhedronRadius(Tpolyhedron *p)
Returns the radius used in the definition of the object.
Definition: polyhedron.c:1232
unsigned int linkID
Definition: cd.h:80
void * bullet
Definition: cd.h:288
#define PQP
One of the possible collison detection engines.
Definition: parameters.h:87
Information on the detected collisions.
Definition: cd.h:60
void HTransformRz2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:226
boolean LinkCanCollide(unsigned int l, unsigned int nl, unsigned int no, boolean **checkCollisionsLL, boolean **checkCollisionsLO)
Identifies links than can collide.
Definition: cd.c:2209
boolean isLink2
Definition: cd.h:64
#define FALSE
FALSE.
Definition: boolean.h:30
void * fcl
Definition: cd.h:282
void HTransformApply(double *p_in, double *p_out, THTransform *t)
Multiply a homogeneous transform and a vector.
Definition: htransform.c:728
void HTransformTxyz(double tx, double ty, double tz, THTransform *t)
Constructor.
Definition: htransform.c:140
unsigned int * bodyID
Definition: cd.h:129
TCollisionInfo * collision
Definition: cd.h:112
DT_RespTableHandle respTable
Definition: cd.h:104
void GetPolyhedronCenter(double *c, Tpolyhedron *p)
Gets the center of the spheres.
Definition: polyhedron.c:1145
#define NOCD
One of the possible collison detection engines.
Definition: parameters.h:141
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
Auxiliary data for the collision detection.
Definition: cd.h:257
void HTransformTz(double tz, THTransform *t)
Constructor.
Definition: htransform.c:128
Information associated with the PQP collision detection engine.
Definition: cd.h:143
unsigned int AddPolyhedron2Vcollide(double **v, unsigned int nf, unsigned int *nvf, unsigned int **fv, Tvcollide *vc)
Adds a polyhedron to the vcollide object.
Definition: cd_vcollide.cpp:30
A homgeneous transform in R^3.
double point[3]
Definition: cd.h:67
Tvcollide * InitVcollide()
Initializes a Vcollide object.
Definition: cd_vcollide.cpp:21
void InitVcollideCD(Tmechanism *m, Tenvironment *e, boolean **checkCollisionsLL, boolean **checkCollisionsLO, TvcollideCD *vc)
Initializes the Vcollide collision engine.
Definition: cd.c:852
void StoreCollisionInfoInt(FILE *f, char *fname, unsigned int objectID, Tmechanism *m, unsigned int nc, TCollisionInfo *c)
Stores the information collected during last collision check into a file.
Definition: cd.c:2029
Information associated with the solid collision detection engine.
Definition: cd.h:102
void DeleteSolidCD(TsolidCD *s)
Deletes the Solid related collision information.
Definition: cd.c:826
CBLAS_INLINE double Norm(unsigned int s, double *v)
Computes the norm of a vector.
unsigned int GetMechanismNLinks(Tmechanism *m)
Gets the number of links of a mechanism.
Definition: mechanism.c:25
boolean correction
Definition: cd.h:92
void InitCD(unsigned int engine, boolean parallel, Tmechanism *m, Tenvironment *e, boolean **checkCollisionsLL, boolean **checkCollisionsLO, TworldCD *cd)
Initializes the collision detector.
Definition: cd.c:2126
boolean CheckCollisionSolid(boolean all, THTransform *tl, TsolidCD *s)
Determines if there is a collision using the SOLID collision engine.
Definition: cd.c:784
void PrintCollisionInfoInt(THTransform *tl, Tmechanism *m, unsigned int nc, TCollisionInfo *c)
Prints information about the last collision check.
Definition: cd.c:2093
TvcollideCD * vcollide
Definition: cd.h:268
#define TRUE
TRUE.
Definition: boolean.h:21
CBLAS_INLINE void Normalize(unsigned int s, double *v)
Normalizes a vector.
#define CYLINDER
One of the possible type of polyhedrons.
Definition: polyhedron.h:80
unsigned int * linkID
Definition: cd.h:145
CBLAS_INLINE void HTransform2GLMatrix(double *m, THTransform *t)
Defines a GL column-major matrix from a homogeneous transform.
Definition: htransform.c:351
void Error(const char *s)
General error function.
Definition: error.c:80
#define RIGIDCLL
One of the possible collison detection engines.
Definition: parameters.h:132
unsigned int * vcID
Definition: cd.h:130
#define OFF
One of the possible type of polyhedrons.
Definition: polyhedron.h:59
A mechanism description.
Definition: mechanism.h:51
#define SEGMENTS
One of the possible type of polyhedrons.
Definition: polyhedron.h:100
TpqpCD * pqp
Definition: cd.h:274
boolean simple
Definition: cd.h:107
CBLAS_INLINE void HTransformProduct(THTransform *t1, THTransform *t2, THTransform *t3)
Product of two homogeneous transforms.
Definition: htransform.c:404
#define LINE
One of the possible type of polyhedrons.
Definition: polyhedron.h:90
void HTransformX2Vect(double sy, double sz, double *p1, double *p2, THTransform *t)
Transform a unitary vector along the X axis to a generic vector.
Definition: htransform.c:539
unsigned int * bodyID
Definition: cd.h:146
unsigned int GetObstacleShapeStatus(unsigned int i, Tenvironment *e)
Gets the status (NORMAL, HIDDEN, DECOR) of an obstacle given its identifier.
Definition: environment.c:93
A polyhedron.
Definition: polyhedron.h:124
Error and warning functions.
Tpqp ** model
Definition: cd.h:147
DT_Bool CDCallBackInfo(void *client_data, void *obj1, void *obj2, const DT_CollData *cd)
Callback called whenever a collision is detected.
Definition: cd.c:464
unsigned int np
Definition: cd.h:105
#define FCL
One of the possible collison detection engines.
Definition: parameters.h:96
boolean VcollideTest(Tvcollide *vc)
Test for collision.
Definition: cd_vcollide.cpp:87
Information of each object.
Definition: cd.h:78
void HTransformInverse(THTransform *t, THTransform *ti)
Inverse of a homogeneous transform.
Definition: htransform.c:468
THTransform t1
Definition: cd.h:69
void * rigidCLL
Definition: cd.h:294
boolean ObstacleCanCollide(unsigned int o, unsigned int nl, boolean **checkCollisionsLO)
Identifies obstacles than can collide.
Definition: cd.c:2231
unsigned int id1
Definition: cd.h:62
A collection of obstacles (convex polyhedrons) with their names.
Definition: environment.h:39
void GetOFFInfo(unsigned int *nv, double ***v, unsigned int *nf, unsigned int **nvf, unsigned int ***fv, Tpolyhedron *p)
Gets the OFF information.
Definition: polyhedron.c:1175
DT_ObjectHandle handler
Definition: cd.h:85
Definitions of constants and macros used in several parts of the cuik library.
void DeleteVcollideObject(unsigned int o, Tvcollide *vc)
Deletes a given vcollide object.
unsigned int nc
Definition: cd.h:110
DT_ShapeHandle AddShape2Solid(Tpolyhedron *p)
Adds a shape to the collision detection data.
Definition: cd.c:530
double normal[3]
Definition: cd.h:68
unsigned int * p2
Definition: cd.h:150
#define C_FCL
One of the possible collison detection engines.
Definition: parameters.h:105
void InitSolidCD(boolean parallel, Tmechanism *m, Tenvironment *e, boolean **checkCollisionsLL, boolean **checkCollisionsLO, TsolidCD *s)
Initializes the Solid collision engine.
Definition: cd.c:633
unsigned int id
Definition: cd.h:79
#define VCOLLIDE
One of the possible collison detection engines.
Definition: parameters.h:78
Tpqp * DefinePQPModel(double **v, unsigned int nf, unsigned int *nvf, unsigned int **fv)
Adds a polyhedron to the pqp object.
Definition: cd_pqp.cpp:20
DT_ResponseClass respClass
Definition: cd.h:86
void DeleteCD(TworldCD *cd)
Collision information destructor.
Definition: cd.c:2391
Tvcollide * vc
Definition: cd.h:126
void StoreCollisionInfo(FILE *f, char *fname, unsigned int objectID, Tmechanism *m, TworldCD *cd)
Stores the information collected during last collision check into a file.
Definition: cd.c:2334
boolean CheckCollision(boolean all, THTransform *tl, THTransform *tlPrev, TworldCD *cd)
Determines if there is a collision.
Definition: cd.c:2251
#define SPHERE
One of the possible type of polyhedrons.
Definition: polyhedron.h:70
boolean isLink1
Definition: cd.h:61
DT_Bool CDCallBack(void *client_data, void *obj1, void *obj2, const DT_CollData *cd)
Callback called whenever a collision is detected.
unsigned int GetPolyhedronStatus(Tpolyhedron *p)
Gets the status of a polyhedron (NORMAL, HIDDEN, DECOR).
Definition: polyhedron.c:1170
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
unsigned int * p1
Definition: cd.h:149
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
CBLAS_INLINE void SumVectorScale(unsigned int s, double *v1, double w, double *v2, double *v)
Adds two vectors with a scale.
Definition: basic_algebra.c:86
DT_ShapeHandle shape
Definition: cd.h:84
CBLAS_INLINE void SubtractVector(unsigned int s, double *v1, double *v2)
Substracts a vector from another vector.
unsigned int GetCDEngine(TworldCD *cd)
Determines the collision engine.
Definition: cd.c:2246
void HTransformTx(double tx, THTransform *t)
Constructor.
Definition: htransform.c:106
void DeleteVcollide(Tvcollide *vc)
Deletes a vcollide object.
void MoveVcollideObject(unsigned int o, THTransform *t, Tvcollide *vc)
Moves a given v-collide object.
Definition: cd_vcollide.cpp:78
Information associated with the Vcollide collision detection engine.
Definition: cd.h:125
unsigned int mc
Definition: cd.h:111
void ActivateCollisionsVcollide(unsigned int o1, unsigned int o2, Tvcollide *vc)
Activates the collision between a pair of objects.
Definition: cd_vcollide.cpp:60
void DeleteVcollideCD(TvcollideCD *vc)
Deletes the Vcollide related collision information.
Definition: cd.c:965
void HTransformDelete(THTransform *t)
Destructor.
Definition: htransform.c:833
unsigned int engine
Definition: cd.h:259
boolean CheckCollisionPQP(THTransform *tl, TpqpCD *p)
Determines if there is a collision using the PQP collision engine.
Definition: cd.c:1084
void GetPolyhedronDefiningPoint(unsigned int i, double *point, Tpolyhedron *p)
Gets a point defining a a object.
Definition: polyhedron.c:1190
Headers of the interface with the collision detection engine.
void DeletePQPCD(TpqpCD *p)
Deletes the PQP related collision information.
Definition: cd.c:1117
#define C_BULLET
One of the possible collison detection engines.
Definition: parameters.h:123
DT_SceneHandle scene
Definition: cd.h:103
Tlink * GetMechanismLink(unsigned int i, Tmechanism *m)
Gets a link given its identifier.
Definition: mechanism.c:146
unsigned int * linkID
Definition: cd.h:128
boolean PQPTest(THTransform *t1, Tpqp *m1, THTransform *t2, Tpqp *m2)
Test for collision.
Definition: cd_pqp.cpp:50
void HTransformTy(double ty, THTransform *t)
Constructor.
Definition: htransform.c:117
void InitPQPCD(Tmechanism *m, Tenvironment *e, boolean **checkCollisionsLL, boolean **checkCollisionsLO, TpqpCD *p)
Initializes the PQP collision engine.
Definition: cd.c:983
unsigned int bodyID
Definition: cd.h:81
void HTransformCopy(THTransform *t_dst, THTransform *t_src)
Copy constructor.
Definition: htransform.c:83
unsigned int np
Definition: cd.h:127
#define BULLET
One of the possible collison detection engines.
Definition: parameters.h:114
TsolidObj * object
Definition: cd.h:106
Tpolyhedron * GetObstacleShape(unsigned int i, Tenvironment *e)
Gets the convex polyhedron of an obstacle given its identifier.
Definition: environment.c:82
boolean CheckCollisionVcollide(THTransform *tl, TvcollideCD *vc)
Determines if there is a collision using the VCOLLIDE collision engine.
Definition: cd.c:949
void DeactivateCollisionsVcollide(unsigned int o1, unsigned int o2, Tvcollide *vc)
Deactivates the collisions between a pair of object.
Definition: cd_vcollide.cpp:69
void Tpqp
The PQP object.
Definition: cd_pqp.h:33
void HTransformPrint(FILE *f, THTransform *t)
Prints the a homogeneous transform to a file.
Definition: htransform.c:768
THTransform t2
Definition: cd.h:70
void HTransformIdentity(THTransform *t)
Constructor.
Definition: htransform.c:69
unsigned int np
Definition: cd.h:144
void HTransformRy2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:216
unsigned int nPairs
Definition: cd.h:148
void PrintCollisionInfo(THTransform *tl, Tmechanism *m, TworldCD *cd)
Prints some information collected during last collision check.
Definition: cd.c:2362
unsigned int GetPolyhedronType(Tpolyhedron *p)
Retrives the type of a polyhedron.
Definition: polyhedron.c:1155
THTransform t
Definition: cd.h:87
unsigned int GetMechanismNBodies(Tmechanism *m)
Gets the number of convex sub-parts (or bodies) of a mechanism.
Definition: mechanism.c:35
#define SOLID
One of the possible collison detection engines.
Definition: parameters.h:69
#define DECOR_SHAPE
One of the possible type of shapes.
Definition: polyhedron.h:46
unsigned int GetEnvironmentNObstacles(Tenvironment *e)
Gets the number of obstacles in the environment.
Definition: environment.c:40
void DeletePQPModel(Tpqp *m)
Deletes a given PQP object.
Definition: cd_pqp.cpp:88
THTransform tc
Definition: cd.h:89
boolean HTransformIsIdentity(THTransform *t)
Identify the identity matrix.
Definition: htransform.c:91