Problems with Collision Detection..
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
Popular Topics
Advertisement