Biomechanical Joint Model
 Author: Anderson Maciel

collide.cpp

Go to the documentation of this file.
00001 
00002 /*************************************************************************\
00003 
00004   Copyright 1995 The University of North Carolina at Chapel Hill.
00005   All Rights Reserved.
00006 
00007   Permission to use, copy, modify and distribute this software and its
00008   documentation for educational, research and non-profit purposes, without
00009    fee, and without a written agreement is hereby granted, provided that the
00010   above copyright notice and the following three paragraphs appear in all
00011   copies.
00012 
00013   IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL BE
00014   LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
00015   CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE
00016   USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
00017   OF NORTH CAROLINA HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
00018   DAMAGES.
00019 
00020   THE UNIVERSITY OF NORTH CAROLINA SPECIFICALLY DISCLAIM ANY
00021   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00022   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
00023   PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
00024   NORTH CAROLINA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
00025   UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00026 
00027   The authors may be contacted via:
00028 
00029   US Mail:             S. Gottschalk
00030                        Department of Computer Science
00031                        Sitterson Hall, CB #3175
00032                        University of N. Carolina
00033                        Chapel Hill, NC 27599-3175
00034 
00035   Phone:               (919)962-1749
00036 
00037   EMail:              {gottscha}@cs.unc.edu
00038 
00039 
00040 \**************************************************************************/
00041 
00042 
00043 #include "RAPID_version.H"
00044 
00045 static char rapidtag_data[] = "RAPIDTAG  file: "__FILE__"    date: "__DATE__"    time: "__TIME__;
00046 
00047 // to silence the compiler's complaints about unreferenced identifiers.
00048 static void r1(char *f){  r1(f);  r1(rapidtag_data);  r1(rapid_version);}
00049 
00050 extern int RAPID_initialized;
00051 void RAPID_initialize();
00052 
00053 #include "RAPID.H"
00054 #include "matvec.H"
00055 #include "overlap.H"
00056 #include "obb.H"
00057 
00058 double RAPID_mR[3][3];
00059 double RAPID_mT[3];
00060 double RAPID_ms;
00061 
00062 
00063 int RAPID_first_contact;
00064 
00065 int RAPID_num_box_tests;
00066 int RAPID_num_tri_tests;
00067 int RAPID_num_contacts;
00068 
00069 int RAPID_num_cols_alloced = 0;
00070 collision_pair *RAPID_contact = 0;
00071 
00072 int add_collision(int id1, int id2);
00073 
00074 int
00075 tri_contact(box *b1, box *b2)
00076 {
00077   // assume just one triangle in each box.
00078 
00079   // the vertices of the tri in b2 is in model1 C.S.  The vertices of
00080   // the other triangle is in model2 CS.  Use RAPID_mR, RAPID_mT, and
00081   // RAPID_ms to transform into model2 CS.
00082 
00083   double i1[3];
00084   double i2[3];
00085   double i3[3];
00086   int rc;  // return code
00087   
00088   sMxVpV(i1, RAPID_ms, RAPID_mR, b1->trp->p1, RAPID_mT);
00089   sMxVpV(i2, RAPID_ms, RAPID_mR, b1->trp->p2, RAPID_mT);
00090   sMxVpV(i3, RAPID_ms, RAPID_mR, b1->trp->p3, RAPID_mT);
00091 
00092   RAPID_num_tri_tests++;
00093 
00094   int f = tri_contact(i1, i2, i3, b2->trp->p1,b2->trp->p2, b2->trp->p3);
00095 
00096   if (f) 
00097     {
00098       // add_collision may be unable to allocate enough memory,
00099       // so be prepared to pass along an OUT_OF_MEMORY return code.
00100       if ((rc = add_collision(b1->trp->id, b2->trp->id)) != RAPID_OK)
00101         return rc;
00102     }
00103   
00104   return RAPID_OK;
00105 }
00106 
00107 
00108 
00109 int 
00110 collide_recursive(box *b1, box *b2, double R[3][3], double T[3], double s)
00111 {
00112   double d[3]; // temp storage for scaled dimensions of box b2.
00113   int rc;      // return codes
00114   
00115   if (1)
00116     {
00117 #if TRACE1
00118       printf("Next collision: b1, b2, R, T, s\n");
00119       printf("b1=%x, b2=%x\n", b1, b2);
00120       Mprint(R);
00121       Vprint(T);
00122       printf("%lf\n", s);
00123 #endif
00124       
00125       if (RAPID_first_contact && (RAPID_num_contacts > 0)) return RAPID_OK;
00126 
00127       // test top level
00128 
00129       RAPID_num_box_tests++;
00130   
00131       int f1;
00132   
00133       d[0] = s * b2->d[0];
00134       d[1] = s * b2->d[1];
00135       d[2] = s * b2->d[2];
00136       f1 = obb_disjoint(R, T, b1->d, d);
00137 
00138 #if TRACE1
00139       if (f1 != 0)
00140         {
00141           printf("BOX TEST %d DISJOINT! (code %d)\n", RAPID_num_box_tests, f1);
00142         }
00143       else
00144         {
00145           printf("BOX TEST %d OVERLAP! (code %d)\n", RAPID_num_box_tests, f1);
00146         }
00147       
00148 #endif
00149 
00150       if (f1 != 0) 
00151         {
00152           return RAPID_OK;  // stop processing this test, go to top of loop
00153         }
00154 
00155       // contact between boxes
00156       if (b1->leaf() && b2->leaf()) 
00157         {
00158           // it is a leaf pair - compare the polygons therein
00159           // tri_contact uses the model-to-model transforms stored in
00160           // RAPID_mR, RAPID_mT, RAPID_ms.
00161 
00162           // this will pass along any OUT_OF_MEMORY return codes which
00163           // may be generated.
00164           return tri_contact(b1, b2);
00165         }
00166 
00167       double U[3];
00168 
00169       double cR[3][3], cT[3], cs;
00170       
00171       // Currently, the transform from model 2 to model 1 space is
00172       // given by [B T s], where y = [B T s].x = s.B.x + T.
00173 
00174       if (b2->leaf() || (!b1->leaf() && (b1->size() > b2->size())))
00175         {
00176           // here we descend to children of b1.  The transform from
00177           // a child of b1 to b1 is stored in [b1->N->pR,b1->N->pT],
00178           // but we will denote it [B1 T1 1] for short.  Notice that
00179           // children boxes always have same scaling as parent, so s=1
00180           // for such nested transforms.
00181 
00182           // Here, we compute [B1 T1 1]'[B T s] = [B1'B B1'(T-T1) s]
00183           // for each child, and store the transform into the collision
00184           // test queue.
00185 
00186           MTxM(cR, b1->N->pR, R); 
00187           VmV(U, T, b1->N->pT); MTxV(cT, b1->N->pR, U);
00188           cs = s;
00189 
00190           if ((rc = collide_recursive(b1->N, b2, cR, cT, cs)) != RAPID_OK)
00191             return rc;
00192           
00193           MTxM(cR, b1->P->pR, R); 
00194           VmV(U, T, b1->P->pT); MTxV(cT, b1->P->pR, U);
00195           cs = s;
00196 
00197           if ((rc = collide_recursive(b1->P, b2, cR, cT, cs)) != RAPID_OK)
00198             return rc;
00199           
00200           return RAPID_OK;
00201         }
00202       else 
00203         {
00204           // here we descend to the children of b2.  See comments for
00205           // other 'if' clause for explanation.
00206 
00207           MxM(cR, R, b2->N->pR); sMxVpV(cT, s, R, b2->N->pT, T);
00208           cs = s;
00209           
00210           if ((rc = collide_recursive(b1, b2->N, cR, cT, cs)) != RAPID_OK)
00211             return rc;
00212           
00213           MxM(cR, R, b2->P->pR); sMxVpV(cT, s, R, b2->P->pT, T);
00214           cs = s;
00215 
00216           if ((rc = collide_recursive(b1, b2->P, cR, cT, cs)) != RAPID_OK)
00217             return rc;
00218           
00219           return RAPID_OK; 
00220         }
00221   
00222     }
00223   
00224   return RAPID_OK;
00225 } 
00226   
00227 int 
00228 RAPID_Collide(double R1[3][3], double T1[3], RAPID_model *RAPID_model1,
00229               double R2[3][3], double T2[3], RAPID_model *RAPID_model2,
00230               int flag)
00231 {
00232   return RAPID_Collide(R1, T1, 1.0, RAPID_model1, R2, T2, 1.0, RAPID_model2, flag);
00233 }
00234 
00235 
00236 int 
00237 RAPID_Collide(double R1[3][3], double T1[3], double s1, RAPID_model *RAPID_model1,
00238               double R2[3][3], double T2[3], double s2, RAPID_model *RAPID_model2,
00239               int flag)
00240 {
00241   if (!RAPID_initialized) RAPID_initialize();
00242 
00243   if (RAPID_model1->build_state != RAPID_BUILD_STATE_PROCESSED)
00244     return RAPID_ERR_UNPROCESSED_MODEL;
00245 
00246   if (RAPID_model2->build_state != RAPID_BUILD_STATE_PROCESSED)
00247     return RAPID_ERR_UNPROCESSED_MODEL;
00248 
00249   box *b1 = RAPID_model1->b;
00250   box *b2 = RAPID_model2->b;
00251   
00252   RAPID_first_contact = 0; 
00253   if (flag == RAPID_FIRST_CONTACT) RAPID_first_contact = 1;
00254   
00255   double tR1[3][3], tR2[3][3], R[3][3];
00256   double tT1[3], tT2[3], T[3], U[3];
00257   double s;
00258   
00259   // [R1,T1,s1] and [R2,T2,s2] are how the two triangle sets
00260   // (i.e. models) are positioned in world space.  [tR1,tT1,s1] and
00261   // [tR2,tT2,s2] are how the top level boxes are positioned in world
00262   // space
00263   
00264   MxM(tR1, R1, b1->pR);                  // tR1 = R1 * b1->pR;
00265   sMxVpV(tT1, s1, R1, b1->pT, T1);       // tT1 = s1 * R1 * b1->pT + T1;
00266   MxM(tR2, R2, b2->pR);                  // tR2 = R2 * b2->pR;
00267   sMxVpV(tT2, s2, R2, b2->pT, T2);       // tT2 = s2 * R2 * b2->pT + T2;
00268   
00269   // (R,T,s) is the placement of b2's top level box within
00270   // the coordinate system of b1's top level box.
00271 
00272   MTxM(R, tR1, tR2);                            // R = tR1.T()*tR2;
00273   VmV(U, tT2, tT1);  sMTxV(T, 1.0/s1, tR1, U);  // T = tR1.T()*(tT2-tT1)/s1;
00274   
00275   s = s2/s1;
00276 
00277   // To transform tri's from model1's CS to model2's CS use this:
00278   //    x2 = ms . mR . x1 + mT
00279 
00280   {
00281     MTxM(RAPID_mR, R2, R1);
00282     VmV(U, T1, T2);  sMTxV(RAPID_mT, 1.0/s2, R2, U);
00283     RAPID_ms = s1/s2;
00284   }
00285   
00286 
00287   // reset the report fields
00288   RAPID_num_box_tests = 0;
00289   RAPID_num_tri_tests = 0;
00290   RAPID_num_contacts = 0;
00291 
00292   // make the call
00293   return collide_recursive(b1, b2, R, T, s);
00294 }
00295 
00296 int
00297 add_collision(int id1, int id2)
00298 {
00299   if (!RAPID_contact)
00300     {
00301       RAPID_contact = new collision_pair[10];
00302       if (!RAPID_contact) 
00303         {
00304           return RAPID_ERR_COLLIDE_OUT_OF_MEMORY;
00305         }
00306       RAPID_num_cols_alloced = 10;
00307       RAPID_num_contacts = 0;
00308     }
00309   
00310   if (RAPID_num_contacts == RAPID_num_cols_alloced)
00311     {
00312       collision_pair *t = new collision_pair[RAPID_num_cols_alloced*2];
00313       if (!t)
00314         {
00315           return RAPID_ERR_COLLIDE_OUT_OF_MEMORY;
00316         }
00317       RAPID_num_cols_alloced *= 2;
00318       
00319       for(int i=0; i<RAPID_num_contacts; i++) t[i] = RAPID_contact[i];
00320       delete [] RAPID_contact;
00321       RAPID_contact = t;
00322     }
00323   
00324   RAPID_contact[RAPID_num_contacts].id1 = id1;
00325   RAPID_contact[RAPID_num_contacts].id2 = id2;
00326   RAPID_num_contacts++;
00327 
00328   return RAPID_OK;
00329 }

Generated on Thu Dec 1 10:13:32 2005 for COME - Biomechanical Joint Model by  doxygen 1.4.5