gjk C++应用代码(碰撞问题)

上传者: tftnmgcx | 上传时间: 2019-12-21 21:14:44 | 文件大小: 50KB | 文件类型: zip
GJK计算碰撞代码的应用 //----------------------------------------------------------------------------- // Torque 3D // Copyright (C) GarageGames.com, Inc. // // The core algorithms in this file are based on code written // by G. van den Bergen for his interference detection library, // "SOLID 2.0" //----------------------------------------------------------------------------- #include "core/dataChunker.h" #include "collision/collision.h" #include "sceneGraph/sceneObject.h" #include "collision/convex.h" #include "collision/gjk.h" //---------------------------------------------------------------------------- static F32 rel_error = 1E-5f; // relative error in the computed distance static F32 sTolerance = 1E-3f; // Distance tolerance static F32 sEpsilon2 = 1E-20f; // Zero length vector static U32 sIteration = 15; // Stuck in a loop? S32 num_iterations = 0; S32 num_irregularities = 0; //---------------------------------------------------------------------------- GjkCollisionState::GjkCollisionState() { a = b = 0; } GjkCollisionState::~GjkCollisionState() { } //---------------------------------------------------------------------------- void GjkCollisionState::swap() { Convex* t = a; a = b; b = t; CollisionStateList* l = mLista; mLista = mListb; mListb = l; v.neg(); } //---------------------------------------------------------------------------- void GjkCollisionState::compute_det() { // Dot new point with current set for (int i = 0, bit = 1; i < 4; ++i, bit <<=1) if (bits & bit) dp[i][last] = dp[last][i] = mDot(y[i], y[last]); dp[last][last] = mDot(y[last], y[last]); // Calulate the determinent det[last_bit][last] = 1; for (int j = 0, sj = 1; j < 4; ++j, sj <<= 1) { if (bits & sj) { int s2 = sj | last_bit; det[s2][j] = dp[last][last] - dp[last][j]; det[s2][last] = dp[j][j] - dp[j][last]; for (int k = 0, sk = 1; k < j; ++k, sk <<= 1) { if (bits & sk) { int s3 = sk | s2; det[s3][k] = det[s2][j] * (dp[j][j] - dp[j][k]) + det[s2][last] * (dp[last][j] - dp[last][k]); det[s3][j] = det[sk | last_bit][k] * (dp[k][k] - dp[k][j]) + det[sk | last_bit][last] * (dp[last][k] - dp[last][j]); det[s3][last] = det[sk | sj][k] * (dp[k][k] - dp[k][last]) + det[sk | sj][j] * (dp[j][k] - dp[j][last]); } } } } if (all_bits == 15) { det[15][0] = det[14][1] * (dp[1][1] - dp[1][0]) + det[14][2] * (dp[2][1] - dp[2][0]) + det[14][3] * (dp[3][1] - dp[3][0]); det[15][1] = det[13][0] * (dp[0][0] - dp[0][1]) + det[13][2] * (dp[2][0] - dp[2][1]) + det[13][3] * (dp[3][0] - dp[3][1]); det[15][2] = det[11][0] * (dp[0][0] - dp[0][2]) + det[11][1] * (dp[1][0] - dp[1][2]) + det[11][3] * (dp[3][0] - dp[3][2]); det[15][3] = det[7][0] * (dp[0][0] - dp[0][3]) + det[7][1] * (dp[1][0] - dp[1][3]) + det[7][2] * (dp[2][0] - dp[2][3]); } } //---------------------------------------------------------------------------- inline void GjkCollisionState::compute_vector(int bits, VectorF& v) { F32 sum = 0; v.set(0, 0, 0); for (int i = 0, bit = 1; i < 4; ++i, bit <<= 1) { if (bits & bit) { sum += det[bits][i]; v += y[i] * det[bits][i]; } } v *= 1 / sum; } //---------------------------------------------------------------------------- inline bool GjkCollisionState::valid(int s) { for (int i = 0, bit = 1; i < 4; ++i, bit <<= 1) { if (all_bits & bit) { if (s & bit) { if (det[s][i] <= 0) return false; } else if (det[s | bit][i] > 0) return false; } } return true; } //---------------------------------------------------------------------------- inline bool GjkCollisionState::closest(VectorF& v) { compute_det(); for (int s = bits; s; --s) { if ((s & bits) == s) { if (valid(s | last_bit)) { bits = s | last_bit; if (bits != 15) compute_vector(bits, v); return true; } } } if (valid(last_bit)) { bits = last_bit; v = y[last]; return true; } return false; } //---------------------------------------------------------------------------- inline bool GjkCollisionState::degenerate(const VectorF& w) { for (int i = 0, bit = 1; i < 4; ++i, bit <<= 1) if ((all_bits & bit) && y[i] == w) return true; return false; } //---------------------------------------------------------------------------- inline void GjkCollisionState::nextBit() { last = 0; last_bit = 1; while (bits & last_bit) { ++last; last_bit <<= 1; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void GjkCollisionState::set(Convex* aa, Convex* bb, const MatrixF& a2w, const MatrixF& b2w) { a = aa; b = bb; bits = 0; all_bits = 0; reset(a2w,b2w); // link mLista = CollisionStateList::alloc(); mLista->mState = this; mListb = CollisionStateList::alloc(); mListb->mState = this; } //---------------------------------------------------------------------------- void GjkCollisionState::reset(const MatrixF& a2w, const MatrixF& b2w) { VectorF zero(0,0,0),sa,sb; a2w.mulP(a->support(zero),&sa); b2w.mulP(b->support(zero),&sb); v = sa - sb; dist = v.len(); } //---------------------------------------------------------------------------- void GjkCollisionState::getCollisionInfo(const MatrixF& mat, Collision* info) { AssertFatal(false, "GjkCollisionState::getCollisionInfo() - There remain scaling problems here."); // This assumes that the shapes do not intersect Point3F pa,pb; if (bits) { getClosestPoints(pa,pb); mat.mulP(pa,&info->point); b->getTransform().mulP(pb,&pa); info->normal = info->point - pa; } else { mat.mulP(p[last],&info->point); info->normal = v; } info->normal.normalize(); info->object = b->getObject(); } void GjkCollisionState::getClosestPoints(Point3F& p1, Point3F& p2) { F32 sum = 0; p1.set(0, 0, 0); p2.set(0, 0, 0); for (int i = 0, bit = 1; i < 4; ++i, bit <<= 1) { if (bits & bit) { sum += det[bits][i]; p1 += p[i] * det[bits][i]; p2 += q[i] * det[bits][i]; } } F32 s = 1 / sum; p1 *= s; p2 *= s; } //---------------------------------------------------------------------------- bool GjkCollisionState::intersect(const MatrixF& a2w, const MatrixF& b2w) { num_iterations = 0; MatrixF w2a,w2b; w2a = a2w; w2b = b2w; w2a.inverse(); w2b.inverse(); reset(a2w,b2w); bits = 0; all_bits = 0; do { nextBit(); VectorF va,sa; w2a.mulV(-v,&va); p[last] = a->support(va); a2w.mulP(p[last],&sa); VectorF vb,sb; w2b.mulV(v,&vb); q[last] = b->support(vb); b2w.mulP(q[last],&sb); VectorF w = sa - sb; if (mDot(v,w) > 0) return false; if (degenerate(w)) { ++num_irregularities; return false; } y[last] = w; all_bits = bits | last_bit; ++num_iterations; if (!closest(v) || num_iterations > sIteration) { ++num_irregularities; return false; } } while (bits < 15 && v.lenSquared() > sEpsilon2); return true; } F32 GjkCollisionState::distance(const MatrixF& a2w, const MatrixF& b2w, const F32 dontCareDist, const MatrixF* _w2a, const MatrixF* _w2b) { num_iterations = 0; MatrixF w2a,w2b; if (_w2a == NULL || _w2b == NULL) { w2a = a2w; w2b = b2w; w2a.inverse(); w2b.inverse(); } else { w2a = *_w2a; w2b = *_w2b; } reset(a2w,b2w); bits = 0; all_bits = 0; F32 mu = 0; do { nextBit(); VectorF va,sa; w2a.mulV(-v,&va); p[last] = a->support(va); a2w.mulP(p[last],&sa); VectorF vb,sb; w2b.mulV(v,&vb); q[last] = b->support(vb); b2w.mulP(q[last],&sb); VectorF w = sa - sb; F32 nm = mDot(v, w) / dist; if (nm > mu) mu = nm; if (mu > dontCareDist) return mu; if (mFabs(dist - mu) <= dist * rel_error) return dist; ++num_iterations; if (degenerate(w) || num_iterations > sIteration) { ++num_irregularities; return dist; } y[last] = w; all_bits = bits | last_bit; if (!closest(v)) { ++num_irregularities; return dist; } dist = v.len(); } while (bits < 15 && dist > sTolerance) ; if (bits == 15 && mu <= 0) dist = 0; return dist; }

文件下载

资源详情

[{"title":"( 27 个子文件 50KB ) gjk C++应用代码(碰撞问题)","children":[{"title":"collision","children":[{"title":"earlyOutPolyList.cpp <span style='color:#111;'> 6.97KB </span>","children":null,"spread":false},{"title":"clippedPolyList.h <span style='color:#111;'> 2.97KB </span>","children":null,"spread":false},{"title":"collision.h <span style='color:#111;'> 3.71KB </span>","children":null,"spread":false},{"title":"polytope.h <span style='color:#111;'> 2.02KB </span>","children":null,"spread":false},{"title":"planeExtractor.cpp <span style='color:#111;'> 2.80KB </span>","children":null,"spread":false},{"title":"gjk.h <span style='color:#111;'> 1.92KB </span>","children":null,"spread":false},{"title":"polyhedron.h <span style='color:#111;'> 976B </span>","children":null,"spread":false},{"title":"boxConvex.cpp <span style='color:#111;'> 5.32KB </span>","children":null,"spread":false},{"title":"gjk.cpp <span style='color:#111;'> 9.26KB </span>","children":null,"spread":false},{"title":"extrudedPolyList.h <span style='color:#111;'> 2.58KB </span>","children":null,"spread":false},{"title":"optimizedPolyList.h <span style='color:#111;'> 3.42KB </span>","children":null,"spread":false},{"title":"depthSortList.cpp <span style='color:#111;'> 27.65KB </span>","children":null,"spread":false},{"title":"planeExtractor.h <span style='color:#111;'> 1.40KB </span>","children":null,"spread":false},{"title":"convex.cpp <span style='color:#111;'> 18.47KB </span>","children":null,"spread":false},{"title":"convex.h <span style='color:#111;'> 7.78KB </span>","children":null,"spread":false},{"title":"polytope.cpp <span style='color:#111;'> 13.18KB </span>","children":null,"spread":false},{"title":"abstractPolyList.h <span style='color:#111;'> 7.31KB </span>","children":null,"spread":false},{"title":"boxConvex.h <span style='color:#111;'> 1.16KB </span>","children":null,"spread":false},{"title":"optimizedPolyList.cpp <span style='color:#111;'> 7.24KB </span>","children":null,"spread":false},{"title":"earlyOutPolyList.h <span style='color:#111;'> 1.99KB </span>","children":null,"spread":false},{"title":"extrudedPolyList.cpp <span style='color:#111;'> 13.97KB </span>","children":null,"spread":false},{"title":"concretePolyList.h <span style='color:#111;'> 1.66KB </span>","children":null,"spread":false},{"title":"clippedPolyList.cpp <span style='color:#111;'> 12.14KB </span>","children":null,"spread":false},{"title":"depthSortList.h <span style='color:#111;'> 3.35KB </span>","children":null,"spread":false},{"title":"abstractPolyList.cpp <span style='color:#111;'> 2.36KB </span>","children":null,"spread":false},{"title":"concretePolyList.cpp <span style='color:#111;'> 3.79KB </span>","children":null,"spread":false},{"title":"polyhedron.cpp <span style='color:#111;'> 2.14KB </span>","children":null,"spread":false}],"spread":false}],"spread":true}]

评论信息

  • sq_wang1983 :
    代码很简单,也没有优化,但是能看清楚gjk的基本逻辑,非常不错
    2016-05-19
  • 守钱 :
    代码很简单,也没有优化,但是能看清楚gjk的基本逻辑,非常不错
    2016-05-19
  • u012371504 :
    只有头文件和源文件,不知道怎么用。不过还是感谢分享
    2015-08-13
  • fatislord :
    只有头文件和源文件,不知道怎么用。不过还是感谢分享
    2015-08-13
  • xitele2036 :
    只有头文件和源文件
    2014-06-05
  • LK-BPFC :
    只有头文件和源文件
    2014-06-05
  • dhull :
    只有头文件和源文件,不知道怎么用。不过还是感谢分享。
    2014-03-07
  • dhull :
    只有头文件和源文件,不知道怎么用。不过还是感谢分享。
    2014-03-07

免责申明

【只为小站】的资源来自网友分享,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,【只为小站】 无法对用户传输的作品、信息、内容的权属或合法性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论 【只为小站】 经营者是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。
本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二条之规定,若资源存在侵权或相关问题请联系本站客服人员,zhiweidada#qq.com,请把#换成@,本站将给予最大的支持与配合,做到及时反馈和处理。关于更多版权及免责申明参见 版权及免责申明