Hi guys...
A few days ago, I wrote a basic collision detector. The problem was that it didn't always work, so I decided to edit my plane intersection function. The problem now is that it works even less of the times.
I would love it if somebody can read through this code, and spot my error :).
Intersection tester. I guess the problem can be found in this function. The function works not bad on the floor, but with vertical faces it does weird things, like finding an intersection far before the face. Note that the innerProduct is the dot product. Long time ago, I called the function like this and I don't know why.
#define PLANE_FRONT 0x01
#define PLANE_BACK 0x02
#define PLANE_NONE 0x03
#define GETSIDE(a) (a > EPSILON ? PLANE_FRONT : (a < -EPSILON ? PLANE_BACK : PLANE_NONE))
bBool bMath::testIntersection(bMPlane& plane, bVertex3f& oldPos, bVertex3f& newPos, bVertex3f& ray, bDouble& t) {
if(plane.equation == 0.0)
return false;
/* If p1 is higher than 0, and p2 is lower than 0 (or the other way around), we
* are passing a plane. */
bDouble p1 = innerProduct(plane.normal, newPos) + plane.equation;
bDouble p2 = innerProduct(plane.normal, oldPos) + plane.equation;
if(GETSIDE(p1) != GETSIDE(p2)) { // did we pass a plane?
/* Ray is a non-normalized version of the new position minus the old position */
t = -p2 / innerProduct(plane.normal, ray);
return true;
}
return false;
}
plane.equation is calculated as follows:
plane_arr.equation = (bFloat) bMath::innerProduct(*plane_arr.point, plane_arr.normal); // plane_arr.point is the origin, plane_arr is an array of planes based on the faces found in the object
The following function creates the sum of the angles from the intersection point towards the vertices of a triangle. I don't think there are any errors in this code, since last time I checked this function returns a good value as long as testIntersection fills in t with a valid value.
bFloat bMath::angleSum(bVertex3f& p, bPoint *v, int n) {
bDouble retVal;
retVal = 0.0;
for(int i = 0; i < n; i++) {
bVertex3f p1 = v.vertice;
bVertex3f p2 = v[(i + 1) % n].vertice;
vertexSubstract(p1, p);
vertexSubstract(p2, p);
bDouble m1 = PYTH3D(p1);
bDouble m2 = PYTH3D(p2);
bDouble m1_m2 = m1 * m2;
if(m1_m2 <= EPSILON)
return (bFloat) PI_2;
else
retVal += acos(innerProduct(p1, p2) / m1_m2);
}
return (bFloat) retVal;
}
This is the function where testIntersection and angleSum are combined. Maybe there is a mistake in the calculation of the intersection point?
/* src is the current position, des is the new position, and dir is the new position minus the old position. */
bDouble t;
if(bMath::testIntersection(plane_arr, src, des, dir, t)) {
/* Calculate the point where the ray and the plane intersect */
bVertex3f intPoint;
intPoint.x = src.x + (dir.x * t);
intPoint.y = src.y + (dir.y * t);
intPoint.z = src.z + (dir.z * t);
bFloat as = bMath::angleSum(intPoint, &info_arr, <span class="cpp-number">3</span>); <span class="cpp-comment">// info_arr is the list with vertices, normals, etc.</span>
<span class="cpp-comment">// PI_2 is 2pi</span>
<span class="cpp-keyword">if</span>(as > (PI_2 - <span class="cpp-number">0</span>.<span class="cpp-number">08</span>) && as < (PI_2 + <span class="cpp-number">0</span>.<span class="cpp-number">08</span>)) {
<span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;
}
}
</pre></div><!–ENDSCRIPT–>
I hope I have commented enough, and thanks a lot for your time.
- Polyphemus
<!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - Polyphemus on March 6, 2006 3:54:24 PM]<!–EDIT–></span><!–/EDIT–>