class RScene | .h |
constructor | RScene() |
destructor | ~RScene() |
Reset | void Reset() Prepare for filling information into this scene |
RemoveCars | void RemoveCars() |
AddCar | bool AddCar(RCar *newCar) |
SetTrack | void SetTrack(RTrack *trk) Set a track (mostly a derived class of RTrack) |
SetView | void SetView(int x,int y,int wid,int hgt) Set scene viewport (in the current graphics context) |
SetDefaultState | void SetDefaultState() Set some OpenGL state variable that we like to use as a default |
Clear | void Clear() Do a default clear of the view Note this may be skipped if you know you're going to paint all over the viewport |
Paint | void Paint() Paint track & cars |
TimeLineCrossed | void TimeLineCrossed(RCar *car) A car has crossed its current timeline (checkpoint). Adjust statistics for this car. |
GetCurrentLapTime | int GetCurrentLapTime(RCar *car) Returns live current lap time for the car This is updated as the car is driving the lap |
GetBestLapTime | int GetBestLapTime(RCar *car) Returns best lap time for the car, or 0 for none. |
/*
* RScene - a scene contains the track and vehicles
* 05-10-00: Created!
* BUGS:
* - Doesn't keep a bound for the #laps (lapTime[])
* (c) Dolphinity/Ruud van Gaal
*/
#include <racer/racer.h>
#include <qlib/debug.h>
#pragma hdrstop
DEBUG_ENABLE
#undef DBG_CLASS
#define DBG_CLASS "RScene"
RScene::RScene()
{
DBG_C("ctor")
int i;
env=0;
track=0;
cars=0;
}
RScene::~RScene()
{
DBG_C("dtor")
int i;
// Track is deleted by RMGR, don't delete here
if(env)delete env;
//if(track)delete track;
RemoveCars();
}
/********
* Reset *
********/
void RScene::Reset()
// Prepare for filling information into this scene
{
int i,j;
RemoveCars();
// Reset timing statistics
for(i=0;i<MAX_CAR;i++)
{
curTimeLine[i]=0;
bestLapTime[i]=0;
for(j=0;j<MAX_LAP;j++)
{
lapTime[i][j]=0;
}
for(j=0;j<RTrackVRML::MAX_TIMELINE;j++)
{
tlTime[i][j]=0;
}
// No lap started yet
curLap[i]=-1;
}
}
/*******
* CARS *
*******/
void RScene::RemoveCars()
{
int i;
for(i=0;i<cars;i++)
if(car[i])
{ delete car[i];
car[i]=0;
}
cars=0;
}
bool RScene::AddCar(RCar *newCar)
{
DBG_C("AddCar")
DBG_ARG_P(newCar)
if(cars==MAX_CAR)
{ qwarn("Too many cars in scene");
return FALSE;
}
car[cars]=newCar;
// Make sure the car knows its place in the scene
car[cars]->SetIndex(cars);
cars++;
return TRUE;
}
/********
* TRACK *
********/
void RScene::SetTrack(RTrack *trk)
// Set a track (mostly a derived class of RTrack)
{
DBG_C("SetTrack")
DBG_ARG_P(trk)
track=trk;
}
/***********
* Painting *
***********/
void RScene::SetView(int x,int y,int wid,int hgt)
// Set scene viewport (in the current graphics context)
{
DBG_C("SetView")
DBG_ARG_I(x)
DBG_ARG_I(y)
DBG_ARG_I(wid)
DBG_ARG_I(hgt)
glViewport(x,y,wid,hgt);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0,(GLfloat)wid/(GLfloat)hgt,1.0,1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void RScene::SetDefaultState()
// Set some OpenGL state variable that we like to use as a default
{
glClearColor(.2,.3,.4,0);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
}
void RScene::Clear()
// Do a default clear of the view
// Note this may be skipped if you know you're going to paint all over the viewport
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}
void RScene::Paint()
// Paint track & cars
{
DBG_C("Paint")
int i;
#ifdef OBS
{
static int roll;
glRotatef(roll,0,1,0);
roll++;
}
#endif
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
if(track)
track->Paint();
for(i=0;i<MAX_CAR;i++)
{
if(car[i])
car[i]->Paint();
}
}
/********************
* Timing statistics *
********************/
void RScene::TimeLineCrossed(RCar *car)
// A car has crossed its current timeline (checkpoint).
// Adjust statistics for this car.
{
int i,n=car->GetIndex();
int lap;
// Check for bad tracks
if(!track->GetTimeLines())return;
// Store intermediate time
if(curTimeLine[n]==0)
{
// Start/finish!
if(curLap[n]==-1)
{
// Just starting the first lap
curLap[n]++;
// Store lap start time in lap time variable
lapTime[n][0]=RMGR->time->GetSimTime();
} else
{
// Finished a lap
lap=curLap[n];
// The start time of this lap was stored in curLapTime[...]
lapTime[n][lap]=RMGR->time->GetSimTime()-lapTime[n][lap];
if(bestLapTime[n]==0||lapTime[n][lap]<bestLapTime[n])
{
// You've got a best lap!
bestLapTime[n]=lapTime[n][lap];
}
// Store start time of next lap
lapTime[n][lap+1]=RMGR->time->GetSimTime();
// Reset intermediate times
for(i=0;i<RTrack::MAX_TIMELINE;i++)
{
tlTime[n][i]=0;
}
curLap[n]++;
}
}
// Switch to next checkpoint timeline
curTimeLine[n]=(curTimeLine[n]+1)%track->GetTimeLines();
}
int RScene::GetCurrentLapTime(RCar *car)
// Returns live current lap time for the car
// This is updated as the car is driving the lap
{
int n=car->GetIndex();
// Doing a lap already?
if(curLap[n]==-1)return 0;
// Calculate the time the car is busy in the current lap
return RMGR->time->GetSimTime()-lapTime[n][curLap[n]];
}
int RScene::GetBestLapTime(RCar *car)
// Returns best lap time for the car, or 0 for none.
{
return bestLapTime[car->GetIndex()];
}