The collision code is a direct port of the one I use for the pc and is made so that I can use the same models for collisions and draw arrays. I tried the same models on my pc and everything worked without any problems.
I use sphere to polygon collisions. I pass a pointer to the model structure and a pointer to my car structure to the function. These have before been malloced and memset to 0 before I've given them the values they should have. The first thing I do is to check AABB collisions, if the car is inside of the bounding box I load the rest of the values I need for the polygon. I check the distance and look if the closest point on the polygon to the cars position is really on the polygon. Then I want to change the cars position but this is where it crashes.
Even if I just do something like cr->pos.y = 0; it crashes if I go to the polygons which make it crash. On all other polygons it works just like it should. I never change the value of cr (the car pointer) but yet it seems to try to change the values inside of it is what's causing the crash. I can still read the values without it crashing and I've even tried moving the values I need in the code to normal variables and moving them back again at the end of the function but it still crashes when trying to move it back, but only on these specific polygons that always seem to cause the crash.
Here is the code:
Code: Select all
void collisionCheck(pspObject *model, car *cr) {
unsigned int i, j, l;
float mx, nx, p1x, p1y, p1z, my, ny, p2x, p2y, p2z, mz, nz, p3x, p3y, p3z, d;
float bbplx, bbphx, bbply, bbphy, bbplz, bbphz;
// player bounding box
float bbplrlx = cr->pos.x - 8.0f;
float bbplrhx = cr->pos.x + 8.0f;
float bbplrly = cr->pos.y - 8.0f;
float bbplrhy = cr->pos.y + 8.0f;
float bbplrlz = cr->pos.z - 8.0f;
float bbplrhz = cr->pos.z + 8.0f;
cr->onground = 0;
j = 0; l = 0;
for(i = 0; i < model->polygonAmount; i++) {
// AABB check
bbplx = model->aabb[l++];
bbphx = model->aabb[l++];
bbply = model->aabb[l++];
bbphy = model->aabb[l++];
bbplz = model->aabb[l++];
bbphz = model->aabb[l++];
if((bbplrhx <= bbplx || bbplrlx >= bbphx ||
bbplrhy <= bbply || bbplrly >= bbphy ||
bbplrhz <= bbplz || bbplrlz >= bbphz)) {
j += 3;
} else {
mx = model->middlePoint[j];
nx = model->polygonNormal[j];
p1x = model->object[j].x;
p1y = model->object[j].y;
p1z = model->object[j++].z;
my = model->middlePoint[j];
ny = model->polygonNormal[j];
p2x = model->object[j].x;
p2y = model->object[j].y;
p2z = model->object[j++].z;
mz = model->middlePoint[j];
nz = model->polygonNormal[j];
p3x = model->object[j].x;
p3y = model->object[j].y;
p3z = model->object[j++].z;
d = model->d[i];
float dist = (nx*(cr->pos.x) + ny*(cr->pos.y) + nz*(cr->pos.z) - d);
if(dist >= -2 && dist <= 8) {
float newx = cr->pos.x - nx*dist;
float newy = cr->pos.y - ny*dist;
float newz = cr->pos.z - nz*dist;
int dominentAxis = 0;
float dominentValue = (float)fabs(nx);
if(fabs(ny) > dominentValue) dominentAxis = 1;
if(fabs(nz) > dominentValue) dominentAxis = 2;
vector2f v1 = {0,0}, v2 = {0,0}, l1 = {0,0}, l2 = {0,0}, l3 = {0,0};
if(dominentAxis == 0) {
v1.x = newz, v1.y = newy;
v2.x = mz, v2.y = my;
l1.x = p1z, l1.y = p1y;
l2.x = p2z, l2.y = p2y;
l3.x = p3z, l3.y = p3y;
} else if(dominentAxis == 1) {
v1.x = newx, v1.y = newz;
v2.x = mx, v2.y = mz;
l1.x = p1x, l1.y = p1z;
l2.x = p2x, l2.y = p2z;
l3.x = p3x, l3.y = p3z;
} else if(dominentAxis == 2) {
v1.x = newx, v1.y = newy;
v2.x = mx, v2.y = my;
l1.x = p1x, l1.y = p1y;
l2.x = p2x, l2.y = p2y;
l3.x = p3x, l3.y = p3y;
}
if(sameSideofLine(v1, v2, l1, l2) &&
sameSideofLine(v1, v2, l2, l3) &&
sameSideofLine(v1, v2, l3, l1)) {
// move the car
cr->pos.x -= nx*(dist-8.0f);
cr->pos.y -= ny*(dist-8.0f);
cr->pos.z -= nz*(dist-8.0f);
cr->onground = 1;
if(ny > 0.75) {
if(cr->speed.y < 0) cr->speed.y = 0;
}
}
}
}
}
}