diff --git a/src/Makefile.am b/src/Makefile.am index 500dd4156..35b29c6de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -220,6 +220,8 @@ supertuxkart_SOURCES = \ physics/triangle_mesh.hpp \ robots/default_robot.cpp \ robots/default_robot.hpp \ + tracks/quad.hpp \ + tracks/quad.cpp \ tracks/quad_graph.hpp \ tracks/quad_graph.cpp \ tracks/quad_set.hpp \ diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 65160331b..df4c7355c 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -361,12 +361,12 @@ scene::ISceneNode *IrrDriver::addMesh(scene::IMesh *mesh) // ---------------------------------------------------------------------------- /** Creates a quad mesh buffer and adds it to the scene graph. */ -scene::IMesh *IrrDriver::createQuadMesh(const video::SColor &color) +scene::IMesh *IrrDriver::createQuadMesh(const video::SMaterial *material) { scene::SMeshBuffer *buffer = new scene::SMeshBuffer(); video::S3DVertex v; v.Pos = core::vector3df(0,0,0); - + // Add the vertices // ---------------- buffer->Vertices.push_back(v); @@ -391,12 +391,8 @@ scene::IMesh *IrrDriver::createQuadMesh(const video::SColor &color) buffer->Vertices[1].Normal = n; buffer->Vertices[2].Normal = n; buffer->Vertices[3].Normal = n; - video::SMaterial m; - m.AmbientColor = color; - m.DiffuseColor = color; - m.EmissiveColor = color; - m.BackfaceCulling = false; - buffer->Material = m; + if(material) + buffer->Material = *material; SMesh *mesh = new SMesh(); mesh->addMeshBuffer(buffer); mesh->recalculateBoundingBox(); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index b45b3ed97..f12f1f692 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -63,7 +63,7 @@ public: bool OnEvent(const irr::SEvent &event); void setAmbientLight(const video::SColor &light); video::ITexture *getTexture(const std::string &filename); - scene::IMesh *createQuadMesh(const video::SColor &c=video::SColor(77, 179, 0, 0)); + scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL); scene::ISceneNode *addWaterNode(scene::IMesh *mesh, float wave_height, float wave_speed, float wave_length); scene::ISceneNode *addOctTree(scene::IMesh *mesh); diff --git a/src/ide/vc9/supertuxkart.vcproj b/src/ide/vc9/supertuxkart.vcproj index ac2f6a0a4..50730d53e 100644 --- a/src/ide/vc9/supertuxkart.vcproj +++ b/src/ide/vc9/supertuxkart.vcproj @@ -608,6 +608,10 @@ + + @@ -1202,6 +1206,10 @@ + + diff --git a/src/items/rubber_band.cpp b/src/items/rubber_band.cpp index 0be204dc4..cf2793bc7 100644 --- a/src/items/rubber_band.cpp +++ b/src/items/rubber_band.cpp @@ -40,7 +40,13 @@ RubberBand::RubberBand(Plunger *plunger, const Kart &kart) : m_plunger(plunger), m_owner(kart) { - m_mesh = irr_driver->createQuadMesh(); + video::SColor color(77, 179, 0, 0); + video::SMaterial m; + m.AmbientColor = color; + m.DiffuseColor = color; + m.EmissiveColor = color; + m.BackfaceCulling = false; + m_mesh = irr_driver->createQuadMesh(&m); m_buffer = m_mesh->getMeshBuffer(0); m_attached_state = RB_TO_PLUNGER; assert(m_buffer->getVertexType()==video::EVT_STANDARD); diff --git a/src/tracks/quad.cpp b/src/tracks/quad.cpp new file mode 100755 index 000000000..0bd012123 --- /dev/null +++ b/src/tracks/quad.cpp @@ -0,0 +1,67 @@ +// $Id$ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2009 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 "irrlicht.h" + +/** Constructor, takes 4 points. */ +Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3) + { + m_p[0]=p0; m_p[1]=p1; m_p[2]=p2; m_p[3]=p3; + m_center = 0.25f*(p0+p1+p2+p3); +} // 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::setVertices(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 + +#include "quad.hpp" + diff --git a/src/tracks/quad.hpp b/src/tracks/quad.hpp new file mode 100755 index 000000000..2b2d5ce77 --- /dev/null +++ b/src/tracks/quad.hpp @@ -0,0 +1,44 @@ +// $Id$ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2009 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. + +#ifndef HEADER_QUAD_HPP +#define HEADER_QUAD_HPP + +#include + +#include "irrlicht.h" + +#include "utils/vec3.hpp" + +class Quad { +public: + /** The four points of a quad. */ + Vec3 m_p[4]; + /** The center, which is used by the AI. This saves some + computations at runtime. */ + Vec3 m_center; + + Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3); + /** Returns the i-th. point of a quad. */ + const Vec3& operator[](int i) const {return m_p[i]; } + /** Returns the center of a quad. */ + const Vec3& getCenter () const {return m_center; } + void setVertices(video::S3DVertex *v, const video::SColor &color) const; +}; // class Quad +#endif diff --git a/src/tracks/quad_graph.cpp b/src/tracks/quad_graph.cpp index 6ef562018..8eab81863 100755 --- a/src/tracks/quad_graph.cpp +++ b/src/tracks/quad_graph.cpp @@ -19,6 +19,8 @@ #include "tracks/quad_graph.hpp" +#include "user_config.hpp" +#include "graphics/irr_driver.hpp" #include "io/file_manager.hpp" #include "io/xml_node.hpp" #include "tracks/quad_set.hpp" @@ -31,9 +33,12 @@ QuadGraph::QuadGraph(const std::string &quad_file_name, const std::string graph_file_name) { + m_node = NULL; + m_mesh = NULL; + m_mesh_buffer = NULL; m_all_quads = new QuadSet(quad_file_name); // First create all nodes - for(unsigned int i=0; igetSize(); i++) { + for(unsigned int i=0; igetNumberOfQuads(); i++) { m_all_nodes.push_back(new GraphNode(i)); } load(graph_file_name); @@ -97,6 +102,59 @@ void QuadGraph::setDefaultSuccessors() } // for icreateQuadMesh(&m); + m_mesh_buffer = m_mesh->getMeshBuffer(0); + assert(m_mesh_buffer->getVertexType()==video::EVT_STANDARD); + + video::S3DVertex* v=(video::S3DVertex*)m_mesh_buffer->getVertices(); + // The mesh buffer already contains one quad, so set the coordinates + // of the first quad in there. + video::SColor c(255, 255, 0, 0); + m_all_quads->getQuad(0).setVertices(v, c); + + unsigned int n = m_all_quads->getNumberOfQuads(); + // Four vertices for each of the n-1 remaining quads + video::S3DVertex *new_v = new video::S3DVertex[(n-1)*4]; + // Each quad consists of 2 triangles with 3 elements, so + // we need 2*3 indices for each quad. + irr::u16 *ind = new irr::u16[(n-1)*6]; + + // Now add all other quads + for(unsigned int i=1; igetQuad(i).setVertices(new_v+(4*i-4), c); + + // Set up the indices for the triangles + // (note, afaik with opengl we could use quads directly, but the code + // would not be portable to directx anymore). + ind[6*i-6] = 4*i-4; // First triangle: vertex 0, 1, 2 + ind[6*i-5] = 4*i-3; + ind[6*i-4] = 4*i-2; + ind[6*i-3] = 4*i-4; // second triangle: vertex 0, 1, 3 + ind[6*i-2] = 4*i-2; + ind[6*i-1] = 4*i-1; + } // for i=1; iappend(new_v, (n-1)*4, ind, (n-1)*6); + m_node = irr_driver->addMesh(m_mesh); + +} // createDebugMesh + // ----------------------------------------------------------------------------- /** Returns the list of successors or a node. * \param node_number The number of the node. diff --git a/src/tracks/quad_graph.hpp b/src/tracks/quad_graph.hpp index 9766e78ef..5cd5f5f9a 100755 --- a/src/tracks/quad_graph.hpp +++ b/src/tracks/quad_graph.hpp @@ -49,26 +49,36 @@ class QuadGraph { /** Returns the number of successors. */ unsigned int getNumberOfSuccessors() const { return (unsigned int)m_vertices.size(); } + /** Returns the index in the quad_set of this node. */ + int getIndex() const { return m_index; } /** Returns the distance to the j-th. successor. */ float getDistanceToSuccessor(int j) const { return m_distance_to_next[j]; } /** Returns the angle from this node to the j-th. successor. */ float getAngleToSuccessor(int j) const { return m_angle_to_next[j]; } - }; + }; // GraphNode // ======================================================================== protected: /** The actual graph data structure. */ std::vector m_all_nodes; + /** The set of all quads. */ QuadSet *m_all_quads; + /** For debug mode only: the node of the debug mesh. */ + scene::ISceneNode *m_node; + /** For debug only: the mesh of the debug mesh. */ + scene::IMesh *m_mesh; + /** For debug only: the actual mesh buffer storing the quads. */ + scene::IMeshBuffer *m_mesh_buffer; + void setDefaultSuccessors(); void load (const std::string &filename); - public: QuadGraph (const std::string &quad_file_name, const std::string graph_file_name); ~QuadGraph (); + void createDebugMesh(); void getSuccessors(int quadNumber, std::vector& succ) const; diff --git a/src/tracks/quad_set.cpp b/src/tracks/quad_set.cpp index d4c60ac4b..2a9743067 100755 --- a/src/tracks/quad_set.cpp +++ b/src/tracks/quad_set.cpp @@ -22,6 +22,7 @@ #include #include "io/file_manager.hpp" +#include "io/xml_node.hpp" #include "utils/string_utils.hpp" /** Constructor, loads the quad set from a file. @@ -48,7 +49,7 @@ void QuadSet::getPoint(const XMLNode *xml, const std::string &attribute_name, std::vector l = StringUtils::split(s, ':'); int n=atoi(l[0].c_str()); int p=atoi(l[1].c_str()); - *result=(*m_allQuads[n])[p]; + *result=(*m_all_quads[n])[p]; } else { @@ -83,7 +84,7 @@ void QuadSet::load(const std::string &filename) { getPoint(xml_node, "p2", &p2); getPoint(xml_node, "p3", &p3); Quad* q=new Quad(p0,p1,p2,p3); - m_allQuads.push_back(q); + m_all_quads.push_back(q); } delete xml; @@ -115,10 +116,11 @@ bool QuadSet::pointInQuad(const Quad& q, const btVector3& p) const { algorithm, used to get the initial quad position of a kart, but not for constantly updating it. */ -int QuadSet::getQuad(const Vec3 &pos) const { - for(unsigned int i=0; i #include -#include "io/xml_node.hpp" -#include "utils/vec3.hpp" +#include "tracks/quad.hpp" + +class Vec3; +class XMLNode; class QuadSet { private: - /** Internal class to store a single quad. */ - class Quad { - public: - /** The four points of a quad. */ - Vec3 m_p[4]; - /** The center, which is used by the AI. This saves some - computations at runtime. */ - Vec3 m_center; - /** Constructor, takes 4 points. */ - Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3) - { - 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_center.setX((p0.getX()+p1.getX()+p2.getX()+p3.getX())/4.0f); - m_center.setY((p0.getY()+p1.getY()+p2.getY()+p3.getY())/4.0f); - m_center.setZ((p0.getZ()+p1.getZ()+p2.getZ()+p3.getZ())/4.0f); - } - /** Returns the i-th. point of a quad. */ - const btVector3& operator[](int i) const {return m_p[i]; } - /** Returns the center of a quad. */ - const Vec3& getCenter () const {return m_center; } - }; // class Quad - // ======================================================================= /** The 2d bounding box, used for hashing. */ // FIXME: named with z being the forward axis float m_xMin, m_xMax, m_zMin, m_zMax; /** The list of all quads. */ - std::vector m_allQuads; + std::vector m_all_quads; void load (const std::string &filename); void getPoint(const XMLNode *xml, const std::string &attribute_name, Vec3 *result) const; @@ -65,20 +44,24 @@ public: static const int QUAD_NONE=-1; QuadSet (const std::string& filename); - int getQuad (const Vec3& p) const; + int getQuadAtPos (const Vec3& p) const; + const Quad& getQuad(int n) const {return *(m_all_quads[n]); } int getCurrentQuad(const Vec3& p, int oldQuad) const; bool pointInQuad (const Quad& q, const btVector3& p) const; /** Returns true if the point p is in the n-th. quad. */ bool pointInQuad (int n, const btVector3& p) const - {return pointInQuad(*m_allQuads[n],p);} + {return pointInQuad(*m_all_quads[n],p);} void getBoundingBox(float* xMin, float* xMax, float* zMin, float* zMax) const { *xMin=m_xMin; *xMax=m_xMax; *zMin=m_zMin; *zMax=m_zMax;} /** Returns the number of quads. */ - unsigned int getSize() const {return (unsigned int)m_allQuads.size(); } + unsigned int getNumberOfQuads() const + {return (unsigned int)m_all_quads.size(); } /** Returns the center of quad n. */ const Vec3& getCenterOfQuad(int n) const - {return m_allQuads[n]->getCenter(); } + {return m_all_quads[n]->getCenter(); } + /** Returns the n-th. quad. */ + const Quad& getQuad(int n) {return *(m_all_quads[n]); } }; // QuadSet #endif diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 85df01cab..389a6e794 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1657,6 +1657,9 @@ void Track::loadTrackModel() irr_driver->setAmbientLight(video::SColor(255, 255, 255, 255)); // Note: the physics world for irrlicht is created in loadMainTrack createPhysicsModel(); + if(user_config->m_track_debug) + m_quad_graph->createDebugMesh(); + } // loadTrack //-----------------------------------------------------------------------------