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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #ifndef COLLISION_CHECKING_CONSERVATIVE_ADVANCEMENT_H
00038 #define COLLISION_CHECKING_CONSERVATIVE_ADVANCEMENT_H
00039
00040 #include <limits>
00041 #include "collision_checking/BVH_defs.h"
00042 #include "collision_checking/BVH_model.h"
00043 #include "collision_checking/BVH_front.h"
00044
00047 namespace collision_checking
00048 {
00049
00053 class InterpMotion
00054 {
00056 struct SimpleQuaternion
00057 {
00059 SimpleQuaternion()
00060 {
00061 data[0] = 1;
00062 data[1] = 0;
00063 data[2] = 0;
00064 data[3] = 0;
00065 }
00066
00067 SimpleQuaternion(BVH_REAL a, BVH_REAL b, BVH_REAL c, BVH_REAL d)
00068 {
00069 data[0] = a;
00070 data[1] = b;
00071 data[2] = c;
00072 data[3] = d;
00073 }
00074
00076 void fromRotation(const Vec3f R[3]);
00077
00079 void toRotation(Vec3f R[3]) const;
00080
00082 void fromAxisAngle(const Vec3f& axis, BVH_REAL angle);
00083
00085 void toAxisAngle(Vec3f& axis, BVH_REAL& angle) const;
00086
00088 BVH_REAL dot(const SimpleQuaternion& other) const;
00089
00091 SimpleQuaternion operator + (const SimpleQuaternion& other) const;
00092
00094 SimpleQuaternion operator - (const SimpleQuaternion& other) const;
00095
00097 SimpleQuaternion operator * (const SimpleQuaternion& other) const;
00098
00100 SimpleQuaternion operator - () const;
00101
00103 SimpleQuaternion operator * (BVH_REAL t) const;
00104
00106 SimpleQuaternion conj() const;
00107
00109 SimpleQuaternion inverse() const;
00110
00112 Vec3f transform(const Vec3f& v) const;
00113
00114 BVH_REAL data[4];
00115 };
00116
00118 struct SimpleTransform
00119 {
00121 Vec3f R[3];
00122 Vec3f T;
00123
00125 SimpleQuaternion q;
00126
00128 SimpleTransform()
00129 {
00130 R[0][0] = 1; R[1][1] = 1; R[2][2] = 1;
00131 }
00132
00133 SimpleTransform(const Vec3f R_[3], const Vec3f& T_)
00134 {
00135 for(int i = 0; i < 3; ++i)
00136 R[i] = R_[i];
00137 T = T_;
00138
00139 q.fromRotation(R_);
00140 }
00141 };
00142
00143 public:
00145 InterpMotion()
00146 {
00148 angular_axis = Vec3f(1, 0, 0);
00149 angular_vel = 0;
00150
00152 }
00153
00155 InterpMotion(const Vec3f R1[3], const Vec3f& T1,
00156 const Vec3f R2[3], const Vec3f& T2)
00157 {
00158 t1 = SimpleTransform(R1, T1);
00159 t2 = SimpleTransform(R2, T2);
00160
00162 t = t1;
00163
00165 computeVelocity();
00166 }
00167
00170 InterpMotion(const Vec3f R1[3], const Vec3f& T1,
00171 const Vec3f R2[3], const Vec3f& T2,
00172 const Vec3f& O)
00173 {
00174 t1 = SimpleTransform(R1, T1 - MxV(R1, O));
00175 t2 = SimpleTransform(R2, T2 - MxV(R2, O));
00176 t = t1;
00177
00179 computeVelocity();
00180 }
00181
00182
00186 bool integrate(double dt)
00187 {
00188 if(dt > 1) dt = 1;
00189
00190 t.T = t1.T + linear_vel * dt;
00191
00192 t.q = absoluteRotation(dt);
00193 t.q.toRotation(t.R);
00194
00195 return true;
00196 }
00197
00203 BVH_REAL computeMotionBound(const RSS& bv, const Vec3f& n) const;
00204
00210 BVH_REAL computeMotionBound(const Vec3f& a, const Vec3f& b, const Vec3f& c, const Vec3f& n) const;
00211
00213 void getCurrentTransformation(Vec3f R[3], Vec3f& T) const
00214 {
00215 for(int i = 0; i < 3; ++i)
00216 {
00217 R[i] = t.R[i];
00218 }
00219
00220 T = t.T;
00221 }
00222
00223 void computeVelocity()
00224 {
00225 linear_vel = t2.T - t1.T;
00226 SimpleQuaternion deltaq = t2.q * t1.q.inverse();
00227 deltaq.toAxisAngle(angular_axis, angular_vel);
00228 }
00229
00230 SimpleQuaternion deltaRotation(BVH_REAL t) const
00231 {
00232 SimpleQuaternion res;
00233 res.fromAxisAngle(angular_axis, (BVH_REAL)(t * angular_vel));
00234 return res;
00235 }
00236
00237 SimpleQuaternion absoluteRotation(BVH_REAL t) const
00238 {
00239 SimpleQuaternion delta_t = deltaRotation(t);
00240 return delta_t * t1.q;
00241 }
00242
00244 SimpleTransform t1;
00245
00247 SimpleTransform t2;
00248
00250 SimpleTransform t;
00251
00253 Vec3f linear_vel;
00254
00256 BVH_REAL angular_vel;
00257
00259 Vec3f angular_axis;
00260 };
00261
00262 struct BVH_CAResult
00263 {
00265 int num_bv_tests;
00266
00268 int num_tri_tests;
00269
00271 BVH_REAL query_time_seconds;
00272
00274 BVH_REAL rel_err;
00275 BVH_REAL abs_err;
00276
00280 BVH_REAL distance;
00281 Vec3f p1, p2;
00282
00289 int qsize;
00290
00292 int last_tri_id1;
00293 int last_tri_id2;
00294
00296 BVH_REAL w;
00297
00299 BVH_REAL toc;
00300 BVH_REAL t_err;
00301
00303 BVH_REAL delta_t;
00304
00306 InterpMotion motion1;
00307 InterpMotion motion2;
00308
00309 BVH_CAResult(BVH_REAL w_ = 1)
00310 {
00311 num_bv_tests = 0;
00312 num_tri_tests = 0;
00313
00314 query_time_seconds = 0;
00315
00316
00317 qsize = 2;
00318
00319
00320 last_tri_id1 = 0;
00321 last_tri_id2 = 0;
00322
00324 rel_err = (BVH_REAL)0.01;
00325 abs_err = (BVH_REAL)0.01;
00326
00327 distance = std::numeric_limits<BVH_REAL>::max();
00328
00329 delta_t = 1;
00330 toc = 0;
00331 t_err = (BVH_REAL)0.001;
00332
00333 w = w_;
00334 }
00335
00336 ~BVH_CAResult() {}
00337
00339 void resetRecord()
00340 {
00341 num_bv_tests = 0;
00342 num_tri_tests = 0;
00343
00344 delta_t = 1;
00345 toc = 0;
00346 }
00347 };
00348
00349
00350
00352 void conservativeAdvancementRecurse(BVNode<RSS>* tree1, BVNode<RSS>* tree2,
00353 const Vec3f R[3], const Vec3f& T,
00354 int b1, int b2,
00355 Vec3f* vertices1, Vec3f* vertices2,
00356 Triangle* tri_indices1, Triangle* tri_indices2,
00357 BVH_CAResult* res, BVHFrontList* front_list = NULL);
00358
00359
00361 void continuousCollide_CA(const BVHModel<RSS>& model1, const Vec3f R1_1[3], const Vec3f& T1_1, const Vec3f R1_2[3], const Vec3f& T1_2,
00362 const BVHModel<RSS>& model2, const Vec3f R2_1[3], const Vec3f& T2_1, const Vec3f R2_2[3], const Vec3f& T2_2,
00363 BVH_CAResult* res, BVHFrontList* front_list = NULL);
00364
00365
00366 }
00367
00368 #endif