Fixed potential incorrect order of karts when a kart is off track.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4999 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2010-03-15 09:21:21 +00:00
parent 9287258788
commit 35925432d5
3 changed files with 41 additions and 3 deletions

View File

@@ -44,6 +44,9 @@ Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3,
m_min_height = std::min ( std::min(p0.getY(), p1.getY()),
std::min(p0.getY(), p1.getY()) );
m_invisible = invisible;
m_lower_center = 0.5f*(m_p[0]+m_p[1]);
m_upper_center = 0.5f*(m_p[2]+m_p[3]);
} // Quad
// ----------------------------------------------------------------------------
@@ -113,10 +116,24 @@ bool Quad::pointInQuad(const Vec3& p) const
* \param result The quad which stores the result.
*/
void Quad::transform(const btTransform &t, Quad *result) const
{
result->m_p[0] = t(m_p[0]);
result->m_p[1] = t(m_p[1]);
result->m_p[2] = t(m_p[2]);
result->m_p[3] = t(m_p[3]);
} // transform
// ----------------------------------------------------------------------------
/** Returns true if the orthognal projection of the point xyz on the center
* line of this quad is inside this quad. This is used when determining
* on which quad a kart is if it is off-track.
* \param xyz The coordinates to project.
* \return True if the orthognal projection is inside this quad.
*/
bool Quad::projectionIsInside(const Vec3 &xyz) const
{
Vec3 v1 = xyz-m_lower_center;
Vec3 v2 = m_upper_center - m_lower_center;
float ratio = v1.dot(v2) / (m_upper_center-m_lower_center).length2();
return ratio>=0 && ratio <=1.0f;
} // projectionIsInside

View File

@@ -37,6 +37,11 @@ private:
* This saves some computations at runtime. */
Vec3 m_center;
/** The middle points of the 'lower' and 'upper' lines. The line
* connecting these two points is used in projectionIsInside().
*/
Vec3 m_lower_center, m_upper_center;
/** The minimum height of the quad, used in case that several quads
* are on top of each other when determining the sector a kart is on. */
float m_min_height;
@@ -51,6 +56,7 @@ public:
void getVertices(video::S3DVertex *v, const video::SColor &color) const;
bool pointInQuad(const Vec3& p) const;
void transform(const btTransform &t, Quad *result) const;
bool projectionIsInside(const Vec3 &xyz) const;
// ------------------------------------------------------------------------
/** Returns the i-th. point of a quad. */
const Vec3& operator[](int i) const {return m_p[i]; }

View File

@@ -446,11 +446,26 @@ int QuadGraph::findOutOfRoadSector(const Vec3& xyz,
else
next_sector = current_sector+1 == (int)getNumNodes() ? 0 : current_sector+1;
// A first simple test uses the 2d distance to the center of the quad.
float dist_2 = xyz.distance2(getQuad(next_sector).getCenter()-xyz);
if(dist_2<min_dist_2)
{
min_dist_2 = dist_2;
min_sector = next_sector;
// If the current quad's center is closer to the kart than the
// previously determined minimum, test if the kart's projected
// position on the center line of the quad is still in the
// same quad. Consider the following situation:
// +-----------------+-----+
// | A | B |
// +-----------------+-----+
// X
// A kart at position X will be closer to the center of quad B
// than to quad A, but it should be considered to be on quad
// A!
if(getQuad(next_sector).projectionIsInside(xyz))
{
min_dist_2 = dist_2;
min_sector = next_sector;
}
}
current_sector = next_sector;
} // for j