Added corner collision
This commit is contained in:
parent
c85a39bb0f
commit
853d3978c5
2 changed files with 51 additions and 9 deletions
|
@ -84,16 +84,16 @@ bool Collision::testEdge(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmm
|
||||||
vmml::vec3f cvec = v1 + vmml::dot(edge, m-v1)*edge / edge.squared_length() - m;
|
vmml::vec3f cvec = v1 + vmml::dot(edge, m-v1)*edge / edge.squared_length() - m;
|
||||||
|
|
||||||
float a = avec.squared_length();
|
float a = avec.squared_length();
|
||||||
float b = vmml::dot(avec, cvec);
|
float b_2 = vmml::dot(avec, cvec);
|
||||||
float c = cvec.squared_length() - r*r;
|
float c = cvec.squared_length() - r*r;
|
||||||
|
|
||||||
float rootSq = b*b - a*c;
|
float rootSq = b_2*b_2 - a*c;
|
||||||
if(rootSq < 0)
|
if(rootSq < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float root = std::sqrt(rootSq);
|
float root = std::sqrt(rootSq);
|
||||||
|
|
||||||
*distance = -(b + root)/a;
|
*distance = -(b_2 + root)/a;
|
||||||
|
|
||||||
float edgeFact = edge.dot(m + move*(*distance) - v1);
|
float edgeFact = edge.dot(m + move*(*distance) - v1);
|
||||||
if(edgeFact < 0 || edgeFact > edge.squared_length())
|
if(edgeFact < 0 || edgeFact > edge.squared_length())
|
||||||
|
@ -105,6 +105,25 @@ bool Collision::testEdge(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmm
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Collision::testVertex(const vmml::vec3f &v, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance) {
|
||||||
|
float a = move.squared_length();
|
||||||
|
float b_2 = vmml::dot(m-v, move);
|
||||||
|
float c = (m-v).squared_length() - r*r;
|
||||||
|
|
||||||
|
float rootSq = b_2*b_2 - a*c;
|
||||||
|
if(rootSq < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float root = std::sqrt(rootSq);
|
||||||
|
|
||||||
|
*distance = -(b_2 + root)/a;
|
||||||
|
|
||||||
|
if(*distance > -MathUtil::EPSILON && *distance < 1)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
float d;
|
float d;
|
||||||
|
|
||||||
|
@ -120,20 +139,42 @@ bool Collision::test(const Triangle &t, const vmml::vec3f &m, float r, const vmm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float minEdgeDistance = std::numeric_limits<float>::infinity();
|
bool collision = false;
|
||||||
|
float minDistance;
|
||||||
|
|
||||||
for(int i = 0; i < 3; ++i) {
|
for(int i = 0; i < 3; ++i) {
|
||||||
if(testEdge(t.getVertex(i), t.getVertex((i+1)%3), m, r, move, &d)) {
|
if(testEdge(t.getVertex(i), t.getVertex((i+1)%3), m, r, move, &d)) {
|
||||||
if(d < minEdgeDistance) {
|
if(!collision || d < minDistance) {
|
||||||
minEdgeDistance = d;
|
minDistance = d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(distance)
|
if(collision) {
|
||||||
*distance = minEdgeDistance;
|
if(distance)
|
||||||
|
*distance = minDistance;
|
||||||
|
|
||||||
return (minEdgeDistance < 1);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
collision = false;
|
||||||
|
for(int i = 0; i < 3; ++i) {
|
||||||
|
if(testVertex(t.getVertex(i), m, r, move, &d)) {
|
||||||
|
if(!collision || d < minDistance) {
|
||||||
|
minDistance = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(collision) {
|
||||||
|
if(distance)
|
||||||
|
*distance = minDistance;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ class Collision {
|
||||||
Collision();
|
Collision();
|
||||||
|
|
||||||
static bool testEdge(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance);
|
static bool testEdge(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance);
|
||||||
|
static bool testVertex(const vmml::vec3f &v, const vmml::vec3f &m, float r, const vmml::vec3f &move, float *distance);
|
||||||
|
|
||||||
static vmml::vec3f projectToEdge(const vmml::vec3f& p, const vmml::vec3f& v1, const vmml::vec3f& v2);
|
static vmml::vec3f projectToEdge(const vmml::vec3f& p, const vmml::vec3f& v1, const vmml::vec3f& v2);
|
||||||
static vmml::vec3f projectToNearestEdge(const vmml::vec3f& p, const Triangle &t);
|
static vmml::vec3f projectToNearestEdge(const vmml::vec3f& p, const Triangle &t);
|
||||||
|
|
Reference in a new issue