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);
349 sgAddVec2(v2a, (
const float*)&(car[i]->DynGCg.vel), tmpv);
353 static float VELMAX = 3.0f;
354 if (fabs(car[i]->VelColl.az) > VELMAX) {
358 sgCopyVec2((
float*)&(car[i]->VelColl.x), v2a);
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++) {
#define RM_CAR_STATE_PIT
Car currently stopped in pits.
#define RM_CAR_STATE_NO_SIMU
Do not simulate the car.
#define SEM_COLLISION_XYSCENE
#define SEM_COLLISION_Z_CRASH
struct CarElt tCarElt
Car structure (tCarElt).
#define RM_CAR_STATE_FINISH
Car having passed the finish line.
#define SEM_COLLISION_CAR
const tdble BorderFriction
void SimCarCollideXYScene(tCar *car)
void SimCarCollideZ(tCar *car)
void SimCarCollideConfig(tCar *car, tTrack *track)
static void SimCarCollideResponse(void *, DtObjectRef obj1, DtObjectRef obj2, const DtCollData *collData)
void SimCarCollideInit(tTrack *track)
static unsigned int fixedid
static void SimCarWallCollideResponse(void *clientdata, DtObjectRef obj1, DtObjectRef obj2, const DtCollData *collData)
static tTrackSeg * getFirstWallStart(tTrackSeg *start, int side)
void SimCarCollideShutdown(int nbcars)
void buildWalls(tTrackSeg *start, int side)
static DtShapeRef fixedobjects[100]
void SimCarCollideCars(tSituation *s)
void SimCollideRemoveCar(tCar *car, int nbcars)
static jsJoystick * js[NUM_JOY]
float tdble
Floating point type used in TORCS.
struct trackSeg tTrackSeg
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
struct Situation tSituation
cars situation used to inform the GUI and the drivers
void dtVertex(DtScalar x, DtScalar y, DtScalar z)
void dtSetObjectResponse(DtObjectRef object, DtResponse response, DtResponseType type, void *client_data)
DtShapeRef dtBox(DtScalar x, DtScalar y, DtScalar z)
void dtCreateObject(DtObjectRef object, DtShapeRef shape)
void dtBegin(DtPolyType type)
void dtClearDefaultResponse()
void dtDeleteShape(DtShapeRef shape)
void dtSetTolerance(DtScalar tol)
void dtSelectObject(DtObjectRef object)
void dtSetDefaultResponse(DtResponse response, DtResponseType type, void *client_data)
void dtMultMatrixf(const float *m)
DtShapeRef dtNewComplexShape()
void dtDeleteObject(DtObjectRef object)
void dtClearObjectResponse(DtObjectRef object)
tCarElt ** cars
list of cars
tdble ay
angle along y axis
tdble ax
angle along x axis
tdble az
angle along z axis
sgMat4 posMat
position matrix
Location on the track in local coordinates.
tdble toLeft
Distance (- to left, + to right) relative to left side of segment.
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
tTrackSeg * seg
Track segment.
tTrackSurface * surface
Barrier surface.
tTrackSurface * surface
Segment surface.
tdble height
Max height for curbs.
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
tTrackBarrier * barrier[2]
Segment barriers.
struct trackSeg * next
Next segment.
struct trackSeg * prev
Previous segment.
int style
Border and barrier segments style:
struct trackSeg * side[2]
tdble kRebound
Coefficient of energy restitution.
tdble kDammage
Dammages in case of collision.
tdble kFriction
Coefficient of friction.
#define SIGN(x)
Sign of the expression.
#define RAD2DEG(x)
Radian to degree conversion.
#define TR_EL
End-Left corner.
#define TR_LPOS_SEGMENT
Relative to the segment which the point is located, including border and sides, mostly used for conta...
struct trackBarrier tTrackBarrier
Barrier.
#define TR_LPOS_TRACK
Local position relative to the outermost barriers, mostly used for collision detection with barrier.
#define TR_ER
End_Right corner.
#define TR_SL
Start-Left corner.
#define TR_WALL
Wall (barrier only)
#define TR_SR
Start-Right corner.
int track(tModInfo *modInfo)