Advertisement

Problems with Collision Detection..

Started by August 24, 2000 06:06 AM
-1 comments, last by Naveed Ahmed 24 years, 3 months ago
I like to add collision detection to 3D engine, as all walls are made of triangles, I used algorithm described at http://www.acm.org/jgt/papers/MollerTrumbore97/ which presents a method for checking for ray/tri intersections, even without knowing the plane equation. Well when I use this function, the player just stucks, as I check current and next positions for collision. Does anyone have better function for collision detection, that works on triangles. here is my current source that stucks defien EPSILON 0.000001 void Cross(float *dest, float *v1, float *v2) { dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; } float Dot(float *v1, float *v2) { return (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]); } void Sub(float *dest, float *v1, float *v2) { dest[0]=v1[0]-v2[0]; dest[1]=v1[1]-v2[1]; dest[2]=v1[2]-v2[2]; } int intersect_triangle(float orig[3], float dir[3], float vert0[3], float vert1[3], float vert2[3], float *t, float *u, float *v) { float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; float det,inv_det; /* find vectors for two edges sharing vert0 */ Sub(edge1, vert1, vert0); Sub(edge2, vert2, vert0); /* begin calculating determinant - also used to calculate U parameter */ Cross(pvec, dir, edge2); /* if determinant is near zero, ray lies in plane of triangle */ det = Dot(edge1, pvec); #ifdef TEST_CULL /* define TEST_CULL if culling is desired */ if (det < EPSILON) return 0; /* calculate distance from vert0 to ray origin */ Sub(tvec, orig, vert0); /* calculate U parameter and test bounds */ *u = Dot(tvec, pvec); if (*u < 0.0 || *u > det) return 0; /* prepare to test V parameter */ Cross(qvec, tvec, edge1); /* calculate V parameter and test bounds */ *v = Dot(dir, qvec); if (*v < 0.0 || *u + *v > det) return 0; /* calculate t, scale parameters, ray intersects triangle */ *t = Dot(edge2, qvec); inv_det = 1.0 / det; *t *= inv_det; *u *= inv_det; *v *= inv_det; #else /* the non-culling branch */ if (det > -EPSILON && det < EPSILON) return 0; inv_det = 1.0 / det; /* calculate distance from vert0 to ray origin */ Sub(tvec, orig, vert0); /* calculate U parameter and test bounds */ *u = Dot(tvec, pvec) * inv_det; if (*u < 0.0 || *u > 1.0) return 0; /* prepare to test V parameter */ Cross(qvec, tvec, edge1); /* calculate V parameter and test bounds */ *v = Dot(dir, qvec) * inv_det; if (*v < 0.0 || *u + *v > 1.0) return 0; /* calculate t, ray intersects triangle */ *t = Dot(edge2, qvec) * inv_det; #endif return 1; } void Collision() { float from[3], to[3], ver1[3], ver2[3], ver3[3], tdis, tx, ty; bool collide = false; to[0] = -xtrans; to[1] = -ytrans; to[2] = -ztrans; from[0] = -xptrans; from[1] = -yptrans; from[2] = -zptrans; for(int i=0; i.numtriangles; j++) { ver1[0] = sectors[currentsector].doors.triangle[j].vertex[0].x; ver1[1] = sectors[currentsector].doors.triangle[j].vertex[0].y; ver1[2] = sectors[currentsector].doors.triangle[j].vertex[0].z; ver2[0] = sectors[currentsector].doors.triangle[j].vertex[1].x; ver2[1] = sectors[currentsector].doors.triangle[j].vertex[1].y; ver2[2] = sectors[currentsector].doors.triangle[j].vertex[1].z; ver3[0] = sectors[currentsector].doors.triangle[j].vertex[2].x; ver3[1] = sectors[currentsector].doors.triangle[j].vertex[2].y; ver3[2] = sectors[currentsector].doors.triangle[j].vertex[2].z; if(intersect_triangle(from, to, ver1, ver2, ver3, &tdis, &tx, &ty)) { collide = true; break; } } if(collide) break; } if(collide) { xtrans = xptrans; ytrans = yptrans; ztrans = zptrans; return; } for (i = 0; i<sectors[currentsector].world.numtriangles; i++) { ver1[0] = sectors[currentsector].world.triangle.vertex[0].x; ver1[1] = sectors[currentsector].world.triangle.vertex[0].y; ver1[2] = sectors[currentsector].world.triangle.vertex[0].z; ver2[0] = sectors[currentsector].world.triangle.vertex[1].x; ver2[1] = sectors[currentsector].world.triangle.vertex[1].y; ver2[2] = sectors[currentsector].world.triangle.vertex[1].z; ver3[0] = sectors[currentsector].world.triangle.vertex[2].x; ver3[1] = sectors[currentsector].world.triangle.vertex[2].y; ver3[2] = sectors[currentsector].world.triangle.vertex[2].z; if(intersect_triangle(from, to, ver1, ver2, ver3, &tdis, &tx, &ty)) { collide = true; break; } } if(collide) { xtrans = xptrans; ytrans = yptrans; ztrans = zptrans; return; } } </i>

This topic is closed to new replies.

Advertisement