PDA

View Full Version : Collision Detection Problems



MrShoe
10-18-2001, 09:30 PM
this is my code for collision detection... it worksto a degree but sometimes it doesnt, and sometimes it "activates" even though no collision occured, can some one point me in the right direction because i have had no luck debugging it for 2 days:

int collision(void){
int mapx, mapz;
VECTOR3D normal;
VECTOR3D origin, destination;
VECTOR3D vertex1, vertex2, vertex3;
VECTOR3D tri_ray1, tri_ray2, tri_ray3;
VECTOR3D intersection_point;
VECTOR3D ray;
float t;
float angle_sum;
float origin_result, destination_result;
float distance;
float magnitude;

// Plane position
origin.x = player1.xpos;
origin.y = player1.ypos;
origin.x = player1.zpos;

// Plane destination
destination.x = player1.xpos + (player1.xi/(SLOWDOWN*2.0));
destination.y = player1.ypos + (player1.yi/(SLOWDOWN*2.0));
destination.z = player1.zpos + (player1.zi/(SLOWDOWN*2.0));

ray.x = destination.x - origin.x;
ray.y = destination.y - origin.y;
ray.z = destination.z - origin.z;

for(mapx = 0; mapx < TERRAIN_WIDTH; mapx++){
for(mapz = 0; mapz < TERRAIN_LENGTH; mapz++){
if(sqrt(((mapx/TERRAIN_SHRINK_FACTOR)-player1.xpos)*((mapx/TERRAIN_SHRINK_FACTOR)-player1.xpos)+(terrain[mapx][mapz]-player1.ypos)*(terrain[mapx][mapz]-player1.ypos)+((mapz/TERRAIN _SHRINK_FACTOR)-player1.zpos)*((mapz/TERRAIN_SHRINK_FACTOR)-player1.zpos)) < 2.0){
angle_sum = 0.0;
normal = plane_normals[mapx][mapz];
distance = normal.x*((float)mapx/TERRAIN_SHRINK_FACTOR) + normal.y*terrain[mapx][mapz] + normal.z*((float)mapz/TERRAIN_SHRINK_FACTOR);
distance = abs(distance); // WARNING...
origin_result = DotProduct(origin, normal) + distance;
destination_result = DotProduct(destination, normal) + distance;

if(origin_result >= 0.0 && destination_result <= 0.0){
t = -((DotProduct(normal, origin) + distance)/DotProduct(normal, ray));
intersection_point.x = origin.x + ray.x*t;
intersection_point.y = origin.y + ray.y*t;
intersection_point.z = origin.z + ray.z*t;

vertex1.x = (float)mapx/TERRAIN_SHRINK_FACTOR;
vertex1.y = terrain[mapx][mapz];
vertex1.z = (float)mapz/TERRAIN_SHRINK_FACTOR;

vertex2.x = (float)(mapx+1)/TERRAIN_SHRINK_FACTOR;
vertex2.y = terrain[mapx+1][mapz];
vertex2.z = (float)mapz/TERRAIN_SHRINK_FACTOR;

vertex2.x = (float)mapx/TERRAIN_SHRINK_FACTOR;
vertex2.y = terrain[mapx][mapz+1];
vertex2.z = (float)(mapz+1)/TERRAIN_SHRINK_FACTOR;

tri_ray1.x = vertex1.x - intersection_point.x;
tri_ray1.y = vertex1.y - intersection_point.y;
tri_ray1.z = vertex1.z - intersection_point.z;
magnitude = sqrt(tri_ray1.x*tri_ray1.x + tri_ray1.y*tri_ray1.y + tri_ray1.z*tri_ray1.z);
tri_ray1.x = tri_ray1.x/magnitude;
tri_ray1.y = tri_ray1.y/magnitude;
tri_ray1.z = tri_ray1.z/magnitude;

tri_ray2.x = vertex2.x - intersection_point.x;
tri_ray2.y = vertex2.y - intersection_point.y;
tri_ray2.z = vertex2.z - intersection_point.z;
magnitude = sqrt(tri_ray2.x*tri_ray2.x + tri_ray2.y*tri_ray2.y + tri_ray2.z*tri_ray2.z);
tri_ray2.x = tri_ray2.x/magnitude;
tri_ray2.y = tri_ray2.y/magnitude;
tri_ray2.z = tri_ray2.z/magnitude;

tri_ray3.x = vertex3.x - intersection_point.x;
tri_ray3.y = vertex3.y - intersection_point.y;
tri_ray3.z = vertex3.z - intersection_point.z;
magnitude = sqrt(tri_ray3.x*tri_ray3.x + tri_ray3.y*tri_ray3.y + tri_ray3.z*tri_ray3.z);
tri_ray3.x = tri_ray3.x/magnitude;
tri_ray3.y = tri_ray3.y/magnitude;
tri_ray3.z = tri_ray3.z/magnitude;

angle_sum += acos(DotProduct(tri_ray1, tri_ray2));
angle_sum += acos(DotProduct(tri_ray2, tri_ray3));
angle_sum += acos(DotProduct(tri_ray3, tri_ray1));
if(angle_sum >= ((2*PI)-COLLISION_ACCURACY) && angle_sum <= ((2*PI)+COLLISION_ACCURACY)){
return 1;
}
}
if(origin_result <= 0.0 && destination_result >= 0.0){
t = -((DotProduct(normal, origin) + distance)/DotProduct(normal, ray));
intersection_point.x = origin.x + ray.x*t;
intersection_point.y = origin.y + ray.y*t;
intersection_point.z = origin.z + ray.z*t;

vertex1.x = (float)mapx/TERRAIN_SHRINK_FACTOR;
vertex1.y = terrain[mapx][mapz];
vertex1.z = (float)mapz/TERRAIN_SHRINK_FACTOR;

vertex2.x = (float)(mapx+1)/TERRAIN_SHRINK_FACTOR;
vertex2.y = terrain[mapx+1][mapz];
vertex2.z = (float)mapz/TERRAIN_SHRINK_FACTOR;

vertex2.x = (float)mapx/TERRAIN_SHRINK_FACTOR;
vertex2.y = terrain[mapx][mapz+1];
vertex2.z = (float)(mapz+1)/TERRAIN_SHRINK_FACTOR;

tri_ray1.x = vertex1.x - intersection_point.x;
tri_ray1.y = vertex1.y - intersection_point.y;
tri_ray1.z = vertex1.z - intersection_point.z;
magnitude = sqrt(tri_ray1.x*tri_ray1.x + tri_ray1.y*tri_ray1.y + tri_ray1.z*tri_ray1.z);
tri_ray1.x = tri_ray1.x/magnitude;
tri_ray1.y = tri_ray1.y/magnitude;
tri_ray1.z = tri_ray1.z/magnitude;

tri_ray2.x = vertex2.x - intersection_point.x;
tri_ray2.y = vertex2.y - intersection_point.y;
tri_ray2.z = vertex2.z - intersection_point.z;
magnitude = sqrt(tri_ray2.x*tri_ray2.x + tri_ray2.y*tri_ray2.y + tri_ray2.z*tri_ray2.z);
tri_ray2.x = tri_ray2.x/magnitude;
tri_ray2.y = tri_ray2.y/magnitude;
tri_ray2.z = tri_ray2.z/magnitude;

tri_ray3.x = vertex3.x - intersection_point.x;
tri_ray3.y = vertex3.y - intersection_point.y;
tri_ray3.z = vertex3.z - intersection_point.z;
magnitude = sqrt(tri_ray3.x*tri_ray3.x + tri_ray3.y*tri_ray3.y + tri_ray3.z*tri_ray3.z);
tri_ray3.x = tri_ray3.x/magnitude;
tri_ray3.y = tri_ray3.y/magnitude;
tri_ray3.z = tri_ray3.z/magnitude;

angle_sum += acos(DotProduct(tri_ray1, tri_ray2));
angle_sum += acos(DotProduct(tri_ray2, tri_ray3));
angle_sum += acos(DotProduct(tri_ray3, tri_ray1));
if(angle_sum >= ((2*PI)-COLLISION_ACCURACY) && angle_sum <= ((2*PI)+COLLISION_ACCURACY)){
return 1;
}
}
}
}
}
return 0;
}