Optimized collision detection
This commit is contained in:
parent
9d152e2773
commit
648ce1d454
1 changed files with 39 additions and 17 deletions
|
@ -64,18 +64,31 @@ bool Collision::testEdge(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmm
|
||||||
if(rootSq < 0)
|
if(rootSq < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float root = std::sqrt(rootSq);
|
float minRoot = -a - b_2;
|
||||||
|
float maxRoot = a*MathUtil::EPSILON - b_2;
|
||||||
|
|
||||||
*distance = -(b_2 + root)/a;
|
if(minRoot < 0)
|
||||||
|
minRoot = 0;
|
||||||
float edgeFact = edge.dot(m + move*(*distance) - v1);
|
if(maxRoot < 0)
|
||||||
if(edgeFact < 0 || edgeFact > edge.squared_length())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(*distance > -MathUtil::EPSILON && *distance < 1)
|
if(rootSq < minRoot*minRoot || rootSq >= maxRoot*maxRoot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
minRoot = a*(edge.dot(m - v1) - edge.squared_length())/edge.dot(move) - b_2;
|
||||||
|
maxRoot = a*edge.dot(m - v1)/edge.dot(move) - b_2;
|
||||||
|
|
||||||
|
if(minRoot < 0)
|
||||||
|
minRoot = 0;
|
||||||
|
if(maxRoot < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(rootSq < minRoot*minRoot || rootSq > maxRoot*maxRoot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*distance = -(b_2 + std::sqrt(rootSq))/a;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Collision::testVertex(const vmml::vec3f &v, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance) {
|
bool Collision::testVertex(const vmml::vec3f &v, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance) {
|
||||||
|
@ -87,24 +100,33 @@ bool Collision::testVertex(const vmml::vec3f &v, const vmml::vec3f &m, float r,
|
||||||
if(rootSq < 0)
|
if(rootSq < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float root = std::sqrt(rootSq);
|
float minRoot = -a - b_2;
|
||||||
|
float maxRoot = a*MathUtil::EPSILON - b_2;
|
||||||
|
|
||||||
*distance = -(b_2 + root)/a;
|
if(minRoot < 0)
|
||||||
|
minRoot = 0;
|
||||||
if(*distance > -MathUtil::EPSILON && *distance < 1)
|
if(maxRoot < 0)
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if(rootSq <= minRoot*minRoot || rootSq >= maxRoot*maxRoot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*distance = -(b_2 + std::sqrt(rootSq))/a;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Collision::test(const Triangle &t, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance) {
|
bool Collision::test(const Triangle &t, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance) {
|
||||||
|
if(move.squared_length() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
float d;
|
float d;
|
||||||
|
|
||||||
if(test(t, MathUtil::Ray(m - r*t.computeNormal(), move), &d) && d > -MathUtil::EPSILON) {
|
if(test(t, MathUtil::Ray(m - r*t.computeNormal(), move), &d) && d > -MathUtil::EPSILON) {
|
||||||
|
if(d < 1) {
|
||||||
if(distance)
|
if(distance)
|
||||||
*distance = d;
|
*distance = d;
|
||||||
|
|
||||||
if(d < 1) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Reference in a new issue