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:
@@ -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
|
||||
|
||||
@@ -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]; }
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user