30#include <robottools.h>
31#include <portability.h>
50 return dx * dx + dy * dy;
78 *x = car->_pos_X_D + (double)car->_pos_X - car->_posMat[3][0];
79 *
y = car->_pos_Y_D + (double)car->_pos_Y - car->_posMat[3][1];
88 point[0] = baseX + x * car->_posMat[0][0] +
y * car->_posMat[1][0] + z * car->_posMat[2][0];
89 point[1] = baseY + x * car->_posMat[0][1] +
y * car->_posMat[1][1] + z * car->_posMat[2][1];
90 point[2] = car->_posMat[3][2] + x * car->_posMat[0][2] +
y * car->_posMat[1][2] + z * car->_posMat[2][2];
116 sgSubVec3(
y, center, eye);
122 sgVectorProductVec3(x,
y, z);
125 sgVectorProductVec3(z, x,
y);
133#define M(row,col) dst[row][col]
134 M(0, 0) = x[0];
M(0, 1) = x[1];
M(0, 2) = x[2];
M(0, 3) = 0.0;
135 M(1, 0) =
y[0];
M(1, 1) =
y[1];
M(1, 2) =
y[2];
M(1, 3) = 0.0;
136 M(2, 0) = z[0];
M(2, 1) = z[1];
M(2, 2) = z[2];
M(2, 3) = 0.0;
137 M(3, 0) = eye[0];
M(3, 1) = eye[1];
M(3, 2) = eye[2];
M(3, 3) = 1.0;
143 float myfovy,
float myfovymin,
float myfovymax,
144 float myfnear,
float myffar,
float myfogstart,
float myfogend)
167 float fovx = atan(
screen->getViewRatio() * tan(
fovy * M_PI / 360.0)) * 360.0 / M_PI;
175 sgVec3 renderEye, renderCenter;
176 sgCopyVec3(renderEye,
eye);
177 sgCopyVec3(renderCenter,
center);
189 const int BUFSIZE = 1024;
204 tdble dx, dy, dz, dd;
213 dd = sqrt(dx * dx + dy * dy + dz * dz);
218 res = (float)
scrh / 2.0 / dd / tan(ang);
227 const int BUFSIZE = 256;
229 const int PATHSIZE = 1024;
276 glMatrixMode(GL_PROJECTION);
283 glMatrixMode(GL_MODELVIEW);
289 static float BACKGROUND_FOVY_CUTOFF = 60.0f;
293 sgSetVec3(
eye, 0, 0, 0);
298 if (
fovy < BACKGROUND_FOVY_CUTOFF) {
299 fovy = BACKGROUND_FOVY_CUTOFF;
310 float myfovy,
float myfovymin,
float myfovymax,
311 float myfnear,
float myffar = 1500.0,
312 float myfogstart = 800.0,
float myfogend = 1500.0)
314 myfovy, myfovymin, myfovymax,
315 myfnear, myffar, myfogstart, myfogend) {
336 glDeleteTextures(1, &
tex);
352 up[0] = car->_posMat[2][0];
353 up[1] = car->_posMat[2][1];
354 up[2] = car->_posMat[2][2];
391 glBindTexture(GL_TEXTURE_2D,
tex);
392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
393 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
394 glReadBuffer(GL_BACK);
396 glCopyTexImage2D(GL_TEXTURE_2D,
414 glEnable(GL_SCISSOR_TEST);
420 glDisable(GL_SCISSOR_TEST);
422 glBindTexture(GL_TEXTURE_2D,
tex);
423 glReadBuffer(GL_BACK);
426 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
436 glBindTexture(GL_TEXTURE_2D,
tex);
437 glBegin(GL_TRIANGLE_STRIP);
439 glColor4f(1.0, 1.0, 1.0, 1.0);
455 float myfovy,
float myfovymin,
float myfovymax,
456 float myfnear,
float myffar = 1500.0,
457 float myfogstart = 1400.0,
float myfogend = 1500.0)
459 myfovy, myfovymin, myfovymax,
460 myfnear, myffar, myfogstart, myfogend) {
467 center[0] =
eye[0] + 30.0f * car->_posMat[0][0];
468 center[1] =
eye[1] + 30.0f * car->_posMat[0][1];
469 center[2] =
eye[2] + 30.0f * car->_posMat[0][2];
471 up[0] = car->_posMat[2][0];
472 up[1] = car->_posMat[2][1];
473 up[2] = car->_posMat[2][2];
500 float mydist,
float myHeight,
float fnear,
float ffar = 1500.0,
501 float myfogstart = 1400.0,
float myfogend = 1500.0)
515 const tdble yawResponseTime = 0.4f;
516 const tdble centerHeightResponseTime = 0.10f;
517 const tdble positionSpring = 45.0f;
518 const tdble velocityDamping = 10.0f;
519 const tdble maxFrameTime = 0.1f;
520 const tdble groundClearance = 0.5f;
521 const tdble lookAhead = 9.0f;
522 const tdble lookHeight = 1.3f;
523 const tdble downhillLookFactor = 0.85f;
524 const tdble downhillEyeLiftFactor = 0.35f;
525 const tdble downhillSampleAhead = 45.0f;
526 const tdble maxDownhillLookDrop = 8.0f;
527 const tdble maxDownhillEyeLift = 2.5f;
534 tdble centerHeightFactor;
537 tdble carGroundHeight;
538 tdble lookGroundDelta;
540 tdble downhillEyeLift;
545 double downhillSampleX;
546 double downhillSampleY;
550 bool resetCamera =
false;
562 if ((dt < 0.0f) || (fabs(dt) > 1.0f)) {
566 else if (dt > maxFrameTime) {
582 yawFactor = (
tdble)(1.0 - exp(-dt / yawResponseTime));
586 cosYaw = cos(carYaw);
587 sinYaw = sin(carYaw);
593 groundHeight =
grTrackHeightD(car->_trkPos.seg, targetEyeX, targetEyeY) + groundClearance;
594 if (targetEye[2] < groundHeight) {
595 targetEye[2] = groundHeight;
601 targetCenter[0] = (float)(carX + lookAhead * cosYaw -
grRenderOrigin[0]);
602 targetCenter[1] = (float)(carY + lookAhead * sinYaw -
grRenderOrigin[1]);
603 targetCenter[2] = car->_pos_Z + lookHeight;
605 downhillSampleX = carX + downhillSampleAhead * cos(trackYaw);
606 downhillSampleY = carY + downhillSampleAhead * sin(trackYaw);
608 lookGroundDelta =
grTrackHeightD(car->_trkPos.seg, downhillSampleX, downhillSampleY) - carGroundHeight;
609 if (lookGroundDelta < -maxDownhillLookDrop) {
610 lookGroundDelta = -maxDownhillLookDrop;
612 if (lookGroundDelta < 0.0f) {
613 downhillDrop = -lookGroundDelta;
614 downhillEyeLift = downhillEyeLiftFactor * downhillDrop;
615 if (downhillEyeLift > maxDownhillEyeLift) {
616 downhillEyeLift = maxDownhillEyeLift;
618 targetCenter[2] -= downhillLookFactor * downhillDrop;
619 targetEye[2] += downhillEyeLift;
622 center[0] = targetCenter[0];
623 center[1] = targetCenter[1];
625 center[2] = targetCenter[2];
628 centerHeightFactor = (
tdble)(1.0 - exp(-dt / centerHeightResponseTime));
633 eye[0] = targetEye[0];
634 eye[1] = targetEye[1];
635 eye[2] = targetEye[2];
636 speed[0] = targetSpeed[0];
637 speed[1] = targetSpeed[1];
638 speed[2] = targetSpeed[2];
640 else if (dt > 0.0f) {
641 speed[0] += (positionSpring * (targetEye[0] -
eye[0]) + velocityDamping * (targetSpeed[0] -
speed[0])) * dt;
642 speed[1] += (positionSpring * (targetEye[1] -
eye[1]) + velocityDamping * (targetSpeed[1] -
speed[1])) * dt;
643 speed[2] += (positionSpring * (targetEye[2] -
eye[2]) + velocityDamping * (targetSpeed[2] -
speed[2])) * dt;
651 if (
eye[2] < minHeight) {
653 if (
speed[2] < 0.0f) {
678 float mydist,
float fnear,
float ffar = 1500.0,
679 float myfogstart = 1400.0,
float myfogend = 1500.0)
701 if (fabs(
PreA - A) > fabs(
PreA - A + 2 *
PI)) {
704 else if (fabs(
PreA - A) > fabs(
PreA - A - 2 *
PI)) {
710 x = carX -
dist * CosA;
711 y = carY -
dist * SinA;
737 float mydist,
float fnear,
float ffar = 1500.0,
738 float myfogstart = 1400.0,
float myfogend = 1500.0)
748 tdble CosA = cos(car->_yaw);
749 tdble SinA = sin(car->_yaw);
755 double x = carX +
dist * CosA;
756 double y = carY +
dist * SinA;
783 float mydistx,
float mydisty,
float mydistz,
785 float myfogstart = 1400.0,
float myfogend = 1500.0)
824 float mydistz,
int axis,
826 float myfogstart = 1600.0,
float myfogend = 1700.0)
856 tdble x = car->_pos_X;
887 float myfogstart = 1400.0,
float myfogend = 1500.0)
904 const int PATHSIZE = 1024;
918 tdble dx, dy, dz, dd;
928 dd = sqrt(dx * dx + dy * dy + dz * dz);
953 float eyex,
float eyey,
float eyez,
954 float centerx,
float centery,
float centerz,
956 float myfogstart = 1600.0,
float myfogend = 1700.0)
1020 float myfogstart = 1400.0,
float myfogend = 1500.0)
1032 curCam = car->_trkPos.seg->cam;
1034 if (curCam == NULL) {
1071 float myfogstart = 1400.0,
float myfogend = 1500.0)
1103 bool reset_camera =
false;
1106 if (fabs(dt) > 1.0f) {
1108 reset_camera =
true;
1113 reset_camera =
true;
1123 reset_camera =
true;
1130 timer = 10.0 + (int)(5.0 * rand() / (RAND_MAX + 1.0));
1131 offset[0] = -0.5 + (rand() / (RAND_MAX + 1.0));
1132 offset[1] = -0.5 + (rand() / (RAND_MAX + 1.0));
1133 offset[2] = 10.0f + (50.0 * rand() / (RAND_MAX + 1.0)) +
zOffset;
1143 eye[0] = car->_pos_X + 50.0 + (50.0 * rand() / (RAND_MAX + 1.0));
1144 eye[1] = car->_pos_Y + 50.0 + (50.0 * rand() / (RAND_MAX + 1.0));
1145 eye[2] = car->_pos_Z + 50.0 + (50.0 * rand() / (RAND_MAX + 1.0));
1157 center[0] = (car->_pos_X);
1158 center[1] = (car->_pos_Y);
1159 center[2] = (car->_pos_Z);
1163 if (
eye[2] < height) {
1164 timer = 10.0 + (int)(10.0 * rand() / (RAND_MAX + 1.0));
1165 offset[2] = height - car->_pos_Z + 1.0;
1191 float myfogstart = 1400.0,
float myfogend = 1500.0)
1204 const int PATHSIZE = 1024;
1205 char path[PATHSIZE];
1219 tdble dx, dy, dz, dd;
1222 curCam = car->_trkPos.seg->cam;
1224 if (curCam == NULL) {
1243 dd = sqrt(dx * dx + dy * dy + dz * dz);
1265 seg = car->_trkPos.seg;
1268 switch (seg->
type) {
1270 lg += car->_trkPos.toStart;
1273 lg += car->_trkPos.toStart * seg->
radius;
1300 float myfogstart = 1400.0,
float myfogend = 1500.0)
1333 if (car == s->
cars[i]) {
1367 if ((
fs > (
grTrack->length - 200.0)) && (car->_remainingLaps == 0)) {
1374 dist = fabs(car->_trkPos.toMiddle) -
grTrack->width / 2.0;
1384 for (j = i + 1; j <
grNbCars; j++) {
1419 curPrio = -1000000.0;
1433 if (last_current !=
current) {
#define RM_CMD_PIT_ASKED
Race command: Pit asked.
#define RM_CAR_STATE_NO_SIMU
Do not simulate the car.
struct CarElt tCarElt
Car structure (tCarElt).
void update(tCarElt *car, tSituation *s)
cGrCamera(class cGrScreen *myscreen, int myid=0, int mydrawCurrent=0, int mydrawdrv=0, int mydrawBackground=0, int mymirrorAllowed=0)
virtual float getFovY(void)
void rebaseLocalRenderCoordinates(void)
int renderCoordinatesLocal
sgVec3 * getCenterv(void)
void add(tGrCamHead *head)
float getDist2(tCarElt *car)
void setLocalRenderCoordinates(void)
cGrCarCamBehind2(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float mydist, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
cGrCarCamBehind(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float mydist, float myHeight, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void onSelect(tCarElt *car, tSituation *s)
void update(tCarElt *car, tSituation *s)
cGrCarCamCenter(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float mydistz, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
void loadDefaults(char *attr)
cGrCarCamFront(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float mydist, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
void update(tCarElt *car, tSituation *s)
cGrCarCamInsideFixedCar(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float myfovy, float myfovymin, float myfovymax, float myfnear, float myffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
cGrCarCamInside(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float myfovy, float myfovymin, float myfovymax, float myfnear, float myffar=1500.0, float myfogstart=800.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
cGrCarCamLookAt(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, int axis, float eyex, float eyey, float eyez, float centerx, float centery, float centerz, float fnear, float ffar=1500.0, float myfogstart=1600.0, float myfogend=1700.0)
virtual ~cGrCarCamMirror()
void activateViewport(void)
void setViewport(int x, int y, int w, int h)
void setPos(int x, int y, int w, int h)
void update(tCarElt *car, tSituation *s)
void update(tCarElt *car, tSituation *s)
void onSelect(tCarElt *car, tSituation *s)
cGrCarCamRoadFly(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
cGrCarCamRoadNoZoom(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
cGrCarCamRoadZoom(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void loadDefaults(char *attr)
void update(tCarElt *car, tSituation *s)
cGrCarCamRoadZoomTVD(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
cGrCarCamSide(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float mydistx, float mydisty, float mydistz, float fnear, float ffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
void update(tCarElt *car, tSituation *s)
cGrCarCamUp(class cGrScreen *myscreen, int id, int drawCurr, int drawBG, float fovy, float fovymin, float fovymax, float mydistz, int axis, float fnear, float ffar=1500.0, float myfogstart=1600.0, float myfogend=1700.0)
void loadDefaults(char *attr)
float getLODFactor(float x, float y, float z)
cGrPerspCamera(class cGrScreen *myscreen, int id, int drawCurr, int drawDrv, int drawBG, int mirrorAllowed, float myfovy, float myfovymin, float myfovymax, float myfnear, float myffar=1500.0, float myfogstart=1400.0, float myfogend=1500.0)
static tdble grTrackHeightD(tTrackSeg *segment, double x, double y)
void grCamCreateSceneCameraList(class cGrScreen *myscreen, tGrCamHead *cams, tdble fovFactor)
static void grTransformCarPointToRender(const tCarElt *car, tdble x, tdble y, tdble z, sgVec3 point)
static tdble GetDistToStart(tCarElt *car)
static void grMakeLookAtMat4(sgMat4 dst, const sgVec3 eye, const sgVec3 center, const sgVec3 up)
static void grGetPreciseCarPosition(const tCarElt *car, double *x, double *y)
class cGrScreen * grScreens[GR_NB_MAX_SCREEN]
float tdble
Floating point type used in TORCS.
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
int GfParmSetNum(void *handle, const char *path, const char *key, const char *unit, tdble val)
Set a numerical parameter in the parameter set handle.
int GfParmWriteFile(const char *file, void *parmHandle, const char *name)
Write parameter set into file.
void GfScrShutdown(void)
Shutdown the screen.
void GfScrGetSize(int *scrw, int *scrh, int *vieww, int *viewh)
Get the screen and viewport sizes.
#define GF_TAILQ_INIT(head)
Head initialization (Mandatory)
struct trackSeg tTrackSeg
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
float grGetHOT(float x, float y)
struct Situation tSituation
cars situation used to inform the GUI and the drivers
tCarElt ** cars
list of cars
double currentTime
current time in sec since the beginning of the simulation
int raceCmd
command issued by the driver
int collision
Collision value for graphics and sound, clearing is managed by consumers.
tDynPt DynGCg
GC data (world axis)
Location on the track in local coordinates.
int type
Geometrical type:
tdble radius
Radius in meters of the middle of the track (>0)
tdble lgfromstart
Length of beginning of segment from starting line.
#define DEG2RAD(x)
Degree to radian conversion.
#define RAD2DEG(x)
Radian to degree conversion.
#define TR_LPOS_SEGMENT
Relative to the segment which the point is located, including border and sides, mostly used for conta...
struct RoadCam tRoadCam
road camera