22 #define CAR_DAMMAGE 0.1 28 const float CRASH_THRESHOLD = -5.0f;
38 sgTransposeNegateMat4(dst);
49 sgXformVec3(dstVec, (
float *) &normal.
x, dst);
53 for (i = 0; i < 4; i++) {
70 if (sumdz > 0.0f) sumdz = 0.0f;
80 if (dotProd < CRASH_THRESHOLD) {
108 tdble dotProd, cx, cy, dotprod2;
116 corner = &(car->
corner[0]);
117 for (i = 0; i < 4; i++, corner++) {
127 }
else if (trkpos.
toLeft < 0.0) {
149 initDotProd = nx * corner->
vel.
x + ny * corner->
vel.
y;
154 tdble cosa = GCgnormvel/absvel;
155 tdble dmgDotProd = GCgnormvel*cosa;
160 dotprod2 = (nx * cx + ny * cy);
163 static tdble VELSCALE = 10.0f;
164 static tdble VELMAX = 6.0f;
165 car->
DynGCg.
vel.
az -= dotprod2 * dotProd / VELSCALE;
171 dotProd = initDotProd;
182 if (dotProd < 0.0f) {
206 car[0] = (
tCar*)obj1;
207 car[1] = (
tCar*)obj2;
212 if ((car[0]->carElt->_state & NO_SIMU_WITHOUT_PIT) ||
213 (car[1]->
carElt->_state & NO_SIMU_WITHOUT_PIT))
218 if (car[0]->carElt->index < car[1]->
carElt->
index) {
220 p[0][0] = (float)collData->
point1[0];
221 p[0][1] = (
float)collData->
point1[1];
222 p[1][0] = (float)collData->
point2[0];
223 p[1][1] = (
float)collData->
point2[1];
224 n[0] = (float)collData->
normal[0];
225 n[1] = (
float)collData->
normal[1];
228 car[0] = (
tCar*)obj2;
229 car[1] = (
tCar*)obj1;
230 p[0][0] = (float)collData->
point2[0];
231 p[0][1] = (
float)collData->
point2[1];
232 p[1][0] = (float)collData->
point1[0];
233 p[1][1] = (
float)collData->
point1[1];
234 n[0] = -(float)collData->
normal[0];
235 n[1] = -(
float)collData->
normal[1];
241 if (isnan(n[0]) || isnan(n[1])) {
248 for (i = 0; i < 2; i++) {
251 sgSubVec2(r[i],
p[i], (
const float*)&(car[i]->statGC));
256 float sina = sin(carElt->_yaw);
257 float cosa = cos(carElt->_yaw);
258 rg[i][0] = r[i][0]*cosa - r[i][1]*sina;
259 rg[i][1] = r[i][0]*sina + r[i][1]*cosa;
267 sgSubVec2(v1ab, vp[0], vp[1]);
271 for (i = 0; i < 2; i++) {
272 sgCopyVec2(pt[i], r[i]);
275 sgFullXformPnt3(pt[i], car[i]->carElt->_posMat);
280 sgSubVec2(pab, pt[1], pt[0]);
281 float distpab = sgLengthVec2(pab);
285 sgScaleVec2(tmpv, n,
MIN(distpab, 0.05));
288 sgAddVec2((
float*)&(car[0]->DynGCg.pos), tmpv);
292 sgSubVec2((
float*)&(car[1]->DynGCg.pos), tmpv);
297 if (sgScalarProductVec2(v1ab, n) > 0) {
303 rpn[0] = sgScalarProductVec2(rg[0], n);
304 rpn[1] = sgScalarProductVec2(rg[1], n);
309 rpsign[0] = n[0]*rg[0][1] - n[1]*rg[0][0];
310 rpsign[1] = -n[0]*rg[1][1] + n[1]*rg[1][0];
312 const float e = 1.0f;
314 float j = -(1.0f + e) * sgScalarProductVec2(v1ab, n) /
316 rpn[0] * rpn[0] * car[0]->Iinv.z + rpn[1] * rpn[1] * car[1]->
Iinv.
z);
318 for (i = 0; i < 2; i++) {
324 tdble damFactor, atmp;
325 atmp = atan2(r[i][1], r[i][0]);
326 if (fabs(atmp) < (
PI / 3.0)) {
339 const float ROT_K = 1.0f;
341 float js = (i == 0) ? j : -j;
342 sgScaleVec2(tmpv, n,
js * car[i]->Minv);
346 sgAddVec2(v2a, (
const float*)&(car[i]->VelColl.x), tmpv);
347 car[i]->VelColl.az = car[i]->VelColl.az +
js * rpsign[i] * rpn[i] * car[i]->Iinv.z * ROT_K;
349 sgAddVec2(v2a, (
const float*)&(car[i]->DynGCg.vel), tmpv);
350 car[i]->VelColl.az = car[i]->DynGCg.vel.az +
js * rpsign[i] * rpn[i] * car[i]->Iinv.z * ROT_K;
353 static float VELMAX = 3.0f;
354 if (fabs(car[i]->VelColl.az) > VELMAX) {
355 car[i]->VelColl.az =
SIGN(car[i]->VelColl.az) * VELMAX;
358 sgCopyVec2((
float*)&(car[i]->VelColl.x), v2a);
361 tCarElt *carElt = car[i]->carElt;
362 sgMakeCoordMat4(carElt->
pub.
posMat, car[i]->DynGCg.pos.x, car[i]->DynGCg.pos.y,
363 car[i]->DynGCg.pos.z - carElt->_statGC_z,
RAD2DEG(carElt->_yaw),
385 if (obj1 == clientdata) {
388 p[0] = (float) collData->
point2[0];
389 p[1] = (
float) collData->
point2[1];
393 p[0] = (float) collData->
point1[0];
394 p[1] = (
float) collData->
point1[1];
398 n[0] = nsign * (float) collData->
normal[0];
399 n[1] = nsign * (
float) collData->
normal[1];
400 float pdist = sgLengthVec2(n);
404 if (isnan(n[0]) || isnan(n[1])) {
409 sgSubVec2(r,
p, (
const float*)&(car->
statGC));
416 float sina = sin(carElt->_yaw);
417 float cosa = cos(carElt->_yaw);
418 rg[0] = r[0]*cosa - r[1]*sina;
419 rg[1] = r[0]*sina + r[1]*cosa;
425 static const float CAR_MIN_MOVEMENT = 0.02f;
426 static const float CAR_MAX_MOVEMENT = 0.05f;
427 sgScaleVec2(tmpv, n,
MIN(
MAX(pdist, CAR_MIN_MOVEMENT), CAR_MAX_MOVEMENT));
429 sgAddVec2((
float*)&(car->
DynGCg.
pos), tmpv);
434 if (sgScalarProductVec2(vp, n) > 0) {
438 float rp = sgScalarProductVec2(rg, n);
442 float rpsign = n[0]*rg[1] - n[1]*rg[0];
444 const float e = 1.0f;
445 float j = -(1.0f + e) * sgScalarProductVec2(vp, n) / (car->
Minv +
rp *
rp * car->
Iinv.
z);
446 const float ROT_K = 0.5f;
449 tdble damFactor, atmp;
450 atmp = atan2(r[1], r[0]);
451 if (fabs(atmp) < (
PI / 3.0)) {
459 static const float DMGFACTOR = 0.00002f;
464 sgScaleVec2(tmpv, n, j * car->
Minv);
468 sgAddVec2(v2a, (
const float*)&(car->
VelColl.
x), tmpv);
471 sgAddVec2(v2a, (
const float*)&(car->
DynGCg.
vel), tmpv);
475 static float VELMAX = 3.0f;
480 sgCopyVec2((
float*)&(car->
VelColl.
x), v2a);
500 for (i = 0; i < nbcars; i++) {
526 for (i = 0; i < nbcars; i++) {
535 for (j = 0; j <
fixedid; j++) {
556 first->
side[side]->
side[side] != NULL)
562 }
while (first != start);
568 first->
side[side]->
side[side] != NULL)
574 }
while (first != start);
606 static float weps = 0.01f;
610 (fabs(
p->vertex[
TR_EL].x - svl.
x) > weps) ||
611 (fabs(
p->vertex[
TR_ER].x - svr.
x) > weps) ||
612 (fabs(h -
p->height) > weps) ||
617 GfError(
"fixedobjects full in %s, line %d\n", __FILE__, __LINE__);
623 GfError(
"Shape not closed %s, line %d\n", __FILE__, __LINE__);
666 GfError(
"Shape not open %s, line %d\n", __FILE__, __LINE__);
673 (fabs(h - n->
height) > weps))
686 GfError(
"Shape not open %s, line %d\n", __FILE__, __LINE__);
692 current = current->
next;
694 }
while (current != start);
707 car->
shape =
dtBox(carElt->_dimension_x, carElt->_dimension_y, carElt->_dimension_z);
738 for (i = 0; i <
fixedid; i++) {
754 for (i = 0; i < s->_ncars; i++) {
775 for (i = 0; i < s->_ncars; i++) {
void SimCarCollideCars(tSituation *s)
#define TR_SR
Start-Right corner.
void dtDeleteObject(DtObjectRef object)
#define TR_ER
End_Right corner.
cars situation used to inform the GUI and the drivers
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
sgMat4 posMat
position matrix
tCarElt ** cars
list of cars
#define SEM_COLLISION_Z_CRASH
Location on the track in local coordinates.
#define TR_SL
Start-Left corner.
#define SIGN(x)
Sign of the expression.
void SimCarCollideShutdown(int nbcars)
void dtSetObjectResponse(DtObjectRef object, DtResponse response, DtResponseType type, void *client_data)
void dtVertex(DtScalar x, DtScalar y, DtScalar z)
#define SEM_COLLISION_CAR
tdble ay
angle along y axis
#define RM_CAR_STATE_NO_SIMU
Do not simulate the car.
tdble kRebound
Coefficient of energy restitution.
void SimCarCollideZ(tCar *car)
#define RAD2DEG(x)
Radian to degree conversion.
void buildWalls(tTrackSeg *start, int side)
void SimCarCollideConfig(tCar *car, tTrack *track)
void dtBegin(DtPolyType type)
void dtSetTolerance(DtScalar tol)
tTrackBarrier * barrier[2]
Segment barriers.
tTrackSurface * surface
Barrier surface.
tdble toLeft
Distance (- to left, + to right) relative to left side of segment.
void dtClearObjectResponse(DtObjectRef object)
void dtMultMatrixf(const float *m)
static DtShapeRef fixedobjects[100]
float tdble
Floating point type used in TORCS.
DtShapeRef dtNewComplexShape()
void SimCarCollideXYScene(tCar *car)
static jsJoystick * js[NUM_JOY]
static void SimCarCollideResponse(void *, DtObjectRef obj1, DtObjectRef obj2, const DtCollData *collData)
static void SimCarWallCollideResponse(void *clientdata, DtObjectRef obj1, DtObjectRef obj2, const DtCollData *collData)
struct trackSeg * side[2]
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
void dtSelectObject(DtObjectRef object)
const tdble BorderFriction
tdble height
Max height for curbs.
void SimCarCollideInit(tTrack *track)
tTrackSeg * seg
Track segment.
#define TR_EL
End-Left corner.
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
int track(tModInfo *modInfo)
void dtDeleteShape(DtShapeRef shape)
#define RM_CAR_STATE_PIT
Car currently stopped in pits.
tdble az
angle along z axis
struct trackSeg * prev
Previous segment.
tTrackSurface * surface
Segment surface.
static unsigned int fixedid
tdble kDammage
Dammages in case of collision.
struct trackSeg * next
Next segment.
#define TR_LPOS_SEGMENT
Relative to the segment which the point is located, including border and sides, mostly used for conta...
tdble ax
angle along x axis
#define SEM_COLLISION_XYSCENE
void SimCollideRemoveCar(tCar *car, int nbcars)
int style
Border and barrier segments style:
#define TR_LPOS_TRACK
Local position relative to the outermost barriers, mostly used for collision detection with barrier...
tdble kFriction
Coefficient of friction.
DtShapeRef dtBox(DtScalar x, DtScalar y, DtScalar z)
static tTrackSeg * getFirstWallStart(tTrackSeg *start, int side)
void dtClearDefaultResponse()
void dtCreateObject(DtObjectRef object, DtShapeRef shape)
#define RM_CAR_STATE_FINISH
Car having passed the finish line.
void dtSetDefaultResponse(DtResponse response, DtResponseType type, void *client_data)
#define TR_WALL
Wall (barrier only)