Refactoring: interpolating values is now handled in a separate class
InterpolationArray. This class is now used for the skidding probability of the AI and the turn radius of all karts (which depends on speed). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11689 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
4f7f1379df
commit
fbb9e5f8d2
@ -280,11 +280,11 @@
|
||||
<swatter duration="10" distance="3" squash-duration="5"
|
||||
squash-slowdown="0.5"/>
|
||||
|
||||
<!-- turn-speed and turn-radius define the turn radius of the kart at
|
||||
the given speed. The actual steering angle is dependent on the
|
||||
<!-- turn-radius defines the turn radius of the kart at
|
||||
a given speed. The actual steering angle is dependent on the
|
||||
wheel base of the kart: radius = wheel_base/sin(steering_angle).
|
||||
The values below define that at speed 0 the turn radius is 3, at
|
||||
speed 10 (and up to 25 then) the radius is 15 etc.
|
||||
The values below define that at speed 0 the turn radius is 2, at
|
||||
speed 10 the radius is 7.5 etc.
|
||||
The actual turn radius is piece-wise linearly interpolated. This
|
||||
allows for tighter turning at lower speeds, and also avoids that
|
||||
the kart becomes too hard to control at high speed (speeds of higher
|
||||
@ -292,8 +292,7 @@
|
||||
time-full-steer is the time when a player's input goes from neutral
|
||||
steering to extreme left or right.
|
||||
-->
|
||||
<turn turn-speed= "0 10 25 45"
|
||||
turn-radius="2.0 7.5 15 25"
|
||||
<turn turn-radius="0:2.0 10:7.5 25:15 45:25"
|
||||
time-full-steer ="0.2" />
|
||||
|
||||
<!-- Speed and acceleration related values: power and max-speed (in m/s)
|
||||
|
@ -95,8 +95,8 @@ src/items/projectile_manager.cpp
|
||||
src/items/rubber_ball.cpp
|
||||
src/items/rubber_band.cpp
|
||||
src/items/swatter.cpp
|
||||
src/karts/abstract_kart_animation.cpp
|
||||
src/karts/abstract_kart.cpp
|
||||
src/karts/abstract_kart_animation.cpp
|
||||
src/karts/cannon_animation.cpp
|
||||
src/karts/controller/ai_base_controller.cpp
|
||||
src/karts/controller/ai_properties.cpp
|
||||
@ -188,13 +188,13 @@ src/states_screens/kart_selection.cpp
|
||||
src/states_screens/main_menu_screen.cpp
|
||||
src/states_screens/minimal_race_gui.cpp
|
||||
src/states_screens/options_screen_audio.cpp
|
||||
src/states_screens/options_screen_input2.cpp
|
||||
src/states_screens/options_screen_input.cpp
|
||||
src/states_screens/options_screen_input2.cpp
|
||||
src/states_screens/options_screen_players.cpp
|
||||
src/states_screens/options_screen_ui.cpp
|
||||
src/states_screens/options_screen_video.cpp
|
||||
src/states_screens/race_gui_base.cpp
|
||||
src/states_screens/race_gui.cpp
|
||||
src/states_screens/race_gui_base.cpp
|
||||
src/states_screens/race_gui_overworld.cpp
|
||||
src/states_screens/race_result_gui.cpp
|
||||
src/states_screens/race_setup_screen.cpp
|
||||
@ -255,8 +255,8 @@ src/animations/billboard_animation.hpp
|
||||
src/animations/ipo.hpp
|
||||
src/animations/three_d_animation.hpp
|
||||
src/audio/dummy_sfx.hpp
|
||||
src/audio/music_dummy.hpp
|
||||
src/audio/music.hpp
|
||||
src/audio/music_dummy.hpp
|
||||
src/audio/music_information.hpp
|
||||
src/audio/music_manager.hpp
|
||||
src/audio/music_ogg.hpp
|
||||
@ -264,8 +264,8 @@ src/audio/sfx_base.hpp
|
||||
src/audio/sfx_buffer.hpp
|
||||
src/audio/sfx_manager.hpp
|
||||
src/audio/sfx_openal.hpp
|
||||
src/challenges/challenge_data.hpp
|
||||
src/challenges/challenge.hpp
|
||||
src/challenges/challenge_data.hpp
|
||||
src/challenges/game_slot.hpp
|
||||
src/challenges/unlock_manager.hpp
|
||||
src/config/device_config.hpp
|
||||
@ -306,11 +306,11 @@ src/guiengine/scalable_font.hpp
|
||||
src/guiengine/screen.hpp
|
||||
src/guiengine/skin.hpp
|
||||
src/guiengine/widget.hpp
|
||||
src/guiengine/widgets.hpp
|
||||
src/guiengine/widgets/bubble_widget.hpp
|
||||
src/guiengine/widgets/button_widget.hpp
|
||||
src/guiengine/widgets/check_box_widget.hpp
|
||||
src/guiengine/widgets/dynamic_ribbon_widget.hpp
|
||||
src/guiengine/widgets.hpp
|
||||
src/guiengine/widgets/icon_button_widget.hpp
|
||||
src/guiengine/widgets/label_widget.hpp
|
||||
src/guiengine/widgets/list_widget.hpp
|
||||
@ -321,8 +321,8 @@ src/guiengine/widgets/spinner_widget.hpp
|
||||
src/guiengine/widgets/text_box_widget.hpp
|
||||
src/input/binding.hpp
|
||||
src/input/device_manager.hpp
|
||||
src/input/input_device.hpp
|
||||
src/input/input.hpp
|
||||
src/input/input_device.hpp
|
||||
src/input/input_manager.hpp
|
||||
src/input/wiimote_manager.hpp
|
||||
src/io/file_manager.hpp
|
||||
@ -343,8 +343,8 @@ src/items/projectile_manager.hpp
|
||||
src/items/rubber_ball.hpp
|
||||
src/items/rubber_band.hpp
|
||||
src/items/swatter.hpp
|
||||
src/karts/abstract_kart_animation.hpp
|
||||
src/karts/abstract_kart.hpp
|
||||
src/karts/abstract_kart_animation.hpp
|
||||
src/karts/cannon_animation.hpp
|
||||
src/karts/controller/ai_base_controller.hpp
|
||||
src/karts/controller/ai_properties.hpp
|
||||
@ -357,8 +357,8 @@ src/karts/controller/present_ai.hpp
|
||||
src/karts/controller/skidding_ai.hpp
|
||||
src/karts/explosion_animation.hpp
|
||||
src/karts/ghost_kart.hpp
|
||||
src/karts/kart_gfx.hpp
|
||||
src/karts/kart.hpp
|
||||
src/karts/kart_gfx.hpp
|
||||
src/karts/kart_model.hpp
|
||||
src/karts/kart_properties.hpp
|
||||
src/karts/kart_properties_manager.hpp
|
||||
@ -449,13 +449,13 @@ src/states_screens/kart_selection.hpp
|
||||
src/states_screens/main_menu_screen.hpp
|
||||
src/states_screens/minimal_race_gui.hpp
|
||||
src/states_screens/options_screen_audio.hpp
|
||||
src/states_screens/options_screen_input2.hpp
|
||||
src/states_screens/options_screen_input.hpp
|
||||
src/states_screens/options_screen_input2.hpp
|
||||
src/states_screens/options_screen_players.hpp
|
||||
src/states_screens/options_screen_ui.hpp
|
||||
src/states_screens/options_screen_video.hpp
|
||||
src/states_screens/race_gui_base.hpp
|
||||
src/states_screens/race_gui.hpp
|
||||
src/states_screens/race_gui_base.hpp
|
||||
src/states_screens/race_gui_overworld.hpp
|
||||
src/states_screens/race_result_gui.hpp
|
||||
src/states_screens/race_setup_screen.hpp
|
||||
@ -484,8 +484,8 @@ src/tracks/check_sphere.hpp
|
||||
src/tracks/check_structure.hpp
|
||||
src/tracks/graph_node.hpp
|
||||
src/tracks/lod_node_loader.hpp
|
||||
src/tracks/quad_graph.hpp
|
||||
src/tracks/quad.hpp
|
||||
src/tracks/quad_graph.hpp
|
||||
src/tracks/quad_set.hpp
|
||||
src/tracks/terrain_info.hpp
|
||||
src/tracks/track.hpp
|
||||
@ -493,11 +493,12 @@ src/tracks/track_manager.hpp
|
||||
src/tracks/track_object.hpp
|
||||
src/tracks/track_object_manager.hpp
|
||||
src/tracks/track_sector.hpp
|
||||
src/tutorial/tutorial_data.hpp
|
||||
src/tutorial/tutorial.hpp
|
||||
src/tutorial/tutorial_data.hpp
|
||||
src/tutorial/tutorial_manager.hpp
|
||||
src/utils/aligned_array.hpp
|
||||
src/utils/constants.hpp
|
||||
src/utils/interpolation_array.hpp
|
||||
src/utils/leak_check.hpp
|
||||
src/utils/no_copy.hpp
|
||||
src/utils/profiler.hpp
|
||||
|
@ -1774,6 +1774,10 @@
|
||||
RelativePath="..\..\utils\cpp2011.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\utils\interpolation_array.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\utils\leak_check.hpp"
|
||||
>
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/interpolation_array.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
@ -442,6 +443,53 @@ int XMLNode::get(const std::string &attribute, std::vector<int> *value) const
|
||||
return value->size();
|
||||
} // get(vector<int>)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Reads an InterpolatioARray. The values must be specified as:
|
||||
* x0:y0 x1:y1 x2:y2 ...
|
||||
* and the X values must be sorted. The function will abort (exit) with
|
||||
* an error message in case of incorrectly formed x:y pairs.
|
||||
* \param attribute Name of the attribute.
|
||||
* \param value The InterpolationArray.
|
||||
* \returns 0 in case of an error, !=0 otherwise
|
||||
*/
|
||||
int XMLNode::get(const std::string &attribute, InterpolationArray *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
std::vector<std::string> pairs = StringUtils::split(s, ' ');
|
||||
for(unsigned int i=0; i<pairs.size(); i++)
|
||||
{
|
||||
std::vector<std::string> pair = StringUtils::split(pairs[i],':');
|
||||
if(pair.size()!=2)
|
||||
{
|
||||
printf("Incorrect interpolation pair '%s' in '%s'.\n",
|
||||
pairs[i].c_str(), attribute.c_str());
|
||||
printf("Must be x:y.\n");
|
||||
exit(-1);
|
||||
}
|
||||
float x;
|
||||
if(!StringUtils::fromString(pair[0], x))
|
||||
{
|
||||
printf("Incorrect x in pair '%s' of '%s'.\n",
|
||||
pairs[i].c_str(), attribute.c_str());
|
||||
exit(-1);
|
||||
}
|
||||
float y;
|
||||
if(!StringUtils::fromString(pair[1], y))
|
||||
{
|
||||
printf("Incorrect y in pair '%s' in '%s'.\n",
|
||||
pair[1].c_str(), attribute.c_str());
|
||||
exit(-1);
|
||||
}
|
||||
if(!value->push_back(x, y))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} // for i
|
||||
return 1;
|
||||
} // get(InterpolationArray)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Interprets the attributes 'x', 'y', 'z' or 'h', 'p', 'r' as a 3d vector
|
||||
* and set the corresponding elements of value. Not all values need to be
|
||||
|
@ -44,6 +44,7 @@ using namespace irr;
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
class InterpolationArray;
|
||||
class Vec3;
|
||||
|
||||
/**
|
||||
@ -93,6 +94,7 @@ public:
|
||||
int get(const std::string &attribute, std::vector<std::string> *value) const;
|
||||
int get(const std::string &attribute, std::vector<float> *value) const;
|
||||
int get(const std::string &attribute, std::vector<int> *value) const;
|
||||
int get(const std::string &attribute, InterpolationArray *value) const;
|
||||
int get(core::vector3df *value) const;
|
||||
int getXYZ(core::vector3df *value) const;
|
||||
int getXYZ(Vec3 *vaslue) const;
|
||||
|
@ -26,6 +26,7 @@ float AIProperties::UNDEFINED = -99.9f;
|
||||
/** Constructor. Sets all properties to the special UNDEFINED value.
|
||||
*/
|
||||
AIProperties::AIProperties()
|
||||
: m_skid_probability(/*decreasing*/false)
|
||||
{
|
||||
m_max_item_angle = UNDEFINED;
|
||||
m_max_item_angle_high_speed = UNDEFINED;
|
||||
@ -45,51 +46,14 @@ void AIProperties::load(const XMLNode *ai_node)
|
||||
ai_node->get("time-full-steer", &m_time_full_steer );
|
||||
ai_node->get("bad-item-closeness", &m_bad_item_closeness_2 );
|
||||
ai_node->get("straight-length-for-zipper",&m_straight_length_for_zipper);
|
||||
ai_node->get("rb-skid-probability", &m_skid_probability );
|
||||
|
||||
std::string s;
|
||||
ai_node->get("rb-skid-probability", &s);
|
||||
std::vector<std::string> pairs = StringUtils::split(s, ' ');
|
||||
for(unsigned int i=0; i<pairs.size(); i++)
|
||||
{
|
||||
std::vector<std::string> pair = StringUtils::split(pairs[i],':');
|
||||
if(pair.size()!=2)
|
||||
{
|
||||
printf("Incorrect pair '%s' in rd-skid-probability.\n",
|
||||
pairs[i].c_str());
|
||||
printf("Must be distance:probability.\n");
|
||||
exit(-1);
|
||||
}
|
||||
float distance;
|
||||
if(!StringUtils::fromString(pair[0], distance))
|
||||
{
|
||||
printf("Incorrect distance in pair '%s'.\n", pairs[i].c_str());
|
||||
exit(-1);
|
||||
}
|
||||
float p;
|
||||
if(!StringUtils::fromString(pair[1], p))
|
||||
{
|
||||
printf(
|
||||
"Incorrect probability in pair '%s' in rb-skid-probability.\n",
|
||||
pair[1].c_str());
|
||||
exit(-1);
|
||||
}
|
||||
m_skid_distances.push_back(distance);
|
||||
m_skid_probabilities.push_back(p);
|
||||
} // for i
|
||||
|
||||
if(m_skid_distances.size()==0)
|
||||
if(m_skid_probability.size()==0)
|
||||
{
|
||||
printf("No skid probability defined.\n");
|
||||
exit(-1);
|
||||
}
|
||||
for(unsigned int i=0; i<m_skid_distances.size()-1; i++)
|
||||
{
|
||||
if(m_skid_distances[i]>=m_skid_distances[i+1])
|
||||
{
|
||||
printf("Skid distances must be sorted.\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// We actually need the square of the distance later
|
||||
m_bad_item_closeness_2 *= m_bad_item_closeness_2;
|
||||
|
||||
@ -120,30 +84,4 @@ void AIProperties::copyFrom(const AIProperties *destination)
|
||||
*this = *destination;
|
||||
} // copyFrom
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
float AIProperties::getSkiddingProbability(float distance) const
|
||||
{
|
||||
if(m_skid_distances.size()==1)
|
||||
return m_skid_probabilities[0];
|
||||
|
||||
if(distance<m_skid_distances[0])
|
||||
return m_skid_probabilities[0];
|
||||
if(distance>m_skid_distances[m_skid_distances.size()-1])
|
||||
return m_skid_probabilities[m_skid_probabilities.size()-1];
|
||||
|
||||
// Now distance must be between two of the distances in the
|
||||
// sorted m_skid_distances array
|
||||
for(unsigned int i=1; i<m_skid_distances.size(); i++)
|
||||
{
|
||||
if(distance >m_skid_distances[i]) continue;
|
||||
float f = m_skid_probabilities[i-1] +
|
||||
(m_skid_probabilities[i]-m_skid_probabilities[i-1]) *
|
||||
(distance - m_skid_distances[i-1])/
|
||||
(m_skid_distances[i]-m_skid_distances[i-1]);
|
||||
return f;
|
||||
}
|
||||
assert(false);
|
||||
return 0.0f;
|
||||
} // getSkiddingProbability
|
||||
|
||||
/* EOF */
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef HEADER_AI_PROPERTIES_HPP
|
||||
#define HEADER_AI_PROPERTIES_HPP
|
||||
|
||||
#include "utils/interpolation_array.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -68,19 +70,21 @@ protected:
|
||||
/** Minimum length of a straight in order to activate a zipper. */
|
||||
float m_straight_length_for_zipper;
|
||||
|
||||
/** The distances at which the skid probability is specified. */
|
||||
std::vector<float> m_skid_distances;
|
||||
|
||||
/** The skidding probability depending on distance, which is stored
|
||||
* in m_skid_distances - the two fields must have the same length. */
|
||||
std::vector<float> m_skid_probabilities;
|
||||
/** The array of (distance, skid_probability) points. */
|
||||
InterpolationArray m_skid_probability;
|
||||
public:
|
||||
|
||||
AIProperties();
|
||||
void load(const XMLNode *skid_node);
|
||||
void copyFrom(const AIProperties *destination);
|
||||
void checkAllSet(const std::string &filename) const;
|
||||
float getSkiddingProbability(float distance) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the skidding probability dependent on the specified distance
|
||||
* to the first player kart. */
|
||||
float getSkiddingProbability(float distance) const
|
||||
{
|
||||
return m_skid_probability.get(distance);
|
||||
} // getSkiddingProbability
|
||||
}; // AIProperties
|
||||
|
||||
|
||||
|
@ -44,6 +44,7 @@ float KartProperties::UNDEFINED = -99.9f;
|
||||
* defined, it is guaranteed that each kart has well defined physics values).
|
||||
*/
|
||||
KartProperties::KartProperties(const std::string &filename)
|
||||
: m_turn_angle_at_speed(/*decreasing*/true)
|
||||
{
|
||||
m_icon_material = NULL;
|
||||
m_minimap_icon = NULL;
|
||||
@ -56,10 +57,6 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_shadow_y_offset = 0.0f;
|
||||
|
||||
m_groups.clear();
|
||||
m_turn_angle_at_speed.clear();
|
||||
m_turn_radius_at_speed.clear();
|
||||
m_turn_speed.clear();
|
||||
m_speed_angle_increase.clear();
|
||||
m_custom_sfx_id.resize(SFXManager::NUM_CUSTOMS);
|
||||
|
||||
// Set all other values to undefined, so that it can later be tested
|
||||
@ -242,20 +239,12 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
||||
m_wheel_radius );
|
||||
m_wheel_base = fabsf( m_kart_model->getWheelPhysicsPosition(0).getZ()
|
||||
-m_kart_model->getWheelPhysicsPosition(2).getZ());
|
||||
for(unsigned int i=0; i<m_turn_radius_at_speed.size(); i++)
|
||||
|
||||
// Now convert the turn radius into turn angle:
|
||||
for(unsigned int i=0; i<m_turn_angle_at_speed.size(); i++)
|
||||
{
|
||||
m_turn_angle_at_speed.push_back(
|
||||
sin(m_wheel_base/m_turn_radius_at_speed[i])
|
||||
);
|
||||
}
|
||||
for(unsigned int i=0; i<m_turn_speed.size()-1; i++)
|
||||
{
|
||||
if(m_turn_speed[i]==m_turn_speed[i+1])
|
||||
m_speed_angle_increase.push_back(0);
|
||||
else
|
||||
m_speed_angle_increase.push_back(
|
||||
(m_turn_angle_at_speed[i]-m_turn_angle_at_speed[i+1])/
|
||||
(m_turn_speed[i+1]-m_turn_speed[i]) );
|
||||
m_turn_angle_at_speed.setY( i,
|
||||
sin(m_wheel_base/m_turn_angle_at_speed.getY(i)) );
|
||||
}
|
||||
|
||||
m_shadow_texture = irr_driver->getTexture(m_shadow_file);
|
||||
@ -347,33 +336,10 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
if(const XMLNode *turn_node = root->getNode("turn"))
|
||||
{
|
||||
turn_node->get("time-full-steer", &m_time_full_steer );
|
||||
turn_node->get("turn-speed", &m_turn_speed );
|
||||
turn_node->get("turn-radius", &m_turn_radius_at_speed);
|
||||
turn_node->get("turn-radius", &m_turn_angle_at_speed );
|
||||
// For now store the turn radius in turn angle, the correct
|
||||
// value can only be determined later in ::load
|
||||
if(m_turn_speed.size()==0 ||
|
||||
m_turn_radius_at_speed.size() != m_turn_speed.size())
|
||||
{
|
||||
printf("Inconsistent turn-speed and turn-radius "
|
||||
"settings for kart %s\n", getIdent().c_str());
|
||||
exit(-1);
|
||||
}
|
||||
for(unsigned int i=0; i<m_turn_speed.size()-1; i++)
|
||||
{
|
||||
if(m_turn_speed[i]>m_turn_speed[i+1])
|
||||
{
|
||||
printf("The turn-speed must be specified with increasing "
|
||||
"values for kart %s.\n", getIdent().c_str());
|
||||
exit(-1);
|
||||
}
|
||||
if(m_turn_radius_at_speed[i]>m_turn_radius_at_speed[i+1])
|
||||
{
|
||||
printf("The turn-radius must be increasing for kart %s.\n",
|
||||
getIdent().c_str());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
} // if turn_node
|
||||
|
||||
if(const XMLNode *engine_node = root->getNode("engine"))
|
||||
{
|
||||
@ -465,7 +431,8 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
collision_node->get("bevel-factor", &m_bevel_factor );
|
||||
}
|
||||
|
||||
//TODO: wheel front right and wheel front left is not loaded, yet is listed as an attribute in the xml file after wheel-radius
|
||||
//TODO: wheel front right and wheel front left is not loaded, yet is
|
||||
//TODO: listed as an attribute in the xml file after wheel-radius
|
||||
//TODO: same goes for their rear equivalents
|
||||
|
||||
if(const XMLNode *plunger_node= root->getNode("plunger"))
|
||||
@ -685,50 +652,6 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
m_ai_properties->checkAllSet(filename);
|
||||
} // checkAllSet
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
float KartProperties::getMaxSteerAngle(float speed) const
|
||||
{
|
||||
if(speed<=m_turn_speed[0]) return m_turn_angle_at_speed[0];
|
||||
unsigned int last = m_turn_speed.size()-1;
|
||||
if(speed>=m_turn_speed[last]) return m_turn_angle_at_speed[last];
|
||||
|
||||
for(unsigned int i=1; i<=last; i++)
|
||||
{
|
||||
if(speed <= m_turn_speed[i])
|
||||
{
|
||||
// Interpolate between i and i+1
|
||||
return m_turn_angle_at_speed[i] -
|
||||
(speed-m_turn_speed[i])*m_speed_angle_increase[i-1];
|
||||
}
|
||||
}
|
||||
// This should never be reached
|
||||
assert (0);
|
||||
return 0; // avoid compiler warning
|
||||
} // getMaxSteerAngle
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the (maximum) speed for a given turn radius.
|
||||
* \param radius The radius for which the speed needs to be computed.
|
||||
*/
|
||||
float KartProperties::getSpeedForTurnRadius(float radius) const
|
||||
{
|
||||
if(radius < m_turn_radius_at_speed[0] )
|
||||
return m_turn_speed[0];
|
||||
|
||||
const unsigned int last = m_turn_speed.size();
|
||||
|
||||
for(unsigned int i=1; i<last; i++)
|
||||
{
|
||||
if(radius < m_turn_radius_at_speed[i])
|
||||
{
|
||||
return m_turn_speed[i-1]
|
||||
+ (m_turn_speed[i]-m_turn_speed[i-1]) * (radius-m_turn_radius_at_speed[i-1])
|
||||
/ (m_turn_radius_at_speed[i]-m_turn_radius_at_speed[i-1]);
|
||||
}
|
||||
} // for i < last
|
||||
return m_turn_speed[last-1];
|
||||
} // getSpeedForTurnRadius
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called the first time a kart accelerates after 'ready-set-go'. It searches
|
||||
* through m_startup_times to find the appropriate slot, and returns the
|
||||
|
@ -34,6 +34,7 @@ using namespace irr;
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "utils/interpolation_array.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
class AIProperties;
|
||||
@ -124,17 +125,9 @@ private:
|
||||
* braking force. */
|
||||
float m_time_full_steer; /**< Time for player karts to reach full
|
||||
* steer angle. */
|
||||
/** Stores the speeds at which the turn angle changes. */
|
||||
std::vector<float> m_turn_speed;
|
||||
|
||||
/** Stores the turn angle at the corresponding turn speed. */
|
||||
std::vector<float> m_turn_angle_at_speed;
|
||||
|
||||
/** Stores the turn radius at the corresponding turn speed. */
|
||||
std::vector<float> m_turn_radius_at_speed;
|
||||
|
||||
/** Increase of turn angle with speed. */
|
||||
std::vector<float> m_speed_angle_increase;
|
||||
/** The turn angle depending on speed. */
|
||||
InterpolationArray m_turn_angle_at_speed;
|
||||
|
||||
/** If != 0 a bevelled box shape is used by using a point cloud as a
|
||||
* collision shape. */
|
||||
@ -300,13 +293,16 @@ private:
|
||||
/** How long the slip stream speed increase will gradually be reduced. */
|
||||
float m_slipstream_fade_out_time;
|
||||
|
||||
float m_camera_distance; /**< Distance of normal camera from kart.*/
|
||||
float m_camera_forward_up_angle; /**< Up angle of the camera in relation to
|
||||
the pitch of the kart when driving
|
||||
forwards. */
|
||||
float m_camera_backward_up_angle; /**< Up angle of the camera in relation to
|
||||
the pitch of the kart when driving
|
||||
backwards. */
|
||||
/** Distance of normal camera from kart. */
|
||||
float m_camera_distance;
|
||||
|
||||
/** Up angle of the camera in relation to the pitch of the kart when
|
||||
* driving forwards. */
|
||||
float m_camera_forward_up_angle;
|
||||
|
||||
/** Up angle of the camera in relation to the pitch of the kart when
|
||||
* driving backwards. */
|
||||
float m_camera_backward_up_angle;
|
||||
|
||||
/** The following two vectors define at what ratio of the maximum speed what
|
||||
* gear is selected. E.g. 0.25 means: if speed <=0.25*maxSpeed --> gear 1,
|
||||
@ -337,12 +333,20 @@ public:
|
||||
void checkAllSet (const std::string &filename);
|
||||
float getStartupBoost () const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the (maximum) speed for a given turn radius.
|
||||
* \param radius The radius for which the speed needs to be computed. */
|
||||
float getSpeedForTurnRadius(float radius) const {
|
||||
float angle = sin(m_wheel_base / radius);
|
||||
return m_turn_angle_at_speed.getReverse(angle);
|
||||
} // getSpeedForTurnRadius
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the maximum steering angle (depending on speed). */
|
||||
float getMaxSteerAngle (float speed) const;
|
||||
|
||||
/** Returns the (maximum) speed for a given turn radius. */
|
||||
float getSpeedForTurnRadius(float radius) const;
|
||||
float getMaxSteerAngle(float speed) const {
|
||||
return m_turn_angle_at_speed.get(speed);
|
||||
} // getMaxSteerAngle
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the material for the kart icons. */
|
||||
Material* getIconMaterial () const {return m_icon_material; }
|
||||
|
||||
@ -360,7 +364,10 @@ public:
|
||||
/** Returns the name of this kart.
|
||||
\note Pass it through fridibi as needed, this is the LTR name
|
||||
*/
|
||||
const wchar_t* getName() const {return translations->w_gettext(m_name.c_str()); }
|
||||
const wchar_t* getName() const
|
||||
{
|
||||
return translations->w_gettext(m_name.c_str());
|
||||
}
|
||||
|
||||
const std::string getNonTranslatedName() const {return m_name;}
|
||||
|
||||
@ -547,10 +554,16 @@ public:
|
||||
|
||||
/** Returns the increase of maximum speed while a rubber band is
|
||||
* pulling. */
|
||||
float getRubberBandSpeedIncrease() const {return m_rubber_band_speed_increase;}
|
||||
float getRubberBandSpeedIncrease() const
|
||||
{
|
||||
return m_rubber_band_speed_increase;
|
||||
}
|
||||
|
||||
/** Return the fade out time once a rubber band is removed. */
|
||||
float getRubberBandFadeOutTime () const {return m_rubber_band_fade_out_time;}
|
||||
float getRubberBandFadeOutTime() const
|
||||
{
|
||||
return m_rubber_band_fade_out_time;
|
||||
}
|
||||
|
||||
/** Returns duration of a plunger in your face. */
|
||||
float getPlungerInFaceTime () const
|
||||
|
147
src/utils/interpolation_array.hpp
Normal file
147
src/utils/interpolation_array.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2012 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_INTERPOLATION_ARRAY_HPP
|
||||
#define HEADER_INTERPOLATION_ARRAY_HPP
|
||||
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
||||
/** This class manages a set of (x_i,y_i) points, x_i must be sorted.
|
||||
* Those values are then used to linearly interpolate the y value for a
|
||||
* given x. If x is less than the minimum x_0, y_0 is returned, if x is
|
||||
* more than the maximum x_n, y_n is returned.
|
||||
*/
|
||||
class InterpolationArray
|
||||
{
|
||||
private:
|
||||
/** The sorted x values. */
|
||||
std::vector<float> m_x;
|
||||
|
||||
/** The y values. */
|
||||
std::vector<float> m_y;
|
||||
|
||||
/* Pre-computed (x[i+1]-x[i])/(y[i+1]/-y[i]) . */
|
||||
std::vector<float> m_delta;
|
||||
|
||||
/** True if the Y values are decreasing. This flag is important when
|
||||
* doing a reverse loopup (find X given Y). */
|
||||
bool m_decreasing;
|
||||
public:
|
||||
InterpolationArray(bool decreasing) : m_decreasing(decreasing) {};
|
||||
|
||||
/** Adds the value pair x/y to the list of all points. It is tested
|
||||
* that the x values are added in order.
|
||||
* \param x, y The pair to add.
|
||||
* \returns 0 If the x values are not sorted, 1 otherwise. */
|
||||
int push_back(float x, float y)
|
||||
{
|
||||
if(m_x.size()>0 && x < m_x[m_x.size()-1])
|
||||
return 0;
|
||||
m_x.push_back(x);
|
||||
m_y.push_back(y);
|
||||
if(m_y.size()>1)
|
||||
{
|
||||
const unsigned int last=m_x.size()-1;
|
||||
m_delta.push_back( (m_y[last]-m_y[last-1])
|
||||
/(m_x[last]-m_x[last-1]) );
|
||||
}
|
||||
return 1;
|
||||
} // push_back
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of X/Y points. */
|
||||
unsigned int size() const { return m_x.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the X value for a specified point. */
|
||||
float getX(unsigned int i) const { return m_x[i]; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the Y value for a specified point. */
|
||||
float getY(unsigned int i) const { return m_y[i]; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the Y value for a specified point. */
|
||||
void setY(unsigned int i, float y)
|
||||
{
|
||||
m_y[i] = y;
|
||||
if(i>0)
|
||||
m_delta[i-1] = (m_y[i]-m_y[i-1])
|
||||
/(m_x[i]-m_x[i-1]);
|
||||
if(i<m_y.size()-1)
|
||||
m_delta[i] = (m_y[i+1]-m_y[i])
|
||||
/(m_x[i+1]-m_x[i]);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the interpolated Y value for a given x. */
|
||||
float get(float x) const
|
||||
{
|
||||
if(m_x.size()==1 || x<m_x[0])
|
||||
return m_y[0];
|
||||
|
||||
if(x>m_x[m_x.size()-1])
|
||||
return m_y[m_y.size()-1];
|
||||
|
||||
// Now x must be between two points in m_x
|
||||
// The array size in STK are pretty small (typically 3 or 4),
|
||||
// so not worth the effort to do a binary search
|
||||
for(unsigned int i=1; i<m_x.size(); i++)
|
||||
{
|
||||
if(x >m_x[i]) continue;
|
||||
return m_y[i-1] + m_delta[i-1] * (x - m_x[i-1]);
|
||||
}
|
||||
assert(false); return 0; // keep compiler happy
|
||||
} // get
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the X value necessary for a specified Y value. If it's not
|
||||
* possible to find a corresponding X (y is too small or too large),
|
||||
* x_min or x_max is returned. */
|
||||
float getReverse(float y) const
|
||||
{
|
||||
if(m_y.size()==1) return m_x[0];
|
||||
|
||||
if(m_decreasing)
|
||||
{
|
||||
if(y > m_y[0]) return m_x[0];
|
||||
|
||||
const unsigned int last = m_x.size();
|
||||
|
||||
for(unsigned int i=1; i<last; i++)
|
||||
{
|
||||
if(y < m_y[i]) continue;
|
||||
return m_x[i-1] + (y-m_y[i-1])/ m_delta[i-1];
|
||||
} // for i < last
|
||||
return m_y[last-1];
|
||||
}
|
||||
else // increasing
|
||||
{
|
||||
if(y < m_y[0]) return m_x[0];
|
||||
|
||||
const unsigned int last = m_x.size();
|
||||
|
||||
for(unsigned int i=1; i<last; i++)
|
||||
{
|
||||
if(y > m_y[i]) continue;
|
||||
return m_x[i-1] + (y-m_y[i-1]) / m_delta[i-1];
|
||||
} // for i < last
|
||||
return m_y[last-1];
|
||||
} // increasing
|
||||
} // getReverse
|
||||
}; // InterpolationArray
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user