Added first version of track mini map to race gui.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3784 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
519dc6426d
commit
89b2eea124
@ -104,7 +104,7 @@ const std::string Challenge::getUnlockedMessage() const
|
|||||||
Track* track = track_manager->getTrack( m_feature[n].name );
|
Track* track = track_manager->getTrack( m_feature[n].name );
|
||||||
message = StringUtils::insert_values(
|
message = StringUtils::insert_values(
|
||||||
_("New track '%s'\nnow available"),
|
_("New track '%s'\nnow available"),
|
||||||
_(track->getName()) );
|
_(track->getName().c_str()) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UNLOCK_MODE:
|
case UNLOCK_MODE:
|
||||||
|
@ -69,22 +69,11 @@ void Scene::reset()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Scene::draw(float dt)
|
void Scene::draw(float dt)
|
||||||
{
|
{
|
||||||
glEnable ( GL_DEPTH_TEST ) ;
|
|
||||||
|
|
||||||
const Track* TRACK = RaceManager::getTrack();
|
const Track* TRACK = RaceManager::getTrack();
|
||||||
|
|
||||||
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
|
|
||||||
|
|
||||||
for (Cameras::iterator i = m_cameras.begin(); i != m_cameras.end(); ++i)
|
for (Cameras::iterator i = m_cameras.begin(); i != m_cameras.end(); ++i)
|
||||||
{
|
{
|
||||||
(*i)->update(dt);
|
(*i)->update(dt);
|
||||||
(*i)->apply ();
|
(*i)->apply ();
|
||||||
} // for cameras
|
} // for cameras
|
||||||
|
|
||||||
if (TRACK->useFog())
|
|
||||||
{
|
|
||||||
glDisable ( GL_FOG ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
glViewport ( 0, 0, UserConfigParams::m_width, UserConfigParams::m_height ) ;
|
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,9 @@ void World::init()
|
|||||||
TimedRace::setClockMode( CHRONO );
|
TimedRace::setClockMode( CHRONO );
|
||||||
m_use_highscores = true;
|
m_use_highscores = true;
|
||||||
|
|
||||||
// Create the race gui before anything else is attached to the scene node.
|
// Create the race gui before anything else is attached to the scene node
|
||||||
// This allows the race gui to do any rendering on texture.
|
// (which happens when the track is loaded). This allows the race gui to
|
||||||
|
// do any rendering on texture.
|
||||||
m_race_gui = new RaceGUI();
|
m_race_gui = new RaceGUI();
|
||||||
|
|
||||||
// Grab the track file
|
// Grab the track file
|
||||||
@ -161,7 +162,6 @@ void World::init()
|
|||||||
// objects need to allocate data structures depending on the number
|
// objects need to allocate data structures depending on the number
|
||||||
// of karts.
|
// of karts.
|
||||||
m_track->reset();
|
m_track->reset();
|
||||||
|
|
||||||
m_track->startMusic();
|
m_track->startMusic();
|
||||||
|
|
||||||
if(!history->replayHistory()) history->initRecording();
|
if(!history->replayHistory()) history->initRecording();
|
||||||
|
@ -42,26 +42,15 @@ using namespace irr;
|
|||||||
*/
|
*/
|
||||||
RaceGUI::RaceGUI()
|
RaceGUI::RaceGUI()
|
||||||
{
|
{
|
||||||
// FIXME: translation problem
|
m_marker_rendered_size = 32;
|
||||||
m_pos_string[0] = "?!?";
|
m_marker_ai_size = 14;
|
||||||
m_pos_string[1] = "1st";
|
m_marker_player_size = 16;
|
||||||
m_pos_string[2] = "2nd";
|
m_map_rendered_width = 128;
|
||||||
m_pos_string[3] = "3rd";
|
m_map_rendered_height = 128;
|
||||||
m_pos_string[4] = "4th";
|
m_map_width = 100;
|
||||||
m_pos_string[5] = "5th";
|
m_map_height = 100;
|
||||||
m_pos_string[6] = "6th";
|
m_map_left = 10;
|
||||||
m_pos_string[7] = "7th";
|
m_map_bottom = 10;
|
||||||
m_pos_string[8] = "8th";
|
|
||||||
m_pos_string[9] = "9th";
|
|
||||||
m_pos_string[10] = "10th";
|
|
||||||
|
|
||||||
int icon_width=40;
|
|
||||||
int icon_player_width=50;
|
|
||||||
if(UserConfigParams::m_height<600)
|
|
||||||
{
|
|
||||||
icon_width = 27;
|
|
||||||
icon_player_width = 35;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_speed_meter_icon = material_manager->getMaterial("speedback.png");
|
m_speed_meter_icon = material_manager->getMaterial("speedback.png");
|
||||||
m_speed_bar_icon = material_manager->getMaterial("speedfore.png");
|
m_speed_bar_icon = material_manager->getMaterial("speedfore.png");
|
||||||
@ -87,16 +76,16 @@ void RaceGUI::createMarkerTexture()
|
|||||||
// Textures must be power of 2, so
|
// Textures must be power of 2, so
|
||||||
while(npower2<n) npower2*=2;
|
while(npower2<n) npower2*=2;
|
||||||
|
|
||||||
int marker_size = 64; // must be a power of 2
|
int radius = (m_marker_rendered_size>>1)-1;
|
||||||
int radius = (marker_size>>1)-1;
|
irr_driver->beginRenderToTexture(core::dimension2di(m_marker_rendered_size * npower2,
|
||||||
irr_driver->beginRenderToTexture(core::dimension2di(marker_size * npower2, marker_size),
|
m_marker_rendered_size),
|
||||||
"RaceGUI::markers");
|
"RaceGUI::markers");
|
||||||
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
||||||
{
|
{
|
||||||
const std::string& kart_name = race_manager->getKartName(i);
|
const std::string& kart_name = race_manager->getKartName(i);
|
||||||
const KartProperties *kp = kart_properties_manager->getKart(kart_name);
|
const KartProperties *kp = kart_properties_manager->getKart(kart_name);
|
||||||
core::vector2df center((float)((marker_size>>1)+i*marker_size),
|
core::vector2df center((float)((m_marker_rendered_size>>1)+i*m_marker_rendered_size),
|
||||||
(float)(marker_size>>1));
|
(float)(m_marker_rendered_size>>1) );
|
||||||
int count = kp->getShape();
|
int count = kp->getShape();
|
||||||
core::array<core::vector2df> vertices;
|
core::array<core::vector2df> vertices;
|
||||||
createRegularPolygon(count, (float)radius, center,&vertices);
|
createRegularPolygon(count, (float)radius, center,&vertices);
|
||||||
@ -109,7 +98,6 @@ void RaceGUI::createMarkerTexture()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_marker = irr_driver->endRenderToTexture();
|
m_marker = irr_driver->endRenderToTexture();
|
||||||
core::dimension2di X = m_marker->getOriginalSize();
|
|
||||||
} // createMarkerTexture
|
} // createMarkerTexture
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -171,64 +159,40 @@ void RaceGUI::drawTimer ()
|
|||||||
} // drawTimer
|
} // drawTimer
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#define TRACKVIEW_SIZE 100
|
/** Draws the mini map and the position of all karts on it.
|
||||||
|
*/
|
||||||
void RaceGUI::drawMap()
|
void RaceGUI::drawMiniMap()
|
||||||
{
|
{
|
||||||
// arenas currently don't have a map.
|
// arenas currently don't have a map.
|
||||||
if(RaceManager::getTrack()->isArena()) return;
|
if(RaceManager::getTrack()->isArena()) return;
|
||||||
|
|
||||||
const video::ITexture *mini_map=RaceManager::getTrack()->getMiniMap();
|
const video::ITexture *mini_map=RaceManager::getTrack()->getMiniMap();
|
||||||
|
|
||||||
core::rect<s32> dest(10, UserConfigParams::m_height-60,
|
int upper_y = UserConfigParams::m_height-m_map_bottom-m_map_height;
|
||||||
60, UserConfigParams::m_height-10);
|
int lower_y = UserConfigParams::m_height-m_map_bottom;
|
||||||
|
core::rect<s32> dest(m_map_left, upper_y,
|
||||||
|
m_map_left + m_map_width, lower_y);
|
||||||
core::rect<s32> source(core::position2di(0, 0), mini_map->getOriginalSize());
|
core::rect<s32> source(core::position2di(0, 0), mini_map->getOriginalSize());
|
||||||
//FIXME irr_driver->getVideoDriver()->draw2DImage(mini_map, dest, source, 0, 0, true);
|
irr_driver->getVideoDriver()->draw2DImage(mini_map, dest, source, 0, 0, true);
|
||||||
|
|
||||||
core::rect<s32> dest1( 10, UserConfigParams::m_height-10,
|
|
||||||
100, UserConfigParams::m_height-110);
|
|
||||||
core::rect<s32> source1(core::position2di(0, 0), m_marker->getOriginalSize());
|
|
||||||
irr_driver->getVideoDriver()->draw2DImage(m_marker, dest, source1, 0, 0, true);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
glDisable ( GL_TEXTURE_2D ) ;
|
|
||||||
assert(RaceManager::getWorld() != NULL);
|
|
||||||
int xLeft = 10;
|
|
||||||
int yTop = 10;
|
|
||||||
|
|
||||||
RaceManager::getTrack() -> draw2Dview ( (float)xLeft, (float)yTop );
|
|
||||||
|
|
||||||
glBegin ( GL_QUADS ) ;
|
|
||||||
|
|
||||||
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
||||||
{
|
{
|
||||||
Kart* kart = RaceManager::getKart(i);
|
const Kart *kart = RaceManager::getKart(i);
|
||||||
if(kart->isEliminated()) continue; // don't draw eliminated kart
|
if(kart->isEliminated()) continue; // don't draw eliminated kart
|
||||||
//glColor3fv ( kart->getColor().toFloat());
|
|
||||||
const Vec3& xyz = kart->getXYZ();
|
const Vec3& xyz = kart->getXYZ();
|
||||||
|
Vec3 draw_at;
|
||||||
/* If it's a player, draw a bigger sign */
|
RaceManager::getTrack()->mapPoint2MiniMap(xyz, &draw_at);
|
||||||
// TODO
|
int marker_height = m_marker->getOriginalSize().Height;
|
||||||
/*
|
core::rect<s32> source(i *m_marker_rendered_size, 0,
|
||||||
if (kart -> isPlayerKart ())
|
(i+1)*m_marker_rendered_size, m_marker_rendered_size);
|
||||||
{
|
int marker_half_size = (kart->isPlayerKart() ? m_marker_player_size
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+3, (float)yTop+3);
|
: m_marker_ai_size )>>1;
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-2, (float)yTop+3);
|
core::rect<s32> position(m_map_left+(int)(draw_at.getX()-marker_half_size),
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-2, (float)yTop-2);
|
lower_y -(int)(draw_at.getY()+marker_half_size),
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+3, (float)yTop-2);
|
m_map_left+(int)(draw_at.getX()+marker_half_size),
|
||||||
}
|
lower_y -(int)(draw_at.getY()-marker_half_size));
|
||||||
else
|
irr_driver->getVideoDriver()->draw2DImage(m_marker, position, source, NULL, NULL, true);
|
||||||
{
|
} // for i<getNumKarts
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+2, (float)yTop+2);
|
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-1, (float)yTop+2);
|
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-1, (float)yTop-1);
|
|
||||||
RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+2, (float)yTop-1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
glEnd () ;
|
|
||||||
glEnable ( GL_TEXTURE_2D ) ;
|
|
||||||
} // drawMap
|
} // drawMap
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -737,7 +701,7 @@ void RaceGUI::drawStatusText()
|
|||||||
drawMusicDescription();
|
drawMusicDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
//drawMap();
|
drawMiniMap();
|
||||||
drawPlayerIcons(info);
|
drawPlayerIcons(info);
|
||||||
|
|
||||||
} // drawStatusText
|
} // drawStatusText
|
||||||
|
@ -84,14 +84,47 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *m_pos_string [11];
|
|
||||||
Material *m_speed_meter_icon;
|
Material *m_speed_meter_icon;
|
||||||
Material *m_speed_bar_icon;
|
Material *m_speed_bar_icon;
|
||||||
Material *m_plunger_face;
|
Material *m_plunger_face;
|
||||||
typedef std::vector<TimedMessage> AllMessageType;
|
typedef std::vector<TimedMessage> AllMessageType;
|
||||||
AllMessageType m_messages;
|
AllMessageType m_messages;
|
||||||
|
/** A texture with all mini dots to be displayed in the minimap for all karts. */
|
||||||
video::ITexture *m_marker;
|
video::ITexture *m_marker;
|
||||||
|
|
||||||
|
/** The mini map of the track. */
|
||||||
|
video::ITexture *m_mini_map;
|
||||||
|
/** The size of a single marker in pixels, must be a power of 2. */
|
||||||
|
int m_marker_rendered_size;
|
||||||
|
|
||||||
|
/** The size of a single marker on the screen for AI karts,
|
||||||
|
* need not be a power of 2. */
|
||||||
|
int m_marker_ai_size;
|
||||||
|
|
||||||
|
/** The size of a single marker on the screen or player karts,
|
||||||
|
* need not be a power of 2. */
|
||||||
|
int m_marker_player_size;
|
||||||
|
|
||||||
|
/** The width of the rendered mini map in pixels, must be a power of 2. */
|
||||||
|
int m_map_rendered_width;
|
||||||
|
|
||||||
|
/** The height of the rendered mini map in pixels, must be a power of 2. */
|
||||||
|
int m_map_rendered_height;
|
||||||
|
|
||||||
|
/** Width of the map in pixels on the screen, need not be a power of 2. */
|
||||||
|
int m_map_width;
|
||||||
|
|
||||||
|
/** Height of the map in pixels on the screen, need not be a power of 2. */
|
||||||
|
int m_map_height;
|
||||||
|
|
||||||
|
/** Distance of map from left side of screen. */
|
||||||
|
int m_map_left;
|
||||||
|
|
||||||
|
/** Distance of map from bottom of screen. */
|
||||||
|
int m_map_bottom;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void createMarkerTexture();
|
void createMarkerTexture();
|
||||||
void createRegularPolygon(unsigned int n, float radius,
|
void createRegularPolygon(unsigned int n, float radius,
|
||||||
const core::vector2df ¢er,
|
const core::vector2df ¢er,
|
||||||
@ -110,7 +143,7 @@ private:
|
|||||||
float ratio_x, float ratio_y );
|
float ratio_x, float ratio_y );
|
||||||
void drawPlayerIcons (const KartIconDisplayInfo* info);
|
void drawPlayerIcons (const KartIconDisplayInfo* info);
|
||||||
void oldDrawPlayerIcons ();
|
void oldDrawPlayerIcons ();
|
||||||
void drawMap ();
|
void drawMiniMap ();
|
||||||
void drawTimer ();
|
void drawTimer ();
|
||||||
void drawMusicDescription ();
|
void drawMusicDescription ();
|
||||||
void cleanupMessages (const float dt);
|
void cleanupMessages (const float dt);
|
||||||
@ -127,6 +160,10 @@ public:
|
|||||||
void addMessage(const std::string &m, const Kart *kart, float time,
|
void addMessage(const std::string &m, const Kart *kart, float time,
|
||||||
int fonst_size,
|
int fonst_size,
|
||||||
const video::SColor &color=video::SColor(255, 255, 0, 255));
|
const video::SColor &color=video::SColor(255, 255, 0, 255));
|
||||||
|
|
||||||
|
/** Returns the size of the texture on which to render the minimap to. */
|
||||||
|
const core::dimension2di getMiniMapSize() const
|
||||||
|
{ return core::dimension2di(m_map_width, m_map_height); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,6 +38,7 @@ QuadGraph::QuadGraph(const std::string &quad_file_name,
|
|||||||
m_node = NULL;
|
m_node = NULL;
|
||||||
m_mesh = NULL;
|
m_mesh = NULL;
|
||||||
m_mesh_buffer = NULL;
|
m_mesh_buffer = NULL;
|
||||||
|
m_lap_length = 0;
|
||||||
m_all_quads = new QuadSet(quad_file_name);
|
m_all_quads = new QuadSet(quad_file_name);
|
||||||
GraphNode::m_all_quads = m_all_quads;
|
GraphNode::m_all_quads = m_all_quads;
|
||||||
GraphNode::m_all_nodes = this;
|
GraphNode::m_all_nodes = this;
|
||||||
@ -132,6 +133,15 @@ void QuadGraph::load(const std::string &filename)
|
|||||||
}
|
}
|
||||||
delete xml;
|
delete xml;
|
||||||
|
|
||||||
|
for(unsigned int i=0; i<m_all_nodes.size(); i++)
|
||||||
|
{
|
||||||
|
if(m_all_nodes[i]->getSuccessor(0)==0)
|
||||||
|
{
|
||||||
|
m_lap_length = m_all_nodes[i]->getDistanceFromStart()
|
||||||
|
+ m_all_nodes[i]->getDistanceToSuccessor(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
setDefaultSuccessors();
|
setDefaultSuccessors();
|
||||||
} // load
|
} // load
|
||||||
|
|
||||||
@ -406,11 +416,6 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2di &dimension,
|
|||||||
const video::SColor &fill_color)
|
const video::SColor &fill_color)
|
||||||
{
|
{
|
||||||
irr_driver->beginRenderToTexture(dimension, name);
|
irr_driver->beginRenderToTexture(dimension, name);
|
||||||
for(unsigned int i=0; i<m_all_quads->getNumberOfQuads(); i++)
|
|
||||||
{
|
|
||||||
// core::array<core::vector2df> vertices;
|
|
||||||
// vertices.push_back(core::vertices
|
|
||||||
}
|
|
||||||
createMesh();
|
createMesh();
|
||||||
video::S3DVertex *v = (video::S3DVertex*)m_mesh_buffer->getVertices();
|
video::S3DVertex *v = (video::S3DVertex*)m_mesh_buffer->getVertices();
|
||||||
for(unsigned int i=0; i<m_mesh_buffer->getVertexCount(); i++)
|
for(unsigned int i=0; i<m_mesh_buffer->getVertexCount(); i++)
|
||||||
@ -420,16 +425,38 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2di &dimension,
|
|||||||
|
|
||||||
m_node = irr_driver->addMesh(m_mesh); // add Debug Mesh
|
m_node = irr_driver->addMesh(m_mesh); // add Debug Mesh
|
||||||
m_node->setMaterialFlag(video::EMF_LIGHTING, false);
|
m_node->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||||
|
|
||||||
// Add the camera:
|
// Add the camera:
|
||||||
|
// ---------------
|
||||||
|
scene::ICameraSceneNode *camera = irr_driver->addCamera();
|
||||||
Vec3 bb_min, bb_max;
|
Vec3 bb_min, bb_max;
|
||||||
m_all_quads->getBoundingBox(&bb_min, &bb_max);
|
m_all_quads->getBoundingBox(&bb_min, &bb_max);
|
||||||
Vec3 center = (bb_max+bb_min)*0.5f;
|
Vec3 center = (bb_max+bb_min)*0.5f;
|
||||||
scene::ICameraSceneNode *camera = irr_driver->addCamera();
|
core::matrix4 projection;
|
||||||
camera->setPosition(core::vector3df(center.getX(), 120, center.getY()));
|
projection.buildProjectionMatrixOrthoLH(bb_max.getX()-bb_min.getX(),
|
||||||
|
bb_max.getY()-bb_min.getY(),
|
||||||
|
-1, bb_max.getZ()-bb_min.getZ()+1);
|
||||||
|
camera->setProjectionMatrix(projection, true);
|
||||||
|
camera->setPosition(core::vector3df(center.getX(), bb_max.getZ(), center.getY()));
|
||||||
camera->setUpVector(core::vector3df(0,0,1));
|
camera->setUpVector(core::vector3df(0,0,1));
|
||||||
camera->setTarget(core::vector3df(center.getX(),0,center.getY()));
|
camera->setTarget(core::vector3df(center.getX(),0,center.getY()));
|
||||||
video::ITexture *texture=irr_driver->endRenderToTexture();
|
video::ITexture *texture=irr_driver->endRenderToTexture();
|
||||||
cleanupDebugMesh();
|
cleanupDebugMesh();
|
||||||
|
m_min_coord = bb_min;
|
||||||
|
m_scaling = dimension.Width/(bb_max.getX()-bb_min.getX());
|
||||||
return texture;
|
return texture;
|
||||||
|
|
||||||
} // drawMiniMap
|
} // drawMiniMap
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns the 2d coordinates of a point when drawn on the mini map
|
||||||
|
* texture.
|
||||||
|
* \param xyz Coordinates of the point to map.
|
||||||
|
* \param draw_at The coordinates in pixel on the mini map of the point,
|
||||||
|
* only the first two coordinates will be used.
|
||||||
|
*/
|
||||||
|
void QuadGraph::mapPoint2MiniMap(const Vec3 &xyz,Vec3 *draw_at) const
|
||||||
|
{
|
||||||
|
draw_at->setX((xyz.getX()-m_min_coord.getX())*m_scaling.getX());
|
||||||
|
draw_at->setY((xyz.getY()-m_min_coord.getY())*m_scaling.getY());
|
||||||
|
|
||||||
|
} // mapPoint
|
@ -41,6 +41,15 @@ private:
|
|||||||
/** For debug only: the actual mesh buffer storing the quads. */
|
/** For debug only: the actual mesh buffer storing the quads. */
|
||||||
scene::IMeshBuffer *m_mesh_buffer;
|
scene::IMeshBuffer *m_mesh_buffer;
|
||||||
|
|
||||||
|
/** The length of the first loop. */
|
||||||
|
float m_lap_length;
|
||||||
|
|
||||||
|
/** The minimum coordinates of the quad graph. */
|
||||||
|
Vec3 m_min_coord;
|
||||||
|
|
||||||
|
/** Scaling for mini map, only x and y components are used. */
|
||||||
|
Vec3 m_scaling;
|
||||||
|
|
||||||
void setDefaultSuccessors();
|
void setDefaultSuccessors();
|
||||||
void load (const std::string &filename);
|
void load (const std::string &filename);
|
||||||
void createMesh();
|
void createMesh();
|
||||||
@ -66,6 +75,7 @@ public:
|
|||||||
const std::string &name,
|
const std::string &name,
|
||||||
const video::SColor &fill_color
|
const video::SColor &fill_color
|
||||||
=video::SColor(127, 255, 255, 255) );
|
=video::SColor(127, 255, 255, 255) );
|
||||||
|
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *out) const;
|
||||||
|
|
||||||
/** Returns the number of nodes in the graph. */
|
/** Returns the number of nodes in the graph. */
|
||||||
unsigned int getNumNodes() const { return m_all_nodes.size(); }
|
unsigned int getNumNodes() const { return m_all_nodes.size(); }
|
||||||
@ -93,6 +103,9 @@ public:
|
|||||||
/** Returns the distance from the start to the beginning of a quad. */
|
/** Returns the distance from the start to the beginning of a quad. */
|
||||||
float getDistanceFromStart(int j) const
|
float getDistanceFromStart(int j) const
|
||||||
{ return m_all_nodes[j]->getDistanceFromStart(); }
|
{ return m_all_nodes[j]->getDistanceFromStart(); }
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** Returns the length of the main driveline. */
|
||||||
|
float getLapLength() const {return m_lap_length; }
|
||||||
}; // QuadGraph
|
}; // QuadGraph
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,6 +45,7 @@ using namespace irr;
|
|||||||
#include "physics/physical_object.hpp"
|
#include "physics/physical_object.hpp"
|
||||||
#include "physics/triangle_mesh.hpp"
|
#include "physics/triangle_mesh.hpp"
|
||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
|
#include "states_screens/race_gui.hpp"
|
||||||
#include "tracks/bezier_curve.hpp"
|
#include "tracks/bezier_curve.hpp"
|
||||||
#include "tracks/check_manager.hpp"
|
#include "tracks/check_manager.hpp"
|
||||||
#include "tracks/quad_graph.hpp"
|
#include "tracks/quad_graph.hpp"
|
||||||
@ -54,13 +55,10 @@ using namespace irr;
|
|||||||
const float Track::NOHIT = -99999.9f;
|
const float Track::NOHIT = -99999.9f;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
Track::Track( std::string filename_, float w, float h, bool stretch )
|
Track::Track( std::string filename)
|
||||||
{
|
{
|
||||||
m_filename = filename_;
|
m_filename = filename;
|
||||||
m_item_style = "";
|
m_item_style = "";
|
||||||
m_track_2d_width = w;
|
|
||||||
m_track_2d_height = h;
|
|
||||||
m_do_stretch = stretch;
|
|
||||||
m_description = "";
|
m_description = "";
|
||||||
m_designer = "";
|
m_designer = "";
|
||||||
m_screenshot = "";
|
m_screenshot = "";
|
||||||
@ -75,7 +73,6 @@ Track::Track( std::string filename_, float w, float h, bool stretch )
|
|||||||
m_animation_manager = NULL;
|
m_animation_manager = NULL;
|
||||||
m_check_manager = NULL;
|
m_check_manager = NULL;
|
||||||
loadTrack(m_filename);
|
loadTrack(m_filename);
|
||||||
loadQuadGraph();
|
|
||||||
} // Track
|
} // Track
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -85,6 +82,7 @@ Track::~Track()
|
|||||||
if(m_quad_graph) delete m_quad_graph;
|
if(m_quad_graph) delete m_quad_graph;
|
||||||
if(m_animation_manager) delete m_animation_manager;
|
if(m_animation_manager) delete m_animation_manager;
|
||||||
if(m_check_manager) delete m_check_manager;
|
if(m_check_manager) delete m_check_manager;
|
||||||
|
if(m_mini_map) irr_driver->removeTexture(m_mini_map);
|
||||||
} // ~Track
|
} // ~Track
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -154,17 +152,8 @@ btTransform Track::getStartTransform(unsigned int pos) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// sometimes the first kart would be too close
|
|
||||||
// to the first driveline point and not to the last one -->
|
|
||||||
// This kart would not get any lap counting done in the first
|
|
||||||
// lap! Therefore an offset is substracted from its Y location,
|
|
||||||
// and this offset is calculated based on the drivelines
|
|
||||||
float offset = 1.5f;
|
|
||||||
if(m_left_driveline[0].getY() > 0 || m_right_driveline[0].getY() > 0)
|
|
||||||
offset += std::max(m_left_driveline[0].getY(), m_left_driveline[0].getY());
|
|
||||||
|
|
||||||
orig.setX( pos<m_start_x.size() ? m_start_x[pos] : ((pos%2==0)?1.5f:-1.5f) );
|
orig.setX( pos<m_start_x.size() ? m_start_x[pos] : ((pos%2==0)?1.5f:-1.5f) );
|
||||||
orig.setY( pos<m_start_y.size() ? m_start_y[pos] : -1.5f*pos-offset );
|
orig.setY( pos<m_start_y.size() ? m_start_y[pos] : -1.5f*pos-1.5f );
|
||||||
orig.setZ( pos<m_start_z.size() ? m_start_z[pos] : 1.0f );
|
orig.setZ( pos<m_start_z.size() ? m_start_z[pos] : 1.0f );
|
||||||
}
|
}
|
||||||
btTransform start;
|
btTransform start;
|
||||||
@ -176,267 +165,6 @@ btTransform Track::getStartTransform(unsigned int pos) const
|
|||||||
return start;
|
return start;
|
||||||
} // getStartTransform
|
} // getStartTransform
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** It's not the nicest solution to have two very similar version of a function,
|
|
||||||
* i.e. drawScaled2D and draw2Dview - but to keep both versions const, the
|
|
||||||
* values m_scale_x/m_scale_y can not be changed, but they are needed in glVtx.
|
|
||||||
* So two functions are provided: one which uses temporary variables, and one
|
|
||||||
* which uses the pre-computed attributes (see constructor/loadQuadGraph)
|
|
||||||
* - which saves a bit of time at runtime as well.
|
|
||||||
* drawScaled2D is called from gui/TrackSel, draw2Dview from RaceGUI.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Track::drawScaled2D(float x, float y, float w, float h) const
|
|
||||||
{
|
|
||||||
float width = m_driveline_max.getX() - m_driveline_min.getX();
|
|
||||||
|
|
||||||
float sx = w / width;
|
|
||||||
float sy = h / ( m_driveline_max.getY()-m_driveline_min.getY() );
|
|
||||||
|
|
||||||
if( sx > sy )
|
|
||||||
{
|
|
||||||
sx = sy;
|
|
||||||
x += w/2 - width*sx/2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sy = sx;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int DRIVELINE_SIZE = (unsigned int)m_driveline.size();
|
|
||||||
|
|
||||||
glPushAttrib ( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT );
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glDisable (GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
glColor4f ( 1, 1, 1, 0.5) ;
|
|
||||||
|
|
||||||
glBegin ( GL_QUAD_STRIP ) ;
|
|
||||||
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
glVertex2f ( x + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * sy) ;
|
|
||||||
|
|
||||||
glVertex2f ( x + ( m_right_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
}
|
|
||||||
glVertex2f ( x + ( m_left_driveline[0].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[0].getY() - m_driveline_min.getY() ) * sy) ;
|
|
||||||
glVertex2f ( x + ( m_right_driveline[0].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[0].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
glEnable( GL_LINE_SMOOTH );
|
|
||||||
glEnable( GL_POINT_SMOOTH );
|
|
||||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
|
||||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
|
||||||
|
|
||||||
glLineWidth(1);
|
|
||||||
glPointSize(1);
|
|
||||||
|
|
||||||
glColor4f ( 0, 0, 0, 1 ) ;
|
|
||||||
|
|
||||||
glBegin ( GL_LINES ) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE - 1 ; ++i )
|
|
||||||
{
|
|
||||||
/*Draw left driveline of the map*/
|
|
||||||
glVertex2f ( x + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x + ( m_left_driveline[i+1].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[i+1].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
|
|
||||||
/*Draw left driveline of the map*/
|
|
||||||
glVertex2f ( x + ( m_right_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x + ( m_right_driveline[i+1].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[i+1].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Close the left driveline
|
|
||||||
glVertex2f ( x + ( m_left_driveline[DRIVELINE_SIZE - 1].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[DRIVELINE_SIZE - 1].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x + ( m_left_driveline[0].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[0].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
|
|
||||||
//Close the right driveline
|
|
||||||
glVertex2f ( x + ( m_right_driveline[DRIVELINE_SIZE - 1].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[DRIVELINE_SIZE - 1].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x + ( m_right_driveline[0].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[0].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//FIXME: We are not sure if it's a videocard problem, but on Linux with a
|
|
||||||
//Nvidia Geforce4 mx 440, we get problems with GL_LINE_LOOP;
|
|
||||||
//If this issue is solved, using GL_LINE_LOOP is a better solution than
|
|
||||||
//GL_LINES
|
|
||||||
glBegin ( GL_LINE_LOOP ) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
glVertex2f ( x + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
}
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
glBegin ( GL_LINE_LOOP ) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
glVertex2f ( x + ( m_right_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
}
|
|
||||||
glEnd () ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
glBegin ( GL_POINTS ) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
glVertex2f ( x + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x + ( m_right_driveline[i].getX() - m_driveline_min.getX() ) * sx,
|
|
||||||
y + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * sy ) ;
|
|
||||||
}
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
glPopAttrib();
|
|
||||||
|
|
||||||
} // drawScaled2D
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void Track::draw2Dview (float x_offset, float y_offset) const
|
|
||||||
{
|
|
||||||
|
|
||||||
const unsigned int DRIVELINE_SIZE = (unsigned int)m_driveline.size();
|
|
||||||
|
|
||||||
glPushAttrib ( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT );
|
|
||||||
|
|
||||||
glEnable ( GL_BLEND );
|
|
||||||
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glDisable (GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
//TODO: maybe colors should be configurable, or at least the alpha value
|
|
||||||
glColor4f ( 1.0f, 1.0f, 1.0f, 0.4f) ;
|
|
||||||
|
|
||||||
|
|
||||||
/*FIXME: Too much calculations here, we should be generating scaled driveline arrays
|
|
||||||
* in Track::loadQuadGraph so all we'd be doing is pumping out predefined
|
|
||||||
* vertexes in-game.
|
|
||||||
*/
|
|
||||||
/*Draw white filling of the map*/
|
|
||||||
glBegin ( GL_QUAD_STRIP ) ;
|
|
||||||
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i ) {
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y) ;
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[i].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
}
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[0].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[0].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[0].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[0].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
|
|
||||||
glEnable( GL_LINE_SMOOTH );
|
|
||||||
glEnable( GL_POINT_SMOOTH );
|
|
||||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
|
||||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
|
||||||
|
|
||||||
glLineWidth(2);
|
|
||||||
glPointSize(2);
|
|
||||||
|
|
||||||
glColor4f ( 0,0,0,1) ;
|
|
||||||
|
|
||||||
|
|
||||||
glBegin ( GL_LINES ) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE - 1 ; ++i )
|
|
||||||
{
|
|
||||||
/*Draw left driveline of the map*/
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[i+1].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[i+1].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
|
|
||||||
/*Draw left driveline of the map*/
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[i].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[i+1].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[i+1].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Close the left driveline
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[DRIVELINE_SIZE - 1].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[DRIVELINE_SIZE - 1].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[0].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[0].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
|
|
||||||
//Close the right driveline
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[DRIVELINE_SIZE - 1].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[DRIVELINE_SIZE - 1].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[0].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[0].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//FIXME: We are not sure if it's a videocard problem, but on Linux with a
|
|
||||||
//Nvidia Geforce4 mx 440, we get problems with GL_LINE_LOOP;
|
|
||||||
//If this issue is solved, using GL_LINE_LOOP is a better solution than
|
|
||||||
//GL_LINES
|
|
||||||
glBegin ( GL_LINE_LOOP ) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
}
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
glBegin ( GL_LINE_LOOP ) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[i].get() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
}
|
|
||||||
glEnd () ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Because of the way OpenGL draws lines of widths higher than 1,
|
|
||||||
*we have to draw the joints too, in order to fill small spaces
|
|
||||||
*between lines
|
|
||||||
*/
|
|
||||||
glBegin ( GL_POINTS) ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
glVertex2f ( x_offset + ( m_left_driveline[i].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_left_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
|
|
||||||
glVertex2f ( x_offset + ( m_right_driveline[i].getX() - m_driveline_min.getX() ) * m_scale_x,
|
|
||||||
y_offset + ( m_right_driveline[i].getY() - m_driveline_min.getY() ) * m_scale_y ) ;
|
|
||||||
}
|
|
||||||
glEnd () ;
|
|
||||||
|
|
||||||
glPopAttrib();
|
|
||||||
|
|
||||||
} // draw2Dview
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Track::loadTrack(const std::string &filename)
|
void Track::loadTrack(const std::string &filename)
|
||||||
{
|
{
|
||||||
@ -453,7 +181,7 @@ void Track::loadTrack(const std::string &filename)
|
|||||||
m_gravity = 9.80665f;
|
m_gravity = 9.80665f;
|
||||||
m_sun_position = core::vector3df(0.4f, 0.4f, 0.4f);
|
m_sun_position = core::vector3df(0.4f, 0.4f, 0.4f);
|
||||||
m_sky_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f);
|
m_sky_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f);
|
||||||
m_fog_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f);
|
m_fog_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f).toSColor();
|
||||||
m_ambient_color = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f);
|
m_ambient_color = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f);
|
||||||
m_specular_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
m_specular_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
m_diffuse_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
m_diffuse_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
@ -600,136 +328,16 @@ void Track::loadQuadGraph()
|
|||||||
{
|
{
|
||||||
m_quad_graph = new QuadGraph(file_manager->getTrackFile(m_ident+".quads"),
|
m_quad_graph = new QuadGraph(file_manager->getTrackFile(m_ident+".quads"),
|
||||||
file_manager->getTrackFile(m_ident+".graph"));
|
file_manager->getTrackFile(m_ident+".graph"));
|
||||||
m_mini_map = m_quad_graph->makeMiniMap(core::dimension2di(128,128), m_ident);
|
m_mini_map = m_quad_graph->makeMiniMap(RaceManager::getWorld()->getRaceGUI()->getMiniMapSize(),
|
||||||
|
"minimap::"+m_ident);
|
||||||
if(m_quad_graph->getNumNodes()==0)
|
if(m_quad_graph->getNumNodes()==0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "No graph nodes defined for track '%s'\n",
|
fprintf(stderr, "No graph nodes defined for track '%s'\n",
|
||||||
m_filename.c_str());
|
m_filename.c_str());
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
readDrivelineFromFile(m_left_driveline, ".drvl");
|
|
||||||
|
|
||||||
const unsigned int DRIVELINE_SIZE = (unsigned int)m_left_driveline.size();
|
|
||||||
m_right_driveline.reserve(DRIVELINE_SIZE);
|
|
||||||
readDrivelineFromFile(m_right_driveline, ".drvr");
|
|
||||||
|
|
||||||
if(m_right_driveline.size() != m_left_driveline.size())
|
|
||||||
std::cout << "Error: driveline's sizes do not match, right " <<
|
|
||||||
"driveline is " << m_right_driveline.size() << " vertex long " <<
|
|
||||||
"and the left driveline is " << m_left_driveline.size()
|
|
||||||
<< " vertex long. Track is " << m_name << " ." << std::endl;
|
|
||||||
|
|
||||||
m_driveline.reserve(DRIVELINE_SIZE);
|
|
||||||
for(unsigned int i = 0; i < DRIVELINE_SIZE; ++i)
|
|
||||||
{
|
|
||||||
Vec3 center_point = (m_left_driveline[i]+m_right_driveline[i])*0.5;
|
|
||||||
m_driveline.push_back(center_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < DRIVELINE_SIZE; ++i)
|
|
||||||
{
|
|
||||||
unsigned int next = i + 1 >= DRIVELINE_SIZE ? 0 : i + 1;
|
|
||||||
float dx = m_driveline[next].getX() - m_driveline[i].getX();
|
|
||||||
float dy = m_driveline[next].getY() - m_driveline[i].getY();
|
|
||||||
|
|
||||||
float theta = -atan2(dx, dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_driveline_min = Vec3( 9999999.9f);
|
|
||||||
m_driveline_max = Vec3(-9999999.9f);
|
|
||||||
|
|
||||||
float d = 0.0f ;
|
|
||||||
for ( size_t i = 0 ; i < DRIVELINE_SIZE ; ++i )
|
|
||||||
{
|
|
||||||
//Both drivelines must be checked to get the true size of
|
|
||||||
//the drivelines, and using the center driveline is not
|
|
||||||
//good enough.
|
|
||||||
m_driveline_min.min(m_right_driveline[i]);
|
|
||||||
m_driveline_min.min(m_left_driveline[i] );
|
|
||||||
m_driveline_max.max(m_right_driveline[i]);
|
|
||||||
m_driveline_max.max(m_left_driveline[i] );
|
|
||||||
|
|
||||||
d += (m_driveline[i]-m_driveline[ i==DRIVELINE_SIZE-1 ? 0 : i+1 ]).length();
|
|
||||||
}
|
|
||||||
m_total_distance = d;
|
|
||||||
Vec3 sc = m_driveline_max - m_driveline_min;
|
|
||||||
|
|
||||||
m_scale_x = m_track_2d_width / sc.getX();
|
|
||||||
m_scale_y = m_track_2d_height / sc.getY();
|
|
||||||
|
|
||||||
if(!m_do_stretch) m_scale_x = m_scale_y = std::min(m_scale_x, m_scale_y);
|
|
||||||
|
|
||||||
} // loadQuadGraph
|
} // loadQuadGraph
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
Track::readDrivelineFromFile(std::vector<Vec3>& line, const std::string& file_ext)
|
|
||||||
{
|
|
||||||
std::string path = file_manager->getTrackFile(m_ident+file_ext);
|
|
||||||
FILE *fd = fopen ( path.c_str(), "r" ) ;
|
|
||||||
|
|
||||||
if ( fd == NULL )
|
|
||||||
{
|
|
||||||
std::ostringstream msg;
|
|
||||||
msg<<"Can't open '"<<path<<"' for reading.\n";
|
|
||||||
throw std::runtime_error(msg.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
int prev_sector = QuadGraph::UNKNOWN_SECTOR;
|
|
||||||
float prev_distance = 1.51f;
|
|
||||||
while(!feof(fd))
|
|
||||||
{
|
|
||||||
char s [ 1024 ] ;
|
|
||||||
|
|
||||||
if ( fgets ( s, 1023, fd ) == NULL )
|
|
||||||
break ;
|
|
||||||
|
|
||||||
if ( *s == '#' || *s < ' ' )
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
float x = 0.0f;
|
|
||||||
float y = 0.0f;
|
|
||||||
float z = 0.0f;
|
|
||||||
|
|
||||||
if (sscanf ( s, "%f,%f,%f", &x, &y, &z ) != 3 )
|
|
||||||
{
|
|
||||||
std::ostringstream msg;
|
|
||||||
msg<<"Syntax error in '"<<path<<"'\n";
|
|
||||||
throw std::runtime_error(msg.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3 point(x,y,z);
|
|
||||||
|
|
||||||
if(prev_sector != QuadGraph::UNKNOWN_SECTOR)
|
|
||||||
prev_distance = (point-line[prev_sector]).length2_2d();
|
|
||||||
|
|
||||||
//1.5f was choosen because it's more or less the length of the tuxkart
|
|
||||||
if(prev_distance < 0.0000001)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "File %s point %d is duplicated!.\n",
|
|
||||||
path.c_str(), prev_sector+1);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
else if(prev_distance < 1.5f)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"File %s point %d is too close(<1.5) to previous point.\n",
|
|
||||||
path.c_str(), prev_sector + 1);
|
|
||||||
}
|
|
||||||
if(prev_distance > 15.0f)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"In file %s point %d is too far(>15.0) from next point at %d.\n",
|
|
||||||
path, prev_sector, prev_distance);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
line.push_back(point);
|
|
||||||
++prev_sector;
|
|
||||||
prev_distance -= 1.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose ( fd ) ;
|
|
||||||
} // readDrivelineFromFile
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
//* Convert the ssg track tree into its physics equivalents.
|
//* Convert the ssg track tree into its physics equivalents.
|
||||||
void Track::createPhysicsModel()
|
void Track::createPhysicsModel()
|
||||||
@ -965,6 +573,11 @@ void Track::createWater(const XMLNode &node)
|
|||||||
*/
|
*/
|
||||||
void Track::loadTrackModel()
|
void Track::loadTrackModel()
|
||||||
{
|
{
|
||||||
|
// Load the graph only now: this function is called from world, after
|
||||||
|
// the race gui was created. The race gui is needed since it stores
|
||||||
|
// the information about the size of the texture to render the mini
|
||||||
|
// map to.
|
||||||
|
loadQuadGraph();
|
||||||
// Add the track directory to the texture search path
|
// Add the track directory to the texture search path
|
||||||
file_manager->pushTextureSearchPath(file_manager->getTrackFile("",getIdent()));
|
file_manager->pushTextureSearchPath(file_manager->getTrackFile("",getIdent()));
|
||||||
file_manager->pushModelSearchPath (file_manager->getTrackFile("",getIdent()));
|
file_manager->pushModelSearchPath (file_manager->getTrackFile("",getIdent()));
|
||||||
@ -1106,11 +719,10 @@ void Track::loadTrackModel()
|
|||||||
file_manager->popTextureSearchPath();
|
file_manager->popTextureSearchPath();
|
||||||
file_manager->popModelSearchPath ();
|
file_manager->popModelSearchPath ();
|
||||||
|
|
||||||
const core::vector3df &sun_pos = getSunPos();
|
|
||||||
|
|
||||||
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 120, 120, 120));
|
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 120, 120, 120));
|
||||||
|
|
||||||
m_light = irr_driver->getSceneManager()->addLightSceneNode(NULL, sun_pos, video::SColorf(1.0f,1.0f,1.0f));
|
m_light = irr_driver->getSceneManager()->addLightSceneNode(NULL, m_sun_position,
|
||||||
|
video::SColorf(1.0f,1.0f,1.0f));
|
||||||
m_light->setLightType(video::ELT_DIRECTIONAL);
|
m_light->setLightType(video::ELT_DIRECTIONAL);
|
||||||
m_light->setRotation( core::vector3df(180, 45, 45) );
|
m_light->setRotation( core::vector3df(180, 45, 45) );
|
||||||
|
|
||||||
@ -1118,13 +730,17 @@ void Track::loadTrackModel()
|
|||||||
m_light->getLightData().SpecularColor = irr::video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
m_light->getLightData().SpecularColor = irr::video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
m_light = irr_driver->getSceneManager()->addLightSceneNode(0, sun_pos);
|
m_light = irr_driver->getSceneManager()->addLightSceneNode(0, m_sun_position);
|
||||||
video::SLight light;
|
video::SLight light;
|
||||||
// HACK & TEST: checking how ambient looks for some things, must be properly done once we reach an agreement
|
// HACK & TEST: checking how ambient looks for some things, must be properly done once we reach an agreement
|
||||||
light.AmbientColor = irr::video::SColorf(0.666666f, 0.666666f, 0.666666f, 0.0f);
|
light.AmbientColor = irr::video::SColorf(0.666666f, 0.666666f, 0.666666f, 0.0f);
|
||||||
m_light->setLightData(light);
|
m_light->setLightData(light);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if(m_use_fog)
|
||||||
|
{
|
||||||
|
irr_driver->getVideoDriver()->setFog(m_fog_color, true, m_fog_start, m_fog_end, m_fog_density);
|
||||||
|
}
|
||||||
|
|
||||||
// Note: the physics world for irrlicht is created in loadMainTrack
|
// Note: the physics world for irrlicht is created in loadMainTrack
|
||||||
createPhysicsModel();
|
createPhysicsModel();
|
||||||
|
@ -72,13 +72,14 @@ private:
|
|||||||
Vec3 m_camera_final_hpr;
|
Vec3 m_camera_final_hpr;
|
||||||
bool m_is_arena;
|
bool m_is_arena;
|
||||||
int m_version;
|
int m_version;
|
||||||
bool loadMainTrack(const XMLNode &node);
|
|
||||||
void createWater(const XMLNode &node);
|
|
||||||
/** The graph used to connect the quads. */
|
/** The graph used to connect the quads. */
|
||||||
QuadGraph *m_quad_graph;
|
QuadGraph *m_quad_graph;
|
||||||
|
|
||||||
/** The type of sky to be used for the track. */
|
/** The type of sky to be used for the track. */
|
||||||
enum {SKY_NONE, SKY_BOX,
|
enum {SKY_NONE, SKY_BOX,
|
||||||
SKY_DOME} m_sky_type;
|
SKY_DOME} m_sky_type;
|
||||||
|
|
||||||
/** A list of the textures for the sky to use. It contains one texture
|
/** A list of the textures for the sky to use. It contains one texture
|
||||||
* in case of a dome, and 6 textures for a box. */
|
* in case of a dome, and 6 textures for a box. */
|
||||||
std::vector<std::string> m_sky_textures;
|
std::vector<std::string> m_sky_textures;
|
||||||
@ -100,6 +101,18 @@ private:
|
|||||||
/** If a sky dome is used, percentage of the texture to be used. */
|
/** If a sky dome is used, percentage of the texture to be used. */
|
||||||
float m_sky_texture_percent;
|
float m_sky_texture_percent;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
bool m_use_fog;
|
||||||
|
float m_fog_density;
|
||||||
|
float m_fog_start;
|
||||||
|
float m_fog_end;
|
||||||
|
core::vector3df m_sun_position;
|
||||||
|
video::SColorf m_ambient_color;
|
||||||
|
video::SColorf m_specular_color;
|
||||||
|
video::SColorf m_diffuse_color;
|
||||||
|
video::SColorf m_sky_color;
|
||||||
|
video::SColor m_fog_color;
|
||||||
|
|
||||||
/** The texture for the mini map, which is displayed in the race gui. */
|
/** The texture for the mini map, which is displayed in the race gui. */
|
||||||
video::ITexture *m_mini_map;
|
video::ITexture *m_mini_map;
|
||||||
|
|
||||||
@ -112,86 +125,60 @@ private:
|
|||||||
/** Checkline manager. */
|
/** Checkline manager. */
|
||||||
CheckManager *m_check_manager;
|
CheckManager *m_check_manager;
|
||||||
|
|
||||||
|
void loadTrack(const std::string &filename);
|
||||||
|
void itemCommand(const Vec3 &xyz, Item::ItemType item_type,
|
||||||
|
int bNeedHeight);
|
||||||
|
void loadQuadGraph();
|
||||||
|
void convertTrackToBullet(const scene::IMesh *mesh);
|
||||||
|
bool loadMainTrack(const XMLNode &node);
|
||||||
|
void createWater(const XMLNode &node);
|
||||||
|
void getMusicInformation(std::vector<std::string>& filenames,
|
||||||
|
std::vector<MusicInformation*>& m_music );
|
||||||
void loadCurves(const XMLNode &node);
|
void loadCurves(const XMLNode &node);
|
||||||
void handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml);
|
void handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string m_name;
|
|
||||||
bool m_use_fog;
|
|
||||||
float m_fog_density;
|
|
||||||
float m_fog_start;
|
|
||||||
float m_fog_end;
|
|
||||||
core::vector3df m_sun_position;
|
|
||||||
video::SColorf m_ambient_color;
|
|
||||||
video::SColorf m_specular_color;
|
|
||||||
video::SColorf m_diffuse_color;
|
|
||||||
video::SColorf m_sky_color;
|
|
||||||
video::SColorf m_fog_color;
|
|
||||||
|
|
||||||
//FIXME: Maybe the next 4 vectors should be inside an struct and be used
|
|
||||||
//from a vector of structs?
|
|
||||||
//FIXME: should the driveline be set as a sgVec2?
|
|
||||||
private:
|
|
||||||
std::vector<Vec3> m_driveline;
|
|
||||||
//Left and Right drivelines for overhead map rendering.
|
|
||||||
std::vector<Vec3> m_left_driveline;
|
|
||||||
std::vector<Vec3> m_right_driveline;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Start positions for arenas (unused in linear races) */
|
/** Start positions for arenas (unused in linear races) */
|
||||||
std::vector<Vec3> m_start_positions;
|
std::vector<Vec3> m_start_positions;
|
||||||
|
|
||||||
|
|
||||||
Vec3 m_driveline_min;
|
|
||||||
Vec3 m_driveline_max;
|
|
||||||
|
|
||||||
|
|
||||||
float m_total_distance;
|
|
||||||
static const float NOHIT;
|
static const float NOHIT;
|
||||||
|
|
||||||
float m_track_2d_width, // Width and heigth of the 2d display of the track
|
Track (std::string filename);
|
||||||
m_track_2d_height;
|
|
||||||
float m_scale_x, // Scaling to fit track into the size determined by
|
|
||||||
m_scale_y; // track2dWidth/Heightheigth
|
|
||||||
bool m_do_stretch; // 2d track display might be stretched to fit better
|
|
||||||
|
|
||||||
Track (std::string filename,float w=100,
|
|
||||||
float h=100, bool stretch=1);
|
|
||||||
~Track ();
|
~Track ();
|
||||||
bool isArena () const { return m_is_arena; }
|
bool isArena () const { return m_is_arena; }
|
||||||
void cleanup ();
|
void cleanup ();
|
||||||
/** Returns the texture with the mini map for this track. */
|
/** Returns the texture with the mini map for this track. */
|
||||||
const video::ITexture*getMiniMap () const { return m_mini_map; }
|
const video::ITexture*getMiniMap () const { return m_mini_map; }
|
||||||
void draw2Dview (float x_offset,
|
|
||||||
float y_offset ) const;
|
|
||||||
void drawScaled2D (float x, float y, float w,
|
|
||||||
float h ) const;
|
|
||||||
|
|
||||||
const Vec3& trackToSpatial (const int SECTOR) const;
|
const Vec3& trackToSpatial (const int SECTOR) const;
|
||||||
void loadTrackModel ();
|
void loadTrackModel ();
|
||||||
void addMusic (MusicInformation* mi)
|
void addMusic (MusicInformation* mi)
|
||||||
{m_music.push_back(mi); }
|
{m_music.push_back(mi); }
|
||||||
float getGravity () const {return m_gravity; }
|
float getGravity () const {return m_gravity; }
|
||||||
|
|
||||||
/** Returns the version of the .track file. */
|
/** Returns the version of the .track file. */
|
||||||
int getVersion () const {return m_version; }
|
int getVersion () const {return m_version; }
|
||||||
float getTrackLength () const {return m_total_distance; }
|
|
||||||
|
/** 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; }
|
const std::string& getIdent () const {return m_ident; }
|
||||||
const char* getName () const {return m_name.c_str(); }
|
|
||||||
|
/** Returns the name of the track, which is e.g. displayed on the screen. */
|
||||||
|
|
||||||
|
const std::string& getName () const {return m_name; }
|
||||||
|
|
||||||
|
/** Returns all groups this track belongs to. */
|
||||||
const std::vector<std::string>
|
const std::vector<std::string>
|
||||||
getGroups () const {return m_groups; }
|
getGroups () const {return m_groups; }
|
||||||
|
|
||||||
|
/** Starts the music for this track. */
|
||||||
void startMusic () const;
|
void startMusic () const;
|
||||||
|
|
||||||
|
/** Returns the filename of this track. */
|
||||||
const std::string& getFilename () const {return m_filename; }
|
const std::string& getFilename () const {return m_filename; }
|
||||||
const core::vector3df& getSunPos () const {return m_sun_position; }
|
|
||||||
const video::SColorf& getAmbientCol () const {return m_ambient_color; }
|
|
||||||
const video::SColorf& getDiffuseCol () const {return m_diffuse_color; }
|
|
||||||
const video::SColorf& getSpecularCol () const {return m_specular_color; }
|
|
||||||
const video::SColorf& getFogColor () const {return m_fog_color; }
|
|
||||||
const video::SColorf& getSkyColor () const {return m_sky_color; }
|
|
||||||
const bool& useFog () const {return m_use_fog; }
|
|
||||||
const float& getFogDensity () const {return m_fog_density; }
|
|
||||||
const float& getFogStart () const {return m_fog_start; }
|
|
||||||
const float& getFogEnd () const {return m_fog_end; }
|
|
||||||
const std::string& getDescription () const {return m_description; }
|
const std::string& getDescription () const {return m_description; }
|
||||||
const std::string& getDesigner () const {return m_designer; }
|
const std::string& getDesigner () const {return m_designer; }
|
||||||
const std::string& getScreenshotFile () const {return m_screenshot; }
|
const std::string& getScreenshotFile () const {return m_screenshot; }
|
||||||
@ -219,25 +206,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
float getAngle(int n) const
|
float getAngle(int n) const
|
||||||
{ return m_quad_graph->getAngleToNext(n, 0); }
|
{ return m_quad_graph->getAngleToNext(n, 0); }
|
||||||
/*
|
/** Returns the 2d coordinates of a point when drawn on the mini map
|
||||||
void glVtx (sgVec2 v, float x_offset, float y_offset) const
|
* texture.
|
||||||
{
|
* \param xyz Coordinates of the point to map.
|
||||||
glVertex2f(
|
* \param draw_at The coordinates in pixel on the mini map of the point,
|
||||||
x_offset+(v[0]-m_driveline_min[0])*m_scale_x,
|
* only the first two coordinates will be used.
|
||||||
y_offset+(v[1]-m_driveline_min[1])*m_scale_y);
|
*/
|
||||||
}*/
|
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *draw_at) const
|
||||||
|
{ m_quad_graph->mapPoint2MiniMap(xyz, draw_at); }
|
||||||
private:
|
}; // class Track
|
||||||
void loadTrack(const std::string &filename);
|
|
||||||
void itemCommand(const Vec3 &xyz, Item::ItemType item_type,
|
|
||||||
int bNeedHeight);
|
|
||||||
void loadQuadGraph();
|
|
||||||
void readDrivelineFromFile(std::vector<Vec3>& line,
|
|
||||||
const std::string& file_ext);
|
|
||||||
void convertTrackToBullet(const scene::IMesh *mesh);
|
|
||||||
void getMusicInformation(std::vector<std::string>& filenames,
|
|
||||||
std::vector<MusicInformation*>& m_music );
|
|
||||||
}
|
|
||||||
; // class Track
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user