00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00032
00033 #include "profiling.h"
00034
00035 PROF_DECLARE(COLLISION_RECURSION);
00036 PROF_DECLARE(CONTACT_LEAF);
00037 PROF_DECLARE(CONTACT_QUICK);
00038 PROF_DECLARE(COLLISION_LEAF);
00039 PROF_DECLARE(COLLISION_QUICK);
00040 PROF_DECLARE(DISTANCE_LEAF);
00041 PROF_DECLARE(DISTANCE_QUICK);
00042
00043 namespace Collision {
00044
00046
00048
00050 void CollisionCallback::leafTest(const Leaf *l1, const Leaf *l2)
00051 {
00052 PROF_TIMER_FUNC(COLLISION_LEAF);
00053 assert(l1); assert(l2);
00054 const std::list<Triangle>* list1 = l1->getTriangles();
00055 const std::list<Triangle>* list2 = l2->getTriangles();
00056 std::list<Triangle>::const_iterator it1, it2;
00057 for (it1=list1->begin(); it1!=list1->end() && !mCollision; it1++) {
00058 Triangle t1(*it1);
00059
00060 t1.applyTransform(mTran1To2);
00061 for (it2 = list2->begin(); it2!=list2->end() && !mCollision; it2++) {
00062 mNumTriangleTests++;
00063 if ( triangleIntersection(t1, *it2) ) {
00064 mCollision = true;
00065 }
00066 }
00067 }
00068 mNumLeafTests++;
00069 }
00070
00072 double CollisionCallback::quickTest(const Node *n1, const Node *n2)
00073 {
00074 PROF_TIMER_FUNC(COLLISION_QUICK);
00075 assert(n1); assert(n2);
00076 mNumQuickTests++;
00077 if(bboxOverlap(n1->getBox(), n2->getBox(), mTran2To1 )) {
00078 return -1.0;
00079 }
00080 return 1.0;
00081 }
00082
00084
00086
00088 double ContactCallback::quickTest(const Node *n1, const Node *n2)
00089 {
00090 PROF_TIMER_FUNC(CONTACT_QUICK);
00091 assert(n1); assert(n2);
00092 mNumQuickTests++;
00093 return bboxDistanceSq(n1->getBox(), n2->getBox(), mTran2To1);
00094 }
00095
00097 void ContactCallback::leafTest(const Leaf *l1, const Leaf *l2)
00098 {
00099 PROF_TIMER_FUNC(CONTACT_LEAF);
00100 assert(l1); assert(l2);
00101 const std::list<Triangle>* list1 = l1->getTriangles();
00102 const std::list<Triangle>* list2 = l2->getTriangles();
00103 std::list<Triangle>::const_iterator it1, it2;
00104 for (it1=list1->begin(); it1!=list1->end(); it1++) {
00105 Triangle t1(*it1);
00106
00107 t1.applyTransform(mTran1To2);
00108 for (it2 = list2->begin(); it2!=list2->end(); it2++) {
00109 mNumTriangleTests++;
00110
00111
00112
00113
00114
00115 std::vector< std::pair<position,position> > contactPoints;
00116 int numContacts = triangleTriangleContact(t1, *it2, mThreshold*mThreshold,
00117 &contactPoints);
00118 if (numContacts < 0) {
00119 DBGA("Collision found when looking for contacts");
00120 }
00121 std::vector< std::pair<position,position> >::iterator it;
00122 for(it=contactPoints.begin(); it!=contactPoints.end(); it++) {
00123 position p1 = (*it).first;
00124 position p2 = (*it).second;
00125
00126 vec3 n1 = normalise(p1 - p2);
00127 vec3 n2 = normalise(p2 - p1);
00128
00129 p1 = p1 * mTran2To1;
00130 n1 = n1 * mTran2To1;
00131
00132 mReport.push_back( ContactData( p1, p2, n1, n2, (p1-p2)%(p1-p2) ) );
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 }
00160 }
00161 mNumLeafTests++;
00162 }
00163
00165
00167
00168 double DistanceCallback::quickTest(const Node *n1, const Node *n2)
00169 {
00170 PROF_TIMER_FUNC(DISTANCE_QUICK);
00171 assert(n1); assert(n2);
00172 mNumQuickTests++;
00173 return bboxDistanceSq(n1->getBox(), n2->getBox(), mTran2To1);
00174 }
00175
00176 void DistanceCallback::leafTest(const Leaf *l1, const Leaf *l2)
00177 {
00178 PROF_TIMER_FUNC(DISTANCE_LEAF);
00179 mNumLeafTests++;
00180 assert(l1); assert(l2);
00181 const std::list<Triangle>* list1 = l1->getTriangles();
00182 std::list<Triangle>::const_iterator it1, it2;
00183 for (it1=list1->begin(); it1!=list1->end() && mMinDistSq >= 0.0; it1++) {
00184 Triangle t1(*it1);
00185 t1.applyTransform(mTran1To2);
00186
00187 const std::list<Triangle>* list2 = l2->getTriangles();
00188 for (it2 = list2->begin(); it2!=list2->end() && mMinDistSq >= 0.0; it2++) {
00189 mNumTriangleTests++;
00190 position p1,p2;
00191
00192 double distSq = triangleTriangleDistanceSq(t1, *it2, p1, p2);
00193 if (distSq < mMinDistSq) {
00194 p1 = p1 * mTran2To1;
00195 if (distSq >= 0.0) {
00196 mP1 = p1; mP2 = p2;
00197 } else {
00198 mP1 = mP2 = position(0,0,0);
00199 }
00200 mMinDistSq = distSq;
00201 }
00202 }
00203 }
00204 }
00205
00207
00209
00210 void
00211 ClosestPtCallback::leafTest(const Leaf *l1, const Leaf *l2)
00212 {
00213 mNumLeafTests++;
00214 assert(l1); assert(!l2);
00215 const std::list<Triangle>* list1 = l1->getTriangles();
00216 std::list<Triangle>::const_iterator it1;
00217 for (it1=list1->begin(); it1!=list1->end() && mMinDistSq >= 0.0; it1++) {
00218 mNumTriangleTests++;
00219 Triangle t1(*it1);
00220
00221 position p1 = closestPtTriangle(t1, mRefPosition);
00222
00223 double distSq = (p1 - mRefPosition).len_sq();
00224 if (distSq < mMinDistSq) {
00225 mMinDistSq = distSq;
00226 mClosestPt = p1;
00227 }
00228 }
00229 }
00230
00231 double
00232 ClosestPtCallback::quickTest(const Node *n1, const Node *n2)
00233 {
00234 assert(n1); assert(!n2);
00235 mNumQuickTests++;
00236
00237 return pointBoxDistanceSq(n1->getBox(), mRefPosition);
00238 }
00239
00241
00243
00244 double
00245 RegionCallback::quickTest(const Node *n1, const Node *n2)
00246 {
00247 assert(n1); assert(!n2);
00248 mNumQuickTests++;
00249
00250 return pointBoxDistanceSq(n1->getBox(), mRefPosition);
00251 }
00252
00253 void
00254 RegionCallback::leafTest(const Leaf *l1, const Leaf *l2)
00255 {
00256 mNumLeafTests++;
00257 assert(l1); assert(!l2);
00258 const std::list<Triangle>* list1 = l1->getTriangles();
00259 std::list<Triangle>::const_iterator it1;
00260 for (it1=list1->begin(); it1!=list1->end(); it1++) {
00261 mNumTriangleTests++;
00262
00263 Triangle t1(*it1);
00264
00265 vec3 normal = t1.normal();
00266
00267 if (normal % mNormal > 0) continue;
00268 position p1 = closestPtTriangle(t1, mRefPosition);
00269 double distSq = (p1 - mRefPosition).len_sq();
00270 if (distSq > mRadiusSq) continue;
00271 insertPoint(t1.v1);
00272 insertPoint(t1.v2);
00273 insertPoint(t1.v3);
00274 }
00275 }
00276
00277 }