00001
00002
00003
00004
00005
00006
00007
00008
00014 #include "colinfo.h"
00015
00016
00017
00018 int ColModel::LineIntersection(PQP_CollideResult& cres, const fVec3& p1, const fVec3& p2)
00019 {
00020 static PQP_REAL T[3], RR[3][3];
00021 static PQP_REAL P1[3], P2[3];
00022 fVec3 pos(joint->abs_pos);
00023 fMat33 att(joint->abs_att);
00024 T[0] = pos(0);
00025 T[1] = pos(1);
00026 T[2] = pos(2);
00027 RR[0][0] = att(0,0);
00028 RR[0][1] = att(0,1);
00029 RR[0][2] = att(0,2);
00030 RR[1][0] = att(1,0);
00031 RR[1][1] = att(1,1);
00032 RR[1][2] = att(1,2);
00033 RR[2][0] = att(2,0);
00034 RR[2][1] = att(2,1);
00035 RR[2][2] = att(2,2);
00036 P1[0] = p1(0);
00037 P1[1] = p1(1);
00038 P1[2] = p1(2);
00039 P2[0] = p2(0);
00040 P2[1] = p2(1);
00041 P2[2] = p2(2);
00042
00043 return PQP_TriLineIntersect(&cres, RR, T, model, P1, P2);
00044 }
00045
00046 int ColPair::Collide(PQP_CollideResult& cres)
00047 {
00048 static PQP_REAL R1[3][3];
00049 static PQP_REAL T1[3];
00050 static PQP_REAL R2[3][3];
00051 static PQP_REAL T2[3];
00052 fVec3 p1(models[0]->joint->abs_pos);
00053 fMat33 r1(models[0]->joint->abs_att);
00054 fVec3 p2(models[1]->joint->abs_pos);
00055 fMat33 r2(models[1]->joint->abs_att);
00056
00057 R1[0][0] = r1(0,0);
00058 R1[0][1] = r1(0,1);
00059 R1[0][2] = r1(0,2);
00060 R1[1][0] = r1(1,0);
00061 R1[1][1] = r1(1,1);
00062 R1[1][2] = r1(1,2);
00063 R1[2][0] = r1(2,0);
00064 R1[2][1] = r1(2,1);
00065 R1[2][2] = r1(2,2);
00066 T1[0] = p1(0);
00067 T1[1] = p1(1);
00068 T1[2] = p1(2);
00069
00070 R2[0][0] = r2(0,0);
00071 R2[0][1] = r2(0,1);
00072 R2[0][2] = r2(0,2);
00073 R2[1][0] = r2(1,0);
00074 R2[1][1] = r2(1,1);
00075 R2[1][2] = r2(1,2);
00076 R2[2][0] = r2(2,0);
00077 R2[2][1] = r2(2,1);
00078 R2[2][2] = r2(2,2);
00079 T2[0] = p2(0);
00080 T2[1] = p2(1);
00081 T2[2] = p2(2);
00082
00083 return PQP_Collide(&cres,
00084 R1, T1, models[0]->model,
00085 R2, T2, models[1]->model);
00086 }
00087
00088 int ColPair::Distance(PQP_DistanceResult& dres,
00089 PQP_REAL rel_error, PQP_REAL abs_error,
00090 int qsize)
00091 {
00092 static PQP_REAL R1[3][3];
00093 static PQP_REAL T1[3];
00094 static PQP_REAL R2[3][3];
00095 static PQP_REAL T2[3];
00096 fVec3 p1(models[0]->joint->abs_pos);
00097 fMat33 r1(models[0]->joint->abs_att);
00098 fVec3 p2(models[1]->joint->abs_pos);
00099 fMat33 r2(models[1]->joint->abs_att);
00100
00101 R1[0][0] = r1(0,0);
00102 R1[0][1] = r1(0,1);
00103 R1[0][2] = r1(0,2);
00104 R1[1][0] = r1(1,0);
00105 R1[1][1] = r1(1,1);
00106 R1[1][2] = r1(1,2);
00107 R1[2][0] = r1(2,0);
00108 R1[2][1] = r1(2,1);
00109 R1[2][2] = r1(2,2);
00110 T1[0] = p1(0);
00111 T1[1] = p1(1);
00112 T1[2] = p1(2);
00113
00114 R2[0][0] = r2(0,0);
00115 R2[0][1] = r2(0,1);
00116 R2[0][2] = r2(0,2);
00117 R2[1][0] = r2(1,0);
00118 R2[1][1] = r2(1,1);
00119 R2[1][2] = r2(1,2);
00120 R2[2][0] = r2(2,0);
00121 R2[2][1] = r2(2,1);
00122 R2[2][2] = r2(2,2);
00123 T2[0] = p2(0);
00124 T2[1] = p2(1);
00125 T2[2] = p2(2);
00126
00127 return PQP_Distance(&dres,
00128 R1, T1, models[0]->model,
00129 R2, T2, models[1]->model,
00130 rel_error, abs_error,
00131 qsize);
00132 }
00133
00134 int ColPair::Tolerance(PQP_ToleranceResult& tres,
00135 PQP_REAL tolerance)
00136 {
00137 static PQP_REAL R1[3][3];
00138 static PQP_REAL T1[3];
00139 static PQP_REAL R2[3][3];
00140 static PQP_REAL T2[3];
00141 fVec3 p1(models[0]->joint->abs_pos);
00142 fMat33 r1(models[0]->joint->abs_att);
00143 fVec3 p2(models[1]->joint->abs_pos);
00144 fMat33 r2(models[1]->joint->abs_att);
00145
00146 R1[0][0] = r1(0,0);
00147 R1[0][1] = r1(0,1);
00148 R1[0][2] = r1(0,2);
00149 R1[1][0] = r1(1,0);
00150 R1[1][1] = r1(1,1);
00151 R1[1][2] = r1(1,2);
00152 R1[2][0] = r1(2,0);
00153 R1[2][1] = r1(2,1);
00154 R1[2][2] = r1(2,2);
00155 T1[0] = p1(0);
00156 T1[1] = p1(1);
00157 T1[2] = p1(2);
00158
00159 R2[0][0] = r2(0,0);
00160 R2[0][1] = r2(0,1);
00161 R2[0][2] = r2(0,2);
00162 R2[1][0] = r2(1,0);
00163 R2[1][1] = r2(1,1);
00164 R2[1][2] = r2(1,2);
00165 R2[2][0] = r2(2,0);
00166 R2[2][1] = r2(2,1);
00167 R2[2][2] = r2(2,2);
00168 T2[0] = p2(0);
00169 T2[1] = p2(1);
00170 T2[2] = p2(2);
00171
00172 return PQP_Tolerance(&tres,
00173 R1, T1, models[0]->model,
00174 R2, T2, models[1]->model,
00175 tolerance);
00176 }
00177
00181 static void apply_transform(TransformNode* tnode, fVec3& pos, int scale_only = false)
00182 {
00183 static float fscale[3];
00184
00185 tnode->getScale(fscale);
00186 pos(0) *= fscale[0];
00187 pos(1) *= fscale[1];
00188 pos(2) *= fscale[2];
00189
00190 if(!scale_only)
00191 {
00192 static fVec3 trans, tmp;
00193 static fMat33 att;
00194 static float fpos[3];
00195 static float frot[4];
00196 tnode->getTranslation(fpos);
00197 tnode->getRotation(frot);
00198 trans(0) = fpos[0];
00199 trans(1) = fpos[1];
00200 trans(2) = fpos[2];
00201 att.rot2mat(fVec3(frot[0], frot[1], frot[2]), frot[3]);
00202 tmp.mul(att, pos);
00203 pos.add(trans, tmp);
00204 }
00205 }
00206
00207 int ColModel::add_triangles(TransformNode* tnode)
00208 {
00209 if(!tnode) return 0;
00210
00211 n_triangle = 0;
00212 add_triangles(tnode, (Node*)tnode);
00213 if(n_triangle > 0)
00214 {
00215
00216 cerr << "add_triangles(" << tnode->getName() << ")" << endl;
00217
00218 model->BeginModel();
00219 create_pqp_model();
00220 model->EndModel();
00221
00222 cerr << " total " << n_triangle << " triangles" << endl;
00223
00224 }
00225 return 0;
00226 }
00227
00228 int ColModel::add_triangles(TransformNode* tnode, Node* cur)
00229 {
00230 if(!cur) return -1;
00231 add_triangles_sub(tnode, cur->getChildNodes());
00232 return 0;
00233 }
00234
00235 int ColModel::add_triangles_sub(TransformNode* tnode, Node* cur)
00236 {
00237 if(!cur) return 0;
00238
00239 if(cur->isIndexedFaceSetNode())
00240 add_triangles_face(tnode, (IndexedFaceSetNode*)cur);
00241 else
00242 {
00243 add_triangles_sub(tnode, cur->next());
00244 add_triangles_sub(tnode, cur->getChildNodes());
00245 }
00246 return 0;
00247 }
00248
00249 int ColModel::add_triangles_face(TransformNode* tnode, IndexedFaceSetNode* inode)
00250 {
00251 CoordinateNode* cnode = inode->getCoordinateNodes();
00252 if(!cnode) return -1;
00253 int n_my_vertex = cnode->getNPoints();
00254 int n_index = inode->getNCoordIndexes();
00255 if(n_my_vertex == 0 || n_index == 0) return 0;
00256 int i;
00257 int vertex_id_base = n_vertex;
00258 n_vertex += n_my_vertex;
00259
00260 #if 1
00261 fVec3* tmp_vertices = vertices;
00262 vertices = new fVec3 [n_vertex];
00263 if(tmp_vertices)
00264 {
00265 for(i=0; i<vertex_id_base; i++)
00266 vertices[i].set(tmp_vertices[i]);
00267 delete[] tmp_vertices;
00268 }
00269 #else
00270 fVec3* tmp_vertices = 0;
00271 if(vertices)
00272 {
00273 tmp_vertices = new fVec3 [vertex_id_base];
00274 for(i=0; i<vertex_id_base; i++)
00275 tmp_vertices[i].set(vertices[i]);
00276 delete[] vertices;
00277 }
00278 vertices = new fVec3 [n_vertex];
00279 for(i=0; i<vertex_id_base; i++)
00280 vertices[i].set(tmp_vertices[i]);
00281 if(tmp_vertices) delete[] tmp_vertices;
00282 #endif
00283 float fp[3];
00284 for(i=0; i<n_my_vertex; i++)
00285 {
00286 cnode->getPoint(i, fp);
00287 vertices[i+vertex_id_base](0) = fp[0];
00288 vertices[i+vertex_id_base](1) = fp[1];
00289 vertices[i+vertex_id_base](2) = fp[2];
00290 apply_all_transforms(tnode, (Node*)cnode, vertices[i+vertex_id_base]);
00291 }
00292
00293 int ccw = inode->getCCW();
00294 for(i=0; i<n_index; i++)
00295 {
00296 int c1, c2, c3;
00297 c1 = inode->getCoordIndex(i);
00298 i++;
00299 while( (c2 = inode->getCoordIndex(i)) != -1 &&
00300 (c3 = inode->getCoordIndex(i+1)) != -1 )
00301 {
00302 TriangleInfo* ti = 0;
00303 if(ccw) ti = new TriangleInfo(c1+vertex_id_base, c2+vertex_id_base, c3+vertex_id_base);
00304 else ti = new TriangleInfo(c1+vertex_id_base, c3+vertex_id_base, c2+vertex_id_base);
00305 triangles.append(ti);
00306 n_triangle++;
00307 i++;
00308 }
00309 i += 1;
00310 }
00311 return 0;
00312 }
00313
00314 void ColModel::apply_all_transforms(TransformNode* tnode, Node* cur, fVec3& pos)
00315 {
00316 Node* node;
00317 int scale_only = false;
00318 for(node=cur; node; node=node->getParentNode())
00319 {
00320 if(node->isTransformNode())
00321 {
00322
00323 if(node == tnode)
00324 scale_only = true;
00325 apply_transform((TransformNode*)node, pos, scale_only);
00326 }
00327 }
00328 }
00329
00330 int ColModel::create_pqp_model()
00331 {
00332 PQP_REAL p1[3], p2[3], p3[3];
00333 PQP_REAL q1[3], q2[3], q3[3];
00334 tListElement<TriangleInfo>* ti;
00335 for(ti=triangles.first(); ti; ti=ti->next())
00336 {
00337 TriangleInfo* tri = ti->body();
00338 tri->neighbor_vertex[0] = -1;
00339 tri->neighbor_vertex[1] = -1;
00340 tri->neighbor_vertex[2] = -1;
00341 tri->neighbor_tri[0] = -1;
00342 tri->neighbor_tri[1] = -1;
00343 tri->neighbor_tri[2] = -1;
00344 int c1 = tri->index[0];
00345 int c2 = tri->index[1];
00346 int c3 = tri->index[2];
00347 tListElement<TriangleInfo>* a;
00348 int vert;
00349 for(a=triangles.first(); a; a=a->next())
00350 {
00351 if(a != ti)
00352 {
00353 if((vert = a->body()->have_edge(c1, c2)) >= 0)
00354 {
00355 tri->neighbor_vertex[0] = vert;
00356 tri->neighbor_tri[0] = a->id();
00357 }
00358 else if((vert = a->body()->have_edge(c2, c3)) >= 0)
00359 {
00360 tri->neighbor_vertex[1] = vert;
00361 tri->neighbor_tri[1] = a->id();
00362 }
00363 else if((vert = a->body()->have_edge(c3, c1)) >= 0)
00364 {
00365 tri->neighbor_vertex[2] = vert;
00366 tri->neighbor_tri[2] = a->id();
00367 }
00368 }
00369 if(tri->neighbor_vertex[0] >= 0 &&
00370 tri->neighbor_vertex[1] >= 0 &&
00371 tri->neighbor_vertex[2] >= 0)
00372 break;
00373 }
00374 p1[0] = (PQP_REAL)vertices[c1](0);
00375 p1[1] = (PQP_REAL)vertices[c1](1);
00376 p1[2] = (PQP_REAL)vertices[c1](2);
00377 p2[0] = (PQP_REAL)vertices[c2](0);
00378 p2[1] = (PQP_REAL)vertices[c2](1);
00379 p2[2] = (PQP_REAL)vertices[c2](2);
00380 p3[0] = (PQP_REAL)vertices[c3](0);
00381 p3[1] = (PQP_REAL)vertices[c3](1);
00382 p3[2] = (PQP_REAL)vertices[c3](2);
00383 if(tri->neighbor_vertex[0] >= 0)
00384 {
00385 q1[0] = (PQP_REAL)vertices[tri->neighbor_vertex[0]](0);
00386 q1[1] = (PQP_REAL)vertices[tri->neighbor_vertex[0]](1);
00387 q1[2] = (PQP_REAL)vertices[tri->neighbor_vertex[0]](2);
00388 }
00389 if(tri->neighbor_vertex[1] >= 0)
00390 {
00391 q2[0] = (PQP_REAL)vertices[tri->neighbor_vertex[1]](0);
00392 q2[1] = (PQP_REAL)vertices[tri->neighbor_vertex[1]](1);
00393 q2[2] = (PQP_REAL)vertices[tri->neighbor_vertex[1]](2);
00394 }
00395 if(tri->neighbor_vertex[2] >= 0)
00396 {
00397 q3[0] = (PQP_REAL)vertices[tri->neighbor_vertex[2]](0);
00398 q3[1] = (PQP_REAL)vertices[tri->neighbor_vertex[2]](1);
00399 q3[2] = (PQP_REAL)vertices[tri->neighbor_vertex[2]](2);
00400 }
00401 int vertex_id[3] = { c1, c2, c3 };
00402 model->AddTri(p1, p2, p3, q1, q2, q3, vertex_id, tri->neighbor_tri, ti->id());
00403 #ifdef VERBOSE
00404 cerr << "triangle " << ti->id() << ": [" << c1 << ", " << c2 << ", " << c3 << "], neighbors = [" << tri->neighbor_tri[0] << ", " << tri->neighbor_tri[1] << ", " << tri->neighbor_tri[2] << "]" << endl;
00405 cerr << vertices[c1] << endl;
00406 cerr << vertices[c2] << endl;
00407 cerr << vertices[c3] << endl;
00408 #endif
00409 }
00410 return 0;
00411 }
00412
00416 void ColInfo::add_pair(ColPair* p)
00417 {
00418 if(n_pairs == n_allocated_pairs) allocate_pair(n_allocated_pairs + 10);
00419 pairs[n_pairs] = p;
00420 n_pairs++;
00421 }
00422
00423 void ColInfo::add_model(ColModel* m)
00424 {
00425 if(n_models == n_allocated_models) allocate_model(n_allocated_models + 10);
00426 models[n_models] = m;
00427 n_models++;
00428 n_total_tri += m->n_triangle;
00429 }
00430
00431 int ColInfo::AddCharPairs(const char* char1, const char* char2, Chain* chain, SceneGraph* sg)
00432 {
00433 cerr << "AddCharPairs(" << char1 << ", " << char2 << ")" << endl;
00434 add_char_pairs(chain->Root(), char1, char2, chain, sg);
00435 return n_pairs;
00436 }
00437
00438 int ColInfo::add_char_pairs(Joint* cur, const char* char1, const char* char2, Chain* chain, SceneGraph* sg)
00439 {
00440 if(!cur) return 0;
00441 char* charname;
00442 if((charname = cur->CharName()) && !strcmp(charname, char1))
00443 {
00444 add_char_pairs(cur, chain->Root(), char2, sg);
00445 }
00446 add_char_pairs(cur->brother, char1, char2, chain, sg);
00447 add_char_pairs(cur->child, char1, char2, chain, sg);
00448 return 0;
00449 }
00450
00451 int ColInfo::add_char_pairs(Joint* j1, Joint* j2, const char* char2, SceneGraph* sg)
00452 {
00453 if(!j2) return 0;
00454 char* charname;
00455 if((charname = j2->CharName()) && !strcmp(charname, char2) && j1 != j2)
00456 {
00457 add_joint_pair(j1, j2, sg);
00458 }
00459 add_char_pairs(j1, j2->brother, char2, sg);
00460 add_char_pairs(j1, j2->child, char2, sg);
00461 return 0;
00462 }
00463
00464 int ColInfo::AddJointPair(const char* joint1, const char* joint2, Chain* chain, SceneGraph* sg)
00465 {
00466 Joint* j1, *j2;
00467 j1 = chain->FindJoint(joint1);
00468 j2 = chain->FindJoint(joint2);
00469 if(!j1 || !j2) return 0;
00470 if(j1 == j2) return 0;
00471 add_joint_pair(j1, j2, sg);
00472 return n_pairs;
00473 }
00474
00475 int ColInfo::add_joint_pair(Joint* j1, Joint* j2, SceneGraph* sg)
00476 {
00477 if(Pair(j1, j2)) return 0;
00478 ColModel* m1, *m2;
00479 m1 = Model(j1);
00480 if(!m1)
00481 {
00482 m1 = new ColModel(j1, sg);
00483 add_model(m1);
00484 }
00485 m2 = Model(j2);
00486 if(!m2)
00487 {
00488 m2 = new ColModel(j2, sg);
00489 add_model(m2);
00490 }
00491 if(m1->n_triangle == 0 || m2->n_triangle == 0) return -1;
00492 if( (j1->parent == j2 && j1->n_dof == 0) || (j2->parent == j1 && j2->n_dof == 0) )
00493 return 0;
00494 cerr << "add joint pair: " << j1->name << ", " << j2->name << endl;
00495 ColPair* p = new ColPair(m1, m2);
00496 add_pair(p);
00497 return 0;
00498 }
00499
00500 ColModel* ColInfo::AddModel(Joint* jref, SceneGraph* sg)
00501 {
00502 ColModel* ret = Model(jref);
00503 if(!ret)
00504 {
00505 ret = new ColModel(jref, sg);
00506 if(ret->n_triangle > 0)
00507 add_model(ret);
00508 else
00509 {
00510 delete ret;
00511 ret = 0;
00512 }
00513 }
00514 return ret;
00515 }