Made QuadGraph use a singleton-like behaviour. It is still created with
explicit calls to QuadGraph::create(...), and the get() function can return NULL (in case of a race mode that does not use a quad graph). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9421 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
7b5160be59
commit
428ed5a07b
@ -48,13 +48,12 @@ RubberBall::RubberBall(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_RUBBE
|
||||
computeTarget();
|
||||
|
||||
const LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
m_quad_graph = &(world->getTrack()->getQuadGraph());
|
||||
m_current_graph_node = world->getSectorForKart(kart->getWorldKartId());
|
||||
|
||||
// Determine distance along track
|
||||
Vec3 ball_distance_vec;
|
||||
m_quad_graph->spatialToTrack(&ball_distance_vec, getXYZ(),
|
||||
m_current_graph_node);
|
||||
QuadGraph::get()->spatialToTrack(&ball_distance_vec, getXYZ(),
|
||||
m_current_graph_node);
|
||||
m_distance_along_track = ball_distance_vec[2];
|
||||
|
||||
// We have to start aiming at the next sector (since it might be possible
|
||||
@ -62,14 +61,14 @@ RubberBall::RubberBall(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_RUBBE
|
||||
m_aimed_graph_node = getSuccessorToHitTarget(m_current_graph_node);
|
||||
|
||||
// Get 4 points for the interpolation
|
||||
int pred = m_quad_graph->getNode(m_current_graph_node)
|
||||
int pred = QuadGraph::get()->getNode(m_current_graph_node)
|
||||
.getPredecessor();
|
||||
m_aiming_points[0] = m_quad_graph->getQuad(pred).getCenter();
|
||||
m_aiming_points[1] = m_quad_graph->getQuad(m_current_graph_node)
|
||||
m_aiming_points[0] = QuadGraph::get()->getQuadOfNode(pred).getCenter();
|
||||
m_aiming_points[1] = QuadGraph::get()->getQuadOfNode(m_current_graph_node)
|
||||
.getCenter();
|
||||
m_aiming_points[2] = m_quad_graph->getQuad(m_aimed_graph_node).getCenter();
|
||||
m_aiming_points[2] = QuadGraph::get()->getQuadOfNode(m_aimed_graph_node).getCenter();
|
||||
int succ_succ = getSuccessorToHitTarget(m_aimed_graph_node);
|
||||
m_aiming_points[3] = m_quad_graph->getQuad(succ_succ).getCenter();
|
||||
m_aiming_points[3] = QuadGraph::get()->getQuadOfNode(succ_succ).getCenter();
|
||||
m_t = 0;
|
||||
m_t_increase = 1.0f/(m_aiming_points[2]-m_aiming_points[1]).length();
|
||||
|
||||
@ -116,7 +115,7 @@ void RubberBall::computeTarget()
|
||||
unsigned int RubberBall::getSuccessorToHitTarget(unsigned int node_index)
|
||||
{
|
||||
// For now: always pick a successor on the main driveline.
|
||||
return m_quad_graph->getNode(node_index).getSuccessor(0);
|
||||
return QuadGraph::get()->getNode(node_index).getSuccessor(0);
|
||||
} // getSuccessorToHitTarget
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -170,20 +169,18 @@ void RubberBall::update(float dt)
|
||||
// FIXME: use interpolation here for smooth curves
|
||||
Vec3 next_xyz = getXYZ() + delta * (m_speed * dt / delta.length());
|
||||
|
||||
GraphNode &gn = m_quad_graph->getNode(m_current_graph_node);
|
||||
int indx = getSuccessorToHitTarget(m_current_graph_node);
|
||||
GraphNode &gn_next = m_quad_graph->getNode(indx);
|
||||
|
||||
// Determine new distance along track
|
||||
Vec3 ball_distance_vec;
|
||||
m_quad_graph->findRoadSector(next_xyz, &m_current_graph_node);
|
||||
QuadGraph::get()->findRoadSector(next_xyz, &m_current_graph_node);
|
||||
if(m_current_graph_node == QuadGraph::UNKNOWN_SECTOR)
|
||||
{
|
||||
m_current_graph_node =
|
||||
m_quad_graph->findOutOfRoadSector(next_xyz,
|
||||
QuadGraph::get()->findOutOfRoadSector(next_xyz,
|
||||
QuadGraph::UNKNOWN_SECTOR );
|
||||
}
|
||||
m_quad_graph->spatialToTrack(&ball_distance_vec, getXYZ(),
|
||||
QuadGraph::get()->spatialToTrack(&ball_distance_vec, getXYZ(),
|
||||
m_current_graph_node);
|
||||
|
||||
// Detect wrap around, i.e. crossing the start line
|
||||
@ -290,7 +287,7 @@ void RubberBall::determineTargetCoordinates(float dt, Vec3 *aim_xyz)
|
||||
|
||||
// Aiming at a graph node
|
||||
// ----------------------
|
||||
GraphNode *gn = &(m_quad_graph->getNode(m_aimed_graph_node));
|
||||
GraphNode *gn = &(QuadGraph::get()->getNode(m_aimed_graph_node));
|
||||
|
||||
// At this stage m_distance_along track is already the new distance (set
|
||||
// in the previous time step when aiming). It has to be detected if the
|
||||
@ -334,7 +331,7 @@ void RubberBall::determineTargetCoordinates(float dt, Vec3 *aim_xyz)
|
||||
|
||||
// FIXME: aim better if necessary!
|
||||
m_aimed_graph_node = getSuccessorToHitTarget(m_aimed_graph_node);
|
||||
gn = &(m_quad_graph->getNode(m_aimed_graph_node));
|
||||
gn = &(QuadGraph::get()->getNode(m_aimed_graph_node));
|
||||
m_aiming_points[3] = gn->getQuad().getCenter();
|
||||
|
||||
// Detect a wrap around of the graph node. We could just test if
|
||||
|
@ -88,9 +88,6 @@ private:
|
||||
* used to keep track of the state of this ball. */
|
||||
bool m_aiming_at_target;
|
||||
|
||||
/** For convenience keep a pointer to the quad graph. */
|
||||
QuadGraph *m_quad_graph;
|
||||
|
||||
void computeTarget();
|
||||
void determineTargetCoordinates(float dt, Vec3 *aim_xyz);
|
||||
unsigned int getSuccessorToHitTarget(unsigned int node_index);
|
||||
|
@ -39,7 +39,6 @@ AIBaseController::AIBaseController(Kart *kart,
|
||||
{
|
||||
m_world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
m_track = m_world->getTrack();
|
||||
m_quad_graph = &m_track->getQuadGraph();
|
||||
computePath();
|
||||
}
|
||||
else
|
||||
@ -48,7 +47,6 @@ AIBaseController::AIBaseController(Kart *kart,
|
||||
// a linear world, since it assumes the existance of drivelines)
|
||||
m_world = NULL;
|
||||
m_track = NULL;
|
||||
m_quad_graph = NULL;
|
||||
m_next_node_index.clear();
|
||||
m_all_look_aheads.clear();
|
||||
m_successor_index.clear();
|
||||
@ -73,15 +71,14 @@ void AIBaseController::newLap(int lap)
|
||||
*/
|
||||
void AIBaseController::computePath()
|
||||
{
|
||||
|
||||
m_next_node_index.resize(m_quad_graph->getNumNodes());
|
||||
m_successor_index.resize(m_quad_graph->getNumNodes());
|
||||
m_next_node_index.resize(QuadGraph::get()->getNumNodes());
|
||||
m_successor_index.resize(QuadGraph::get()->getNumNodes());
|
||||
std::vector<unsigned int> next;
|
||||
for(unsigned int i=0; i<m_quad_graph->getNumNodes(); i++)
|
||||
for(unsigned int i=0; i<QuadGraph::get()->getNumNodes(); i++)
|
||||
{
|
||||
next.clear();
|
||||
// Get all successors the AI is allowed to take.
|
||||
m_quad_graph->getSuccessors(i, next, /*for_ai*/true);
|
||||
QuadGraph::get()->getSuccessors(i, next, /*for_ai*/true);
|
||||
// For now pick one part on random, which is not adjusted during the
|
||||
// race. Long term statistics might be gathered to determine the
|
||||
// best way, potentially depending on race position etc.
|
||||
@ -102,8 +99,8 @@ void AIBaseController::computePath()
|
||||
// find too good a driveline. Note that in general this list should
|
||||
// be computed recursively, but since the AI for now is using only
|
||||
// (randomly picked) path this is fine
|
||||
m_all_look_aheads.resize(m_quad_graph->getNumNodes());
|
||||
for(unsigned int i=0; i<m_quad_graph->getNumNodes(); i++)
|
||||
m_all_look_aheads.resize(QuadGraph::get()->getNumNodes());
|
||||
for(unsigned int i=0; i<QuadGraph::get()->getNumNodes(); i++)
|
||||
{
|
||||
std::vector<int> l;
|
||||
int current = i;
|
||||
@ -121,20 +118,20 @@ void AIBaseController::update(float dt)
|
||||
{
|
||||
Controller::update(dt);
|
||||
|
||||
if(m_quad_graph)
|
||||
if(QuadGraph::get())
|
||||
{
|
||||
// Update the current node:
|
||||
int old_node = m_track_node;
|
||||
if(m_track_node!=QuadGraph::UNKNOWN_SECTOR)
|
||||
{
|
||||
m_quad_graph->findRoadSector(m_kart->getXYZ(), &m_track_node,
|
||||
QuadGraph::get()->findRoadSector(m_kart->getXYZ(), &m_track_node,
|
||||
&m_all_look_aheads[m_track_node]);
|
||||
}
|
||||
// If we can't find a proper place on the track, to a broader search
|
||||
// on off-track locations.
|
||||
if(m_track_node==QuadGraph::UNKNOWN_SECTOR)
|
||||
{
|
||||
m_track_node = m_quad_graph->findOutOfRoadSector(m_kart->getXYZ());
|
||||
m_track_node = QuadGraph::get()->findOutOfRoadSector(m_kart->getXYZ());
|
||||
}
|
||||
// IF the AI is off track (or on a branch of the track it did not
|
||||
// select to be on), keep the old position.
|
||||
@ -155,7 +152,7 @@ void AIBaseController::update(float dt)
|
||||
unsigned int AIBaseController::getNextSector(unsigned int index)
|
||||
{
|
||||
std::vector<unsigned int> successors;
|
||||
m_quad_graph->getSuccessors(index, successors);
|
||||
QuadGraph::get()->getSuccessors(index, successors);
|
||||
return successors[0];
|
||||
} // getNextSector
|
||||
|
||||
@ -167,7 +164,8 @@ unsigned int AIBaseController::getNextSector(unsigned int index)
|
||||
float AIBaseController::steerToAngle(const unsigned int sector,
|
||||
const float add_angle)
|
||||
{
|
||||
float angle = m_quad_graph->getAngleToNext(sector, getNextSector(sector));
|
||||
float angle = QuadGraph::get()->getAngleToNext(sector,
|
||||
getNextSector(sector));
|
||||
|
||||
//Desired angle minus current angle equals how many angles to turn
|
||||
float steer_angle = angle - m_kart->getHeading();
|
||||
|
@ -52,9 +52,6 @@ protected:
|
||||
/** Keep a pointer to world. */
|
||||
LinearWorld *m_world;
|
||||
|
||||
/** The graph of qudas of this track. */
|
||||
const QuadGraph *m_quad_graph;
|
||||
|
||||
/** The current node the kart is on. This can be different from the value
|
||||
* in LinearWorld, since it takes the chosen path of the AI into account
|
||||
* (e.g. the closest point in LinearWorld might be on a branch not
|
||||
|
@ -49,7 +49,6 @@
|
||||
|
||||
DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart)
|
||||
{
|
||||
// Reset must be called after m_quad_graph etc. is set up
|
||||
reset();
|
||||
|
||||
switch( race_manager->getDifficulty())
|
||||
@ -132,12 +131,14 @@ void DefaultAIController::reset()
|
||||
|
||||
AIBaseController::reset();
|
||||
m_track_node = QuadGraph::UNKNOWN_SECTOR;
|
||||
m_quad_graph->findRoadSector(m_kart->getXYZ(), &m_track_node);
|
||||
QuadGraph::get()->findRoadSector(m_kart->getXYZ(), &m_track_node);
|
||||
if(m_track_node==QuadGraph::UNKNOWN_SECTOR)
|
||||
{
|
||||
fprintf(stderr, "Invalid starting position for '%s' - not on track - can be ignored.\n",
|
||||
fprintf(stderr,
|
||||
"Invalid starting position for '%s' - not on track"
|
||||
" - can be ignored.\n",
|
||||
m_kart->getIdent().c_str());
|
||||
m_track_node = m_quad_graph->findOutOfRoadSector(m_kart->getXYZ());
|
||||
m_track_node = QuadGraph::get()->findOutOfRoadSector(m_kart->getXYZ());
|
||||
}
|
||||
|
||||
} // reset
|
||||
@ -287,7 +288,7 @@ void DefaultAIController::handleBraking()
|
||||
m_world->isOnRoad(m_kart->getWorldKartId()) )
|
||||
{
|
||||
float kart_ang_diff =
|
||||
m_quad_graph->getAngleToNext(m_track_node,
|
||||
QuadGraph::get()->getAngleToNext(m_track_node,
|
||||
m_successor_index[m_track_node])
|
||||
- m_kart->getHeading();
|
||||
kart_ang_diff = normalizeAngle(kart_ang_diff);
|
||||
@ -307,8 +308,9 @@ void DefaultAIController::handleBraking()
|
||||
//even if we are in the inside, because the kart would be 'thrown'
|
||||
//out of the curve.
|
||||
if(!(m_world->getDistanceToCenterForKart(m_kart->getWorldKartId())
|
||||
> m_quad_graph->getNode(m_track_node).getPathWidth() *
|
||||
-CURVE_INSIDE_PERC || m_curve_angle > RAD_TO_DEGREE*m_kart->getMaxSteerAngle()))
|
||||
> QuadGraph::get()->getNode(m_track_node).getPathWidth() *
|
||||
-CURVE_INSIDE_PERC ||
|
||||
m_curve_angle > RAD_TO_DEGREE*m_kart->getMaxSteerAngle()) )
|
||||
{
|
||||
m_controls->m_brake = false;
|
||||
return;
|
||||
@ -317,8 +319,9 @@ void DefaultAIController::handleBraking()
|
||||
else if( m_curve_angle < -MIN_TRACK_ANGLE ) //Next curve is right
|
||||
{
|
||||
if(!(m_world->getDistanceToCenterForKart( m_kart->getWorldKartId() )
|
||||
< m_quad_graph->getNode(m_track_node).getPathWidth() *
|
||||
CURVE_INSIDE_PERC || m_curve_angle < -RAD_TO_DEGREE*m_kart->getMaxSteerAngle()))
|
||||
< QuadGraph::get()->getNode(m_track_node).getPathWidth() *
|
||||
CURVE_INSIDE_PERC ||
|
||||
m_curve_angle < -RAD_TO_DEGREE*m_kart->getMaxSteerAngle()))
|
||||
{
|
||||
m_controls->m_brake = false;
|
||||
return;
|
||||
@ -355,12 +358,14 @@ void DefaultAIController::handleSteering(float dt)
|
||||
*/
|
||||
//Reaction to being outside of the road
|
||||
if( fabsf(m_world->getDistanceToCenterForKart( m_kart->getWorldKartId() )) >
|
||||
0.5f* m_quad_graph->getNode(m_track_node).getPathWidth()+0.5f )
|
||||
0.5f* QuadGraph::get()->getNode(m_track_node).getPathWidth()+0.5f )
|
||||
{
|
||||
steer_angle = steerToPoint(m_quad_graph->getQuad(next).getCenter());
|
||||
steer_angle = steerToPoint(QuadGraph::get()->getQuadOfNode(next)
|
||||
.getCenter());
|
||||
|
||||
#ifdef AI_DEBUG
|
||||
m_debug_sphere->setPosition(m_quad_graph->getQuad(next).getCenter().toIrrVector());
|
||||
m_debug_sphere->setPosition(QuadGraph::get()->getQuad(next)
|
||||
.getCenter().toIrrVector());
|
||||
std::cout << "- Outside of road: steer to center point." <<
|
||||
std::endl;
|
||||
#endif
|
||||
@ -886,7 +891,7 @@ void DefaultAIController::checkCrashes(int steps, const Vec3& pos )
|
||||
/*Find if we crash with the drivelines*/
|
||||
if(current_node!=QuadGraph::UNKNOWN_SECTOR &&
|
||||
m_next_node_index[current_node]!=-1)
|
||||
m_quad_graph->findRoadSector(step_coord, ¤t_node,
|
||||
QuadGraph::get()->findRoadSector(step_coord, ¤t_node,
|
||||
/* sectors to test*/ &m_all_look_aheads[current_node]);
|
||||
|
||||
if( current_node == QuadGraph::UNKNOWN_SECTOR)
|
||||
@ -921,7 +926,7 @@ void DefaultAIController::findNonCrashingPoint(Vec3 *result)
|
||||
target_sector = m_next_node_index[sector];
|
||||
|
||||
//direction is a vector from our kart to the sectors we are testing
|
||||
direction = m_quad_graph->getQuad(target_sector).getCenter()
|
||||
direction = QuadGraph::get()->getQuadOfNode(target_sector).getCenter()
|
||||
- m_kart->getXYZ();
|
||||
|
||||
float len=direction.length_2d();
|
||||
@ -944,22 +949,22 @@ void DefaultAIController::findNonCrashingPoint(Vec3 *result)
|
||||
{
|
||||
step_coord = m_kart->getXYZ()+direction*m_kart_length * float(i);
|
||||
|
||||
m_quad_graph->spatialToTrack(&step_track_coord, step_coord,
|
||||
sector );
|
||||
QuadGraph::get()->spatialToTrack(&step_track_coord, step_coord,
|
||||
sector );
|
||||
|
||||
float distance = fabsf(step_track_coord[0]);
|
||||
|
||||
//If we are outside, the previous sector is what we are looking for
|
||||
if ( distance + m_kart_width * 0.5f
|
||||
> m_quad_graph->getNode(sector).getPathWidth() )
|
||||
> QuadGraph::get()->getNode(sector).getPathWidth() )
|
||||
{
|
||||
*result = m_quad_graph->getQuad(sector).getCenter();
|
||||
*result = QuadGraph::get()->getQuadOfNode(sector).getCenter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
sector = target_sector;
|
||||
} // for i<100
|
||||
*result = m_quad_graph->getQuad(sector).getCenter();
|
||||
*result = QuadGraph::get()->getQuadOfNode(sector).getCenter();
|
||||
} // findNonCrashingPoint
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -982,7 +987,7 @@ int DefaultAIController::calcSteps()
|
||||
if( fabsf(m_controls->m_steer) > 0.95 )
|
||||
{
|
||||
const int WIDTH_STEPS =
|
||||
(int)( m_quad_graph->getNode(m_future_sector).getPathWidth()
|
||||
(int)( QuadGraph::get()->getNode(m_future_sector).getPathWidth()
|
||||
/( m_kart_length * 2.0 ) );
|
||||
|
||||
steps += WIDTH_STEPS;
|
||||
@ -1007,14 +1012,16 @@ void DefaultAIController::findCurve()
|
||||
for(i = m_track_node; total_dist < m_kart->getVelocityLC().getZ();
|
||||
i = m_next_node_index[i])
|
||||
{
|
||||
total_dist += m_quad_graph->getDistanceToNext(i, m_successor_index[i]);
|
||||
total_dist += QuadGraph::get()->getDistanceToNext(i,
|
||||
m_successor_index[i]);
|
||||
}
|
||||
|
||||
|
||||
m_curve_angle =
|
||||
normalizeAngle(m_quad_graph->getAngleToNext(i, m_successor_index[i])
|
||||
-m_quad_graph->getAngleToNext(m_track_node,
|
||||
m_successor_index[m_track_node]) );
|
||||
normalizeAngle(QuadGraph::get()->getAngleToNext(i,
|
||||
m_successor_index[i])
|
||||
-QuadGraph::get()->getAngleToNext(m_track_node,
|
||||
m_successor_index[m_track_node]) );
|
||||
|
||||
m_curve_target_speed = m_kart->getCurrentMaxSpeed();
|
||||
} // findCurve
|
||||
|
@ -56,14 +56,14 @@ EndController::EndController(Kart *kart, StateManager::ActivePlayer *player)
|
||||
// with a path that always picks the first branch (i.e. it follows
|
||||
// the main driveline).
|
||||
std::vector<unsigned int> next;
|
||||
for(unsigned int i=0; i<m_quad_graph->getNumNodes(); i++)
|
||||
for(unsigned int i=0; i<QuadGraph::get()->getNumNodes(); i++)
|
||||
{
|
||||
// 0 is always a valid successor - so even if the kart should end
|
||||
// up by accident on a non-selected path, it will keep on working.
|
||||
m_successor_index[i] = 0;
|
||||
|
||||
next.clear();
|
||||
m_quad_graph->getSuccessors(i, next);
|
||||
QuadGraph::get()->getSuccessors(i, next);
|
||||
m_next_node_index[i] = next[0];
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ EndController::EndController(Kart *kart, StateManager::ActivePlayer *player)
|
||||
// find too good a driveline. Note that in general this list should
|
||||
// be computed recursively, but since the AI for now is using only
|
||||
// (randomly picked) path this is fine
|
||||
for(unsigned int i=0; i<m_quad_graph->getNumNodes(); i++)
|
||||
for(unsigned int i=0; i<QuadGraph::get()->getNumNodes(); i++)
|
||||
{
|
||||
std::vector<int> l;
|
||||
int current = i;
|
||||
@ -88,7 +88,7 @@ EndController::EndController(Kart *kart, StateManager::ActivePlayer *player)
|
||||
}
|
||||
} // if not battle mode
|
||||
|
||||
// Reset must be called after m_quad_graph etc. is set up
|
||||
// Reset must be called after QuadGraph::get() etc. is set up
|
||||
reset();
|
||||
|
||||
m_max_handicap_accel = 1.0f;
|
||||
@ -122,15 +122,15 @@ void EndController::reset()
|
||||
|
||||
m_track_node = QuadGraph::UNKNOWN_SECTOR;
|
||||
// In battle mode there is no quad graph, so nothing to do in this case
|
||||
if(m_quad_graph)
|
||||
if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES)
|
||||
{
|
||||
m_quad_graph->findRoadSector(m_kart->getXYZ(), &m_track_node);
|
||||
QuadGraph::get()->findRoadSector(m_kart->getXYZ(), &m_track_node);
|
||||
|
||||
// Node that this can happen quite easily, e.g. an AI kart is
|
||||
// taken over by the end controller while it is off track.
|
||||
if(m_track_node==QuadGraph::UNKNOWN_SECTOR)
|
||||
{
|
||||
m_track_node = m_quad_graph->findOutOfRoadSector(m_kart->getXYZ());
|
||||
m_track_node = QuadGraph::get()->findOutOfRoadSector(m_kart->getXYZ());
|
||||
}
|
||||
}
|
||||
} // reset
|
||||
@ -187,10 +187,10 @@ void EndController::handleSteering(float dt)
|
||||
*/
|
||||
//Reaction to being outside of the road
|
||||
if( fabsf(m_world->getDistanceToCenterForKart( m_kart->getWorldKartId() )) >
|
||||
0.5f* m_quad_graph->getNode(m_track_node).getPathWidth()+0.5f )
|
||||
0.5f* QuadGraph::get()->getNode(m_track_node).getPathWidth()+0.5f )
|
||||
{
|
||||
const int next = m_next_node_index[m_track_node];
|
||||
target_point = m_quad_graph->getQuad(next).getCenter();
|
||||
target_point = QuadGraph::get()->getQuadOfNode(next).getCenter();
|
||||
#ifdef AI_DEBUG
|
||||
std::cout << "- Outside of road: steer to center point." <<
|
||||
std::endl;
|
||||
@ -251,7 +251,8 @@ void EndController::findNonCrashingPoint(Vec3 *result)
|
||||
target_sector = m_next_node_index[sector];
|
||||
|
||||
//direction is a vector from our kart to the sectors we are testing
|
||||
direction = m_quad_graph->getQuad(target_sector).getCenter() - m_kart->getXYZ();
|
||||
direction = QuadGraph::get()->getQuadOfNode(target_sector).getCenter()
|
||||
- m_kart->getXYZ();
|
||||
|
||||
float len=direction.length_2d();
|
||||
steps = int( len / m_kart_length );
|
||||
@ -268,16 +269,16 @@ void EndController::findNonCrashingPoint(Vec3 *result)
|
||||
{
|
||||
step_coord = m_kart->getXYZ()+direction*m_kart_length * float(i);
|
||||
|
||||
m_quad_graph->spatialToTrack(&step_track_coord, step_coord,
|
||||
QuadGraph::get()->spatialToTrack(&step_track_coord, step_coord,
|
||||
sector );
|
||||
|
||||
distance = fabsf(step_track_coord[0]);
|
||||
|
||||
//If we are outside, the previous sector is what we are looking for
|
||||
if ( distance + m_kart_width * 0.5f
|
||||
> m_quad_graph->getNode(sector).getPathWidth() )
|
||||
> QuadGraph::get()->getNode(sector).getPathWidth() )
|
||||
{
|
||||
*result = m_quad_graph->getQuad(sector).getCenter();
|
||||
*result = QuadGraph::get()->getQuadOfNode(sector).getCenter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
NewAIController::NewAIController(Kart *kart) : AIBaseController(kart)
|
||||
{
|
||||
// Reset must be called after m_quad_graph etc. is set up
|
||||
// Reset must be called after QuadGraph::get() etc. is set up
|
||||
reset();
|
||||
|
||||
switch( race_manager->getDifficulty())
|
||||
@ -227,7 +227,7 @@ void NewAIController::handleBraking()
|
||||
m_world->isOnRoad(m_kart->getWorldKartId()) )
|
||||
{
|
||||
float kart_ang_diff =
|
||||
m_quad_graph->getAngleToNext(m_track_node,
|
||||
QuadGraph::get()->getAngleToNext(m_track_node,
|
||||
m_successor_index[m_track_node])
|
||||
- m_kart->getHeading();
|
||||
kart_ang_diff = normalizeAngle(kart_ang_diff);
|
||||
@ -244,7 +244,7 @@ void NewAIController::handleBraking()
|
||||
//even if we are in the inside, because the kart would be 'thrown'
|
||||
//out of the curve.
|
||||
if(!(m_world->getDistanceToCenterForKart(m_kart->getWorldKartId())
|
||||
> m_quad_graph->getNode(m_track_node).getPathWidth() *
|
||||
> QuadGraph::get()->getNode(m_track_node).getPathWidth() *
|
||||
-CURVE_INSIDE_PERC || m_curve_angle > RAD_TO_DEGREE*m_kart->getMaxSteerAngle()))
|
||||
{
|
||||
m_controls->m_brake = false;
|
||||
@ -254,7 +254,7 @@ void NewAIController::handleBraking()
|
||||
else if( m_curve_angle < -MIN_TRACK_ANGLE ) //Next curve is right
|
||||
{
|
||||
if(!(m_world->getDistanceToCenterForKart( m_kart->getWorldKartId() )
|
||||
< m_quad_graph->getNode(m_track_node).getPathWidth() *
|
||||
< QuadGraph::get()->getNode(m_track_node).getPathWidth() *
|
||||
CURVE_INSIDE_PERC || m_curve_angle < -RAD_TO_DEGREE*m_kart->getMaxSteerAngle()))
|
||||
{
|
||||
m_controls->m_brake = false;
|
||||
@ -292,7 +292,7 @@ void NewAIController::handleSteering(float dt)
|
||||
*/
|
||||
//Reaction to being outside of the road
|
||||
if( fabsf(m_world->getDistanceToCenterForKart( m_kart->getWorldKartId() )) >
|
||||
0.5f* m_quad_graph->getNode(m_track_node).getPathWidth()+1.0f )
|
||||
0.5f* QuadGraph::get()->getNode(m_track_node).getPathWidth()+1.0f )
|
||||
{
|
||||
steer_angle = steerToPoint(m_last_target_point);
|
||||
|
||||
@ -723,7 +723,7 @@ void NewAIController::checkCrashes( const int STEPS, const Vec3& pos )
|
||||
/*Find if we crash with the drivelines*/
|
||||
if(current_node!=QuadGraph::UNKNOWN_SECTOR &&
|
||||
m_next_node_index[current_node]!=-1)
|
||||
m_quad_graph->findRoadSector(step_coord, ¤t_node,
|
||||
QuadGraph::get()->findRoadSector(step_coord, ¤t_node,
|
||||
/* sectors to test*/ &m_all_look_aheads[current_node]);
|
||||
|
||||
if( current_node == QuadGraph::UNKNOWN_SECTOR)
|
||||
@ -739,7 +739,7 @@ float NewAIController::findNonCrashingAngle()
|
||||
{
|
||||
unsigned int current_sector = m_next_node_index[m_track_node];
|
||||
const Vec3 &xyz = m_kart->getXYZ();
|
||||
const Quad &q = m_quad_graph->getQuad(current_sector);
|
||||
const Quad &q = QuadGraph::get()->getQuadOfNode(current_sector);
|
||||
const Vec3 &right = q[2];
|
||||
const Vec3 &left = q[3];
|
||||
Vec3 final_right = q[2];
|
||||
@ -763,7 +763,7 @@ float NewAIController::findNonCrashingAngle()
|
||||
|
||||
while(dist<40.0f)
|
||||
{
|
||||
const Quad &q = m_quad_graph->getQuad(current_sector);
|
||||
const Quad &q = QuadGraph::get()->getQuadOfNode(current_sector);
|
||||
const Vec3 &right = q[2];
|
||||
const Vec3 &left = q[3];
|
||||
|
||||
@ -794,7 +794,7 @@ float NewAIController::findNonCrashingAngle()
|
||||
very_right = angle_right;
|
||||
final_right = right;
|
||||
}
|
||||
dist += m_quad_graph->getDistanceToNext(current_sector,
|
||||
dist += QuadGraph::get()->getDistanceToNext(current_sector,
|
||||
m_successor_index[current_sector]);
|
||||
current_sector = m_next_node_index[current_sector];
|
||||
}
|
||||
@ -825,12 +825,12 @@ void NewAIController::reset()
|
||||
m_distance_behind = 0.0f;
|
||||
m_track_node = QuadGraph::UNKNOWN_SECTOR;
|
||||
AIBaseController::reset();
|
||||
m_quad_graph->findRoadSector(m_kart->getXYZ(), &m_track_node);
|
||||
QuadGraph::get()->findRoadSector(m_kart->getXYZ(), &m_track_node);
|
||||
if(m_track_node==QuadGraph::UNKNOWN_SECTOR)
|
||||
{
|
||||
fprintf(stderr, "Invalid starting position for '%s' - not on track - can be ignored.\n",
|
||||
m_kart->getIdent().c_str());
|
||||
m_track_node = m_quad_graph->findOutOfRoadSector(m_kart->getXYZ());
|
||||
m_track_node = QuadGraph::get()->findOutOfRoadSector(m_kart->getXYZ());
|
||||
}
|
||||
|
||||
} // reset
|
||||
@ -855,7 +855,7 @@ int NewAIController::calcSteps()
|
||||
if( fabsf(m_controls->m_steer) > 0.95 )
|
||||
{
|
||||
const int WIDTH_STEPS =
|
||||
(int)( m_quad_graph->getNode(m_future_sector).getPathWidth()
|
||||
(int)( QuadGraph::get()->getNode(m_future_sector).getPathWidth()
|
||||
/( m_kart_length * 2.0 ) );
|
||||
|
||||
steps += WIDTH_STEPS;
|
||||
@ -878,13 +878,13 @@ void NewAIController::findCurve()
|
||||
for(i = m_track_node; total_dist < m_kart->getVelocityLC().getZ();
|
||||
i = m_next_node_index[i])
|
||||
{
|
||||
total_dist += m_quad_graph->getDistanceToNext(i, m_successor_index[i]);
|
||||
total_dist += QuadGraph::get()->getDistanceToNext(i, m_successor_index[i]);
|
||||
}
|
||||
|
||||
|
||||
m_curve_angle =
|
||||
normalizeAngle(m_quad_graph->getAngleToNext(i, m_successor_index[i])
|
||||
-m_quad_graph->getAngleToNext(m_track_node,
|
||||
normalizeAngle(QuadGraph::get()->getAngleToNext(i, m_successor_index[i])
|
||||
-QuadGraph::get()->getAngleToNext(m_track_node,
|
||||
m_successor_index[m_track_node]) );
|
||||
|
||||
m_curve_target_speed = m_kart->getCurrentMaxSpeed();
|
||||
|
@ -64,8 +64,8 @@ void LinearWorld::init()
|
||||
info.m_track_sector = QuadGraph::UNKNOWN_SECTOR;
|
||||
info.m_last_valid_sector = 0;
|
||||
info.m_lap_start_time = 0;
|
||||
m_track->getQuadGraph().findRoadSector(m_karts[n]->getXYZ(),
|
||||
&info.m_track_sector);
|
||||
QuadGraph::get()->findRoadSector(m_karts[n]->getXYZ(),
|
||||
&info.m_track_sector);
|
||||
|
||||
//If m_track_sector == UNKNOWN_SECTOR, then the kart is not on top of
|
||||
//the road, so we have to use another function to find the sector.
|
||||
@ -73,13 +73,13 @@ void LinearWorld::init()
|
||||
if (!info.m_on_road)
|
||||
{
|
||||
info.m_track_sector =
|
||||
m_track->getQuadGraph().findOutOfRoadSector(m_karts[n]->getXYZ(),
|
||||
QuadGraph::UNKNOWN_SECTOR );
|
||||
QuadGraph::get()->findOutOfRoadSector(m_karts[n]->getXYZ(),
|
||||
QuadGraph::UNKNOWN_SECTOR );
|
||||
}
|
||||
|
||||
m_track->getQuadGraph().spatialToTrack(&info.m_curr_track_coords,
|
||||
m_karts[n]->getXYZ(),
|
||||
info.m_track_sector );
|
||||
QuadGraph::get()->spatialToTrack(&info.m_curr_track_coords,
|
||||
m_karts[n]->getXYZ(),
|
||||
info.m_track_sector );
|
||||
|
||||
info.m_race_lap = -1;
|
||||
info.m_lap_start_time = 0;
|
||||
@ -118,8 +118,8 @@ void LinearWorld::restartRace()
|
||||
info.m_track_sector = QuadGraph::UNKNOWN_SECTOR;
|
||||
info.m_last_valid_sector = 0;
|
||||
info.m_lap_start_time = 0;
|
||||
m_track->getQuadGraph().findRoadSector(m_karts[i]->getXYZ(),
|
||||
&info.m_track_sector);
|
||||
QuadGraph::get()->findRoadSector(m_karts[i]->getXYZ(),
|
||||
&info.m_track_sector);
|
||||
|
||||
//If m_track_sector == UNKNOWN_SECTOR, then the kart is not on top of
|
||||
//the road, so we have to use another function to find the sector.
|
||||
@ -127,13 +127,13 @@ void LinearWorld::restartRace()
|
||||
if (!info.m_on_road)
|
||||
{
|
||||
info.m_track_sector =
|
||||
m_track->getQuadGraph().findOutOfRoadSector(m_karts[i]->getXYZ(),
|
||||
QuadGraph::UNKNOWN_SECTOR );
|
||||
QuadGraph::get()->findOutOfRoadSector(m_karts[i]->getXYZ(),
|
||||
QuadGraph::UNKNOWN_SECTOR);
|
||||
}
|
||||
|
||||
m_track->getQuadGraph().spatialToTrack(&info.m_curr_track_coords,
|
||||
m_karts[i]->getXYZ(),
|
||||
info.m_track_sector );
|
||||
QuadGraph::get()->spatialToTrack(&info.m_curr_track_coords,
|
||||
m_karts[i]->getXYZ(),
|
||||
info.m_track_sector );
|
||||
info.m_race_lap = -1;
|
||||
info.m_lap_start_time = -0;
|
||||
info.m_time_at_last_lap = 99999.9f;
|
||||
@ -197,8 +197,8 @@ void LinearWorld::update(float dt)
|
||||
|
||||
// update sector variables
|
||||
int prev_sector = kart_info.m_track_sector;
|
||||
m_track->getQuadGraph().findRoadSector(kart->getXYZ(),
|
||||
&kart_info.m_track_sector);
|
||||
QuadGraph::get()->findRoadSector(kart->getXYZ(),
|
||||
&kart_info.m_track_sector);
|
||||
|
||||
kart_info.m_on_road = kart_info.m_track_sector != QuadGraph::UNKNOWN_SECTOR;
|
||||
if(kart_info.m_on_road)
|
||||
@ -209,11 +209,11 @@ void LinearWorld::update(float dt)
|
||||
{
|
||||
// Kart off road. Find the closest sector instead.
|
||||
kart_info.m_track_sector =
|
||||
m_track->getQuadGraph().findOutOfRoadSector(kart->getXYZ(), prev_sector );
|
||||
QuadGraph::get()->findOutOfRoadSector(kart->getXYZ(), prev_sector );
|
||||
}
|
||||
|
||||
// Update track coords (=progression)
|
||||
m_track->getQuadGraph().spatialToTrack(&kart_info.m_curr_track_coords,
|
||||
QuadGraph::get()->spatialToTrack(&kart_info.m_curr_track_coords,
|
||||
kart->getXYZ(),
|
||||
kart_info.m_track_sector );
|
||||
|
||||
@ -581,11 +581,13 @@ void LinearWorld::moveKartAfterRescue(Kart* kart)
|
||||
// Using the predecessor has the additional afvantage (besides punishing
|
||||
// the player a bit more) that it makes it less likely to fall in a
|
||||
// rescue loop since the kart moves back on each attempt.
|
||||
const QuadGraph &qg = m_track->getQuadGraph();
|
||||
info.m_track_sector = qg.getNode(info.m_track_sector).getPredecessor();
|
||||
info.m_last_valid_sector= qg.getNode(info.m_track_sector).getPredecessor();
|
||||
info.m_track_sector = QuadGraph::get()->getNode(info.m_track_sector)
|
||||
.getPredecessor();
|
||||
info.m_last_valid_sector= QuadGraph::get()->getNode(info.m_track_sector)
|
||||
.getPredecessor();
|
||||
|
||||
kart->setXYZ( m_track->trackToSpatial(info.m_track_sector) );
|
||||
kart->setXYZ( QuadGraph::get()->getQuadOfNode(info.m_track_sector)
|
||||
.getCenter());
|
||||
|
||||
btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f),
|
||||
m_track->getAngle(info.m_track_sector) );
|
||||
@ -820,7 +822,7 @@ void LinearWorld::checkForWrongDirection(unsigned int i)
|
||||
// If the kart can go in more than one directions from the current track
|
||||
// don't do any reverse message handling, since it is likely that there
|
||||
// will be one direction in which it isn't going backwards anyway.
|
||||
if(m_track->getQuadGraph().getNumberOfSuccessors(m_kart_info[i].m_track_sector)>1)
|
||||
if(QuadGraph::get()->getNumberOfSuccessors(m_kart_info[i].m_track_sector)>1)
|
||||
return;
|
||||
|
||||
// check if the player is going in the wrong direction
|
||||
|
@ -367,11 +367,10 @@ void World::resetAllKarts()
|
||||
if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES &&
|
||||
UserConfigParams::m_track_debug)
|
||||
{
|
||||
const QuadGraph &qg=m_track->getQuadGraph();
|
||||
Vec3 eps = Vec3(0,1.5f*m_karts[0]->getKartHeight(),0);
|
||||
for(unsigned int quad=0; quad<qg.getNumNodes(); quad++)
|
||||
for(unsigned int quad=0; quad<QuadGraph::get()->getNumNodes(); quad++)
|
||||
{
|
||||
const Quad &q = qg.getQuad(quad);
|
||||
const Quad &q = QuadGraph::get()->getQuadOfNode(quad);
|
||||
const Vec3 center = q.getCenter();
|
||||
// We have to test for all karts, since the karts have different
|
||||
// heights and so things might change from kart to kart.
|
||||
|
@ -75,7 +75,7 @@ void GraphNode::addSuccessor(unsigned int to)
|
||||
const Quad &this_quad = m_all_quads->getQuad(m_quad_index);
|
||||
// to is the graph node, so we have to use m_all_nodes to get the right quad
|
||||
GraphNode &gn = m_all_nodes->getNode(to);
|
||||
const Quad &next_quad = m_all_nodes->getQuad(to);
|
||||
const Quad &next_quad = m_all_nodes->getQuadOfNode(to);
|
||||
|
||||
// Keep the first predecessor, which is usually the most 'natural' one.
|
||||
if(gn.m_predecessor==-1)
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "tracks/quad_set.hpp"
|
||||
|
||||
const int QuadGraph::UNKNOWN_SECTOR = -1;
|
||||
QuadGraph *QuadGraph::m_quad_graph = NULL;
|
||||
|
||||
/** Constructor, loads the graph information for a given set of quads
|
||||
* from a graph file.
|
||||
@ -533,7 +534,7 @@ void QuadGraph::findRoadSector(const Vec3& xyz, int *sector,
|
||||
{
|
||||
// Most likely the kart will still be on the sector it was before,
|
||||
// so this simple case is tested first.
|
||||
if(*sector!=UNKNOWN_SECTOR && getQuad(*sector).pointInQuad(xyz) )
|
||||
if(*sector!=UNKNOWN_SECTOR && getQuadOfNode(*sector).pointInQuad(xyz) )
|
||||
{
|
||||
return;
|
||||
} // if still on same quad
|
||||
@ -562,7 +563,7 @@ void QuadGraph::findRoadSector(const Vec3& xyz, int *sector,
|
||||
indx = (*all_sectors)[i];
|
||||
else
|
||||
indx = indx<(int)m_all_nodes.size()-1 ? indx +1 : 0;
|
||||
const Quad &q = getQuad(indx);
|
||||
const Quad &q = getQuadOfNode(indx);
|
||||
float dist = xyz.getY() - q.getMinHeight();
|
||||
// While negative distances are unlikely, we allow some small netative
|
||||
// numbers in case that the kart is partly in the track.
|
||||
|
@ -39,13 +39,21 @@ using namespace irr;
|
||||
class CheckLine;
|
||||
|
||||
/**
|
||||
* \brief This class stores a graph of quads.
|
||||
* \ingroup tracks
|
||||
* \brief This class stores a graph of quads. It uses a 'simplified singleton'
|
||||
* design pattern: it has a static create function to create exactly instance,
|
||||
* a destroy function, and a get function (that does not have the side effect
|
||||
* of the 'normal singleton' design pattern to create an instance). Besides
|
||||
* saving on the if statement in get(), this is necessary since certain race
|
||||
* modes might not have a quad graph at all (e.g. battle mode). So get()
|
||||
* returns NULL in this case, and this is tested where necessary.
|
||||
* \ingroup tracks
|
||||
*/
|
||||
class QuadGraph : public NoCopy
|
||||
{
|
||||
|
||||
private:
|
||||
static QuadGraph *m_quad_graph;
|
||||
|
||||
/** The actual graph data structure. */
|
||||
std::vector<GraphNode*> m_all_nodes;
|
||||
/** The set of all quads. */
|
||||
@ -74,12 +82,12 @@ private:
|
||||
void createMesh(bool show_invisible=true,
|
||||
const video::SColor *track_color=NULL,
|
||||
const video::SColor *lap_color=NULL);
|
||||
QuadGraph (const std::string &quad_file_name,
|
||||
const std::string graph_file_name);
|
||||
~QuadGraph ();
|
||||
public:
|
||||
static const int UNKNOWN_SECTOR;
|
||||
|
||||
QuadGraph (const std::string &quad_file_name,
|
||||
const std::string graph_file_name);
|
||||
~QuadGraph ();
|
||||
void createDebugMesh();
|
||||
void cleanupDebugMesh();
|
||||
void getSuccessors(int node_number,
|
||||
@ -106,7 +114,33 @@ public:
|
||||
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *out) const;
|
||||
void updateDistancesForAllSuccessors(unsigned int indx, float delta);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns the one instance of this object. It is possible that there
|
||||
* is no instance created (e.g. in battle mode, since it doesn't have
|
||||
* a quad graph), so we don't assert that an instance exist, and we
|
||||
* also don't create one if it doesn't exists. */
|
||||
static QuadGraph *get() { return m_quad_graph; }
|
||||
// ----------------------------------------------------------------------
|
||||
/** Creates a QuadGraph instance. */
|
||||
static void create(const std::string &quad_file_name,
|
||||
const std::string graph_file_name)
|
||||
{
|
||||
assert(m_quad_graph==NULL);
|
||||
m_quad_graph = new QuadGraph(quad_file_name, graph_file_name);
|
||||
} // create
|
||||
// ----------------------------------------------------------------------
|
||||
/** Cleans up the quad graph. It is possible that this function is called
|
||||
* even if no instance exists (e.g. in battle mode). So it is not an
|
||||
* error if there is no instance. */
|
||||
static void destroy()
|
||||
{
|
||||
if(m_quad_graph)
|
||||
{
|
||||
delete m_quad_graph;
|
||||
m_quad_graph = NULL;
|
||||
}
|
||||
} // destroy
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns the number of nodes in the graph. */
|
||||
unsigned int getNumNodes() const { return m_all_nodes.size(); }
|
||||
// ----------------------------------------------------------------------
|
||||
@ -124,7 +158,7 @@ public:
|
||||
{ return m_all_nodes[n]->getNumberOfSuccessors(); }
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns the quad that belongs to a graph node. */
|
||||
const Quad& getQuad(unsigned int j) const
|
||||
const Quad& getQuadOfNode(unsigned int j) const
|
||||
{ return m_all_quads->getQuad(m_all_nodes[j]->getIndex()); }
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns the quad that belongs to a graph node. */
|
||||
|
@ -65,7 +65,7 @@ using namespace irr;
|
||||
const float Track::NOHIT = -99999.9f;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
Track::Track(std::string filename)
|
||||
Track::Track(const std::string &filename)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0x17AC3802;
|
||||
@ -83,7 +83,6 @@ Track::Track(std::string filename)
|
||||
m_all_cached_meshes.clear();
|
||||
m_is_arena = false;
|
||||
m_camera_far = 1000.0f;
|
||||
m_quad_graph = NULL;
|
||||
m_check_manager = NULL;
|
||||
m_mini_map = NULL;
|
||||
m_sky_particles = NULL;
|
||||
@ -121,14 +120,9 @@ void Track::reset()
|
||||
/** Removes the physical body from the world.
|
||||
* Called at the end of a race.
|
||||
*/
|
||||
|
||||
void Track::cleanup()
|
||||
{
|
||||
if(m_quad_graph)
|
||||
{
|
||||
delete m_quad_graph;
|
||||
m_quad_graph = NULL;
|
||||
}
|
||||
QuadGraph::destroy();
|
||||
|
||||
ParticleKindManager::get()->cleanUpTrackSpecificGfx();
|
||||
|
||||
@ -191,7 +185,7 @@ void Track::cleanup()
|
||||
}
|
||||
m_all_cached_meshes.clear();
|
||||
|
||||
if(m_quad_graph) delete m_quad_graph;
|
||||
QuadGraph::destroy();
|
||||
if(m_check_manager) delete m_check_manager;
|
||||
if(m_mini_map)
|
||||
{
|
||||
@ -256,12 +250,6 @@ void Track::cleanup()
|
||||
|
||||
} // cleanup
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const Vec3& Track::trackToSpatial(const int sector) const
|
||||
{
|
||||
return m_quad_graph->getQuad(sector).getCenter();
|
||||
} // trackToSpatial
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Track::loadTrackInfo()
|
||||
{
|
||||
@ -388,6 +376,8 @@ void Track::getMusicInformation(std::vector<std::string>& filenames,
|
||||
} // getMusicInformation
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Select and set the music for this track (doesn't actually start it yet).
|
||||
*/
|
||||
void Track::startMusic() const
|
||||
{
|
||||
// In case that the music wasn't found (a warning was already printed)
|
||||
@ -401,29 +391,34 @@ void Track::startMusic() const
|
||||
*/
|
||||
void Track::loadQuadGraph(unsigned int mode_id)
|
||||
{
|
||||
m_quad_graph = new QuadGraph(m_root+"/"+m_all_modes[mode_id].m_quad_name,
|
||||
m_root+"/"+m_all_modes[mode_id].m_graph_name);
|
||||
QuadGraph::create(m_root+"/"+m_all_modes[mode_id].m_quad_name,
|
||||
m_root+"/"+m_all_modes[mode_id].m_graph_name);
|
||||
#ifdef DEBUG
|
||||
for(unsigned int i=0; i<m_quad_graph->getNumNodes(); i++)
|
||||
for(unsigned int i=0; i<QuadGraph::get()->getNumNodes(); i++)
|
||||
{
|
||||
assert(m_quad_graph->getNode(i).getPredecessor()!=-1);
|
||||
assert(QuadGraph::get()->getNode(i).getPredecessor()!=-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(m_quad_graph->getNumNodes()==0)
|
||||
if(QuadGraph::get()->getNumNodes()==0)
|
||||
{
|
||||
fprintf(stderr, "[Track] WARNING: No graph nodes defined for track '%s'\n",
|
||||
fprintf(stderr,
|
||||
"[Track] WARNING: No graph nodes defined for track '%s'\n",
|
||||
m_filename.c_str());
|
||||
if (race_manager->getNumberOfKarts() > 1)
|
||||
{
|
||||
fprintf(stderr, "[Track] FATAL: I can handle the lack of driveline in single kart mode, but not with AIs\n");
|
||||
fprintf(stderr,
|
||||
"[Track] FATAL: I can handle the lack of driveline in single"
|
||||
"kart mode, but not with AIs\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mini_map = m_quad_graph->makeMiniMap(World::getWorld()->getRaceGUI()->getMiniMapSize(),
|
||||
"minimap::"+m_ident);
|
||||
m_mini_map=
|
||||
QuadGraph::get()->makeMiniMap(World::getWorld()->getRaceGUI()
|
||||
->getMiniMapSize(),
|
||||
"minimap::"+m_ident);
|
||||
|
||||
}
|
||||
} // loadQuadGraph
|
||||
@ -1122,11 +1117,11 @@ void Track::loadTrackModel(World* parent, unsigned int mode_id)
|
||||
}
|
||||
m_start_transforms.resize(race_manager->getNumberOfKarts());
|
||||
if(!m_is_arena)
|
||||
m_quad_graph->setDefaultStartPositions(&m_start_transforms,
|
||||
karts_per_row,
|
||||
forwards_distance,
|
||||
sidewards_distance,
|
||||
upwards_distance);
|
||||
QuadGraph::get()->setDefaultStartPositions(&m_start_transforms,
|
||||
karts_per_row,
|
||||
forwards_distance,
|
||||
sidewards_distance,
|
||||
upwards_distance);
|
||||
|
||||
loadMainTrack(*root);
|
||||
unsigned int main_track_count = m_all_nodes.size();
|
||||
@ -1366,7 +1361,7 @@ void Track::loadTrackModel(World* parent, unsigned int mode_id)
|
||||
|
||||
|
||||
createPhysicsModel(main_track_count);
|
||||
if (UserConfigParams::m_track_debug) m_quad_graph->createDebugMesh();
|
||||
if (UserConfigParams::m_track_debug) QuadGraph::get()->createDebugMesh();
|
||||
|
||||
// Only print warning if not in battle mode, since battle tracks don't have
|
||||
// any quads or check lines.
|
||||
|
@ -136,9 +136,6 @@ private:
|
||||
/** Far value for cameras for this track. */
|
||||
float m_camera_far;
|
||||
|
||||
/** The graph used to connect the quads. */
|
||||
QuadGraph *m_quad_graph;
|
||||
|
||||
/** The type of sky to be used for the track. */
|
||||
enum {SKY_NONE, SKY_BOX,
|
||||
SKY_DOME, SKY_COLOR} m_sky_type;
|
||||
@ -255,37 +252,9 @@ public:
|
||||
|
||||
static const float NOHIT;
|
||||
|
||||
Track (std::string filename);
|
||||
Track (const std::string &filename);
|
||||
~Track ();
|
||||
bool isArena () const { return m_is_arena; }
|
||||
void cleanup ();
|
||||
/** Returns the texture with the mini map for this track. */
|
||||
const video::ITexture*getMiniMap () const { return m_mini_map; }
|
||||
const Vec3& trackToSpatial (const int SECTOR) const;
|
||||
void loadTrackModel (World* parent, unsigned int mode_id=0);
|
||||
void addMusic (MusicInformation* mi)
|
||||
{m_music.push_back(mi); }
|
||||
float getGravity () const {return m_gravity; }
|
||||
|
||||
/** Returns the version of the .track file. */
|
||||
int getVersion () const {return m_version; }
|
||||
|
||||
/** Returns the length of the main driveline. */
|
||||
float getTrackLength () const {return m_quad_graph->getLapLength(); }
|
||||
|
||||
/** Returns a unique identifier for this track (the directory name). */
|
||||
const std::string& getIdent () const {return m_ident; }
|
||||
|
||||
/** Returns the name of the track, which is e.g. displayed on the screen.
|
||||
\note this is the LTR name, invoke fribidi as needed
|
||||
*/
|
||||
const wchar_t* getName () const {return translations->w_gettext(m_name.c_str()); }
|
||||
|
||||
/** Returns all groups this track belongs to. */
|
||||
const std::vector<std::string>
|
||||
getGroups () const {return m_groups; }
|
||||
|
||||
/** Select and set the music for this track (doesn't actually start it yet) */
|
||||
void startMusic () const;
|
||||
|
||||
bool setTerrainHeight(Vec3 *pos) const;
|
||||
@ -298,15 +267,48 @@ public:
|
||||
unsigned int k);
|
||||
void handleExplosion(const Vec3 &pos,
|
||||
const PhysicalObject *mp) const;
|
||||
std::vector< std::vector<float> >
|
||||
buildHeightMap();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the texture with the mini map for this track. */
|
||||
const video::ITexture*getMiniMap () const { return m_mini_map; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool isArena () const { return m_is_arena; }
|
||||
// ------------------------------------------------------------------------
|
||||
void loadTrackModel (World* parent, unsigned int mode_id=0);
|
||||
// ------------------------------------------------------------------------
|
||||
void addMusic (MusicInformation* mi)
|
||||
{m_music.push_back(mi); }
|
||||
// ------------------------------------------------------------------------
|
||||
float getGravity () const {return m_gravity; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the version of the .track file. */
|
||||
int getVersion () const {return m_version; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the length of the main driveline. */
|
||||
float getTrackLength () const
|
||||
{return QuadGraph::get()->getLapLength();}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a unique identifier for this track (the directory name). */
|
||||
const std::string& getIdent () const {return m_ident; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the track, which is e.g. displayed on the screen.
|
||||
\note this is the LTR name, invoke fribidi as needed. */
|
||||
const wchar_t* getName () const
|
||||
{return translations->w_gettext(m_name.c_str()); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns all groups this track belongs to. */
|
||||
const std::vector<std::string>
|
||||
getGroups () const {return m_groups; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the filename of this track. */
|
||||
const std::string& getFilename () const {return m_filename; }
|
||||
const std::string& getFilename () const {return m_filename; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the designer. */
|
||||
const core::stringw& getDesigner () const {return m_designer; }
|
||||
const core::stringw& getDesigner () const {return m_designer; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an absolute path to the screenshot file of this track */
|
||||
const std::string& getScreenshotFile () const {return m_screenshot; }
|
||||
const std::string& getScreenshotFile () const {return m_screenshot; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the start coordinates for a kart with a given index.
|
||||
* \param index Index of kart ranging from 0 to kart_num-1. */
|
||||
@ -317,9 +319,6 @@ public:
|
||||
void getAABB(const Vec3 **min, const Vec3 **max) const
|
||||
{ *min = &m_aabb_min; *max = &m_aabb_max; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the graph of quads, mainly for the AI. */
|
||||
QuadGraph& getQuadGraph() const { return *m_quad_graph; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns 'a' angle for quad n. This angle is used to position a kart
|
||||
* after a rescue, and to detect wrong directions. This function will
|
||||
* always return the angle towards the first successor, i.e. the angle
|
||||
@ -327,7 +326,7 @@ public:
|
||||
* \param n Number of the quad for which the angle is asked.
|
||||
*/
|
||||
float getAngle(int n) const
|
||||
{ return m_quad_graph->getAngleToNext(n, 0); }
|
||||
{ return QuadGraph::get()->getAngleToNext(n, 0); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the 2d coordinates of a point when drawn on the mini map
|
||||
* texture.
|
||||
@ -336,7 +335,7 @@ public:
|
||||
* only the first two coordinates will be used.
|
||||
*/
|
||||
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *draw_at) const
|
||||
{ m_quad_graph->mapPoint2MiniMap(xyz, draw_at); }
|
||||
{ QuadGraph::get()->mapPoint2MiniMap(xyz, draw_at); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the full path of a given file inside this track directory. */
|
||||
std::string getTrackFile(const std::string &s) const
|
||||
@ -347,15 +346,14 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the i-th. mode. */
|
||||
const std::string &getModeName(unsigned int i) const
|
||||
{ return m_all_modes[i].m_name;}
|
||||
{ return m_all_modes[i].m_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the default ambient color. */
|
||||
const video::SColor &getDefaultAmbientColor() const
|
||||
{ return m_default_ambient_color;}
|
||||
{ return m_default_ambient_color; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the far value for cameras. */
|
||||
float getCameraFar() const { return m_camera_far; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the triangle mesh for this track. */
|
||||
const TriangleMesh& getTriangleMesh() const {return *m_track_mesh; }
|
||||
@ -365,15 +363,14 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the number of start positions defined in the scene file. */
|
||||
unsigned int getNumberOfStartPositions() const
|
||||
{ return m_start_transforms.size(); }
|
||||
|
||||
{ return m_start_transforms.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
WeatherType getWeatherType () const { return m_weather_type; }
|
||||
// ------------------------------------------------------------------------
|
||||
ParticleKind* getSkyParticles () { return m_sky_particles; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool isFogEnabled() const { return m_use_fog; }
|
||||
|
||||
std::vector< std::vector<float> > buildHeightMap();
|
||||
|
||||
}; // class Track
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user