diff --git a/src/Makefile.am b/src/Makefile.am index 45dec6aaf..12d4c3f5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -269,10 +269,14 @@ supertuxkart_SOURCES = \ states_screens/race_gui.hpp \ states_screens/state_manager.cpp \ states_screens/state_manager.hpp \ + tracks/ambient_light_sphere.cpp \ + tracks/ambient_light_sphere.hpp \ tracks/bezier_curve.cpp \ tracks/bezier_curve.hpp \ tracks/check_manager.cpp \ tracks/check_manager.hpp \ + tracks/check_sphere.cpp \ + tracks/check_sphere.hpp \ tracks/check_structure.cpp \ tracks/check_structure.hpp \ tracks/checkline.cpp \ diff --git a/src/ide/vc9/supertuxkart.vcproj b/src/ide/vc9/supertuxkart.vcproj index 04597e18c..5af167355 100644 --- a/src/ide/vc9/supertuxkart.vcproj +++ b/src/ide/vc9/supertuxkart.vcproj @@ -608,6 +608,10 @@ + + @@ -616,6 +620,10 @@ RelativePath="..\..\tracks\check_manager.cpp" > + + @@ -1326,6 +1334,10 @@ + + @@ -1334,6 +1346,10 @@ RelativePath="..\..\tracks\check_manager.hpp" > + + diff --git a/src/main_loop.cpp b/src/main_loop.cpp index fd2b368e9..caf4aa1e5 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -91,7 +91,7 @@ float MainLoop::getLimitedDt() } dt *= 0.001f; return dt; -} +} // getLimitedDt //----------------------------------------------------------------------------- /** Updates all race related objects. diff --git a/src/tracks/ambient_light_sphere.cpp b/src/tracks/ambient_light_sphere.cpp new file mode 100644 index 000000000..5a232128c --- /dev/null +++ b/src/tracks/ambient_light_sphere.cpp @@ -0,0 +1,85 @@ +// $Id: ambient_light_sphere.cpp 1681 2008-04-09 13:52:48Z hikerstk $ +// +// 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/ambient_light_sphere.hpp" + +#include +#include + +#include "io/xml_node.hpp" +#include "modes/world.hpp" +#include "race/race_manager.hpp" +#include "tracks/track.hpp" + +/** Constructor for a checksphere. + * \param check_manager Pointer to the check manager, which is needed when + * resetting e.g. new lap counters. + * \param node XML node containing the parameters for this checkline. + */ +AmbientLightSphere::AmbientLightSphere(CheckManager *check_manager, + const XMLNode &node) + : CheckSphere(check_manager, node) +{ + m_ambient_color = video::SColor(255, 0, 255, 0); // green + m_inner_radius2 = 1; + node.get("inner-radius", &m_inner_radius2); + m_inner_radius2 *= m_inner_radius2; // store the squared value + node.get("color", &m_ambient_color); +} // AmbientLightSphere + +// ---------------------------------------------------------------------------- +void AmbientLightSphere::update(float dt) +{ + CheckStructure::update(dt); + for(unsigned int i=0; igetNumKarts(); i++) + { + if(isInside(i)) + { + float d2=getDistance2ForKart(i); + video::SColor color; + Track *track=RaceManager::getWorld()->getTrack(); + if(d2 use new ambient color + color = m_ambient_color; + } + else // Interpolate between default and this ambient color + { + float f = (getRadius2()-d2)/(getRadius2()-m_inner_radius2); + const video::SColor &def = track->getDefaultAmbientColor(); + color = m_ambient_color.getInterpolated(def, f); + } + track->setAmbientColor(color); + } // if active + } // for igetKart(indx)->isPlayerKart()) return false; + return CheckSphere::isTriggered(old_pos, new_pos, indx); +} // isTriggered diff --git a/src/tracks/ambient_light_sphere.hpp b/src/tracks/ambient_light_sphere.hpp new file mode 100644 index 000000000..c9555085b --- /dev/null +++ b/src/tracks/ambient_light_sphere.hpp @@ -0,0 +1,58 @@ +// $Id: ambient_light_sphere.hpp 1681 2008-04-09 13:52:48Z hikerstk $ +// +// 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_AMBIENT_LIGHT_SPHERE_HPP +#define HEADER_AMBIENT_LIGHT_SPHERE_HPP + +#include "irrlicht.h" +using namespace irr; + +#include "tracks/check_sphere.hpp" + +class XMLNode; +class CheckManager; + +/** This class implements a check sphere that is used to change the ambient + * light if a kart is inside this sphere. Besides a normal radius this + * sphere also has a 2nd 'inner' radius: player karts inside the inner + * radius will have the full new ambient light, karts outside the default + * light, and karts in between will mix the light dependent on distance. + */ +class AmbientLightSphere : public CheckSphere +{ +private: + /** The inner radius defines the area during which the ambient light + * is extrapolated. The square of the value specified in the scene + * file is stored. */ + float m_inner_radius2; + + /** THe full ambient color to use once the kart is inside the + * inner radius. */ + video::SColor m_ambient_color; +public: + AmbientLightSphere(CheckManager *check_manager, + const XMLNode &node); + virtual ~AmbientLightSphere() {}; + virtual void update(float dt); + virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, + int indx); +}; // AmbientLightSphere + +#endif + diff --git a/src/tracks/check_manager.cpp b/src/tracks/check_manager.cpp index 93defc4d5..26b66ae8c 100644 --- a/src/tracks/check_manager.cpp +++ b/src/tracks/check_manager.cpp @@ -23,9 +23,11 @@ #include "io/xml_node.hpp" #include "tracks/checkline.hpp" +#include "tracks/ambient_light_sphere.hpp" #include "tracks/check_structure.hpp" +#include "tracks/track.hpp" -CheckManager::CheckManager(const XMLNode &node) +CheckManager::CheckManager(const XMLNode &node, Track *track) { for(unsigned int i=0; igetName(); if(type=="checkline") { - m_all_checks.push_back(new Checkline(this, *check_node)); - } + Checkline *cl = new Checkline(this, *check_node); + m_all_checks.push_back(cl); + if(cl->getType()==CheckStructure::CT_NEW_LAP) + { + track->getQuadGraph().setStartCoordinate(cl->getCenterPoint()); + } + } // checkline + else if(type=="check-sphere") + { + AmbientLightSphere *cs = new AmbientLightSphere(this, *check_node); + m_all_checks.push_back(cs); + } // checksphere } // for i m_all_checks; public: - CheckManager(const XMLNode &node); + CheckManager(const XMLNode &node, Track *track); void update(float dt); void reset(const Track &track); void activateNewLapChecks(int kart_index); diff --git a/src/tracks/check_sphere.cpp b/src/tracks/check_sphere.cpp new file mode 100644 index 000000000..3fc2ecdfa --- /dev/null +++ b/src/tracks/check_sphere.cpp @@ -0,0 +1,69 @@ +// $Id: check+sphere.cpp 1681 2008-04-09 13:52:48Z hikerstk $ +// +// 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/check_sphere.hpp" + +#include +#include + +#include "io/xml_node.hpp" +#include "modes/world.hpp" +#include "race/race_manager.hpp" + +/** Constructor for a checksphere. + * \param check_manager Pointer to the check manager, which is needed when + * resetting e.g. new lap counters. + * \param node XML node containing the parameters for this checkline. + */ +CheckSphere::CheckSphere(CheckManager *check_manager, const XMLNode &node) + : CheckStructure(check_manager, node) +{ + m_radius2 = 1; + + node.get("radius", &m_radius2); + m_radius2 *= m_radius2; + node.get("xyz", &m_center_point); + m_is_inside.resize(race_manager->getNumKarts()); + m_distance2.resize(race_manager->getNumKarts()); + for(unsigned int i=0; i< race_manager->getNumKarts(); i++) + { + m_is_inside[i] = false; + } +} // CheckSphere + +// ---------------------------------------------------------------------------- +/** True if going from old_pos to new_pos enters or leaves this sphere. This + * function is called from update (of the checkline structure). It also + * updates the flag about which karts are inside + * \param old_pos Position in previous frame. + * \param new_pos Position in current frame. + * \param kart_id Index of the kart, can be used to store kart specific + * additional data. + */ +bool CheckSphere::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, int kart_id) +{ + float old_dist2 = (old_pos-m_center_point).length2(); + float new_dist2 = (new_pos-m_center_point).length2(); + m_is_inside[kart_id] = new_dist2=m_radius2 && new_dist2 < m_radius2) || + (old_dist2< m_radius2 && new_dist2 >=m_radius2); +} // isTriggered diff --git a/src/tracks/check_sphere.hpp b/src/tracks/check_sphere.hpp new file mode 100644 index 000000000..18342fdc7 --- /dev/null +++ b/src/tracks/check_sphere.hpp @@ -0,0 +1,70 @@ +// $Id: check_sphere.hpp 1681 2008-04-09 13:52:48Z hikerstk $ +// +// 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_CHECK_SPHERE_HPP +#define HEADER_CHECK_SPHERE_HPP + +#include "irrlicht.h" +using namespace irr; + +#include "tracks/check_structure.hpp" + +class XMLNode; +class CheckManager; + +/** This class implements a check sphere that is used to change the ambient + * light if a kart is inside this sphere. Besides a normal radius this + * sphere also has a 2nd 'inner' radius: player karts inside the inner + * radius will have the full new ambient light, karts outside the default + * light, and karts in between will mix the light dependent on distance. + */ +class CheckSphere : public CheckStructure +{ +private: + /** Center of the sphere. */ + Vec3 m_center_point; + /** Squared radius of the sphere. */ + float m_radius2; + /** A flag for each kart to indicate if it's inside of the sphere. */ + std::vector m_is_inside; + /** Stores the distance of each kart from the center of this sphere. + * This saves some computations. */ + std::vector m_distance2; +public: + CheckSphere(CheckManager *check_manager, const XMLNode &node); + virtual ~CheckSphere() {}; + virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, + int kart_id); + // ------------------------------------------------------------------------ + /** Returns if kart indx is currently inside of the sphere. */ + bool isInside(int index) const { return m_is_inside[index]; } + // ------------------------------------------------------------------------- + /** Returns the squared distance of kart index from the enter of + * this sphere. */ + float getDistance2ForKart(int index) const { return m_distance2[index];} + // ------------------------------------------------------------------------- + /** Returns the center point of this checkline. */ + Vec3 getCenterPoint() const { return m_center_point; } + // ------------------------------------------------------------------------- + /** Returns the square of the radius of this sphere. */ + float getRadius2() const { return m_radius2; } +}; // CheckSphere + +#endif + diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index 999f42fa1..99bba385e 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -34,10 +34,14 @@ CheckStructure::CheckStructure(CheckManager *check_manager, m_check_type = CT_NEW_LAP; else if(type=="reset-new-lap") m_check_type = CT_RESET_NEW_LAP; + else if(type=="ambient-light") + m_check_type = CT_AMBIENT_SPHERE; else { printf("Unknown check structure '%s' - ignored.\n", type.c_str()); } + m_active_at_reset=true; + node.get("active", &m_active_at_reset); } // CheckStructure // ---------------------------------------------------------------------------- @@ -55,7 +59,7 @@ void CheckStructure::reset(const Track &track) m_previous_position.push_back(xyz); // Activate all checkline - m_is_active.push_back(true); + m_is_active.push_back(m_active_at_reset); } // for iremoveTexture(m_mini_map); + if(m_quad_graph) delete m_quad_graph; + if(m_check_manager) delete m_check_manager; + if(m_mini_map) irr_driver->removeTexture(m_mini_map); } // ~Track //----------------------------------------------------------------------------- @@ -93,6 +93,7 @@ Track::~Track() */ void Track::reset() { + m_ambient_color = m_default_ambient_color; if(m_animation_manager) m_animation_manager->reset(); if(m_check_manager) @@ -201,7 +202,7 @@ void Track::loadTrackInfo(const std::string &filename) m_sun_position = core::vector3df(0.4f, 0.4f, 0.4f); m_sky_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f); m_fog_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f).toSColor(); - m_ambient_color = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f); + m_default_ambient_color = video::SColor(255, 120, 120, 120); m_specular_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); m_diffuse_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); XMLNode *root = file_manager->createXMLTree(m_filename); @@ -504,6 +505,8 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml) */ void Track::update(float dt) { + irr_driver->getSceneManager()->setAmbientLight(m_ambient_color); + for(unsigned int i=0; iupdate(dt); @@ -693,7 +696,7 @@ void Track::loadTrackModel(unsigned int mode_id) } else if(name=="checks") { - m_check_manager = new CheckManager(*node); + m_check_manager = new CheckManager(*node, this); } else if(name=="sky-dome" || name=="sky-box") { @@ -746,7 +749,7 @@ void Track::loadTrackModel(unsigned int mode_id) file_manager->popTextureSearchPath(); file_manager->popModelSearchPath (); - irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 120, 120, 120)); + irr_driver->getSceneManager()->setAmbientLight(m_ambient_color); m_light = irr_driver->getSceneManager()->addLightSceneNode(NULL, m_sun_position, video::SColorf(1.0f,1.0f,1.0f)); diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 72db365ad..54d17381d 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -131,7 +131,8 @@ private: float m_fog_start; float m_fog_end; core::vector3df m_sun_position; - video::SColorf m_ambient_color; + video::SColor m_default_ambient_color; + video::SColor m_ambient_color; video::SColorf m_specular_color; video::SColorf m_diffuse_color; video::SColorf m_sky_color; @@ -220,9 +221,9 @@ public: void handleExplosion(const Vec3 &pos, const PhysicalObject *mp) const; /** Sets pointer to the aabb of this track. */ void getAABB(const Vec3 **min, const Vec3 **max) const - { *min = &m_aabb_min; *max = &m_aabb_max; } + { *min = &m_aabb_min; *max = &m_aabb_max; } /** Returns the graph of quads, mainly for the AI. */ - const QuadGraph& getQuadGraph() const { return *m_quad_graph; } + QuadGraph& getQuadGraph() const { return *m_quad_graph; } /** Returns 'a' angle for quad n. This angle is used to position a kart * after a rescue, and to detect wrong directions. This function will @@ -248,6 +249,12 @@ public: /** Returns the name of the i-th. mode. */ const std::string &getModeName(unsigned int i) const { return m_all_modes[i].m_name;} + /** Returns the default ambient color. */ + const video::SColor &getDefaultAmbientColor() const + { return m_default_ambient_color;} + /** Sets the current ambient color. */ + void setAmbientColor(const video::SColor &color) + { m_ambient_color = color; } }; // class Track #endif