bced8cdb9f
patch). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@14605 178a84e3-b1eb-0310-8ba1-8eac791a3b58
137 lines
5.5 KiB
C++
137 lines
5.5 KiB
C++
//
|
|
// SuperTuxKart - a fun racing game with go-kart
|
|
// Copyright (C) 2009-2013 Joerg Henrichs
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 3
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
#include "tracks/quad.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <S3DVertex.h>
|
|
#include <triangle3d.h>
|
|
|
|
#include "LinearMath/btTransform.h"
|
|
|
|
/** Constructor, takes 4 points. */
|
|
Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3,
|
|
bool invisible, bool ai_ignore)
|
|
{
|
|
if(p1.sideOfLine2D(p0, p2)>0 ||
|
|
p3.sideOfLine2D(p0, p2)<0)
|
|
{
|
|
printf("Warning: quad has wrong orientation: p0=%f %f %f p1=%f %f %f\n",
|
|
p0.getX(), p0.getY(), p0.getZ(),p1.getX(), p1.getY(), p1.getZ());
|
|
printf("The quad will be swapped, nevertheless test for correctness -\n");
|
|
printf("quads must be counter-clockwise oriented.\n");
|
|
m_p[0]=p1; m_p[1]=p0; m_p[2]=p3; m_p[3]=p2;
|
|
}
|
|
else
|
|
{
|
|
m_p[0]=p0; m_p[1]=p1; m_p[2]=p2; m_p[3]=p3;
|
|
}
|
|
m_center = 0.25f*(p0+p1+p2+p3);
|
|
m_min_height = std::min ( std::min(p0.getY(), p1.getY()),
|
|
std::min(p2.getY(), p3.getY()) );
|
|
m_max_height = std::max ( std::max(p0.getY(), p1.getY()),
|
|
std::max(p2.getY(), p3.getY()) );
|
|
m_invisible = invisible;
|
|
m_ai_ignore = ai_ignore;
|
|
|
|
} // Quad
|
|
|
|
// ----------------------------------------------------------------------------
|
|
/** Sets the vertices in a irrlicht vertex array to the 4 points of this quad.
|
|
* \param v The vertex array in which to set the vertices.
|
|
* \param color The color to use for this quad.
|
|
*/
|
|
void Quad::getVertices(video::S3DVertex *v, const video::SColor &color) const
|
|
{
|
|
// Eps is used to raise the track debug quads a little bit higher than
|
|
// the ground, so that they are actually visible.
|
|
core::vector3df eps(0, 0.1f, 0);
|
|
v[0].Pos = m_p[0].toIrrVector()+eps;
|
|
v[1].Pos = m_p[1].toIrrVector()+eps;
|
|
v[2].Pos = m_p[2].toIrrVector()+eps;
|
|
v[3].Pos = m_p[3].toIrrVector()+eps;
|
|
|
|
core::triangle3df tri(m_p[0].toIrrVector(), m_p[1].toIrrVector(),
|
|
m_p[2].toIrrVector());
|
|
core::vector3df normal = tri.getNormal();
|
|
normal.normalize();
|
|
v[0].Normal = normal;
|
|
v[1].Normal = normal;
|
|
v[2].Normal = normal;
|
|
|
|
core::triangle3df tri1(m_p[0].toIrrVector(), m_p[2].toIrrVector(),
|
|
m_p[3].toIrrVector());
|
|
core::vector3df normal1 = tri1.getNormal();
|
|
normal1.normalize();
|
|
v[3].Normal = normal1;
|
|
|
|
v[0].Color = color;
|
|
v[1].Color = color;
|
|
v[2].Color = color;
|
|
v[3].Color = color;
|
|
} // setVertices
|
|
|
|
// ----------------------------------------------------------------------------
|
|
bool Quad::pointInQuad(const Vec3& p) const
|
|
{
|
|
// In case that a kart can validly run too high over one driveline
|
|
// and it should not be considered to be on that driveline. Example:
|
|
// a kart is driving over a bridge, slightly off the bridge
|
|
// driveline. It must be avoided that the kart is then considered
|
|
// to be on the driveline under the brige. So the vertical distance
|
|
// is taken into account, too. to simplify this test we only compare
|
|
// with the minimum height of the quad (and not with the actual
|
|
// height of the quad at the point where the kart is).
|
|
if(p.getY() - m_max_height > 5.0f ||
|
|
p.getY() - m_min_height < -1.0f )
|
|
return false;
|
|
|
|
// If a point is exactly on the line of two quads (e.g. between points
|
|
// 0,1 on one quad, and 3,2 of the previous quad), assign this point
|
|
// to be on the 'later' quad, i.e. on the line between points 0 and 1.
|
|
if(p.sideOfLine2D(m_p[0], m_p[2])<0) {
|
|
return p.sideOfLine2D(m_p[0], m_p[1]) >= 0.0 &&
|
|
p.sideOfLine2D(m_p[1], m_p[2]) >= 0.0;
|
|
} else {
|
|
return p.sideOfLine2D(m_p[2], m_p[3]) > 0.0 &&
|
|
p.sideOfLine2D(m_p[3], m_p[0]) >= 0.0;
|
|
}
|
|
} // pointInQuad
|
|
|
|
// ----------------------------------------------------------------------------
|
|
/** Transforms a quad by a given transform (i.e. translation+rotation). This
|
|
* function does not modify this quad, the results are stored in the quad
|
|
* specified as parameter. These functions are used for slipstreaming to
|
|
* determine the slipstream area from the original value (kart at 0,0,0 and
|
|
* no rotation) to the current value.
|
|
* \param t The transform to apply.
|
|
* \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]);
|
|
result->m_min_height = std::min ( std::min(result->m_p[0].getY(),
|
|
result->m_p[1].getY()),
|
|
std::min(result->m_p[2].getY(),
|
|
result->m_p[3].getY()) );
|
|
} // transform
|
|
|