Improved shortcut handling:
1) on road/off road is now detected with a certain tolerance to the drivelines (currently 15%), i.e. the drivelines are made 15% wider. 2) Skipped segments distance was shortened to 50m (since it should be used less with the above higher tolerance, and it caused problems with shortcut not being detected. 3) The new drivelines with tolerance can be seen with --track-debug=4 (--track-debug=2 shows the original drivelines) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2890 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
bddf82e272
commit
2c0a135d94
@ -39,8 +39,9 @@
|
||||
(zipper-force 250.0 ) ;; additional zipper force
|
||||
(zipper-speed-gain 4.5 ) ;; one time additional speed
|
||||
|
||||
(shortcut-length 120 ) ;; leaving the road and coming back on it more than
|
||||
(shortcut-length 50 ) ;; leaving the road and coming back on it more than
|
||||
;; x 'meters" later is considered to be a shortcut
|
||||
(offroad-tolerance 0.15) ;; Widen the road 15% for shortcut detection.
|
||||
(enable_networking #f ) ;; For now disable networking
|
||||
(explosion-impulse 10000.0 ) ;; explosion impulse on not directly hit karts
|
||||
(explosion-impulse-objects 500.0) ;; explosion impulse for physics objects (smaller
|
||||
|
@ -451,12 +451,13 @@ void InitTuxkart()
|
||||
highscore_manager = new HighscoreManager ();
|
||||
grand_prix_manager = new GrandPrixManager ();
|
||||
network_manager = new NetworkManager ();
|
||||
|
||||
stk_config->load(file_manager->getConfigFile("stk_config.data"));
|
||||
track_manager->loadTrackList();
|
||||
// Check needs GP and track manager.
|
||||
// unlock_manager->check needs GP and track manager.
|
||||
unlock_manager->check();
|
||||
sound_manager->addMusicToTracks();
|
||||
|
||||
stk_config->load(file_manager->getConfigFile("stk_config.data"));
|
||||
race_manager = new RaceManager ();
|
||||
// default settings for Quickstart
|
||||
race_manager->setNumPlayers(1);
|
||||
|
@ -149,8 +149,9 @@ void LinearWorld::update(float delta)
|
||||
|
||||
// update sector variables
|
||||
int prev_sector = kart_info.m_track_sector;
|
||||
m_track->findRoadSector( kart->getXYZ(), &kart_info.m_track_sector);
|
||||
|
||||
m_track->findRoadSector( kart->getXYZ(), &kart_info.m_track_sector,
|
||||
/*tolerance*/ true);
|
||||
|
||||
// Check if the kart is taking a shortcut (if it's not already doing one):
|
||||
// -----------------------------------------------------------------------
|
||||
kart_info.m_on_road = kart_info.m_track_sector != Track::UNKNOWN_SECTOR;
|
||||
|
@ -108,6 +108,7 @@ void STKConfig::load(const std::string &filename)
|
||||
CHECK_NEG(m_zipper_force, "zipper-force" );
|
||||
CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" );
|
||||
CHECK_NEG(m_shortcut_length, "shortcut-length" );
|
||||
CHECK_NEG(m_offroad_tolerance, "offroad-tolerance" );
|
||||
CHECK_NEG(m_explosion_impulse, "explosion-impulse" );
|
||||
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
|
||||
CHECK_NEG(m_max_history, "max-history" );
|
||||
@ -135,7 +136,7 @@ void STKConfig::init_defaults()
|
||||
m_explosion_impulse = m_explosion_impulse_objects =
|
||||
m_shortcut_length = m_music_credit_time =
|
||||
m_delay_finish_time = m_skid_fadeout_time =
|
||||
m_slowdown_factor =
|
||||
m_slowdown_factor = m_offroad_tolerance =
|
||||
UNDEFINED;
|
||||
m_max_karts = -100;
|
||||
m_grid_order = -100;
|
||||
@ -175,7 +176,8 @@ void STKConfig::getAllData(const lisp::Lisp* lisp)
|
||||
// Get the values which are not part of the default KartProperties
|
||||
// ---------------------------------------------------------------
|
||||
lisp->get("anvil-weight", m_anvil_weight );
|
||||
lisp->get("shortcut-length", m_shortcut_length );
|
||||
lisp->get("shortcut-length", m_shortcut_length );
|
||||
lisp->get("offroad-tolerance", m_offroad_tolerance );
|
||||
lisp->get("anvil-speed-factor", m_anvil_speed_factor );
|
||||
lisp->get("parachute-friction", m_parachute_friction );
|
||||
lisp->get("parachute-time", m_parachute_time );
|
||||
|
@ -55,6 +55,9 @@ public:
|
||||
float m_zipper_speed_gain; /**<Initial one time speed gain. */
|
||||
float m_shortcut_length; /**<Skipping more than this distance
|
||||
in segments triggers a shortcut. */
|
||||
float m_offroad_tolerance; /**<Road width is extended by that
|
||||
fraction to make shortcut detection
|
||||
more forgiving. */
|
||||
float m_explosion_impulse; /**<Impulse affecting each non-hit kart.*/
|
||||
float m_explosion_impulse_objects;/**<Impulse of explosion on moving
|
||||
objects, e.g. road cones, ... */
|
||||
|
@ -141,17 +141,37 @@ int Track::pointInQuad
|
||||
*
|
||||
* The 'sector' could be defined as the number of the closest track
|
||||
* segment to XYZ.
|
||||
* \param XYZ Position for which the segment should be determined.
|
||||
* \param sector Contains the previous sector (as a shortcut, since usually
|
||||
* the sector is the same as the last one), and on return the result
|
||||
* \param with_tolerance If true, the drivelines with tolerance are used.
|
||||
* This reduces the impact of driving slightly off road.
|
||||
*/
|
||||
void Track::findRoadSector(const Vec3& XYZ, int *sector )const
|
||||
void Track::findRoadSector(const Vec3& XYZ, int *sector,
|
||||
bool with_tolerance )const
|
||||
{
|
||||
if(*sector!=UNKNOWN_SECTOR)
|
||||
{
|
||||
int next = (unsigned)(*sector) + 1 < m_left_driveline.size() ? *sector + 1 : 0;
|
||||
if(pointInQuad( m_left_driveline[*sector], m_right_driveline[*sector],
|
||||
m_right_driveline[next], m_left_driveline[next],
|
||||
XYZ ) != QUAD_TRI_NONE)
|
||||
// Still in the same sector, no changes
|
||||
return;
|
||||
if(with_tolerance)
|
||||
{
|
||||
if(pointInQuad(m_dl_with_tolerance_left[*sector],
|
||||
m_dl_with_tolerance_right[*sector],
|
||||
m_dl_with_tolerance_right[next],
|
||||
m_dl_with_tolerance_left[next],
|
||||
XYZ ) != QUAD_TRI_NONE)
|
||||
// Still in the same sector, no changes
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pointInQuad(m_left_driveline[*sector],
|
||||
m_right_driveline[*sector],
|
||||
m_right_driveline[next],
|
||||
m_left_driveline[next], XYZ ) != QUAD_TRI_NONE)
|
||||
// Still in the same sector, no changes
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* To find in which 'sector' of the track the kart is, we use a
|
||||
'point in triangle' algorithm for each triangle in the quad
|
||||
@ -165,9 +185,14 @@ void Track::findRoadSector(const Vec3& XYZ, int *sector )const
|
||||
for( size_t i = 0; i < DRIVELINE_SIZE ; ++i )
|
||||
{
|
||||
next = (unsigned int)i + 1 < DRIVELINE_SIZE ? (int)i + 1 : 0;
|
||||
triangle = pointInQuad( m_left_driveline[i], m_right_driveline[i],
|
||||
m_right_driveline[next], m_left_driveline[next],
|
||||
XYZ );
|
||||
triangle = with_tolerance
|
||||
? pointInQuad(m_dl_with_tolerance_left[i],
|
||||
m_dl_with_tolerance_right[i],
|
||||
m_dl_with_tolerance_right[next],
|
||||
m_dl_with_tolerance_left[next], XYZ )
|
||||
: pointInQuad(m_left_driveline[i], m_right_driveline[i],
|
||||
m_right_driveline[next], m_left_driveline[next],
|
||||
XYZ );
|
||||
|
||||
if (triangle != QUAD_TRI_NONE && ((XYZ.getZ()-m_left_driveline[i].getZ()) < 1.0f))
|
||||
{
|
||||
@ -202,6 +227,9 @@ void Track::findRoadSector(const Vec3& XYZ, int *sector )const
|
||||
segment = possible_segment_tris[i].segment;
|
||||
next = segment + 1 < DRIVELINE_SIZE ? (int)segment + 1 : 0;
|
||||
|
||||
// Note: we can make the plane with the normal driveliens
|
||||
// (not the one with tolerance), since the driveliens with
|
||||
// tolerance lie in the same plane.
|
||||
if( possible_segment_tris[i].triangle == QUAD_TRI_FIRST )
|
||||
{
|
||||
sgMakePlane( plane, m_left_driveline[segment].toFloat(),
|
||||
@ -500,20 +528,25 @@ void Track::addDebugToScene(int type) const
|
||||
scene->add(sphere);
|
||||
} // for i
|
||||
} /// type ==1
|
||||
if(type&2)
|
||||
// 2: drivelines, 4: driveline with tolerance
|
||||
if(type&6)
|
||||
{
|
||||
ssgVertexArray* v_array = new ssgVertexArray();
|
||||
ssgColourArray* c_array = new ssgColourArray();
|
||||
const std::vector<Vec3> &left = type&2 ? m_left_driveline
|
||||
: m_dl_with_tolerance_left;
|
||||
const std::vector<Vec3> &right = type&2 ? m_right_driveline
|
||||
: m_dl_with_tolerance_right;
|
||||
for(unsigned int i = 0; i < m_driveline.size(); i++)
|
||||
{
|
||||
int ip1 = i==m_driveline.size()-1 ? 0 : i+1;
|
||||
// The segment display must be slightly higher than the
|
||||
// track, otherwise it's not clearly visible.
|
||||
sgVec3 v;
|
||||
sgCopyVec3(v,m_left_driveline [i ].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgCopyVec3(v,m_right_driveline[i ].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgCopyVec3(v,m_right_driveline[ip1].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgCopyVec3(v,m_left_driveline [ip1].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgCopyVec3(v,left [i ].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgCopyVec3(v,right[i ].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgCopyVec3(v,right[ip1].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgCopyVec3(v,left [ip1].toFloat()); v[2]+=0.1f; v_array->add(v);
|
||||
sgVec4 vc;
|
||||
vc[0] = i%2==0 ? 1.0f : 0.0f;
|
||||
vc[1] = 1.0f-v[0];
|
||||
@ -902,8 +935,7 @@ void Track::startMusic() const {
|
||||
} // startMusic
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
Track::loadDriveline()
|
||||
void Track::loadDriveline()
|
||||
{
|
||||
readDrivelineFromFile(m_left_driveline, ".drvl");
|
||||
|
||||
@ -917,6 +949,8 @@ Track::loadDriveline()
|
||||
"and the left driveline is " << m_left_driveline.size()
|
||||
<< " vertex long. Track is " << m_name << " ." << std::endl;
|
||||
|
||||
m_dl_with_tolerance_left.reserve(DRIVELINE_SIZE);
|
||||
m_dl_with_tolerance_right.reserve(DRIVELINE_SIZE);
|
||||
m_driveline.reserve(DRIVELINE_SIZE);
|
||||
m_path_width.reserve(DRIVELINE_SIZE);
|
||||
m_angle.reserve(DRIVELINE_SIZE);
|
||||
@ -927,6 +961,13 @@ Track::loadDriveline()
|
||||
|
||||
float width = ( m_right_driveline[i] - center_point ).length();
|
||||
m_path_width.push_back(width);
|
||||
|
||||
// Compute the drivelines with tolerance
|
||||
Vec3 diff = (m_left_driveline[i] - m_right_driveline[i])
|
||||
* stk_config->m_offroad_tolerance;
|
||||
m_dl_with_tolerance_left.push_back(m_left_driveline[i]+diff);
|
||||
m_dl_with_tolerance_right.push_back(m_right_driveline[i]-diff);
|
||||
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < DRIVELINE_SIZE; ++i)
|
||||
|
@ -97,7 +97,11 @@ public:
|
||||
//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?
|
||||
std::vector<Vec3> m_driveline;
|
||||
std::vector<Vec3> m_driveline;
|
||||
/** Same as drivelines, but with stk_config->m_offroad_tolerance applied
|
||||
* to widen the road (to make shortcut detection less severe). */
|
||||
std::vector<Vec3> m_dl_with_tolerance_left;
|
||||
std::vector<Vec3> m_dl_with_tolerance_right;
|
||||
std::vector<SGfloat> m_distance_from_start;
|
||||
std::vector<SGfloat> m_path_width;
|
||||
std::vector<SGfloat> m_angle;
|
||||
@ -134,7 +138,8 @@ public:
|
||||
void drawScaled2D (float x, float y, float w,
|
||||
float h ) const;
|
||||
|
||||
void findRoadSector (const Vec3& XYZ, int *sector) const;
|
||||
void findRoadSector (const Vec3& XYZ, int *sector,
|
||||
bool with_tolerance=false) const;
|
||||
int findOutOfRoadSector(const Vec3& XYZ,
|
||||
const RoadSide SIDE,
|
||||
const int CURR_SECTOR
|
||||
|
Loading…
x
Reference in New Issue
Block a user