PDA

View Full Version : Collision Detection Problem



tjames221188
03-10-2011, 07:38 AM
Hi.

I am trying to make a very simple first person shooter - shooting boxes. the problem i am having is with the shooting part.

I have a method called shoot() that is called when the mouse button is clicked.



void shoot()
{
Click = false;

Point3d Ro = {player.xpos, player.height, player.zpos};
Point3d Rd;
//calculate bullet direction from x and y heading
float xRads = player.xHeading*piover180;
float yRads = player.yHeading*piover180;
Rd.x = cos(yRads) * cos(xRads);
Rd.y = sin(yRads) * cos(xRads);
Rd.z = sin(xRads);
//normalise Rd
float magnitude;
magnitude = sqrt((Rd.x*Rd.x)+(Rd.y*Rd.y)+(Rd.z*Rd.z));
Rd.x = Rd.x/magnitude;
Rd.y = Rd.y/magnitude;
Rd.z = Rd.z/magnitude;
//for each target use the ray equation and the plane equation
//to determine if any target has been hit
int i;
int j;
Point3d p,q,r,v,w,n;

float D;
float denominator;
float numerator;
float t;
//for each target
for (i = 0; i < arena.numTargets; i++)
{
//for each surface on the target
for (j = 0; j < 5; j++)
{
//for each surface
switch (j)
{
case 0://front face
//calculate surface normal
//get 3 points P, Q, R on the surface
p.x = targets[i].x - (targets[i].size/2);//bottom left of the quad
p.y = 0.0f;
p.z = targets[i].z + (targets[i].size/2);

q.x = targets[i].x + (targets[i].size/2);//bottom right of the quad
q.y = 0.0f;
q.z = targets[i].z + (targets[i].size/2);

r.x = targets[i].x + (targets[i].size/2);//top right of the quad
r.y = targets[i].height;
r.z = targets[i].z + (targets[i].size/2);

//calculate 2 perpendicular vectors in the plane
//v = q - p and w = r - p
v.x = q.x - p.x;
v.y = q.y - p.y;
v.z = q.z - p.z;

w.x = r.x - p.x;
w.y = r.y - p.y;
w.z = r.z - p.z;

//calculate the V x W (cross product) to obtain the plane normal
n.x = (v.y * w.z) - (w.y * v.z);
n.y = (v.z * w.x) - (w.z * v.x);
n.z = (v.x * w.y) - (w.x * v.y);

//define plane by Ax + By + Cz + D = 0
//calculate D from Ro.n (normalised)
//so normalise Ro and n
magnitude = sqrt((Ro.x*Ro.x)+(Ro.y*Ro.y)+(Ro.z*Ro.z));
Ro.x = Ro.x/magnitude;
Ro.y = Ro.y/magnitude;
Ro.z = Ro.z/magnitude;

magnitude = sqrt((n.x*n.x)+(n.y*n.y)+(n.z*n.z));
n.x = n.x/magnitude;
n.y = n.y/magnitude;
n.z = n.z/magnitude;

D = (Ro.x*n.x) + (Ro.y*n.y) + (Ro.z*n.z);

//A,B,C is the normal to the plane
//substitute in the ray equation to get
//A(x0 + txd)+ B(y0 + tyd) + C(z0 + tzd) + D = 0
//rearrange to solve for t
// _(N.Ro + D)
// ----------
// N.Rd

//first work out the denominator

denominator = (n.x*Rd.x) + (n.y*Rd.y) + (n.z*Rd.z);
if (denominator == 0.0f)
{
//bullet path is parallel to the plane
break;
}
if (denominator > 0.0f)
{
//normal to the plane is pointing away from the bullet path
break;
}

//now work out the numerator [-(N.Ro + D)]
numerator = -((n.x*Ro.x) + (n.y*Ro.y) + (n.z*Rd.z) + D);
t = numerator/denominator;
if (t < 0)//plane is behind origin
{

break;
}
else
{
//work out point of intersection
Point3d poi;
poi.x = Ro.x + Rd.x * t;
poi.y = Ro.y + Rd.y * t;
poi.z = Ro.z = Rd.z * t;
//now check if the point of intersection is within the
//rectangle on the surface of the target
//calculate rectangle vertices
//we already have 3 vertices p,q and r
//calculate the 4th:
Point3d s;
s.x = targets[i].x - targets[i].size;
s.y = targets[i].height;
s.z = targets[i].z + targets[i].size;

float left,right,top,bottom;
left = p.x;
right = q.x;
top = r.y;
bottom = q.y;
if (poi.x > left &amp;&amp; poi.x < right &amp;&amp;
poi.y > bottom &amp;&amp; poi.y < top)
{
targets[i].hit = true;
}
}

break;

case 1://back face

break;

case 2://top face

break;

case 3://right face

break;

case 4://left face

break;
}
}
}
}


As you can see im still trying to do this for 1 face of a box. I dont have any vector class so i am just hard coding the maths as it is only supposed to be a bit of learning.

i have traced through the program and found that no matter where i position my player the denominator is always > 0, but i cannot find out why.

If anyone can see what im doing wrong i would greatly appreciate any input.

Thanks in advance,

Toby