diff --git a/src/modules/simu/simuv5/collide.cpp b/src/modules/simu/simuv5/collide.cpp index 638b13809..3f57a27dd 100644 --- a/src/modules/simu/simuv5/collide.cpp +++ b/src/modules/simu/simuv5/collide.cpp @@ -418,10 +418,30 @@ static void SimCarCollideResponse(void * /*dummy*/, DtObjectRef obj1, DtObjectRe } } +// Static object and shape list. +// TODO: Dynamic implementation. +static DtShapeRef fixedobjects[100]; +// Id to the next free slot in fixedobjects. +static size_t fixedid; + +static bool isFixedObject(DtObjectRef obj) +{ + for (size_t i = 0; i < fixedid; i++) + { + if (obj == &(fixedobjects[i])) + return true; + } + return false; +} + // Collision response for walls. // TODO: Separate common code with car-car collision response. static void SimCarWallCollideResponse(void *clientdata, DtObjectRef obj1, DtObjectRef obj2, const DtCollData *collData) { + // ignore wall with wall collision + if (isFixedObject(obj1) && isFixedObject(obj2)) + return; + tCar* car; // The car colliding with the wall. float nsign; // Normal direction correction for collision plane. sgVec2 p; // Cars collision point delivered by solid. @@ -569,17 +589,9 @@ void SimCollideRemoveCar(tCar *car, int nbcars) } } -// Static object and shape list. -// TODO: Dynamic implementation. -static DtShapeRef fixedobjects[100]; -// Id to the next free slot in fixedobjects. -static unsigned int fixedid; - void SimCarCollideShutdown(int nbcars) { - int i; - - for (i = 0; i < nbcars; i++) + for (int i = 0; i < nbcars; i++) { // Check if car has not been removed already (wrecked). if (SimCarTable[i].shape != NULL) @@ -589,8 +601,7 @@ void SimCarCollideShutdown(int nbcars) } } - unsigned int j; - for (j = 0; j < fixedid; j++) + for (size_t j = 0; j < fixedid; j++) { dtClearObjectResponse(&fixedobjects[j]); dtDeleteObject(&fixedobjects[j]); @@ -637,9 +648,19 @@ static tTrackSeg *getFirstWallStart(tTrackSeg *start, int side) return NULL; } -// Create the left walls, start must point to a segment with a wall on the left and a leading -// non wall segment. -// FIXME: Does not work for a closed ring "by design". +static tdble distance(const t3Dd &p1, const t3Dd &p2) +{ + tdble dx = p1.x - p2.x; + tdble dy = p1.y - p2.y; + tdble dz = p1.z - p2.z; + + return sqrt(dx * dx + dy * dy + dz * dz); +} + +// Create the walls, start must point to a segment with a wall. +// +// Solid has problems when 2 walls touch so we nolonger break up walls that have changes +// in height or width. This should not be a problem as long as cars stay on the ground. void buildWalls(tTrackSeg *start, int side) { if (start == NULL) { @@ -665,12 +686,8 @@ void buildWalls(tTrackSeg *start, int side) { t3Dd evr = s->vertex[TR_ER]; static float weps = 0.01f; - // Close the start with a ploygon? - if (p == NULL || p->style != TR_WALL || - (fabs(p->vertex[TR_EL].x - svl.x) > weps) || - (fabs(p->vertex[TR_ER].x - svr.x) > weps) || - (fabs(h - p->height) > weps) || - fixedid == 0) + // Close the wall start with a ploygon? + if (p == NULL || p->style != TR_WALL || fixedid == 0) { // Enough space in array? if (fixedid >= sizeof(fixedobjects)/sizeof(fixedobjects[0])) @@ -698,6 +715,13 @@ void buildWalls(tTrackSeg *start, int side) { dtEnd(); } + // fill in hole if width changes + if (p != NULL && p->style == TR_WALL && (distance(p->vertex[TR_EL], svl) > weps || distance(p->vertex[TR_ER], svr) > weps)) + { + // TODO: we can get away with not adding this polygon if the change of width + // is small but it will be a problem if the hole is bigger than a car. + } + // Build sides, left, top, right. Depending on how we want to use it we // can remove top perhaps. // TODO: do we want the top poly? @@ -732,10 +756,7 @@ void buildWalls(tTrackSeg *start, int side) { } // Close the end with a ploygon? - if (n == NULL || n->style != TR_WALL || - (fabs(n->vertex[TR_SL].x - evl.x) > weps) || - (fabs(n->vertex[TR_SR].x - evr.x) > weps) || - (fabs(h - n->height) > weps)) + if (n == NULL || n->style != TR_WALL) { if (close == true) { @@ -754,7 +775,6 @@ void buildWalls(tTrackSeg *start, int side) { GfError("Shape not open %s, line %d\n", __FILE__, __LINE__); } } - } current = current->next; @@ -799,8 +819,7 @@ SimCarCollideInit(tTrack *track) buildWalls(firstleft, TR_SIDE_LFT); buildWalls(firstright, TR_SIDE_RGT); - unsigned int i; - for (i = 0; i < fixedid; i++) { + for (size_t i = 0; i < fixedid; i++) { dtCreateObject(&fixedobjects[i], fixedobjects[i]); dtSetObjectResponse(&fixedobjects[i], SimCarWallCollideResponse, DT_SMART_RESPONSE, &fixedobjects[i]); }