#include "header.h" typedef struct { long sx, sy, ex, ey; } Line; int LineCollision(Line a, Line b); void TrackCollide(void) { Line a, b; VERTEX *v0, *v1, *v2, *v3; int i, loopAgain; // Get collision point segment numbers for (i=0; i<3; i++) { do { loopAgain = 0; v0 = &vertexLut[primitiveLut[racer.collisionSegment[i]].vert0]; v1 = &vertexLut[primitiveLut[racer.collisionSegment[i]].vert1]; v2 = &vertexLut[primitiveLut[racer.collisionSegment[i]].vert2]; v3 = &vertexLut[primitiveLut[racer.collisionSegment[i]].vert3]; a.sx = racer.pos.vx+racer.vel.vx+racer.collisionPoint[i].vx; a.sy = racer.pos.vz+racer.vel.vz+racer.collisionPoint[i].vz; a.ex = (v0->vx+v1->vx+v2->vx+v3->vx)>>2; a.ey = (v0->vz+v1->vz+v2->vz+v3->vz)>>2; b.sx = v2->vx; b.sy = v2->vz; b.ex = v3->vx; b.ey = v3->vz; if (LineCollision(a, b)) { racer.collisionSegment[i] = (racer.collisionSegment[i]+1)%rawTrack->numSegments; loopAgain = 1; } else { b.sx = v0->vx; b.sy = v0->vz; b.ex = v1->vx; b.ey = v1->vz; if (LineCollision(a, b)) { racer.collisionSegment[i]--; if (racer.collisionSegment[i] < 0) racer.collisionSegment[i] = rawTrack->numSegments-1; loopAgain = 1; } } } while (loopAgain); } // Get height point segment numbers for (i=0; i<4; i++) { do { loopAgain = 0; v0 = &vertexLut[primitiveLut[racer.heightSegment[i]].vert0]; v1 = &vertexLut[primitiveLut[racer.heightSegment[i]].vert1]; v2 = &vertexLut[primitiveLut[racer.heightSegment[i]].vert2]; v3 = &vertexLut[primitiveLut[racer.heightSegment[i]].vert3]; a.sx = racer.pos.vx+racer.vel.vx+racer.heightPoint[i].vx; a.sy = racer.pos.vz+racer.vel.vz+racer.heightPoint[i].vz; a.ex = (v0->vx+v1->vx+v2->vx+v3->vx)>>2; a.ey = (v0->vz+v1->vz+v2->vz+v3->vz)>>2; b.sx = v2->vx; b.sy = v2->vz; b.ex = v3->vx; b.ey = v3->vz; if (LineCollision(a, b)) { racer.heightSegment[i] = (racer.heightSegment[i]+1)%rawTrack->numSegments; loopAgain = 1; } else { b.sx = v0->vx; b.sy = v0->vz; b.ex = v1->vx; b.ey = v1->vz; if (LineCollision(a, b)) { racer.heightSegment[i]--; if (racer.heightSegment[i] < 0) racer.heightSegment[i] = rawTrack->numSegments-1; loopAgain = 1; } } } while (loopAgain); // Get which half of segment each point is on a.ex = (v0->vx+v1->vx)>>1; a.ey = (v0->vz+v1->vz)>>1; b.sx = v0->vx; b.sy = v0->vz; b.ex = v3->vx; b.ey = v3->vz; if (LineCollision(a, b)) racer.half[i] = 1; else racer.half[i] = 0; } } int LineCollision(Line a, Line b) { long swapTemp; long ay, by, cy, dy; // Ensure coords are defined in correct order if (a.sx > a.ex) { swapTemp=a.sx; a.sx=a.ex; a.ex=swapTemp; swapTemp=a.sy; a.sy=a.ey; a.ey=swapTemp; } if (b.sx > b.ex) { swapTemp=b.sx; b.sx=b.ex; b.ex=swapTemp; swapTemp=b.sy; b.sy=b.ey; b.ey=swapTemp; } // Clip lines if (a.sx < b.sx) { if (a.ex <= b.sx) return 0; ay = ((a.ey-a.sy)*(b.sx-a.sx)) / (a.ex-a.sx) + a.sy; cy = b.sy; if (b.ex < a.ex) { by = ((a.ey-a.sy)*(b.ex-a.sx)) / (a.ex-a.sx) + a.sy; dy = b.ey; } else { by = a.ey; dy = ((b.ey-b.sy)*(a.ex-b.sx)) / (b.ex-b.sx) + b.sy; } } else { if (b.ex <= a.sx) return 0; ay = a.sy; cy = ((b.ey-b.sy)*(a.sx-b.sx)) / (b.ex-b.sx) + b.sy; if (a.ex < b.ex) { by = a.ey; dy = ((b.ey-b.sy)*(a.ex-b.sx)) / (b.ex-b.sx) + b.sy; } else { by = ((a.ey-a.sy)*(b.ex-a.sx)) / (a.ex-a.sx) + a.sy; dy = b.ey; } } // Don't accept collision if lines are touching if (ay==cy || by==dy) return 0; // Check that they cross return (Sgn(cy-ay) != Sgn(dy-by)); }